/* ============================================================
   Pilotage — styles
   Design : warm cream + terracotta accent · Source Serif 4 (titres) + Inter Tight (texte & chiffres)
   ============================================================ */

:root {
  --bg: #faf8f4;
  --bg-2: #f3efe7;
  --card: #ffffff;
  --ink: #1a1815;
  --ink-2: #514c44;
  --ink-3: #8a8479;
  --line: #e8e2d5;
  --line-2: #d9d2c2;
  --accent: #b85834;
  --accent-soft: #f5e4db;
  --accent-2: #d97641;
  --olive: #6b7a3a;
  --olive-soft: #eaecd8;
  --mimosa: #d9a91f;
  --mimosa-soft: #fbf2d2;
  --info: #4180a8;
  --info-soft: #d5e6f0;
  --plum: #7e3f5f;
  --plum-soft: #efdfe7;
  --danger: #c23b3b;
  --danger-soft: #fadede;
  --ok: #2d7a4f;
  --ok-soft: #dcefe2;
  --radius: 8px;
  --radius-lg: 14px;
  --radius-xl: 18px;
  --shadow-sm: 0 1px 2px rgba(26,24,21,.04), 0 1px 1px rgba(26,24,21,.03);
  --shadow: 0 4px 16px rgba(26,24,21,.06), 0 1px 2px rgba(26,24,21,.04);
  --shadow-lg: 0 18px 48px rgba(26,24,21,.12), 0 2px 4px rgba(26,24,21,.04);
  --ease: cubic-bezier(.2,.9,.3,1);
  --dur: .18s;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
  font-family: 'Inter Tight', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  background: var(--bg);
  color: var(--ink);
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
}
body { min-height: 100vh; min-height: 100dvh; }
.serif { font-family: 'Source Serif 4', Georgia, serif; font-optical-sizing: auto; }
.mono { font-family: 'Inter Tight', system-ui, sans-serif; font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ====== LAYOUT ====== */
.app { display: flex; min-height: 100vh; min-height: 100dvh; }
.sidebar {
  width: 240px;
  background: var(--card);
  border-right: 1px solid var(--line);
  padding: 20px 0;
  display: flex;
  flex-direction: column;
  position: fixed;
  height: 100vh;
  height: 100dvh;
  overflow-y: auto;
}
.brand { padding: 0 22px 24px; border-bottom: 1px solid var(--line); }
.brand-title {
  font-family: 'Source Serif 4', serif;
  font-weight: 500;
  font-size: 22px;
  letter-spacing: -0.02em;
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.brand-sub {
  font-size: 11px;
  color: var(--ink-3);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-top: 6px;
  font-weight: 500;
}
.nav { padding: 16px 12px; flex: 1; }
.nav-label {
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
  padding: 12px 10px 8px;
}
.nav-item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 10px;
  border-radius: 6px;
  cursor: pointer;
  color: var(--ink-2);
  font-weight: 500;
  font-size: 13.5px;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
  border: none;
  background: transparent;
  width: 100%;
  text-align: left;
  margin-bottom: 2px;
}
@media (hover: hover) { .nav-item:hover { background: var(--bg-2); color: var(--ink); } }
.nav-item.active { background: var(--ink); color: #faf8f4; }
.nav-item .icon { width: 18px; height: 18px; flex-shrink: 0; }
.nav-item .badge {
  margin-left: auto;
  font-size: 10px;
  padding: 1px 6px;
  background: var(--accent);
  color: white;
  border-radius: 10px;
  font-weight: 600;
}
.nav-item .badge:empty { display: none; }
.user-chip {
  margin: 12px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  display: flex;
  align-items: center;
  gap: 10px;
}
.avatar {
  width: 30px; height: 30px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: white;
  display: grid;
  place-items: center;
  font-weight: 600;
  font-size: 12px;
}
.user-info { flex: 1; min-width: 0; line-height: 1.3; }
.user-name { font-weight: 600; font-size: 13px; }
.user-role { color: var(--ink-3); font-size: 11px; }
.user-switch {
  border: 1px solid var(--line);
  background: var(--card);
  width: 26px; height: 26px;
  border-radius: 6px;
  cursor: pointer;
  color: var(--ink-3);
  font-size: 12px;
}
.user-switch:hover { color: var(--ink); border-color: var(--ink-3); }

/* min-width:0 → permet à .main (enfant flex) de se comprimer sous la largeur d'un tableau large,
   sinon une table min-width:1160 force un scroll horizontal de TOUTE la page au lieu du seul tableau. */
.main { flex: 1; min-width: 0; margin-left: 240px; min-height: 100vh; min-height: 100dvh; }
.topbar {
  padding: 18px 32px;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 16px;
  position: sticky;
  top: 0;
  z-index: 40;
  backdrop-filter: blur(12px);
  background: rgba(250,248,244,.85);
}
.topbar h1 {
  font-family: 'Source Serif 4', serif;
  font-weight: 500;
  font-size: 22px;
  letter-spacing: -0.015em;
}
.search-bar { margin-left: auto; position: relative; }
.search-bar input {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 7px 12px 7px 32px;
  width: 260px;
  font-family: inherit;
  font-size: 13px;
  color: var(--ink);
  outline: none;
  transition: border-color var(--dur) var(--ease);
}
.search-bar input:focus { border-color: var(--ink-3); }
.search-bar::before {
  content: "";
  position: absolute;
  left: 11px;
  top: 16px;
  transform: translateY(-50%);
  width: 15px; height: 15px;
  background: var(--ink-3);
  -webkit-mask: center / contain no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E");
  mask: center / contain no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E");
  pointer-events: none;
}

/* Menu déroulant « + Nouveau » (header) */
.new-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 180px;
  background: var(--card);
  border: 1px solid var(--line-2);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.16);
  z-index: 1200;
  padding: 6px;
}
.new-menu button {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border: none;
  background: transparent;
  color: var(--ink);
  font-family: inherit;
  font-size: 13.5px;
  border-radius: 7px;
  cursor: pointer;
  text-align: left;
}
.new-menu button:hover { background: var(--bg-2); }
.new-menu svg { width: 17px; height: 17px; color: var(--ink-3); flex: none; }

/* Dropdown autocomplete de la recherche globale */
.gsearch-results {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  width: 340px;
  max-height: 420px;
  overflow-y: auto;
  background: var(--card);
  border: 1px solid var(--line-2);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.16);
  z-index: 1200;
  padding: 6px;
}
.gsearch-group {
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
  padding: 8px 8px 4px;
}
.gsearch-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 8px;
  border-radius: 7px;
  cursor: pointer;
  transition: background var(--dur) var(--ease);
}
@media (hover: hover) { .gsearch-item:hover { background: var(--bg-2); } }
.gsearch-ico { color: var(--ink-3); display: inline-flex; flex-shrink: 0; }
.gsearch-label {
  font-size: 13px;
  color: var(--ink);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
}
.gsearch-sub {
  font-size: 11px;
  color: var(--ink-3);
  white-space: nowrap;
  flex-shrink: 0;
}
.gsearch-empty {
  padding: 14px 10px;
  font-size: 12.5px;
  color: var(--ink-3);
  text-align: center;
}

.btn {
  border: 1px solid var(--line-2);
  background: var(--card);
  padding: 7px 14px;
  border-radius: 6px;
  font-family: inherit;
  font-weight: 500;
  font-size: 13px;
  color: var(--ink);
  cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
  display: inline-flex;
  align-items: center;
  justify-content: center;   /* contenu centré (utile quand le bouton est pleine largeur, ex. mobile) */
  gap: 6px;
  white-space: nowrap;
}
.btn:hover { background: var(--bg-2); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn:disabled:hover { background: var(--card); }
.btn-accent:disabled:hover { background: var(--accent); }
.btn-primary { background: var(--ink); color: #faf8f4; border-color: var(--ink); }
.btn-primary:hover { background: #000; }
.btn-accent { background: var(--accent); color: white; border-color: var(--accent); }
.btn-accent:hover { background: #a04a2a; border-color: #a04a2a; }
.btn-danger { background: var(--danger); color: white; border-color: var(--danger); }
.btn-danger:hover { background: #a82b2b; }
.btn-sm { padding: 4px 10px; font-size: 12px; }
.btn-xs { padding: 2px 8px; font-size: 11px; }
.btn-ghost { border-color: transparent; background: transparent; }
.btn-ghost:hover { background: var(--bg-2); }
/* Bouton icône seule : carré, compact */
.btn-icon { padding-left: 0; padding-right: 0; width: 34px; min-width: 34px; justify-content: center; flex: none; }
.btn-sm.btn-icon { width: 30px; min-width: 30px; }
/* Boutons « supprimer » dans les listes : sobres (contour gris → rouge au survol), pas de carré rouge plein */
.recep-action .btn-icon.btn-danger,
.recep-line-remove {
  background: transparent; border: 1px solid var(--line); color: var(--ink-3); box-shadow: none;
}
.recep-action .btn-icon.btn-danger:hover,
.recep-line-remove:hover {
  background: var(--danger-soft); border-color: #f2bdbd; color: var(--danger);
}

.content { padding: 28px 32px 60px; max-width: 1400px; }

/* ====== CARDS & GRIDS ====== */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 20px;
}
.card-title {
  font-family: 'Source Serif 4', serif;
  font-weight: 500;
  font-size: 16px;
  letter-spacing: -0.01em;
  margin-bottom: 4px;
}
.card-sub { font-size: 12px; color: var(--ink-3); margin-bottom: 14px; }

.grid { display: grid; gap: 16px; }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-2-1 { grid-template-columns: 2fr 1fr; }

/* ====== KPI ====== */
.kpi {
  padding: 16px 18px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  position: relative;
  overflow: hidden;
}
.kpi-label {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
}
.kpi-value {
  font-family: 'Source Serif 4', serif;
  font-weight: 400;
  font-size: 30px;
  letter-spacing: -0.02em;
  margin-top: 6px;
}
.kpi-value .unit { font-size: 16px; color: var(--ink-3); margin-left: 2px; }
.kpi-delta {
  font-size: 11.5px;
  margin-top: 4px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 4px;
}
.kpi-delta.up { color: var(--ok); }
.kpi-delta.down { color: var(--danger); }
.kpi-delta.warn { color: var(--accent); }
.kpi-delta.flat { color: var(--ink-3); }
.kpi-sparkline {
  position: absolute;
  right: 14px;
  top: 14px;
  width: 70px;
  height: 30px;
  opacity: .65;
}

/* ====== TABLES ====== */
table { width: 100%; border-collapse: collapse; font-size: 13px; }
thead th {
  text-align: left;
  padding: 9px 10px;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
  background: var(--card);
}
tbody td {
  padding: 11px 10px;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
  transition: background var(--dur) var(--ease);
}
tbody tr:last-child td { border-bottom: none; }
tfoot td { padding: 11px 10px; }
tbody tr:hover { background: var(--bg-2); }
tbody tr.clickable { cursor: pointer; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
td.mono { font-family: 'Inter Tight', system-ui, sans-serif; font-size: 12px; }

/* Tableau Stocks : largeurs maîtrisées + nom d'article sur 2 lignes max.
   min-width = somme des colonnes → en dessous, le conteneur scrolle horizontalement
   au lieu d'écraser la colonne Article (qui garde sa largeur fixe de 240px). */
#stockTable { table-layout: fixed; width: 100%; min-width: 1192px; }
#stockTable td { overflow: hidden; }
#stockTable .stk-etat { display: none; }   /* badge état visible en carte mobile uniquement */
#stockTable .stk-val-prixu { display: none; }   /* prix/u : carte mobile uniquement (desktop = valeur €) */
/* Stock min — édité directement dans le tableau (desktop) */
#stockTable td.stk-seuil-cell { overflow: visible; }
.stk-seuil-field { display: inline-flex; align-items: baseline; gap: 4px; justify-content: flex-end; }
.stk-seuil-input {
  width: 52px; text-align: right; font: inherit; font-size: 13px;
  padding: 3px 5px; border: 1px solid var(--line); border-radius: 6px;
  background: var(--bg); color: var(--ink); font-variant-numeric: tabular-nums;
}
.stk-seuil-input:hover { border-color: var(--ink-3); }
.stk-seuil-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 22%, transparent); }
.stk-seuil-input::placeholder { color: var(--ink-3); }
.stk-seuil-u { font-size: 11px; }
.stock-art-name {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  line-height: 1.25;
  word-break: break-word;
}

/* Tableau Stocks → cartes compactes sur mobile (plus de scroll horizontal) */
@media (max-width: 840px) {
  .stocks-table-wrap { overflow: visible !important; border: none; background: transparent; box-shadow: none; }
  #stockTable { min-width: 0; width: 100%; table-layout: auto; display: block; }
  #stockTable thead { display: none; }
  #stockTable tbody { display: block; }
  #stockTable tr.stk-row {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "name   valeur"
      "stock  stock"
      "foot   foot";
    position: relative;
    align-items: start;
    gap: 1px 12px;
    padding: 9px 13px;
    margin-bottom: 7px;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
  }
@media (hover: hover) {   #stockTable tr.stk-row:hover { background: var(--card); } }
  #stockTable td { display: block; overflow: visible; padding: 0; border: none; font-size: 13px; }
  /* masqué sur la carte — dispo dans la fiche article au tap */
  #stockTable td.stk-check,
  #stockTable td[data-label="Catégorie"],
  #stockTable td[data-label="Prix (PMP)"],
  #stockTable td.stk-seuil-cell,
  #stockTable td.stk-evo { display: none; }
  #stockTable td[data-label]::before { content: none; }   /* pas de gros libellés empilés */

  #stockTable td.stk-name {
    grid-area: name;
    display: flex; align-items: center; gap: 8px;
    margin-bottom: 1px;
  }
  #stockTable td.stk-name .stock-art-name {
    -webkit-line-clamp: unset; display: inline;
    font-size: 15.5px; font-weight: 600;
  }
  #stockTable td.stk-name .stk-etat { display: inline-block; position: absolute; top: 10px; right: 13px; margin: 0; }
  #stockTable td.stk-name .muted { display: none; }   /* unité redondante avec Stock */

  #stockTable td[data-label="Stock"] {
    grid-area: stock; text-align: left; margin-top: 6px;
  }
  #stockTable td[data-label="Valeur"] {
    grid-area: valeur; text-align: right; margin-top: 22px;
    font-size: 13px; color: var(--ink-2);
  }
  #stockTable td[data-label="Valeur"]::before {
    content: "prix "; color: var(--ink-3); font-size: 11px; font-weight: 500;
  }
  /* sur la carte mobile : prix/unité fournisseur favori (pas la valeur du stock) */
  #stockTable .stk-val-eur { display: none; }
  #stockTable .stk-val-prixu { display: inline; }
  #stockTable td.stk-niveau {
    grid-area: niveau;
    display: flex; align-items: center; gap: 10px;
    margin-top: 3px;
  }
  #stockTable td.stk-niveau .stock-bar { flex: 1; max-width: none; margin: 0; }
  #stockTable td.stk-niveau .muted { font-size: 10.5px; white-space: nowrap; margin: 0 !important; }

  /* pied : zones · fournisseur sur une ligne discrète */
  #stockTable td.stk-zones { grid-area: foot; font-size: 11.5px; color: var(--ink-3); margin-top: 5px; }
  #stockTable td.stk-fourn { display: none; }   /* fournisseur visible dans la fiche */
}

/* ====== BADGES ====== */
.badge-tag {
  display: inline-block;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 2px 8px;
  border-radius: 10px;
  text-transform: uppercase;
  line-height: 1.5;
  white-space: nowrap;
}
.badge-ok { background: var(--ok-soft); color: var(--ok); }
.badge-warn { background: var(--mimosa-soft); color: #8a6a10; }
.badge-danger { background: var(--danger-soft); color: var(--danger); }
.badge-neutral { background: var(--bg-2); color: var(--ink-2); }
.badge-accent { background: var(--accent-soft); color: var(--accent); }
.badge-olive { background: var(--olive-soft); color: var(--olive); }
.badge-info { background: var(--info-soft); color: var(--info); }
.badge-plum { background: var(--plum-soft); color: var(--plum); }

/* ====== STOCK BAR ====== */
.stock-bar {
  position: relative;
  width: 100%;
  height: 5px;
  background: var(--bg-2);
  border-radius: 3px;
  overflow: hidden;
  margin-top: 4px;
}
.stock-bar-fill {
  height: 100%;
  border-radius: 3px;
  transition: width .3s var(--ease);
}
.stock-bar-fill.high { background: var(--ok); }
.stock-bar-fill.mid { background: var(--mimosa); }
.stock-bar-fill.low { background: var(--danger); }

/* ====== SECTION HEADER ====== */
.section-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin: 28px 0 14px;
  gap: 14px;
  flex-wrap: wrap;
}
.section-header h2 {
  font-family: 'Source Serif 4', serif;
  font-weight: 500;
  font-size: 20px;
  letter-spacing: -0.015em;
}
.section-header .meta { font-size: 12px; color: var(--ink-3); }

/* ====== PAGE TRANSITION ====== */
.page { animation: fadeUp .25s var(--ease); }
@keyframes fadeUp { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* ====== TABS / FILTERS ====== */
/* Une barre d'onglets a besoin de respirer AVANT le contenu qu'elle commande, sinon le premier
   libellé se lit comme une partie de l'onglet actif. Valeur unique, volontairement : cinq écrans
   la surchargeaient en dur (14 à 18 px) et resserraient l'affichage chacun à leur façon. */
.tabs {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 26px;
}
.tab {
  padding: 9px 14px;
  border: none;
  background: transparent;
  font-family: inherit;
  font-weight: 500;
  font-size: 13px;
  color: var(--ink-3);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color var(--dur) var(--ease);
}
.tab:hover { color: var(--ink); }
.tab.active { color: var(--ink); border-bottom-color: var(--accent); }

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

/* Page Commande (mobile) : 2 boutons d'action + filtres empilés */
.cmg-actions { display: flex; gap: 8px; margin-bottom: 12px; }
.cmg-actions .btn { flex: 1; justify-content: center; min-height: 44px; }
@media (max-width: 840px) {
  .cmg-filters { flex-direction: column; align-items: stretch; }
  .cmg-filters > *, .cmg-filters input, .cmg-filters select { width: 100%; max-width: none; }
}
.filter-row select, .filter-row input, .filter-row textarea {
  padding: 6px 10px;
  border: 1px solid var(--line-2);
  border-radius: 6px;
  font-family: inherit;
  font-size: 13px;
  background: var(--card);
  color: var(--ink);
  outline: none;
}
.filter-row select:focus, .filter-row input:focus { border-color: var(--ink-3); }

/* Hauteur UNIFORME des contrôles de barre de filtre (boutons, recherche, déroulants, période, multi-select).
   On utilise `height` (et pas min-height) → les overrides mobiles en min-height 44/46px restent prioritaires. */
.filter-row .btn,
.filter-row input,
.filter-row select,
.filter-row .period-preset,
.filter-row .ms-filter > .ms-dd-summary {
  height: 36px;
  box-sizing: border-box;
}
.filter-row .btn { padding-top: 0; padding-bottom: 0; }
.filter-row .period-preset { padding-top: 0; padding-bottom: 0; }

/* ── DESKTOP : barre recherche+filtres COLLANTE sous la topbar (comme sur mobile) ──
   S'applique à la 1re barre de filtres de CHAQUE page + aux onglets/filtres de Recettes.
   `--topbar-h` / `--tabs-h` sont mesurés par _setTopbarH() (à chaque nav + resize). */
@media (min-width: 841px) {
  .page > .filter-row:first-child,
  .page > .sticky-tabs,
  #recettesContent > .filter-row {
    position: sticky;
    z-index: 25;
    background: var(--bg);
    /* couvre le padding latéral 32px de .content → bord à bord */
    margin-left: -32px;
    margin-right: -32px;
    padding-left: 32px;
    padding-right: 32px;
  }
  .page > .filter-row:first-child {
    top: var(--topbar-h, 64px);
    margin-top: -28px;   /* annule le padding haut de .content → la barre est collée sous la topbar DÈS le départ (pas de saut au scroll) */
    padding-top: 14px;
    padding-bottom: 14px;
    box-shadow: 0 6px 10px -8px rgba(26, 24, 21, .20);
  }
  .page > .sticky-tabs {
    top: var(--topbar-h, 64px);
    z-index: 26;
    margin-top: -28px;   /* idem : onglets Recettes collés dès le départ */
    padding-top: 12px;
  }
  /* 2e barre collante (sous-onglets Food Cost « FC général / FC menu ») : se cale SOUS la barre de filtres. */
  .page > #fcTabs {
    position: sticky;
    top: calc(var(--topbar-h, 64px) + var(--filter-h, 64px));
    z-index: 24;
    background: var(--bg);
    margin-top: -16px;   /* annule la marge basse de la barre filtres → collé sans saut */
    margin-left: -32px;
    margin-right: -32px;
    padding: 4px 32px 0;
    box-shadow: 0 6px 10px -8px rgba(26, 24, 21, .20);
  }
  /* Recettes : la barre filtres se cale SOUS les onglets (topbar + hauteur des onglets). */
  #recettesContent > .filter-row {
    top: calc(var(--topbar-h, 64px) + var(--tabs-h, 0px));
    margin-top: -20px;   /* annule la marge basse des onglets (.tabs = 20px) → collé dès le départ, pas de saut */
    padding-top: 12px;
    padding-bottom: 12px;
    box-shadow: 0 6px 10px -8px rgba(26, 24, 21, .20);
  }
}

/* ====== ALERT STRIP ====== */
.alert-strip {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 10px;
  padding: 11px 14px;
  background: var(--mimosa-soft);
  border: 1px solid #eadd9a;
  border-radius: var(--radius);
  margin-bottom: 16px;
  font-size: 13px;
}
.alert-strip .alert-text { flex: 1; min-width: 180px; line-height: 1.4; }
.alert-strip .btn { flex-shrink: 0; }
.alert-strip.danger { background: var(--danger-soft); border-color: #f2bdbd; color: var(--danger); }
.alert-strip.ok { background: var(--ok-soft); border-color: #bfe2cb; color: #1a5a38; }
.alert-strip .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--mimosa);
  flex-shrink: 0;
  box-shadow: 0 0 0 4px rgba(217,169,31,.15);
}
.alert-strip.danger .dot { background: var(--danger); box-shadow: 0 0 0 4px rgba(194,59,59,.15); }
.alert-strip.ok .dot { background: var(--ok); box-shadow: 0 0 0 4px rgba(45,122,79,.15); }
.alert-dismiss {
  border: none; background: transparent;
  color: var(--ink-3);
  width: 24px; height: 24px;
  border-radius: 5px;
  cursor: pointer;
  font-size: 16px;
  display: inline-grid;
  place-items: center;
  margin-left: auto;
}
.alert-dismiss:hover { background: rgba(0,0,0,.06); color: var(--ink); }

/* ====== RECIPE CARDS ====== */
.recipe-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 14px;
}
.recipe-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 16px 18px;
  cursor: pointer;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
  position: relative;
  overflow: hidden;
}
.recipe-card::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: var(--rc, var(--accent));
}
@media (hover: hover) { .recipe-card:hover { transform: translateY(-1px); box-shadow: var(--shadow); border-color: var(--line-2); } }
.rec-line-row { transition: background .15s ease; }
@media (hover: hover) { .rec-line-row:hover { background: var(--bg-2); } }
.recipe-name {
  font-family: 'Source Serif 4', serif;
  font-weight: 500;
  font-size: 17px;
  letter-spacing: -0.01em;
  margin-bottom: 2px;
  margin-top: 4px;
}
.recipe-meta { font-size: 11.5px; color: var(--ink-3); margin-bottom: 14px; }
.recipe-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
.recipe-stat-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-3);
  font-weight: 600;
}
.recipe-stat-value {
  font-family: 'Source Serif 4', serif;
  font-weight: 500;
  font-size: 15px;
  margin-top: 2px;
}

/* ====== MODAL ====== */
.modal-bg {
  position: fixed;
  inset: 0;
  background: rgba(26,24,21,.5);
  /* PAS de backdrop-filter ici : il ferait du modal le « containing block » des enfants
     position:fixed (le picker produit), cassant leur ancrage au viewport (barre de recherche
     qui part hors écran avec le clavier). Le fond sombre suffit à la séparation. */
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 20px;
}
.modal-bg.show { display: flex; animation: fadeIn .2s var(--ease); }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.modal {
  background: var(--card);
  border-radius: var(--radius-lg);
  width: 100%;
  max-width: 720px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: var(--shadow-lg);
  animation: scaleIn .22s var(--ease);
}
/* Modales à onglets : hauteur STABLE (desktop) → changer d'onglet ne redimensionne ni ne recentre la fenêtre. Mobile = 92dvh (voir plus bas). */
.modal:has(.tabs) { height: min(660px, 85vh); }
@keyframes scaleIn { from { opacity: 0; transform: scale(.97); } to { opacity: 1; transform: none; } }
@keyframes sheetUp { from { transform: translateY(100%); } to { transform: none; } }
.modal-header {
  padding: 20px 24px;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  flex-shrink: 0;
}
.modal-header h3 {
  font-family: 'Source Serif 4', serif;
  font-weight: 500;
  font-size: 20px;
  letter-spacing: -0.01em;
}
.modal-close {
  border: none;
  background: var(--bg-2);
  font-size: 18px;
  cursor: pointer;
  color: var(--ink-2);
  width: 30px; height: 30px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  flex-shrink: 0;
}
.modal-close:hover { background: var(--line); color: var(--ink); }
.modal-body {
  padding: 20px 24px;
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 0;
}
.modal-footer {
  padding: 14px 24px;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  flex-shrink: 0;
  background: var(--card);
}
/* Paire de boutons de footer (ex. Modifier + Valider) : transparent en desktop (les 2 boutons
   restent des enfants directs du flex), regroupés sur UNE MÊME ligne en mobile (cf. media query). */
.ftr-pair { display: contents; }

/* ====== RESPONSIVE MODALS / FORMULAIRES (mobile) ====== */
/* Les <select>/<input> en flex ne rétrécissent pas sous leur contenu sans min-width:0 → scroll latéral. */
.perte-line { display: flex; flex-direction: column; gap: 8px; padding: 9px 0; border-bottom: 1px dashed var(--line); }
.perte-line:last-child { border-bottom: none; }
.perte-line .form-field { min-width: 0; }
.perte-line select { width: 100%; min-width: 0; box-sizing: border-box; }
.perte-line .perte-art { width: 100%; }
/* Bouton « Choisir un article » (ouvre le picker recherche) — ressemble à un select */
.perte-art-btn { width: 100%; box-sizing: border-box; text-align: left; padding: 8px 11px; border: 1px solid var(--line-2); border-radius: 7px; background: var(--card); font-family: inherit; font-size: 13.5px; color: var(--ink); cursor: pointer; min-height: 38px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: border-color var(--dur) var(--ease); }
.perte-art-btn:hover { border-color: var(--ink-3); }
.perte-art-btn.is-empty { color: var(--ink-3); }
.perte-line-controls { display: flex; align-items: center; gap: 8px; justify-content: flex-end; }
.perte-line-controls .perte-zone { flex: 1; min-width: 0; }
.perte-line-controls .qte-stepper { flex: 0 0 auto; width: auto; }
.perte-unit { font-size: 11.5px; color: var(--ink-3); white-space: nowrap; min-width: 22px; }
.perte-rm { flex: 0 0 auto; }
.inv-count-actions .qte-stepper.inv-qte { width: auto; height: auto; }
.inv-unit { font-size: 12px; min-width: 22px; }
/* Nom d'article cliquable → comptage par conditionnement */
.inv-count-info { cursor: pointer; }
.inv-count-info:hover .inv-count-nom { color: var(--accent); }
.inv-cond-row { display: flex; align-items: center; gap: 12px; padding: 11px 0; border-bottom: 1px dashed var(--line); }
.inv-cond-row:last-child { border-bottom: none; }
.inv-cond-row .qte-stepper.inv-cond-qte { width: auto; height: auto; flex: none; }
/* Le champ de comptage est type="text" (clavier décimal FR) → les règles .qte-stepper input[type=number]
   ne l'atteignent pas et il retombe sur le champ navigateur par défaut (large, bordé). On lui redonne le
   MÊME look que tous les steppers de l'app : nombre étroit, transparent, sans bordure, entre les 2 ronds. */
