/* ======================================================
   MNP SUIVI PRODUCTION — Design System v2
   ====================================================== */

/* ── 1. TOKENS ────────────────────────────────────────── */
:root {
  /* Vignettes produit (images de variantes) : DEUX tailles seulement */
  --vignette-sm: 36px;
  --vignette-lg: 50px;

  /* ACCENT UNIQUE : BLEU (le violet a été entièrement supprimé).
     Boutons pleins = --accent (hover --accent-strong) ; éléments actifs /
     compteurs / onglets = fonds transparents --accent-bg + texte --accent-strong. */
  --accent:          #4C63D2;
  --accent-strong:   #3B4FB8;
  --accent-text:     var(--accent-strong);   /* alias */
  --accent-bg:       rgba(76, 99, 210, 0.10);
  --accent-bg-hover: rgba(76, 99, 210, 0.16);
  --accent-border:   rgba(76, 99, 210, 0.28);

  /* Alias historiques (--brand*) : pointent désormais sur le bleu — tout le code
     existant (boutons, liens, barres de progression, focus…) bascule d'un coup. */
  --brand:        var(--accent);
  --brand-hover:  var(--accent-strong);
  --brand-active: #324399;
  --brand-soft:   var(--accent-bg);
  --brand-softer: rgba(76, 99, 210, 0.05);

  /* Accent profond — logo sidebar, totaux facture uniquement */
  --navy: #1e2340;

  /* Sémantique */
  --success:        #2E9E63;
  --success-soft:   #f0fbf4;
  --success-border: #bfe7cd;
  --success-ink:    #1C7A49;   /* variante AA pour TEXTE sur clair */
  --warning:        #C5871B;
  --warning-soft:   #fcf7ec;
  --warning-border: #f0dcae;
  --warning-ink:    #8A6113;   /* variante AA pour TEXTE sur clair */
  --danger:         #D24B4B;
  --danger-soft:    #fdf1f1;
  --danger-border:  #f3c9c9;
  --danger-ink:     #B23636;   /* variante AA pour TEXTE sur clair */
  --info:           #4C63D2;
  --info-soft:      #eef0fb;
  --info-border:    #c9d0f3;

  /* Encre */
  --ink:   #11141f;
  --ink-2: #374151;
  --ink-3: #6b7280;
  --ink-4: #6e7682;   /* assombri pour WCAG AA (~4.6:1 sur blanc, petit texte) */
  --ink-5: #7c828d;   /* assombri (~3.9:1 sur blanc), reste + clair que --ink-4 */

  /* Surfaces */
  --bg:         #f4f5f9;
  --surface:    #ffffff;
  --surface-2:  #f9fafb;
  --line:       #ebecf2;
  --line-soft:  #f1f2f6;

  /* Géométrie */
  --r-xs:   6px;
  --r-sm:   8px;
  --r-md:   12px;
  --r-lg:   16px;
  --r-pill: 999px;

  /* Ombres */
  --sh-sm: 0 1px 3px rgba(17,20,31,.06);
  --sh-md: 0 4px 16px rgba(17,20,31,.08);
  --sh-lg: 0 12px 32px rgba(17,20,31,.12);
  --sh-card: 0 1px 2px rgba(17,20,31,.04), 0 10px 24px -14px rgba(17,20,31,.12);

  /* Typographie */
  --fs-xs:   11px;
  --fs-sm:   12px;
  --fs-base: 13px;
  --fs-md:   14px;
  --fs-lg:   16px;
  --fs-xl:   19px;
  --fs-2xl:  24px;
  --fs-display: 32px;

  /* Graisses : DEUX seulement (l'emphase passe par la TAILLE + la COULEUR) */
  --fw-regular: 400;
  --fw-medium:  500;

  /* Espacement : échelle 4px unique */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;

  /* Hauteur partagée de TOUS les contrôles (inputs, recherche, selects, .btn, filtres).
     Calée sur la hauteur FINE des boutons de filtre (.filtre-btn « Tous »). */
  --control-h: 28px;

  /* Layout */
  --sidebar-w: 220px;
}

/* ── 2. RESET ─────────────────────────────────────────── */
*, *::before, *::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* Gouttière de scrollbar réservée en permanence sur le document : empêche le « saut »
   de la mise en page (navbar/contenu) quand la scrollbar verticale apparaît/disparaît
   au rechargement (changement de filtre, navigation). scrollbar-gutter:stable n'affiche
   PAS de piste vide sur les pages courtes (≠ overflow-y:scroll) et n'ajoute pas de 2e
   scrollbar (les .nav-rail/.nav-panel gardent leur scroll interne). Mobile : overlay
   scrollbars → sans effet visible, pas de dégradation. */
html { scrollbar-gutter: stable; }

/* ── 3. BODY ──────────────────────────────────────────── */
body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--bg);
  color: var(--ink-2);
  font-size: var(--fs-md);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* ── 4. LAYOUT PRIMITIVES ─────────────────────────────── */
.page {
  padding: 24px;
  background: var(--bg);   /* gris partagé (= body) pour faire ressortir les cartes blanches */
  min-height: 100vh;
}

.page__inner {
  margin: 0 auto;
  width: 100%;
}
.page__inner--narrow { max-width: 720px; }
.page__inner--mid    { max-width: 1100px; }
.page__inner--wide   { max-width: 1500px; }

/* ── 5. EN-TÊTE DE PAGE ───────────────────────────────── */
.page-head {
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: 12px 20px;
  margin-bottom: 20px;
  box-shadow: var(--sh-sm);
  display: flex;
  align-items: center;
  gap: 12px;
}

.page-head__back {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--r-sm);
  border: 1.5px solid var(--line);
  color: var(--ink-3);
  background: var(--surface);
  cursor: pointer;
  flex-shrink: 0;
  transition: border-color .15s, color .15s;
}
.page-head__back:hover { border-color: var(--brand); color: var(--brand); }

