:root{
  --bg:#09090b; --card:#18181b; --card2:#1f1f23; --line:#27272a; --line2:#3f3f46;
  --tx:#f4f4f5; --mut:#a1a1aa; --mut2:#71717a;
  --blue:#3b82f6; --blue2:#60a5fa; --em:#34d399; --am:#fbbf24; --rd:#f87171;
  --vi:#a78bfa; --r:14px; --r2:10px;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--bg);color:var(--tx);padding:0 0 72px;
  font:15px/1.55 Inter,system-ui,-apple-system,"Segoe UI",Roboto,Arial,sans-serif;
  -webkit-font-smoothing:antialiased}
a{color:var(--blue2);text-decoration:none}
a:hover{text-decoration:underline}
h1,h2,h3{margin:0;font-weight:650;letter-spacing:-.01em}
h1{font-size:1.05rem}
h2{font-size:.95rem}
h3{font-size:.9rem}
.wrap{max-width:1180px;margin:0 auto;padding:0 16px}

/* ---------- entête ---------- */
header.top{position:sticky;top:0;z-index:30;background:rgba(9,9,11,.92);
  border-bottom:1px solid var(--line);backdrop-filter:blur(8px)}
/* padding-top/bottom et non « padding:11px 0 » : l'élément porte AUSSI la
   classe .wrap, dont la marge latérale (et l'encoche iOS sur téléphone)
   serait effacée par la forme courte. L'entête collait sinon au bord de
   l'écran alors que tout le reste de la page respire. */
.topin{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  padding-top:11px;padding-bottom:11px}
.brand{display:flex;align-items:center;gap:9px;min-width:0}
.mark{width:30px;height:30px;border-radius:9px;flex:0 0 auto;display:grid;
  place-items:center;font-size:.66rem;font-weight:800;letter-spacing:.02em;
  color:#fff;background:linear-gradient(135deg,#3b82f6,#8b5cf6)}
.brand small{display:block;color:var(--mut2);font-size:.72rem;line-height:1.2}
nav.main{display:flex;gap:4px;flex-wrap:wrap;margin-left:auto}
/* 44 px de haut sur TOUS les écrans : la barre de navigation est le seul
   chemin entre les pages, et l'exploitant la vise aussi bien à la souris
   depuis le magasin qu'au doigt sur une tablette posée au comptoir. */
nav.main a,nav.main button{display:inline-flex;align-items:center;
  min-height:44px;padding:6px 11px;border-radius:9px;
  font-size:.83rem;color:var(--mut);border:1px solid transparent;background:none;
  cursor:pointer;font-family:inherit}
nav.main a:hover,nav.main button:hover{background:var(--card);color:var(--tx);
  text-decoration:none;border-color:var(--line)}
nav.main a[aria-current="page"]{background:var(--card);color:var(--tx);
  border-color:var(--line2)}
nav.main form{display:inline}
/* Bouton d'ouverture du menu, entête du volet et voile de fond : ils
   n'existent que sur téléphone (voir la requête média plus bas), où la
   barre de navigation ne tient pas sur une ligne. */
a.burger,nav.main .navhd,a.navshade{display:none}
/* titre court réservé au téléphone (voir la requête média) : sur 390 px il
   reste 139 px entre le logo, la pastille de verdict et le bouton du menu
   — le titre long s'y coupait au milieu d'un mot. */
.brand h1 .hm{display:none}

/* ---------- cartes ---------- */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);
  margin:16px 0;overflow:hidden}
.card>.hd{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:13px 16px;border-bottom:1px solid var(--line)}
.card>.bd{padding:14px 16px}
.card>.bd.flush{padding:0}
/* Bandeau « vente à perte » : la seule carte qui annonce une somme qui
   part à chaque commande. Elle porte 1rem — 16 px, la taille de référence
   du navigateur — au lieu des 15 px du reste : c'est la phrase qu'on doit
   lire au comptoir sans rapprocher l'écran. Le liseré rouge la distingue
   de la pause et des alertes, qui n'appellent pas le même geste.
   overflow-wrap:anywhere : le détail cite des noms d'articles et des
   numéros de fiche venus du site, donc des suites de caractères qu'on ne
   choisit pas — aucune ne doit pousser la carte hors d'un écran de
   360 px. */
