/*
 * Feuille unique du portail (v2, 18/09/2026). Issue de maquette/css/portail.css (référence historique du
 * 17/09) mais ne la suit plus : jetons responsives, contraste AA, composants corrigés pour le téléphone.
 * Catalogue des classes et paliers : docs/design-tokens.md.
 * Paliers : < 820 px (barre basse, max-width:819.98px) et ≤ 520 px (téléphone). Grilles : 1180, 1080, 1000 (connexion), 980.
 */

/* ---------- tokens (charte C2M) ---------- */
:root{
  --bg:#F4F7F9; --surface:#FFFFFF; --surface-2:#F7F9FB; --line:#E3E8EE; --line-2:#EEF2F6;
  --ink:#1B2A4E; --navy:#1F3168; --ink-2:#4A5872; --ink-3:#647083;
  --green:#2E9E5B; --green-dark:#1E7A44; --green-soft:#E6F5EC; --green-soft-2:#D3EEDC;
  --blue:#2F6BD8; --blue-dark:#2453B0; --blue-soft:#E7EEFB; --blue-soft-2:#D6E2F8;
  --red:#E23D3D; --red-dark:#B82B2B; --red-soft:#FCE9E9; --red-soft-2:#F8D6D6;
  --orange:#F3A21A; --orange-dark:#B8760A; --orange-soft:#FFF4DD; --orange-soft-2:#FBE7BD;
  --purple:#7E3FF2; --purple-dark:#5B2BB3; --purple-soft:#F0E9FC; --purple-soft-2:#E3D7F9;
  --grey-soft:#EEF1F5;
  /* ajustements AA : fond des actions pleines, texte sur orange pâle, série N-1, ombre de défilement */
  --accent-bg:#1E7A44; --on-accent:#FFFFFF; --orange-ink:#8A5A00; --chart-prev:#AFC0D4; --defil:rgba(27,42,78,.35); --barre:color-mix(in srgb,var(--ink-3) 70%,transparent);
  /* panneaux flottants : fond et voile (en sombre, le panneau se distingue des cartes) */
  --pop-bg:var(--surface); --voile:rgba(15,21,32,.38);
  --shadow:0 2px 6px rgba(27,42,78,.05),0 14px 30px -18px rgba(27,42,78,.18);
  --r:14px; --r-sm:10px; --r-xs:6px;
  --side:196px; --top:62px;
  /* typographie */
  --fs-base:14.5px; --fs-sm:13px; --fs-xs:12px; --fs-2xs:11px;
  --fs-h1:34px; --fs-h1-page:26px; --fs-h2:19px; --fs-h3:15px;
  --fs-tbl:13.5px; --fs-kv:18px; --fs-stat:28px; --fs-pill:10.5px;
  /* espacements */
  --pad-page:24px; --gap-page:22px; --gap-grid:16px; --pad-card:18px;
  --cell-y:12px; --cell-x:14px;
  --bottom:0px;                 /* hauteur de la barre basse (0 quand elle n'existe pas) */
  --font:'Nunito',ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
  --script:'Caveat','Segoe Script','Bradley Hand',cursive;
  color-scheme:light dark;
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --bg:#0F1520; --surface:#171E2B; --surface-2:#1C2534; --line:#2A3446; --line-2:#222B3A;
    --ink:#E7ECF5; --navy:#E7ECF5; --ink-2:#B3BDCE; --ink-3:#7F8BA0;
    --green:#3FB56E; --green-dark:#8FE0AF; --green-soft:#16301F; --green-soft-2:#1C4028;
    --blue:#5B8BEA; --blue-dark:#A9C3F5; --blue-soft:#182640; --blue-soft-2:#1E3153;
    --red:#EA5A5A; --red-dark:#F5A3A3; --red-soft:#3A1B1B; --red-soft-2:#4B2222;
    --orange:#F5B23E; --orange-dark:#F6CF86; --orange-soft:#3A2B10; --orange-soft-2:#4B3814;
    --purple:#9A6BF5; --purple-dark:#C9B3F8; --purple-soft:#271B44; --purple-soft-2:#33245A;
    --grey-soft:#232C3B;
    --accent-bg:#3FB56E; --on-accent:#0F1520; --orange-ink:#F6CF86; --chart-prev:#5B6B85; --defil:rgba(255,255,255,.18); --pop-bg:var(--surface-2); --voile:rgba(0,0,0,.55);
    --shadow:0 2px 6px rgba(0,0,0,.4),0 14px 30px -18px rgba(0,0,0,.7);
  }
}
:root[data-theme="dark"]{
  --bg:#0F1520; --surface:#171E2B; --surface-2:#1C2534; --line:#2A3446; --line-2:#222B3A;
  --ink:#E7ECF5; --navy:#E7ECF5; --ink-2:#B3BDCE; --ink-3:#7F8BA0;
  --green:#3FB56E; --green-dark:#8FE0AF; --green-soft:#16301F; --green-soft-2:#1C4028;
  --blue:#5B8BEA; --blue-dark:#A9C3F5; --blue-soft:#182640; --blue-soft-2:#1E3153;
  --red:#EA5A5A; --red-dark:#F5A3A3; --red-soft:#3A1B1B; --red-soft-2:#4B2222;
  --orange:#F5B23E; --orange-dark:#F6CF86; --orange-soft:#3A2B10; --orange-soft-2:#4B3814;
  --purple:#9A6BF5; --purple-dark:#C9B3F8; --purple-soft:#271B44; --purple-soft-2:#33245A;
  --grey-soft:#232C3B;
  --accent-bg:#3FB56E; --on-accent:#0F1520; --orange-ink:#F6CF86; --chart-prev:#5B6B85; --defil:rgba(255,255,255,.18); --pop-bg:var(--surface-2); --voile:rgba(0,0,0,.55);
  --shadow:0 2px 6px rgba(0,0,0,.4),0 14px 30px -18px rgba(0,0,0,.7);
}
/* les jetons portent le responsive : les composants s'écrivent une fois */
@media (max-width:819.98px){:root{
  --pad-page:14px; --gap-page:16px; --gap-grid:12px; --pad-card:16px;
  --fs-h1:24px; --fs-h1-page:22px;
  --bottom:calc(58px + env(safe-area-inset-bottom));
}}
@media (max-width:520px){:root{
  --fs-base:14px; --fs-sm:12.5px; --fs-xs:11.5px; --fs-2xs:10.5px;
  --fs-h1:20px; --fs-h1-page:20px; --fs-h2:16px; --fs-h3:14.5px;
  --fs-tbl:13px; --fs-kv:16px; --fs-stat:20px; --fs-pill:10px;
  --pad-card:14px; --gap-page:14px; --gap-grid:10px; --cell-y:8px; --cell-x:10px;
  --r:12px; --top:52px;
}}