.page-head__icon {
  width: 36px;
  height: 36px;
  border-radius: var(--r-md);
  background: #eef0f3;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
/* Les SVG des templates portent souvent stroke="white"/fill="white" (hérité du
   fond plein) : la couleur accent est forcée au niveau CSS, prioritaire sur
   l'attribut de présentation. */
.page-head__icon svg { color: #383b42; stroke: #383b42; }
.page-head__icon svg[fill]:not([fill="none"]) { fill: #383b42; stroke: none; }

/* Placeholder « montre » UNIFIÉ pour les vignettes produit sans image (ou image cassée).
   Look seul (fond + couleur douce + centrage) ; la TAILLE/le radius restent portés par
   le style/classe existant de chaque vignette (aucune dimension changée). SVG en currentColor. */
.vign-ph { display:inline-flex; align-items:center; justify-content:center; background:#f2f3f6; color:#9aa0aa; box-sizing:border-box; overflow:hidden; }
.vign-ph svg { width:58%; height:58%; max-width:72px; max-height:72px; display:block; }

/* Badge compteur d'en-tête (« 44 OF », « 20 variantes »…) — pill accent partagée */
.count-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  background: #eef0f3;
  color: #383b42;
  font-size: var(--fs-sm);
  font-weight: 400;
  line-height: 1.4;
  white-space: nowrap;
}

.page-head__title {
  font-size: var(--fs-xl);
  font-weight: 500;
  color: var(--ink);
  margin: 0;
}

.page-head__subtitle {
  font-size: var(--fs-sm);
  color: var(--ink-4);
  margin: 0;
}

.page-head__actions { margin-left: auto; display: flex; gap: 8px; align-items: center; }

/* Typo : deux graisses seulement (400 normal / 500 medium). Le gras par défaut
   des balises <b>/<strong> est neutralisé ici — un vrai titre porte 500 via sa classe. */
b, strong { font-weight: 400; }

/* ── 6. CARTES ────────────────────────────────────────── */
.card {
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: var(--space-5) var(--space-6);
  margin-bottom: var(--space-4);
  box-shadow: var(--sh-card);
}

/* Alias rétro-compatible */
.form-card {
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: var(--space-5) var(--space-6);
  margin-bottom: var(--space-4);
  box-shadow: var(--sh-card);
}

.form-card-title {
  font-size: var(--fs-md);
  font-weight: 500;
  color: var(--ink-2);
  margin-bottom: 18px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.form-card-icon { font-size: var(--fs-lg); }

/* ── 7. LABEL DE SECTION ──────────────────────────────── */
.section-label {
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--ink-4);
  text-transform: uppercase;
  letter-spacing: .06em;
  margin-bottom: 14px;
  display: block;
}

/* ── 8. BOUTONS ───────────────────────────────────────── */

/* P2.1 — Anneau de focus CLAVIER cohérent pour les éléments interactifs sans style
   de focus propre (boutons inline, lignes role=button, liens icône, .modal__close…).
   Spécificité 0 via :where() → ne surcharge pas les .btn*/.input:focus existants. */
:where(button, [role="button"], a[href], summary, [tabindex]):focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 1px;
}

/* Base — TOUTE la géométrie ici (hauteur = padding vertical + line-height + font-size ;
   box-sizing, radii, poids, gap). Les VARIANTES ne changent QUE la couleur.
   .btn-primary / .btn-secondary = alias rétro-compat sur la MÊME base → hauteur
   identique partout (avec/sans bordure colorée, avec/sans icône). */
.btn,
.btn-primary,
.btn-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  box-sizing: border-box;
  height: var(--control-h);          /* = hauteur des inputs/recherche/selects → alignement parfait */
  padding: 0 var(--space-4);         /* vertical piloté par height ; flex centre le contenu */
  border: 1.5px solid transparent;   /* réservée sur TOUS → même hauteur quelle que soit la couleur */
  border-radius: 7px;                /* forme cible unifiée (littéral, PAS --r-sm partagé avec inputs/chips) */
  font-family: inherit;
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, box-shadow .15s;
}
.btn:focus-visible,
.btn-primary:focus-visible,
.btn-secondary:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}
.btn:disabled, .btn[disabled],
.btn-primary:disabled, .btn-secondary:disabled {
  opacity: .45;
  cursor: default;
  pointer-events: none;
}