.card.perte{border-color:rgba(248,113,113,.55)}
.card.perte>.bd{font-size:1rem;overflow-wrap:anywhere}
.hint{color:var(--mut2);font-size:.8rem;margin:0}
.hd .hint{margin-left:auto;text-align:right}

/* ---------- badges ---------- */
.b{display:inline-flex;align-items:center;gap:5px;padding:3px 9px;border-radius:999px;
  font-size:.74rem;font-weight:600;white-space:nowrap;border:1px solid transparent}
.b-em{background:rgba(52,211,153,.10);border-color:rgba(52,211,153,.30);color:var(--em)}
.b-am{background:rgba(251,191,36,.10);border-color:rgba(251,191,36,.30);color:var(--am)}
.b-rd{background:rgba(248,113,113,.10);border-color:rgba(248,113,113,.30);color:var(--rd)}
.b-bl{background:rgba(59,130,246,.10);border-color:rgba(59,130,246,.30);color:var(--blue2)}
.b-vi{background:rgba(167,139,250,.10);border-color:rgba(167,139,250,.30);color:var(--vi)}
.b-gy{background:rgba(161,161,170,.08);border-color:rgba(161,161,170,.24);color:var(--mut)}
.b-lg{font-size:.82rem;padding:5px 13px}
.dot{width:7px;height:7px;border-radius:99px;background:currentColor;flex:0 0 auto}
code.tech{font:600 .7rem/1.4 ui-monospace,SFMono-Regular,Consolas,monospace;
  color:var(--mut2);background:rgba(161,161,170,.08);border:1px solid var(--line);
  border-radius:6px;padding:1px 5px;white-space:nowrap}

/* ---------- grille de compteurs ---------- */
.kpis{display:grid;gap:10px;grid-template-columns:repeat(auto-fill,minmax(158px,1fr))}
.kpi{background:var(--card2);border:1px solid var(--line);border-radius:var(--r2);
  padding:11px 13px}
.kpi .lb{display:flex;align-items:center;gap:5px;color:var(--mut);font-size:.76rem;
  margin-bottom:3px}
.kpi .vl{font-size:1.5rem;font-weight:700;letter-spacing:-.02em;line-height:1.15}
.kpi.em .vl{color:var(--em)} .kpi.am .vl{color:var(--am)}
.kpi.rd .vl{color:var(--rd)} .kpi.bl .vl{color:var(--blue2)}
.kpi.mut .vl{color:var(--mut)}

/* ---------- tableaux ---------- */
.scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
/* .875rem = 14px : plancher de lisibilité du texte courant sur téléphone */
table{border-collapse:collapse;width:100%;font-size:.875rem}
th,td{text-align:left;padding:9px 12px;border-bottom:1px solid var(--line);
  vertical-align:top}
th{color:var(--mut);font-weight:600;font-size:.76rem;white-space:nowrap;
  background:var(--card2);position:relative}
tbody tr:last-child td{border-bottom:0}
tbody tr:hover td{background:rgba(255,255,255,.018)}
td.n,th.n{text-align:right;font-variant-numeric:tabular-nums}
/* les colonnes de nombres se réduisent à leur contenu : la place va au texte */
th.n{width:1%}
td.mono{font:.8rem/1.5 ui-monospace,SFMono-Regular,Consolas,monospace;
  color:var(--mut)}
td.nom{min-width:180px}
.empty{padding:22px 16px;text-align:center;color:var(--mut2);font-size:.875rem}
/* chapeau d'une section « flush » (le corps de carte n'a pas de marge) */
p.lede{padding:12px 16px 2px;max-width:82ch;line-height:1.55}
/* explication d'un écart, dans la cellule du libellé */
td .expl{margin:5px 0 0;max-width:74ch;line-height:1.5}