.inv-cond-qte input { flex: 0 0 52px; width: 52px; min-width: 0; text-align: center; font-size: 15px; font-weight: 700; border: none; background: transparent; color: var(--ink); padding: 0; outline: none; -webkit-appearance: none; appearance: none; }

/* ===== Contenant « entamé » : sélecteur de niveau visuel (bouteille / fût / bac / sac / poche / boîte) ===== */
.inv-ent { padding: 12px 0 4px; margin-top: 6px; border-top: 1px dashed var(--line); }
.inv-ent-title { font-size: 11px; color: var(--ink-3); margin-bottom: 9px; }
.inv-ent-row { display: flex; align-items: center; gap: 8px; }
.inv-ent-cont { touch-action: none; cursor: ns-resize; overflow: visible; flex: none; }
/* Options à gauche (grandissent) ; contenant CENTRÉ dans une colonne à droite qui s'adapte au type :
   min 96 px (le décale du bord droit, même pour une bouteille étroite) et max 42 % (garde ≥58 % aux options
   → « + entamé » reste sur sa ligne même avec un chip). Le SVG est responsive (règle ci-dessous) donc un
   contenant large (fût, bac) est réduit pour tenir dans la colonne sans déborder — user 2026-08-26. */
.inv-ent-ctrl { flex: 1 1 auto; min-width: 0; }
.inv-ent-contwrap { flex: 0 1 auto; min-width: 96px; max-width: 42%; display: flex; align-items: center; justify-content: center; }
.inv-ent-contwrap svg { max-width: 100%; height: auto; }
.inv-ent-pre { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.inv-ent-preset { min-width: 48px; min-height: 40px; display: inline-grid; place-items: center; border: 1px solid var(--line-2); background: var(--card); border-radius: 12px; padding: 4px 10px; font-size: 16px; cursor: pointer; color: var(--ink-2); user-select: none; }
.inv-ent-preset.on { background: var(--accent); color: #fff; border-color: var(--accent); }
.inv-ent-chips { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.inv-ent-chip { display: inline-flex; align-items: center; gap: 5px; background: var(--bg-2); border: 1px solid var(--line-2); border-radius: 8px; padding: 4px 7px 4px 10px; font-size: 12.5px; font-weight: 600; color: var(--ink); cursor: pointer; }
.inv-ent-chip.on { outline: 2px solid var(--accent); outline-offset: -1px; }
.inv-ent-chip-rm { color: var(--ink-3); font-weight: 700; cursor: pointer; padding: 0 3px; }
.inv-ent-add { border: 1px dashed #c9a98e; background: var(--card); border-radius: 8px; padding: 4px 11px; font-size: 12.5px; cursor: pointer; color: var(--accent); font-weight: 600; }
/* Barre de niveau : fine, dépasse à gauche/droite (2 points), bouge pour inviter puis se fige au réglage. */
.lvlbar line { stroke: var(--accent); stroke-width: 2; }
.lvlbar .halo { stroke: #fff; stroke-width: 4.5; }
.lvlbar circle { fill: var(--accent); stroke: #fff; stroke-width: 1.4; }
.lvlbar.anim { animation: invEntBob 1.45s ease-in-out infinite; }
@keyframes invEntBob { 0%, 100% { transform: translateY(-2.5px); } 50% { transform: translateY(2.5px); } }

/* ===== Sélecteur de quantité « rond » sur mobile (boutons circulaires, fond transparent) ===== */
@media (max-width: 840px) {
  .qte-stepper {
    border: none !important; background: transparent !important;
    height: auto !important; width: auto !important;
    gap: 4px; overflow: visible; flex: 0 0 auto;
  }
  .qte-stepper .qte-step-btn {
    flex: 0 0 36px; width: 36px; height: 36px; border-radius: 50%;
    background: var(--bg-2); border: 1px solid var(--line);
    color: var(--ink-2); font-size: 19px; font-weight: 500;
  }
  .qte-stepper .qte-step-btn:last-child { color: var(--ok); }      /* « + » en vert, comme l'appli */
  .qte-stepper .qte-step-btn:active { background: var(--line); }
  .qte-stepper input[type="number"] {
    flex: 0 0 auto; width: 44px; min-width: 44px; text-align: center;
    background: transparent; font-size: 16px; font-weight: 700; padding: 0;
  }
  /* Picker commande : colonne quantité ajustée à la taille du sélecteur compact (à droite, sur la ligne) */
  .recep-search-result { grid-template-columns: 1fr auto; }
  .rsr-base { font-size: 11px; }
}
@media (max-width: 840px) {
  .perte-line-controls .qte-stepper { width: auto; }
  .inv-count-actions .qte-stepper.inv-qte { width: 140px; height: 42px; }
}
@media (max-width: 840px) {
  /* Modal pleine largeur, jamais de débordement horizontal */
  .modal-bg { padding: 12px; }
  .modal-body { padding-left: 16px; padding-right: 16px; }
  .modal-body[style*="max-width"] { max-width: none !important; }
  /* Barre d'outils inventaire : recherche pleine largeur, toggles en dessous */
  .inv-count-toolbar { flex-wrap: wrap; }
  .inv-count-toolbar input[type="text"] { flex: 1 1 100%; }
  /* Réassort auto + Ajouter un produit : plus gros, sur la même ligne */
  .cmd-prod-actions { flex: 1 1 100%; }
  .cmd-prod-actions .btn { flex: 1 1 0; min-width: 0; min-height: 40px; font-size: 13px; justify-content: center; }
}

/* ====== DRAWER ====== */
/* z-index > modal (100) pour pouvoir s'ouvrir par-dessus une modal */
.drawer-bg {
  position: fixed; inset: 0;
  background: rgba(26,24,21,.35);
  backdrop-filter: blur(2px);
  display: none;
  z-index: 150;
}
.drawer-bg.show { display: block; animation: fadeIn .2s var(--ease); }
.drawer {
  position: fixed;
  top: 0; right: -680px;
  width: 660px;
  max-width: 100vw;
  height: 100vh; height: 100dvh;
  background: var(--card);
  border-left: 1px solid var(--line);
  box-shadow: -8px 0 32px rgba(26,24,21,.12);
  z-index: 151;
  transition: right .28s cubic-bezier(.2,.9,.3,1);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.drawer.show { right: 0; }
@media (max-width: 840px) {
  /* Fiche article en bottom-sheet (slide depuis le bas), comme les autres modals */
  .drawer {
    width: 100%; max-width: 100%;
    left: 0; right: 0;
    top: auto; bottom: -100%;
    height: auto; max-height: 92dvh;
    border-left: none;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    box-shadow: 0 -8px 32px rgba(26, 24, 21, .18);
    transition: bottom .28s cubic-bezier(.2, .9, .3, 1);
  }
  .drawer.show { right: 0; bottom: 0; }
  .drawer-header { padding: 12px 18px 12px; position: relative; }
  .drawer-header::before {
    content: ""; position: absolute; top: 6px; left: 50%; transform: translateX(-50%);
    width: 36px; height: 4px; border-radius: 3px; background: var(--line-2);
  }
  .drawer-title { font-size: 20px; }
}
.drawer-header {
  padding: 20px 24px 16px;
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.drawer-header-top {
  display: flex; justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 14px;
}
.drawer-title {
  font-family: 'Source Serif 4', serif; font-weight: 500;
  font-size: 24px; letter-spacing: -0.02em;
  margin-bottom: 3px;
}
.drawer-sub { font-size: 12px; color: var(--ink-3); }
.drawer-close {
  border: none; background: var(--bg-2);
  width: 32px; height: 32px; border-radius: 50%;
  cursor: pointer; font-size: 18px; color: var(--ink-2);
  display: grid; place-items: center;
  flex-shrink: 0;
}
.drawer-close:hover { background: var(--line); }
.drawer-kpis {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}
.drawer-kpi {
  padding: 10px 12px;
  background: var(--bg-2);
  border-radius: 8px;
}
.drawer-kpi-label {
  font-size: 9.5px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-3);
  font-weight: 600; margin-bottom: 2px;
}
.drawer-kpi-value {
  font-family: 'Source Serif 4', serif; font-weight: 500;
  font-size: 17px; letter-spacing: -0.01em;
}
.drawer-kpi-value .unit { font-size: 11px; color: var(--ink-3); margin-left: 2px; }
.drawer-tabs {
  display: flex; gap: 2px;
  padding: 0 14px;
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
  flex-wrap: nowrap;                /* TOUS sur une seule ligne */
  overflow: hidden;                 /* pas de scroll latéral : les onglets se compriment pour tenir */
  scrollbar-width: none;
}
.drawer-tabs::-webkit-scrollbar { display: none; }
.drawer-tab {
  padding: 10px 8px;
  flex: 0 1 auto; min-width: 0;     /* rétrécit si besoin pour rester sur une ligne */
  overflow: hidden; text-overflow: ellipsis;
  border: none; background: transparent;
  font-family: inherit; font-weight: 500; font-size: 12.5px;
  color: var(--ink-3); cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
  display: flex; align-items: center; gap: 5px;
  transition: color var(--dur) var(--ease);
}
.drawer-tab .count { flex: none; }
.drawer-tab:hover { color: var(--ink); }
.drawer-tab.active { color: var(--ink); border-bottom-color: var(--accent); }
.drawer-tab .count {
  font-size: 10.5px;
  padding: 1px 6px;
  background: var(--bg-2);
  border-radius: 10px;
  font-weight: 600;
}
.drawer-tab.active .count { background: var(--accent-soft); color: var(--accent); }
.drawer-body {
  flex: 1; overflow-y: auto;
  padding: 18px 24px 40px;
  overscroll-behavior: contain;
}
.drawer-tab-pane { display: none; }
.drawer-tab-pane.active { display: block; animation: fadeIn .2s var(--ease); }

/* ====== FORM ====== */
/* L'écart VERTICAL entre deux champs doit largement dominer celui qui sépare un libellé
   de son propre champ (5 px), sinon le libellé se lit comme appartenant au champ du dessus.
   14 px ne suffisaient pas : l'écart horizontal reste à 14 px, seul le vertical s'ouvre. */
.form-grid { display: grid; row-gap: 20px; column-gap: 14px; }
.form-grid.cols-2 { grid-template-columns: 1fr 1fr; }
.form-grid.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
.form-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.form-field label {
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
}
.form-field input,
.form-field select,
.form-field textarea {
  padding: 8px 11px;
  border: 1px solid var(--line-2);
  border-radius: 7px;
  font-family: inherit;
  font-size: 13.5px;
  color: var(--ink);
  background: var(--card);
  outline: none;
  transition: border-color var(--dur) var(--ease);
  width: 100%;
  min-width: 0;       /* sinon un <select> à longue option déborde de la grille/modal sur mobile */
  max-width: 100%;
}
.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus { border-color: var(--accent); }
.form-field textarea { min-height: 60px; resize: vertical; }
.form-field .hint { font-size: 11px; color: var(--ink-3); }
.form-field-row { display: flex; gap: 8px; align-items: center; }

/* Interrupteurs (case + libellé + explication) — ex. « Article actif », « Disponible à la commande » */
.form-toggle-group { display: flex; flex-direction: column; gap: 12px; }
.form-toggle { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; margin: 0; }
.form-toggle input[type="checkbox"] {
  width: 18px; height: 18px; min-width: 18px; max-width: 18px;
  margin: 1px 0 0; padding: 0; flex: none;
  accent-color: var(--accent); cursor: pointer; box-shadow: none;
}
.form-toggle input[type="checkbox"]:focus { border-color: transparent; }
.form-toggle-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.form-toggle-title { font-size: 13.5px; font-weight: 600; color: var(--ink); text-transform: none; letter-spacing: 0; }
.form-toggle-sub { font-size: 11px; font-weight: 400; color: var(--ink-3); text-transform: none; letter-spacing: 0; line-height: 1.35; }

.chip-list { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 10px;
  background: var(--bg-2);
  border: 1px solid transparent;
  border-radius: 14px;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--ink-2);
  cursor: pointer;
  transition: background var(--dur) var(--ease);
}
.chip:hover { background: var(--line); }
.chip.active { background: var(--ink); color: #faf8f4; }

/* ====== TOAST ====== */
.toast-host {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 99999; /* toasts toujours au-dessus de l'empilement dynamique modal/drawer */
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}
@media (max-width: 840px) { .toast-host { bottom: 90px; } }
.toast {
  background: var(--ink);
  color: #faf8f4;
  padding: 11px 18px 11px 14px;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 500;
  box-shadow: var(--shadow-lg);
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 240px;
  max-width: 380px;
  pointer-events: auto;
  animation: toastIn .25s var(--ease);
}
.toast.leaving { animation: toastOut .2s var(--ease) forwards; }
.toast-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--ok);
  flex-shrink: 0;
}
.toast.err .toast-dot { background: var(--danger); }
.toast.warn .toast-dot { background: var(--mimosa); }
@keyframes toastIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes toastOut { to { opacity: 0; transform: translateY(6px); } }

/* Voile bloquant pendant le passage de la main à une appli externe (SMS/WhatsApp/e-mail) :
   empêche de quitter Pilotage avant que le message ne soit parti. */
.send-overlay { position: fixed; inset: 0; z-index: 9999; display: flex; align-items: center; justify-content: center; padding: 24px; background: rgba(20,16,12,.55); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); animation: fadeIn .15s ease; }
.send-overlay-card { background: var(--card); border-radius: 16px; padding: 26px 28px; max-width: 360px; width: 100%; text-align: center; box-shadow: 0 20px 60px rgba(0,0,0,.32); animation: scaleIn .18s ease; }
.send-spin { width: 42px; height: 42px; margin: 0 auto 16px; border: 3px solid var(--line); border-top-color: var(--accent); border-radius: 50%; animation: btnSpin .8s linear infinite; }
.send-check { width: 42px; height: 42px; margin: 0 auto 16px; border-radius: 50%; background: var(--ok); color: #fff; display: flex; align-items: center; justify-content: center; }
.send-overlay-title { font-size: 16px; font-weight: 700; color: var(--ink); margin-bottom: 6px; }
.send-overlay-sub { font-size: 13px; color: var(--ink-3); line-height: 1.45; }
.send-overlay-card .btn { margin-top: 16px; }

/* ====== EMPTY STATE ====== */
.empty {
  text-align: center;
  padding: 60px 20px;
  color: var(--ink-3);
}
.empty-icon {
  font-family: 'Source Serif 4', serif;
  font-size: 56px;
  opacity: .2;
  margin-bottom: 12px;
}
.empty-title {
  font-family: 'Source Serif 4', serif;
  font-size: 18px;
  color: var(--ink-2);
  margin-bottom: 6px;
}
.empty-sub { font-size: 13px; max-width: 380px; margin: 0 auto; }

/* ====== STUB PAGE (à implémenter) ====== */
.page-stub {
  padding: 50px 20px;
  text-align: center;
  background: var(--card);
  border: 1px dashed var(--line-2);
  border-radius: var(--radius-lg);
  color: var(--ink-3);
}
.page-stub-title {
  font-family: 'Source Serif 4', serif;
  font-size: 22px;
  color: var(--ink-2);
  margin-bottom: 8px;
}
.page-stub-sub { font-size: 14px; max-width: 520px; margin: 0 auto; }

/* ====== MOBILE ====== */
.mobile-only { display: none; }
.desktop-only { display: block; }
.topbar-actions { display: none; }
/* Barre de filtres Stocks : catégorie+fournisseur groupés, recherche + case « Stock bas » */
.stk-filters { display: flex; gap: 8px; align-items: center; }
.stk-search { display: flex; gap: 10px; align-items: center; flex: 1 1 260px; min-width: 0; }
.stk-search > #filterSearch { flex: 1 1 auto; min-width: 0; max-width: 320px; }
.stk-low { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; font-size: 12.5px; color: var(--ink-2); cursor: pointer; user-select: none; }
.stk-low input[type="checkbox"] { appearance: auto; -webkit-appearance: auto; width: 16px; height: 16px; padding: 0; margin: 0; border: none; background: none; accent-color: var(--accent); cursor: pointer; flex: 0 0 auto; }
.stk-low:has(input:checked) { color: var(--accent); font-weight: 600; }

@media (max-width: 840px) {
  .sidebar { display: none; }
  .main { margin-left: 0; }
  .topbar { padding: 14px 14px; gap: 8px; }
  .content { padding: 14px 14px 100px; }
  .desktop-only { display: none !important; }
  .mobile-only { display: block; }
  .stk-filters { flex: 1 1 100%; flex-wrap: wrap; }
  .stk-filters > .ms-filter { flex: 1 1 40%; min-width: 0; }
  .stk-filters > .ms-filter > .ms-dd-summary { width: 100%; }
  /* Menu « Affichage » (food cost / hors food cost / hors inventaire) : sa PROPRE ligne, pleine largeur
     (il n'avait aucune règle mobile → il se tassait/superposait aux 2 autres filtres, user 2026-08-28). */
  .stk-filters > #filterView { flex: 1 1 100%; width: 100%; box-sizing: border-box; height: 42px; }
  .stk-search { flex: 1 1 100%; }
  .stk-search > #filterSearch { max-width: none; }
  /* Boutons d'action de page dans le header (à la place du titre), taille confortable */
  .topbar-actions { display: flex; gap: 6px; margin-left: auto; align-items: center; flex-wrap: nowrap; }
  .topbar.has-actions .topbar-actions { flex: 1 1 auto; margin-left: 0; }
  .topbar.has-actions #topbarTitle { display: none; }
  .topbar-actions .btn {
    flex: 1 1 0; min-width: 0; min-height: 40px; height: 40px;
    font-size: 13px; padding: 0 10px; justify-content: center; white-space: nowrap;
  }
  .topbar-actions .btn span { overflow: hidden; text-overflow: ellipsis; }
  .topbar-actions .btn svg { width: 16px; height: 16px; flex: none; }
  /* Recherche de barre de filtre = pleine largeur, comme les déroulants */
  .filter-row input[type="text"] { width: 100% !important; max-width: none !important; flex: 1 1 100%; }
  /* Boutons d'action déplacés dans le header sur mobile → masqués dans la page */
  .hide-mobile { display: none !important; }
  /* Dashboard mobile : barre de recherche (gauche) + menu « + Nouveau » (droite) dans le header */
  .topbar.is-dashboard #topbarTitle { display: none; }
  .topbar.is-dashboard .topbar-actions { display: none; }   /* zone vide sur le dashboard → ne décale pas la recherche */
  .topbar.is-dashboard .search-bar { display: flex !important; flex: 1 1 auto; min-width: 0; margin-left: 0; align-items: center; }
  .topbar.is-dashboard .search-bar input { width: 100%; height: 40px; min-height: 40px; box-sizing: border-box; }
  .topbar.is-dashboard .new-menu-wrap { display: block !important; flex: none; }
  .topbar.is-dashboard #globalNewBtn { height: 40px; min-height: 40px; font-size: 13px; padding: 0 14px; }
  .grid-4, .grid-3, .grid-2, .grid-2-1 { grid-template-columns: 1fr; }
  /* KPI dashboard : 2 colonnes compactes plutôt qu'une pile de 4 */
  .dash-kpis { grid-template-columns: 1fr 1fr; gap: 10px; }
  .dash-kpis .kpi-value { font-size: 22px; }
  /* Bandeau d'alerte : texte sur toute la largeur, bouton dessous */
  .alert-strip .alert-text { flex-basis: 100%; }
  .alert-strip .btn { width: 100%; justify-content: center; min-height: 42px; }
  .topbar h1 { font-size: 18px; }
  .form-grid.cols-2, .form-grid.cols-3 { grid-template-columns: 1fr; }

  /* Derniers mouvements : table → cartes empilées */
  .dash-mvt-wrap { overflow-x: visible; }
  .dash-mvt-table { display: block; min-width: 0; }
  .dash-mvt-table thead { display: none; }
  .dash-mvt-table tbody { display: block; }
  .dash-mvt-table tr.dash-mvt-row {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 4px 12px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--line);
  }
  .dash-mvt-table td { display: block; padding: 0; border: none; }
  .dash-mvt-table td.dash-mvt-art { grid-column: 1; font-weight: 600; font-size: 14px; order: 1; }
  .dash-mvt-table td.dash-mvt-type { grid-column: 2; text-align: right; order: 2; }
  .dash-mvt-table td[data-label] { order: 3; font-size: 12.5px; }
  .dash-mvt-table td[data-label]::before {
    content: attr(data-label) " : ";
    color: var(--ink-3); font-weight: 700; font-size: 11px;
  }
  .dash-mvt-table td.dash-mvt-note:empty { display: none; }
  .dash-mvt-table td.num { text-align: left; }

  .mobile-nav {
    display: flex;
    position: fixed;
    bottom: 0; left: 0; right: 0;
    /* iOS : promeut la nav sur sa propre couche GPU → évite qu'un position:fixed « décroche » et flotte
       en plein contenu pendant le scroll inertiel / rebond (glitch Safari mobile, user 2026-08-11). */
    transform: translateZ(0);
    will-change: transform;
    background: var(--card);
    border-top: 1px solid var(--line);
    z-index: 90;
    padding: 8px 6px calc(env(safe-area-inset-bottom, 8px) + 8px);
    /* 5 icônes visibles, le reste accessible en SCROLL HORIZONTAL (une seule rangée, jamais de wrap vertical). */
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    overscroll-behavior-x: contain;
    box-shadow: 0 -2px 8px rgba(0,0,0,.04);
  }
  .mobile-nav::-webkit-scrollbar { display: none; }
  .mobile-nav button {
    flex: 0 0 20%;   /* 20 % de la largeur → exactement 5 par écran ; les suivants défilent */
    scroll-snap-align: start;
    min-width: 0;
    background: transparent;
    border: none;
    padding: 7px 2px;
    margin: 0;
    font-family: inherit;
    font-size: 9.5px;
    font-weight: 600;
    color: var(--ink-3);
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
    letter-spacing: 0.01em;
    border-radius: 14px;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .mobile-nav button.active { color: var(--accent); background: var(--accent-soft); }
  .mobile-nav button.active .mn-icon { background: transparent; color: var(--accent); }
  .mobile-nav button .mn-icon, .mobile-nav button > svg.mn-icon {
    width: 36px;
    height: 22px;
    padding: 2px 8px;
    display: grid;
    place-items: center;
    border-radius: 11px;
    transition: background var(--dur) var(--ease);
    box-sizing: content-box;
  }
  .mobile-nav button > svg.mn-icon { padding: 3px 9px; }
}
@media (min-width: 841px) { .mobile-nav { display: none; } }
/* Clavier mobile ouvert → on masque la nav du bas (sinon elle flotte AU-DESSUS du clavier). */
.kb-open .mobile-nav { display: none !important; }

/* Mapping caisse — tableau de correspondance (produit → recette), façon mockup B.
   Desktop = 3 colonnes [pill produit] [flèche] [pill recette] ; mobile = pills empilées. */
.vt-brow { display: grid; grid-template-columns: minmax(0,1fr) 22px minmax(0,1.15fr); gap: 8px; align-items: center; }
.vt-brow-arw { text-align: center; display: flex; align-items: center; justify-content: center; }
.vt-cell { display: flex; align-items: center; gap: 9px; min-width: 0; background: var(--card); border: 1px solid var(--line); border-radius: 9px; padding: 8px 11px; }
.vt-cell-todo { background: var(--mimosa-soft); border-color: rgba(214,158,46,.4); }
@media (max-width: 560px) {
  .vt-brow { grid-template-columns: 1fr; gap: 5px; }
  .vt-brow-arw, .vt-head { display: none; }
}
/* Mapping caisse — rendu MOBILE « Option C » (action d'abord) : une carte par produit. */
.vtm-card { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; }
.vtm-card.vtm-todo { background: var(--mimosa-soft); border-color: rgba(214,158,46,.4); }
.vtm-opt { padding: 9px 0; border-top: 1px solid rgba(214,158,46,.25); }
.vtm-links { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; margin-top: 7px; }
.vtm-links > span { font-size: 11.5px; color: var(--ink-3); cursor: pointer; display: inline-flex; align-items: center; gap: 4px; }

/* Helpers */
.row { display: flex; gap: 8px; align-items: center; }
.spacer { flex: 1; }
.muted { color: var(--ink-3); }
.strong { font-weight: 600; }
hr.sep { border: none; height: 1px; background: var(--line); margin: 14px 0; }
.var-pos { color: var(--ok); font-weight: 600; }
.var-neg { color: var(--danger); font-weight: 600; }

/* ============================================================
   DRAWER — Factures reçues / Évolution prix / Par fournisseur
   (matching demo1 exactly)
   ============================================================ */

/* Toolbar des filtres dans Factures reçues */
.inv-toolbar {
  display: flex;
  gap: 6px;
  align-items: center;
  margin-bottom: 14px;
  flex-wrap: nowrap;   /* filtre fournisseur SUR LA MÊME LIGNE que les filtres prix (user 2026-07-21) */
}
.inv-toolbar select {
  padding: 6px 10px;
  border: 1px solid var(--line-2);
  border-radius: 6px;
  background: var(--card);
  font-family: inherit;
  font-size: 12.5px;
  color: var(--ink);
  outline: none;
  min-width: 0;        /* peut se rétrécir plutôt que de pousser le select à la ligne suivante */
  flex: 0 1 auto;
}
.inv-filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 9px;
  background: var(--bg-2);
  border-radius: 12px;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--ink-2);
  cursor: pointer;
  border: 1px solid transparent;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.inv-filter-chip:hover { background: var(--line); }
.inv-filter-chip.active {
  background: var(--ink);
  color: #faf8f4;
}

/* Ligne facture dans la liste */
.inv-row {
  display: grid;
  /* date | fournisseur | total ligne | prix normalisé (le + à droite avant badge) | badge */
  grid-template-columns: 72px 1fr 90px 110px 60px;
  gap: 10px;
  padding: 12px 14px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  margin-bottom: 6px;
  align-items: center;
  cursor: pointer;
  transition: all var(--dur) var(--ease);
}
@media (hover: hover) { .inv-row:hover {
  border-color: var(--line-2);
  box-shadow: var(--shadow-sm);
} }
.inv-row.highest {
  border-color: #f2bdbd;
  background: #fdf7f7;
}
.inv-row.lowest {
  border-color: #bfe2cb;
  background: #f7fbf8;
}
.inv-date {
  font-family: 'Inter Tight', system-ui, sans-serif;
  font-size: 11.5px;
  color: var(--ink-2);
  line-height: 1.3;
}
.inv-date .yr {
  color: var(--ink-3);
  font-size: 10.5px;
}
.inv-supplier {
  font-weight: 600;
  font-size: 13px;
}
.inv-num {
  font-family: 'Inter Tight', system-ui, sans-serif;
  font-size: 11px;
  color: var(--ink-3);
  margin-top: 2px;
}
.inv-qty {
  text-align: right;
  font-family: 'Inter Tight', system-ui, sans-serif;
  font-size: 12.5px;
  color: var(--ink-2);
}
.inv-price {
  text-align: right;
  font-family: 'Inter Tight', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 700;
}
.inv-price .price-unit {
  font-size: 10px;
  color: var(--ink-3);
  font-weight: 500;
  display: block;
  margin-top: 1px;
}
.inv-badge-slot {
  text-align: right;
}
.inv-row.ignored { opacity: 0.72; }
.inv-ignore-btn {
  display: inline-block;
  margin-top: 4px;
  font-size: 10px;
  padding: 2px 7px;
  border-radius: 10px;
  border: 1px solid var(--line-2);
  background: var(--card);
  color: var(--ink-3);
  cursor: pointer;
  white-space: nowrap;
}
.inv-ignore-btn:hover { border-color: var(--ink-3); color: var(--ink); }
.inv-ignore-btn.on { background: var(--mimosa-soft); border-color: var(--mimosa); color: #8a6a10; }

/* Mini graphique d'évolution prix */
.price-mini-chart {
  background: var(--bg-2);
  border-radius: 10px;
  padding: 14px 16px;
  margin-bottom: 16px;
  position: relative;
}
.price-mini-chart-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 8px;
  gap: 10px;
  flex-wrap: wrap;
}
.price-mini-chart-title {
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 700;
}
.price-mini-chart-stats {
  font-size: 11.5px;
  color: var(--ink-2);
  font-family: 'Inter Tight', system-ui, sans-serif;
}
.price-mini-chart-stats strong { color: var(--ink); }
.price-mini-svg {
  width: 100%;
  height: 90px;
  display: block;
  overflow: visible;   /* laisse le point grossir au survol sans être coupé */
}
/* Points prix d'achat : effet au survol/focus pour signaler qu'ils sont cliquables (→ réception) */
.evo-pt { outline: none; }
.evo-pt .evo-dot { transition: transform .12s ease, filter .12s ease, stroke-width .12s ease; transform-box: fill-box; transform-origin: center; }
.evo-pt:hover .evo-dot, .evo-pt:focus-visible .evo-dot { transform: scale(1.75); stroke-width: 2; filter: drop-shadow(0 1px 3px rgba(40, 30, 10, .45)); }

/* Carte d'insight (alerte / opportunité / analyse) */
.insight-card {
  padding: 14px 16px;
  background: var(--mimosa-soft);
  border: 1px solid #eadd9a;
  border-radius: 10px;
  margin-bottom: 14px;
  font-size: 12.5px;
  color: #5a4410;
  line-height: 1.5;
}
.insight-card.danger {
  background: var(--danger-soft);
  border-color: #f2bdbd;
  color: #8a2a2a;
}
.insight-card.ok {
  background: var(--ok-soft);
  border-color: #bfe2cb;
  color: #1a5a38;
}
.insight-card strong {
  display: block;
  margin-bottom: 3px;
  font-size: 13px;
}

/* Ligne fournisseur ou variation mensuelle (Par fournisseur tab + Évolution prix tab) */
.supp-row {
  display: grid;
  grid-template-columns: 1fr 90px 90px 90px;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
  align-items: center;
  font-size: 12.5px;
}
.supp-row:last-child { border-bottom: none; }
.supp-row.head {
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
  padding: 6px 12px;
}

/* Stats par fournisseur : 5 colonnes (Fournisseur · Vol. · Moyenne · Min · Max) */
.supp-row-5 {
  display: grid;
  grid-template-columns: 1fr 72px 76px 60px 60px;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
  align-items: center;
  font-size: 12.5px;
}
.supp-row-5:last-child { border-bottom: none; }
.supp-row-5.head {
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
  padding: 6px 12px;
}

/* Infobulle instantanée des points du graphe menu engineering (Food Cost) */
.fc-matrix-tip {
  position: fixed; display: none; z-index: 9999; pointer-events: none;
  background: var(--ink); color: #fff; font-size: 11.5px; line-height: 1.5;
  padding: 7px 10px; border-radius: 7px; max-width: 250px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.25);
}

/* Assistant d'import : table d'aperçu */
.imp-table-wrap { max-height: 260px; overflow: auto; border: 1px solid var(--line); border-radius: 8px; }
.imp-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.imp-table th { position: sticky; top: 0; background: var(--bg-2); text-align: left; font-weight: 600; color: var(--ink-3); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; padding: 7px 10px; border-bottom: 1px solid var(--line); }
.imp-table td { padding: 6px 10px; border-bottom: 1px solid var(--line); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 220px; }
.imp-table tbody tr:last-child td { border-bottom: none; }

/* Food cost par catégorie (vente) : barres largeur ∝ CA, segment coût/marge */
.fccat-row { display: grid; grid-template-columns: 132px 1fr 64px; gap: 12px; align-items: center; }
.fccat-bar { display: flex; height: 26px; border-radius: 5px; overflow: hidden; min-width: 10px; }
.fccat-seg { display: flex; align-items: center; justify-content: center; color: #fff; font-size: 11px; white-space: nowrap; overflow: hidden; }
@media (max-width: 768px) {
  .fccat-row { grid-template-columns: 92px 1fr 50px; gap: 8px; }
  .fccat-seg { font-size: 10px; }
}

/* Évolution prix dans la table stocks (sparkline) */
.evo-up { color: var(--danger); font-weight: 700; }
.evo-down { color: var(--ok); font-weight: 700; }
.evo-flat { color: var(--ink-3); font-weight: 500; }

/* Mobile : empile les colonnes de la ligne facture */
@media (max-width: 840px) {
  .inv-row {
    grid-template-columns: 56px 1fr 80px 50px;
    gap: 8px;
    padding: 10px 12px;
  }
  .inv-row .inv-qty { display: none; }
  .supp-row { grid-template-columns: 1fr 80px; gap: 6px; font-size: 12px; }
  .supp-row > div:nth-child(3),
  .supp-row > div:nth-child(4) { display: none; }
  .supp-row-5 { grid-template-columns: 1fr 58px 70px; gap: 6px; font-size: 12px; }
  .supp-row-5 > div:nth-child(4),
  .supp-row-5 > div:nth-child(5) { display: none; }
}

/* ============================================================
   ICÔNES INLINE — SVG flat pro (Lucide-like)
   ============================================================ */
.icon {
  display: inline-block;
  vertical-align: -0.2em;
  flex-shrink: 0;
}
button .icon, .btn .icon, h1 .icon, h2 .icon, h3 .icon, h4 .icon {
  vertical-align: -0.18em;
}
.icon + span, span + .icon { margin-left: 4px; }
.btn .icon { margin-right: 5px; }
.btn .icon:only-child { margin-right: 0; }
.modal-header h3 .icon { margin-right: 7px; vertical-align: -0.15em; }
.empty .icon { width: 28px; height: 28px; color: var(--ink-3); margin-bottom: 8px; }
.empty-icon .icon { width: 28px; height: 28px; }
.kpi-label .icon { vertical-align: -0.15em; margin-right: 3px; opacity: .7; }

/* Icône colorée selon contexte */
.icon-danger { color: var(--danger); }
.icon-ok { color: var(--ok); }
.icon-warn { color: var(--mimosa); }
.icon-accent { color: var(--accent); }

/* ============================================================
   SÉLECTEUR DE PÉRIODE — presets + dates personnalisées
   ============================================================ */
/* Même langage visuel que le segmenté Jour/Semaine/Mois (.dash-seg) : pilule fond gris translucide,
   bordure fine, arrondi 9px, police 12/600, chevron custom. UNIQUEMENT la card Ventes (.ventes-ctrls) :
   le sélecteur du header a été remis dans son style d'origine (user 2026-08-11). Double sélecteur
   (spécificité 0,2,0) pour l'emporter sur `.filter-row select`. */
.ventes-ctrls .period-preset {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  background-color: rgba(128, 128, 128, .14);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238a8479' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 9px center;
  border: 1px solid var(--line);
  border-radius: 9px;
  color: var(--ink);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.2;
  padding: 6px 28px 6px 11px;
  cursor: pointer;
  outline: none;
}
@media (hover: hover) {
  .ventes-ctrls .period-preset:hover { border-color: var(--ink-3); }
}
.period-custom {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
/* Agenda d'inventaires en mode « dates personnalisées » : passe sur sa propre ligne sous le sélecteur */
.period-cal { flex-basis: 100%; width: 100%; margin-top: 8px; }

/* Calendrier de sélection de période avec inventaires (page Écart théo/réel) */
/* Case « inventaire de départ automatique » en BAS du calendrier (sous la légende). */
.varcal-auto { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 600; color: var(--ink-2); margin: 12px 0 0; padding-top: 10px; border-top: 1px solid var(--line); cursor: pointer; user-select: none; }
.varcal-auto input { width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; flex: none; }
/* Menu déroulant CUSTOM des inventaires (page Écart) — le <select> natif iOS ignore les couleurs d'option. */
.var-dd { position: relative; }
.var-dd-btn { width: 100%; display: flex; align-items: center; gap: 8px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--card); font-size: 13px; color: var(--ink); cursor: pointer; text-align: left; }
.var-dd-btn:disabled { cursor: default; background: var(--bg-2); }
.var-dd-btn.open { border-color: var(--accent); }
.var-dd-lbl { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.var-dd-caret { flex: none; color: var(--ink-3); font-size: 10px; }
.var-dd-dot { flex: none; width: 11px; height: 11px; border-radius: 50%; box-shadow: inset 0 0 0 1px rgba(0,0,0,.15); }
.var-dd-dots { display: inline-flex; gap: 2px; flex: none; }
.var-dd-panel { position: absolute; z-index: 70; top: calc(100% + 4px); left: 0; right: 0; max-height: 280px; overflow-y: auto; background: var(--card); border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.20); padding: 4px; }
.var-dd-opt { width: 100%; display: flex; align-items: center; gap: 8px; padding: 8px 9px; border: none; border-radius: 7px; color: var(--ink); font-size: 12.5px; cursor: pointer; text-align: left; margin-bottom: 2px; }
.var-dd-opt:last-child { margin-bottom: 0; }
.var-dd-opt-lbl { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (hover: hover) { .var-dd-opt:hover { filter: brightness(0.97); } }
/* Inventaire ALÉATOIRE : liste d'articles à cocher (recherche + filtre catégorie) dans le modal Nouvel inventaire. */
.inv-art-list { max-height: 300px; overflow-y: auto; border: 1px solid var(--line); border-radius: 10px; padding: 4px; background: transparent; }
.inv-art-row { display: flex; align-items: center; gap: 9px; padding: 8px 9px; border-radius: 7px; cursor: pointer; font-size: 13px; }
.inv-art-row + .inv-art-row { margin-top: 1px; }
.inv-art-row.on { background: var(--accent-soft, rgba(184,88,52,.12)); }
.inv-art-row input { width: 16px; height: 16px; accent-color: var(--accent); flex: none; cursor: pointer; }
.inv-art-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.inv-art-cat { flex: none; font-size: 10.5px; color: var(--ink-3); }
/* Mobile (bottom-sheet) : la liste de produits « aléatoire » remplit toute la hauteur dispo jusqu'au champ
   Nom, qui reste juste au-dessus du bouton (user 2026-08-28). Desktop garde le max-height fixe (300px). */
@media (max-width: 840px) {
  .modal.modal-arts-full { height: calc(92dvh - var(--kb, 0px)) !important; }
  .modal.modal-arts-full .modal-body { display: flex; flex-direction: column; padding-bottom: 12px; }
  .modal.modal-arts-full #invArtWrap { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
  .modal.modal-arts-full .inv-art-list { flex: 1 1 auto; max-height: none; min-height: 140px; }
  /* Recherche focus (clavier ouvert) : Nom + bouton masqués → la liste prend toute la place jusqu'au clavier. */
  .modal.modal-arts-full.search-focus #invNomField { display: none; }
  .modal.modal-arts-full.search-focus .modal-footer { display: none; }
}
.varcal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.varcal-head > div { text-align: center; font-size: 10px; color: var(--ink-3); font-weight: 700; padding: 2px 0; }
/* Cellule en colonne : le chiffre EN HAUT, les points EN FLUX en dessous (la cellule grandit → jamais de
   recouvrement du chiffre, même avec plusieurs points sur 2 rangées). */
.varcal-day { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; min-height: 46px; padding: 5px 2px 6px; font-size: 12px; border-radius: 6px; cursor: pointer; user-select: none; }
.varcal-dots { position: static; display: flex; justify-content: center; align-items: center; gap: 3px; flex-wrap: wrap; padding: 0; max-width: 100%; }
.varcal-dots .vcd { width: 10px; height: 10px; border-radius: 50%; flex: none; box-shadow: 0 0 0 1.5px var(--bg-1, #fff), 0 0 0 2px rgba(0,0,0,.16); }
.varcal-day.sel .vcd { box-shadow: 0 0 0 1.5px #fff, 0 0 0 2.5px rgba(0,0,0,.25); }
.varcal-day.empty { cursor: default; }
@media (hover: hover) { .varcal-day:not(.empty):hover { background: var(--bg-2); } }
.varcal-day.has-inv { font-weight: 700; }
.varcal-day.inrange { background: var(--bg-2); }
.varcal-day.sel { background: var(--accent); color: #fff; }
/* Info-bulle INSTANTANÉE des inventaires du jour au survol : vraies <div> EMPILÉES (Chromium n'honore pas les
   \n de attr(), et un ancien bloc nowrap écrasait tout — on passe donc par un enfant .varcal-tip). */
.varcal-tip { display: none; position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); margin-bottom: 6px; background: var(--ink); color: #fff; font-size: 11px; font-weight: 500; line-height: 1.45; text-align: left; padding: 6px 10px; border-radius: 7px; z-index: 60; pointer-events: none; box-shadow: 0 4px 14px rgba(0,0,0,.28); }
.varcal-tip > div { white-space: nowrap; padding: 1px 0; }
.varcal-tip::after { content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border: 5px solid transparent; border-top-color: var(--ink); }
@media (hover: hover) { .varcal-day:hover .varcal-tip { display: block; } }
.varcal-dot { position: absolute; bottom: 3px; left: 50%; transform: translateX(-50%); width: 10px; height: 10px; border-radius: 50%; box-shadow: 0 0 0 1px rgba(0,0,0,.16); }

/* Matrice Menu Engineering : nom du plat affiché au survol du point uniquement */
#fcMatrix .fc-pt-label { opacity: 0; transition: opacity .08s ease; }
#fcMatrix .fc-pt:hover .fc-pt-label { opacity: 1; }
#fcMatrix .fc-pt:hover circle { stroke: var(--ink-3); stroke-width: 1.6; }
.period-custom input[type="date"] {
  padding: 6px 8px;
  font-size: 12.5px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--card);
  color: var(--ink);
  font-family: 'Inter Tight', system-ui, sans-serif;
}
@media (max-width: 840px) {
  .period-preset { flex: 1 1 100%; min-height: 44px; font-size: 15px; }
  .period-custom { flex: 1 1 100%; }
  .period-custom input[type="date"] { flex: 1; min-height: 44px; font-size: 15px; }
}

/* Bouton "attention" (badge nouveaux articles…) */
.btn-warn {
  background: var(--mimosa-soft);
  border-color: #eadd9a;
  color: #7a5e10;
}
.btn-warn:hover { background: #f3e9c0; }

/* ============================================================
   NOUVEAUX ARTICLES — lignes non rapprochées
   ============================================================ */
.na-card {
  border: 1px solid var(--line);
  border-left: 3px solid var(--mimosa);
  border-radius: 10px;
  padding: 12px 14px;
  margin-bottom: 10px;
  background: var(--card);
}
.na-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  flex-wrap: wrap;
}
.na-libelle {
  font-family: 'Inter Tight', system-ui, sans-serif;
  font-weight: 700;
  font-size: 13.5px;
}
.na-meta { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }
.na-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.na-form {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed var(--line);
  display: grid;
  gap: 10px;
  min-width: 0;
}
.na-form input, .na-form select { width: 100%; box-sizing: border-box; min-width: 0; }
.na-form-label { font-size: 12px; font-weight: 600; color: var(--ink-2); }
.na-form-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.na-form-close { flex: 0 0 auto; border: 1px solid var(--line); background: var(--card); color: var(--ink-3); border-radius: 7px; width: 28px; height: 28px; display: grid; place-items: center; cursor: pointer; }
@media (hover: hover) { .na-form-close:hover { background: var(--bg-2); color: var(--ink); } }
.na-search { width: 100%; box-sizing: border-box; min-width: 0; }
.na-results { display: flex; flex-direction: column; gap: 5px; max-height: 240px; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.na-result-item {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  width: 100%; box-sizing: border-box; min-width: 0; text-align: left;
  padding: 9px 11px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--card); cursor: pointer; font: inherit; font-size: 13px; color: var(--ink);
}
.na-result-item .na-ri-main { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: flex; align-items: center; }
.na-result-item.na-sug { border-color: var(--accent); background: var(--accent-soft); }
@media (hover: hover) {
.na-result-item:hover { background: var(--bg-2); }
.na-result-item.na-sug:hover { background: var(--accent-soft); }
}
@media (max-width: 840px) {
  .na-actions { width: 100%; }
  .na-actions .btn { flex: 1; min-height: 42px; }
  .swipe-wrap:has(.na-card) { margin-bottom: 10px; border-radius: 11px; }
  .swipe-fg.na-card { margin-bottom: 0; }
}

/* ============================================================
   ÉVOLUTION COS — tableau des recettes
   ============================================================ */
.cos-header {
  display: grid;
  grid-template-columns: minmax(170px, 300px) 96px 82px 86px 82px 116px 116px 1fr;
  gap: 10px;
  align-items: end;
  font-size: 11px; font-weight: 700; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: 0.06em;
  padding: 9px 14px;
  border-bottom: 1px solid var(--line-2);
}
.cos-header > div:not(:first-child) { text-align: right; }
.cos-header .th-sort { white-space: normal; line-height: 1.2; }   /* titres longs sur 2 lignes (pas de chevauchement) */
.cos-row {
  display: grid;
  grid-template-columns: minmax(170px, 300px) 96px 82px 86px 82px 116px 116px 1fr;
  gap: 10px;
  align-items: center;
  padding: 10px 14px;
  border-bottom: 1px dashed var(--line);
  cursor: pointer;
  font-size: 13px;
  transition: background .15s ease;
}
@media (hover: hover) { .cos-row:hover { background: var(--bg-2); } }
.cos-num { text-align: right; }
@media (max-width: 840px) {
  .cos-header { display: none; }
  .cos-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 14px;
    border: 1px solid var(--line);
    border-radius: 10px;
    margin-bottom: 8px;
    padding: 12px;
  }
  .cos-row .cos-nom { flex: 1 1 60%; min-width: 0; }
  .cos-row > div:nth-child(2)::before,
  .cos-row > div:nth-child(3)::before,
  .cos-row > div:nth-child(5)::before,
  .cos-row > div:nth-child(6)::before,
  .cos-row > div:nth-child(7)::before {
    font-size: 9.5px; color: var(--ink-3);
    text-transform: uppercase; letter-spacing: 0.05em;
    margin-right: 3px;
  }
  .cos-row > div:nth-child(2)::before { content: 'coût'; }
  .cos-row > div:nth-child(3)::before { content: 'pv'; }
  .cos-row > div:nth-child(5)::before { content: 'marge'; }
  .cos-row > div:nth-child(6)::before { content: 'évo période'; }
  .cos-row > div:nth-child(7)::before { content: 'évo création'; }
}

/* En-têtes de colonnes triables (Stocks, Évolution Prix…) */
.th-sort { cursor: pointer; user-select: none; white-space: nowrap; }
.th-sort:hover { color: var(--accent); }
.sort-ind { font-size: 9px; color: var(--accent); }

/* ============================================================
   ÉVOLUTION DES PRIX — liste cross-articles
   ============================================================ */
.px-header {
  display: grid;
  grid-template-columns: 1fr 130px 130px 100px;
  gap: 12px;
  font-size: 11px; font-weight: 700; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: 0.06em;
  padding: 9px 14px;
  border-bottom: 1px solid var(--line-2);
}
.px-header > div:nth-child(3) { text-align: right; }
.px-header > div:nth-child(4) { text-align: right; }
.px-row {
  display: grid;
  grid-template-columns: 1fr 130px 130px 100px;
  gap: 12px;
  align-items: center;
  padding: 11px 14px;
  border-bottom: 1px dashed var(--line);
  cursor: pointer;
  transition: background .15s ease;
}
@media (hover: hover) { .px-row:hover { background: var(--bg-2); } }
.px-art-nom { font-weight: 600; font-size: 13.5px; }
.px-art-meta { font-size: 11px; color: var(--ink-3); margin-top: 1px; }
.px-price { text-align: right; font-weight: 700; font-size: 14px; }
.px-price .px-unit { font-size: 10.5px; color: var(--ink-3); font-weight: 500; }
.px-evo { text-align: right; }

@media (max-width: 840px) {
  .px-header { display: none; }
  .px-row {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "art  evo"
      "spark price";
    row-gap: 8px;
    border: 1px solid var(--line);
    border-radius: 10px;
    margin-bottom: 8px;
    padding: 12px;
  }
  .px-row .px-art { grid-area: art; }
  .px-row .px-evo { grid-area: evo; align-self: start; }
  .px-row .px-spark { grid-area: spark; }
  .px-row .px-price { grid-area: price; align-self: center; }
}

/* ============================================================
   INVENTAIRE — écran de comptage mobile-first
   ============================================================ */
/* En-tête de comptage figé (recherche + bascule + zones) : fond opaque, au-dessus des lignes qui défilent */
.inv-count-sticky {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--card);
  padding-top: 12px;
  box-shadow: 0 6px 7px -7px rgba(26, 24, 21, .18);
}
.inv-count-toolbar {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 4px 0 10px;
}
.inv-count-toolbar input[type="text"] {
  flex: 1;
  min-height: 42px;
  font-size: 15px;
}
.inv-toggle-restants {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--ink-2);
  white-space: nowrap;
  cursor: pointer;
}
/* Toggle vue Par zone / Totaux */
.inv-view-toggle {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: 9px;
  overflow: hidden;
  flex-shrink: 0;
}
.inv-view-toggle button {
  border: none;
  background: var(--card);
  padding: 9px 14px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-2);
  cursor: pointer;
  min-height: 42px;
}
.inv-view-toggle button.active { background: var(--accent-soft); color: var(--accent); }

/* Chips de filtre par zone */
.inv-zone-chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  padding: 8px 0 2px;
}
.inv-zone-chip {
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 20px;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-2);
  cursor: pointer;
  user-select: none;
  min-height: 34px;
  display: inline-flex;
  align-items: center;
}
.inv-zone-chip.active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }

.inv-zone-head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding: 14px 2px 6px;
  border-bottom: 1px solid var(--line-2);
  margin-bottom: 4px;
}
.inv-count-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 4px;
  border-bottom: 1px dashed var(--line);
}
.inv-count-hint { font-size: 11px; color: var(--ink-3); padding: 5px 2px 0; display: flex; align-items: flex-start; gap: 5px; line-height: 1.35; }
.inv-count-hint svg { flex: 0 0 auto; margin-top: 1px; color: var(--mimosa); }
.inv-count-row.counted { background: var(--ok-soft); border-radius: 8px; padding-left: 8px; padding-right: 8px; }
/* PARTIEL (vue « Toutes ») : compté dans certaines zones mais pas toutes → orange, pas vert. */
.inv-count-row.partial { background: var(--mimosa-soft); border-radius: 8px; padding-left: 8px; padding-right: 8px; }
/* À RECOMPTER : demande de recomptage depuis la page Écart → fond ambre + liseré, remonté en haut de liste. */
.inv-count-row.recount-todo { background: #FCEAD2; border-left: 3px solid #E1912B; border-radius: 8px; padding-left: 8px; padding-right: 8px; }
.inv-count-clickable.recount-todo:hover { background: #F8DFBC; }
.inv-count-info { min-width: 0; flex: 1; }
/* Ligne générique cliquable : quantité + unité empilées à droite (alignées), chevron */
.inv-count-clickable { cursor: pointer; }
@media (hover: hover) {
.inv-count-clickable:hover { background: var(--bg-2); border-radius: 8px; padding-left: 8px; padding-right: 8px; }
.inv-count-clickable.counted:hover { background: var(--ok-soft); }
.inv-count-clickable.partial:hover { background: var(--mimosa-soft); }
}
.inv-count-qty { text-align: right; flex: 0 0 auto; line-height: 1.15; min-width: 56px; }
.inv-qty-val { font-size: 17px; font-weight: 600; color: var(--ink); }
.inv-qty-unit { font-size: 11px; color: var(--ink-3); }
.inv-qty-todo { font-size: 13px; font-weight: 500; color: var(--ink-3); }
.inv-count-go { color: var(--ink-3); flex: 0 0 auto; display: flex; align-items: center; }
.inv-count-nom {
  font-weight: 600;
  font-size: 13.5px;
  line-height: 1.3;
  display: flex;
  align-items: center;
  gap: 5px;
  flex-wrap: wrap;
}
.inv-count-theo { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }
.inv-who {
  display: inline-grid;
  place-items: center;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 9.5px;
  font-weight: 700;
}
.inv-count-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.inv-btn-theo {
  min-height: 40px;
  white-space: nowrap;
  font-family: 'Inter Tight', system-ui, sans-serif;
  font-size: 11px;
}
.inv-count-input { height: 42px; width: 130px; }
.inv-count-input input[type="number"] { font-size: 15px; }
.inv-count-input .prix-cur { font-size: 11px; }

@media (max-width: 840px) {
  .inv-count-row { padding: 12px 6px; }
  .inv-count-nom { font-size: 15px; }
  .inv-btn-theo { min-height: 46px; padding: 0 12px; }
  .inv-count-input { height: 46px; width: 120px; }
  .inv-count-input input[type="number"] { font-size: 16px; }
}

/* ============================================================
   ÉDITEUR RECETTE — libellé d'ingrédient cliquable (rouvre le picker)
   ============================================================ */
.er-ing {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  width: 100%;
  min-height: 34px;
  padding: 5px 9px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--card);
  cursor: pointer;
  font-size: 13px;
  text-align: left;
  color: var(--ink);
}
@media (hover: hover) { .er-ing:hover { border-color: var(--accent); color: var(--accent); } }
.er-ing .er-ing-nom {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.er-ing > svg:last-child { flex-shrink: 0; opacity: .45; }
/* La cellule « ingrédient » porte le libellé ET, pour une recette de base ou un plat
   imbriqué, la flèche qui ouvre sa fiche. */
.er-lrow > :first-child { display: flex; align-items: center; gap: 6px; min-width: 0; }
.er-lrow .er-ing { flex: 1; min-width: 0; }
.er-ing-go {
  flex: none; width: 28px; height: 28px;
  border: 1px solid var(--line); border-radius: 7px;
  background: var(--card); color: var(--ink-3);
  display: grid; place-items: center; cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
}
.er-ing-go:hover { border-color: var(--accent); color: var(--accent); }

/* ============================================================
   PAGE FOURNISSEURS — annuaire contacts
   ============================================================ */
.fourn-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: 12px;
}
.fourn-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px 18px;
  cursor: pointer;
  transition: transform .15s var(--ease), box-shadow .15s var(--ease);
}
@media (hover: hover) { .fourn-card:hover { transform: translateY(-1px); box-shadow: var(--shadow); } }
.fourn-card.inactif { opacity: .55; }
.fourn-card-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: 8px;
}
.fourn-card-nom {
  font-family: 'Source Serif 4', serif;
  font-weight: 600;
  font-size: 17px;
  letter-spacing: -0.01em;
}
.fourn-line {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  padding: 2px 0;
  color: var(--ink-2);
  min-width: 0;
}
.fourn-line a { color: var(--accent); text-decoration: none; overflow: hidden; text-overflow: ellipsis; }
.fourn-line a:hover { text-decoration: underline; }
.fourn-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--line);
  font-size: 11px;
  color: var(--ink-3);
}
.fourn-card-meta span { display: inline-flex; align-items: center; gap: 4px; }