/* Variantes — COULEUR uniquement (aucune ne touche padding / height / font-size) */
.btn--primary, .btn-primary             { background: #383b42; color: #fff; }
.btn--primary:hover, .btn-primary:hover   { background: #4d515b; }
.btn--primary:active, .btn-primary:active { background: #4d515b; }

.btn--ghost, .btn-secondary             { background: transparent; color: var(--ink-2); border-color: var(--line); }
.btn--ghost:hover, .btn-secondary:hover { background: var(--surface-2); color: var(--ink); border-color: var(--ink-5); }

.btn--danger        { background: var(--danger);  color: #fff; }
.btn--danger:hover  { background: #b91c1c; }
.btn--success       { background: var(--success); color: #fff; }
.btn--success:hover { background: var(--success-ink); }
.btn--warning       { background: var(--warning); color: #fff; }
.btn--warning:hover { background: #a8740f; }
.btn--danger-outline       { background: transparent; color: var(--danger-ink); border-color: var(--danger-border); }
.btn--danger-outline:hover { background: var(--danger-soft); }

/* Taille optionnelle — par défaut tout le monde a la MÊME hauteur */
.btn--sm   { height: auto; padding: 5px 12px; font-size: var(--fs-sm); }   /* exception explicite (compact) */
.btn--icon { width: 32px; height: 32px; padding: 0; }

/* ── Sélecteur de fichier stylé (composant partagé — partial _upload.html) ── */
.filepick { display: inline-flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
/* input natif masqué visuellement mais FOCUSABLE (clavier + lecteurs d'écran) */
.filepick__input { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.filepick__btn { cursor: pointer; }   /* hérite .btn-secondary : hauteur / radii / poids tokens */
.filepick__input:focus-visible + .filepick__btn { outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent); }
.filepick__name { font-size: var(--fs-base); color: var(--ink-3); max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.filepick__name--empty { color: var(--ink-5); }
.filepick__act { display: inline-flex; align-items: center; gap: 4px; background: none; border: none; cursor: pointer; font-family: inherit; font-size: var(--fs-sm); font-weight: var(--fw-medium); padding: 4px 8px; border-radius: var(--r-sm); }
.filepick__act[hidden] { display: none; }   /* l'attribut hidden doit primer sur le display inline-flex */
.filepick__act:hover { background: var(--surface-2); }
.filepick__replace { color: var(--ink-3); }        /* ghost neutre */
.filepick__remove  { color: var(--danger-ink); }   /* ghost danger-ink */

/* ── 9. CHAMPS DE FORMULAIRE ──────────────────────────── */
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-bottom: 14px;
}
.form-row:last-child { margin-bottom: 0; }

.form-field,
.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.form-field label,
.field label {
  font-size: var(--fs-sm);
  font-weight: 400;
  color: var(--ink-4);
  text-transform: uppercase;
  letter-spacing: .04em;
}

.form-field input,
.form-field select,
.form-field textarea,
.field input,
.field select,
.field textarea,
.input,
.select {
  padding: 0 12px;                   /* vertical piloté par height (--control-h fin) ; texte centré */
  border: 1.5px solid var(--line);
  border-radius: var(--r-sm);
  font-family: inherit;
  font-size: var(--fs-md);
  color: var(--ink);
  background: var(--surface);
  transition: border-color .15s, box-shadow .15s;
  width: 100%;
  box-sizing: border-box;
  height: var(--control-h);
}
/* Les zones de texte multi-lignes gardent une hauteur libre (pilotée par rows). */
.form-field textarea, .field textarea, textarea.input { height: auto; min-height: 72px; padding: 9px 12px; }

.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus,
.field input:focus,
.field select:focus,
.field textarea:focus,
.input:focus,
.select:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 15%, transparent);
}

/* ── Barre de recherche unifiée (320px, filtrage à la frappe) ──────────── */
.search-box { position: relative; width: 320px; max-width: 100%; }
.search-box > svg { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 14px; height: 14px; color: var(--ink-4); pointer-events: none; }
.search-box > input {
  /* Hauteur unifiée sur --control-h (alignée inputs / selects / .btn). */
  width: 100%; height: var(--control-h); padding: 0 12px 0 34px;
  border: 1.5px solid var(--line); border-radius: var(--r-sm);
  font-family: inherit; font-size: var(--fs-sm); color: var(--ink);
  background: var(--surface); outline: none; box-sizing: border-box;
  transition: border-color .15s;
}
.search-box > input:focus { border-color: var(--brand); }
/* Rangée [filtres][recherche] calée à gauche. Les filtres déroulants prennent la même
   hauteur que les chips/la recherche (padding vertical identique). */
.search-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 14px; }
.search-row .input, .search-row select { width: auto; padding-top: 6px; padding-bottom: 6px; }
/* Filtre déroulant standard — EXACTEMENT la même hauteur que la barre de recherche
   (.search-box > input : padding vertical 6px, bordure 1.5px, police --fs-sm). Largeur auto
   (inchangée). À appliquer à tous les <select> de filtre des barres d'outils. */
.filtre-select {
  width: auto;
  height: var(--control-h);
  box-sizing: border-box;
  padding: 0 12px;
  border: 1.5px solid var(--line);
  border-radius: var(--r-sm);
  font-family: inherit;
  font-size: var(--fs-sm);
  color: var(--ink);
  background: var(--surface);
  outline: none;
  box-sizing: border-box;
  cursor: pointer;
  transition: border-color .15s;
}
.filtre-select:focus { border-color: var(--brand); }

/* ── <select> : flèche personnalisée UNIFIÉE (tout le logiciel) ────────────────────────────
   Un <select> natif dessine sa flèche ▽ DANS le padding-droit → le texte paraît décalé/mal
   centré. On neutralise la flèche native (appearance:none) et on pose une flèche SVG à droite,
   avec un padding-droit qui lui réserve la place.
   • On n'écrase QUE padding-left / padding-right + l'image : le padding VERTICAL et le
     background-COLOR des classes ne sont pas touchés → hauteurs et couleurs préservées.
   • Sélecteur `select:not([multiple])` = spécificité (0,1,1) : gagne sur les classes de select
     (.filtre-select / .input / .s-select / .pagination__select, toutes (0,1,0)) — y compris leur
     `background:<couleur>` qui, en raccourci, remettrait background-image à none — SANS toucher
     aux <input>/<button> qui partagent ces classes (le sélecteur ne matche que des <select>).
   • Les <select multiple> / listbox (size>1) sont exclus (garderaient une flèche incongrue).
   Aucun <select> de l'app n'avait de flèche custom auparavant → zéro risque de double flèche. */
select:not([multiple]) {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  padding-left: 12px;
  padding-right: 30px;                 /* réserve la place de la flèche (le texte ne passe pas dessous) */
  text-align-last: left;
  line-height: normal;                 /* défaut : convient aux selects à hauteur AUTO (déjà centrés) */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  background-size: 12px 12px;
}

/* Centrage VERTICAL du texte des <select> à HAUTEUR FIXE.
   appearance:none (ci-dessus) supprime le centrage vertical NATIF du navigateur ; dans un select
   à height fixe (28px / 32px), le texte tombe alors sur la ligne de base → trop bas. On le recentre
   en faisant REMPLIR la hauteur de contenu par le line-height (le glyphe se centre dans sa propre
   ligne via le demi-interligne, quelle que soit la taille de police). padding vertical remis à 0
   pour que « contenu == line-height » (annule aussi le padding vertical des filtres de barre,
   .search-row select). NE concerne PAS les selects à hauteur AUTO (.s-select, selects nus hors
   .form-field/.field) : sans espace vertical superflu, ils sont déjà centrés → on n'y touche pas. */
select.filtre-select,
select.input,
select.select,
.form-field select:not([multiple]),
.field select:not([multiple]) {
  padding-top: 0;
  padding-bottom: 0;
  line-height: calc(var(--control-h) - 3px);   /* 25px = hauteur de contenu (28 − 2×1.5px bordure) */
}
select.pagination__select {
  padding-top: 0;
  padding-bottom: 0;
  line-height: 29px;                            /* 32 − 2×1.5px bordure */
}

/* ── 10. TABLEAUX ─────────────────────────────────────── */
.table-wrapper { overflow-x: auto; }

table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  background: var(--surface);
}

/* En-tête clair — fini le gris foncé */
thead tr { background: var(--surface-2); }
thead th {
  padding: 10px 14px;
  text-align: left;
  font-size: var(--fs-xs);
  font-weight: 400;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-3);
  border-bottom: 1.5px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface-2);
}

tbody tr {
  border-bottom: 1px solid var(--line-soft);
  transition: background .12s;
}
tbody tr:nth-child(even) { background: var(--surface-2); }
tbody tr:hover           { background: var(--brand-softer); }
tbody tr:last-child      { border-bottom: none; }

tbody td {
  padding: 11px 14px;
  font-size: var(--fs-base);
  color: var(--ink-2);
  border-bottom: 1px solid var(--line-soft);
}

/* Lignes cliquables (style plat hérité) */
.table--clickable tbody tr { cursor: pointer; }
.table--clickable tbody tr:hover { background: #f2f3f6 !important; }

/* Pour les tbody tr.clickable existants */
tbody tr.clickable { cursor: pointer; }
tbody tr.clickable:hover { background: var(--brand-softer) !important; }

.rh-cols      { grid-template-columns: 5px 44px 2fr 1.3fr 1.1fr 24px; gap: 0 16px; display: grid; }
.cl-cols      { grid-template-columns: 5px 1.5fr 1.5fr 1fr 1fr 24px; gap: 0 16px; display: grid; }
.cs-cols      { grid-template-columns: 5px 1.5fr 2fr 1fr 24px; gap: 0 16px; display: grid; }
.inv-cols     { grid-template-columns: 5px 1.5fr 1fr 0.8fr 0.8fr 0.8fr 1.5fr 24px; gap: 0 16px; display: grid; }
.st-prod-cols { grid-template-columns: 5px 1.1fr 1.8fr 1fr 0.8fr 1.3fr; gap: 0 16px; display: grid; }
.st-comp-cols { grid-template-columns: 5px 2fr 1fr 0.8fr 0.8fr 0.9fr 1.5fr; gap: 0 16px; display: grid; }
.st-def-cols  { grid-template-columns: 5px 2fr 1fr 0.8fr 0.8fr 1.5fr; gap: 0 16px; display: grid; }
/* Dropdown de recherche d'OF (rattachement de mouvement). */
.of-res { position:absolute; left:0; right:0; top:100%; z-index:60; margin-top:2px; background:var(--surface); border:1px solid var(--line); border-radius:8px; box-shadow:var(--sh-md); max-height:200px; overflow-y:auto; }
.of-res__item { padding:8px 12px; font-size:13px; cursor:pointer; }
.of-res__item:hover { background:var(--brand-softer); }
.of-res__vide { padding:10px 12px; font-size:13px; color:var(--ink-4); }
.st-mouv-cols { grid-template-columns: 5px 1.1fr 2fr 1fr 0.7fr 0.7fr 0.7fr 1.2fr; gap: 0 16px; display: grid; }

/* Cas particulier facture — en-tête navy (non surchargé : inline dans le PDF) */

/* ── 11. PAGINATION ───────────────────────────────────── */
.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--line-soft);
  gap: 8px;
}

.pagination__info {
  font-size: var(--fs-base);
  color: var(--ink-4);
}

.pagination-info { /* alias */
  font-size: var(--fs-base);
  color: var(--ink-4);
}

.pagination-btns { display: flex; gap: 6px; align-items: center; }

.page-btn,
.btn-page {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  height: 32px;
  padding: 0 10px;
  border: 1.5px solid var(--line);
  border-radius: var(--r-sm);
  font-family: inherit;
  font-size: var(--fs-base);
  color: var(--ink-3);
  background: var(--surface);
  cursor: pointer;
  text-decoration: none;
  transition: border-color .15s, color .15s, background .15s;
}
.page-btn:hover:not(:disabled),
.btn-page:hover:not(:disabled) {
  border-color: var(--accent-border);
  color: var(--accent-text);
}
.page-btn.is-active,
.page-btn.active,
.btn-page.active,
.btn-page.is-on {
  border-color: #383b42;
  background: #eef0f3;
  color: #383b42;
  font-weight: 400;
}
.page-btn:disabled,
.btn-page:disabled {
  opacity: .35;
  cursor: default;
  pointer-events: none;
}

/* Composant de pagination partagé (boutons ‹ › numérotés + sélecteur lignes/page) */
.pagination__right { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.pagination__btns { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pagination__gap { color: var(--ink-4); padding: 0 2px; user-select: none; }
.pagination__select {
  height: 32px;
  padding: 0 26px 0 10px;
  border: 1.5px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink-3);
  font-family: inherit;
  font-size: var(--fs-base);
  font-weight: 400;
  cursor: pointer;
}
.pagination__select:hover { border-color: var(--accent-border); color: var(--accent-text); }

/* ── 12. CHIPS / BADGES / STATUTS ─────────────────────── */
/* Badges / pastilles — UN seul système. La BASE fixe toute la géométrie (hauteur =
   padding vertical + line-height + font-size ; box-sizing ; radii pill ; poids).
   Référence de hauteur = « Manuel ». Les VARIANTES ne changent QUE la couleur.
   .chip / .chip--* = alias rétro-compat sur la MÊME base → hauteur identique partout. */
.badge, .chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  box-sizing: border-box;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  font-size: var(--fs-xs);
  font-weight: var(--fw-regular);
  line-height: 1.4;
  white-space: nowrap;
}

/* Variantes — COULEUR uniquement (aucune ne touche padding / height / font-size) */
.badge--neutral, .chip--muted   { background: var(--surface-2);    color: var(--ink-4); }
.badge--warning, .chip--warning { background: var(--warning-soft); color: var(--warning-ink); }
.badge--success, .chip--success { background: var(--success-soft); color: var(--success-ink); }
.badge--info,    .chip--info    { background: var(--info-soft);    color: var(--info); }
.badge--danger,  .chip--danger  { background: var(--danger-soft);  color: var(--danger-ink); }
.badge--brand,   .chip--brand   { background: var(--accent-bg);    color: var(--accent-strong); }

/* Nom de client / marque présenté en pilule douce — pour une cellule de liste ou un
   champ de fiche AUTONOME (jamais dans un titre H1 ni un libellé produit composite). */
.bulle-client {
  display: inline-block;
  background: #F1EFE8;
  color: var(--ink-3);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: var(--fs-xs);
  font-weight: 400;
  line-height: 1.4;
  white-space: nowrap;
}

.chip__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

/* Statuts OF */
.statut-encours  { color: var(--accent-strong); font-size: var(--fs-sm); font-weight: 400; }
.statut-termine  { color: var(--success); font-size: var(--fs-sm); font-weight: 400; }
.statut-pause    { color: var(--warning); font-size: var(--fs-sm); font-weight: 400; }
.statut-splitte  { color: var(--ink-4);   font-size: var(--fs-sm); font-weight: 400; }

/* Badges existants (rétro-compat) */
.badge-vide {
  background: var(--surface-2);
  color: var(--ink-4);
  padding: 3px 10px;
  border-radius: var(--r-pill);
  font-size: var(--fs-sm);
}

/* ── 13. MODALES ──────────────────────────────────────── */
.modal {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(17,20,31,.45);
  z-index: 5000;
  align-items: center;
  justify-content: center;
  backdrop-filter: blur(2px);
}
.modal.is-open { display: flex; }

.modal__panel {
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: 28px;
  width: 420px;
  max-width: 92vw;
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: var(--sh-lg);
  animation: modal-in .18s ease-out;
}
.modal__panel--wide    { width: 600px; }
.modal__panel--tall    { max-height: 95vh; }
.modal__panel--confirm { width: 360px; padding: 24px 24px 20px; }

@keyframes modal-in {
  from { opacity: 0; transform: translateY(12px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

.modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
}
.modal__head h3 {
  font-size: var(--fs-lg);
  font-weight: 500;
  color: var(--ink);
  margin: 0;
}

/* Titre des modales de confirmation centrées (h3 hors .modal__head) */
.modal__panel h3 { font-size: var(--fs-lg); font-weight: 500; color: var(--ink); }

.modal__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--r-sm);
  border: none;
  background: none;
  color: var(--ink-4);
  font-size: 20px;
  cursor: pointer;
  line-height: 1;
  transition: color .15s, background .15s;
}
.modal__close:hover { background: var(--surface-2); color: var(--ink-2); }

.modal__icon {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 16px;
}
.modal__icon--danger  { background: var(--danger-soft); }
.modal__icon--warning { background: var(--warning-soft); }
.modal__icon--brand   { background: var(--brand-soft); }

.modal__body { margin-bottom: 0; }

.modal__footer {
  display: flex;
  gap: 10px;
  justify-content: center;
  margin-top: 24px;
}

/* ── 14. TOAST ────────────────────────────────────────── */
#toast-global {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 9999;
  padding: 12px 18px;
  border-radius: var(--r-md);
  font-family: inherit;
  font-size: var(--fs-base);
  font-weight: 500;
  box-shadow: var(--sh-md);
  display: none;
  align-items: center;
  gap: 10px;
  max-width: 360px;
  min-width: 200px;
  border-left: 3px solid;
  animation: toast-in .2s ease-out;
  pointer-events: none;
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

.toast--success { background: var(--success-soft); border-color: var(--success); color: var(--success); }
.toast--error   { background: var(--danger-soft);  border-color: var(--danger);  color: var(--danger);  }
.toast--info    { background: var(--info-soft);    border-color: var(--info);    color: var(--info);    }

/* ── 15. ÉTAT VIDE ────────────────────────────────────── */
.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px 24px;
  text-align: center;
  gap: 12px;
}
.empty__icon {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--surface-2);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-5);
}
.empty__title {
  font-size: var(--fs-md);
  font-weight: 400;
  color: var(--ink-3);
}
.empty__sub {
  font-size: var(--fs-base);
  color: var(--ink-4);
  max-width: 300px;
}