/* ---------- passes ---------- */
.run{border-bottom:1px solid var(--line);padding:13px 16px}
.run:last-child{border-bottom:0}
.run .rh{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.run .rt{font-weight:650;font-size:.9rem}
.run .when{color:var(--mut2);font-size:.78rem}
.chips{display:flex;gap:6px;flex-wrap:wrap;margin:9px 0 0}
.chip{display:inline-flex;align-items:baseline;gap:5px;background:var(--card2);
  border:1px solid var(--line);border-radius:8px;padding:4px 9px;font-size:.76rem;
  color:var(--mut)}
.chip b{color:var(--tx);font-variant-numeric:tabular-nums;font-size:.86rem}
.chip.em b{color:var(--em)} .chip.am b{color:var(--am)} .chip.rd b{color:var(--rd)}
.chip.bl b{color:var(--blue2)}
.gap{margin:10px 0 0;padding:9px 11px;border-radius:var(--r2);font-size:.82rem;
  background:rgba(59,130,246,.06);border:1px solid rgba(59,130,246,.20);
  color:#c7d2fe}
.gap.ok{background:rgba(52,211,153,.06);border-color:rgba(52,211,153,.20);
  color:#a7f3d0}
.gap b{color:#fff}
.gap ul{margin:6px 0 0;padding-left:18px}
.gap li{margin:2px 0}
/* remarque laissée par le moteur sur une passe */
p.rnote{margin:9px 0 0;padding:8px 11px;border-radius:var(--r2);font-size:.8rem;
  background:rgba(161,161,170,.06);border:1px solid var(--line2);color:var(--mut)}

/* ---------- écarts ---------- */
.ec{border-bottom:1px solid var(--line);padding:14px 16px}
.ec:last-child{border-bottom:0}
.ec .eh{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
/* le nom du type mène à ses articles, comme sur le tableau de bord :
   c'est le titre qu'on vise quand on veut voir « lesquels ». */
.ec .et{font-weight:650;font-size:.92rem}
.ec .et a{color:var(--tx);text-decoration:none}
.ec .et a:hover{color:var(--blue2);text-decoration:underline}
.ec p{margin:7px 0 0;color:var(--mut);font-size:.875rem;max-width:76ch}
.ec .who{color:var(--mut2);font-size:.78rem;margin-top:6px}
/* Les deux blocs d'écarts (cf. db.py) : l'inventaire complet de la nuit,
   et ce qui a été trouvé depuis. Le second est ce que l'exploitant n'a
   pas encore vu — il porte donc un liseré et un fond propres, pour qu'on
   ne le confonde pas au premier coup d'œil avec la liste de la nuit. Sans
   cette séparation, il faudrait comparer les dates ligne à ligne. */
h3.sec{margin:0;padding:14px 16px 0;font-size:.82rem;font-weight:650;
  letter-spacing:.04em;text-transform:uppercase;color:var(--mut)}
.neuf{border-left:3px solid var(--amber,#d99a2b);background:var(--card2)}
.neuf>p.hint{margin:0;padding:4px 16px 10px;max-width:82ch;line-height:1.55}
.ec.neuf{border-left:3px solid var(--amber,#d99a2b)}
/* La colonne « Depuis » du tableau de bord : un « +12 » se lit comme un
   mouvement, pas comme un total. */
td b.neuf{color:var(--amber,#d99a2b)}
p.bloc2{padding:2px 16px 10px;max-width:82ch;line-height:1.55}
/* Liens de la liste d'écarts : ce sont les gestes du quotidien (ouvrir la
   fiche à corriger, télécharger sa liste), donc de vraies cibles au doigt
   et non des mots soulignés de 20 px de haut. */
td a.fiche{display:inline-flex;align-items:center;justify-content:center;
  min-width:44px;min-height:44px}
.hd p.hint a{display:inline-flex;align-items:center;justify-content:center;
  min-width:44px;min-height:44px}
/* « CSV », « détail → », le nom d'un type d'écart : quelques mots soulignés
   hauts de 16 px, alors que ce sont les sauts d'un écran à l'autre. */
a.jump{display:inline-flex;align-items:center;min-height:44px}
/* les deux gestes d'un type d'écart : voir la liste entière, l'emporter en
   CSV. Atteignables au doigt sans avoir à déplier l'aperçu. */
.ec .dl{margin-top:9px;display:flex;gap:8px;flex-wrap:wrap}
.ec .dl a,.pg a{display:inline-flex;align-items:center;min-height:44px;
  padding:0 13px;border:1px solid var(--line);border-radius:8px;
  background:var(--card2);color:var(--blue2);font-size:.82rem;
  text-decoration:none}
.ec .dl a:hover,.pg a:hover{border-color:var(--line2)}
/* feuilletage d'une liste : la page d'avant, la page d'après, et où l'on
   en est. Répété au-dessus et au-dessous du tableau pour qu'on n'ait pas
   à remonter 200 lignes pour tourner la page. */
.pg{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin:0;padding:9px 16px}
.pg span.hint{margin-left:auto}
.pg a+span.hint{margin-left:0;margin-right:auto}
/* « Articles 1 à 200 sur 3388 » : le repère de lecture, séparé de
   l'explication qui le précède pour ne pas s'y confondre. */
p.cadre{margin:0;padding:9px 16px 0;font-size:.82rem;color:var(--mut)}
details{margin-top:9px}
details>summary{cursor:pointer;color:var(--blue2);font-size:.82rem;
  list-style:none;display:inline-flex;align-items:center;gap:6px;
  min-height:44px;padding:0 13px;border:1px solid var(--line);
  border-radius:8px;background:var(--card2)}
details>summary::-webkit-details-marker{display:none}
details>summary:hover{border-color:var(--line2)}
details[open]>summary{margin-bottom:8px}
/* légende des colonnes : repli réservé au téléphone (entête masqué) */
details.legend{display:none}
details.legend ul{margin:2px 0 10px;padding-left:17px;color:var(--mut);
  font-size:.8rem}
details.legend li{margin:5px 0}
details.legend b{color:var(--tx);font-weight:600}

/* ---------- rapport ---------- */
pre.rap{margin:0;padding:14px 16px;background:#101013;color:#d4d4d8;
  border:1px solid var(--line);border-radius:var(--r2);overflow-x:auto;
  white-space:pre-wrap;word-break:break-word;
  font:.8rem/1.6 ui-monospace,SFMono-Regular,Consolas,monospace}

/* ---------- info-bulles ---------- */
button.tip{appearance:none;-webkit-appearance:none;width:16px;height:16px;
  flex:0 0 auto;padding:0;border-radius:99px;border:1px solid var(--line2);
  background:var(--card2);color:var(--mut);cursor:help;font:700 10px/1 inherit;
  vertical-align:middle;display:inline-grid;place-items:center}
button.tip:hover{color:var(--tx);border-color:var(--blue);background:rgba(59,130,246,.12)}
button.tip:focus-visible,button.tip.tip-on{outline:2px solid var(--blue);
  outline-offset:1px;color:var(--tx)}
th button.tip{margin-left:4px}
/* la zone sensible de la pastille « ? » est definie tout en bas, apres la
   requete media du telephone : elle depend aussi de la largeur d'ecran. */
#tipbox{position:fixed;z-index:200;display:none;max-width:min(330px,86vw);
  background:#101013;color:#e4e4e7;border:1px solid var(--line2);
  border-radius:var(--r2);padding:10px 12px;font-size:.8rem;line-height:1.5;
  box-shadow:0 12px 34px rgba(0,0,0,.62)}
#tipbox.on{display:block}
#tipbox.sheet{left:10px!important;right:10px;top:auto!important;bottom:10px;
  max-width:none;font-size:.875rem;padding:13px 15px}

/* ---------- connexion et formulaires ---------- */
.login{min-height:100vh;display:grid;place-items:center;padding:22px 16px}
.login .box{width:100%;max-width:392px}
.login .mark{width:42px;height:42px;border-radius:12px;font-size:.8rem;margin:0 auto}
.login h1{text-align:center;margin:13px 0 4px;font-size:1.12rem}
.login .sub{text-align:center;color:var(--mut2);font-size:.82rem;margin:0 0 18px}
.login .card{margin:0}
form.form{max-width:520px}
label.f{display:block;margin-bottom:13px}
label.f span{display:block;color:var(--mut);font-size:.8rem;margin-bottom:5px}
/* 1rem = 16 px : en dessous, iOS zoome tout seul à la prise de focus et
   l'exploitant perd la page des yeux, clavier ouvert. */
input[type=text],input[type=password],select{width:100%;padding:10px 12px;
  font-size:1rem;min-height:44px;color:var(--tx);background:#101013;
  border:1px solid var(--line2);border-radius:var(--r2);font-family:inherit}
input:focus,select:focus{outline:2px solid var(--blue);outline-offset:0;
  border-color:var(--blue)}
button.go{width:100%;padding:11px 14px;min-height:44px;font:650 .95rem inherit;
  font-family:inherit;color:#fff;background:var(--blue);border:0;
  border-radius:var(--r2);cursor:pointer}
button.go:hover{background:#2563eb}
button.go:focus-visible,button.act:focus-visible,nav.main a:focus-visible,
nav.main button:focus-visible,summary:focus-visible{outline:2px solid var(--blue);
  outline-offset:2px}
button.go.auto{width:auto;padding:11px 18px}
/* boutons d'action d'une ligne de tableau (rôle, activation) */
.rowact{display:flex;gap:6px;flex-wrap:wrap}
.rowact form{display:inline}
button.act{min-height:44px;padding:7px 11px;border-radius:8px;cursor:pointer;
  border:1px solid var(--line2);background:var(--card2);color:var(--tx);
  font:600 .8rem inherit;font-family:inherit}
button.act:hover{border-color:var(--blue);background:rgba(59,130,246,.12)}
button.act.danger:hover{border-color:var(--rd);color:#fecaca;
  background:rgba(248,113,113,.12)}
.err{margin:0 0 14px;padding:10px 12px;border-radius:var(--r2);font-size:.875rem;
  background:rgba(248,113,113,.10);border:1px solid rgba(248,113,113,.32);
  color:#fecaca}
.ok{margin:0 0 14px;padding:10px 12px;border-radius:var(--r2);font-size:.875rem;
  background:rgba(52,211,153,.10);border:1px solid rgba(52,211,153,.32);
  color:#a7f3d0}
.warn{margin:0 0 14px;padding:10px 12px;border-radius:var(--r2);font-size:.875rem;
  background:rgba(251,191,36,.10);border:1px solid rgba(251,191,36,.32);
  color:#fde68a}
p.help{margin:0 0 14px;color:var(--mut);font-size:.82rem;max-width:76ch}
.note{margin:14px 0 0;color:var(--mut2);font-size:.76rem;text-align:center;
  line-height:1.5}
/* Liaison interrompue. Volontairement DISCRET et volontairement NON MODAL :
   la page reste lisible dessous, l'exploitant continue de consulter ce qu'il
   avait à l'écran. Il ne masque rien d'utile — posé en bas, au-dessus du
   pied de page, il laisse le contenu intact. `pointer-events:none` pour ne
   jamais intercepter un clic destiné à ce qui est derrière. */
.offline{position:fixed;left:50%;transform:translateX(-50%);
  bottom:max(12px,env(safe-area-inset-bottom));z-index:60;margin:0;
  max-width:min(92vw,52ch);padding:9px 14px;border-radius:999px;
  font-size:.8rem;line-height:1.4;text-align:center;pointer-events:none;
  background:rgba(251,191,36,.14);border:1px solid rgba(251,191,36,.38);
  color:#fde68a;backdrop-filter:blur(6px)}
footer.ft{color:var(--mut2);font-size:.78rem;padding:6px 0 0}
/* le lien du pied de page est un vrai geste (aller lire le JSON brut) :
   il se vise au doigt comme le reste, sans grossir le texte. */
footer.ft a{color:var(--mut);display:inline-flex;align-items:center;
  min-height:44px}

/* ---------- téléphone : tableaux empilés ---------- */
@media(max-width:760px){
  /* max(...) : marge normale, élargie s'il y a une encoche ou un bord
     arrondi (téléphone récent tenu en paysage). */
  .wrap{padding:0 max(11px,env(safe-area-inset-right)) 0
    max(11px,env(safe-area-inset-left))}
  /* L'entête tenait sur 257 px de haut (30 % d'un écran de 844 px) : les
     huit entrées de navigation s'y empilaient sur trois lignes, et comme
     l'entête est collant, chaque page perdait ce tiers d'écran en
     permanence. Le menu passe donc dans un volet qui s'ouvre au doigt —
     en CSS pur (:target), pour qu'il reste utilisable sans JavaScript. */
  .topin{padding-top:8px;padding-bottom:8px;flex-wrap:nowrap;gap:9px}
  /* le titre se raccourcit d'abord : sans min-width:0 sur le bloc de
     texte (un élément de flex refuse par défaut de descendre sous la
     largeur de son contenu), la ligne débordait et le titre passait
     SOUS la pastille de verdict. */
  .brand{flex:1 1 auto}
  .brand>span{min-width:0}
  .brand h1{font-size:.92rem;white-space:nowrap;overflow:hidden;
    text-overflow:ellipsis}
  .brand h1 .hs{display:none}
  .brand h1 .hm{display:inline}
  .brand small{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .b-lg{font-size:.74rem;padding:4px 9px}
  a.burger{display:inline-flex;align-items:center;justify-content:center;
    gap:7px;flex:0 0 auto;min-width:44px;min-height:44px;padding:0 11px;
    font-size:1.05rem;line-height:1;color:var(--tx);background:var(--card);
    border:1px solid var(--line2);border-radius:11px}
  a.burger:hover{text-decoration:none;border-color:var(--blue)}
  a.burger .lbl{font-size:.83rem;font-weight:600}
  /* volet posé sous l'entête collant (position:absolute dans header.top,
     jamais fixed : le backdrop-filter de l'entête ferait du fixed un
     positionnement relatif à l'entête, donc un volet de 60 px de haut) */
  nav.main{display:none;position:absolute;top:100%;left:0;right:0;z-index:2;
    margin-left:0;width:auto;flex-direction:column;gap:6px;
    max-height:calc(100vh - 100%);overflow-y:auto;overflow-x:hidden;
    background:var(--bg);border-bottom:1px solid var(--line);
    box-shadow:0 18px 40px rgba(0,0,0,.55);
    padding:10px max(11px,env(safe-area-inset-right))
      max(14px,env(safe-area-inset-bottom)) max(11px,env(safe-area-inset-left))}
  nav.main:target{display:flex}
  nav.main .navhd{display:flex;align-items:center;justify-content:space-between;
    margin:0;color:var(--mut2);font-size:.78rem}
  nav.main a.navclose{display:inline-flex;align-items:center;
    justify-content:center;width:auto;min-width:44px;min-height:44px;
    padding:0;font-size:1.4rem;line-height:1;color:var(--mut);
    background:none;border:0}
  nav.main a,nav.main button{width:100%;min-height:50px;padding:0 13px;
    font-size:.95rem;justify-content:flex-start;color:var(--tx);
    background:var(--card);border:1px solid var(--line);border-radius:11px}
  nav.main a[aria-current="page"]{border-color:var(--blue);
    background:rgba(59,130,246,.14);color:var(--blue2)}
  nav.main form{display:block;width:100%}
  /* refermer en touchant à côté du volet, comme dans une application */
  nav.main:target~a.navshade{display:block;position:absolute;top:100%;
    left:0;right:0;height:100vh;z-index:1;background:rgba(0,0,0,.55)}
  /* « margin-left:auto ; text-align:right » range la mention de l'entête à
     droite du titre, sur la même ligne. Sur téléphone le titre prend déjà
     toute la largeur : la mention passe TOUJOURS à la ligne, et alignée à
     droite elle revenait en escalier, un séparateur « · » orphelin en bout
     de ligne. Sous le titre, elle se lit comme le reste de la carte. */
  .card>.hd{align-items:flex-start}
  .hd .hint{margin-left:0;width:100%;text-align:left}
  button.act{flex:1 1 auto}
  /* « auto » existe pour qu'un bouton ne s'étire pas sur toute la largeur
     d'une carte de 1200 px. Sur téléphone la carte fait 340 px : la
     largeur libre redevient la bonne largeur, sous des champs qui, eux,
     sont déjà pleine largeur. Un bouton de 143 px sous un champ de 340 px
     se rate au doigt et casse la colonne du formulaire. */
  button.go.auto{width:100%}
  .rowact{width:100%}
  table.stack td.act::before{display:none}
  table.stack td.act{display:block;text-align:left;padding-top:8px}
  .kpis{grid-template-columns:repeat(auto-fill,minmax(136px,1fr))}
  .kpi .vl{font-size:1.3rem}
  table.stack thead{display:none}
  details.legend{display:block;margin:11px 13px 0}
  table.stack,table.stack tbody,table.stack tr,table.stack td{display:block;
    width:100%}
  table.stack tr{border-bottom:1px solid var(--line);padding:9px 13px}
  table.stack tr:last-child{border-bottom:0}
  table.stack td{border:0;padding:2px 0;display:flex;gap:12px;
    align-items:baseline}
  table.stack td::before{content:attr(data-label);color:var(--mut2);
    font-size:.74rem;text-align:left;flex:0 0 40%}
  /* La valeur forme UN seul élément de flex (voir l'emballage .v posé par
     table()). Elle s'aligne à gauche : un libellé de 40 % laisse 60 % à la
     valeur, et une désignation d'article y tient rarement sur une ligne —
     alignée à droite elle revenait en escalier, illisible. Les colonnes de
     chiffres gardent l'alignement à droite, qui les rend comparables. */
  table.stack td>.v{flex:1 1 auto;min-width:0;text-align:left}
  table.stack td.n>.v{text-align:right}
  table.stack td:empty{display:none}
  /* première cellule = titre du bloc : pleine largeur, aligné à gauche */
  table.stack td.first{display:block;padding:0 0 5px}
  table.stack td.first>.v{font-weight:650;font-size:.92rem;text-align:left}
  table.stack td.first::before{display:block;flex:none;margin-bottom:2px;
    font-weight:400}
  .scroll{overflow-x:visible}
}
/* Écran tactile plus large que 760 px (tablette, portable à écran tactile) :
   la mise en page reste celle du bureau, mais on vise avec un doigt et non
   avec un pointeur au pixel — les boutons d'action gardent leurs 44 px.
   « any-pointer » en plus de « pointer » : un portable à écran tactile
   annonce son pavé tactile comme pointeur principal (pointer:fine) et ne
   signale sa dalle que par « any-pointer:coarse ». Sans lui, l'exploitant
   qui pose le doigt sur un tel écran vise des cibles de 16 px. */
@media(pointer:coarse),(any-pointer:coarse){
  button.act{min-height:44px;padding:9px 13px}
}
/* La pastille « ? » ne fait que 16 px de côté : on l'entoure d'une zone
   sensible de 44 px, sans la grossir ni bouger la mise en page. Le
   pseudo-élément se superpose au texte voisin mais ne le capte pas :
   pointer-events reste sur le bouton lui-même, déjà au-dessus.
   Trois conditions, pas une : « pointer:coarse » n'est pas toujours annoncé
   (iPhone en mode « site pour ordinateur », navigateur émulé) et laissait
   alors une cible de 16 px sur un écran de 390 px ; un portable à écran
   tactile ne se signale que par « any-pointer:coarse », son pointeur
   principal restant le pavé tactile. Sous 760 px on est au doigt de toute
   façon. */
@media(pointer:coarse),(any-pointer:coarse),(max-width:760px){
  button.tip{position:relative}
  button.tip::after{content:"";position:absolute;top:50%;left:50%;
    width:44px;height:44px;transform:translate(-50%,-50%)}
}
@media(prefers-reduced-motion:reduce){*{transition:none!important}}