/* Sélecteur jours de livraison */
.fourn-jours { display: flex; gap: 6px; flex-wrap: wrap; }
.fourn-jour {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 42px;
  min-height: 38px;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 9px;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  user-select: none;
  background: var(--card);
  color: var(--ink-2);
  transition: all .12s ease;
}
.fourn-jour input { display: none; }
.fourn-jour.on {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}
@media (max-width: 840px) {
  .fourn-grid { grid-template-columns: 1fr; }
  .fourn-jour { min-height: 44px; flex: 1; }
}

/* Sélecteur multi-options : chips inline (ordi) / menu déroulant (mobile) */
.ms-dd > .ms-dd-summary { display: none; }
.ms-dd > .ms-dd-panel { display: flex; }   /* ordi : chips visibles (hérite .fourn-jours) */

@media (max-width: 840px) {
  .ms-dd { position: relative; }
  .ms-dd > .ms-dd-summary {
    display: flex; align-items: center; gap: 8px; width: 100%;
    min-height: 46px; padding: 11px 14px;
    border: 1px solid var(--line); border-radius: 10px;
    background: var(--card); color: var(--ink); cursor: pointer;
    font-family: inherit; font-size: 15px; font-weight: 500; text-align: left;
  }
  .ms-dd .ms-dd-label { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .ms-dd .ms-dd-caret { color: var(--ink-3); flex-shrink: 0; transition: transform .18s ease; }
  .ms-dd.open > .ms-dd-summary { border-color: var(--accent); border-radius: 10px 10px 0 0; }
  .ms-dd.open .ms-dd-caret { transform: rotate(180deg); }

  .ms-dd > .ms-dd-panel { display: none; }
  .ms-dd.open > .ms-dd-panel {
    display: flex; flex-direction: column; flex-wrap: nowrap; gap: 2px;
    padding: 4px; margin: 0;
    border: 1px solid var(--accent); border-top: none; border-radius: 0 0 10px 10px;
    background: var(--card); max-height: 48dvh; overflow-y: auto; overflow-x: hidden;
  }
  .ms-dd.open > .ms-dd-panel .fourn-jour {
    width: 100%; flex: none; justify-content: flex-start;
    min-height: 44px; padding: 10px 12px; gap: 10px;
    border: none; border-radius: 8px; font-weight: 500;
  }
  .ms-dd.open > .ms-dd-panel .fourn-jour.on { background: var(--accent-soft); }
  .ms-dd.open > .ms-dd-panel .fourn-jour:not(.ms-add)::before {
    content: ''; width: 19px; height: 19px; flex-shrink: 0;
    border: 1.6px solid var(--line-2); border-radius: 5px;
    background-position: center; background-repeat: no-repeat; background-size: 13px;
  }
  .ms-dd.open > .ms-dd-panel .fourn-jour.on::before {
    background-color: var(--accent); border-color: var(--accent);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
  }
  .ms-dd.open > .ms-dd-panel .ms-add {
    color: var(--accent); justify-content: center;
    border: 1px dashed var(--line-2) !important; margin-top: 2px;
  }
}

/* Variante FILTRE : menu déroulant flottant sur ordi ET mobile (jamais chips inline) */
.ms-filter { position: relative; display: inline-block; min-width: 160px; vertical-align: top; }
.ms-filter > .ms-dd-summary {
  display: flex !important; align-items: center; gap: 8px; width: 100%;
  min-height: 36px; padding: 6px 10px;
  border: 1px solid var(--line-2); border-radius: 6px;
  background: var(--card); color: var(--ink); cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 500; text-align: left;
}
.ms-filter .ms-dd-label { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ms-filter .ms-dd-caret { color: var(--ink-3); flex-shrink: 0; transition: transform .18s ease; }
.ms-filter.open > .ms-dd-summary { border-color: var(--accent); }
.ms-filter.open .ms-dd-caret { transform: rotate(180deg); }
.ms-filter > .ms-dd-panel {
  display: none !important;
  position: absolute !important; top: calc(100% + 4px); left: 0; z-index: 60;
  flex-direction: column; flex-wrap: nowrap !important; gap: 2px;
  min-width: 100%; width: max-content; max-width: 280px; max-height: 320px; overflow-y: auto; overflow-x: hidden;
  background: var(--card) !important; border: 1px solid var(--line-2) !important;
  border-radius: 8px !important; box-shadow: var(--shadow); padding: 4px;
}
.ms-filter.open > .ms-dd-panel { display: flex !important; }
.ms-filter .fourn-jour {
  width: 100%; flex: none; justify-content: flex-start;
  min-height: 38px; padding: 8px 10px; gap: 10px;
  border: none; border-radius: 6px; font-weight: 500; font-size: 13px;
}
.ms-filter .fourn-jour.on { background: var(--accent-soft); }
.ms-filter .fourn-jour::before {
  content: ''; width: 18px; height: 18px; flex-shrink: 0;
  border: 1.5px solid var(--line-2); border-radius: 5px;
  background-position: center; background-repeat: no-repeat; background-size: 12px;
}
.ms-filter .fourn-jour.on::before {
  background-color: var(--accent); border-color: var(--accent);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
}
@media (max-width: 840px) {
  .ms-filter { display: block; width: 100%; min-width: 0; }
  .ms-filter > .ms-dd-summary { min-height: 46px; font-size: 15px; border-radius: 10px; }
  .ms-filter > .ms-dd-panel { max-width: none; width: 100%; }
}

/* ============================================================
   VISIONNEUSE PHOTO — pincer pour zoomer, balayer pour changer de page
   ============================================================ */
.pv {
  position: fixed;
  inset: 0;
  z-index: 400;
  display: none;
  background: rgba(20, 18, 16, .95);
  overflow: hidden;
  /* Les gestes sont gérés à la main (pointer events) : le navigateur ne doit ni
     défiler ni zoomer par-dessus. */
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  animation: fadeIn .15s var(--ease);
}
.pv-track {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  will-change: transform;
}
/* PAGE PDF — le lecteur natif du navigateur, dans la visionneuse plutôt que dans un onglet.
   `touch-action: auto` ANNULE le `touch-action: none` du conteneur : sans ça le document ne
   défilerait pas au doigt. Même logique pour la sélection de texte, qu'on veut garder ici. */
.pv-pdf {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  background: #fff;
  display: none;
  touch-action: auto;
  user-select: text;
  -webkit-user-select: text;
}
.pv.is-pdf .pv-pdf { display: block; }
.pv.is-pdf .pv-track { display: none; }
/* La barre du bas n'a pas de z-index propre : elle ne passe au-dessus du lecteur que parce
   qu'elle le suit dans le DOM. On le fixe explicitement — sans elle, plus de nom de fichier ni
   de compteur « 2 / 5 » sur un PDF. (Les flèches et la croix ont déjà z-index: 2.) */
.pv.is-pdf .pv-bar { z-index: 2; }
/* Arrivée de la page suivante / précédente. En animation CSS et non en transition JS :
   l'état de repos reste « pas de transformation » même si l'animation ne part pas. */
.pv-track.pv-in-r { animation: pvInR .2s ease-out; }
.pv-track.pv-in-l { animation: pvInL .2s ease-out; }
@keyframes pvInR { from { transform: translateX(40px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pvInL { from { transform: translateX(-40px); opacity: 0; } to { transform: none; opacity: 1; } }
/* Pas d'object-fit ici : avec width/height auto, la boîte de l'image ÉGALE l'image
   affichée. C'est ce qui permet de borner exactement le déplacement quand on zoome
   (object-fit laisserait des bandes vides dans la boîte, donc un déplacement faux). */
.pv-img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  display: block;
  border-radius: 4px;
  transform-origin: center center;
  will-change: transform;
  -webkit-user-drag: none;
}
.pv.is-zoomed .pv-img { border-radius: 0; }
.pv.is-broken .pv-img { visibility: hidden; }
.pv-broken { display: none; }
.pv.is-broken .pv-broken {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 24px;
  text-align: center;
  color: rgba(255,255,255,.75);
  font-size: 13px;
}
.pv-btn {
  position: absolute;
  z-index: 2;
  width: 44px; height: 44px;
  border-radius: 50%;
  border: none;
  background: rgba(255,255,255,.16);
  color: #fff;
  display: grid; place-items: center;
  cursor: pointer;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.pv-btn:hover { background: rgba(255,255,255,.3); }
.pv-close { top: calc(14px + env(safe-area-inset-top)); right: 14px; }
.pv-rotate { top: calc(14px + env(safe-area-inset-top)); right: 68px; }   /* juste à gauche du bouton fermer */
.pv.is-pdf .pv-rotate, .pv.no-rotate .pv-rotate { display: none; }         /* PDF ou pièce sans chemin de stockage */
.pv.pv-rotating .pv-rotate { opacity: .5; pointer-events: none; }
.pv-prev, .pv-next { top: 50%; margin-top: -22px; display: none; }
.pv.is-multi .pv-prev, .pv.is-multi .pv-next { display: grid; }
.pv-prev { left: 12px; }
.pv-prev svg { transform: rotate(180deg); }   /* une seule icône de flèche existe */
.pv-next { right: 12px; }
.pv-bar {
  position: absolute;
  left: 0; right: 0;
  bottom: calc(12px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  color: rgba(255,255,255,.8);
  font-size: 12px;
  pointer-events: none;
  text-shadow: 0 1px 3px rgba(0,0,0,.6);
}
.pv-count { font-variant-numeric: tabular-nums; font-weight: 600; }
.pv-name {
  font-size: 11px;
  color: rgba(255,255,255,.55);
  max-width: 80%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 840px) {
  /* Au doigt on balaye : les flèches ne feraient que masquer la facture. */
  .pv.is-multi .pv-prev, .pv.is-multi .pv-next { display: none; }
  .pv-track { padding: 0; }
}

/* ============================================================
   PAGE FACTURES — lignes avec matching
   ============================================================ */
.fac-line {
  position: relative;
  padding: 14px 14px 12px;
  padding-right: 44px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 12px;
  margin-bottom: 10px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.fac-line .fac-line-libelle {
  width: 100%;
  font-size: 14px;
  font-weight: 600;
  padding: 9px 12px;
  min-height: 42px;
}
.fac-line-remove {
  position: absolute;
  top: 12px; right: 12px;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: transparent;
  color: var(--ink-3);
  border: 1px solid var(--line);
  padding: 0;
  display: grid; place-items: center;
}
.fac-line-remove:hover, .fac-line-remove:active {
  background: var(--danger-soft); color: var(--danger); border-color: #f2bdbd;
}

/* Chip d'association produit */
.fac-match-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border-radius: 9px;
  padding: 8px 12px;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  border: 1px dashed var(--line-2);
  background: var(--card);
  color: var(--ink-2);
  width: 100%;
  justify-content: flex-start;
  text-align: left;
  min-height: 40px;
}
.fac-match-chip.matched {
  border-style: solid;
  border-color: var(--ok);
  background: var(--ok-soft);
  color: #1a5a38;
}
.fac-match-chip.unmatched:hover { border-color: var(--accent); color: var(--accent); }
.fac-match-chip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Contrôles qte + prix + total sur une ligne */
.fac-line-controls {
  display: grid;
  grid-template-columns: 1.4fr 1fr auto;
  gap: 10px;
  align-items: center;
}
.fac-line-controls .qte-stepper { height: 44px; }
.fac-line-controls .prix-input { height: 44px; }
.fac-line-total {
  font-family: 'Inter Tight', system-ui, sans-serif;
  font-weight: 700;
  font-size: 14px;
  text-align: right;
  white-space: nowrap;
  min-width: 64px;
}

/* Footer du picker de matching */
.fac-match-footer {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 18px;
  border-top: 1px solid var(--line);
  background: var(--card);
}
.fac-match-footer .btn { width: 100%; justify-content: center; min-height: 44px; }
.fac-match-section-label {
  font-size: 10.5px; font-weight: 700; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: 0.07em;
  padding: 12px 14px 6px;
  display: flex; align-items: center; gap: 5px;
}

@media (max-width: 840px) {
  .fac-line-controls { grid-template-columns: 1.4fr 1fr; grid-template-areas: "qte prix" "total total"; }
  .fac-line-controls .qte-stepper { grid-area: qte; }
  .fac-line-controls .prix-input { grid-area: prix; }
  .fac-line-total { grid-area: total; text-align: right; font-size: 15px; }
}

/* ============================================================
   PAGE RÉCEPTION — Mobile-first (cuisine, tablette, téléphone)
   ============================================================ */

/* Mode AUTO — 2 gros boutons côte à côte */
.recep-auto-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-top: 4px;
}
.recep-auto-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 18px 12px;
  min-height: 88px;
  border: 1.5px dashed var(--line-2);
  background: var(--bg-2);
  transition: all .15s ease;
  border-radius: 12px;
}
.recep-auto-btn:hover, .recep-auto-btn:active {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}
.recep-auto-btn-icon { font-size: 28px; line-height: 1; }
.recep-auto-btn-label { font-size: 13px; font-weight: 600; }

/* Liste des photos ajoutées (mode auto) — grille de cards */
.recep-photo-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 10px;
}
.recep-photo-card {
  position: relative;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  color: var(--ink);
}
.recep-photo-card img {
  width: 100%;
  aspect-ratio: 4/3;
  object-fit: cover;
  display: block;
}
.recep-photo-doc {
  aspect-ratio: 4/3;
  display: grid;
  place-items: center;
  font-size: 42px;
  background: var(--card);
}
.recep-photo-meta {
  padding: 8px 10px;
  font-size: 11.5px;
  line-height: 1.35;
}
.recep-photo-name {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.recep-photo-size {
  color: var(--ink-3);
  font-size: 10.5px;
  margin-top: 2px;
}
.recep-photo-remove {
  position: absolute;
  top: 6px; right: 6px;
  width: 28px; height: 28px;
  padding: 0;
  display: grid;
  place-items: center;
  border-radius: 50%;
  box-shadow: var(--shadow);
}


/* En-tête tableau (desktop) */
.recep-list-header {
  font-size: 11px; font-weight: 700; color: var(--ink-3);
  display: grid;
  grid-template-columns: 104px 1fr 80px 100px 104px 136px;
  column-gap: 12px;
  padding: 9px 16px;
  border-bottom: 1px solid var(--line-2);
  letter-spacing: 0.06em; text-transform: uppercase;
}

/* Vue Commande unifiée (desktop) : encarts par statut */
.ord-section { margin-bottom: 20px; }
.ord-section-head { display: flex; align-items: center; gap: 8px; margin: 0 0 8px 2px; }
.ord-section-head .icon { color: var(--ink-3); }
.ord-section-title { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-2); }
/* Rubrique « À rescanner » (réceptions au scan illisible) : fond JAUNE. */
.ord-section-rescan .ord-section-title { color: #8a6a10; }
.ord-section-rescan .ord-section-head .icon { color: #b8901a; }
.ord-section-rescan > .card { background: var(--mimosa-soft); border-color: #e6cf7a; }
/* « À rescanner » — MOBILE : bandeau orange plein (Option B) pour bien la distinguer ; desktop garde le jaune ci-dessus */
@media (max-width: 840px) {
  .ord-section-rescan { border: 1.5px solid #e8791b; border-radius: 14px; overflow: hidden; box-shadow: 0 4px 14px rgba(232, 121, 27, 0.18); }
  .ord-section-rescan .ord-section-head { margin: 0; padding: 10px 13px; background: #e8791b; border-radius: 0; }
  .ord-section-rescan .ord-section-head .icon { color: #fff; }
  .ord-section-rescan .ord-section-title { color: #fff; letter-spacing: 0.07em; }
  .ord-section-rescan .ord-section-count { margin-left: auto; background: rgba(255, 255, 255, 0.24); color: #fff; border-color: transparent; }
  .ord-section-rescan > .card { background: #fff6ee; border: none; border-radius: 0; }
}
.ord-section-count { margin-left: 2px; font-size: 10.5px; }
/* Filets réguliers entre lignes : la bordure est portée par le .swipe-wrap (conteneur
   extérieur, jamais rogné par son overflow:hidden). La ligne INTERNE, elle, voyait sa
   bordure rognée au pixel près → « parfois un trait, parfois rien ». */
.ord-section .card > .recep-row:last-child { border-bottom: none; }
.ord-section .card > .swipe-wrap { border-bottom: 1px dashed var(--line); }
.ord-section .card > .swipe-wrap:last-child { border-bottom: none; }
.ord-section .card > .swipe-wrap > .recep-row { border-bottom: none; }
/* Pertes (modale) — même principe (lignes enveloppées par le swipe) */
#perteLines > .swipe-wrap { border-bottom: 1px dashed var(--line); }
#perteLines > .swipe-wrap:last-child { border-bottom: none; }
#perteLines > .swipe-wrap > .perte-line { border-bottom: none; }

/* Modale visualisation commande — grille responsive (évite le débordement horizontal sur mobile) */
.cmdv-line { display: grid; grid-template-columns: 1fr 90px 130px 100px; padding: 9px 0; border-bottom: 1px dashed var(--line); font-size: 13px; align-items: start; }
.cmdv-line.cmdv-head { font-size: 11px; font-weight: 700; color: var(--ink-3); border-bottom: 1px solid var(--line-2); padding: 7px 0; align-items: center; }
.cmdv-qte, .cmdv-total { text-align: right; }
/* Chip dans sa propre colonne → nom générique ET nom fournisseur (sous-ligne) alignés verticalement */
.cmdv-prod { display: flex; align-items: flex-start; gap: 8px; }
.cmdv-chipw { flex: 0 0 auto; }
.cmdv-txt { min-width: 0; }
.cmdv-u { font-size: 9px; color: var(--ink-3); font-weight: 400; }
/* PU HT : prix (noir) aligné à droite + « / label » (gris) aligné à gauche → les « / » l'un sous l'autre ;
   prix/pack et prix/unité au MÊME format. */
.cmdv-pu { display: grid; grid-template-columns: max-content max-content; justify-content: end; column-gap: 3px; row-gap: 1px; align-items: baseline; }
.cmdv-pu .cpv { text-align: right; color: var(--ink); }
.cmdv-pu .cpl { text-align: left; color: var(--ink-3); font-size: 11px; }
@media (max-width: 840px) {
  .cmdv-head { display: none; }
  .cmdv-line { grid-template-columns: auto auto 1fr; grid-template-areas: "prod prod prod" "qte pu total"; row-gap: 5px; column-gap: 14px; align-items: baseline; padding: 11px 0; }
  .cmdv-prod { grid-area: prod; }
  .cmdv-qte { grid-area: qte; text-align: left; }
  .cmdv-pu { grid-area: pu; display: block; }             /* mobile : prix/pack puis prix/unité sur la MÊME ligne */
  .cmdv-pu .cpv.cpu { margin-left: 6px; }                  /* séparateur avant le prix/unité */
  .cmdv-total { grid-area: total; text-align: right; font-size: 14px; }
  .cmdv-qte::before { content: "Qté "; color: var(--ink-3); font-weight: 600; }
  .cmdv-pu::before { content: "Prix "; color: var(--ink-3); font-weight: 600; }
}
.recep-list-header > div:nth-child(3),
.recep-list-header > div:nth-child(4),
.recep-list-header > div:nth-child(5) { text-align: right; }

/* Ligne réception (desktop) */
.recep-row {
  display: grid;
  grid-template-columns: 104px 1fr 80px 100px 104px 136px;
  column-gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px dashed var(--line);
  font-size: 13px;
  align-items: center;
  cursor: pointer;
  transition: background .15s ease;
  min-height: 56px;
}
@media (hover: hover) { .recep-row:hover { background: var(--bg-2); } }
/* Lignes « commande à réceptionner » (en haut de la liste Réception) — liseré accent */
.recep-row-pending { box-shadow: inset 3px 0 0 var(--accent); background: rgba(184, 88, 52, .05); }
@media (hover: hover) { .recep-row-pending:hover { background: rgba(184, 88, 52, .1); } }
.recep-row .recep-date-block { line-height: 1.35; }
.recep-row .recep-supplier { font-weight: 600; }
.recep-row .recep-meta { color: var(--ink-3); font-size: 11px; margin-top: 2px; }
.recep-row .recep-num,
.recep-row .recep-total,
.recep-row .recep-status,
.recep-row .recep-action { text-align: right; }
.recep-row .recep-action button { min-height: 36px; }

/* Picker overlay (modal-dans-modal pour l'ajout de produit) */
.recep-picker-overlay {
  position: fixed;
  inset: 0;
  bottom: var(--kb, 0px);   /* remonte au-dessus du clavier mobile → résultats jamais masqués */
  background: rgba(26,24,21,.48);
  backdrop-filter: blur(3px);
  z-index: 200;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0;
  animation: fadeIn .15s var(--ease);
}
.recep-picker-card {
  background: var(--card);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  width: 100%;
  max-width: 640px;
  /* Hauteur DÉFINIE (pas un %) = espace visible au-dessus du clavier. Ainsi la carte ne
     déborde jamais : seuls les RÉSULTATS défilent à l'intérieur, l'en-tête + la recherche
     restent fixes (iOS ne peut plus faire défiler la carte pour révéler l'input focus). */
  max-height: calc(100dvh - var(--kb, 0px));
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: var(--shadow-lg);
  animation: pickerSlideUp .25s var(--ease);
}
@keyframes pickerSlideUp {
  from { transform: translateY(100%); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}
.recep-picker-header {
  flex: 0 0 auto;   /* fixe : ne défile pas avec les résultats */
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 10px;
  padding: 16px 18px 12px;
  border-bottom: 1px solid var(--line);
}
.recep-picker-title {
  font-family: 'Source Serif 4', serif;
  font-weight: 500;
  font-size: 18px;
  letter-spacing: -0.01em;
}
.recep-picker-sub {
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 2px;
}
.recep-picker-search {
  flex: 0 0 auto;   /* fixe : reste visible, seuls les résultats défilent */
  padding: 12px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-2);
}
.recep-picker-search input {
  width: 100%;
  font-size: 16px;
  padding: 10px 14px;
  min-height: 44px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--card);
}

/* Recherche picker (zone résultat) */
.recep-search-wrap { position: relative; }
.recep-search-results {
  position: absolute;
  top: 100%; left: 0; right: 0;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: var(--shadow);
  margin-top: 4px;
  max-height: 320px;
  overflow-y: auto;
  z-index: 10;
  display: none;
}
/* Variante inline (utilisée dans le picker overlay : pas de positionnement absolu,
   pas de border, déborde naturellement dans la card) */
.recep-search-results--inline {
  position: static;
  border: none;
  border-radius: 0;
  box-shadow: none;
  margin: 0;
  max-height: none;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  display: block !important;
}
/* Le picker ne défile QU'au niveau des résultats : tout drag ailleurs (header, champ de
   recherche, fond) n'initie AUCUN scroll → l'en-tête + la recherche restent fixes, même si
   le drag DÉMARRE sur le champ de recherche (iOS ne fait plus remonter le header). */
.recep-picker-card, .recep-picker-card * { touch-action: none; }
.recep-search-results--inline, .recep-search-results--inline * { touch-action: pan-y; }
/* Desktop : la carte du picker garde une HAUTEUR MINIMALE même avec 1 seul résultat (plus de « saut » de
   hauteur selon le nombre d'items). Scopé desktop pour ne pas gêner le scroll flex du bottom-sheet mobile. */
@media (min-width: 841px) {
  .recep-search-results--inline { min-height: min(340px, 50vh); }
}
/* Groupe = article générique ; options = fiches fournisseur dessous */
.rsr-group { border-bottom: 1px solid var(--line); }
.rsr-group:last-child { border-bottom: none; }
.rsr-group-head {
  font-size: 13.5px;
  font-weight: 700;
  padding: 11px 14px 4px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.rsr-group-count {
  font-size: 10px;
  font-weight: 600;
  color: var(--accent);
  background: var(--accent-soft);
  border-radius: 20px;
  padding: 2px 8px;
  letter-spacing: 0.02em;
}
/* Pastilles stock : EMPILÉES (stock au-dessus, « en attente » en dessous), mobile ET desktop. */
.cmd-stock-pills { display: inline-flex; flex-direction: column; align-items: flex-end; gap: 3px; }
/* « En attente » = bleu HACHURÉ, même langage visuel que le segment .sbar-att de la barre de stock
   (hachures adoucies pour rester lisible sous le texte). */
.cmd-att-pill {
  background: repeating-linear-gradient(45deg, #C7DDF7 0 3px, #EAF2FD 3px 7px);
  color: #2F6FB0;
  border: 1px solid #C7DDF7;
}
.rsr-group-head .cmd-stock-pills { margin-left: auto; }
.recep-line-title .cmd-stock-pills { vertical-align: middle; margin-left: 4px; }
.rsr-option {
  padding-left: 26px !important;     /* options indentées sous le générique */
  border-bottom: 1px dashed var(--line);
  min-height: 48px !important;
}
.rsr-option:last-child { border-bottom: none; }
.rsr-supplier-label {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-2);
  font-family: 'Inter Tight', system-ui, sans-serif;
  letter-spacing: -0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Étoile favori : logée dans l'indentation de gauche (26px) SANS décaler le nom fournisseur.
   La marge négative annule le padding → le texte reste à sa position, l'étoile va dans le gouttière. */
.rsr-supplier-label.has-star { position: relative; padding-left: 18px; margin-left: -18px; }
.rsr-fav-star { position: absolute; left: 0; top: 50%; transform: translateY(-50%); color: var(--mimosa); display: inline-flex; align-items: center; }

.recep-search-result {
  padding: 11px 14px;
  cursor: pointer;
  border-bottom: 1px dashed var(--line);
  display: grid;
  grid-template-columns: 1fr 130px;
  gap: 10px;
  align-items: center;
  min-height: 54px;
}
@media (hover: hover) { .recep-search-result:hover { background: var(--bg-2); } }
.recep-search-result:last-child { border-bottom: none; }
.recep-search-result .rsr-title { font-weight: 600; font-size: 13px; line-height: 1.3; }
.recep-search-result .rsr-meta { color: var(--ink-3); font-size: 11.5px; margin-top: 3px; line-height: 1.35; }
.recep-search-result .rsr-price { text-align: right; font-family: 'Inter Tight', system-ui, sans-serif; font-size: 13px; }
.recep-search-result .rsr-price small { color: var(--ink-3); font-size: 10.5px; }
/* Picker : prix en ligne + stepper de quantité à droite (sélection multiple) */
.rsr-price-inline { font-family: 'Inter Tight', system-ui, sans-serif; font-size: 12px; color: var(--ink-2); margin-top: 3px; }
.rsr-price-inline small { color: var(--ink-3); font-size: 10.5px; }
.rsr-base { display: inline-block; background: var(--ok-soft); color: var(--ok); border-radius: 20px; padding: 2px 9px; font-size: 11.5px; font-weight: 600; margin-top: 5px; }
.rsr-base:empty { display: none; }
/* Barre de récap en bas du picker (style Maquette 3) */
.rec-picker-bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 11px 14px; border-top: 1px solid var(--line); background: var(--accent-soft); flex: 0 0 auto; }
.rec-picker-bar .rpb-1 { font-size: 13px; font-weight: 600; color: var(--accent); }
.rec-picker-bar .rpb-2 { font-size: 11.5px; color: var(--ink-2); margin-top: 1px; }
.rec-picker-bar .rpb-done { display: flex; align-items: center; gap: 6px; background: var(--accent); color: #fff; border: none; border-radius: 9px; padding: 9px 15px; font-size: 13px; font-weight: 600; cursor: pointer; flex: 0 0 auto; }
.rsr-option { cursor: default; }
.rsr-option .qte-stepper.rsr-qty { height: 38px; width: 100%; }
.rsr-picked { background: var(--ok-soft); }
.rsr-picked .qte-stepper.rsr-qty { border-color: var(--ok); }

/* Lignes du modal réception (desktop) — alignement strict header/row */
.recep-line-header {
  font-size: 11px; font-weight: 700; color: var(--ink-3);
  display: grid;
  grid-template-columns: minmax(150px, 1fr) 120px 230px 90px 36px;
  gap: 12px; padding: 10px 4px 6px;
  border-bottom: 1px solid var(--line-2);
  text-transform: uppercase; letter-spacing: 0.06em;
  align-items: end;
}
.recep-line-header > div:nth-child(2) { text-align: center; }
.recep-line-header > div:nth-child(3) { text-align: center; }
.recep-line-header > div:nth-child(4) { text-align: right; }

.recep-line {
  display: grid;
  grid-template-columns: minmax(150px, 1fr) 120px 230px 90px 36px;
  gap: 12px; align-items: end;            /* contrôles alignés par le bas (les champs prix ont un label au-dessus) */
  padding: 12px 4px;
  border-bottom: 1px dashed var(--line);
  position: relative;
}
.recep-line > .recep-line-product { align-self: center; }
.recep-line > .qte-stepper, .recep-line > .recep-line-total, .recep-line > .recep-line-remove { margin-bottom: 1px; }
.recep-line .recep-line-product { min-width: 0; }
.recep-line .recep-line-title { font-weight: 600; font-size: 14px; line-height: 1.3; }
.recep-line .recep-line-sub { color: var(--ink-3); font-size: 11.5px; margin-top: 2px; }
.recep-line .recep-line-equiv { font-size: 11.5px; font-weight: 600; color: var(--ok); margin-top: 3px; }
/* Deux champs prix CÔTE À CÔTE (prix/pack + prix/unité), liés bidirectionnellement */
.recep-line .prix-row { display: flex; flex-direction: row; gap: 8px; min-width: 0; align-items: flex-end; }
.recep-line .prix-cell { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 0 0 102px; }   /* largeur FIXE → le champ restant ne s'élargit pas */
.recep-line .prix-lab { font-size: 10px; font-weight: 700; color: var(--ink-3); text-transform: uppercase; letter-spacing: .03em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.recep-line .prix-cell .prix-input { width: 100%; }
/* Ligne de COMMANDE : produit + quantité + suppression (pas de prix éditable ni colonne total) */
.recep-line-cmd { grid-template-columns: minmax(160px, 1fr) 130px 36px; }
.recep-line .recep-line-meta-mobile { display: none; }
.recep-line .recep-line-total {
  font-family: 'Inter Tight', system-ui, sans-serif;
  font-weight: 700;
  text-align: right;
  font-size: 14px;
}
.recep-line .rlm-tot-lbl { display: none; }   /* desktop : l'en-tête « Total » suffit */
.recep-line .recep-line-remove {
  width: 34px; height: 34px;
  padding: 0;
  display: grid; place-items: center;
  border-radius: 8px;
}

/* ============================================================
   COMPARATIF commande vs réception (vue détail réception)
   ============================================================ */
.cmp-header {
  display: grid;
  grid-template-columns: 1fr 130px 130px 110px;
  gap: 10px;
  font-size: 11px; font-weight: 700; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: 0.06em;
  padding: 8px 4px 6px;
  border-bottom: 1px solid var(--line-2);
}
.cmp-row {
  display: grid;
  grid-template-columns: 1fr 130px 130px 110px;
  gap: 10px;
  align-items: center;
  padding: 10px 4px;
  border-bottom: 1px dashed var(--line);
  font-size: 13px;
}
.cmp-row.cmp-warn {
  background: var(--mimosa-soft);
  border-left: 3px solid var(--mimosa);
  padding-left: 8px;
}
.cmp-row.cmp-missing {
  background: var(--danger-soft);
  border-left: 3px solid var(--danger);
  padding-left: 8px;
}
.cmp-row.cmp-hors {
  background: var(--bg-2);
  border-left: 3px solid var(--ink-3);
  padding-left: 8px;
}
.cmp-prod-title { font-weight: 600; line-height: 1.3; }
.cmp-prod-sub { color: var(--ink-3); font-size: 11px; margin-top: 1px; }
.cmp-mini-label { display: none; }
.cmp-val-diff { color: #7a5e10; font-weight: 700; }
.cmp-val-bad { color: var(--danger); font-weight: 700; }
.cmp-statut {
  display: flex;
  gap: 4px;
  justify-content: flex-end;
  flex-wrap: wrap;
  align-items: center;
}

/* Chips d'écart chiffrées : la valeur du delta, signée et colorée */
.ecart-chip {
  display: inline-flex;
  align-items: center;
  font-family: 'Inter Tight', system-ui, sans-serif;
  font-weight: 700;
  font-size: 11px;
  padding: 3px 8px;
  border-radius: 6px;
  white-space: nowrap;
  line-height: 1.3;
}
.ecart-chip.e-down { background: var(--danger-soft); color: var(--danger); }        /* reçu en moins / manquant */
.ecart-chip.e-up { background: var(--mimosa-soft); color: #7a5e10; }                /* reçu en plus */
.ecart-chip.e-prix-up { background: var(--danger-soft); color: var(--danger); }     /* plus cher que commandé */
.ecart-chip.e-prix-down { background: var(--ok-soft); color: #1a5a38; }             /* moins cher */
.ecart-ok { color: var(--ok); display: inline-flex; }

@media (max-width: 840px) {
  /* Version COMPACTE : 2 lignes de texte par produit, badge à droite du titre,
     « commandé → reçu » sur une seule ligne, pas de labels verbeux. */
  .cmp-header { display: none; }
  .cmp-row {
    grid-template-columns: 1fr auto auto;
    grid-template-areas:
      "prod prod statut"
      "cmd  recu recu";
    row-gap: 3px;
    column-gap: 6px;
    align-items: center;
    border-radius: 9px;
    border: 1px solid var(--line);
    margin-bottom: 6px;
    padding: 9px 11px;
    font-size: 12.5px;
  }
  .cmp-row.cmp-warn, .cmp-row.cmp-missing, .cmp-row.cmp-hors { padding-left: 9px; border-left-width: 3px; }
  .cmp-row .cmp-prod { grid-area: prod; min-width: 0; }
  .cmp-prod-title {
    display: inline;
    font-size: 13.5px;
  }
  .cmp-prod-sub {
    display: inline;
    margin-left: 5px;
    font-size: 11px;
  }
  .cmp-row .cmp-cell:nth-of-type(2) { grid-area: cmd; }
  .cmp-row .cmp-cell:nth-of-type(3) {
    grid-area: recu;
    display: flex;
    align-items: center;
    justify-content: flex-end;   /* « → reçu » toujours collé à droite, peu importe la largeur du badge */
    gap: 6px;
  }
  .cmp-row .cmp-cell:nth-of-type(3)::before {
    content: "→";
    color: var(--ink-3);
    font-family: 'Inter Tight', system-ui, sans-serif;
  }
  .cmp-row .cmp-cell .mono { font-size: 12.5px; white-space: nowrap; }
  .cmp-mini-label { display: none; }
  .cmp-row .cmp-statut {
    grid-area: statut;
    justify-content: flex-end;
    align-self: start;
  }
  .cmp-row .cmp-statut .badge-tag,
  .cmp-row .cmp-statut .ecart-chip {
    font-size: 10px;
    padding: 2px 7px;
  }
}

/* Écart vs bon de commande — signalement visuel */
.recep-line.has-ecart {
  border-left: 3px solid var(--mimosa);
  background: var(--mimosa-soft);
  padding-left: 11px;
}
.recep-ecart-note {
  grid-column: 1 / -1;
  font-size: 11.5px;
  color: #7a5e10;
  display: flex;
  align-items: center;
  gap: 5px;
  margin-top: 2px;
}
.recep-ecart-note strong { color: #5a4410; }
.qte-stepper.field-ecart,
.prix-input.field-ecart {
  border-color: var(--mimosa);
  box-shadow: 0 0 0 2px var(--mimosa-soft);
}

/* ========== STEPPER quantité — composant réutilisable ========== */
/* Sélecteur de quantité — DEUX BOUTONS RONDS partout (ordi comme mobile) */
.qte-stepper {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  border: none;
  background: transparent;
  height: auto;
  width: auto;
  user-select: none;
}
.qte-stepper .qte-step-btn {
  flex: 0 0 34px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--bg-2);
  color: var(--ink-2);
  font-size: 18px;
  font-weight: 500;
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
  line-height: 1;
  transition: background .12s ease;
}
.qte-stepper .qte-step-btn:last-child { color: var(--ok); }   /* « + » en vert */
.qte-stepper .qte-step-btn:hover { background: var(--line); }
.qte-stepper .qte-step-btn:active { background: var(--line-2); }
.qte-stepper input[type="number"] {
  flex: 0 0 44px;
  width: 44px;
  border: none;
  text-align: center;
  font-size: 15px;
  font-weight: 700;
  font-family: 'Inter Tight', system-ui, sans-serif;
  min-width: 0;
  padding: 0;
  background: transparent;
  outline: none;
  /* masque les flèches natives du browser */
  appearance: textfield;
  -moz-appearance: textfield;
}
.qte-stepper input[type="number"]::-webkit-outer-spin-button,
.qte-stepper input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
/* Flèches natives haut/bas des champs number : masquées PARTOUT (doublons des boutons +/−
   des steppers, et inutiles ailleurs — la saisie se fait au clavier). Desktop surtout. */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type="number"] { -moz-appearance: textfield; }

/* ========== INPUT prix avec suffixe d'unité ========== */
.prix-input {
  position: relative;
  display: flex;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--card);
  height: 40px;
  padding: 0 10px 0 0;
  overflow: hidden;
}
.prix-input input[type="number"] {
  flex: 1 1 auto;
  border: none;
  outline: none;
  background: transparent;
  font-size: 15px;
  font-weight: 600;
  font-family: 'Inter Tight', system-ui, sans-serif;
  padding: 0 6px 0 12px;
  text-align: right;
  min-width: 0;
  appearance: textfield;
  -moz-appearance: textfield;
}
.prix-input input[type="number"]::-webkit-outer-spin-button,
.prix-input input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.prix-input .prix-unit {
  font-size: 11.5px;
  color: var(--ink-3);
  white-space: nowrap;
  font-weight: 500;
  flex-shrink: 0;
}

/* ============================================================
   MOBILE — Réception (≤ 840px)
   ============================================================ */
@media (max-width: 840px) {
  /* On masque l'en-tête tableau, on bascule les lignes en cards */
  .recep-list-header { display: none; }
  .recep-row {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "main  status"
      "date  total";
    row-gap: 2px;
    column-gap: 10px;
    padding: 10px 12px;
    min-height: auto;
    align-items: center;
  }
  .recep-row .recep-supplier-block { grid-area: main; }
  .recep-row .recep-supplier { font-size: 14.5px; }
  .recep-row .recep-meta { font-size: 11px; margin-top: 1px; }
  .recep-row .recep-date-block {
    grid-area: date; display: flex; gap: 6px; align-items: baseline; line-height: 1.2;
  }
  .recep-row .recep-date-block > div { font-size: 11.5px !important; font-weight: 500 !important; color: var(--ink-3) !important; }
  .recep-row .recep-num { display: none; }   /* nombre de lignes / comptés : superflu sur mobile */
  .recep-row .recep-total { grid-area: total; font-size: 15px; font-weight: 700; text-align: right; }
  .recep-row .recep-status { grid-area: status; text-align: right; align-self: center; }
  .recep-row .recep-temp,
  .recep-row .recep-action { display: none; }
  /* Inventaire / perte : !important pour battre le style inline display:flex (mobile = swipe). Ne touche pas aux lignes commande (bouton Réceptionner). */
  .recep-row-act .recep-action { display: none !important; }

  /* Mobile : pas de boutons d'action sur les lignes inventaire/perte (remplacés par le swipe) ;
     glisser vers la gauche pour supprimer, taper pour modifier. */
  .swipe-wrap { position: relative; overflow: hidden; }
  .swipe-action {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: flex-end; gap: 6px;
    padding-right: 20px; background: var(--danger); color: #fff;
    font-size: 12px; font-weight: 600;
  }
  .swipe-wrap.armed .swipe-action { background: #a82b2b; }
  .swipe-fg { position: relative; background: var(--card); touch-action: pan-y; will-change: transform; }
  .swipe-fg.recep-row, .swipe-fg.rsr-group { border-radius: 0; }
  /* Lignes de commande : la marge passe sur le wrap pour que l'action rouge ne déborde pas */
  .swipe-wrap:has(.recep-line) { margin-bottom: 7px; border-radius: 10px; }
  .swipe-fg.recep-line { margin-bottom: 0; }
  /* Cartes réception (manuelle / correction) : idem — sinon le fond rouge du swipe déborde autour de la carte */
  .swipe-wrap:has(.recep-line3) { margin-bottom: 9px; border-radius: 12px; }
  .swipe-fg.recep-line3 { margin-bottom: 0; }
  /* Carte résumé commande : idem */
  .swipe-wrap:has(.cmd-card) { margin-bottom: 10px; border-radius: 13px; }
  .swipe-fg.cmd-card { margin-bottom: 0; }
  /* Fiche fournisseur (tiroir article) : idem — la marge inline 6px passe sur le wrap */
  .swipe-wrap:has(.sup-fiche-card) { margin-bottom: 6px; border-radius: var(--radius-lg); }
  .swipe-fg.sup-fiche-card { margin-bottom: 0 !important; }
  /* Ligne de commande mobile : produit + sélecteur (total dans l'équivalent, suppression par swipe) */
  .recep-line-cmd {
    grid-template-columns: 1fr auto;
    grid-template-areas: "product stepper";
    padding-right: 12px;
  }
  .recep-line-cmd .recep-line-product { grid-area: product; }
  .recep-line-cmd .qte-stepper { grid-area: stepper; }

  /* Page Commande mobile — carte COMPACTE (2 rangées de grille, demande user 2026-07-17).
     Avant : le bouton d'action prenait une 3e rangée PLEINE LARGEUR (~42px) sous le badge, et le total
     était gros et aligné à droite. Maintenant :
       rangée 1 : fournisseur (+ n° du bon et mode de réception, empilés dans .recep-supplier-block) | badge
       rangée 2 : date · liv. · TOTAL (petit, noir)                                                  | bouton
     Le total reste un élément de grille distinct (le markup est PARTAGÉ avec l'ordi, où c'est une
     colonne) : on le pose donc simplement à côté du bloc date, et le « · » vient d'un ::before. */
  .cmg-row {
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
      "main main  status"
      "date total action";
  }
  .cmg-row .recep-total {
    grid-area: total; justify-self: start; align-self: center;
    font-size: 11.5px; font-weight: 600; color: var(--ink); text-align: left;
  }
  /* Le badge se cale sur la LIGNE DU FOURNISSEUR, pas au milieu du bloc (nom + n° du bon) :
     centré, il retombait entre les deux lignes. `start` + 1px pour l'aligner à l'optique du nom. */
  .cmg-row .recep-status { align-self: start; margin-top: 1px; }
  .cmg-row .recep-total::before { content: "·"; margin-right: 5px; color: var(--ink-3); font-weight: 400; }
  .cmg-row .recep-action {
    display: flex; grid-area: action; justify-content: flex-end; align-items: center; gap: 6px;
    /* Le bouton est tiré vers le haut pour se caler juste sous le badge. La rangée 2 fait pile sa hauteur,
       il ne peut donc pas remonter par simple alignement — d'où le retrait négatif, qui resserre aussi la
       carte. ⚠ Valeur MESURÉE dans le navigateur, pas estimée : le badge est juste au-dessus, dans la
       MÊME colonne de grille — à -18px il ne restait que 0,7px entre eux, d'où ce repli à -13px (~5,7px
       d'air). Ne pas remonter davantage sans re-mesurer : ils se chevaucheraient. */
    align-self: start; margin-top: -13px;
  }
  .cmg-row .recep-action .btn { min-height: 37px; padding: 0 13px; font-size: 13.2px; }
  .cmg-row .recep-action .btn svg { width: 15px; height: 15px; }
  /* Corbeille du brouillon : inutile sur mobile, le glisser-gauche supprime déjà. */
  .cmg-row .recep-action .btn-danger { display: none; }

  /* Modale = bottom sheet : remonte du bas, coins hauts arrondis, laisse voir la page derrière */
  .modal-bg { align-items: flex-end; padding: 0 0 var(--kb, 0px); }   /* --kb = hauteur du clavier → la feuille remonte au-dessus */
  .modal {
    max-width: 100% !important;
    width: 100%;
    max-height: calc(92dvh - var(--kb, 0px)) !important;   /* tient au-dessus du clavier, corps scrollable */
    height: auto;
    border-radius: 18px 18px 0 0;
    animation: sheetUp .28s var(--ease);
  }
  /* Fiche à onglets : hauteur STABLE → changer d'onglet ne fait plus « re-glisser » la feuille (juste le contenu change). */
  .modal:has(.tabs) { height: 92dvh !important; }
  .modal::before {
    content: '';
    display: block;
    width: 38px; height: 4px;
    border-radius: 999px;
    background: var(--line-2);
    margin: 8px auto 2px;
    flex-shrink: 0;
  }
  .modal-body { padding: 12px 16px 88px; }
  .modal-header { padding: 8px 16px 12px; }
  .modal-footer {
    padding: 12px 16px calc(env(safe-area-inset-bottom, 8px) + 10px);
    position: sticky; bottom: 0;
    flex-wrap: wrap;           /* les boutons s'enroulent au lieu de déborder hors champ */
  }
  .modal-footer .btn { flex: 1 1 auto; min-height: 44px; justify-content: center; }
  .modal-footer .btn-accent, .modal-footer .btn-primary { flex-basis: 100%; }  /* action principale pleine largeur */
  .modal-footer > div:empty { display: none; }   /* spacer flex:1 ne prend pas une ligne */
  /* Paire Modifier + Valider : une seule rangée pleine largeur, les 2 boutons côte à côte */
  .modal-footer .ftr-pair { display: flex; gap: 8px; flex: 1 1 100%; }
  .modal-footer .ftr-pair .btn { flex: 1 1 auto; flex-basis: auto; min-height: 44px; }

  /* Footer « en ligne » : tout sur une seule rangée (perte, inventaire) */
  .modal-footer-inline { flex-wrap: nowrap; gap: 6px; }
  .modal-footer-inline .btn-accent, .modal-footer-inline .btn-primary { flex: 1 1 auto; flex-basis: auto; }
  .modal-footer-inline .btn-compact { flex: 0 0 auto; width: 48px; min-width: 48px; padding-left: 0; padding-right: 0; justify-content: center; }
  .modal-footer-inline .btn-compact span { display: none; }   /* icône seule sur mobile */

  /* Inputs / selects : 16px pour éviter le zoom iOS, touch targets confortables */
  .modal input[type="text"],
  .modal input[type="number"],
  .modal input[type="search"],
  .modal input[type="date"],
  .modal input[type="tel"],
  .modal input[type="email"],
  .modal input[type="file"],
  .modal textarea,
  .modal select {
    font-size: 16px;
    min-height: 44px;
    padding: 10px 12px;
  }
  .modal textarea { min-height: 70px; }

  /* Tabs réception (manuel/auto) plus gros */
  .modal .tabs .tab {
    padding: 12px 8px;
    font-size: 13px;
    min-height: 48px;
  }

  /* Search results : liste épurée — en-tête article discret + filets fins, sélecteur compact à droite */
  .recep-search-results--inline { padding: 0; }
  .recep-search-result {
    grid-template-columns: 1fr auto;
    gap: 4px 12px;
    padding: 9px 16px;
    min-height: 54px;
    align-items: center;
    overflow: visible;
  }
  .recep-search-result .rsr-price { text-align: right; font-size: 13px; }
  .recep-search-result .rsr-price small { display: inline; margin-left: 6px; }
  .rsr-group { border: none; border-top: 1px solid var(--line); border-radius: 0; margin: 0; overflow: visible; }
  .rsr-group:first-child { border-top: none; }
  .rsr-group-head { background: transparent; padding: 12px 16px 3px; }
  .rsr-option { padding-left: 26px !important; border-bottom: 1px solid #f4f0e9; }
  .rsr-group .recep-search-result:last-child { border-bottom: none; }
  .rsr-base { background: transparent; padding: 0; margin-top: 3px; }
  .cmd-stock-pill { text-transform: none; letter-spacing: 0; font-weight: 600; }

  /* Lignes : card mobile — titre + total en haut, meta dessous, qte+prix en bas.
     Corbeille flotte en absolute coin haut droit. Sur mobile le prix n'affiche que "€"
     (le conditionnement est déjà dans la ligne meta). */
  .recep-line-header { display: none; }
  .recep-line {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "product  stepper"
      "price    price"
      "total    total";
    row-gap: 8px;
    column-gap: 12px;
    padding: 11px 12px;
    padding-right: 34px;            /* place pour la poubelle */
    background: var(--card);
    border-radius: 10px;
    border: 1px solid var(--line);
    margin-bottom: 7px;
    position: relative;
    align-items: center;
  }
  .recep-line .recep-line-product { grid-area: product; min-width: 0; align-self: center; }
  .recep-line .recep-line-title { font-size: 14px; line-height: 1.2; }
  .recep-line .recep-line-sub { display: block; font-size: 11px; color: var(--ink-3); margin-top: 1px; }
  .recep-line .recep-line-equiv { font-size: 11.5px; font-weight: 600; color: var(--ok); margin-top: 3px; }
  .recep-line .recep-line-meta-mobile { display: none; }   /* info déjà dans le sous-titre */
  .recep-line .recep-line-total {
    grid-area: total;
    font-size: 15px;
    text-align: right;
    align-self: center;
    font-weight: 700;
    white-space: nowrap;
  }
  .recep-line .rlm-tot-lbl { display: inline; font-weight: 400; color: var(--ink-3); font-size: 12.5px; }   /* mobile : « Total = » (pas d'en-tête de colonne) */

  /* Stepper — rond, à droite (style global) */
  .recep-line .qte-stepper { grid-area: stepper; }

  /* Prix — deux champs côte à côte, pleine largeur sous le produit */
  .recep-line .prix-row { grid-area: price; }
  .recep-line .prix-input {
    height: 38px;
    width: 100%;
    min-width: 0;
    padding-right: 10px;
  }
  .recep-line .prix-input input[type="number"] {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 16px;
    padding-left: 10px;
  }
  .recep-line .prix-input .prix-cond { display: none; }   /* masque " / Bouteille 70cl" sur mobile */
  .recep-line .prix-input .prix-cur { font-size: 14px; font-weight: 600; color: var(--ink-2); }

  /* Poubelle : cercle discret coin haut droit */
  .recep-line .recep-line-remove {
    position: absolute;
    top: 8px;
    right: 8px;
    grid-area: unset;
    width: 26px; height: 26px;
    border-radius: 50%;
    background: transparent;
    color: var(--ink-3);
    border: 1px solid var(--line);
    padding: 0;
    box-shadow: none;
  }
  .recep-line .recep-line-remove:hover,
  .recep-line .recep-line-remove:active {
    background: var(--danger-soft);
    color: var(--danger);
    border-color: #f2bdbd;
  }

  /* Filter row au-dessus de la liste (page Réception) */
  .filter-row { flex-wrap: wrap; gap: 8px; }
  .filter-row input[type="text"],
  .filter-row select {
    min-height: 44px; font-size: 15px; flex: 1 1 100%;
  }
  .filter-row .btn { flex: 1 1 100%; min-height: 48px; font-size: 14px; }
  .filter-row .spacer { display: none; }
  /* Recherche de l'onglet Recettes : pleine largeur sur mobile (user 2026-07-21).
     Elle est en type="search" — hors du sélecteur input[type="text"] ci-dessus — et son
     max-width:320px inline la bridait. On force donc la pleine largeur ici. */
  .rec-search-bar { flex: 1 1 100% !important; max-width: none !important; min-height: 44px; font-size: 15px; }

  /* Barre recherche + filtres FIXE sous la topbar sur mobile → seul le contenu en dessous défile.
     (Stocks / Commande / Recettes / Fournisseurs ; l'inventaire de comptage a son propre sticky.) */
  /* Ligne d'onglets de page (ex. Recettes : Plats / Recettes de base) FIXE sous la topbar. */
  .sticky-tabs {
    position: sticky;
    top: var(--topbar-h, 56px);
    z-index: 26;
    background: var(--bg);
    margin: -14px -14px 0;   /* bord à bord + pas de marge basse (la barre filtres suit) */
    padding: 12px 14px 0;
  }
  .filter-row.sticky-tools {
    position: sticky;
    top: calc(var(--topbar-h, 56px) + var(--tabs-h, 0px));   /* sous la topbar (+ onglets si présents) */
    z-index: 25;
    background: var(--bg);
    margin: -14px -14px 8px;   /* couvre le padding 14px de .content → bord à bord */
    padding: 12px 14px 10px;
    box-shadow: 0 6px 8px -8px rgba(26, 24, 21, .22);
  }
  /* Recettes : la barre filtres est SOUS les onglets → pas de marge haute négative (les onglets calent déjà le haut). */
  #recettesContent > .filter-row.sticky-tools { margin-top: 0; }

  /* Mapping caisse (mobile) : le HEADER (barre de progression + compteurs) JUSQU'AUX onglets reste FIXE
     sous la topbar quand on fait défiler la liste des produits (user 2026-07-21). On rend le conteneur
     collant, et les onglets internes cessent de coller seuls (sinon ils se décrocheraient du header). */
  #vtBody .vt-stickhead {
    position: sticky;
    top: var(--topbar-h, 56px);
    z-index: 25;
    background: var(--bg);
    margin: 0 -14px;                 /* bord à bord : couvre le padding 14px du contenu */
    padding: 10px 14px 0;
    box-shadow: 0 6px 8px -8px rgba(26, 24, 21, .22);
  }
  #vtBody .vt-stickhead .tabs.tabs-stick { position: static; top: auto; }

  /* Mode auto : boutons photo encore plus gros */
  .recep-auto-btn { min-height: 110px; padding: 22px 12px; }
  .recep-auto-btn-icon { font-size: 36px; }
  .recep-auto-btn-label { font-size: 14px; }

  /* Liste photos : 2 colonnes sur mobile pour rester lisible */
  .recep-photo-list { grid-template-columns: 1fr 1fr; gap: 8px; }
}

/* Food cost — chevron de dépliage d'une formule (entrecôte + accompagnement…). Discret au repos,
   il ne doit pas concurrencer le nom du plat, mais rester une cible cliquable au doigt. */
.fc-exp {
  border: 0; background: transparent; cursor: pointer;
  color: var(--ink-3); font-size: 11px; line-height: 1;
  padding: 4px 6px; margin: -4px 2px -4px -6px;
  border-radius: 4px;
}
@media (hover: hover) { .fc-exp:hover { background: var(--bg-2); color: var(--ink); } }
.fc-exp:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Une part de formule est une LIGNE ORDINAIRE du tableau : mêmes colonnes, même alignement.
   Seuls un fond légèrement teinté et un décalage du nom la rattachent à sa formule. */
.fc-sub { cursor: pointer; background: var(--bg-2); }
@media (hover: hover) { .fc-sub:hover { background: var(--accent-soft); } }
.fc-sub .fc-sub-nom { padding-left: 22px; position: relative; }
.fc-sub .fc-sub-nom::before {
  content: '└'; position: absolute; left: 6px; color: var(--ink-3); font-size: 11px;
}

/* Tableau de bord — pastille de classement (1er, 2e…) */
.dash-rank { flex:0 0 auto; min-width:30px; text-align:center; font-size:11px; font-weight:700; color:var(--ink-3); font-family:'Inter Tight', monospace; }
.dash-tops { margin-top: 32px; }   /* plus d'air entre « Ventes par jour » et les Top 10 */
.dash-recept-btn { min-height: 33px; padding: 6px 13px; font-size: 12.5px; }   /* bouton Réceptionner (ordi) — taille intermédiaire */
.dash-recept-btn svg { width: 14px; height: 14px; }
@media (max-width: 768px) {
  .dash-tops { margin-top: 26px; }
  .dash-recept-btn { min-height: 42px; padding: 10px 14px; }   /* bouton Réceptionner plus grand au doigt */
}

/* Paramètres — chips multi-zones d'une catégorie de stock */
.catzone-chips { display: flex; gap: 5px; flex-wrap: wrap; align-items: center; max-width: 360px; }

/* Commande — chips des dates de livraison possibles (vert = jour de livraison du fournisseur) */
.cmd-date-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; }
.cmd-date-chip { padding: 5px 10px; border: 1px solid var(--ok); color: var(--ok); background: transparent; border-radius: 6px; font-size: 12px; font-weight: 600; cursor: pointer; text-transform: capitalize; }
@media (hover: hover) { .cmd-date-chip:hover { background: color-mix(in srgb, var(--ok) 12%, transparent); } }
.cmd-date-chip.on { background: var(--ok); color: #fff; }

/* Fiche fournisseur — onglet Volume d'affaire (tableau par produit) */
.fnvol-row { display: grid; grid-template-columns: 1fr 130px 110px; gap: 8px; padding: 9px 14px; border-bottom: 1px solid var(--line); font-size: 13px; align-items: center; }
.fnvol-row > div:nth-child(2), .fnvol-row > div:nth-child(3) { text-align: right; }
.fnvol-row:last-child { border-bottom: none; }
/* Ligne cliquable → fiche de l'article (le tiroir s'ouvre par-dessus la fiche fournisseur) */
.fnvol-row.clickable { cursor: pointer; transition: background .12s; }
@media (hover: hover) { .fnvol-row.clickable:hover { background: var(--bg-2); } }
.fnvol-head { font-weight: 700; background: var(--bg-2); color: var(--ink-3); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; }

/* Curseur : flèche classique partout — pas de « main » (cursor:pointer) nulle part. Demande utilisateur. */
* { cursor: default !important; }
/* Sauf la saisie de texte qui garde le curseur texte (I-beam) */
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="button"]):not([type="submit"]):not([type="reset"]),
textarea,
[contenteditable="true"] { cursor: text !important; }

/* ── Tableau fournisseurs éditable (vue desktop) ── */
.ftbl-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); }
.ftbl { border-collapse: collapse; font-size: 12px; width: 100%; }
.ftbl th, .ftbl td { border: 1px solid var(--line); padding: 2px 4px; vertical-align: middle; }
.ftbl thead th { position: sticky; top: 0; background: var(--bg-2); font-size: 10px; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-3); font-weight: 700; white-space: nowrap; padding: 6px; z-index: 2; }
@media (hover: hover) { .ftbl tbody tr:hover { background: var(--accent-soft); } }
.ftbl tbody tr.inactif { opacity: .5; }
.ftbl input[type=text], .ftbl input[type=email], .ftbl input[type=tel], .ftbl input[type=number], .ftbl select { border: 1px solid transparent; background: transparent; padding: 4px 5px; font-size: 12px; width: 100%; border-radius: 4px; color: var(--ink); font-family: inherit; }
.ftbl input:focus, .ftbl select:focus { border-color: var(--accent); background: var(--card); outline: none; }
.ftbl td.ftbl-num input { width: 62px; }
.ftbl td.ftbl-chk { text-align: center; }
.ftbl td.ftbl-chk input { width: 16px; height: 16px; cursor: pointer; }
.ftbl-jours { display: flex; gap: 2px; }
.ftbl-jours label { font-size: 9px; padding: 2px 3px; border: 1px solid var(--line); border-radius: 3px; cursor: pointer; user-select: none; color: var(--ink-3); }
.ftbl-jours label.on { background: var(--accent); color: #fff; border-color: var(--accent); }
.ftbl-jours input { display: none; }
.ftbl .ftbl-min { min-width: 150px; }
.ftbl .ftbl-min-sm { min-width: 108px; }
/* Colonne « Nom » figée horizontalement : reste visible quand on scrolle vers les dernières colonnes. */
.ftbl th:first-child, .ftbl td:first-child { position: sticky; left: 0; background: var(--card); z-index: 1; box-shadow: inset -1px 0 0 var(--line); }
.ftbl thead th:first-child { background: var(--bg-2); z-index: 3; }
@media (hover: hover) { .ftbl tbody tr:hover td:first-child { background: var(--accent-soft); } }

/* ── Aide contextuelle : petite icône info discrète à côté des sections ── */
.help-dot {
  background: none; border: none; padding: 2px; margin-left: 5px;
  color: var(--ink-3); cursor: pointer; line-height: 0;
  vertical-align: middle; opacity: .5;
  transition: opacity .15s ease, color .15s ease;
}
.help-dot:hover { opacity: 1; color: var(--accent); }

/* ── Éditeur de recette : lignes d'ingrédients responsives ── */
.er-lhead, .er-lrow { display: grid; grid-template-columns: 1fr 90px 110px 80px 30px; gap: 6px; align-items: center; }
.er-lhead { padding: 4px 0 6px; font-size: 10.5px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3); font-weight: 700; border-bottom: 1px solid var(--line-2); }
.er-lrow { padding: 7px 0; border-bottom: 1px dashed var(--line); font-size: 13px; }
@media (max-width: 640px) {
  .er-lhead { display: none; }
  .er-lrow {
    grid-template-columns: 70px 1fr auto auto;
    grid-template-areas: "nom nom nom nom" "qte unite cout suppr";
    gap: 6px 8px; padding: 10px 0;
  }
  .er-lrow > :nth-child(1) { grid-area: nom; min-width: 0; }
  .er-lrow > :nth-child(2) { grid-area: qte; }
  .er-lrow > :nth-child(3) { grid-area: unite; }
  .er-lrow > :nth-child(4) { grid-area: cout; text-align: right; }
  .er-lrow > :nth-child(5) { grid-area: suppr; justify-self: end; }
  .er-lrow input, .er-lrow select { width: 100%; box-sizing: border-box; }
}

/* ── Combobox : un seul champ déroulant avec barre de recherche en haut ── */
.combo-trigger {
  width: 100%; box-sizing: border-box; display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 11px; border: 1px solid var(--line-2); border-radius: 7px; background: var(--card);
  color: var(--ink); font-family: inherit; font-size: 13.5px; cursor: pointer; text-align: left;
}
.combo-trigger:hover, .combo-trigger.open { border-color: var(--accent); }
.combo-trigger > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.combo-panel { margin-top: 6px; border: 1px solid var(--line); border-radius: 8px; padding: 6px; background: var(--card); box-shadow: var(--shadow-sm); }
.combo-panel > input { width: 100%; box-sizing: border-box; padding: 7px 9px; border: 1px solid var(--line-2); border-radius: 6px; margin-bottom: 6px; font-size: 13px; font-family: inherit; }
.combo-list { max-height: 240px; overflow-y: auto; }
.combo-opt { padding: 8px 10px; border-radius: 6px; cursor: pointer; font-size: 13px; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
@media (hover: hover) { .combo-opt:hover { background: var(--accent-soft); } }
.combo-opt.sel { background: var(--accent-soft); font-weight: 600; }

/* ── Pastille de notifications (tableau de bord) ── */
/* Pastille de notifications. Le piège : avec box-sizing border-box, la bordure (2×2 px) et
   le padding (2×4 px) se prenaient SUR les 17 px de large, laissant 5 px au chiffre — qui
   débordait donc et étirait la pastille en ovale. Ici la largeur mini couvre bordure +
   padding + deux chiffres : rond parfait jusqu'à 99, gélule seulement au-delà. */
.notif-pastille {
  position: absolute; top: -6px; right: -6px;
  min-width: 20px; height: 20px; padding: 0 2px;
  background: var(--danger); color: #fff; border-radius: 999px;
  font-size: 10px; font-weight: 700; font-variant-numeric: tabular-nums;
  display: flex; align-items: center; justify-content: center; line-height: 1;
  border: 2px solid var(--bg);
}
.notif-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--ink-3); flex: none; margin-top: 5px; }
.notif-dot.is-warn { background: var(--mimosa); }
.notif-dot.is-danger { background: var(--danger); }

/* ── Cloche notif sans cadre + pastille mobile simple ── */
.notif-bell { position: relative; background: none; border: none; padding: 6px; cursor: pointer; color: var(--ink-2); line-height: 0; transition: color .15s ease; }
.notif-bell:hover { color: var(--accent); }
@media (max-width: 640px) {
  .notif-bell { padding: 8px; }                  /* mobile : cloche VISIBLE + pastille (tap target élargi) */
  .notif-pastille { min-width: 19px; height: 19px; }   /* reste carrée : sinon elle s'ovalise */
  /* Tableau de bord : période réduite + cloche SUR LA MÊME LIGNE */
  .dash-filter .period-preset { flex: 1 1 auto; min-width: 0; width: auto; }
  .dash-filter .spacer { display: none; }
  .dash-filter .notif-bell { flex: none; }
}
/* Lignes de notif : glisser vers la gauche pour supprimer */
.notif-row { position: relative; display: flex; gap: 10px; padding: 10px 2px; border-bottom: 1px dashed var(--line); background: var(--card); align-items: flex-start; touch-action: pan-y; will-change: transform; }
.notif-row-del { margin-left: auto; align-self: center; background: none; border: none; color: var(--ink-3); cursor: pointer; padding: 6px; flex: none; line-height: 0; border-radius: 6px; }
.notif-row-del:hover { color: var(--danger); background: var(--danger-soft); }

/* ── Fiche fournisseur : formulaire 2 colonnes (desktop) + sections + toggles propres ── */
.fn-form { grid-template-columns: 1fr 1fr; gap: 15px 18px; align-items: start; }
.fn-form .span2 { grid-column: 1 / -1; }
.fn-sec { grid-column: 1 / -1; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); font-weight: 700; padding-bottom: 6px; border-bottom: 1px solid var(--line); margin-top: 8px; }
.fn-toggle { display: flex; align-items: flex-start; gap: 11px; padding: 11px 13px; border: 1px solid var(--line-2); border-radius: 9px; background: var(--bg-2); cursor: pointer; }
.fn-toggle:hover { border-color: var(--line); }
.fn-toggle input[type="checkbox"] { width: 17px; height: 17px; margin-top: 1px; flex: none; }
.fn-toggle-body { display: flex; flex-direction: column; gap: 2px; }
.fn-toggle-t { font-size: 13.5px; color: var(--ink); font-weight: 500; }
.fn-toggle .hint { font-size: 11.5px; color: var(--ink-3); line-height: 1.45; }
.fn-toggle.is-locked { opacity: .55; }
@media (max-width: 640px) { .fn-form { grid-template-columns: 1fr; } }

/* ── Onglet Produits de la fiche fournisseur ── */
.fnp-row { display: grid; grid-template-columns: 1fr auto auto; gap: 14px; align-items: center; padding: 10px 14px; border-bottom: 1px solid var(--line); }
.fnp-row:last-child { border-bottom: none; }
.fnp-row.clickable { cursor: pointer; transition: background .12s; }
@media (hover: hover) { .fnp-row.clickable:hover { background: var(--bg-2); } }

/* ── Colonne Stock fusionnée (barre niveau + seuil + en attente) ── */
.stk-merged { vertical-align: middle; padding-top: 6px; padding-bottom: 6px; }
.sbar-wrap { position: relative; margin-top: 13px; }
.sbar-flag { position: absolute; top: -12px; font-size: 9px; color: var(--ink-3); white-space: nowrap; pointer-events: none; }
.sbar-trk { position: relative; height: 9px; border-radius: 5px; background: #E9E7E0; }
.sbar-fill { position: absolute; left: 0; top: 0; bottom: 0; }
.sbar-att { position: absolute; top: 0; bottom: 0; border-radius: 0 5px 5px 0; background: repeating-linear-gradient(45deg, #4C8DF0 0 3px, #C7DDF7 3px 7px); }
.sbar-tick { position: absolute; top: -3px; bottom: -3px; width: 2px; background: #2C2A27; border-radius: 1px; }
.sbar-ax { position: relative; height: 14px; font-size: 9.5px; margin-top: 3px; }
.sbar-cur { position: absolute; color: var(--ink); font-weight: 600; white-space: nowrap; }
.sbar-mn { position: absolute; color: var(--ink-3); white-space: nowrap; }
.sbar-at { position: absolute; right: 0; color: #2F6FB0; font-weight: 500; white-space: nowrap; }

/* ============================================================
   Fix débordement horizontal des modals de réception sur mobile (2026-07-11)
   - Table « Articles reçus » (vue réception sans commande) rendue responsive.
   - Noms d'articles longs (MarketMan, sans espace) forcés à revenir à la ligne
     pour ne plus élargir le modal (« flotte droite/gauche »).
   ============================================================ */
/* Récap réception — tableau aligné (desktop). Colonnes : Article · Qté · Prix · Total.
   Dans Qté : nombre de CONDITIONNEMENT à gauche, nombre d'UNITÉ à droite (l'unité collée au nombre). */
/* Récap réception — vue « C1 » (ordi ET mobile, disposition identique) :
   ligne 1 = pastille · nom (+ flèche fiche collée) · TOTAL à droite ;
   ligne 2 = équivalent unités (vert) · prix /pack + prix /unité empilés SOUS le total. */
/* Colonne pastille à largeur FIXE → tous les noms démarrent à la même verticale. */
.recepv-line { display: grid; grid-template-columns: 64px minmax(0,1fr) auto; column-gap: 12px; row-gap: 3px;
  grid-template-areas: "chip name tt" "eq name pr"; padding: 10px 0; border-bottom: 1px dashed var(--line); font-size: 13px; }
.rvc-chip { grid-area: chip; align-self: start; justify-self: end; display: inline-flex; align-items: center; gap: 5px; justify-content: center;
  background: var(--accent-soft); border: 1px solid #e6cdb9; border-radius: 9px; padding: 4px 8px; }
.rvc-chip .mult { font-family: 'Inter Tight', ui-monospace, monospace; font-weight: 700; font-size: 13.5px; color: var(--accent); line-height: 1; }
.rvc-chip .box { font-size: 11px; color: var(--accent); opacity: .82; }
.rvc-chip.solo { background: var(--ok-soft); border-color: #bfe2cb; }
.rvc-chip.solo .mult { color: var(--ok); }
.rvc-name { grid-area: name; align-self: start; min-width: 0; overflow-wrap: break-word; font-weight: 500; font-size: 14.5px; line-height: 1.25; }
.rvc-name .lr-go { white-space: nowrap; }   /* flèche jamais coupée du nom */
.rvc-eq { grid-area: eq; align-self: start; justify-self: end; white-space: nowrap; color: var(--ok); font-weight: 600; font-size: 11px; }   /* équivalence stock SOUS la pastille, alignée à droite */
.rvc-tt { grid-area: tt; align-self: center; text-align: right; white-space: nowrap; font-weight: 700; font-size: 14px; }
.rvc-pr { grid-area: pr; align-self: start; text-align: right; white-space: nowrap; line-height: 1.3; }
.rvc-pr .pk { display: block; font-size: 12px; font-weight: 600; }
.rvc-pr .un { display: block; font-size: 11px; color: var(--ink-3); }
@media (max-width: 640px) { .rvc-tt { font-size: 15px; } }   /* total +1pt sur mobile */
/* break-word (et NON anywhere) : ne coupe un mot QUE s'il est trop long pour la colonne,
   sans casser les mots courts comme « Beurre ». */
.recep-line-title, .recep-line-sub, .cmp-prod-title, .cmp-prod-sub { overflow-wrap: break-word; }
/* Champ date iOS : le contrôle natif garde une largeur intrinsèque qui déborde du modal ;
   -webkit-appearance:none + reset de la valeur interne le force à respecter width:100%. */
.modal input[type="date"] { -webkit-appearance: none; appearance: none; text-align: left; width: 100%; min-width: 0; max-width: 100%; box-sizing: border-box; }
.modal input[type="date"]::-webkit-date-and-time-value { text-align: left; margin: 0; min-width: 0; }
@media (max-width: 640px) {
  /* Filet : coupe uniquement les mots TROP LONGS (pas les mots courts) */
  .modal-body { overflow-wrap: break-word; }
}

/* ============================================================
   Popup de MISE À JOUR FORCÉE (bloquant) — 2026-07-11
   ============================================================ */
#updateOverlay {
  position: fixed; inset: 0; z-index: 100000;
  background: rgba(30, 28, 25, .55);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center; padding: 24px;
  animation: fadeIn .2s var(--ease, ease);
}
#updateOverlay .update-card {
  background: var(--card, #fff); border-radius: 16px; padding: 28px 24px;
  max-width: 340px; width: 100%; text-align: center;
  box-shadow: 0 24px 64px rgba(0, 0, 0, .32);
}
#updateOverlay h3 { margin: 12px 0 6px; font-size: 19px; }
#updateOverlay p { color: var(--ink-2, #5a564e); font-size: 14px; line-height: 1.5; margin: 0 0 18px; }
#updateOverlay .btn { width: 100%; justify-content: center; min-height: 46px; }

/* ============================================================
   Écran « RÉSEAU NON DISPONIBLE » (hors ligne) — bloquant, 2026-07-16
   Au-dessus des toasts (99999) : sans réseau, c'est LE message à voir.
   ============================================================ */
#netOffline {
  position: fixed; inset: 0; z-index: 100001;
  background: rgba(30, 28, 25, .55);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center; padding: 24px;
  animation: fadeIn .2s var(--ease, ease);
}
#netOffline .net-card {
  background: var(--card, #fff); border-radius: 16px; padding: 28px 24px;
  max-width: 340px; width: 100%; text-align: center;
  box-shadow: 0 24px 64px rgba(0, 0, 0, .32);
}
#netOffline .net-ico { display: flex; justify-content: center; color: var(--mimosa, #d69e2e); }
#netOffline h3 { margin: 12px 0 6px; font-size: 19px; }
#netOffline p { color: var(--ink-2, #5a564e); font-size: 14px; line-height: 1.5; margin: 0 0 18px; }
#netOffline .btn { width: 100%; justify-content: center; min-height: 46px; }
#netOffline .net-hint { font-size: 12px; color: var(--ink-3, #8a857c); margin-top: 10px; min-height: 15px; }

/* Suggestion de fusion directement dans la carte d'un nouvel article (2026-07-11) */
.na-suggest {
  display: flex; align-items: center; gap: 8px;
  margin-top: 10px; padding: 8px 10px;
  background: var(--accent-soft, #f3ede2); border: 1px solid var(--line-2, #d8d4cc);
  border-radius: 10px; font-size: 12.5px;
}
.na-suggest .na-suggest-txt { flex: 1 1 auto; min-width: 0; color: var(--ink-2, #5a564e); line-height: 1.35; overflow-wrap: break-word; }
.na-suggest .na-suggest-txt strong { color: var(--ink, #2c2a27); }
.na-suggest .na-suggest-btn { flex: 0 0 auto; }

/* Sécurité mobile : le sélecteur de quantité prend sa largeur de contenu et s'aligne à droite
   (ne s'étire jamais sur toute la colonne, même si le nom d'article est court/coupé). */
@media (max-width: 640px) {
  .recep-line .qte-stepper, .recep-line-cmd .qte-stepper { justify-self: end; }
}

/* ============================================================
   Ligne d'article — édition réception (option A : prix/u à gauche, quantité à droite)
   Quantité bien visible (centaines/milliers), 2026-07-11
   ============================================================ */
.recep-line2 { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 12px; margin-bottom: 9px; }
.recep-line2 .rl2-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.recep-line2 .recep-line-product { min-width: 0; }
.recep-line2 .recep-line-title { font-size: 14px; font-weight: 500; line-height: 1.25; overflow-wrap: break-word; }
.recep-line2 .recep-line-sub { font-size: 11px; color: var(--ink-3); margin-top: 2px; }
.recep-line2 .recep-line-remove { flex: 0 0 26px; width: 26px; height: 26px; border-radius: 50%; border: 1px solid var(--line); background: transparent; color: var(--ink-3); display: grid; place-items: center; padding: 0; }
.recep-line2 .recep-line-remove:active { background: var(--danger-soft); color: var(--danger); }
.recep-line2 .rl2-div { height: 1px; background: var(--line-2); margin: 9px 0; }
/* Prix (gauche, largeur fixe) · Quantité (droite, sélecteur compact calé à droite) */
.recep-line2 .rl2-fields { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.recep-line2 .rl2-price, .recep-line2 .rl2-priceu { flex: 0 0 84px; width: 84px; }
.recep-line2 .rl2-qty { flex: 1 1 120px; min-width: 0; }
.recep-line2 .rl2-qty .rl2-flab { text-align: right; }
.recep-line2 .rl2-flab { font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-3); font-weight: 700; margin-bottom: 5px; }
/* Prix : petite boîte encadrée (comme le mockup) */
.recep-line2 .prix-input2 { display: flex; align-items: center; height: 36px; border: 1px solid var(--line); border-radius: 9px; padding: 0 10px; background: var(--card); }
.recep-line2 .prix-input2 input[type="number"] { flex: 1 1 auto; min-width: 0; width: 100%; border: none; background: transparent; font-size: 15px; font-weight: 600; text-align: left; padding: 0; min-height: 0; }
.recep-line2 .prix-input2 .rl2-cur { color: var(--ink-3); margin-left: 6px; flex: 0 0 auto; }
/* Quantité : AUCUN cadre — 2 boutons ronds serrés autour du nombre (jamais > qq centaines) */
.recep-line2 .qte-stepper2 { display: flex; align-items: center; justify-content: flex-end; gap: 6px; height: 36px; }
.recep-line2 .qte-step-btn2 { flex: 0 0 32px; width: 32px; height: 32px; border-radius: 50%; background: var(--bg-2); border: 1px solid var(--line); color: var(--ink-2); font-size: 18px; font-weight: 500; display: grid; place-items: center; }
.recep-line2 .qte-step-btn2.plus { color: var(--ok); }
.recep-line2 .qte-step-btn2:active { background: var(--line); }
.recep-line2 .qte-stepper2 input[type="number"] { flex: 0 0 52px; width: 52px; min-width: 0; text-align: center; border: none; background: transparent; font-size: 15px; font-weight: 600; padding: 0; min-height: 0; color: var(--ink); }
.recep-line2 .rl2-total { display: flex; justify-content: space-between; align-items: baseline; }
.recep-line2 .rl2-totlab { font-size: 12px; color: var(--ink-3); }
.recep-line2 .rl2-totval { font-size: 15px; font-weight: 700; }

/* Pastille conditionnement « 2× 39 » réutilisable (récap commande, ligne de commande…) — devant le nom. */
.line-chip { display: inline-flex; align-items: center; gap: 5px; vertical-align: middle; margin-right: 6px; background: var(--accent-soft); border: 1px solid #e6cdb9; border-radius: 9px; padding: 4px 8px; }
.line-chip .mult { font-family: 'Inter Tight', ui-monospace, monospace; font-weight: 700; font-size: 13.5px; color: var(--accent); line-height: 1; }
.line-chip .box { font-size: 11px; color: var(--accent); opacity: .82; }
.line-chip.solo { background: var(--ok-soft); border-color: #bfe2cb; }
.line-chip.solo .mult { color: var(--ok); }

/* Fiche fournisseur : bouton supprimer dans le coin bas-droite (ordi ; mobile = swipe) */
.sup-fiche-card .sup-fiche-del { position: absolute; bottom: 8px; right: 10px; }

/* « Ajouter fiche fournisseur » : très légèrement plus grand sur mobile (cible tactile) */
@media (max-width: 840px) {
  .sup-add-fiche { padding: 6px 13px; font-size: 12.5px; }
}

/* Carte « résumé commande » (option 1) — pastille + nom générique/fournisseur + équivalent unités ;
   badge stock actuel + sélecteur à droite ; prix /pack & /u en INFO seule (fiche) sur la rangée du bas. */
.cmd-card { background: var(--card); border: 1px solid var(--line); border-radius: 13px; padding: 11px 12px; margin-bottom: 10px; }
.cmd-card .cc-r1 { display: flex; align-items: flex-start; gap: 10px; }
.cmd-card .cc-chipw { flex: 0 0 64px; display: flex; flex-direction: column; align-items: flex-end; gap: 3px; }   /* pastille EN HAUT (droite) + équivalence stock DESSOUS */
.cmd-card .cc-chipw .line-chip { margin-right: 0; }   /* aligne le bord droit de la pastille avec l'équivalence dessous */
.cmd-card .cc-mid { flex: 1; min-width: 0; }
.cmd-card .cc-name { font-size: 13.5px; font-weight: 600; line-height: 1.25; overflow-wrap: break-word; }
.cmd-card .cc-name .lr-go { white-space: nowrap; }
.cmd-card .cc-supp { font-size: 11.5px; color: var(--ink-2); margin-top: 2px; line-height: 1.2; }
.cmd-card .cc-eq { color: var(--ok); font-weight: 600; font-size: 11px; white-space: nowrap; }
.cmd-card .cc-rcol { display: flex; flex-direction: column; align-items: flex-end; gap: 7px; flex: 0 0 auto; }
.cmd-card .cc-rcol .cmd-stock-pill, .cmd-card .cc-rcol .cmd-stock-pills { margin: 0; }
.cmd-card .cc-r2 { display: flex; align-items: center; gap: 8px; margin-top: 9px; border-top: 1px dashed var(--line); padding-top: 8px; }
.cmd-card .cc-pinfo { font-size: 11px; color: var(--ink-3); font-variant-numeric: tabular-nums; padding-left: 74px; }   /* aligné sous le nom (colonne pastille 64px + gap 10px) */
@media (max-width: 640px) {
  .cmd-card .cc-chipw { flex: 0 0 54px; }   /* colonne pastille plus étroite sur mobile */
  .cmd-card .cc-pinfo { padding-left: 64px; }   /* reste aligné sous le nom (54 + gap 10) */
}
.cmd-card .cc-pinfo b { color: var(--ink-2); font-weight: 600; }
.cmd-card .cc-tot { margin-left: auto; font-weight: 700; font-size: 15px; white-space: nowrap; }

/* Flèche « aller à la fiche produit » — même ↗ que le lien sous-recette/ingrédient dans une recette.
   Elle est déjà en couleur accent au repos : un survol qui ne change QUE la couleur ne se voit pas
   (l'ancienne règle `:hover { color: var(--accent) }` ne faisait donc rien). L'affordance passe par une
   pastille de fond, comme les badges et la nav active. */
.lr-go { display: inline-flex; align-items: center; justify-content: center; padding: 2px 4px; border: none; background: transparent; color: var(--accent); font-size: 13px; line-height: 1; cursor: pointer; margin-left: 4px; vertical-align: baseline; border-radius: 6px; transition: background-color 120ms ease, transform 120ms ease; }
/* hover:hover → pas de survol « collé » après un tap sur mobile */
@media (hover: hover) {
  .lr-go:hover { background: var(--accent-soft); }
}
.lr-go:active { background: var(--accent-soft); transform: translateY(1px); }
.lr-go:focus-visible { background: var(--accent-soft); outline: 2px solid var(--accent); outline-offset: 1px; }
@media (prefers-reduced-motion: reduce) { .lr-go { transition: none; } }
.recep-line2 .rl2-head-actions { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.recep-line2 .rl2-head-actions .lr-go { font-size: 16px; padding: 4px 6px; }

/* ── Carte d'édition compacte (recEditCard) : réception manuelle + « Modifier la réception ».
   Ligne 1 = pastille conditionnement · nom (+↗) / équivalent unités (vert) · stepper · corbeille(ordi).
   Ligne 2 = « Prix » · prix/pack · prix/unité · total. Swipe-gauche = supprimer (mobile). */
.recep-line3 { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 11px 12px; margin-bottom: 9px; }
.recep-line3.has-ecart { border-color: #e6b98f; background: #fdf6ef; }
.recep-line3 .rl3-top { display: flex; align-items: flex-start; gap: 10px; }   /* haut alignés : pastille sur la même ligne que le nom */
/* Slot pastille à largeur FIXE → les noms démarrent à la même verticale (la pastille, elle, épouse « 2× 39 »). */
.recep-line3 .rl3-chipwrap { flex: 0 0 64px; display: flex; flex-direction: column; align-items: flex-end; gap: 3px; }   /* pastille EN HAUT + équivalence stock DESSOUS, alignées à DROITE (collées au nom) */
.recep-line3 .rl3-chip { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px; justify-content: center; background: var(--accent-soft); border: 1px solid #e6cdb9; border-radius: 9px; padding: 4px 8px; }
.recep-line3 .rl3-chip .mult { font-family: 'Inter Tight', ui-monospace, monospace; font-weight: 700; font-size: 13.5px; color: var(--accent); line-height: 1; }
.recep-line3 .rl3-chip .box { font-size: 11px; color: var(--accent); opacity: .82; }
.recep-line3 .rl3-chip.solo { background: var(--ok-soft); border-color: #bfe2cb; }
.recep-line3 .rl3-chip.solo .mult { color: var(--ok); font-family: 'Inter Tight', ui-monospace, monospace; font-weight: 700; font-size: 13.5px; }
.recep-line3 .rl3-name { flex: 1 1 auto; min-width: 0; }
.recep-line3 .rl3-title { font-size: 14.5px; font-weight: 600; line-height: 1.25; overflow-wrap: break-word; }
.recep-line3 .rl3-title .lr-go { white-space: nowrap; font-size: 15px; color: var(--accent); margin-left: 0; }
/* Bouton « détacher → nouveau produit » : icône neutre (secondaire) à côté de la flèche fiche (accent). */
.recep-line3 .rl3-title .lr-new { color: var(--ink-3); font-size: 13px; }
.recep-line3 .rl3-eq { color: var(--ok); font-weight: 600; font-size: 11px; white-space: nowrap; }
.recep-line3 .rl3-step { flex: 0 0 auto; }
.recep-line3 .rl3-del { flex: 0 0 30px; width: 30px; height: 30px; border-radius: 50%; border: 1px solid var(--line); background: transparent; color: var(--ink-3); display: grid; place-items: center; padding: 0; cursor: pointer; }
.recep-line3 .rl3-del:hover, .recep-line3 .rl3-del:active { background: var(--danger-soft); color: var(--danger); }
.recep-line3 .rl3-bot { display: flex; align-items: center; gap: 8px; margin-top: 10px; flex-wrap: wrap; padding-left: 74px; }   /* ordi : « Prix » aligné sous le nom (largeur pastille 64px + gap 10px) */
.recep-line3 .rl3-plab { flex: 0 0 auto; font-size: 10px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); font-weight: 700; }
/* Cadre prix à taille FIXE (juste de quoi contenir « 1000,00 ») → le total tient sur la même ligne.
   Le nombre est aligné à droite pour être COLLÉ au signe € qui le suit. */
.recep-line3 .rl3-price { flex: 0 0 auto; display: flex; align-items: center; height: 34px; border: 1px solid var(--line); border-radius: 9px; padding: 0 9px; background: var(--card); }
.recep-line3 .rl3-price input[type="number"] { flex: 0 0 auto; width: 54px; text-align: right; border: none; background: transparent; font-size: 14px; font-weight: 600; padding: 0; min-height: 0; }
.recep-line3 .rl3-price .suf { flex: 0 0 auto; color: var(--ink-3); font-size: 11px; white-space: nowrap; padding-left: 2px; }
.recep-line3 .rl3-price.field-ecart { border-color: var(--accent); background: #fdeee6; }
.recep-line3 .rl3-total { flex: 1 1 auto; text-align: right; font-size: 15px; font-weight: 700; white-space: nowrap; }
/* stepper compact (recEditCard) */
.recep-line3 .qte-stepper2 { display: flex; align-items: center; justify-content: flex-end; gap: 5px; height: 34px; }
.recep-line3 .qte-step-btn2 { flex: 0 0 30px; width: 30px; height: 30px; border-radius: 50%; background: var(--bg-2); border: 1px solid var(--line); color: var(--ink-2); font-size: 17px; font-weight: 500; display: grid; place-items: center; cursor: pointer; }
.recep-line3 .qte-step-btn2.plus { color: var(--ok); }
.recep-line3 .qte-step-btn2:active { background: var(--line); }
.recep-line3 .qte-stepper2 input[type="number"] { flex: 0 0 42px; width: 42px; min-width: 0; text-align: center; border: none; background: transparent; font-size: 15px; font-weight: 600; padding: 0; min-height: 0; color: var(--ink); }
.recep-line3 .qte-stepper2.field-ecart { outline: 1.5px solid var(--accent); outline-offset: 2px; border-radius: 20px; }
.recep-line3 .recep-ecart-note { margin-top: 9px; }
@media (max-width: 840px) {
  .recep-line3 .rl3-del { display: none; }   /* mobile : swipe pour supprimer */
  .recep-line3 .rl3-plab { display: none; }  /* mobile : masque « Prix » → gagne de la place, total sur la même ligne */
  .recep-line3 .rl3-bot { padding-left: 0; } /* mobile : pas d'indentation (place limitée) */
}

/* ── Croix (✕) de reset dans les champs de recherche (type="search") ───────────
   Native webkit : le pseudo-élément apparaît dès qu'il y a du texte (Safari iOS + Chrome).
   On remplace le rendu par défaut par une ✕ plate maison (cohérente avec icon()).
   Le clic vide le champ ET émet un événement 'input' → les listes filtrées se réinitialisent. */
input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  height: 18px;
  width: 18px;
  margin-left: 6px;
  cursor: pointer;
  border-radius: 50%;
  background: var(--line, #e6e2da) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cg stroke='%23847d70' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M6 6l8 8M14 6l-8 8'/%3E%3C/g%3E%3C/svg%3E") center / 12px 12px no-repeat;
  opacity: .75;
}
input[type="search"]::-webkit-search-cancel-button:hover { opacity: 1; }
/* Firefox n'a pas de bouton natif ; les champs restent fonctionnels (croix absente). */

/* Food Cost — tuiles d'impact des offerts (Option A) sous la carte FC théo/réel/écart */
.fc-off-tiles { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); display: grid; grid-template-columns: repeat(4, 1fr); }
.fc-off-tiles .fot { text-align: center; padding: 0 6px; }
.fc-off-tiles .fot + .fot { border-left: 1px solid var(--line); }
.fc-off-tiles .fov { font-size: 20px; line-height: 1.15; }
.fc-off-tiles .fok { font-size: 10px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); margin-top: 3px; font-weight: 600; }
@media (max-width: 560px) {
  .fc-off-tiles { grid-template-columns: repeat(2, 1fr); row-gap: 14px; }
  .fc-off-tiles .fot:nth-child(3) { border-left: 0; }
}

/* ============================================================
   Journal de bord (Paramètres › Journal) — 2026-07-16
   Une ligne = une action. Le diff avant→après est l'information centrale :
   il doit se lire d'un coup d'œil, sans déplier quoi que ce soit.
   ============================================================ */
.jnl-row { padding: 10px 13px; margin-bottom: 6px; }
.jnl-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.jnl-obj { font-size: 13px; }
.jnl-meta { font-size: 11.5px; margin-left: auto; white-space: nowrap; }
.jnl-chg { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; margin-top: 5px; font-size: 12px; }
.jnl-col { color: var(--ink-3); min-width: 130px; }
.jnl-old { color: var(--ink-3); text-decoration: line-through; }
.jnl-arrow { color: var(--ink-3); }
.jnl-new { color: var(--ink); font-weight: 600; }

@media (max-width: 560px) {
  /* La date passe sous le titre : sur un écran étroit, « quoi » prime sur « quand ». */
  .jnl-meta { margin-left: 0; width: 100%; white-space: normal; }
  .jnl-col { min-width: 0; font-weight: 500; }
  .jnl-chg { gap: 4px; }
}

/* ============================================================
   Mapping — largeur FIXE du filtre catégorie (2026-07-18)
   `.ms-filter` n'a qu'un `min-width` : le bouton résumé s'adapte au libellé sélectionné, donc la barre
   se réagençait à chaque choix (« Toutes catégories » → « Vins » = saut de largeur). On fige la largeur
   pour que rien ne bouge, et on tronque proprement les libellés longs.
   ============================================================ */
.vt-cat-fixed { display: inline-block; width: 200px; flex: 0 0 200px; }
.vt-cat-fixed > .ms-filter { width: 100%; min-width: 0; }
.vt-cat-fixed .ms-dd-summary > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

@media (max-width: 840px) {
  /* Mobile : le filtre prend la largeur dispo (la barre passe en colonnes), mais garde une base stable. */
  .vt-cat-fixed { width: auto; flex: 1 1 160px; min-width: 0; }
}

/* ============================================================
   Bouton « Ajouter un ingrédient » — noir, un cran plus grand (2026-07-18)
   Action principale des éditeurs recette ET sous-recette : elle doit se distinguer de l'accent orange
   utilisé partout ailleurs (Enregistrer, Réceptionner…), sans devenir criarde.
   ============================================================ */
.btn-ink { background: var(--ink); color: #fff; border-color: var(--ink); }
.btn-ink:hover { background: #322e29; border-color: #322e29; }
.er-add { min-height: 36px; padding: 0 15px; font-size: 13.5px; }
.er-add svg { width: 15px; height: 15px; }

/* ============================================================
   Onglets de modal FIXES en haut (2026-07-18)
   `.modal-body` est le conteneur de défilement ; les `.tabs` défilaient donc avec le contenu et
   disparaissaient dès qu'on descendait dans une recette longue. On les colle en haut du corps du modal.
   Le fond opaque + les marges négatives évitent que le contenu transparaisse sur les côtés en glissant
   dessous (le corps a 20px/24px de padding).
   ============================================================ */
/* ⚠ `top` DOIT ÉGALER LA MARGE HAUTE NÉGATIVE (user 2026-07-20).
   Le collage se calcule sur la BOÎTE DE MARGE, pas sur la boîte de bordure. Avec `top: 0` et
   `margin-top: -20px`, les onglets étaient 20 px plus haut au repos qu'une fois collés : dès le
   premier défilement, la barre redescendait de 20 px et venait recouvrir le premier champ du
   formulaire. C'est cette marche de 20 px qu'on percevait comme « une bande au-dessus des onglets ».
   En posant `top: -20px`, la position au repos et la position collée coïncident : plus de saut.
   Le `padding-top` égale lui aussi la marge : il fournit le fond opaque qui masque le contenu
   passant dessous, sur toute la hauteur du padding du corps de modal. */
.modal-body > .tabs {
  position: sticky;
  top: -20px;
  z-index: 5;
  background: var(--card);
  margin: -20px -24px 16px;
  padding: 20px 24px 0;
}
@media (max-width: 840px) {
  /* le corps du modal passe à `padding: 12px 16px 88px` sur mobile → marge, top et padding suivent */
  .modal-body > .tabs { top: -12px; margin: -12px -16px 14px; padding: 12px 16px 0; }
}

/* ============================================================
   Bouton « occupé » — retour immédiat au clic (2026-07-18)
   Les actions de modal enchaînent plusieurs requêtes : sans signal, l'utilisateur reclique.
   Le clic est neutralisé (pointer-events) ET le bouton s'assombrit, avec un petit rond qui tourne.
   ============================================================ */
.btn.is-busy { pointer-events: none; opacity: .72; position: relative; color: transparent !important; }
.btn.is-busy > * { visibility: hidden; }
.btn.is-busy::after {
  content: ""; position: absolute; top: 50%; left: 50%;
  width: 15px; height: 15px; margin: -7.5px 0 0 -7.5px;
  border: 2px solid currentColor; border-top-color: transparent; border-radius: 50%;
  color: #fff; animation: btnSpin .6s linear infinite;
}
/* Boutons clairs (fond blanc) : le rond doit rester visible */
.btn.is-busy:not(.btn-accent):not(.btn-ink):not(.btn-danger)::after { color: var(--ink-2); }
@keyframes btnSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .btn.is-busy::after { animation: none; } }

/* ============================================================
   Éditeur de recette / sous-recette sur MOBILE — maquette A (2026-07-18)
   Problème : il fallait traverser tout le formulaire (nom, catégorie, portions, prix, cible FC)
   avant d'atteindre les INGRÉDIENTS, qui sont le vrai travail.
   Réponse : les informations se replient derrière une bande, et les KPI (coût / food cost)
   restent collés en haut pendant qu'on fait défiler et qu'on saisit les quantités.
   ============================================================ */
.er-info-toggle { display: none; }          /* ordi : pas de bande, les champs sont toujours dépliés */
/* Ce conteneur (ajouté pour le repli mobile) sortait les champs de la grille parente : ils
   se retrouvaient collés, chaque libellé touchant le champ du dessus. Il reprend donc le
   même rythme vertical que .form-grid. */
.er-info-fields { display: grid; row-gap: 20px; column-gap: 14px; }
.er-kpi-pv { display: none; }               /* ordi : le prix de vente est déjà lisible dans son champ */
.er-ing-count { display: none; }            /* ordi : l'entête de colonnes suffit, pas de compteur */
.er-add-short { display: none; }            /* ordi : libellé long « Ajouter un ingrédient » */
.er-allerg-m { display: none; }             /* ordi : les allergènes restent la 3ᵉ carte KPI */

@media (max-width: 840px) {
  .er-info-toggle {
    display: flex; align-items: center; gap: 8px; width: 100%;
    background: var(--bg-2); border: none; border-radius: 9px;
    padding: 10px 12px; margin: 0 0 11px; font: inherit; font-size: 12.5px;
    color: var(--ink); text-align: left; cursor: pointer;
  }
  .er-info-toggle .eit-t { font-weight: 500; white-space: nowrap; }
  .er-info-toggle .eit-s {
    color: var(--ink-3); margin-left: auto; font-size: 11.5px;
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .er-info-toggle .eit-c { color: var(--ink-3); transition: transform 160ms ease; }
  .er-info-toggle[aria-expanded="true"] .eit-c { transform: rotate(180deg); }
  .er-info-toggle[aria-expanded="true"] .eit-s { display: none; }   /* déplié : le résumé fait doublon */
  .er-info-fields.is-folded { display: none; }

  /* Les KPI passent EN TÊTE (order) et se collent en haut : le coût et le food cost restent
     sous les yeux pendant toute la saisie. La bande d'informations vient juste après. */
  .grid.er-kpis {
    order: -1;
    position: sticky; top: 0; z-index: 3;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 6px !important;
    background: var(--card); margin: 0 -16px 11px !important; padding: 8px 16px 10px;
    border-bottom: 1px solid var(--line);
  }
  .er-kpis .kpi:last-child { display: none; }   /* allergènes → sortis du bandeau, cf. .er-allerg-m */
  .er-allerg-m {
    order: -1;                                  /* juste sous le bandeau, avant la bande d'infos */
    display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 8px;
    margin: -4px 0 2px; font-size: 12px;
  }
  .er-allerg-m-lbl {
    font-size: 9px; letter-spacing: .05em; text-transform: uppercase;
    color: var(--ink-3); font-weight: 600;
  }
  /* Le corps de modal a un padding haut : sans ça, les champs défilent dans cette bande
     de quelques pixels au-dessus des KPI collés. Le débord est rogné par l'overflow. */
  .er-kpis::before {
    content: ''; position: absolute; left: 0; right: 0; top: -24px; height: 24px;
    background: var(--card);
  }
  .er-kpi-pv { display: block; }
  .er-kpis .kpi {
    padding: 7px 8px !important; text-align: center;
    background: var(--bg-2); border-color: transparent; border-radius: 9px;
  }
  .er-kpis .kpi-label { font-size: 9px !important; letter-spacing: .05em; }
  .er-kpis .kpi-value { font-size: 17px !important; margin-top: 1px; }
  .er-kpis #erAllergKpi { margin-top: 3px !important; line-height: 1.5; }

  /* Entête « n INGRÉDIENTS » + bouton d'ajout réduit à une pastille : sur mobile un bouton
     pleine largeur écrasait le compteur et poussait les ingrédients hors de l'écran. */
  .er-ing-count { display: inline; }
  .er-add-long { display: none; }
  .er-add-short { display: inline; }
  .er-add { min-height: 34px; padding: 0 12px; font-size: 12.5px; }

  /* Pas d'entête de colonnes : elle ne veut plus rien dire dès que la ligne tient sur 2 rangées. */
  .er-lhead { display: none; }

  /* Ligne d'ingrédient sur 2 rangées :
       rangée 1 — le nom (en entier, il peut passer à la ligne) et le COÛT aligné à droite ;
       rangée 2 — la quantité, l'unité, puis la suppression tout à droite.
     Les zones sont assignées explicitement : l'ordre du balisage (nom, qté, unité, coût, suppr)
     ne correspond pas à l'ordre d'affichage. */
  .er-lrow {
    grid-template-columns: 66px auto 1fr auto;
    grid-template-areas:
      "nom   nom   nom cout"
      "qte   unite .   suppr";
    gap: 7px 8px; padding: 11px 0;
  }
  .er-lrow > :nth-child(1) { grid-area: nom; display: flex; align-items: flex-start; gap: 8px; }
  .er-lrow > :nth-child(2) { grid-area: qte; justify-self: start; width: 100%; }
  .er-lrow > :nth-child(3) { grid-area: unite; justify-self: start; max-width: 118px; }
  .er-lrow > :nth-child(4) { grid-area: cout; align-self: flex-start; white-space: nowrap; }
  .er-lrow > :nth-child(5) { grid-area: suppr; justify-self: end; }
  .er-lrow input[type="number"] { height: 34px; font-size: 13px; }
  .er-lrow select { height: 34px; }

  /* Le nom redevient du TEXTE : sur mobile, une boîte bordée par ingrédient faisait un mur
     de champs. L'icône d'échange reste, c'est elle qui signale qu'on peut le remplacer. */
  .er-lrow .er-ing {
    min-height: 32px; padding: 0; border: none; background: none;
    align-items: flex-start; justify-content: flex-start; gap: 7px;
  }
  .er-lrow .er-ing:hover { border-color: transparent; }
  .er-lrow .er-ing .er-ing-nom {
    white-space: normal; overflow: visible; text-overflow: clip;
    align-items: flex-start; line-height: 1.3;
  }
  .er-lrow .er-ing > svg:last-child { margin-top: 3px; }

  /* Suppression discrète : un bouton rouge par ligne braquait l'œil sur l'action destructrice. */
  .er-lrow .btn-danger {
    background: none; border: none; color: var(--ink-3);
    min-height: 32px; min-width: 30px; font-size: 17px; line-height: 1; padding: 0;
  }
}

/* ============================================================
   TABLEAU DE BORD — SUIVI DE PRIX (maquette A, 2026-07-18)
   Ce qui a bougé sur la période choisie en haut, séparé Cuisine / Bar.
   La card entière disparaît quand aucun prix n'a changé : un prix stable
   n'est pas une information.
   ============================================================ */
.dash-prix { padding: 10px 18px 16px; }

/* Entete de famille : le titre porte, la moyenne le qualifie. Les deux familles doivent
   se reperer d'un coup d'oeil — c'est l'axe de lecture de la card. */
.dp-fam { display: flex; align-items: baseline; gap: 12px; margin: 22px 0 8px; }
.dp-fam:first-child { margin-top: 8px; }
.dp-fam-n {
  font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink);
}
.dp-fam-moy { font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; }
.dp-fam-moy.up { color: var(--danger); }
.dp-fam-moy.dn { color: var(--ok); }
.dp-fam-l { flex: 1; height: 1px; background: var(--line); }
.dp-fam-c { font-size: 11px; color: var(--ink-3); font-variant-numeric: tabular-nums; }

.dp-row {
  display: flex; align-items: center; gap: 16px;
  padding: 11px 0; font-size: 13px; cursor: pointer;
  border-bottom: 1px dashed var(--line);
  /* Le doigt qui DEFILE par-dessus ne doit ni surligner la ligne ni selectionner son texte. */
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none; user-select: none;
}
.dp-row:last-child { border-bottom: none; }
@media (hover: hover) { .dp-row:hover .dp-nom { color: var(--accent); } }
.dp-nom { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.dp-px {
  color: var(--ink-3); font-size: 11.5px; white-space: nowrap;
  font-variant-numeric: tabular-nums; text-align: right;
}

/* Barre divergente, ordi seulement : l'ampleur et le sens se lisent sans chiffre.
   Echelle commune aux deux familles (calculee en JS) pour rester comparable. */
.dp-bar { position: relative; flex: 0 0 180px; height: 16px; }
.dp-ax { position: absolute; left: 50%; top: 0; bottom: 0; width: 1px; background: var(--line-2); }
.dp-fill { position: absolute; top: 4px; height: 8px; border-radius: 2px; min-width: 2px; }
.dp-fill.up { background: var(--danger); }
.dp-fill.dn { background: var(--ok); }
.dp-pct {
  font-variant-numeric: tabular-nums; font-weight: 600; font-size: 12px;
  padding: 3px 8px; border-radius: 5px; white-space: nowrap;
  min-width: 62px; text-align: right;
}
.dp-pct.up { background: var(--danger-soft); color: var(--danger); }
.dp-pct.dn { background: var(--ok-soft); color: var(--ok); }
.dp-vide { font-size: 11.5px; color: var(--ink-3); padding: 8px 0 2px; }
/* « Voir tout (+14) » — ouvre la liste complete de la famille. Bouton, pas texte mort :
   c'est la seule facon d'atteindre les articles masques. */
.dp-plus {
  display: block; width: 100%;
  margin-top: 6px; padding: 7px 0;
  background: none; border: none; border-radius: 6px;
  font: inherit; font-size: 11.5px; font-weight: 500;
  color: var(--accent); text-align: right; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
@media (hover: hover) { .dp-plus:hover { background: var(--bg-2); text-align: right; } }

/* Dans le popup : pas de fond de card, la liste occupe toute la largeur du modal. */
.dp-modal { padding: 0; }
.dp-modal .dp-fam:first-child { margin-top: 0; }

@media (max-width: 840px) {
  /* Le nom prend sa ligne : les noms d'articles sont longs et la variation doit rester lisible. */
  .dash-prix { padding: 4px 13px 10px; }
  .dp-row { flex-wrap: wrap; gap: 3px 10px; padding: 11px 0; }
  .dp-nom { flex-basis: 100%; white-space: normal; overflow: visible; line-height: 1.3; }
  /* Pas de barre au doigt : sur 100 px elle n'ajoutait rien que le pourcentage ne dise deja. */
  .dp-bar { display: none; }
  .dp-px { text-align: left; font-size: 11px; }
  .dp-pct { margin-left: auto; }
  .dp-fam { flex-wrap: wrap; gap: 4px 10px; margin: 18px 0 4px; }
  .dp-fam-n { font-size: 12px; }
  .dp-fam-moy { font-size: 11.5px; }
}

/* ============================================================
   SURVOL — RESERVE AU POINTEUR FIN (souris / trackpad)
   Sur ecran tactile, :hover se declenche au tap et RESTE colle : la ligne tapee garde son fond
   allume alors que le doigt est parti (signale par l'utilisateur sur l'onglet Volume d'affaire).
   L'ancien correctif neutralisait l'effet APRES COUP avec `background: inherit` — donc le fond du
   PARENT, pas celui de l'element : une recipe-card tapee perdait son fond blanc. On enferme
   desormais chaque effet decoratif dans @media (hover: hover) : au doigt il n'existe pas, et
   l'element garde son propre style. Le retour au toucher passe par :active ou par la navigation.
   Les BOUTONS gardent leur survol : leur mise en avant fait partie du retour au clic.
   ============================================================ */

/* ============================================================
   TACTILE — pas de surbrillance quand le doigt ne fait que PASSER
   (user 2026-07-18 : « éviter la surbrillance sur mobile suite à un glissé touché »)
   Trois symptômes distincts, trois remèdes — aucun ne remplace les autres :
     · halo gris/bleu au toucher      → -webkit-tap-highlight-color
     · texte surligné pendant le glissé → user-select
     · fond qui RESTE après le doigt   → :hover collant d'iOS
   ============================================================ */
* { -webkit-tap-highlight-color: transparent; }

/* La sélection n'est coupée QUE sur pointeur tactile : sur ordi, sélectionner du texte
   pour le copier reste un usage normal et on n'y touche pas. */
@media (pointer: coarse) {
  html { -webkit-user-select: none; user-select: none; }

  /* EXCEPTIONS — ce qu'on veut encore pouvoir saisir ou copier au doigt.
     (le préfixe -webkit- est obligatoire avant iOS 16.4) */
  input, textarea, select, [contenteditable="true"],
  a[href^="mailto:"], a[href^="tel:"],        /* email / téléphone fournisseur */
  .recep-meta,                                 /* n° de BL, n° de commande */
  .stk-row, .stk-row *,                        /* noms d'articles du tableau stock */
  tr.clickable, tr.clickable *,                /* tableaux de chiffres : théo / compté / écart */
  .fnp-row, .fnp-row *,                        /* références fournisseur */
  .supp-row, .supp-row *,
  .sup-fiche-card, .sup-fiche-card *,
  .fourn-card, .fourn-card *,                  /* adresse, contacts */
  .recep-line, .recep-line *,                  /* lignes de facture éditables */
  .recep-line3, .recep-line3 *,
  .inv-count-row, .inv-count-row * {           /* comptage d'inventaire */
    -webkit-user-select: text; user-select: text;
  }
}



/* ============================================================
   COMMANDE VS RÉCEPTION — disposition F (2026-07-18)
   Une section par nature d'écart, et la grammaire du récap de commande :
   pastille « packs × contenu », équivalence en unités dessous, nom + réf,
   TOTAL puis prix. Deux pastilles : commandé / reçu.
   Ce sont les deux équivalences en unités, côte à côte, qui rendent l'écart
   vérifiable — « 6 packs » face à « 90 pots » ne veut rien dire.
   ============================================================ */
.cmpf-sec {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; margin: 0 -12px;
  background: var(--bg-2);
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.cmpf-sec:first-child { border-top: none; }
.cmpf-sec-t { font-size: 10px; letter-spacing: .07em; text-transform: uppercase; font-weight: 700; }
.cmpf-sec.px .cmpf-sec-t { color: var(--mimosa-ink, #8a6a10); }
.cmpf-sec.ko .cmpf-sec-t { color: var(--danger); }
.cmpf-sec.ok .cmpf-sec-t { color: var(--ok); }

.cmpf-row {
  display: grid;
  grid-template-columns: 74px 74px minmax(0, 1fr) auto;
  column-gap: 14px; row-gap: 3px;
  grid-template-areas: "cC cR nom tt" "eC eR nom pr";
  padding: 12px 0; border-bottom: 1px dashed var(--line);
  align-items: start; font-size: 13px;
}
.cmpf-row:last-child { border-bottom: none; }
.cmpf-row.ko { background: rgba(178, 60, 51, .035); }
.cmpf-row > .cmpf-chip:nth-of-type(1) { grid-area: cC; }
.cmpf-row > .cmpf-chip:nth-of-type(2) { grid-area: cR; }
.cmpf-row > .cmpf-eq:nth-of-type(1) { grid-area: eC; }
.cmpf-row > .cmpf-eq:nth-of-type(2) { grid-area: eR; }

.cmpf-chip {
  justify-self: center; align-self: start;
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  padding: 4px 8px; border-radius: 9px;
  background: var(--accent-soft); border: 1px solid #e6cdb9;
}
.cmpf-chip .mult { font-family: 'Inter Tight', ui-monospace, monospace; font-weight: 700; font-size: 13.5px; color: var(--accent); line-height: 1; }
.cmpf-chip .box { font-size: 11px; color: var(--accent); opacity: .82; }
.cmpf-chip.rec { background: var(--ok-soft); border-color: #bfe2cb; }
.cmpf-chip.rec .mult, .cmpf-chip.rec .box { color: var(--ok); }
.cmpf-chip.man { background: var(--danger-soft); border-color: #e8c3bd; }
.cmpf-chip.man .mult, .cmpf-chip.man .box { color: var(--danger); }
.cmpf-chip.nil { background: var(--bg-2); border-color: var(--line-2); }
.cmpf-chip.nil .mult { color: var(--ink-3); opacity: .6; }

.cmpf-eq {
  justify-self: stretch; align-self: start;
  /* Pas de nowrap : « = 36 bouteille » dépassait de sa colonne et chevauchait la pastille
     voisine. On laisse passer à la ligne plutôt que de rogner l'unité. */
  white-space: normal; overflow-wrap: break-word; line-height: 1.2;
  font-weight: 600; font-size: 10.5px; text-align: center;
}
.cmpf-eq.c { color: var(--accent); }
.cmpf-eq.r { color: var(--ok); }
.cmpf-eq.k { color: var(--danger); }
.cmpf-eq.n { color: var(--ink-3); }

.cmpf-nom { grid-area: nom; align-self: center; min-width: 0; overflow-wrap: break-word; font-weight: 500; font-size: 14.5px; line-height: 1.25; }
.cmpf-ref { font-size: 10.5px; color: var(--ink-3); font-weight: 400; margin-top: 2px; }
/* Total AU-DESSUS du prix : on lit ce que pèse la ligne, puis à quel tarif. */
.cmpf-tt { grid-area: tt; align-self: start; padding-top: 2px; text-align: right; white-space: nowrap; font-weight: 700; font-size: 15px; line-height: 1.1; }
.cmpf-tt.ko { color: var(--danger); }
.cmpf-tt.px { color: var(--mimosa-ink, #8a6a10); }
.cmpf-pr { grid-area: pr; align-self: start; text-align: right; white-space: nowrap; font-size: 11.5px; line-height: 1.4; color: var(--ink-3); }
.cmpf-pr .old { text-decoration: line-through; }
.cmpf-pr .new { font-weight: 700; color: var(--ink); }
.cmpf-pr .cnd { color: var(--ink-3); font-weight: 400; }
.cmpf-note { grid-column: 3 / -1; margin-top: 6px; font-size: 11px; line-height: 1.35; color: var(--mimosa-ink, #8a6a10); background: var(--mimosa-soft); padding: 6px 9px; border-radius: 7px; }
.cmpf-fold { display: block; width: 100%; padding: 10px 0; background: none; border: none; font: inherit; font-size: 11.5px; font-weight: 500; color: var(--accent); text-align: center; cursor: pointer; -webkit-tap-highlight-color: transparent; }

@media (max-width: 840px) {
  /* Le nom prend sa ligne : les libellés fournisseur sont longs. */
  .cmpf-row {
    grid-template-columns: 62px 62px minmax(0, 1fr);
    grid-template-areas: "nom nom nom" "cC cR tt" "eC eR pr";
    column-gap: 9px; row-gap: 4px; padding: 11px 0;
  }
  .cmpf-nom { align-self: start; font-size: 13.5px; }
  .cmpf-tt { align-self: center; padding-top: 0; font-size: 14.5px; }
  .cmpf-pr { align-self: center; font-size: 11px; white-space: normal; }
  .cmpf-note { grid-column: 1 / -1; }
  .cmpf-sec { margin: 0 -10px; padding: 8px 10px; }
}
/* Bouton d'action dans une note de rapprochement */
.cmpf-go {
  margin-left: 6px; padding: 3px 9px;
  background: var(--card); border: 1px solid #e6cdb9; border-radius: 6px;
  font: inherit; font-size: 11px; font-weight: 600; color: var(--accent);
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
@media (hover: hover) { .cmpf-go:hover { background: var(--accent); color: #fff; border-color: var(--accent); } }

/* Journal : bouton d'annulation, et raison quand l'action n'est pas annulable */
.jnl-undo { margin-left: auto; flex: none; }
.jnl-undo svg { transform: rotate(180deg); }   /* la flèche pointe en arrière */
.jnl-nope { margin-left: auto; flex: none; font-size: 10.5px; font-style: italic; white-space: nowrap; }
.jnl-why { font-size: 11px; line-height: 1.35; margin-top: 6px; padding: 6px 9px; background: var(--bg-2); border-radius: 7px; }

/* ── Ligne de DÉTAIL du comparatif ───────────────────────────────────────────
   Une ligne de facture = une ligne à l'écran. Quand une référence occupe plusieurs
   lignes du bon (4 caisses payées + 1 offerte, deux tarifs sur le même document),
   chacune se lit séparément, rattachée visuellement à la ligne principale : trait
   de continuité à gauche, typo en retrait, pas de bordure qui la détacherait. */
.cmpf-row.det {
  padding: 7px 0 7px 10px;
  margin-left: 4px;
  border-bottom: none;
  border-left: 2px solid var(--line-2);
  font-size: 12.5px;
}
.cmpf-row.det + .cmpf-row:not(.det) { border-top: 1px dashed var(--line); }
.cmpf-row.det .cmpf-nom { font-size: 12px; font-weight: 400; color: var(--ink-3); }
.cmpf-row.det .cmpf-tt { font-size: 13px; font-weight: 600; color: var(--ink-2); }
.cmpf-row.det .cmpf-chip { padding: 3px 7px; }
.cmpf-row.det .cmpf-chip .mult { font-size: 12px; }
.cmpf-det-t { letter-spacing: .01em; }
/* La case « commandé » d'une ligne de détail est vide par nature : on garde la colonne
   pour l'alignement, mais sans pastille — elle n'a rien à annoncer. */
.cmpf-row.det > .cmpf-chip:nth-of-type(1) { background: none; border-color: transparent; }
.cmpf-row.det > .cmpf-chip:nth-of-type(1) .mult { opacity: .25; }

/* ── Inventaire : comptage par ZONE ──────────────────────────────────────────
   Un article peut vivre dans plusieurs zones (le coca au bar et à la cave). Chaque
   zone a son bloc de conditionnements et son sous-total ; le grand total ne sert
   qu'à se relire, il n'est jamais réparti. */
.inv-cond-zone {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin: 16px 0 6px; padding-bottom: 5px; border-bottom: 1px solid var(--line);
}
.inv-cond-zone:first-child { margin-top: 0; }
/* En-tête de zone quand on compte UNE zone précise : nom en gros en haut du modal. */
.inv-cond-zonehead { display: flex; align-items: baseline; gap: 9px; margin-bottom: 16px; }
.inv-cond-zonehead .eyebrow { font-size: 11px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-3); }
.inv-cond-zonehead .znom { font-size: 20px; font-weight: 800; color: var(--accent); letter-spacing: .01em; }
.inv-cond-zone-nom { font-size: 12px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--accent); }
.inv-cond-zone-sub { font-size: 11px; color: var(--ink-3); white-space: nowrap; }
/* « Pas de stock » (par zone) : marque la zone comptée à 0 ; devient vert « Vide · 0 » quand actif. */
.inv-cond-vide-btn { flex: none; border: 1px solid var(--line); background: var(--card); color: var(--ink-2);
  font-size: 11.5px; font-weight: 600; border-radius: 999px; padding: 5px 12px; cursor: pointer;
  white-space: nowrap; display: inline-flex; align-items: center; gap: 4px; }
.inv-cond-vide-btn:hover { border-color: var(--ink-3); }
.inv-cond-vide-btn.on { background: var(--ok-soft); border-color: transparent; color: var(--ok); }
.inv-cond-rows.is-empty { opacity: .42; pointer-events: none; }
.inv-cond-sous-tot {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 6px; padding: 5px 9px; border-radius: 7px;
  background: var(--bg-2); font-size: 12px; font-weight: 600; color: var(--ink-2);
}
.inv-cond-grand {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 16px; padding-top: 12px; border-top: 2px solid var(--line);
}
.inv-cond-grand .serif { font-size: 20px; }
/* Rappel des zones sur la ligne de la liste : vert = déjà compté. */
.inv-count-zones { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }
.inv-zsum {
  font-size: 10.5px; line-height: 1.5; padding: 1px 6px; border-radius: 6px;
  background: var(--bg-2); border: 1px solid var(--line-2); color: var(--ink-3);
}
.inv-zsum.ok { background: var(--ok-soft); border-color: #bfe2cb; color: var(--ok); font-weight: 600; }

/* ── EN-TÊTES ET ONGLETS TOUJOURS VISIBLES ───────────────────────────────────
   Sur une longue liste on perd la signification des colonnes et l'onglet courant.
   Même convention que la barre de filtres : on se cale sous la topbar, en réutilisant
   les hauteurs mesurées par _setTopbarH() (--topbar-h / --filter-h).
   Les fonds sont OPAQUES : sans ça, les lignes défilent visiblement sous l'en-tête. */

/* Onglets Mapping (Ventes) et Paramètres — collants sur mobile ET desktop. */
.tabs.tabs-stick, .settings-tabs {
  position: sticky;
  z-index: 24;
  background: var(--bg);
  top: var(--topbar-h, 56px);
}
.tabs.tabs-stick { padding-top: 8px; }
.settings-tabs { padding-top: 10px; }

@media (min-width: 841px) {
  /* Mapping vit sous la barre de filtres de la page Ventes → on empile dessous. */
  .tabs.tabs-stick { top: calc(var(--topbar-h, 64px) + var(--filter-h, 64px)); }
  /* Paramètres n'a pas de barre de filtres : directement sous la topbar. */
  .settings-tabs {
    top: var(--topbar-h, 64px);
    margin-left: -32px; margin-right: -32px;
    padding-left: 32px; padding-right: 32px;
  }
  .tabs.tabs-stick {
    margin-left: -32px; margin-right: -32px;
    padding-left: 32px; padding-right: 32px;
    box-shadow: 0 6px 10px -8px rgba(26, 24, 21, .20);
  }
  /* En-têtes de tableau : Évolution prix et Évolution coût recette.
     (Masqués sous 841px — la vue mobile est en cartes, il n'y a pas de colonnes.) */
  .px-header, .cos-header {
    position: sticky;
    top: calc(var(--topbar-h, 64px) + var(--filter-h, 64px));
    z-index: 22;
    background: var(--bg);
    box-shadow: 0 6px 10px -8px rgba(26, 24, 21, .20);
  }
}

/* ── Toggle glissant « Offerts inclus ⇄ exclus » (page Food Cost) ──
   Piste segmentée à 2 options avec un pouce (thumb) qui glisse sous l'option active.
   Même langage visuel que .dash-seg (pilule gris translucide, thumb blanc ombré). */
.fc-off-wrap { display: inline-flex; align-items: center; gap: 8px; }
.fc-off-cap { font-size: 12px; font-weight: 600; color: var(--ink-3); }
.fc-off-tgl { position: relative; display: inline-flex; align-items: stretch; padding: 2px; margin: 0; border: 1px solid var(--line); border-radius: 9px; background: rgba(128, 128, 128, .14); cursor: pointer; font: inherit; -webkit-tap-highlight-color: transparent; }
.fc-off-thumb { position: absolute; top: 2px; bottom: 2px; left: 2px; width: calc(50% - 2px); background: var(--card); border-radius: 7px; box-shadow: 0 1px 2px rgba(0, 0, 0, .10); transition: transform .2s cubic-bezier(.4, 0, .2, 1); }
.fc-off-tgl.excl .fc-off-thumb { transform: translateX(100%); }
.fc-off-opt { position: relative; z-index: 1; flex: 1 1 0; min-width: 58px; text-align: center; padding: 5px 12px; font-size: 12px; font-weight: 600; color: var(--ink-3); white-space: nowrap; transition: color .2s; }
.fc-off-tgl:not(.excl) .fc-off-inc { color: var(--ink); }
.fc-off-tgl.excl .fc-off-exc { color: var(--ink); }
@media (prefers-reduced-motion: reduce) { .fc-off-thumb { transition: none; } .fc-off-opt { transition: none; } }

/* ── Card « Ventes » du tableau de bord : filtre segmenté + barres robustes ── */
.dash-seg { display: inline-flex; gap: 2px; background: rgba(128, 128, 128, .14); border: 1px solid var(--line); border-radius: 9px; padding: 2px; }
.dash-seg-btn { border: 0; background: transparent; color: var(--ink-3); font-size: 12px; font-weight: 600; padding: 5px 11px; border-radius: 7px; cursor: pointer; white-space: nowrap; line-height: 1.2; }
.dash-seg-btn.on { background: var(--card); color: var(--ink); box-shadow: 0 1px 2px rgba(0, 0, 0, .10); }
.vbars-scroll { overflow-x: auto; overflow-y: hidden; }
/* min-width:100% → au moins toute la largeur de la card (barres peu nombreuses = étirées) ;
   width:max-content → grandit au-delà quand il y a trop de barres → le scroll horizontal s'enclenche. */
.vbars { display: flex; align-items: stretch; gap: 8px; height: 150px; padding-top: 10px; min-width: 100%; width: max-content; }
/* flex:1 0 30px → chaque barre s'étire pour remplir la card, sans jamais descendre sous 30px (→ scroll). */
.vbar { flex: 1 0 30px; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.vbar-track { flex: 1; width: 100%; min-height: 0; display: flex; align-items: flex-end; }
.vbar-fill { width: 100%; border-radius: 3px 3px 0 0; min-height: 2px; position: relative; }
.vbar-fill-cur { background: linear-gradient(to top, #e0791b, #ef9c3f); }
.vbar-fill-prev { background: linear-gradient(to top, #2f6d43, #3f8556); }
/* Valeur € en BLANC, centrée, au PIED de chaque barre (user 2026-08-11). */
.vbar-inval { position: absolute; bottom: 3px; left: 0; right: 0; text-align: center; font-size: 9px; font-weight: 700; color: #fff; font-family: 'Inter Tight', monospace; pointer-events: none; text-shadow: 0 1px 1.5px rgba(0, 0, 0, .35); white-space: nowrap; }
.vbar-val { font-size: 10px; color: var(--ink-2); font-family: 'Inter Tight', monospace; white-space: nowrap; }
.vbar-lbl { font-size: 10.5px; color: var(--ink-3); font-weight: 600; white-space: nowrap; }
.vbars-sub { margin-top: 12px; font-size: 12px; color: var(--ink-3); }
.vbars-dual .vbar { flex: 1 1 56px; min-width: 56px; }
.vbars-dual .vbar-track { gap: 8px; justify-content: center; overflow: visible; }
.vbar-gbar { flex: 1 1 0; max-width: 46px; min-width: 14px; position: relative; }
.vbar-delta { position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); margin-bottom: 3px; font-size: 9.5px; font-weight: 700; line-height: 1; white-space: nowrap; }
.vbar-delta.up { color: #1a8f4e; }
.vbar-delta.down { color: var(--danger); }
.vbar-vals { display: flex; gap: 5px; font-size: 9.5px; font-family: 'Inter Tight', monospace; white-space: nowrap; line-height: 1.1; }
.vv-cur { color: #c46810; font-weight: 700; }
.vv-prev { color: #2f6d43; }
.vbars-legend { display: flex; gap: 16px; margin-top: 10px; font-size: 11px; color: var(--ink-3); }
.vbars-legend > span { display: inline-flex; align-items: center; gap: 5px; }
.vbars-legend .lg-dot { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.vbars-legend .lg-cur { background: #e0791b; }
.vbars-legend .lg-prev { background: #2f6d43; }

/* ===== Onglet « Volume d'achat » (page Fournisseurs) — achats par fournisseur sur une période ===== */
.fvol-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.fvol-title { font-family: 'Source Serif 4', serif; font-size: 19px; font-weight: 600; }
.fvol-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 11px; margin-bottom: 16px; }
.fvol-kpi { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; }
.fvol-kpi-l { font-size: 11px; font-weight: 600; letter-spacing: .03em; text-transform: uppercase; color: var(--ink-3); }
.fvol-kpi-v { font-family: 'Source Serif 4', serif; font-size: 23px; font-weight: 600; margin-top: 3px; }
.fvol-kpi-s { font-size: 11.5px; margin-top: 2px; }
.fvol-kpi-s.up { color: var(--danger); } .fvol-kpi-s.down { color: var(--ok); } .fvol-kpi-s.flat { color: var(--ink-3); }
.fvol-kpi-v.ok { color: var(--ok); } .fvol-kpi-v.bad { color: var(--danger); }
/* % achats/CA en petit sous le total HT (mobile) : vert ≤ 25 %, rouge sinon. */
.fvol-carat { font-family: 'Inter Tight', system-ui, sans-serif; font-size: 12px; font-weight: 700; margin-left: 4px; vertical-align: 2px; }
.fvol-carat.ok { color: var(--ok); } .fvol-carat.bad { color: var(--danger); }
/* Bandeau résumé (mobile) */
.fvol-banner { display: flex; justify-content: space-between; align-items: flex-end; gap: 10px; background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; margin-bottom: 14px; }
.fvol-b-big { font-family: 'Source Serif 4', serif; font-size: 24px; font-weight: 600; line-height: 1.05; }
.fvol-b-big.up { color: var(--danger); } .fvol-b-big.down { color: var(--ok); } .fvol-b-big.flat { color: var(--ink-3); }
/* Tableau (desktop) */
.fvol-tw { overflow-x: auto; border: 1px solid var(--line); border-radius: 12px; background: var(--card); }
.fvol-table { border-collapse: collapse; width: 100%; min-width: 900px; font-size: 13px; }
.fvol-table th, .fvol-table td { padding: 9px 11px; text-align: right; white-space: nowrap; border-bottom: 1px solid var(--line); }
.fvol-table th { font-size: 10.5px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--ink-3); background: var(--bg-2); position: sticky; top: 0; cursor: pointer; user-select: none; }
.fvol-table th:first-child, .fvol-table td:first-child { text-align: left; }
.fvol-table td.fn { font-weight: 600; }
.fvol-table tbody tr:hover td { background: var(--bg-2); }
.fvol-clickable { cursor: pointer; }
.fvol-c.fvol-clickable:active { background: var(--bg-2); }
.fvol-table tfoot td { font-weight: 700; background: var(--bg-2); border-top: 2px solid var(--line-2); border-bottom: none; }
.fvol-share { display: inline-flex; align-items: center; gap: 7px; justify-content: flex-end; }
.fvol-sbar { width: 46px; height: 6px; border-radius: 3px; background: var(--line-2); overflow: hidden; flex: none; } .fvol-sbar i { display: block; height: 100%; background: var(--accent); }
.fvol-pill { display: inline-block; padding: 2px 7px; border-radius: 20px; font-size: 11.5px; font-weight: 600; font-variant-numeric: tabular-nums; }
.fvol-pill.up { background: var(--danger-soft); color: var(--danger); }
.fvol-pill.down { background: var(--ok-soft); color: var(--ok); }
.fvol-pill.na { background: var(--bg-2); color: var(--ink-3); }
.fvol-spark { display: inline-flex; align-items: flex-end; gap: 2px; height: 22px; }
.fvol-spark i { width: 5px; background: var(--line-2); border-radius: 1px; } .fvol-spark i.last { background: var(--accent); }
.fvol-note { font-size: 11.5px; margin-top: 10px; line-height: 1.5; }
/* Cartes (mobile) */
.fvol-sortrow { margin-bottom: 10px; }
.fvol-sortrow select { width: 100%; border: 1px solid var(--line-2); border-radius: 10px; background: var(--card); font-size: 13px; color: var(--ink); padding: 9px 12px; height: 42px; }
.fvol-c { background: var(--card); border: 1px solid var(--line); border-radius: 13px; padding: 12px 13px; margin-bottom: 9px; }
.fvol-c .r1 { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.fvol-c .nom { font-size: 15px; font-weight: 700; min-width: 0; }
.fvol-c .htbox { text-align: right; flex: none; }
.fvol-c .ht { font-family: 'Source Serif 4', serif; font-size: 19px; font-weight: 600; color: var(--accent); line-height: 1.05; }
.fvol-c .ttc { font-size: 10.5px; color: var(--ink-3); margin-top: 1px; }
.fvol-c .r2 { font-size: 11.5px; color: var(--ink-3); margin-top: 7px; }
.fvol-c .r3 { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 9px; }
.fvol-c .r3 .fvol-sbar { width: 70px; height: 7px; }
.fvol-c .sp { font-size: 11.5px; font-weight: 600; color: var(--ink-2); }
.fvol-c .pills { display: flex; gap: 5px; flex: none; }
/* Sélecteur de période : MÊME rendu que le tableau de bord (styles `.filter-row select`/`.period-preset`
   répliqués, car ici on n'est pas dans une `.filter-row` → sinon le <select> retombe en natif). */
.fvol-psel { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fvol-psel .period-preset, .fvol-psel input, .fvol-psel select {
  height: 36px; box-sizing: border-box; padding: 6px 10px; border: 1px solid var(--line-2);
  border-radius: 6px; font-family: inherit; font-size: 13px; background: var(--card); color: var(--ink); outline: none;
}
.fvol-psel .period-preset { padding-top: 0; padding-bottom: 0; }
.fvol-psel .period-preset:focus, .fvol-psel input:focus { border-color: var(--ink-3); }
@media (max-width: 840px) { .fvol-psel { flex: 1 1 100%; } }

/* ===== Nav mobile : 3 principaux (Stocks/Inventaire/Commande) + bouton « Autres » déroulant ===== */
@media (max-width: 840px) {
  /* Plus de scroll horizontal (4 boutons) → overflow visible pour laisser sortir le menu « Autres » au-dessus.
     ⚠ NE PAS toucher à `position` : la barre reste `fixed` (bas d'écran) ; le `transform:translateZ(0)` déjà
     posé sur `.mobile-nav` sert de bloc conteneur au popover `#mnMore` (position:absolute). */
  .mobile-nav { overflow: visible; }
  .mobile-nav > button { flex: 0 0 20%; }   /* 5 boutons : Accueil / Stocks / Inventaire / Commande / Autres */
  .mn-more-btn.open { color: var(--accent); }
  .mn-more {
    position: absolute; bottom: calc(100% + 8px); left: 6px; right: 6px; z-index: 95;
    background: var(--card); border: 1px solid var(--line); border-radius: 16px;
    box-shadow: 0 6px 28px rgba(0,0,0,.18); padding: 8px;
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px;
    animation: mnMoreUp .16s var(--ease);
  }
  .mn-more[hidden] { display: none; }   /* sinon display:grid l'emporterait sur l'attribut hidden */
  .mn-more button { flex: none; width: auto; padding: 10px 4px; border-radius: 12px; }
}
@keyframes mnMoreUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* Commande/Réception mobile : le sélecteur de fournisseur est masqué (hide-mobile), le sélecteur de PÉRIODE
   prend sa place (pleine largeur) pour afficher les commandes plus anciennes. user 2026-08-28. */
@media (max-width: 840px) { .cmg-filters .cmg-period { flex: 1 1 100%; } }