/* ── 16. PERMISSIONS / NIVEAUX ────────────────────────── */

/* Boutons lecture/écriture — partagés (ex-locaux dans 3 templates) */
.btn-niveau-lect-active {
  padding: 4px 12px;
  border-radius: var(--r-sm);
  font-family: inherit;
  font-size: var(--fs-xs);
  font-weight: 400;
  cursor: pointer;
  border: 1.5px solid #383b42;
  background: #eef0f3;
  color: #383b42;
  transition: all .15s;
}
.btn-niveau-ecr-active {
  padding: 4px 12px;
  border-radius: var(--r-sm);
  font-family: inherit;
  font-size: var(--fs-xs);
  font-weight: 400;
  cursor: pointer;
  border: 1.5px solid var(--success);
  background: var(--success-soft);
  color: var(--success);
  transition: all .15s;
}
.btn-niveau-lect-inactive,
.btn-niveau-ecr-inactive {
  padding: 4px 12px;
  border-radius: var(--r-sm);
  font-family: inherit;
  font-size: var(--fs-xs);
  font-weight: 400;
  cursor: pointer;
  border: 1.5px solid var(--line);
  background: var(--surface);
  color: var(--ink-4);
  transition: all .15s;
}
.btn-niveau-lect-inactive:hover,
.btn-niveau-ecr-inactive:hover {
  border-color: var(--ink-5);
  color: var(--ink-3);
}