/* ---------- base ---------- */
*{box-sizing:border-box}
html,body{margin:0;padding:0}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%;scroll-padding-top:calc(var(--top) + 12px)}
body{font-family:var(--font);font-size:var(--fs-base);line-height:1.5;color:var(--ink);background:var(--bg);-webkit-font-smoothing:antialiased}
h1,h2,h3,h4{margin:0;font-weight:800;line-height:1.2;color:var(--navy)}
h1{font-size:var(--fs-h1);font-weight:900;letter-spacing:-.01em}
h2{font-size:var(--fs-h2)}
h3{font-size:var(--fs-h3)}
h1,h2,h3,.b{overflow-wrap:break-word}
p{margin:0}
a{color:var(--green-dark);text-decoration:none}
a:hover{text-decoration:underline}
button{font:inherit;color:inherit}
img{max-width:100%;display:block}
svg{flex-shrink:0}
table{border-collapse:collapse;width:100%}
:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.muted{color:var(--ink-2)} .small{font-size:var(--fs-sm)} .tiny{font-size:var(--fs-xs);color:var(--ink-3)}
.mono{font-variant-numeric:tabular-nums}
.nowrap{white-space:nowrap}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.meta{display:flex;flex-wrap:wrap;column-gap:10px;row-gap:2px;font-size:var(--fs-xs);color:var(--ink-2)}
.eyebrow{color:var(--green-dark);font-weight:900;font-size:12px;letter-spacing:.08em;text-transform:uppercase}
.alerte{color:var(--red-dark);font-weight:700;font-size:var(--fs-sm)}
.clamp-1{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.clamp-2{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

/* ---------- controls ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:9px 14px;border-radius:var(--r-sm);border:1px solid var(--line);background:var(--surface);cursor:pointer;font-weight:700;font-size:13.5px;line-height:1.2;white-space:nowrap;color:var(--ink);text-decoration:none}
.btn:hover{background:var(--surface-2);text-decoration:none}
.btn.primary{background:var(--accent-bg);border-color:var(--accent-bg);color:var(--on-accent)}
.btn.primary:hover{background:var(--accent-bg);filter:brightness(1.08)}
.btn.soft{background:var(--green-soft);border-color:transparent;color:var(--green-dark)}
.btn.soft:hover{background:var(--green-soft-2)}
.btn.pink{background:var(--red-soft);border-color:transparent;color:var(--red-dark)}
.btn.sm{padding:6px 10px;font-size:12.5px}
.btn.block{width:100%}
.btn svg{width:15px;height:15px}
.btn .arr{margin-left:auto}
.input,.select,.textarea{width:100%;padding:9px 12px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface);color:var(--ink);font:inherit;font-size:14px}
.input.qte{max-width:110px}
.textarea{min-height:96px;resize:vertical}
.field{display:flex;flex-direction:column;gap:6px}
.field label{font-size:13px;font-weight:800;color:var(--ink-2)}
.form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}
.form-grid .span2{grid-column:1/-1}
.form-ligne{display:flex;gap:8px;align-items:stretch}
/* rangée secondaire d'un formulaire : repli (commentaire) à gauche, action discrète à droite */
.form-ligne.suite{flex-wrap:wrap;align-items:center}
.form-ligne.suite > .repli{flex:1 1 auto;min-width:0} .form-ligne.suite > .repli[open]{flex-basis:100%}
.form-ligne.suite > .btn{margin-left:auto}
.dropzone{border:1.5px dashed var(--line);border-radius:var(--r-sm);padding:18px;text-align:center;color:var(--ink-2);background:var(--surface-2);font-size:13.5px}
.dropzone strong{color:var(--ink)}
.dropzone svg{width:22px;height:22px;margin:0 auto 6px;display:block;color:var(--green)}
.search{position:relative}
.search svg{position:absolute;left:12px;top:50%;transform:translateY(-50%);width:16px;height:16px;color:var(--ink-3)}
.search .input{padding-left:36px}
.recherche{max-width:560px}
/* Le bouton caméra de la Vue 360° (01/10/2026), dans le champ, à droite. ⚠ `.search svg` place toute
   icône du formulaire à gauche : celle du bouton reprend sa place normale. */
.search .scan-btn{position:absolute;right:4px;top:50%;transform:translateY(-50%);width:38px;height:38px;border:0;border-radius:10px;background:var(--green-soft);color:var(--green-dark);display:grid;place-items:center;cursor:pointer}
.search .scan-btn[hidden]{display:none}
.search .scan-btn svg{position:static;transform:none;width:20px;height:20px;color:currentColor}
.search:has(.scan-btn:not([hidden])) .input{padding-right:48px}
dialog.scan{border:0;padding:0 0 16px;width:min(560px,100vw);max-width:100vw;max-height:100dvh;border-radius:16px;background:#0F1520;color:#fff;text-align:center;overflow:hidden}
dialog.scan::backdrop{background:rgba(0,0,0,.75)}
dialog.scan .scan-cadre{position:relative;background:#000;aspect-ratio:4/3;overflow:hidden}
dialog.scan video{width:100%;height:100%;object-fit:cover;display:block}
dialog.scan .visee{position:absolute;left:12%;right:12%;top:30%;bottom:30%;border:3px solid #3FB56E;border-radius:12px;box-shadow:0 0 0 9999px rgba(0,0,0,.35)}
dialog.scan .scan-etat{margin:12px 16px;font-weight:700;font-size:14px}
dialog.scan .btn{min-width:140px}
@media (max-width:520px){ dialog.scan{border-radius:0;width:100vw;height:100dvh} dialog.scan .scan-cadre{aspect-ratio:auto;height:calc(100dvh - 130px)} }
/* ============================================================================
   Espace achats v2 — aperçu (docs/achats-v2.md, 27/09/2026).
   ⚠ CET ÉCRAN SORT DE LA COLONNE DE 1240 px, et lui seul : la liste et son
     panneau ne tiennent pas à côté dans la largeur des autres pages. Le
     sélecteur passe par :has(), pour ne rien changer au gabarit commun.
   ⚠ PAS DE VARIANTE TÉLÉPHONE (décision de Bruno) : sous 1000 px l'écran le
     DIT au lieu de se démonter en lignes-cartes illisibles.
   ========================================================================= */
.content:has(.reassort){max-width:none;padding-left:18px;padding-right:18px}
.reassort{display:flex;flex-direction:column;gap:12px;min-width:0}
.ra-tete{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap}
.ra-tete h1{font-size:var(--fs-h1-page)}
.ra-tete .tiny{margin-top:2px}
.ra-cible{display:flex;align-items:center;gap:6px}
.ra-cible .lbl{font-size:12.5px;color:var(--ink-3);margin-right:2px}
.ra-cible button{border:1px solid var(--line);background:var(--surface);border-radius:var(--r-sm);padding:6px 10px;font-weight:700;font-size:12.5px;cursor:pointer;color:var(--ink)}
.ra-cible button.on{background:var(--accent-bg);border-color:var(--accent-bg);color:var(--on-accent)}
.ra-vues{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.ra-vues .tabs{flex:1 1 auto}
.ra-vues .tabs a b{margin-left:6px;opacity:.75}
.ra-vues .search{flex:0 1 300px}

/* Les filtres fins et les pastilles de ce qui est coché. */
.ra-filtres{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
/* Le nombre de chaque option, à droite et détaché du texte (Bruno, 03/10/2026 : « collé au texte » —
   le <label> n'avait pas la classe `opt` qui le met en ligne souple). */
.ra-filtres .fmulti .menu{min-width:19rem}
/* La plage de rotation tapée (03/10/2026) : « De [ ] à [ ] / mois », sous les tranches à cocher. */
.rot-plage{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:6px;padding:8px 8px 2px;border-top:1px solid var(--line-2);
  font-size:var(--fs-sm);font-weight:700;color:var(--ink-2)}
.rot-plage .input{width:4.5rem;min-height:34px;padding:4px 8px;text-align:right}
.rot-plage .titre{flex:1 0 100%;font-size:var(--fs-xs);font-weight:800;color:var(--ink-3)}
.rot-plage.seuils{gap:8px 10px}
.rot-plage .seuil{display:flex;flex:1 0 100%;align-items:center;gap:8px;font-weight:700;color:var(--ink-2)}
.rot-plage .seuil .input{width:3.6rem}
.ra-filtres .fmulti .opts label .n{margin-left:auto;padding:0 7px;border-radius:999px;background:var(--surface-2);color:var(--ink-3);font-size:11.5px;font-weight:800;line-height:1.6;font-variant-numeric:tabular-nums;flex:none}
.ra-filtres .chip{display:inline-flex;align-items:center;gap:5px;background:var(--green-soft);color:var(--green-dark);border-radius:999px;padding:3px 10px;font-size:12px;font-weight:700;text-decoration:none}
.ra-filtres .chip:hover{background:var(--green-soft-2)}
.ra-filtres .chip svg{width:11px;height:11px}
.ra-filtres .chip.vide{background:none;color:var(--ink-3);text-decoration:underline}
/* Le nombre d'articles après filtres (05/10/2026) : poussé au bout de la rangée des filtres. */
.ra-compte{margin-left:auto;font-size:13px;color:var(--ink-2);white-space:nowrap}
.ra-compte b{color:var(--navy);font-size:14px;font-variant-numeric:tabular-nums}
.ra-compte .sur{color:var(--ink-3);font-size:12px}

/* Le champ de quantité : le seul de la page, donc il se voit. Vert dès qu'il porte une valeur. */
.ra-q{width:72px;text-align:right;padding:2px 6px;font-weight:800;font-size:12.5px}
.ra-q.on{border-color:var(--green);background:var(--green-soft)}
/* Le conseil, bouton qui le met dans « Je commande » (05/10/2026) : le nombre reste lisible comme une
   valeur de colonne, la flèche dit qu'il part à droite. */
.ra-prendre-un{display:inline-flex;align-items:center;gap:2px;border:1px solid transparent;border-radius:var(--r-xs, 6px);
  background:var(--green-soft);color:var(--green-dark);font:inherit;font-weight:800;padding:2px 4px 2px 7px;cursor:pointer;min-height:26px}
.ra-prendre-un:hover,.ra-prendre-un:focus-visible{border-color:var(--green)}
.ra-prendre-un svg{width:12px;height:12px}

/* La commande, en bas : le total à gauche, les sorties à droite. */
.ra-pied{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;
         background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r-md);padding:10px 14px;
         position:sticky;bottom:10px;box-shadow:var(--shadow)}
.ra-pied .t{font-size:13.5px}
.ra-pied .t .tiny{margin-left:8px;color:var(--ink-3)}
.ra-pied .a{display:flex;align-items:center;gap:8px}
.ra-pied .a form{display:inline}
.ra-pied .a [hidden]{display:none}
/* L'échange suggéré (30/09/2026) : sous le nom dans la vue des échanges, en bloc dans le panneau. */
.ra-ech{display:block;font-size:12px;font-weight:700;white-space:normal;color:var(--ink-2)}
.ra-ech.recuperer{color:var(--green-dark)}
.ra-d-ech{margin:10px 0;padding:10px 12px;background:var(--blue-soft);border-radius:var(--r-sm);font-size:13.5px}
.ra-d-ech ul{margin:6px 0;padding-left:18px}
.ra-d-ech .tiny{display:block}

/* Deux pavés à défilement propre : le panneau reste en vue pendant qu'on
   parcourt la liste. C'est là tout l'intérêt du côte-à-côte. */
.ra-main{display:grid;grid-template-columns:minmax(0,1fr) clamp(420px,34%,600px);gap:14px;align-items:start}
/* ⚠ SOUS 1 080 PX, LES DEUX COLONNES S'EMPILENT — sinon la seconde, qui vaut au moins 420 px, pousse
   la page au-delà de la fenêtre et TOUT défile de côté, menu compris. L'écran est entré dans la barre
   du téléphone le 27/09/2026 (« Espace achats » mène à /achats/v2) : il devait cesser de supposer une
   grande largeur. Le détail passe dessous, et la liste reprend toute la place.
   ⚠ Le panneau perd alors `sticky` et sa hauteur bornée : collé en bas d'une page qui défile, il se
   serait superposé à la liste. */
@media (max-width:1080px){
  .ra-main{grid-template-columns:minmax(0,1fr)}
  .ra-detail{position:static;max-height:none}
  .ra-liste{max-height:calc(100vh - 300px)}
}
.ra-liste{background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r-md);overflow:auto;max-height:calc(100vh - 260px)}
.ra-detail{background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r-md);padding:12px 14px;position:sticky;top:12px;max-height:calc(100vh - 200px);overflow:auto;display:flex;flex-direction:column;gap:10px}

/* Le tableau dense du réassort (27/09/2026, demande de Bruno) : une ligne par article, police
   serrée, le maximum d'articles à l'écran. Ce qui tenait sur trois lignes est réparti en colonnes. */
/* ⚠ `min-width` : en `table-layout:fixed`, un tableau à `width:100%` trop étroit ne défile pas, il
   RABOTE les largeurs demandées au prorata — et les titres se remettraient à se couper, en silence.
   685 px, c'est la somme des sept colonnes de droite (532) et du minimum du nom (150). En dessous,
   `.ra-liste` défile, ce qui arrive vers 1 390 px de page.
   ⚠ HUIT COLONNES ET UN NOM LISIBLE NE TIENNENT PAS À 1 280 PX, c'est mesuré : la liste y fait
   564 px et les colonnes de droite en réclament 532, il resterait 32 px pour le nom. Rapetisser
   l'en-tête ne sauve rien (476 px à 9,5 px de police, donc 88 px pour le nom, et un titre qu'on ne
   lit plus). À cette largeur on fait donc défiler, plutôt que de tout écraser : aucune colonne n'est
   cachée en douce. Retirer « Dépôt » et « En route » sous 1 400 px rendrait 132 px au nom — les deux
   sont répétés dans le panneau — mais c'est une décision à prendre, pas à deviner. */
table.ra-tbl{width:100%;min-width:685px;border-collapse:separate;border-spacing:0;font-size:12px;table-layout:fixed}
/* ⚠ L'EN-TÊTE TIENT SUR UNE LIGNE, ET C'EST LA COLONNE QUI S'Y PLIE (27/09/2026, demande de Bruno :
   « diminua a coluna produit para caber o nome das colunas confortavelmente »). Il avait le droit de
   passer à deux lignes du temps de la colonne « Ce qu'il faut faire », qui n'existe plus ; depuis,
   ce droit servait à cacher que cinq colonnes étaient plus étroites que leur propre titre. */
table.ra-tbl thead th{position:sticky;top:0;z-index:2;background:var(--surface-2);color:var(--ink-3);text-align:left;
  font-size:10.5px;text-transform:uppercase;letter-spacing:.02em;padding:5px 6px;border-bottom:1px solid var(--line);
  white-space:nowrap;line-height:1.15;vertical-align:bottom}
table.ra-tbl thead th.num{text-align:right}
table.ra-tbl thead th a.tri{display:inline-flex;align-items:center;gap:3px;color:inherit;text-decoration:none}
table.ra-tbl thead th a.tri:hover{color:var(--ink);text-decoration:underline}
table.ra-tbl thead th a.tri.on{color:var(--green-dark)}
table.ra-tbl thead th a.tri .fl{font-size:10px}
table.ra-tbl td{padding:4px 6px;border-bottom:1px solid var(--line-2);vertical-align:middle;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
table.ra-tbl td.num{text-align:right;font-variant-numeric:tabular-nums}
table.ra-tbl td.vide{color:var(--ink-3)}
table.ra-tbl tr.on td{background:var(--green-soft)}
table.ra-tbl tr[data-ean]{cursor:pointer}
table.ra-tbl tr[data-ean]:hover td{background:var(--surface-2)}
table.ra-tbl tr.on:hover td{background:var(--green-soft)}

/* Les largeurs : seule la colonne du produit et celle du verdict respirent. */
/* ⚠ CHAQUE LARGEUR EST CELLE DE SON TITRE, MESURÉE AU NAVIGATEUR AVEC NUNITO : Stock 57,
   Rota. / mois 90, En route 75, Tient 52, Dépôt 57, Conseillé 80, Je commande 99 — 510 px en tout,
   là où le CSS n'en donnait que 406. Cinq colonnes étaient plus étroites que leur propre titre, qui
   passait donc à la ligne pendant que le nom du produit, seul en `auto`, gardait tout le reste.
   ⚠⚠ MESURER AVEC LA VRAIE POLICE, PAS AVEC CELLE DE SECOURS : une première mesure, faite sans
   charger Nunito, donnait 66 px pour « Rota. / mois » et 92 pour « Je commande » au lieu de 90 et
   99 — l'écart atteint 36 % sur une colonne, et le titre ressortait coupé (« ROTA. / MOI »). Le banc
   de mesure charge donc Nunito et attend `document.fonts.ready`.
   Les valeurs ci-dessous ajoutent deux à six pixels : une flèche de tri qui change d'état ne doit
   pas rouvrir le problème. Tout le surplus va toujours au nom, qui est ce qu'on parcourt des yeux. */
table.ra-tbl th.lib,table.ra-tbl td.lib{width:auto;min-width:150px}
table.ra-tbl td.lib .b{font-weight:700}
table.ra-tbl th:nth-child(2),table.ra-tbl td:nth-child(2){width:60px}
table.ra-tbl th:nth-child(3),table.ra-tbl td:nth-child(3){width:92px}
table.ra-tbl th:nth-child(4),table.ra-tbl td:nth-child(4){width:78px}
table.ra-tbl th:nth-child(5),table.ra-tbl td:nth-child(5){width:58px}
table.ra-tbl th:nth-child(6),table.ra-tbl td:nth-child(6){width:60px}
table.ra-tbl th:nth-child(7),table.ra-tbl td:nth-child(7){width:82px}
table.ra-tbl th.qte,table.ra-tbl td.qte{width:102px}

/* Le verdict n'a plus de colonne : sa couleur tient sur le bord gauche de la rangée, et elle dit
   du TEMPS — rouge : ça manque ou ça va manquer ; ambre : à vérifier ; vert : une autre voie. */
table.ra-tbl tbody tr{border-left:3px solid transparent}
table.ra-tbl tbody tr td:first-child{border-left:3px solid transparent;padding-left:8px}
table.ra-tbl tbody tr.v-todo td:first-child{border-left-color:var(--red)}
table.ra-tbl tbody tr.v-ko   td:first-child{border-left-color:var(--orange-dark)}
table.ra-tbl tbody tr.v-soon td:first-child{border-left-color:var(--green)}
table.ra-tbl tbody tr.v-done td:first-child{border-left-color:transparent}
table.ra-tbl td .sais{margin-left:3px;color:var(--orange-dark);font-size:10px}
table.ra-tbl td.tient{font-variant-numeric:tabular-nums}

/* ⚠ LE VERDICT RESTE UNE PHRASE, JAMAIS UNE PASTILLE EN CAPITALES : ici il est court, et sa couleur
   dit du TEMPS (rouge : ça manque ou ça va manquer ; ambre : à vérifier ; vert : une autre voie). */
.ra-v{display:block;padding-left:7px;border-left:3px solid var(--line);line-height:1.3;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis}
.ra-v.todo{border-color:var(--red);font-weight:700}
.ra-v.ko{border-color:var(--orange-dark)}
.ra-v.soon{border-color:var(--green)}
.ra-v.done{border-color:var(--line);color:var(--ink-3)}
.ra-ceder{color:var(--orange-dark);font-weight:600}
.ra-borne{padding:10px 12px}

.ra-d-tete .lib{font-weight:900;font-size:15px;line-height:1.25}
/* La décision, en haut et sur une rangée : la quantité en gros, la phrase à côté. */
.ra-d-decide{display:flex;align-items:center;gap:12px;border-radius:var(--r-sm);padding:10px 12px}
.ra-d-decide .q{display:flex;flex-direction:column;align-items:center;min-width:76px}
.ra-d-decide .q b{font-size:30px;font-weight:900;line-height:1}
.ra-d-decide .q span{font-size:11.5px;opacity:.85;white-space:nowrap}
.ra-d-decide .p{display:flex;flex-direction:column;min-width:0}
.ra-d-decide .p b{font-size:13.5px}
.ra-d-decide .p span{font-size:12.5px;line-height:1.3}
.ra-d-decide.todo{background:var(--red-soft);color:var(--red-dark)}
.ra-d-decide.ko{background:var(--orange-soft);color:var(--orange-ink)}
.ra-d-decide.soon{background:var(--green-soft);color:var(--green-dark)}
.ra-d-decide.done{background:var(--surface-2);color:var(--ink-2)}

/* Chez vous / à la centrale : deux colonnes de lignes clé-valeur, denses. */
.ra-d-deux{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.ra-d-deux .b{border:1px solid var(--line-2);border-radius:var(--r-sm);padding:10px 12px;min-width:0}
.ra-d-deux .t{font-size:11.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--green-dark);font-weight:900;margin:0 0 8px}
/* Les deux nombres qui décident, en grand. */
.ra-kpis{display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-bottom:4px}
.ra-kpis .k{background:var(--surface-2);border-radius:var(--r-xs);padding:7px 9px;min-width:0}
.ra-kpis .l{display:block;font-size:11.5px;font-weight:800;color:var(--ink-3);line-height:1.2}
.ra-kpis .v{display:block;font-size:22px;font-weight:900;line-height:1.15;color:var(--ink);margin-top:2px}
.ra-kpis .v.down{color:var(--red-dark)}
.ra-kpis .v.up{color:var(--green-dark)}
.ra-kpis .s{display:block;font-size:10.5px;color:var(--ink-3);line-height:1.2;margin-top:1px}
/* Puis des lignes séparées : libellé à gauche, valeur à droite, l'explication en petit dessous. */
.ra-lignes{margin:0}
/* ⚠ RIEN NE SE COUPE AU MILIEU D'UN MOT : la carte n'a que ~157 px utiles dans le panneau, et la règle
   héritée `overflow-wrap:break-word` coupait la date (« 22/09/20 | 26 ») ou écrasait le libellé à une
   lettre par ligne (vu à la capture). Libellé et valeur sont donc insécables ; quand ils ne tiennent pas
   côte à côte, la valeur passe entière à la ligne, alignée à droite. */
.ra-lignes > div{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;column-gap:10px;padding:7px 0;border-top:1px solid var(--line-2)}
.ra-lignes dt{font-size:13px;color:var(--ink-2);font-weight:700;white-space:nowrap}
.ra-lignes dd{margin:0 0 0 auto;font-size:14px;font-weight:900;color:var(--ink);text-align:right;white-space:nowrap;overflow-wrap:normal}
.ra-lignes small{flex:1 0 100%;font-size:11.5px;color:var(--ink-3);line-height:1.3;margin-top:2px}
.ra-arrivees{list-style:none;margin:2px 0 6px;padding:0;font-size:12px;color:var(--ink-2)}
.ra-arrivees li{padding:2px 0}
@media (max-width:520px){ .ra-d-deux{grid-template-columns:1fr} }

.ra-d-marge{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.ra-d-marge .m{border:1px solid var(--line-2);border-radius:var(--r-sm);padding:8px 10px;display:flex;flex-direction:column}
.ra-d-marge .m.perte{background:var(--red-soft)}
.ra-d-marge .l{font-size:11px;text-transform:uppercase;letter-spacing:.02em;color:var(--ink-3);font-weight:800}
.ra-d-marge b{font-size:18px;font-weight:900;line-height:1.2}
.ra-d-marge .s{font-size:11.5px;color:var(--ink-3);line-height:1.3}

.ra-d-promo{font-size:12.5px;line-height:1.35;border-left:3px solid var(--green);padding-left:9px;color:var(--ink-2)}
.ra-d-promo.passee{border-color:var(--orange);color:var(--orange-dark)}

/* Le graphique année contre année, sans son cadre : le panneau en est déjà un. */
.ra-graph .card-head{margin-bottom:2px}
.ra-graph .card-head h3{font-size:11px;text-transform:uppercase;letter-spacing:.02em;color:var(--ink-3);font-weight:800}
.ra-graph .legend{font-size:11px}
.ra-graph .chart-wrap.show-sm{display:none}

table.ra-cons{width:100%;border-collapse:collapse;font-size:12.5px}
table.ra-cons td{padding:3px 0;border-bottom:1px solid var(--line-2)}
table.ra-cons th{padding:0 0 3px;font-size:10.5px;text-transform:uppercase;letter-spacing:.02em;color:var(--ink-3);font-weight:800;text-align:right}
table.ra-cons th:first-child{text-align:left}
table.ra-cons td.num{text-align:right;white-space:nowrap;font-weight:700}
table.ra-cons .u{display:none}
table.ra-cons tr.dort td{background:var(--orange-soft)}
.ra-echange{margin-top:8px;font-size:12.5px;line-height:1.4;color:var(--ink-2);background:var(--orange-soft);border-radius:var(--r-sm);padding:8px 10px}
.ra-d-bloc .t{font-size:11.5px;text-transform:uppercase;letter-spacing:.02em;color:var(--ink-3);font-weight:800;margin-bottom:6px}
.ra-note{opacity:.8}
.ra-note-promo{color:var(--orange-dark);font-weight:600}

@media(max-width:1000px){
  .reassort{display:none}
  .content:has(.reassort)::before{content:"Cet écran demande un écran large : il montre la liste et le détail côte à côte. Ouvrez-le sur un ordinateur.";display:block;padding:18px;background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r-md);color:var(--ink-2);font-size:14px}
}

/* ============================================================================
   Marges (01/10/2026), sur le modèle de l'espace achats v2.
   ⚠ COMPACT ET SANS VARIANTE TÉLÉPHONE (Bruno, 01/10/2026 : « mais compacta, et pas pour le
     téléphone ») : pas de bandeau photo, tuiles et graphique côte à côte, un tableur d'une ligne par
     article qui défile dans son cadre. Sous 1 000 px, l'écran le DIT au lieu de se démonter.
   ========================================================================= */
.content:has(.marges){max-width:none;padding-left:18px;padding-right:18px}
.marges{display:flex;flex-direction:column;gap:10px;min-width:0}
.mg-tete{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap}
.mg-tete h1{font-size:var(--fs-h1-page)}
.mg-tete .tiny{margin-top:2px}
.mg-perim{display:flex;align-items:center;gap:6px}
.mg-perim .lbl{font-size:12.5px;color:var(--ink-3);margin-right:2px}
.mg-perim a{border:1px solid var(--line);background:var(--surface);border-radius:var(--r-sm);padding:5px 10px;font-weight:700;font-size:12.5px;color:var(--ink);text-decoration:none;white-space:nowrap}
.mg-perim a:hover{text-decoration:none;border-color:var(--ink-3)}
.mg-perim a.on{background:var(--accent-bg);border-color:var(--accent-bg);color:var(--on-accent)}
/* Les tuiles en deux par deux à gauche, le graphique à droite : une seule rangée de hauteur. */
.mg-haut{display:grid;grid-template-columns:minmax(380px,460px) minmax(0,1fr);gap:10px;align-items:stretch}
.mg-kpis{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.mg-k{background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r-md);padding:8px 12px;display:flex;flex-direction:column;justify-content:center;min-width:0}
.mg-k .l{font-size:11px;text-transform:uppercase;letter-spacing:.02em;color:var(--ink-3);font-weight:800;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mg-k b{font-size:20px;font-weight:900;color:var(--navy);line-height:1.25}
.mg-k .s{font-size:11.5px;color:var(--ink-3);line-height:1.3}
.mg-k .s.up{color:var(--green-dark);font-weight:700} .mg-k .s.down{color:var(--red-dark);font-weight:700}
.mg-graph{padding:8px 12px;display:flex;flex-direction:column;justify-content:center}
.mg-graph .card-head{margin-bottom:0}
.mg-graph .card-head h3{font-size:11px;text-transform:uppercase;letter-spacing:.02em;color:var(--ink-3);font-weight:800}
.mg-graph .legend{font-size:11px}
.mg-vues{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.mg-vues .tabs a b{margin-left:6px;opacity:.75}
.mg-vues .mg-export{margin-left:auto}
/* La phrase qui résume la liste, chiffres compris : la première chose à lire sous les onglets. */
.mg-resume{font-size:13px;color:var(--ink-2);margin-top:-2px}
.mg-resume b{color:var(--ink)}
.mg-liste{background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r-md);overflow:auto;max-height:calc(100vh - 400px);min-height:260px}
/* Le tableur : une ligne par article, largeurs fixes (classes `w…` portées par l'en-tête, voir
   Marges::COLONNES), le nom et le motif prennent le reste. `min-width` : en dessous, la liste défile
   dans son cadre au lieu de raboter les colonnes au prorata (même raison que `table.ra-tbl`). */
table.mg-tbl{width:100%;min-width:1010px;border-collapse:separate;border-spacing:0;font-size:12px;table-layout:fixed}
table.mg-tbl thead th{position:sticky;top:0;z-index:2;background:var(--surface-2);color:var(--ink-3);text-align:left;
  font-size:10.5px;text-transform:uppercase;letter-spacing:.02em;padding:5px 6px;border-bottom:1px solid var(--line);
  white-space:nowrap;line-height:1.15}
table.mg-tbl thead th.num{text-align:right}
table.mg-tbl thead th a.tri{display:inline-flex;align-items:center;gap:3px;color:inherit;text-decoration:none}
table.mg-tbl thead th a.tri:hover{color:var(--ink);text-decoration:underline}
table.mg-tbl thead th a.tri.on{color:var(--green-dark)}
table.mg-tbl thead th a.tri .fl{font-size:10px}
table.mg-tbl td{padding:4px 6px;border-bottom:1px solid var(--line-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
table.mg-tbl td.num{text-align:right;font-variant-numeric:tabular-nums}
table.mg-tbl td.muted,table.mg-tbl td .muted{color:var(--ink-3)}
table.mg-tbl tbody tr:nth-child(even) td{background:var(--surface-2)}
table.mg-tbl tbody tr:hover td{background:var(--line-2)}
table.mg-tbl td.lib .b{font-weight:700}
table.mg-tbl th.lib{width:auto;min-width:170px}
table.mg-tbl th.motif{width:30%}
table.mg-tbl .w64{width:64px} table.mg-tbl .w72{width:72px} table.mg-tbl .w80{width:80px} table.mg-tbl .w88{width:88px}
table.mg-tbl .w96{width:96px} table.mg-tbl .w100{width:100px} table.mg-tbl .w104{width:104px}
table.mg-tbl .w112{width:112px} table.mg-tbl .w150{width:150px}
/* La promotion d'une ligne : verte quand elle justifie le prix, ambre quand elle l'explique seulement. */
.mg-p.ok{color:var(--green-dark);font-weight:700}
.mg-p.alerte{color:var(--orange-dark);font-weight:700}
@media(max-width:1000px){
  .marges{display:none}
  .content:has(.marges)::before{content:"Cet écran demande un écran large : ses tableaux ne tiennent pas sur un téléphone. Ouvrez-le sur un ordinateur.";display:block;padding:18px;background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r-md);color:var(--ink-2);font-size:14px}
}
/* Courbe minuscule des ventes d'une officine, dans une cellule du tableau du groupe (Vue 360°,
   25/09/2026) : une silhouette, pas un graphique. Largeur fixe pour que les sept se comparent. */
.tbl td.spark{width:120px;padding-top:6px;padding-bottom:6px}
.sparkline{display:block;width:108px;height:30px}
@media(max-width:520px){ .tbl.cartes td.spark{width:auto} .tbl.cartes .sparkline{margin-left:auto} }
.switch{display:inline-flex;align-items:center;gap:10px;cursor:pointer;font-weight:700;font-size:13.5px}
.switch input{appearance:none;width:40px;height:22px;border-radius:999px;background:var(--line);position:relative;margin:0;cursor:pointer;transition:background .15s}
.switch input::after{content:"";position:absolute;top:3px;left:3px;width:16px;height:16px;border-radius:50%;background:#fff;transition:transform .15s}
.switch input:checked{background:var(--green)}
.switch input:checked::after{transform:translateX(18px)}
/* iOS zoome au focus d'un champ de moins de 16 px, et reste zoomé : 16 px sur écran tactile */
@media (max-width:819.98px),(pointer:coarse){
  .input,.select,.textarea{font-size:16px}
  .btn,.tabs button,.tabs a,.chip,.pop .sel button{min-height:40px}
  .btn.sm{min-height:36px}
}

/* ---------- pastilles, étiquettes, puces ---------- */
/* fond pâle et texte foncé (AA dans les deux thèmes) */
.pill{display:inline-flex;align-items:center;gap:4px;padding:3px 8px;border-radius:999px;font-size:var(--fs-pill);font-weight:900;letter-spacing:.04em;text-transform:uppercase;white-space:nowrap;line-height:1.4;box-shadow:inset 0 0 0 1px var(--pill-bord,transparent)}
.pill svg{width:11px;height:11px}
.pill.todo {background:var(--red-soft);   color:var(--red-dark);   --pill-bord:var(--red-soft-2)}
.pill.doing{background:var(--green-soft); color:var(--green-dark); --pill-bord:var(--green-soft-2)}
.pill.soon {background:var(--blue-soft);  color:var(--blue-dark);  --pill-bord:var(--blue-soft-2)}
.pill.done {background:var(--grey-soft);  color:var(--ink-2);      --pill-bord:var(--line)}
.pill.ko   {background:var(--orange-soft);color:var(--orange-ink); --pill-bord:var(--orange-soft-2)}
.tagc{display:inline-flex;align-items:center;gap:6px;padding:3px 10px;border-radius:999px;font-size:12px;font-weight:800;white-space:nowrap;max-width:100%}
.tagc span{font-weight:600}
.tagc.c1{background:var(--green-soft);color:var(--green-dark)} .tagc.c2{background:var(--blue-soft);color:var(--blue-dark)} .tagc.c3{background:var(--red-soft);color:var(--red-dark)} .tagc.c4{background:var(--orange-soft);color:var(--orange-ink)} .tagc.c5{background:var(--purple-soft);color:var(--purple-dark)}
.chips{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.chips .tagc{white-space:normal;flex-wrap:wrap;row-gap:0;border-radius:var(--r-sm)}   /* un titre de promotion réel passe à la ligne */
.chips .tagc span{white-space:nowrap}
.tag{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:var(--r-xs);font-size:var(--fs-xs);font-weight:700;background:var(--grey-soft);color:var(--ink-2);white-space:nowrap;vertical-align:middle}
.tag + .tag{margin-left:6px}  .chips > .tag + .tag{margin-left:0}
.tag.fort{background:var(--accent-bg);color:var(--on-accent)}
.tag.rouge{background:var(--red-soft);color:var(--red-dark)} .tag.vert{background:var(--green-soft);color:var(--green-dark)}
.tag.orange{background:var(--orange-soft);color:var(--orange-ink)} .tag.bleu{background:var(--blue-soft);color:var(--blue-dark)}
.chip{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:999px;border:1px solid var(--line);background:var(--surface);font-size:var(--fs-sm);font-weight:800;color:var(--ink-2);white-space:nowrap;text-decoration:none;cursor:pointer}
.chip:hover{background:var(--surface-2);text-decoration:none}
.chip.on{background:var(--green-soft);border-color:var(--green);color:var(--green-dark)}
.chip svg{width:14px;height:14px}
.count{display:inline-flex;min-width:18px;height:18px;padding:0 5px;align-items:center;justify-content:center;border-radius:999px;background:var(--red);color:#fff;font-size:10.5px;font-weight:900}

/* ---------- top bar ---------- */
.topbar{position:sticky;top:0;z-index:40;height:var(--top);background:var(--surface);border-bottom:1px solid var(--line);display:flex;align-items:center;gap:18px;padding:0 22px}
.logo{display:flex;align-items:center;gap:9px;text-decoration:none;color:var(--navy)}
.logo .tx{display:flex;flex-direction:column;line-height:1}
.logo:hover{text-decoration:none}
.logo img{width:40px;height:38px;object-fit:contain}
.logo .l1{font-size:22px;font-weight:900;line-height:1;letter-spacing:-.01em}
.logo .l2{font-size:10.5px;font-weight:700;line-height:1.15;color:var(--ink-2);margin-top:2px}
.card-head a svg,.news a svg,.tiny svg{width:13px;height:13px;display:inline-block;vertical-align:-2px}
.logo.sm img{width:26px;height:24px} .logo.sm .l1{font-size:16px}
.topnav{display:flex;gap:4px;margin-left:24px}
.topnav a{display:flex;align-items:center;gap:8px;padding:9px 14px;border-radius:10px;font-weight:800;font-size:13.5px;color:var(--ink);text-decoration:none}
.topnav a svg{width:17px;height:17px;color:var(--ink-2)}
.topnav a:hover{background:var(--surface-2)}
.topnav a.active{background:var(--red-soft);color:var(--red-dark)} .topnav a.active svg{color:var(--red)}
.spacer{flex:1}
.iconbtn{width:38px;height:38px;border-radius:10px;border:0;background:transparent;display:grid;place-items:center;cursor:pointer;position:relative;color:var(--ink)}
.iconbtn:hover{background:var(--surface-2)}
.iconbtn svg{width:19px;height:19px}
.iconbtn .count{position:absolute;top:2px;right:2px}
.me{display:flex;align-items:center;gap:10px;padding:4px 6px 4px 4px;border-radius:999px;border:0;background:transparent;cursor:pointer;max-width:320px;min-width:0}
.me:hover{background:var(--surface-2)}
.me > div{min-width:0}
.me img{width:34px;height:34px;border-radius:50%;object-fit:cover;background:var(--green-soft);border:2px solid var(--green-soft-2)}
.me .n{font-weight:800;font-size:13px;line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--navy)}
.me .r{font-size:12px;color:var(--ink-3);line-height:1.15}
.me svg{width:14px;height:14px;color:var(--ink-3)}

/* ---------- panneaux flottants (cloche, profil, feuille « Plus ») ---------- */
.pop{position:absolute;right:22px;top:calc(var(--top) - 4px);width:330px;background:var(--pop-bg);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow);padding:8px;z-index:50;max-height:min(70vh,560px);overflow-y:auto;overscroll-behavior:contain}
.pop .item{display:flex;gap:10px;padding:10px;border-radius:10px;align-items:center;font-size:13.5px;color:var(--ink);text-decoration:none;width:100%;border:0;background:none;text-align:left;cursor:pointer}
.pop .item:hover{background:var(--grey-soft);text-decoration:none}
.pop .item .t{min-width:0;flex:1} .pop .item .t b{display:block} .pop .item .t .tiny{display:block}
.pop .tout{justify-content:center;font-weight:800;color:var(--green-dark)}
.pop .head{padding:8px 10px;font-weight:900;font-size:12.5px;color:var(--ink-3);display:flex;justify-content:space-between;gap:10px;position:sticky;top:-8px;background:var(--pop-bg);z-index:1}
.pop .vide{padding:0 10px 8px}
.pop .note{padding:0 10px 4px}
.pop .sel{margin:4px 10px 10px;display:flex;gap:6px}
.pop .sel button{flex:1;padding:7px 4px;border-radius:8px;border:1px solid var(--line);background:var(--surface);font-size:12px;font-weight:800;cursor:pointer}
.sheet-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:4px}
.pop .item:focus-visible{outline-offset:-2px}
.sheet .item{flex-direction:row;align-items:center;gap:8px;padding:10px 8px;font-size:13px;font-weight:700;position:relative}
.sheet .item .ic{width:28px;height:28px}
.sheet .item > span:not(.ic):not(.count){min-width:0;hyphens:auto}
.sheet .item.active{background:var(--red-soft);color:var(--red-dark)}
.sheet .item .count{margin-left:auto}                                /* en bout de ligne, loin du libellé */
.ic{width:30px;height:30px;border-radius:9px;display:grid;place-items:center;flex:none}
.ic svg{width:15px;height:15px}
.ic.green{background:var(--green-soft);color:var(--green)} .ic.blue{background:var(--blue-soft);color:var(--blue)} .ic.red{background:var(--red-soft);color:var(--red)} .ic.orange,.ic.amber{background:var(--orange-soft);color:var(--orange-ink)} .ic.purple{background:var(--purple-soft);color:var(--purple)} .ic.grey{background:var(--grey-soft);color:var(--ink-2)}
.ic.lg{width:44px;height:44px;border-radius:12px} .ic.lg svg{width:22px;height:22px}

/* ---------- body: sidebar + main ---------- */
.body{display:grid;grid-template-columns:var(--side) minmax(0,1fr);min-height:calc(100vh - var(--top))}
.sidebar{background:var(--surface);border-right:1px solid var(--line);padding:14px 10px;display:flex;flex-direction:column;gap:2px;position:sticky;top:var(--top);height:calc(100vh - var(--top));overflow:auto}
.sidebar a.nv{display:flex;align-items:center;gap:10px;padding:10px 10px;border-radius:10px;color:var(--ink);font-weight:700;font-size:13px;text-decoration:none}
.sidebar a.nv .ic{width:26px;height:26px;border-radius:7px;background:var(--green-soft);color:var(--green)}
.sidebar a.nv .ic svg{width:14px;height:14px}
.sidebar a.nv:hover{background:var(--surface-2)}
.sidebar a.nv.active{background:var(--red-soft);color:var(--red-dark)} .sidebar a.nv.active .ic{background:var(--red-soft-2);color:var(--red)}
.sidebar a.nv .count{margin-left:auto}
.sidebar .help{margin-top:auto;padding:14px 12px;border-radius:12px;background:var(--surface-2);border:1px solid var(--line-2);font-size:12.5px;color:var(--ink-2)}
.sidebar .help .ic{margin-bottom:8px}
.sidebar .help b{display:block;color:var(--navy);font-size:13.5px}
.sidebar .help .btn{margin-top:10px}
.sidebar .promo-b{margin-top:10px;border-radius:12px;padding:16px 12px;background:linear-gradient(160deg,#EAF6EC,#D3EBD8);color:#1E4D30;font-weight:800;font-size:13px;line-height:1.3;position:relative;overflow:hidden}
.sidebar .promo-b .logo{margin-top:12px}
.sidebar .promo-b svg.leaf{position:absolute;right:-14px;top:-14px;width:70px;height:70px;color:#8CC9A0;opacity:.6}
.main{min-width:0;display:flex;flex-direction:column}
.content{padding:20px var(--pad-page) 28px;max-width:1240px;width:100%;display:flex;flex-direction:column;gap:var(--gap-page)}
.bottomnav{display:none}

/* ---------- hero ---------- */
.hero{position:relative;border-radius:16px;overflow:hidden;min-height:226px;display:flex;align-items:center;background:var(--surface);border:1px solid var(--line-2)}
.hero .photo{position:absolute;inset:0;background-size:cover;background-position:center 45%}
.hero::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,var(--surface) 0%,color-mix(in srgb,var(--surface) 92%,transparent) 34%,color-mix(in srgb,var(--surface) 30%,transparent) 62%,transparent 100%)}
.hero .txt{position:relative;z-index:2;padding:26px 30px;max-width:60%;min-width:0}
.hero .eyebrow{display:flex;align-items:center;gap:10px}
.hero .eyebrow::before{content:"";width:44px;height:3px;border-radius:2px;background:var(--green);flex:none}
.hero h1{margin-top:8px;font-size:var(--fs-h1)}
.hero .sub{margin-top:8px;color:var(--ink-2);font-size:15px;max-width:52ch}
.hero .tagline{margin-top:16px;font-family:var(--script);font-size:26px;line-height:1.05;color:var(--green-dark);transform:rotate(-2deg);transform-origin:left;display:inline-block;position:relative;max-width:34ch}
.hero .tagline::after{content:"";position:absolute;left:4px;right:14px;bottom:-6px;height:3px;border-radius:3px;background:var(--green)}
.hero .quote{position:absolute;right:24px;top:24px;bottom:24px;z-index:1;width:196px;background:color-mix(in srgb,var(--surface) 90%,transparent);backdrop-filter:blur(8px);border-radius:14px;padding:18px 18px 16px;display:flex;flex-direction:column;box-shadow:var(--shadow)}
.hero .quote .q{font-size:28px;line-height:.6;color:var(--green);font-weight:900;font-family:Georgia,serif;margin-bottom:12px}
.hero .quote p{font-style:italic;font-weight:700;color:var(--navy);font-size:15px;line-height:1.3}
.hero .quote .who{margin-top:auto;padding-top:10px;font-weight:900;color:var(--navy);font-size:15px}
.hero .quote .who::before{content:"";display:block;width:34px;height:3px;background:var(--green);border-radius:2px;margin-bottom:8px}
.hero .titulaire{position:absolute;right:36px;bottom:0;height:92%;z-index:1;width:auto;filter:drop-shadow(0 6px 12px rgba(0,0,0,.28))}
.hero.tall{min-height:300px}
.hero.tall .photo{background-size:118%;background-position:100% 30%}
.hero.tall::after{background:linear-gradient(90deg,var(--surface) 0%,color-mix(in srgb,var(--surface) 90%,transparent) 30%,color-mix(in srgb,var(--surface) 25%,transparent) 50%,transparent 66%)}
.hero.tall .txt{max-width:50%}
.hero.compact{min-height:150px}
.hero.compact .txt{padding:20px 26px}
.hero.compact h1{font-size:var(--fs-h1-page)}
.hero .actions{position:relative;z-index:2;margin-left:auto;padding:0 24px;display:flex;gap:8px;flex-wrap:wrap;align-self:flex-end;margin-bottom:22px}

/* ---------- cards ---------- */
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);padding:var(--pad-card)}
.card.tight{padding:0;overflow:hidden}
.card .card-head{display:flex;align-items:center;justify-content:space-between;gap:12px;row-gap:4px;flex-wrap:wrap;margin-bottom:12px}
.card .card-head > h3{min-width:0}
.card.tight .card-head{padding:14px var(--pad-card);border-bottom:1px solid var(--line-2);margin:0}
/* filet de sécurité : dans une carte « tight », ce qui n'est ni l'en-tête ni un tableau reçoit une marge */
.card.tight > :is(p,form,ul,ol,.chips,.kv,.notice,.stack,.tabs,.lignes){margin:0;padding:12px var(--pad-card)}
.card.tight > .kv{padding-bottom:var(--pad-card)}
.card.tight > :is(ul,ol):not(.todo){padding-left:calc(var(--pad-card) + 1.2em)}   /* la puce ne touche pas le bord */
/* deux blocs du filet qui se suivent ne doublent pas la marge (liste, puis notes de « Ma participation ») */
.card.tight > :is(p,form,ul,ol,.chips,.kv,.notice,.stack,.tabs,.lignes) + :is(p:not(.empty),form,ul,ol,.chips,.kv,.notice,.stack,.tabs,.lignes){padding-top:0}
.card-body{padding:12px var(--pad-card) 14px;display:flex;flex-direction:column;gap:8px}
.card.tight > .card-body + .tbl-wrap{border-top:1px solid var(--line-2)}   /* totaux, puis détail : un filet les sépare */
.card.lien{display:block;color:inherit;text-decoration:none;transition:box-shadow .15s}
.card.lien:hover{box-shadow:var(--shadow);text-decoration:none}
.card.bord-rouge{border-color:var(--red)}
.empty{padding:24px var(--pad-card);text-align:center;color:var(--ink-2);font-size:var(--fs-sm)}
.card.tight > p.empty{padding:24px var(--pad-card)}
.etat{display:flex;gap:14px;align-items:center}
.etat > div{min-width:0}
.notice{display:flex;gap:12px;align-items:center}
.notice > div{min-width:0}
.notice.urgent{border-color:var(--red)}
.stack{display:flex;flex-direction:column;gap:8px}
.lignes > *{padding:10px 0;border-top:1px solid var(--line-2)} .lignes > :first-child{border-top:0;padding-top:0}
.repli > summary{list-style:none;display:inline-flex;align-items:center;gap:8px;cursor:pointer;font-weight:800;font-size:var(--fs-sm);color:var(--green-dark);padding:6px 0}
.repli > summary::-webkit-details-marker{display:none}
.repli > summary::after{content:"";width:7px;height:7px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(45deg);margin-top:-3px;transition:transform .15s}
.repli[open] > summary::after{transform:rotate(-135deg);margin-top:3px}
/* libellé double « Voir les N autres » / « Masquer » selon l'état du repli */
.repli:not([open]) > summary .masquer,.repli[open] > summary .voir{display:none}
/* repli en bas d'une carte « tight » (suite d'un tableau) : aligné sur le contenu, séparé par un filet */
.card.tight > .repli{border-top:1px solid var(--line-2)} .card.tight > .repli > summary{padding:10px var(--pad-card)}
.grid{display:grid;gap:var(--gap-grid)}
.grid > *{min-width:0}
.g2{grid-template-columns:repeat(2,minmax(0,1fr))} .g3{grid-template-columns:repeat(3,minmax(0,1fr))}
.g4{grid-template-columns:repeat(4,minmax(0,1fr))} .g5{grid-template-columns:repeat(5,minmax(0,1fr))}
.g-2-1{grid-template-columns:minmax(0,2fr) minmax(0,1fr);align-items:start}
.grid.top{align-items:start}
.grid.auto:has(> form){row-gap:22px}          /* deux formulaires empilés ne se confondent pas */
.grid.auto{grid-template-columns:repeat(auto-fill,minmax(min(100%,var(--min,260px)),1fr))}
.section-title{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
.section-title h2{font-size:var(--fs-h2)}
.section-title .compte{font-size:var(--fs-sm);color:var(--ink-2);font-weight:700}

/* pastel module cards */
.mod{display:flex;flex-direction:column;gap:8px;text-decoration:none;color:inherit;border-radius:var(--r);padding:18px 16px 14px;border:1px solid transparent;min-height:180px;position:relative}
.mod:hover{text-decoration:none;box-shadow:var(--shadow)}
.mod .big{width:52px;height:52px;border-radius:50%;display:grid;place-items:center;flex:none}
.mod .big svg{width:24px;height:24px}
.mod h3{font-size:15.5px;margin-top:4px;line-height:1.2}
.mod p{color:var(--ink-2);font-size:12.5px;flex:1;line-height:1.35}
.mod .kpi{display:flex;align-items:center;gap:8px;background:var(--surface);border-radius:10px;padding:9px 12px;font-size:12.5px;color:var(--ink-2);font-weight:700}
.mod .kpi b{font-size:18px;font-weight:900;white-space:nowrap}
.mod .kpi svg{width:14px;height:14px;margin-left:auto;color:var(--ink);flex:none}
/* modules de l'accueil : un chiffre large (« +19,1 % ») laisse la phrase passer sous lui plutôt que la
   couper sur quatre lignes étroites ; un chiffre court garde la phrase à côté */
.grid.mods .mod .kpi{flex-wrap:wrap}
.grid.mods .mod .kpi .kpi-l{flex:1 1 9em}
.mod .goto{position:absolute;top:14px;right:14px;width:26px;height:26px;border-radius:50%;background:var(--surface);display:grid;place-items:center}
.mod .goto svg{width:14px;height:14px}
.mod.green{--accent:var(--green)} .mod.blue{--accent:var(--blue)} .mod.red{--accent:var(--red)}
.mod.orange{--accent:var(--orange)} .mod.purple{--accent:var(--purple)} .mod.grey{--accent:var(--ink-3)}
.mod.green{background:var(--green-soft)} .mod.green .big{background:var(--green-soft-2);color:var(--green)} .mod.green .kpi b{color:var(--green)}
.mod.blue{background:var(--blue-soft)} .mod.blue .big{background:var(--blue-soft-2);color:var(--blue)} .mod.blue .kpi b{color:var(--blue)}
.mod.red{background:var(--red-soft)} .mod.red .big{background:var(--red-soft-2);color:var(--red)} .mod.red .kpi b{color:var(--red)}
.mod.orange{background:var(--orange-soft)} .mod.orange .big{background:var(--orange-soft-2);color:var(--orange-dark)} .mod.orange .kpi b{color:var(--orange-dark)}
.mod.purple{background:var(--purple-soft)} .mod.purple .big{background:var(--purple-soft-2);color:var(--purple)} .mod.purple .kpi b{color:var(--purple)}
.mod.grey{background:var(--grey-soft)} .mod.grey .big{background:var(--line);color:var(--ink-2)} .mod.grey .kpi b{color:var(--ink)}
/* Tuiles de circuit : l'icône passe À CÔTÉ du texte, et non plus au-dessus (demande de Bruno du
   23/09/2026 : elles étaient trop hautes). Mesuré à 1280 px : 280 px de haut avant, avec le chiffre
   retiré et l'icône de côté. Le paragraphe garde ses lignes entières : le couper cacherait ce qu'est
   le circuit, et c'est la seule phrase qui le dit. */
.mod.circuit{display:grid;grid-template-columns:auto minmax(0,1fr);grid-template-areas:"big n" "h3 h3" "p p";
  column-gap:9px;row-gap:0;align-content:start;min-height:0;padding:12px 14px;cursor:pointer;text-align:left;font:inherit}
.mod.circuit.on,.mod.circuit[aria-current="true"]{border-color:var(--accent,currentColor);box-shadow:inset 0 0 0 1px var(--accent,currentColor)}
.mod.circuit .big{grid-area:big;width:34px;height:34px} .mod.circuit .big svg{width:18px;height:18px}
.mod.circuit .n{grid-area:n;align-self:center;font-size:11.5px;font-weight:900;color:var(--ink-2)}
/* ⚠ LE NOM PREND TOUTE LA LARGEUR, il ne se met pas à côté de l'icône : dans la colonne restante
   (≈ 120 px à 1280), « Réseau Lafayette (FAKS) » tombait sur trois lignes et c'est lui qui donnait
   sa hauteur à la rangée entière — les cinq tuiles s'alignent sur la plus haute. */
.mod.circuit h3{grid-area:h3;margin:6px 0 0;font-size:14.5px}
.mod.circuit p{grid-area:p;flex:none;margin-top:4px;font-size:12px}

/* À traiter (accueil) : ul.todo, pour ne pas écraser la pastille .pill.todo */
ul.todo{list-style:none;margin:0;padding:0}
ul.todo li{display:flex;align-items:center;gap:12px;padding:10px 0;border-top:1px solid var(--line-2);font-size:13.5px}
ul.todo li:first-child{border-top:0;padding-top:0}
ul.todo li:has(> .todo-l){padding:0;display:block}
ul.todo .todo-l{display:flex;align-items:center;gap:12px;padding:10px 0;color:inherit;text-decoration:none}
ul.todo li:first-child > .todo-l{padding-top:0}
ul.todo .todo-l:hover{text-decoration:none} ul.todo .todo-l:hover .t b{text-decoration:underline}
ul.todo .t{flex:1;min-width:0}
ul.todo .t b{display:block;font-weight:800;color:var(--navy)}
ul.todo .t span{color:var(--ink-3);font-size:12.5px}
.repli > ul.todo{margin-top:6px}
.repli > ul.todo li:first-child{border-top:1px solid var(--line-2);padding-top:10px}
.repli > ul.todo li:first-child:has(> .todo-l){padding-top:0}
.repli > ul.todo li:first-child > .todo-l{padding-top:10px}

/* stat tiles */
.stat-tile{padding:16px 18px}
.stat-tile .l{font-size:12.5px;color:var(--ink-2);font-weight:700}
.stat-tile .v{font-size:var(--fs-stat);font-weight:900;margin-top:4px;color:var(--navy)}
.stat-tile .d{font-size:12.5px;margin-top:2px;font-weight:700}
.grid.stats{grid-template-columns:repeat(4,minmax(0,1fr))} .grid.stats.s3{grid-template-columns:repeat(3,minmax(0,1fr))}
.up{color:var(--green-dark)} .down{color:var(--red-dark)}

/* ---------- tableaux ---------- */
.tbl{width:100%;font-size:var(--fs-tbl)}
.tbl th{text-align:left;font-size:12px;font-weight:800;color:var(--ink-3);padding:calc(var(--cell-y) - 2px) var(--cell-x);border-bottom:1px solid var(--line);background:var(--surface-2);white-space:nowrap}
.tbl td{padding:var(--cell-y) var(--cell-x);border-bottom:1px solid var(--line-2);vertical-align:middle}
.tbl tr:last-child td{border-bottom:0}
.tbl tr.row:hover td{background:var(--surface-2);cursor:pointer}
.tbl .num{text-align:right;font-variant-numeric:tabular-nums}
.tbl td.num,.tbl td.date,.tbl td.nowrap{white-space:nowrap}
.tbl .b{font-weight:800;color:var(--navy)}
.tbl td.lib{min-width:12rem}
.tbl td.lib.court{min-width:0}                /* libellé court (numéro de commande) : pas de largeur réservée */
.tbl td.num .sous,.tbl td.date .sous{white-space:normal}
.tbl .sous{display:block;font-size:var(--fs-xs);color:var(--ink-3);font-weight:600;margin-top:2px}
.tbl .sous.down{color:var(--red-dark)}
.tbl a.b,.tbl .b > a{color:var(--navy);text-decoration:underline;text-decoration-color:var(--line);text-decoration-thickness:2px;text-underline-offset:3px}
.tbl a:hover{text-decoration:underline} .tbl a.b:hover,.tbl .b > a:hover{text-decoration-color:currentColor}
.tbl tr.groupe th{background:var(--bg);color:var(--ink-2);font-size:var(--fs-xs);padding:6px var(--cell-x);text-align:left}
.moi td{background:var(--green-soft)}
/* Tableau dense (.tbl.dense) : beaucoup de lignes lues d'un coup, comme un tableur — mêmes jetons,
   moins d'air. Interligne serré, filets verticaux entre colonnes, une ligne sur deux teintée, notes
   ramenées sur la ligne. Sous 520 px, .tbl.cartes reprend la main (règles plus loin dans la feuille). */
.tbl.dense{font-size:var(--fs-sm)}
.tbl.dense th{padding:5px var(--cell-x);font-size:var(--fs-2xs)}
.tbl.dense td{padding:5px var(--cell-x)}
.tbl.dense :is(th,td) + :is(th,td){border-left:1px solid var(--line-2)}
.tbl.dense tbody tr:nth-child(even) td{background:var(--surface-2)}
.tbl.dense tbody tr:hover td{background:var(--line-2)}
.tbl.dense td{white-space:nowrap}                       /* une ligne = une ligne, comme un tableur */
.tbl.dense td:is(.small,.pleine){white-space:normal}    /* sauf une cellule de phrase : elle respire */
.tbl.dense td.lib{min-width:0;max-width:none}
/* seul le NOM est coupé, jamais l'EAN ni le laboratoire qui le suivent : c'est le nom qui est long,
   et l'EAN est ce qui identifie la ligne. Le nom entier reste dans le title. */
.tbl.dense td.lib > :is(a.b,b){display:inline-block;max-width:18rem;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom}
.tbl.dense .sous,.tbl.dense td.num .sous,.tbl.dense td.date .sous{display:inline;white-space:nowrap;margin:0 0 0 6px;font-size:var(--fs-2xs)}
/* zone qui défile : ombre au bord tant qu'il reste du contenu (sans JS), barre fine visible */
.tbl-wrap,.chart-wrap{overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:thin;scrollbar-color:var(--barre) var(--line-2);
  background:
    linear-gradient(90deg,var(--surface) 30%,transparent) left center / 32px 100% no-repeat local,
    linear-gradient(270deg,var(--surface) 30%,transparent) right center / 32px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%,var(--defil),transparent) left center / 12px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%,var(--defil),transparent) right center / 12px 100% no-repeat scroll;
  background-color:var(--surface)}
:is(.tbl-wrap,.chart-wrap)::-webkit-scrollbar{height:10px;width:10px} :is(.tbl-wrap,.chart-wrap)::-webkit-scrollbar-track{background:var(--line-2)}
:is(.tbl-wrap,.chart-wrap)::-webkit-scrollbar-thumb{background:var(--barre);border-radius:5px}
.tbl-wrap.borne{max-height:min(70vh,640px);overflow:auto}
.tbl-wrap.borne thead th{position:sticky;top:0;z-index:1}

/* ---------- onglets, barre d'outils, rangées défilantes ---------- */
.tabs{display:flex;gap:6px;flex-wrap:wrap}
.tabs button,.tabs a{display:inline-flex;align-items:center;gap:6px;padding:8px 14px;border-radius:999px;border:0;background:var(--green-soft);color:var(--green-dark);font-weight:800;font-size:12.5px;cursor:pointer;white-space:nowrap;text-decoration:none}
.tabs button svg,.tabs a svg{width:15px;height:15px}
.tabs a:hover{text-decoration:none}
.tabs .n{font-size:11px;font-weight:900;padding:1px 6px;border-radius:999px;background:color-mix(in srgb,currentColor 14%,transparent)}
.tabs.petits button,.tabs.petits a{padding:5px 10px;font-size:11.5px;min-height:34px;background:none;box-shadow:inset 0 0 0 1px var(--line);color:var(--ink-2)}
.tabs button.on,.tabs a.on,.tabs a[aria-current="page"],.pop .sel button.on,.seg button.on{background:var(--accent-bg);border-color:var(--accent-bg);color:var(--on-accent)}
.rail{display:flex;gap:8px}
/* rangée qui a défilé : fondu des deux côtés (classe posée par portail.js) */
:is(.tabs,.rail,.grid.circuits).defile-g{-webkit-mask-image:linear-gradient(90deg,transparent,#000 28px,#000 calc(100% - 28px),transparent);mask-image:linear-gradient(90deg,transparent,#000 28px,#000 calc(100% - 28px),transparent)}
.toolbar{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.toolbar .search{flex:1;min-width:min(100%,220px)}
.toolbar .end{margin-left:auto;display:flex;gap:6px;align-items:center}
/* Choix de la disposition des cartes (partiel `partials/affichage.php`) : deux liens, l'actif tenu.
   Masqué sous 820 px, où une carte par ligne est la seule disposition possible. */
.affichage{display:inline-flex;border:1px solid var(--line);border-radius:9px;overflow:hidden;margin-left:auto}
.affichage a{display:inline-flex;align-items:center;gap:6px;padding:7px 10px;background:var(--surface);
  color:var(--ink-2);font-size:var(--fs-xs);font-weight:800;text-decoration:none;white-space:nowrap}
.affichage a + a{border-left:1px solid var(--line)}
.affichage a:hover{background:var(--surface-2);color:var(--ink)}
.affichage a.on{background:var(--green-soft);color:var(--green-dark)}
.affichage svg{width:15px;height:15px;flex:0 0 auto}

.seg{display:inline-flex;border:1px solid var(--line);border-radius:9px;overflow:hidden}
.seg button{border:0;background:var(--surface);padding:7px 9px;cursor:pointer;display:grid;place-items:center}
.seg button svg{width:15px;height:15px}
@media (min-width:1180px){ .toolbar.colle{position:sticky;top:var(--top);z-index:5;background:var(--bg);padding:8px 0;margin:-8px 0;box-shadow:0 1px 0 var(--line)}
  /* une ancre (#liste d'un lien de page) ne passe pas sous la barre collante : sa hauteur réelle est
     posée dans --colle par portail.js. Sous 1180 px, onglets et recherche passent sur deux lignes :
     la barre, trop haute, ne colle pas. */
  html:has(.toolbar.colle){scroll-padding-top:calc(var(--top) + var(--colle,57px) + 12px)} }


/* Filtres fins (état de la photo, emplacement) : une rangée discrète sous la barre d'outils. */
/* Barre des mois des promotions (02/10/2026, modèle `/operations` de Labscore) : « Tous » fixe, puis une
   rangée qui défile. Cibles de 40 px, nombres bien lisibles ; au téléphone, pas de flèches, on glisse. */
.mois-bar{display:flex;align-items:stretch;gap:4px;margin:12px 0 0;padding:4px;background:var(--surface);
  border:1px solid var(--line-2);border-radius:var(--r-sm);box-shadow:var(--shadow)}
.mb-tous{flex:0 0 auto;display:inline-flex;align-items:center;padding:0 14px;min-height:40px;border-radius:var(--r-xs);
  font-weight:900;font-size:13px;color:var(--green-dark);text-decoration:none}
.mb-tous:hover{background:var(--green-soft);text-decoration:none}
.mb-tous.on{background:var(--accent-bg);color:var(--on-accent)}
.mb-nav{flex:0 0 30px;display:inline-flex;align-items:center;justify-content:center;border:0;border-radius:var(--r-xs);
  background:none;color:var(--ink-3);cursor:pointer}
.mb-nav:hover{background:var(--surface-2);color:var(--ink-2)}
.mb-nav svg{width:16px;height:16px}
.mb-nav[data-mois-nav="-1"] svg{transform:rotate(90deg)}
.mb-nav[data-mois-nav="1"] svg{transform:rotate(-90deg)}
.mois-bar .mb-rail{flex:1 1 auto;min-width:0;gap:2px;overflow-x:auto;scroll-snap-type:x proximity;scrollbar-width:none;overscroll-behavior-x:contain}
.mb-rail::-webkit-scrollbar{display:none}
.mb-m{flex:0 0 auto;scroll-snap-align:start;display:inline-flex;align-items:center;gap:7px;padding:0 12px;min-height:40px;
  border-radius:var(--r-xs);font-weight:800;font-size:13px;color:var(--ink-2);text-decoration:none;white-space:nowrap}
a.mb-m:hover{background:var(--surface-2);text-decoration:none}
.mb-m .n{font-size:11px;font-weight:900;line-height:1.5;padding:0 7px;border-radius:999px;background:var(--green);color:#fff}
.mb-m.on{background:var(--accent-bg);color:var(--on-accent)}
.mb-m.on .n{background:var(--surface);color:var(--green-dark)}
/* Le mois en cours : un point, comme dans Labscore — repère quand la rangée a défilé ailleurs. */
.mb-m.courant::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--orange-dark);flex:0 0 auto}
.mb-m.vide{color:var(--ink-3);opacity:.6;cursor:default}
@media(max-width:820px){
  .mb-nav{display:none}
  .mb-tous{padding:0 12px;border-right:1px solid var(--line-2);border-radius:var(--r-xs) 0 0 var(--r-xs)}
  .mb-m{padding:0 11px;font-size:12.5px}
}
.filtres-fins .tabs.merch{margin-left:auto}
@media(max-width:520px){ .filtres-fins .tabs.merch{margin-left:0;width:100%} }
.filtres-fins{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:8px}
.filtres-fins label{color:var(--ink-3);font-weight:800}
/* ⚠ LARGEUR RENDUE À LA SÉLECTION : `.select` est à 100 % pour les formulaires en colonne ; dans une
   rangée de filtres, deux listes pleine largeur prenaient deux lignes entières au-dessus du tableau. */
.filtres-fins .select{width:auto;min-width:10rem;max-width:16rem;flex:0 0 auto}
.select.sm{padding:5px 26px 5px 8px;font-size:var(--fs-xs);min-height:0}

/* Filtres à cocher, façon filtre automatique d'Excel (23/09/2026) : un `<details>` par colonne, une
   case par valeur. Le panneau s'ouvre et s'envoie sans script ; `portail.js` n'ajoute que la fermeture
   au clic dehors et à Échap. La pastille prend la couleur d'accent dès qu'une case est cochée. */
.fmulti{position:relative;flex:0 0 auto}
.fmulti>summary{list-style:none;display:inline-flex;align-items:center;gap:6px;padding:5px 9px;border:1px solid var(--line);
  border-radius:var(--r-sm);background:var(--surface);font-size:var(--fs-xs);font-weight:800;color:var(--ink);cursor:pointer;white-space:nowrap}
.fmulti>summary::-webkit-details-marker{display:none}
.fmulti>summary::marker{content:''}
.fmulti>summary .l{color:var(--ink-3);font-weight:800}
.fmulti>summary .v{max-width:11rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fmulti>summary svg{width:13px;height:13px;color:var(--ink-3);flex:none}
.fmulti[open]>summary svg{transform:rotate(180deg)}
.fmulti.on>summary{border-color:var(--green);background:var(--green-soft);color:var(--green-dark)}
.fmulti.on>summary :is(.l,svg){color:inherit}
/* ⚠ EN SURIMPRESSION, PAS DANS LE FLUX : ouvert dans le flux, le panneau poussait le tableau vers le
   bas à chaque clic. `z-index` au-dessus de la barre d'outils collante. */
.fmulti .menu{position:absolute;z-index:40;top:calc(100% + 6px);left:0;min-width:15rem;
  max-width:min(22rem,calc(100vw - 32px));background:var(--pop-bg);border:1px solid var(--line);
  border-radius:12px;box-shadow:var(--shadow);padding:6px}
/* Le panneau fermé est masqué explicitement : les navigateurs cachent bien le contenu d'un `<details>`
   replié, mais un enfant en `position:absolute` s'en échappe sur certaines versions. */
.fmulti:not([open]) .menu{display:none}
.fmulti .opts{display:flex;flex-direction:column;max-height:16rem;overflow:auto}
.fmulti .opt{display:flex;align-items:center;gap:9px;padding:6px 8px;border-radius:8px;font-size:var(--fs-sm);font-weight:700;cursor:pointer}
.fmulti .opt:hover{background:var(--surface-2)}
.fmulti .opt input{width:15px;height:15px;flex:none;accent-color:var(--green);margin:0}
.fmulti .pied{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:4px;padding:6px 4px 2px;border-top:1px solid var(--line-2)}
.fmulti .pied a{font-size:var(--fs-xs);font-weight:800}

/* ---------- pagination ---------- */
.pager{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
.pager .compte{font-size:var(--fs-sm);color:var(--ink-2);font-weight:700}
.pager .pages{display:flex;align-items:center;gap:6px}
.pager .pg{min-width:36px;height:36px;padding:0 8px;display:inline-grid;place-items:center;border-radius:10px;border:1px solid var(--line);background:var(--surface);font-weight:800;font-size:13px;color:var(--ink);text-decoration:none}
.pager a.pg:hover{background:var(--surface-2);text-decoration:none}
.pager .pg svg{width:16px;height:16px}
.pager .pg.on{background:var(--accent-bg);border-color:var(--accent-bg);color:var(--on-accent)}
.pager .pg.off{opacity:.35} .pager .pg.gap{border:0;background:none;min-width:0}
.pager .pos{display:none}
.card.tight > .pager{padding:10px var(--pad-card);border-top:1px solid var(--line-2)}

/* promo cards (opérations, nouveautés) */
.promo{display:flex;flex-direction:column;padding:14px;gap:8px}
.promo .head{display:flex;justify-content:space-between;align-items:center;gap:8px;row-gap:4px;flex-wrap:wrap}
.promo .head .d{font-size:11px;color:var(--ink-2);font-weight:700;white-space:normal;text-align:right;margin-left:auto}
.promo .vis{height:118px;border-radius:10px;background:linear-gradient(135deg,var(--surface-2),var(--grey-soft));display:flex;align-items:center;justify-content:center;position:relative;overflow:hidden}
.promo .vis .lab{font-weight:900;font-size:20px;color:var(--ink-3);letter-spacing:0;text-transform:none}
.promo .vis svg{position:absolute;right:-8px;bottom:-10px;width:70px;height:70px;color:var(--line);opacity:.8}
.promo .lab{font-size:var(--fs-2xs);font-weight:900;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-3)}
.promo h3{font-size:15px;margin-top:2px}
.promo .lb{font-size:13px;color:var(--ink-2);line-height:1.35}
.promo .lb b{color:var(--ink);display:block;font-weight:700}
.promo .lb.meta > :nth-child(2)::before{content:"·";margin-right:10px;color:var(--ink-3);font-weight:700}   /* participation · encodage */
.promo .lb.meta > :nth-child(3){flex-basis:100%}                     /* la photo attendue sur sa ligne */
.promo .dates{display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--ink-2);font-weight:700}
.promo .dates svg{width:14px;height:14px;color:var(--green)}
.promo .deadline{font-size:12px;color:var(--red-dark);font-weight:800}
.promo .deadline.photo-urgente{display:flex;align-items:center;gap:6px;padding:5px 9px;border-radius:var(--r-xs);background:var(--red-soft)}
.promo .deadline.photo-urgente svg{width:14px;height:14px;flex:0 0 auto}
.promo .foot{margin-top:auto;display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;gap:8px;padding-top:4px}
/* Étiquette « photo » : l'appareil dit qu'une photo est attendue, sa couleur dit si ça presse —
   rouge en retard, jaune bientôt, vert sinon. Pas d'appareil = pas de photo demandée. */
.tag-photo{display:inline-flex;align-items:center;justify-content:center;width:26px;height:22px;
  border-radius:999px;flex:0 0 auto}
.tag-photo svg{width:14px;height:14px}
.tag-photo.ok{background:var(--green-soft);color:var(--green-dark)}
.tag-photo.bientot{background:var(--orange-soft);color:var(--orange-ink)}
.tag-photo.retard{background:var(--red-soft);color:var(--red-dark)}
.tag-photo.attente{background:var(--surface-2);border:1px solid var(--line-2);color:var(--ink-3)}
/* Étiquette d'emplacement (tête de gondole, intercomptoir…), servie par la centrale. */
.tag-emp{display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;background:var(--surface-2);
  border:1px solid var(--line-2);color:var(--ink-2);font-size:10.5px;font-weight:800;white-space:nowrap}
/* Tag brut de la centrale (P20) : le mot saisi, en trait discret pour ne pas passer pour un emplacement. */
.tag-brut{display:inline-flex;align-items:center;padding:1px 7px;border-radius:999px;border:1px dashed var(--line);
  color:var(--ink-3);font-size:10.5px;font-weight:700;white-space:nowrap}
.tbl .sous .tag-brut{margin:2px 4px 0 0}
.tags-op{display:flex;flex-wrap:wrap;gap:4px}
.promo .foot .tagc{align-self:flex-start}
.card.promo.lien{display:flex;flex-direction:column}
.card.promo > form{margin-top:auto}
.card.promo.lien:hover h3{text-decoration:underline}
/* Logo du laboratoire, quand la centrale en sert un (§ 2.2.1). Hauteur fixe et `contain` : les logos
   arrivent dans toutes les proportions, et un logo déformé fait plus de mal que pas de logo. */
/* La tuile du logo : même traitement sur la carte et dans le tableau — carré, coins arrondis, fond
   blanc, zoom ×1,25 (voir la note du tableau plus bas pour la mesure). */
.promo-logo{display:flex;align-items:center;justify-content:center;height:56px;width:88px;margin:2px 0;
  overflow:hidden;border-radius:var(--r-sm);background:#fff}
.card.tight > .promo-logo{margin:2px var(--pad-card)}
.promo-logo img{height:56px;width:88px;object-fit:contain;transform:scale(1.25)}
.promo-logo[hidden]{display:none}
/* Le nom du laboratoire ne revient que sans logo, ou si l'image n'a pas chargé. */
.promo .lab.repli-nom{display:none}
.card.sans-logo .lab.repli-nom{display:block}

.grid.promos{grid-template-columns:repeat(auto-fill,minmax(min(100%,240px),1fr))}
.grid.promos.nouveautes{grid-template-columns:repeat(auto-fill,minmax(min(100%,300px),1fr));align-items:start}   /* cartes-formulaires : plus larges */

/* Le mode « Tableau » de la liste des opérations (.tbl.ope) et le mode « une par ligne » des
   nouveautés (.rangs), au-dessus de 820 px seulement : en dessous, la liste est déjà en cartes.
   Une carte de nouveauté est un formulaire : elle prend la pleine largeur, sans réordonner. */
@media (min-width:820.02px){
  .grid.promos.nouveautes.rangs{grid-template-columns:minmax(0,1fr)}
  /* Pleine largeur, une vignette reste une vignette : sans cela les photos s'étirent sur tout l'écran. */
  .grid.promos.nouveautes.rangs .nv-photos{grid-template-columns:repeat(auto-fill,110px);justify-content:start}
}
/* Une disposition rendue deux fois, une seule montrée : le tableau sur grand écran, les cartes sur
   téléphone (le serveur ne sait pas quelle largeur a l'écran). */
.sur-petit{display:none}
@media (max-width:820px){ .affichage{display:none} .sur-grand{display:none} .sur-petit{display:grid} }

/* En-tête de colonne cliquable : le libellé est un lien, la flèche dit le sens du tri en cours. */
.tbl th a.tri{display:inline-flex;align-items:center;gap:4px;color:inherit;text-decoration:none}
.tbl th a.tri:hover{color:var(--ink);text-decoration:underline}
.tbl th a.tri.on{color:var(--green-dark)}
.tbl th a.tri .fl{font-size:11px;line-height:1}
/* Tableau des opérations : deux lignes par opération, comme sur la liste de Labscore — le circuit sous
   le titre, la mise en place sous la période. Tout tenir sur une seule ligne dépassait la largeur
   disponible (mesuré : 1 265 px pour 1 034), et c'est la colonne « Statut » qui disparaissait. */
.tbl.ope td.lib .sous,.tbl.ope td.date .sous{display:block;margin:3px 0 0;white-space:normal}
/* ⚠ TOUT PEUT REVENIR À LA LIGNE DANS CE TABLEAU, et c'est ce qui le fait tenir : en vrai, les titres
   d'opération, les noms de laboratoire et les libellés de statut sont bien plus longs que ceux de la
   démonstration — « En attente de validation (labo) », « LABORATOIRES EXPANSCIENCE ». Avec `nowrap`,
   la largeur s'additionnait et le tableau débordait de sa carte (signalé en production le 22/09/2026).
   La date reste courte (« 06/09 → 06/10/2026 ») plutôt que la phrase entière. */
.tbl.ope td{white-space:normal}
.tbl.ope td.date{min-width:6.5rem;font-size:12px;white-space:normal}
/* La place du bouton « Filtres » flottant : la dernière ligne de la liste ne passe pas dessous. */
.page-promos{padding-bottom:calc(var(--bottom) + 90px)}
.tbl.ope .pill{white-space:normal}
.tbl.ope td.lib{max-width:22rem}
/* Le titre tient sur deux lignes au plus : en production, « BOEHRINGER - PROMO BRI 2€ FRONTPRO &
   COMBOT CHAT - JUIN 2026 » en prenait quatre et faisait des rangées deux fois trop hautes. Le titre
   entier reste dans l'infobulle. */
.tbl.ope td.lib > a.b{max-width:100%;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* Tableau des opérations : le logo du laboratoire, et la colonne d'action à droite. */
/* Dans le tableau, la marque parle d'elle-même : le logo prend la place du nom, en plus grand. Le nom
   n'apparaît que s'il n'y a pas de logo — ou si l'image ne charge pas (`.sans-logo`, posé par onerror).
   ⚠ UNE TUILE CARRÉE, PAS UNE BANDE : les logos servis sont presque tous des carrés de 200 px (mesuré
     sur huit : six carrés, deux paysage) avec beaucoup de blanc autour. Dans une bande large et basse,
     ils se réduisaient à la hauteur et devenaient illisibles.
   ⚠ ZOOM ×1,25, ET PAS PLUS : le blanc de la source se mange au recadrage. Comparé sur six vrais logos
     (Pierre Fabre, Bouchara, Modilac, Arkopharma, Lierac, Gilbert) — à ×1,45 « LABORATOIRES GILBERT »
     perd le bas de ses lettres, à ×1,25 aucun n'est entamé. Labscore calcule, lui, un zoom PAR logo
     (analyse des pixels, impossible ici : l'image vient d'un autre domaine et teinte le canevas) ; le
     jour où l'API le sert, ce nombre-là remplacera celui-ci. */
.tbl.ope td.labo{white-space:normal;text-align:center}
.tbl.ope td.labo .promo-logo{margin:0 auto}
/* ---------- fiche d'une nouveauté, en panneau (dialog) ----------
   Le panneau est rendu par le serveur et seulement ouvert par le script : rien n'est reconstruit. */
dialog.fiche{border:0;padding:0;background:transparent;max-width:min(760px,94vw);width:100%;max-height:88vh}
dialog.fiche::backdrop{background:var(--voile)}
/* ---------- gaveta des filtres des promotions (02/10/2026) ----------
   À droite sur ordinateur, toute la hauteur ; au téléphone, elle monte du bas (« bottom sheet ») et le
   bouton « Afficher » reste sous le pouce. Chaque choix est une puce de 40 px avec son nombre. */
dialog.fiche.tiroir{position:fixed;inset:0 0 0 auto;margin:0;width:min(460px,100vw);max-width:100vw;height:100dvh;max-height:100dvh}
.tiroir-form{height:100%;display:flex;flex-direction:column;background:var(--pop-bg);border-left:1px solid var(--line);box-shadow:var(--shadow)}
.tiroir-tete{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px 18px;border-bottom:1px solid var(--line-2)}
.tiroir-tete h2{display:flex;align-items:center;gap:8px;font-size:var(--fs-h2);margin:0}
.tiroir-tete h2 svg{width:20px;height:20px;color:var(--green)}
.tiroir-corps{flex:1 1 auto;overflow:auto;padding:4px 18px 8px;display:flex;flex-direction:column;overscroll-behavior:contain}
.tiroir-groupe{border-bottom:1px solid var(--line-2);min-width:0}
.tiroir-groupe:last-child{border-bottom:0}
.tiroir-groupe > summary{display:flex;align-items:center;gap:8px;min-height:48px;cursor:pointer;list-style:none;
  -webkit-tap-highlight-color:transparent}
.tiroir-groupe > summary::-webkit-details-marker{display:none}
.tiroir-groupe > summary > svg:first-child{width:17px;height:17px;color:var(--green);flex:0 0 auto}
.tiroir-groupe > summary .t{font-size:14px;font-weight:900;color:var(--ink)}
.tiroir-groupe > summary .resume{margin-left:auto;font-size:12.5px;font-weight:700;color:var(--ink-3);text-align:right;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.tiroir-groupe > summary .resume.on{color:var(--green-dark);font-weight:900}
.tiroir-groupe > summary > svg:last-child{width:16px;height:16px;color:var(--ink-3);flex:0 0 auto;transition:transform .15s}
.tiroir-groupe[open] > summary > svg:last-child{transform:rotate(180deg)}
.tiroir-groupe > fieldset{border:0;margin:0;padding:2px 0 16px;min-width:0}
.puces{display:flex;flex-wrap:wrap;gap:8px}
.tiroir-periode{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.tiroir-periode label{display:flex;flex-direction:column;gap:4px;font-size:12px;font-weight:800;color:var(--ink-3)}
.tiroir-periode .select{min-height:44px;font-size:14px;font-weight:700}
.tiroir-groupe .tiny{margin:6px 0 0}
/* UNE OPTION PAR LIGNE (Bruno, 02/10/2026) : la case à gauche, le libellé, le nombre à droite ; la ligne
   entière se touche (46 px) et se teinte quand elle est cochée. */
.tiroir-groupe .puces{flex-direction:column;flex-wrap:nowrap;gap:2px}
.puce{display:flex;align-items:center;gap:12px;min-height:46px;padding:0 10px;border-radius:10px;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.puce:hover{background:var(--surface-2)}
.puce input{flex:0 0 auto;width:20px;height:20px;margin:0;accent-color:var(--green);cursor:pointer}
.puce span{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:8px;color:var(--ink-2);font-size:14px;font-weight:700;line-height:1.25}
.puce .n{margin-left:auto;font-size:12px;font-weight:900;line-height:1.6;padding:0 8px;border-radius:999px;background:var(--surface-2);color:var(--ink-3)}
.puce:has(input:checked){background:var(--green-soft)}
.puce input:checked + span{color:var(--green-dark);font-weight:900}
.puce input:checked + span .n{background:var(--green);color:#fff}
.puce input:focus-visible{outline:2px solid var(--green);outline-offset:2px}
.puce.vide{cursor:default;opacity:.45}
.puce.vide:hover{background:none}
.puce.vide input{cursor:default}
.puce.courant span::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--orange-dark);flex:0 0 auto}
/* Photo : la couleur de la pastille des cartes devant chaque état ; la ligne « urgente » en rouge. */
.puce[class*="ph-"] span::before{content:"";width:10px;height:10px;border-radius:50%;background:var(--line);flex:0 0 auto}
.puce.ph-urgente span::before{background:var(--red)}
.puce.ph-retard span::before{background:var(--red-dark)}
.puce.ph-bientot span::before{background:var(--orange-dark)}
.puce.ph-ok span::before{background:var(--green)}
.puce.ph-urgente span{color:var(--red-dark)}
.puce.ph-urgente input{accent-color:var(--red)}
.puce.ph-urgente:has(input:checked){background:var(--red-soft)}
.puce.ph-urgente input:checked + span{color:var(--red-dark)}
.puce.ph-urgente input:checked + span .n{background:var(--red)}
/* Pré-filtres : des lignes-liens en tête de la gaveta, appliquées au clic. */
.tiroir-pref{display:flex;flex-direction:column;gap:6px;padding:12px 0 14px;border-bottom:1px solid var(--line-2)}
.tiroir-pref h3{display:flex;align-items:center;gap:8px;margin:0 0 2px;font-size:14px;font-weight:900;color:var(--ink)}
.tiroir-pref h3 svg{width:17px;height:17px;color:var(--orange-dark)}
.prefiltre{display:flex;align-items:center;gap:10px;min-height:48px;padding:0 12px;border-radius:12px;border:1.5px solid var(--line);
  background:var(--surface);color:var(--ink);font-size:14px;font-weight:800;text-decoration:none}
.prefiltre:hover{border-color:var(--green);text-decoration:none}
.prefiltre svg{width:18px;height:18px;color:var(--green);flex:0 0 auto}
.prefiltre span{flex:1 1 auto;min-width:0}
.prefiltre .n{font-size:12px;font-weight:900;line-height:1.6;padding:0 8px;border-radius:999px;background:var(--surface-2);color:var(--ink-3)}
.prefiltre.on{background:var(--accent-bg);border-color:var(--accent-bg);color:var(--on-accent)}
.prefiltre.on svg{color:var(--on-accent)}
.prefiltre.on .n{background:var(--surface);color:var(--green-dark)}
.prefiltre.urgente svg{color:var(--red)}
.prefiltre.urgente:not(.vide) .n{background:var(--red);color:#fff}
.prefiltre.vide{opacity:.5}
.tiroir-pied{display:flex;align-items:center;gap:10px;padding:12px 18px calc(12px + env(safe-area-inset-bottom));border-top:1px solid var(--line-2)}
.tiroir-pied .btn.primary{flex:1 1 auto;justify-content:center;min-height:44px}
@media(max-width:820px){
  dialog.fiche.tiroir{inset:auto 0 0 0;width:100vw;height:auto;max-height:90dvh}
  .tiroir-form{max-height:90dvh;border-left:0;border-top:1px solid var(--line);border-radius:18px 18px 0 0}
}
/* La barre au-dessus de la liste : le bouton « Filtres » (avec le nombre de choix retenus), puis les pastilles. */
.filtres-barre{display:flex;align-items:center;gap:10px;margin-top:12px;min-width:0}
.filtres-barre .chips{flex:1 1 auto;min-width:0}
.filtres-btn{flex:0 0 auto;display:inline-flex;align-items:center;gap:8px;min-height:40px;padding:0 16px;border-radius:999px;
  border:1.5px solid var(--line);background:var(--surface);color:var(--ink-2);font-weight:900;cursor:pointer}
.filtres-btn svg{width:18px;height:18px;color:var(--green)}
.filtres-btn:hover{border-color:var(--green)}
.filtres-btn .n{font-size:11px;font-weight:900;line-height:1.6;padding:0 7px;border-radius:999px;background:var(--green);color:#fff}
.filtres-btn.on{border-color:var(--green);color:var(--green-dark)}
/* Le bouton « Filtres » flottant (02/10/2026) : vert plein, ombre portée, en bas à droite ; au téléphone,
   au-dessus de la barre de navigation (--bottom). Le nombre de choix retenus dans une pastille blanche. */
.filtres-fab{position:fixed;right:20px;bottom:calc(var(--bottom) + 20px);z-index:40;display:inline-flex;align-items:center;gap:9px;
  min-height:54px;padding:0 22px;border:0;border-radius:999px;background:var(--accent-bg);color:var(--on-accent);
  font:inherit;font-size:15px;font-weight:900;cursor:pointer;box-shadow:0 6px 18px rgba(0,0,0,.22),0 2px 5px rgba(0,0,0,.14)}
.filtres-fab:hover{filter:brightness(1.06)}
.filtres-fab svg{width:20px;height:20px}
.filtres-fab .n{font-size:12px;font-weight:900;line-height:1.6;padding:0 8px;border-radius:999px;background:var(--surface);color:var(--green-dark)}
@media (max-width:819.98px){ .filtres-fab{right:14px;bottom:calc(var(--bottom) + 14px);min-height:50px;padding:0 18px} }
.filtres-barre:empty{display:none}
.mod.circuit h3 .court{display:none}
.sur-telephone{display:none}

.fiche-in{background:var(--pop-bg);border:1px solid var(--line);border-radius:var(--r);padding:var(--pad-card);
  display:flex;flex-direction:column;gap:12px;max-height:88vh;overflow:auto;box-shadow:var(--shadow)}
.fiche-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}
.fiche-head h2{font-size:var(--fs-h2);margin:2px 0 0;overflow-wrap:break-word}
.fiche-head .lab{font-size:var(--fs-2xs);font-weight:900;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-3)}
.fiche-photos{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,200px),1fr));gap:10px}
.nv-grande{margin:0;border:1px solid var(--line-2);border-radius:var(--r-sm);overflow:hidden;background:var(--surface-2)}
.nv-grande img{display:block;width:100%;height:220px;object-fit:contain;background:var(--surface-2)}
.nv-grande figcaption{padding:6px 8px;font-size:var(--fs-xs);color:var(--ink-2);font-weight:600}
.nv-grande[hidden]{display:none}
.fiche-bloc h3{font-size:var(--fs-h3);margin-bottom:4px}
.fiche-pied{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;
  border-top:1px solid var(--line-2);padding-top:10px}
/* Un titre qui ouvre la fiche : un bouton, mais qui se lit comme le titre qu'il remplace. */
.lien-titre{border:0;background:none;padding:0;margin:0;font:inherit;color:inherit;text-align:left;cursor:pointer}
.lien-titre:hover{text-decoration:underline}
.tbl .lien-titre{font-weight:800;color:var(--navy)}
@media (max-width:520px){ .nv-grande img{height:180px} }

/* Tableau des nouveautés : la vignette rappelle le produit, elle ne le montre pas — la carte le fait. */
.tbl.nv .nv-mini{display:block;float:left;width:34px;height:34px;margin:0 8px 2px 0;overflow:hidden;
  border:0;padding:0;cursor:pointer;border-radius:var(--r-xs);background:var(--surface-2)}
.tbl.nv .nv-mini img{width:34px;height:34px;object-fit:contain}
.tbl.nv .nv-mini[hidden]{display:none}
/* Deux lignes par nouveauté : le prix et la marge portent chacun une note, et les mettre bout à bout
   poussait le tableau à 1 133 px pour 1 034 — c'est « Votre réponse » qui sortait de l'écran. */
.tbl.nv td .sous,.tbl.nv td.num .sous{display:block;margin:3px 0 0;white-space:normal}
.tbl.nv td.lib{max-width:22rem;white-space:normal}
.tbl.nv td.reponse{white-space:normal;min-width:15rem}
.tbl.nv td.reponse .form-ligne{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.tbl.nv td.reponse .input.qte{width:5.5rem}
.tbl.nv td.reponse .repli{margin-top:4px}
.tbl.nv td.lib .sous .pill{margin-top:2px}
.tbl.ope td.labo .nom.repli-nom{display:none}
.tbl.ope td.labo.sans-logo .nom.repli-nom{display:block}
.tbl.ope td.actions,.tbl.ope th.actions{text-align:right;white-space:nowrap;width:1%;padding-left:4px;padding-right:10px}
.tbl.ope td.actions .btn.fleche{width:34px;height:34px;min-height:0;padding:0;justify-content:center}
.tbl.ope td.actions .btn.fleche svg{width:16px;height:16px;margin:0}
.tbl.ope td.photo,.tbl.ope th.photo{text-align:center;white-space:nowrap}
.tbl.ope td.emp{white-space:normal}
/* La promotion consommateur (30/09/2026) : un texte de la centrale, deux lignes au plus, le reste en infobulle. */
.tbl.ope td.comp{white-space:normal;min-width:7.5rem;max-width:12rem;font-size:12.5px;color:var(--ink-2)}
/* En-têtes sur deux lignes au besoin (« Promotion / consommateur ») : sur une seule, ils élargissaient leur
   colonne au-delà de son contenu, et le tableau débordait à 1 280 px (02/10/2026). */
.tbl.ope thead th{white-space:normal;line-height:1.2;vertical-align:bottom;hyphens:auto;-webkit-hyphens:auto}
.card.promo .comp{font-size:12.5px;color:var(--ink-2)}
.tbl.ope td.emp .tag-emp{margin:1px 2px 1px 0}
.tbl.ope td.photo .sous{display:block;margin:3px 0 0;font-size:10.5px;white-space:nowrap}
/* Dans le tableau, le titre porte la ligne : l'étiquette de circuit descend d'un cran (11 px, moins
   de fond, le nom du circuit en gris) pour ne pas lui disputer l'œil. */
.tbl.ope td.lib > a.b{font-size:14.5px}
.tbl.ope td.lib .sous{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.tbl.ope td.lib .sous .tagc{margin-top:0;font-size:10.5px;padding:1px 7px;gap:4px}
.tbl.ope td.lib .sous .tag-photo{width:24px;height:20px}
.tbl.ope td.lib .sous .tagc span{font-weight:600;color:var(--ink-2)}

/* Photos et liens d'une nouveauté (contrat § 2.4, servis par Labscore depuis le 21/09/2026).
   Les photos sont chargées depuis labscore.fr : la politique de contenu autorise cette
   origine, déduite de l'adresse de l'API (helpers.php). */
/* Le parcours d'une nouveauté (contrat § 2.4.4, 02/10/2026) : les six étapes de Labscore. Cases datées
   dans la fiche ; pastilles seules sur la carte et dans le tableau, où six libellés ne tiennent pas
   (libellé et date en infobulle). Vert : fait · ambre : en cours · gris : à venir · rouge : abandon. */
.nv-frise{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:6px;list-style:none;margin:4px 0;padding:0}
.nv-frise li{display:flex;flex-direction:column;gap:2px;min-width:0;padding:6px 6px;border:1px solid var(--line-2);
  border-radius:var(--r-sm);background:var(--surface-2);color:var(--ink-3);font-size:12px}
.nv-frise .t{display:flex;align-items:center;gap:5px;font-weight:800;min-width:0;font-size:11.5px}
.nv-frise .l{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.nv-frise .n{display:inline-grid;place-items:center;flex:none;width:18px;height:18px;border-radius:50%;
  background:var(--line);color:var(--ink-2);font-size:10.5px;font-weight:900}
.nv-frise .n svg{width:11px;height:11px}
.nv-frise .d{font-size:11px;font-weight:600}
.nv-frise li.fait{background:var(--green-soft);border-color:var(--green-soft-2);color:var(--green-dark)}
.nv-frise li.fait .n{background:var(--green);color:#fff}
.nv-frise li.encours{background:var(--orange-soft);border-color:var(--orange-soft-2);color:var(--orange-ink)}
.nv-frise li.encours .n{background:var(--orange-dark);color:#fff}
.nv-frise li.arret{background:var(--red-soft);border-color:var(--red-soft-2);color:var(--red-dark)}
.nv-frise li.arret .n{background:var(--red);color:#fff}
.nv-frise.mini{display:flex;gap:4px;margin:6px 0 2px}
.nv-frise.mini li{padding:0;border:0;background:none}
.nv-situation{font-size:12.5px;font-weight:700;color:var(--ink-2);margin:0}
/* Le complément après la date limite (§ 2.4.5) : une règle à part, dite avant le formulaire. */
.nv-complement{font-size:12.5px;line-height:1.35;color:var(--orange-ink);background:var(--orange-soft);border-radius:var(--r-sm);padding:6px 9px;margin:0}
@media(max-width:520px){ .nv-frise:not(.mini){grid-template-columns:repeat(3,minmax(0,1fr))} }
/* « À engager » : sous-filtres et bascule vers la réponse en masse (02/10/2026). */
.nv-filtres{display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;margin:0 0 12px}
.nv-stock{font-weight:800;color:var(--green-dark)}
.nv-masse .coche{width:36px;text-align:center}
.nv-masse .coche input{width:18px;height:18px;cursor:pointer}
.nv-masse .lib label{cursor:pointer}
.nv-masse .qte{width:88px;text-align:right}
.nv-masse-pied{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:12px 14px;border-top:1px solid var(--line-2)}
.nv-masse-pied .tiny{flex:1 1 260px}
.nv-photos{display:grid;grid-template-columns:repeat(auto-fill,minmax(84px,1fr));gap:6px;margin:2px 0 4px}
.nv-ph{display:block;border:1px solid var(--line-2);border-radius:var(--r-xs);overflow:hidden;background:var(--surface-2);text-decoration:none}
.nv-ph:hover{border-color:var(--green)}
/* `contain` et pas `cover` : une boîte photographiée en hauteur se ferait rogner la tête
   et le pied, et c'est là que se lisent la marque et le dosage. */
.nv-ph img{display:block;width:100%;height:72px;object-fit:contain;background:var(--surface-2)}
/* ⚠ LA LÉGENDE PASSE À LA LIGNE, ELLE NE SE COUPE PAS. Tronquée, « Le produit en
   linéaire » s'affichait « Le produit en li… » — vu à la capture, à 1280 px comme à
   390. Une légende qui s'arrête au milieu d'un mot n'apprend rien, et la place ne
   manque pas : la carte a de la hauteur à revendre. Deux lignes au plus, pour que
   les vignettes d'une même rangée gardent des hauteurs voisines. */
.nv-ph span{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
            padding:3px 5px;font-size:var(--fs-2xs);color:var(--ink-2);line-height:1.25;
            overflow:hidden;overflow-wrap:anywhere}
/* ⚠ `[hidden]` DOIT ÊTRE FORCÉ : la règle du navigateur porte la spécificité la plus faible
   qui soit, et `.nv-ph{display:block}` la bat. Sans cela, une photo retirée par la centrale
   laisserait un cadre vide que le script croit avoir caché. */
.nv-photos [hidden]{display:none !important}
/* Photos envoyées par l'officine sur une promotion (contrat § 3.1.1, 03/10/2026) : les vignettes de
   l'historique et l'aperçu avant l'envoi reprennent celles des nouveautés. `.doc .t span` réduirait
   et grisait tout ce qui est dans la ligne : la grille et l'état se redéclarent. */
.doc .t .nv-photos.preuves{display:grid;grid-template-columns:repeat(auto-fill,84px);margin:6px 0 2px}
.preuves-apercu{grid-template-columns:repeat(auto-fill,84px)}
.preuves-apercu[hidden]{display:none}
.preuves-apercu .nv-ph{cursor:default}
.preuves-apercu canvas{display:block;width:100%;height:72px;object-fit:contain;background:var(--surface-2)}
/* Les deux boutons du choix (Bruno, 03/10/2026) : « Prendre une photo » ouvre l'appareil, « Choisir des
   photos » la galerie. Le champ est caché (`.sr-only`) dans son étiquette : c'est l'étiquette qui se
   touche, et elle prend le contour du clavier quand le champ a le focus. */
.preuves-choix{display:flex;flex-direction:column;gap:6px}
.preuves-boutons{display:flex;flex-wrap:wrap;gap:6px}
.preuves-boutons .btn{flex:1 1 150px;min-height:40px;position:relative}   /* ancre du champ caché */
.preuves-boutons label:focus-within{outline:2px solid var(--green);outline-offset:2px}
.preuves-choix.pleine .preuves-boutons{display:none}
/* Sur ordinateur, `capture` est ignoré : le bouton ouvrirait la même fenêtre de fichiers que l'autre. */
@media (hover:hover) and (pointer:fine){.preuve-camera{display:none}}
.preuves-apercu .nv-ph{position:relative}
.preuve-retirer{position:absolute;top:3px;right:3px;width:32px;height:32px;border:0;border-radius:50%;
                background:rgba(0,0,0,.62);color:#fff;font-size:20px;line-height:1;cursor:pointer;
                display:flex;align-items:center;justify-content:center}
.preuve-retirer:hover{background:rgba(0,0,0,.8)}
.preuve-nom{display:flex;align-items:center;justify-content:center;height:72px;padding:4px;font-size:var(--fs-2xs);
            color:var(--ink-2);overflow-wrap:anywhere;text-align:center}
.preuves-compte.refusee{color:var(--red-dark);font-weight:700}
.preuve-etat{display:block;font-size:var(--fs-xs);color:var(--ink-3);margin-top:2px}
.doc .t .preuve-etat.validee,.preuve-etat.validee{color:var(--green-dark);font-weight:700}
.doc .t .preuve-etat.refusee,.preuve-etat.refusee{color:var(--red-dark);font-weight:700}
.nv-liens{display:flex;flex-direction:column;gap:3px;margin:2px 0 4px}
.nv-liens a{display:flex;align-items:center;gap:6px;font-size:var(--fs-xs);color:var(--blue-dark);
            font-weight:700;text-decoration:none;min-height:28px;word-break:break-word}
.nv-liens a:hover{text-decoration:underline}
.nv-liens svg{width:13px;height:13px;flex:0 0 auto;color:var(--blue)}

/* detail blocks */
.kv{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
.kv.k1{grid-template-columns:minmax(0,1fr)} .kv.k2{grid-template-columns:repeat(2,minmax(0,1fr))}
.kv.k4{grid-template-columns:repeat(4,minmax(0,1fr))}
/* Six tuiles sur une rangée au-dessus de 1080 px (Vue 360°) : en trois colonnes, les prix et les stocks
   d'un article prenaient deux rangées et repoussaient tout le reste sous la ligne de flottaison. */
@media (min-width:1080.02px){ .kv.k6{grid-template-columns:repeat(6,minmax(0,1fr))} .kv.k6 .k{padding:10px 12px} }
.kv .k{background:var(--surface-2);border:1px solid var(--line-2);border-radius:12px;padding:12px 14px;min-width:0}
.kv .k .l{font-size:12px;color:var(--ink-3);font-weight:800}
.kv .k .v{font-size:var(--fs-kv);font-weight:900;margin-top:2px;color:var(--navy);overflow-wrap:break-word}
.kv .k .s{font-size:12px;color:var(--ink-2)}
.kv .k.good{background:var(--green-soft);border-color:transparent} .kv .k.good .l,.kv .k.good .s{color:var(--green-dark)}
.kv .k .v.down,.kv .k .s.down{color:var(--red-dark)}
.kv .k.bad{background:var(--red-soft);border-color:transparent} .kv .k.bad :is(.l,.v,.s){color:var(--red-dark)}
/* liste de définitions : libellé à gauche, valeur à droite, note dessous */
.kv.liste{display:block}
.kv.liste .k{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:2px 12px;background:none;border:0;border-bottom:1px solid var(--line-2);border-radius:0;padding:9px 0}
.kv.liste .k:last-child{border-bottom:0}
.kv.liste .k .l{font-size:var(--fs-sm);font-weight:700;color:var(--ink-2)}
.kv.liste .k .v{font-size:15px;margin:0 0 0 auto;text-align:right}
.kv.liste .k .s{flex-basis:100%;font-size:var(--fs-xs)}
.kv.liste .k.good .v{color:var(--green-dark)} .kv.liste .k.bad{background:none} .kv.liste .k.bad .l{color:var(--ink-2)} .kv.liste .k.bad .v{color:var(--red-dark)}
.thread{display:flex;flex-direction:column;gap:12px}
.msg{display:flex;gap:10px;max-width:640px}
.msg img,.msg .av{width:32px;height:32px;border-radius:50%;object-fit:cover;flex:none}
.msg .av{background:var(--green);color:#fff;display:grid;place-items:center;font-size:11px;font-weight:900}
.msg .bub{background:var(--surface-2);border:1px solid var(--line-2);border-radius:12px;padding:10px 12px;font-size:13.5px}
.msg .bub .who{font-size:12px;color:var(--ink-3);font-weight:800;margin-bottom:2px}
.msg.me{align-self:flex-end;flex-direction:row-reverse}
.msg.me .bub{background:var(--green-soft);border-color:transparent}
.steps{display:flex;gap:0;align-items:center;flex-wrap:wrap}
.steps .st{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:800;color:var(--ink-3)}
.steps .st::before{content:"";width:10px;height:10px;border-radius:50%;background:var(--line);flex:none}
.steps .st.done{color:var(--green-dark)} .steps .st.done::before{background:var(--green)}
.steps .st.now{color:var(--navy)} .steps .st.now::before{background:var(--blue);box-shadow:0 0 0 4px var(--blue-soft)}
.steps .ln{width:34px;height:1px;background:var(--line);margin:0 10px}
.back{display:inline-flex;align-items:center;gap:6px;font-weight:800;color:var(--ink-2);font-size:13.5px}
.back svg{width:16px;height:16px}
.crumbs{font-size:12.5px;color:var(--ink-3);font-weight:700;display:flex;gap:6px;row-gap:2px;align-items:center;flex-wrap:wrap}
.crumbs a{color:var(--ink-3);white-space:nowrap}
.crumbs .cur{color:var(--navy);min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* product 360 */
.p360{display:grid;grid-template-columns:240px minmax(0,1fr);gap:20px}
.p360 .vis{background:var(--surface-2);border:1px solid var(--line-2);border-radius:14px;aspect-ratio:1;display:grid;place-items:center;color:var(--ink-3)}
.p360 .vis svg{width:64px;height:64px;opacity:.4}
.titre-fiche{font-size:22px;line-height:1.2;margin-top:2px}

/* group page */
.pharm{padding:0;overflow:hidden;display:flex;flex-direction:column}
.pharm .top{position:relative;height:150px;background-size:cover;background-position:center}
.pharm .top::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(20,40,70,0) 40%,rgba(20,40,70,.72))}
.pharm .top .city{position:absolute;left:14px;bottom:10px;color:#fff;font-weight:900;font-size:18px;z-index:1;text-shadow:0 1px 3px rgba(0,0,0,.7)}
.pharm .top img{position:absolute;right:10px;bottom:0;height:138px;width:auto;z-index:1;filter:drop-shadow(0 4px 10px rgba(0,0,0,.35))}
.pharm .b{padding:14px 16px;display:flex;flex-direction:column;gap:3px;min-width:0}
.pharm .b b{font-size:14.5px;color:var(--navy)}
.pharm .b > span:not(.tiny){font-size:12.5px;color:var(--ink-2)}
.pharm .b a{overflow-wrap:anywhere}

/* docs & news */
.doc{display:flex;align-items:center;gap:12px;padding:12px 0;border-top:1px solid var(--line-2)}
.doc:first-child{border-top:0;padding-top:0}
.doc .ic{width:38px;height:38px;font-size:11px;font-weight:900}
.doc .t{flex:1;min-width:0}
.doc .t b{display:block;color:var(--navy)}
.doc .t span{font-size:12.5px;color:var(--ink-3)}
.news{display:flex;gap:14px;padding:12px 0;border-top:1px solid var(--line-2)}
.news:first-child{border-top:0;padding-top:0}
.news > div{min-width:0}
.news .d{font-size:12px;color:var(--ink-3);font-weight:800;width:64px;flex:none;padding-top:3px}
.news b{display:block;color:var(--navy)}
.news p{font-size:13.5px;color:var(--ink-2);margin-top:2px}
.news .tagr{display:inline-block;font-size:10px;font-weight:900;letter-spacing:.06em;color:var(--green-dark);background:var(--green-soft);padding:2px 7px;border-radius:5px;margin-bottom:4px}

/* footer */
.footer{margin-top:auto;border-top:1px solid var(--line);padding:16px var(--pad-page);display:flex;align-items:center;gap:16px;font-size:12.5px;color:var(--ink-2);flex-wrap:wrap}
.footer .links{margin-left:auto;display:flex;flex-wrap:wrap;gap:6px 16px}
.footer .links > *{white-space:nowrap}
.footer .links a{color:var(--ink-2)}

/* fraîcheur des sources (règle 3 : chaque source datée par son passage) */
.fraicheur{display:flex;flex-wrap:wrap;gap:2px 14px;font-size:11.5px;color:var(--ink-2);margin:-6px 0 0}
.fraicheur > span{max-width:100%} .fraicheur .src{font-weight:700;white-space:nowrap} .fraicheur .ko{color:var(--red-dark);font-weight:800}
.fraicheur .demo{font-size:10px;font-weight:800;padding:0 5px;border-radius:4px;background:var(--grey-soft)}

/* login */
.login{min-height:100vh;display:flex;flex-direction:column}
.login .wrap{padding:24px;max-width:1100px;width:100%;margin:0 auto;display:flex;flex-direction:column;gap:22px}
.pick{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px}
.pick button{padding:0;border:1px solid var(--line);background:var(--surface);border-radius:14px;overflow:hidden;text-align:left;cursor:pointer;display:flex;flex-direction:column;font:inherit}
.pick button:hover{box-shadow:var(--shadow)}
.pick .ph{height:110px;background-size:cover;background-position:center;position:relative}
.pick .ph img{position:absolute;right:-6px;bottom:-4px;width:56px;height:56px;border-radius:50%;object-fit:cover;border:3px solid var(--surface);background:var(--green-soft)}
.pick .tx{padding:12px 14px}
.pick .tx b{display:block;font-size:14px;color:var(--navy)}
.pick .tx span{font-size:12px;color:var(--ink-2)}
.pick .code{font-size:11px;font-weight:900;color:var(--green)}
.login .cen{display:flex;align-items:center;gap:12px;padding:14px 16px;border:1px solid var(--line);border-radius:14px;background:var(--surface);max-width:560px}

/* auth */
.auth{flex:1;display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:24px;max-width:1100px;width:100%;margin:0 auto;padding:28px 24px;align-items:start;align-content:start}   /* en une colonne, les rangées ne s'étirent pas sur la hauteur libre */
.auth.seule{grid-template-columns:minmax(0,1fr);max-width:640px}
.auth-visual{position:relative;border-radius:18px;overflow:hidden;min-height:440px;background:var(--surface);border:1px solid var(--line-2)}
.auth-visual .photo{position:absolute;inset:0;background-size:cover;background-position:60% 30%}
.auth-visual::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 35%,color-mix(in srgb,var(--surface) 92%,transparent) 72%,var(--surface) 100%)}
.auth-visual .txt{position:absolute;left:0;right:0;bottom:0;padding:26px 28px;z-index:1}
.auth-visual .eyebrow{display:flex;align-items:center;gap:10px}
.auth-visual .eyebrow::before{content:"";width:44px;height:3px;border-radius:2px;background:var(--green);flex:none}
.auth-visual h1{margin-top:8px;color:var(--navy)}
.auth-visual .sub{margin-top:8px;color:var(--ink-2);max-width:46ch}
.auth-visual .tagline{margin-top:14px;font-family:var(--script);font-size:26px;line-height:1.05;color:var(--green-dark);transform:rotate(-2deg);transform-origin:left;display:inline-block;position:relative}
.auth-visual .tagline::after{content:"";position:absolute;left:4px;right:14px;bottom:-6px;height:3px;border-radius:3px;background:var(--green)}
.auth-card{background:var(--surface);border:1px solid var(--line);border-radius:18px;padding:30px 30px 24px;display:flex;flex-direction:column;gap:16px;box-shadow:var(--shadow);min-width:0}
.auth-card h2{font-size:22px}
.auth-card .lead{color:var(--ink-2);font-size:14px;margin-top:4px}
.auth-card form{display:flex;flex-direction:column;gap:14px}
.auth-card .row{display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap;font-size:13px}
.auth-card .row a{white-space:nowrap}
.auth-card .row label{display:flex;align-items:center;gap:8px;font-weight:700;color:var(--ink-2);cursor:pointer}
.auth-card .row input{accent-color:var(--green)}
.auth-card .btn.primary{padding:12px 16px;font-size:15px}
.auth-card .sep{display:flex;align-items:center;gap:12px;color:var(--ink-3);font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.06em}
.auth-card .sep::before,.auth-card .sep::after{content:"";flex:1;height:1px;background:var(--line)}
/* boutons de démo de la connexion (form.demo : .demo seul désigne aussi la mention « démo » de la fraîcheur) */
.demo-niveau{display:flex;align-items:center;gap:8px;margin:0 0 8px;font-weight:700;color:var(--ink-2)} .demo-niveau .select{width:auto}
form.demo,.auth-card form.demo{display:grid;grid-template-columns:repeat(auto-fill,minmax(76px,1fr));gap:6px}
form.demo button{border:1px solid var(--line);background:var(--surface);border-radius:12px;padding:8px 4px 6px;cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:5px;font:inherit;min-width:0}
form.demo button:hover{border-color:var(--green);background:var(--green-soft)}
form.demo img{width:40px;height:40px;border-radius:50%;object-fit:cover;background:var(--green-soft)}
form.demo span{font-size:10.5px;font-weight:800;color:var(--ink-2);line-height:1.1;text-align:center;max-width:100%;overflow-wrap:normal;hyphens:manual}
.auth-card .foot{font-size:12px;color:var(--ink-3);text-align:center;margin-top:auto}
.field .pw{position:relative}
.field .pw button{position:absolute;right:8px;top:50%;transform:translateY(-50%);border:0;background:none;color:var(--ink-3);cursor:pointer;font-size:12px;font-weight:800}

/* toast */
.toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);width:max-content;max-width:calc(100vw - 28px);background:var(--navy);color:#fff;padding:11px 16px;border-radius:12px;font-weight:800;font-size:13.5px;box-shadow:var(--shadow);z-index:100;display:flex;align-items:center;gap:10px}
.toast svg{width:16px;height:16px;color:#7FE0A3}
:root[data-theme="dark"] .toast{background:#2A3446} @media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .toast{background:#2A3446}}

/* charts */
.chart{width:100%;height:auto}
.legend{display:flex;flex-wrap:wrap;gap:6px 14px;font-size:12.5px;color:var(--ink-2);font-weight:700}
.legend span{white-space:nowrap}
.legend i{display:inline-block;width:10px;height:10px;border-radius:2px;margin-right:6px;vertical-align:middle}

/* ---------- utilitaires d'affichage par largeur ---------- */
/* .show-sm n'est MASQUÉ qu'au-dessus de 520 px : pas de display:revert, qui annulerait .tbl .sous{display:block} */
@media (min-width:520.02px){.show-sm{display:none!important}}
@media (min-width:1080.02px){.show-md{display:none!important}}

/* ---------- responsive ---------- */
@media (max-width:1180px){
  .g4,.g5{grid-template-columns:repeat(3,minmax(0,1fr))}
  .pick{grid-template-columns:repeat(3,minmax(0,1fr))}
  .hero .titulaire{display:none}
  /* circuits : rangée défilante de pastilles d'environ 44 px */
  .grid.circuits{display:flex;gap:8px;overflow-x:auto;scrollbar-width:none;padding-inline-end:28px;
    -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 28px),transparent);mask-image:linear-gradient(90deg,#000 calc(100% - 28px),transparent)}
  .grid.circuits::-webkit-scrollbar{display:none}
  /* La pastille reprend le flux en ligne : `display:flex` est répété ici parce que la tuile large est
     en grille (aires nommées), qui l'emporterait sinon sur le `display` de `.mod`. */
  .grid.circuits .mod{display:flex;flex:0 0 auto;flex-direction:row;align-items:center;gap:8px;min-height:0;padding:8px 12px;border-radius:999px}
  .grid.circuits .mod .big{width:26px;height:26px} .grid.circuits .mod .big svg{width:14px;height:14px}
  .grid.circuits .mod :is(p,.n){display:none}
  .grid.circuits .mod h3{font-size:13px;margin:0;white-space:nowrap}
  /* modules de l'accueil : 2 colonnes plutôt que 3 + 3 + 2 */
  .grid.mods{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:1080px){
  .g-2-1,.p360{grid-template-columns:minmax(0,1fr)}
  .hide-md{display:none!important}
  /* tableur : la ligne unique tient tant qu'il y a la place ; en dessous, les cellules reviennent à la
     ligne plutôt que d'imposer un défilement horizontal dans la carte */
  .tbl.dense td{white-space:normal} .tbl.dense td.lib > :is(a.b,b){max-width:none;overflow:visible}
  .tbl.dense .sous,.tbl.dense td.num .sous,.tbl.dense td.date .sous{display:block;white-space:normal;margin:2px 0 0}
  /* accueil : dès que la grille du bas passe sur une colonne, « À traiter » passe avant les modules */
  .page-accueil > *{order:9} .page-accueil > .hero{order:0}
  .page-accueil > .accueil-bas{display:contents}
  .page-accueil .accueil-todo{order:1} .page-accueil > .accueil-mods{order:2} .page-accueil .accueil-news{order:3}
}
/* connexion : une colonne jusqu'à 1000 px (à deux colonnes, la carte tombait sous 350 px), visuel en bandeau */
@media (max-width:1000px){
  .auth{grid-template-columns:minmax(0,1fr);max-width:560px}
  .auth-visual{min-height:0;display:flex;flex-direction:column}
  .auth-visual .photo{position:relative;inset:auto;height:120px} .auth-visual::after{display:none}
  .auth-visual .txt{position:relative;padding:14px 18px}
}
@media (max-width:980px){
  .chart text{font-size:14px}                   /* unités du viewBox : le graphique rétrécit, le texte reste lisible */
  .g4,.g5,.g3{grid-template-columns:repeat(2,minmax(0,1fr))}
  .grid.stats:not(.s3){grid-template-columns:repeat(2,minmax(0,1fr))}
  .kv.k4{grid-template-columns:repeat(2,minmax(0,1fr))}
  .topnav .lbl,.topnav a > span:not(.count){position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
  .topnav a{padding:9px 10px;position:relative}
  .topnav a .count{position:absolute;top:0;right:0}
  .hero .quote{display:none}
  .hero .txt{max-width:70%}
  .hero::after{background:linear-gradient(90deg,var(--surface) 0%,color-mix(in srgb,var(--surface) 94%,transparent) 55%,color-mix(in srgb,var(--surface) 60%,transparent) 100%)}
}
@media (max-width:819.98px){
  .body{grid-template-columns:minmax(0,1fr)}
  .sidebar{display:none}
  .topbar{padding:0 12px;gap:8px}
  .topnav{display:none}
  .logo .l2{display:none}
  .me > div{display:none}
  .content{padding:14px var(--pad-page) 24px}
  /* panneaux : pleine largeur, bornés entre la barre du haut et la barre basse */
  .pop{position:fixed;left:8px;right:8px;width:auto;top:calc(var(--top) + 6px);max-height:calc(100dvh - var(--top) - var(--bottom) - 20px)}
  /* voile sans JS : l'ombre étendue détache le panneau de la page (surtout en sombre, même fond que les cartes) */
  .pop:not([hidden]){box-shadow:0 0 0 100vmax var(--voile),var(--shadow)}
  .pop.sheet{top:auto;bottom:calc(var(--bottom) + 8px)}
  /* barre basse : cinq entrées de largeur égale */
  /* hauteur calée sur le jeton --bottom : le contenu et la feuille « Plus » s'arrêtent au bon endroit */
  .bottomnav{display:flex;position:fixed;left:0;right:0;bottom:0;z-index:30;height:var(--bottom);background:var(--surface);border-top:1px solid var(--line);padding:4px 4px calc(4px + env(safe-area-inset-bottom))}
  .bottomnav > a,.bottomnav > button{flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;gap:2px;padding:6px 2px;border:0;background:none;font:inherit;font-size:10.5px;font-weight:800;color:var(--ink-3);text-decoration:none;border-radius:10px;position:relative;cursor:pointer}
  .bottomnav > a:hover{text-decoration:none}
  .bottomnav .lbl,.bottomnav > a > span:not(.count){max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.2}
  .bottomnav svg{width:22px;height:22px}
  .bottomnav .active,.bottomnav [aria-expanded="true"]{color:var(--red-dark)}
  .bottomnav .count{position:absolute;top:0;left:calc(50% + 7px);box-shadow:0 0 0 2px var(--surface)}   /* liseré : la pastille se détache de l'icône */
  .main{padding-bottom:var(--bottom)}
  .toast{bottom:calc(var(--bottom) + 12px)}
  /* bandeau : le texte d'abord, les actions dessous */
  .hero{flex-direction:column;align-items:stretch;min-height:0}
  /* .tall et .compact redonnés ici : leur hauteur de base (deux classes) l'emporterait sur .hero */
  .hero.tall,.hero.compact{min-height:0} .hero.tall .photo{background-size:cover;background-position:70% 30%} .hero.tall .txt{max-width:100%}
  .hero .txt,.hero.compact .txt{padding:16px 18px;max-width:100%}   /* .compact redonné : sa marge de base (deux classes) l'emporterait */
  .hero .actions{margin:0;padding:0 18px 16px;align-self:flex-start}
  .hero .sub{font-size:14px} .hero .tagline{font-size:20px}
  .hero::after{background:linear-gradient(90deg,var(--surface) 0%,color-mix(in srgb,var(--surface) 92%,transparent) 55%,color-mix(in srgb,var(--surface) 55%,transparent) 100%)}
  .g2,.g-2-1{grid-template-columns:minmax(0,1fr)}
  .grid.mods{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  .mod{min-height:0;padding:14px 12px;gap:6px} .mod .big{width:40px;height:40px} .mod .big svg{width:18px;height:18px} .mod h3{font-size:14px} .mod p{font-size:12px} .mod .kpi{display:block;padding:8px 10px;font-size:12px;line-height:1.3} .mod .kpi b{margin-right:6px;font-size:16px} .mod .kpi svg{display:none} .mod .goto{display:none}
  .form-grid{grid-template-columns:minmax(0,1fr)}
  .p360 .vis{max-width:200px}
  .pick{grid-template-columns:repeat(2,minmax(0,1fr))}
  .steps .ln{width:14px;margin:0 6px}
  .footer{font-size:12px} .footer .links{margin-left:0}
  .tbl td.lib{min-width:10rem}
  /* onglets et rangées : défilement horizontal avec un fondu à droite */
  .tabs,.rail{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;overscroll-behavior-x:contain;scroll-snap-type:x proximity;padding-inline-end:28px;
    -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 28px),transparent);mask-image:linear-gradient(90deg,#000 calc(100% - 28px),transparent)}
  .tabs::-webkit-scrollbar,.rail::-webkit-scrollbar{display:none}
  .tabs > *,.rail > *{flex:none;scroll-snap-align:start}
  .toolbar > .tabs{flex:1 1 100%;min-width:0}
  /* connexion */
  .auth{max-width:520px;padding:16px 14px;gap:16px}
  .auth-visual h1{font-size:26px} .auth-visual .tagline{font-size:20px}
  .auth-card{padding:22px 18px}
}
@media (max-width:520px){
  .pick{grid-template-columns:repeat(2,minmax(0,1fr))}
  .tabs button,.tabs a{font-size:12px;padding:7px 11px}
  .g3,.g4,.g5{grid-template-columns:minmax(0,1fr)}
  .hide-sm{display:none!important}
  /* barre du haut */
  .logo img{width:32px;height:30px} .logo .l1{font-size:19px}
  .iconbtn{width:36px;height:36px} .me img{width:30px;height:30px}
  .footer{padding:12px var(--pad-page);gap:8px 12px;font-size:11.5px} .footer .slogan{display:none}
  /* bandeau : une ligne de titre */
  .hero .txt{padding:14px 16px}
  .hero .eyebrow{font-size:10.5px;letter-spacing:.06em;gap:8px} .hero .eyebrow::before{width:18px}
  .hero h1{margin-top:4px}
  /* le sous-titre n'est jamais coupé : les vues l'écrivent court (deux lignes à 320 px) */
  .hero .sub{font-size:13px;margin-top:4px}
  .hero .tagline{display:none}
  /* la photo ne passe jamais sous le texte : masquée, sauf sur l'accueil où elle devient une bande au-dessus */
  .hero .photo,.hero::after{display:none}
  .hero .txt{max-width:100%}
  .page-accueil > .hero .photo{display:block;position:relative;inset:auto;height:76px;flex:none}
  .hero{border-color:var(--line)}
  .hero .actions{padding:0 16px 14px}
  .hero.compact .txt{padding:14px 16px}
  /* cartes */
  .card.tight .card-head{padding:12px var(--pad-card)}
  .card .card-head{flex-direction:column;align-items:flex-start;gap:2px}
  /* blocs clé-valeur et tuiles */
  .kv,.kv.k4{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
  .kv.k1{grid-template-columns:minmax(0,1fr)}
  .kv .k{padding:10px 12px;border-radius:10px} .kv .k .l,.kv .k .s{font-size:11.5px}
  .kv.liste .k{padding:9px 0;border-radius:0}
  /* .liste-sm : tuiles sur grand écran, liste de définitions sur téléphone */
  .kv.liste-sm{display:block}
  .kv.liste-sm .k{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:2px 12px;background:none;border:0;border-bottom:1px solid var(--line-2);border-radius:0;padding:9px 0}
  .kv.liste-sm .k:last-child{border-bottom:0}
  .kv.liste-sm .k .l{font-size:var(--fs-sm);font-weight:700;color:var(--ink-2)}
  .kv.liste-sm .k .v{font-size:15px;margin:0 0 0 auto;text-align:right}
  .kv.liste-sm .k .s{flex-basis:100%;font-size:var(--fs-xs)}
  .kv.liste-sm .k.good .v{color:var(--green-dark)} .kv.liste-sm .k.bad{background:none} .kv.liste-sm .k.bad .l{color:var(--ink-2)} .kv.liste-sm .k.bad .v{color:var(--red-dark)}
  .grid.stats,.grid.stats.s3{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
  .grid.stats > :last-child:nth-child(odd){grid-column:1/-1}
  .stat-tile{padding:10px 12px} .stat-tile .l,.stat-tile .d{font-size:11.5px}
  /* libellé, chiffre et note alignés d'une tuile à l'autre par une sous-grille : la rangée prend la
     hauteur du plus long libellé réel, sans ligne vide réservée ; la note n'est jamais coupée */
  .grid.stats{grid-auto-rows:auto}
  .grid.stats > .stat-tile{display:grid;grid-row:span 3;grid-template-rows:subgrid;row-gap:0;align-content:start}
  /* tableaux : lignes-cartes (.tbl.cartes) — le dense redevient une carte lisible */
  .tbl.dense.cartes tbody tr:nth-child(even) td,.tbl.dense.cartes tbody tr:hover td{background:none}
  .tbl.dense.cartes :is(th,td) + :is(th,td){border-left:0}
  .tbl.dense.cartes td .sous,.tbl.dense.cartes td.num .sous,.tbl.dense.cartes td.date .sous{display:block;white-space:normal;margin:2px 0 0}
  .tbl.dense.cartes td,.tbl.dense.cartes td.lib,.tbl.dense.cartes td.lib > :is(a.b,b){white-space:normal;max-width:none;overflow:visible}
  .tbl-wrap.borne{max-height:none}
  .tbl.cartes{font-size:var(--fs-sm)}
  .tbl.cartes thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
  .tbl.cartes,.tbl.cartes tbody{display:block}
  .tbl.cartes tr{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px 12px;padding:12px var(--pad-card);border-bottom:1px solid var(--line-2)}
  .tbl.cartes tr:last-child{border-bottom:0}
  .tbl.cartes td,.tbl.cartes th{display:block;padding:0;border:0;min-width:0;text-align:left}
  .tbl.cartes td.lib{grid-column:1/3;grid-row:1;min-width:0}
  .tbl.cartes tr:not(:has(> td.cle)) > td.lib{grid-column:1/-1}
  .tbl.cartes td.cle{grid-column:3;grid-row:1;justify-self:end;text-align:right}
  .tbl.cartes td.pleine,.tbl.cartes tr.groupe > th{grid-column:1/-1}
  /* .q4 : quatre chiffres courts par ligne au lieu de trois (une rangée de moins) */
  .tbl.cartes.q4 tr{grid-template-columns:repeat(4,minmax(0,1fr))} .tbl.cartes.q4 td.lib{grid-column:1/4} .tbl.cartes.q4 td.cle{grid-column:4}
  .tbl.cartes td[data-label]::before{content:attr(data-label);display:block;font-size:var(--fs-2xs);font-weight:800;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .tbl.cartes td.cle::before{content:none}
  .tbl.cartes td:empty,.tbl.cartes .hide-sm,.tbl.cartes td.vide{display:none}
  /* seule cellule secondaire : libellé en ligne, sur toute la largeur */
  .tbl.cartes td.en-ligne{grid-column:1/-1}
  .tbl.cartes td.en-ligne::before{display:inline;margin-right:6px}
  /* ligne « vous » (fond vert) : libellés et notes en --ink-2 pour rester AA */
  .tbl.cartes tr.moi td[data-label]::before,.tbl.cartes tr.moi .sous{color:var(--ink-2)}
  .tbl.cartes tr.groupe{display:block;padding:8px var(--pad-card);background:var(--bg)}
  .tbl.cartes tr.groupe > th{padding:0}                 /* intertitre aligné sur le contenu des lignes */
  .tbl.cartes tr.row:hover td{background:none}
  /* ligne « vous » : un seul fond pour la ligne-carte, pas un bloc par cellule */
  .tbl.cartes tr.moi{background:var(--green-soft)} .tbl.cartes tr.moi td{background:none}
  /* une note sous un montant ou une date passe à la ligne dans sa colonne (td.num et td.date sont en nowrap) */
  .tbl.cartes .sous{white-space:normal}
  /* pagination : « ‹ 3 / 75 › » */
  .pager{justify-content:center} .pager .compte{flex-basis:100%;text-align:center}
  .pager .num,.pager .gap,.pager .pg.on{display:none} .pager .pos{display:inline-grid;border:0;background:none}
  /* À traiter : toute la ligne est cliquable, le bouton « Ouvrir » devient un chevron */
  ul.todo .t b{font-size:13.5px}
  ul.todo .t span{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:12px}
  ul.todo .todo-l .btn{display:none}
  ul.todo .todo-l::after{content:"";width:8px;height:8px;border-right:2px solid var(--ink-3);border-top:2px solid var(--ink-3);transform:rotate(45deg);flex:none;margin-right:4px}
  /* modules de l'accueil en lignes d'environ 56 px */
  .grid.mods{grid-template-columns:minmax(0,1fr);gap:8px}
  /* icône | titre et phrase du chiffre | chiffre | chevron : chaque ligne se lit comme un lien, le chiffre garde son libellé */
  .grid.mods .mod{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;grid-template-areas:"big h3 num chev" "big l num chev";align-items:center;column-gap:12px;row-gap:1px;padding:10px 12px;min-height:0}
  .grid.mods .mod :is(p,.goto,.kpi svg){display:none}
  .grid.mods .mod .big{grid-area:big;width:36px;height:36px} .grid.mods .mod .big svg{width:18px;height:18px}
  .grid.mods .mod h3{grid-area:h3;margin:0;font-size:14px;min-width:0;align-self:end}
  .grid.mods .mod .kpi{display:contents}
  .grid.mods .mod .kpi b{grid-area:num;font-size:16px;margin:0}
  .grid.mods .mod .kpi-l{grid-area:l;align-self:start;font-size:12px;font-weight:600;color:var(--ink-2);line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  .grid.mods .mod::after{content:"";grid-area:chev;width:8px;height:8px;border-right:2px solid var(--ink-3);border-top:2px solid var(--ink-3);transform:rotate(45deg);margin-right:4px}
  /* cartes d'opération */
  .grid.promos{gap:8px} .card.promo{padding:12px;gap:6px} .promo .vis{display:none}
  /* pages particulières */
  .news{flex-direction:column;gap:2px} .news .d{width:auto;padding:0}
  .crumbs > *{display:none} .crumbs > a:nth-last-of-type(1){display:inline-flex}
  .crumbs > a:nth-last-of-type(1)::before{content:"‹";margin-right:6px}
  .steps{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:4px;align-items:start}
  .steps .ln{display:none} .steps .st{flex-direction:column;gap:4px;text-align:center;font-size:11.5px}
  .titre-fiche{font-size:19px}
  .chart text{font-size:15px}                   /* unités du viewBox : environ 11 px à l'écran */
  .pharm .top{height:96px} .pharm .top img{height:88px}
  .pharm .top::after{background:linear-gradient(180deg,rgba(20,40,70,0) 20%,rgba(20,40,70,.82))}
  .auth-visual .sub,.auth-visual .tagline{display:none} .auth-visual h1{font-size:22px}
  .login .topbar .tiny{display:none}
}
@media (max-width:360px){
  .bottomnav{padding-left:2px;padding-right:2px}
  .bottomnav > a,.bottomnav > button{padding:6px 1px;font-size:10px;letter-spacing:-.01em}
}

/* ---------- administration C2M (/admin) ---------- */
.admin-contenu{margin:0 auto}
.admin-qui{display:flex;flex-direction:column;align-items:flex-end;line-height:1.25;font-size:var(--fs-sm)}
.console{margin:0;padding:12px var(--pad-card);background:var(--surface-2);border-top:1px solid var(--line-2);color:var(--ink);
  font:12.5px/1.45 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre;overflow:auto;max-height:70vh}
@media (max-width:520px){ .admin-qui{display:none} .console{font-size:11.5px} }

/* L'attente d'une page (30/09/2026, portail.js) : une barre en haut après 300 ms, « Chargement… »
   après 1,5 s. Rien ne se voit sur une page rapide ; aucun clic n'est intercepté. */
/* La barre de chargement (30/09/2026). ⚠ Classe propre : « .attente » valait aussi pour la pastille photo
   « à venir » (`tag-photo attente`), que ce `position:fixed` arrachait de sa cellule (03/10/2026). */
.chargement-page{position:fixed;inset:0 0 auto 0;z-index:120;pointer-events:none}
.chargement-page .barre{height:3px;background:linear-gradient(90deg,transparent,var(--green),transparent) no-repeat;background-size:40% 100%;opacity:0;transition:opacity .15s;animation:attente-barre 1.1s ease-in-out infinite}
.chargement-page.on .barre{opacity:1}
.chargement-page .mot{position:fixed;left:50%;top:calc(var(--top) + 12px);transform:translateX(-50%);display:flex;align-items:center;gap:8px;padding:7px 14px;border-radius:999px;background:var(--pop-bg);border:1px solid var(--line);box-shadow:var(--shadow);font-size:13px;font-weight:800;color:var(--ink);opacity:0;transition:opacity .2s}
.chargement-page.long .mot{opacity:1}
.chargement-page .rond{width:14px;height:14px;border:2px solid var(--line);border-top-color:var(--green);border-radius:50%;animation:attente-rond .8s linear infinite}
@keyframes attente-barre{from{background-position:-60% 0}to{background-position:160% 0}}
@keyframes attente-rond{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.chargement-page .barre{animation:none;background:var(--green)}.chargement-page .rond{animation:none}}

/* ---------- promotions au téléphone (02/10/2026, Bruno) ----------
   Les cinq circuits sur une rangée, sans défilement ; ni onglets de statut ni barre des mois (tout est
   dans la gaveta) ; les filtres actifs en une rangée compacte qui glisse.
   ⚠ EN FIN DE FEUILLE : la rangée défilante des circuits (palier 1 180 px) est écrite plus bas que
   le reste et l'emporterait à spécificité égale — vu à la capture, invisible à la lecture. */
@media (max-width:819.98px){
  .grid.circuits{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:6px;overflow:visible;padding:0;
    -webkit-mask-image:none;mask-image:none}
  .grid.circuits .mod{flex-direction:column;justify-content:flex-start;gap:4px;padding:8px 3px;border-radius:12px;text-align:center}
  .grid.circuits .mod .big{width:26px;height:26px} .grid.circuits .mod .big svg{width:14px;height:14px}
  .grid.circuits .mod h3{font-size:10.5px;line-height:1.15;white-space:normal;overflow-wrap:anywhere}
  .mod.circuit h3 .long{display:none}
  .mod.circuit h3 .court{display:inline}
  .promo-onglets,.mois-bar{display:none}
  .sur-telephone{display:block}
  .filtres-barre{gap:8px}
  .filtres-btn{min-height:36px;padding:0 13px;font-size:13px}
  .filtres-barre .chips{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
  .filtres-barre .chips::-webkit-scrollbar{display:none}
  .filtres-barre .chip{padding:3px 9px;gap:4px;font-size:11.5px}
  .filtres-barre .chip svg{width:11px;height:11px}
}

/* ---------- Planogramme des promotions (03/10/2026, Bruno) ----------
   Trois étapes (mois, emplacements, document) puis une page à imprimer. Le document se lit à l'écran
   comme une suite de cartes ; imprimé, il passe en noir sur blanc, une section par page. */
.plano-etape{max-width:760px}
.plano-mois{display:grid;grid-template-columns:repeat(auto-fill,minmax(170px,1fr));gap:8px}
.plano-mois .btn{justify-content:space-between;min-height:44px}
.plano-mois .n,.plano-choix .n,.plano-mep .n{font-weight:900;font-size:var(--fs-xs);opacity:.85;margin-left:auto}
.plano-choix{border:0;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}
.plano-choix label,.plano-mep{display:flex;align-items:center;gap:10px;min-height:44px;padding:6px 12px;border:1px solid var(--line-2);
  border-radius:var(--r-sm);cursor:pointer;font-weight:700;color:var(--ink)}
.plano-choix label:has(input:checked),.plano-mep:has(input:checked){background:var(--green-soft);border-color:transparent}
.plano-choix input,.plano-mep input{width:18px;height:18px;flex:none}
.plano-choix .plano-tous{border-style:dashed}
.plano-barre{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;margin-bottom:12px}
.plano-actions{display:flex;gap:8px;flex-wrap:wrap}
.plano{background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r-md, 12px);padding:20px 22px}
.plano-tete{display:flex;justify-content:space-between;align-items:flex-end;gap:12px;flex-wrap:wrap;
  border-bottom:2px solid var(--navy);padding-bottom:10px;margin-bottom:14px}
.plano-tete h1{font-size:22px;color:var(--navy);margin:0}
.plano-sous{font-weight:800;color:var(--ink-2);margin:2px 0 0}
.plano-meta{font-size:var(--fs-xs);color:var(--ink-3);text-align:right;margin:0}
.plano-section{margin-top:18px}
.plano-section h2{display:flex;align-items:baseline;gap:10px;font-size:18px;color:var(--navy);
  background:var(--surface-2);border-left:5px solid var(--green);padding:8px 12px;margin:0 0 10px}
.plano-section h2 span{font-size:var(--fs-xs);font-weight:700;color:var(--ink-3)}
.plano-op{border:1px solid var(--line-2);border-radius:var(--r-sm);padding:12px 14px;margin-bottom:12px}
.plano-op-tete{display:flex;justify-content:space-between;align-items:baseline;gap:10px;flex-wrap:wrap}
.plano-op-tete h3{font-size:15.5px;color:var(--navy);margin:0}
.plano-labo{font-weight:900;color:var(--green-dark);text-transform:uppercase;font-size:var(--fs-sm)}
.plano-infos{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:4px 16px;margin:8px 0}
.plano-infos div{min-width:0}
.plano-infos dt{font-size:var(--fs-2xs);font-weight:800;color:var(--ink-3);text-transform:uppercase;letter-spacing:.03em}
.plano-infos dd{margin:0;font-weight:700;color:var(--ink);overflow-wrap:anywhere}
.plano-desc{font-size:var(--fs-sm);color:var(--ink-2);margin:6px 0 8px;white-space:normal}
.plano-vide{color:var(--ink-3);font-style:italic;font-size:var(--fs-sm)}
.plano-art{width:100%;border-collapse:collapse;font-size:var(--fs-sm)}
.plano-art th{text-align:left;font-size:var(--fs-2xs);text-transform:uppercase;color:var(--ink-3);border-bottom:1px solid var(--line);padding:4px 6px}
.plano-art td{border-bottom:1px solid var(--line-2);padding:4px 6px;vertical-align:top}
.plano-art .ean{width:9.5em;font-variant-numeric:tabular-nums;white-space:nowrap}
@media (max-width:520px){
  .plano{padding:14px 12px}
  .plano-meta{text-align:left}
  .plano-art .ean{width:auto}
}
/* ⚠ À L'IMPRESSION : la navigation disparaît, chaque emplacement commence une page, une ligne d'article
   ne se coupe pas en deux, l'en-tête du tableau se répète, et TOUT passe en noir sur blanc — un poste en
   mode sombre imprimerait sinon du texte clair, et l'impression ne garde pas les fonds par défaut. */
@media print{
  @page{size:A4;margin:12mm}
  .topbar,.sidebar,.bottomnav,.footer,.no-print,.chargement-page,.toast,#menu-plus{display:none !important}
  html,body,.main,.content{background:#fff !important;margin:0 !important;padding:0 !important}
  .plano{border:0;padding:0;border-radius:0}
  .plano,.plano *{color:#000 !important;background:transparent !important;box-shadow:none !important}
  .plano-tete{border-bottom-color:#000}
  .plano-meta{text-align:left}
  .plano-section{break-before:page;margin-top:0}
  .plano-section:first-of-type{break-before:auto}
  .plano-section h2{border-left-color:#000;padding-left:8px;break-after:avoid}
  .plano-op{border-color:#999;break-inside:auto}
  .plano-op-tete,.plano-infos,.plano-desc{break-inside:avoid;break-after:avoid}
  .plano-art thead{display:table-header-group}
  .plano-art tr{break-inside:avoid}
  .plano-art th,.plano-art td{border-color:#bbb}
}