/* Boutons surcharges individuelles (admin_utilisateur_detail) */
.perm-btn {
  padding: 3px 10px;
  border-radius: var(--r-sm);
  font-family: inherit;
  font-size: var(--fs-xs);
  font-weight: 400;
  cursor: pointer;
  transition: all .12s;
}
.perm-heritage      { border: 1.5px solid var(--line);           background: var(--surface);      color: var(--ink-4); }
.perm-heritage-role { border: 1.5px solid var(--accent-border);  background: var(--accent-bg);    color: var(--accent-strong); }
.perm-accorde       { border: 1.5px solid var(--success);         background: var(--success-soft); color: var(--success); }
.perm-refuse        { border: 1.5px solid var(--danger);          background: var(--danger-soft);  color: var(--danger); }

/* ── 17. PAGE SCAN ────────────────────────────────────── */
.scan-container {
  max-width: 600px;
  margin: 30px auto;
  padding: 0 20px;
}
.scan-bloc {
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: 28px;
  box-shadow: var(--sh-sm);
  margin-bottom: 16px;
}
.scan-bloc h2 {
  font-size: var(--fs-lg);
  font-weight: 500;
  margin-bottom: 18px;
  color: var(--ink);
}
.scan-hint {
  font-size: var(--fs-base);
  color: var(--ink-4);
  margin-bottom: 12px;
}
.operateurs-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px;
}
.btn-operateur {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 16px 10px;
  border-radius: var(--r-md);
  border: 2px solid var(--line);
  background: var(--surface);
  cursor: pointer;
  font-family: inherit;
  font-size: var(--fs-md);
  font-weight: 500;
  color: var(--ink);
  transition: transform .2s, box-shadow .2s, border-color .15s, background .15s;
}
.btn-operateur:hover {
  transform: translateY(-2px);
  box-shadow: var(--sh-md);
  border-color: var(--op, var(--line));
  background: color-mix(in srgb, var(--op, var(--line)) 8%, var(--surface));
}
.btn-operateur:active {
  border-color: var(--op, var(--line));
  background: color-mix(in srgb, var(--op, var(--line)) 14%, var(--surface));
}
.btn-operateur:focus-visible {
  outline: none;
  border-color: var(--op, var(--line));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--op, var(--brand)) 25%, transparent);
}
.avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: 400;
  font-size: var(--fs-lg);
}

/* Champ scan unifié : le cadre est porté par .scan-field (scan.html). #input-of (sélecteur ID)
   est NEUTRALISÉ ici — sinon sa bordure/box-shadow redessinait un 2e cadre intérieur (spécificité
   ID (1,0,0) > .scan-field input (0,1,1)). Le focus passe sur .scan-field:focus-within. */
#input-of {
  flex: 1; min-width: 0; width: auto;
  padding: 15px 0; margin: 0;
  border: none; border-radius: 0; background: transparent; box-shadow: none;
  -webkit-appearance: none; appearance: none; outline: none;
  font-size: var(--fs-xl); letter-spacing: 1px; text-align: center; font-family: inherit;
}
#input-of:focus { border: none; box-shadow: none; }

.etapes-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
.btn-etape {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 16px 8px;
  border-radius: 10px;
  border: 1.5px solid var(--line);
  background: var(--surface);
  cursor: pointer;
  font-family: inherit;
  transition: all .2s;
}
.btn-etape:hover {
  border-color: var(--brand);
  background: var(--brand-softer);
  transform: translateY(-1px);
}
.btn-etape strong {
  font-size: 15px;
  color: var(--ink);
}
.btn-etape span {
  font-size: var(--fs-xs);
  color: var(--ink-4);
}
.confirmation {
  text-align: center;
  border: 2px solid var(--success);
}
.check {
  font-size: 48px;
  color: var(--success);
  margin-bottom: 12px;
}

/* ── 18. NAVBAR (legacy top-bar) ──────────────────────── */
.header {
  background: var(--navy);
  color: white;
  padding: 16px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.header h1 { font-size: var(--fs-xl); font-weight: 500; letter-spacing: .3px; }
.header-actions { display: flex; gap: 10px; }

.navbar {
  background: var(--navy);
  padding: 0 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 56px;
  position: sticky;
  top: 0;
  z-index: 100;
  box-shadow: 0 2px 12px rgba(0,0,0,.2);
}
.nav-brand {
  color: white;
  font-size: var(--fs-lg);
  font-weight: 400;
  letter-spacing: .5px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.nav-links, .nav-group { display: flex; align-items: center; gap: 2px; }
.nav-separator { width: 1px; height: 20px; background: rgba(255,255,255,.12); margin: 0 10px; }
.nav-link {
  color: rgba(255,255,255,.75);
  text-decoration: none;
  padding: 6px 13px;
  border-radius: var(--r-sm);
  font-size: var(--fs-base);
  font-weight: 500;
  transition: all .2s;
  display: flex;
  align-items: center;
  gap: 6px;
}
.nav-link:hover   { color: white; background: rgba(255,255,255,.1); }
.nav-link.active  { color: white; background: var(--brand); box-shadow: 0 2px 8px color-mix(in srgb, var(--brand) 40%, transparent); }
.nav-icon         { font-size: var(--fs-md); opacity: .85; }
.nav-logout       { color: #f87171; }
.nav-logout:hover { color: white; background: rgba(239,68,68,.2); }

/* ── 19. BADGE ATELIER ────────────────────────────────── */
.legende {
  padding: 12px 24px;
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.badges-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  padding: 24px;
}
.badge-atelier {
  background: var(--surface);
  border-radius: 14px;
  padding: 20px;
  text-align: center;
  border-top: 6px solid;
  box-shadow: var(--sh-sm);
  width: 160px;
}
.badge-atelier img { width: 120px; height: 120px; margin-bottom: 10px; }
.badge-atelier .prenom { font-size: var(--fs-lg); font-weight: 400; margin-bottom: 4px; }
.badge-atelier .code   { font-size: 10px; color: var(--ink-4); letter-spacing: 1px; }

.avatar-op {
  position: relative;
  cursor: pointer;
}
.avatar-op::after {
  content: attr(data-nom);
  position: absolute;
  bottom: 26px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--navy);
  color: white;
  font-size: var(--fs-xs);
  font-weight: 400;
  padding: 4px 8px;
  border-radius: 6px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity .15s;
  box-shadow: var(--sh-sm);
}
.avatar-op:hover::after { opacity: 1; }

/* ── 20. FORMULAIRE OF ────────────────────────────────── */
.form-container {
  max-width: 700px;
  margin: 30px auto;
  padding: 0 20px 40px;
}

/* ── 21. STOCK ÉTATS ──────────────────────────────────── */
.stock-vide   { color: var(--ink-4); }
.stock-alerte { color: var(--danger); }
.stock-ok     { color: var(--success); }

/* ── ASSEMBLAGE — CARTES ──────────────────────────────── */
/* Colonnes : strip · photo · OF · Client · Produit · Statut · Échéance · Avancement · icône msg */
.asm-cols { grid-template-columns: 5px 64px 1.1fr 1.1fr 1.4fr 1.2fr 1.2fr 1.6fr 44px; gap: 0 16px; display: grid; }
.of-cols  { grid-template-columns: 5px 1.2fr 1.4fr 1fr 1fr 0.9fr; gap: 0 16px; display: grid; width: 100%; }

.asm-header {
  padding: 0 0 6px;
  margin-bottom: 2px;
}
.asm-header > div {
  font-size: var(--fs-xs);
  font-weight: 400;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.asm-card {
  align-items: center;
  background: var(--surface);
  border-radius: var(--r-md);
  box-shadow: var(--sh-card);
  margin-bottom: var(--space-2);
  overflow: hidden;
  cursor: pointer;
  transition: box-shadow .15s, transform .1s;
}
.asm-card:hover {
  box-shadow: var(--sh-md);
  transform: translateY(-1px);
  border-color: transparent;
}

/* Colonne de garde 5px des grilles (ex-bande de statut colorée, SUPPRIMÉE :
   le statut est porté par la chip seule). La colonne reste pour ne pas décaler
   l'alignement des lignes et des en-têtes ; le background transparent !important
   est un filet de sécurité contre tout background inline résiduel. */
.asm-strip { align-self: stretch; background: transparent !important; }

.asm-cell { padding: var(--space-3) var(--space-2) var(--space-3) 0; }

/* Avancement (liste Assemblage) : étape en cours + mini-pipeline 1 segment/étape.
   Couleurs pilotées par --seg-done / --seg-cur posés inline selon l'état. */
.asm-prog { display: flex; flex-direction: column; gap: 5px; }
.asm-prog__head { display: flex; align-items: center; gap: 6px; }
.asm-prog__head .chip { padding: 2px 8px; font-size: 11px; font-weight: 400; background: var(--success-soft); color: var(--success-ink); }  /* libellé complet (nowrap hérité de .chip) ; pastille d'étape UNIFORME émeraude — spécificité (0,2,0) > .chip--* (0,1,0), sans !important */
.asm-prog__count { font-size: 11px; color: var(--ink-4); flex-shrink: 0; }
.asm-pipe { display: flex; gap: 3px; width: 160px; max-width: 100%; }
.asm-seg { height: 5px; flex: 1 1 0; min-width: 5px; border-radius: 99px; background: var(--line); }
.asm-seg--done { background: var(--seg-done, var(--success)); }
.asm-seg--cur  { background: var(--surface-2); box-shadow: inset 0 0 0 1.5px var(--seg-cur, var(--success)); }

/* ── 22. DIVERS ───────────────────────────────────────── */
.table-wrapper { overflow-x: auto; }
.cell-termine  { text-align: left; }
.cell-vide     { background: transparent; }
.initiale      { font-weight: 400; font-size: 15px; }

canvas { max-width: 100%; }

/* Stats cards */
#cartes > div {
  box-shadow: var(--sh-md) !important;
  border: none !important;
  border-radius: 18px !important;
}
#cartes > div:hover { transform: translateY(-4px) !important; }
#podium { margin-top: 20px; }

/* ── 23. FILTRES / ONGLETS UTILITAIRES ────────────────── */

/* Boutons filtre toggle */
.filtre-btn {
  height: var(--control-h);
  box-sizing: border-box;
  padding: 0 14px;
  border: 1.5px solid var(--line);
  border-radius: var(--r-sm);
  font-family: inherit;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--ink-3);
  background: var(--surface);
  cursor: pointer;
  transition: all .15s;
}
.filtre-btn:hover  { border-color: var(--accent-border); color: var(--accent-text); }
.filtre-btn.active { border-color: #383b42; background: #eef0f3; color: #383b42; font-weight: 400; }

/* Onglets */
.onglets {
  display: flex;
  gap: 4px;
  margin-bottom: 20px;
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: 6px;
  box-shadow: var(--sh-sm);
}
.onglet-btn {
  flex: 1;
  padding: 10px 16px;
  border-radius: 10px;
  border: none;
  cursor: pointer;
  font-family: inherit;
  font-size: var(--fs-base);
  font-weight: 400;
  transition: all .15s;
  background: transparent;
  color: var(--ink-3);
}
.onglet-btn.active, .onglet-btn.is-on {
  background: #eef0f3;
  color: #383b42;
  box-shadow: none;
  font-weight: 500;
}
.onglet-btn:hover:not(.active):not(.is-on) { background: #f2f3f6; color: #383b42; }
.onglet-content         { display: none; }
.onglet-content.active  { display: block; }

/* Onglets/segments « pilule » (portail OF, stock client, demandes clients) — composant
   partagé, factorisé depuis 3 copies locales identiques. Distinct de .onglet-btn (autre
   style d'onglets, conservé tel quel). Valeurs strictement identiques aux copies locales. */
.ps-tab { flex: 1; padding: 10px; border: none; border-radius: var(--r-sm); cursor: pointer; font-size: var(--fs-base); font-weight: 400; background: transparent; color: var(--ink-3); transition: background .15s, color .15s; }
.ps-tab.is-on { background: #eef0f3; color: #383b42; font-weight: 500; }
/* Onglets segmentés (fiche OF / fiche variante : dans un conteneur clair, actif accentué).
   Look STRICTEMENT identique à l'ancien style inline (sans transition). Mécanique pilotée
   par le composant MNP.onglet* (bascule de .is-on). */
.seg-tab { flex: 1; padding: 10px; border: none; border-radius: 8px; cursor: pointer; font-size: 13px; font-weight: 400; background: transparent; color: var(--ink-3); }
.seg-tab.is-on { background: #eef0f3; color: #383b42; font-weight: 500; }

/* ── 24. SHELL & SIDEBAR ──────────────────────────────── */
.app-shell { display: flex; min-height: 100vh; }

.sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: #faf9ff;
  border-right: 1px solid var(--line);
  padding: 20px 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.sidebar__logo { display: flex; align-items: center; gap: 10px; padding: 6px 8px; margin-bottom: 12px; }
.sidebar__logo img { height: 65px; width: 65px; object-fit: contain; border-radius: 6px; }

.sidebar__group {
  font-size: 10px;
  font-weight: 500;
  color: var(--ink-5);
  text-transform: uppercase;
  letter-spacing: .08em;
  padding: 4px 8px 2px;
}
.sidebar__group--first { margin-bottom: 4px; }

.sidebar__sep { height: 1px; background: var(--line-soft); margin: 8px 4px; }

.sidebar__link {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 12px;
  border-radius: 10px;
  font-size: var(--fs-base);
  font-weight: 500;
  text-decoration: none;
  color: var(--ink-3);
  transition: background .15s, color .15s;
}
.sidebar__link:hover { background: var(--brand-soft); color: var(--brand); }
.sidebar__link--active { background: var(--brand); color: white; }
.sidebar__link--active:hover { background: var(--brand-hover); color: white; }

.sidebar__foot {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-top: 8px;
  border-top: 1px solid var(--line-soft);
}
.sidebar__user-id { padding: 6px 12px; font-size: var(--fs-xs); color: var(--ink-4); }
.sidebar__logout {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 12px;
  border-radius: 10px;
  font-size: var(--fs-base);
  font-weight: 500;
  text-decoration: none;
  color: var(--danger);
  transition: background .15s;
}
.sidebar__logout:hover { background: var(--danger-soft); }

.main-content { flex: 1; min-width: 0; }

/* ── 25. ALIAS ────────────────────────────────────────── */
.btn-page.is-active {
  border-color: var(--accent-border);
  background: var(--accent-bg);
  color: var(--accent-text);
  font-weight: 400;
}

/* ── PANNEAU DE FILTRES (popover) — pattern RÉUTILISABLE ──────────────────
   Structure générique :
   <div class="filtres-pop" id="...">
     <button class="filtres-pop__btn" aria-expanded="false" aria-controls="...">
       <svg entonnoir/> Filtres <span class="filtres-pop__badge">2</span>
     </button>
     <div class="filtres-pop__panneau" id="...">
       …contrôles… <button class="filtres-pop__effacer">Tout effacer</button>
     </div>
   </div>
   Ouverture : .is-open sur .filtres-pop. Badge masqué si vide. Le bouton prend
   .is-actif quand au moins un filtre est appliqué. */
.filtres-pop { position: relative; }
.filtres-pop__btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 14px; border-radius: 10px;
  border: 1.5px solid var(--line); background: var(--surface);
  font-size: 13px; font-weight: 400; color: var(--ink-3);
  cursor: pointer; transition: border-color .15s, color .15s, background .15s;
}
.filtres-pop__btn:hover { border-color: var(--accent-border); color: var(--accent-text); }
.filtres-pop__btn.is-actif { border-color: var(--accent-border); color: var(--accent-text); background: var(--accent-bg); }
.filtres-pop__badge {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--accent-bg); color: var(--accent-text);
  font-size: 11px; font-weight: 400; line-height: 18px; text-align: center;
}
.filtres-pop__panneau {
  display: none; position: absolute; top: calc(100% + 6px); left: 0; z-index: 60;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-md);
  padding: 14px; min-width: 280px;
  flex-direction: column; gap: 10px;
}
.filtres-pop.is-open .filtres-pop__panneau { display: flex; }
.filtres-pop__panneau .filtre-select { width: 100%; }
.filtres-pop__effacer {
  align-self: flex-end; background: none; border: none; cursor: pointer;
  font-size: 12px; font-weight: 400; color: var(--ink-4); padding: 4px 6px;
}
.filtres-pop__effacer:hover { color: var(--danger); }

/* ── BADGE DE RÉFÉRENCE (n° de référence produit/composant) — composant partagé,
   modelé sur le badge gris monospace du stock. Une seule apparence partout. ── */
.badge-ref {
  font-family: monospace;
  font-size: 12px;
  background: var(--line-soft);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 2px 8px;
  color: var(--ink-3);
}

/* ── 26. CHAMPS OBLIGATOIRES / ERREURS IN-MODALE ──────── */
.champ-obligatoire { color: var(--danger); margin-left: 2px; font-weight: 400; }
.modale-erreur { color: var(--danger); font-size: var(--fs-sm); margin: 2px 0 10px; }
.champ-erreur { border-color: var(--danger) !important; }

/* ══════════════════════════════════════════════════════════════════════
   CONVENTION DES COULEURS DE STATUT (chips .chip--*)
   ──────────────────────────────────────────────────────────────────────
   ROUGE  (--danger)  = attention requise : rupture, retard, erreur, refusé
   BLEU   (--accent)  = en cours (travail actif)
   VERT   (--success) = succès / terminé / OK
   ORANGE (--warning) = en attente (attente passive d'une action à venir)
   GRIS   (--ink-4)   = inactif / passif / annulé / splitté
   (Les bandes latérales .asm-strip ont été supprimées : la chip est le seul
   porteur de couleur de statut sur les lignes.)
   ══════════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════════════════
   27. RESPONSIVE (P3) — Desktop (> 768px) INCHANGÉ : tout est ajouté SOUS
   le breakpoint uniquement. Seuils : tablette 768px, mobile 480px.
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 768px) {
  /* En-tête de page : les actions peuvent revenir à la ligne */
  .page-head { flex-wrap: wrap; }

  /* Barre de recherche : jamais plus large que l'écran */
  .search-box, .search-box > input { width: 100%; }

  /* Grilles de formulaire 2 colonnes -> 1 colonne */
  .form-row { grid-template-columns: 1fr; }

  /* ── Tableaux-cartes à colonnes fixes -> cartes empilées ──
     Bande de couleur à gauche sur toute la hauteur ; chaque cellule en pleine
     largeur, l'une sous l'autre ; en-têtes de colonnes masquées. (Les grilles
     du portail client gardent leurs propres media queries.) */
  .asm-header.asm-cols, .asm-header.of-cols, .asm-header.cl-cols, .asm-header.rh-cols,
  .asm-header.cs-cols, .asm-header.inv-cols, .asm-header.st-prod-cols, .asm-header.st-comp-cols,
  .asm-header.st-def-cols, .asm-header.st-mouv-cols { display: none; }

  .asm-cols, .of-cols, .cl-cols, .rh-cols, .cs-cols, .inv-cols,
  .st-prod-cols, .st-comp-cols, .st-def-cols, .st-mouv-cols {
    grid-template-columns: 5px 1fr;
    row-gap: 2px;
  }
  .asm-cols > .asm-strip, .of-cols > .asm-strip, .cl-cols > .asm-strip, .rh-cols > .asm-strip,
  .cs-cols > .asm-strip, .inv-cols > .asm-strip, .st-prod-cols > .asm-strip,
  .st-comp-cols > .asm-strip, .st-def-cols > .asm-strip, .st-mouv-cols > .asm-strip {
    grid-row: 1 / -1;
  }
  .asm-cols > *:not(.asm-strip), .of-cols > *:not(.asm-strip), .cl-cols > *:not(.asm-strip),
  .rh-cols > *:not(.asm-strip), .cs-cols > *:not(.asm-strip), .inv-cols > *:not(.asm-strip),
  .st-prod-cols > *:not(.asm-strip), .st-comp-cols > *:not(.asm-strip),
  .st-def-cols > *:not(.asm-strip), .st-mouv-cols > *:not(.asm-strip) {
    grid-column: 2 / -1; min-width: 0; padding-top: 0; padding-bottom: 4px;
  }
}

@media (max-width: 480px) {
  .page { padding: 14px; }
  .page-head { padding: 12px 14px; }
  /* Grille d'opérateurs / étapes du poste de scan : 2 colonnes en mobile */
  .etapes-grid { grid-template-columns: 1fr 1fr; }
}

/* ── LOT A1 — Filet de scroll universel pour les <table> sur mobile ──
   Toute <table> du contenu de page (hors navbar) devient scrollable horizontalement
   sous 768px au lieu de déborder. `screen and` protège les documents imprimables
   (étiquettes 62mm, fiches OF/SAV) — la règle ne s'applique JAMAIS à l'impression.
   Pas de width:100% (n'impose pas le scroll aux tables qui tiennent déjà).
   Échappatoire : ajouter .no-mobile-scroll à une table pour l'exclure. */
@media screen and (max-width: 768px) {
  .main-content table:not(.no-mobile-scroll) {
    display: block;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* ════════ Champ éditable verrouillable (MNP.champEditable : crayon + Entrée) ════════ */
.ce { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; }
.ce.ce--multi { display: flex; flex-direction: column; align-items: stretch; gap: 4px; }
.ce-view { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.ce.ce--multi .ce-view { white-space: pre-wrap; }
.ce-view--vide { color: var(--ink-4); }
.ce-pencil {
  flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
  padding: 3px; border: none; background: none; color: var(--ink-4); cursor: pointer;
  border-radius: 5px; line-height: 0; transition: color .12s, background .12s;
}
.ce-pencil:hover { color: var(--brand); background: var(--surface-2); }
.ce-input {
  flex: 1 1 auto; width: 100%; box-sizing: border-box; padding: 6px 10px;
  border: 1.5px solid var(--brand); border-radius: 6px; font: inherit; font-size: 13px;
  outline: none; background: var(--surface); color: var(--ink);
}
.ce-input:disabled { opacity: .6; cursor: progress; }
.ce.ce--multi .ce-input { resize: vertical; min-height: 60px; line-height: 1.45; }
.ce-indice { font-size: 11px; color: var(--ink-4); }

/* ── Sélecteur de MOIS « maison » (MNP.moisPicker, défini dans base.html) ─────────────
   Identique sur Chrome / Edge / Firefox / Safari : que du CSS/HTML standard, aucune
   dépendance à <input type=month>. Bouton + panneau (grille 12 mois + nav année). */
.mois-picker { position: relative; display: inline-block; }
.mp-btn {
    display: inline-flex; align-items: center; justify-content: space-between; gap: 8px;
    width: 180px; padding: 8px 12px; font: inherit; text-align: left; cursor: pointer;
    background: var(--surface); color: var(--ink);
    border: 1px solid var(--line); border-radius: var(--r-md);
}
.mp-btn:hover { border-color: var(--brand); }
.mp-btn.mp-vide .mp-lbl { color: var(--ink-4); }
.mp-caret { color: var(--ink-4); font-size: 11px; flex-shrink: 0; }
.mp-pop {
    position: absolute; z-index: 300; top: 100%; left: 0; margin-top: 4px; width: 240px;
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--r-md); box-shadow: var(--sh-md); padding: 10px;
}
.mp-pop[hidden] { display: none; }
/* Ouverture vers le HAUT (au-dessus du bouton) : posée par JS quand la place manque en dessous
   (ex. champ en bas d'une modale à overflow-y). Le panneau reste flottant (position:absolute),
   ne pousse rien et n'allonge pas la modale. */
.mp-pop--haut { top: auto; bottom: 100%; margin-top: 0; margin-bottom: 4px; }
.mp-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.mp-year { font-weight: 700; font-size: 14px; color: var(--ink); }
.mp-nav {
    width: 28px; height: 28px; border: 1px solid var(--line); border-radius: 6px;
    background: var(--surface); color: var(--ink); cursor: pointer; font-size: 16px; line-height: 1;
}
.mp-nav:hover { background: var(--brand-soft); border-color: var(--brand); }
.mp-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.mp-m {
    padding: 8px 4px; border: 1px solid var(--line); border-radius: 6px;
    background: var(--surface); color: var(--ink); cursor: pointer; font-size: 12px;
}
.mp-m:hover { background: var(--brand-soft); border-color: var(--brand); }
.mp-m.is-sel { background: var(--brand); color: #fff; border-color: var(--brand); font-weight: 600; }
.mp-foot { display: flex; justify-content: space-between; gap: 6px; margin-top: 8px; }
.mp-clear, .mp-now {
    background: none; border: none; color: var(--brand); cursor: pointer;
    font: inherit; font-size: 12px; padding: 4px 2px;
}
.mp-clear:hover, .mp-now:hover { text-decoration: underline; }

/* ── Lien de document en cours de génération (voir MNP.docChargement, base.html) ──
   Ajoute un petit spinner APRÈS le libellé et grise le lien pendant que le PDF se génère
   côté serveur. On ne met PAS pointer-events:none : le clic doit encore atteindre le
   handler pour être annulé (return false = anti double-clic) ; sur une carte cliquable, le
   pass-through déclencherait sinon la navigation de la carte. */
a.is-loading { opacity: 0.6; cursor: progress; }
a.is-loading::after {
    content: "";
    display: inline-block;
    width: 0.85em; height: 0.85em;
    margin-left: 0.5em;
    vertical-align: -0.15em;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: doc-spin 0.6s linear infinite;
}
@keyframes doc-spin { to { transform: rotate(360deg); } }
