/* Lua d'Enigmas — Gestion
   Habillage (18.6) : celui du site luadenigmas.com — noir, blanc, gris, filets
   fins, aucun arrondi ; EB Garamond pour les titres, Raleway pour le texte.
   Lisibilité (18.8) : sept familles d'état, chacune une couleur pleine et un
   signe — rouge ▲ le retard, ambre ● ce qui presse, bleu ◆ le rendez-vous, bleu
   pâle ○ le prévu, prune ✚ ce qui arrive, vert ✓ le fait, gris le reste. Les
   noms des variables datent de l'ancienne palette prune (`--plum`…) : ils ne
   changent pas, seules leurs valeurs. */

:root {
  color-scheme: light;
  --bg: #FAF9F7;
  --surface: #FFFFFF;
  --ink: #111111;
  --muted: #555555;
  /* Les étiquettes (en-têtes de colonnes, petits titres), en minuscules grasses. */
  --etiquette: #444444;
  --line: #E0E0E0;
  --line-strong: #D0D0D0;
  --plum: #000000;
  --plum-ink: #000000;
  --plum-soft: #F2F2F2;
  /* Les fonds des badges (pleins ou pâles) et leur texte (18.8). */
  --badge-rouge: #D63B2F; --sur-rouge: #FFFFFF;
  --badge-ambre: #F2B722; --sur-ambre: #111111;
  --badge-bleu: #2B6CB0;  --sur-bleu: #FFFFFF;
  --badge-plan: #DCE8F7;  --sur-plan: #1E4E8C;
  --badge-prune: #EADFF7; --sur-prune: #5B2D8A;
  --badge-vert: #2E8B57;  --sur-vert: #FFFFFF;
  --badge-gris: #E6E6E6;  --sur-gris: #444444;
  /* Les couleurs d'état en texte et en fond pâle, alignées sur les badges. */
  --vert: #2E8B57;      --vert-soft: #E6F3EC;      --vert-bord: #A9D8BC;
  --ambre: #B7791F;     --ambre-soft: #FFF6DD;     --ambre-bord: #F2D27A;
  --ambre-fort: #B7791F; --ambre-fort-soft: #FFF6DD; --ambre-fort-bord: #F2D27A;
  --rouge: #D63B2F;     --rouge-soft: #FDECEA;     --rouge-bord: #F3B8AF;
  --bleu: #2B6CB0;      --bleu-soft: #E6EEF8;      --bleu-bord: rgba(43, 108, 176, .45);
  /* Le prévu, en bleu pâle : à envoyer, à organiser, à conclure, devis… */
  --bleu-clair: #1E4E8C; --bleu-clair-soft: #DCE8F7; --bleu-clair-bord: #8FB3DF;
  --bleu-fonce: #1E4E8C; --bleu-fonce-soft: #DCE8F7; --bleu-fonce-bord: #8FB3DF;
  /* Ce qui arrive : reçu, nouveau, premier contact, à vérifier. */
  --prune-etat: #5B2D8A; --prune-etat-bord: #B08AD6;
  --gris-soft: #F2F2F2;
  /* Le fond des boutons principaux et des pastilles actives : noir en clair,
     blanc en sombre, le texte de l'autre couleur par-dessus. */
  --plum-bg: #000000;   --plum-bg-hover: #333333;  --on-plum: #FFFFFF;
  --rouge-fort: #D63B2F; --on-rouge: #FFFFFF;
  --zebra: #FFFFFF;     --zebra-doux: #FAF9F7;
  /* Le voile sous une feuille du téléphone, et l'ombre du bouton Saisir (15.6). */
  --voile: rgba(0, 0, 0, .45);
  --ombre-saisir: rgba(0, 0, 0, .35);
  --ombre-menu: 0 8px 24px rgba(0, 0, 0, .12);
  --radius: 0;
  --font-display: "EB Garamond", Georgia, "Times New Roman", serif;
  --font-body: "Raleway", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* Mode sombre : le noir du site. Seules les couleurs changent, la mise en page
   est identique ; les badges gardent leurs fonds pleins. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0D0D0D;
  --surface: #161616;
  --ink: #E6E6E6;
  --muted: #B5B5B5;
  --etiquette: #CCCCCC;
  --line: #2A2A2A;
  --line-strong: #444444;
  --plum: #FFFFFF;
  --plum-ink: #FFFFFF;
  --plum-soft: #262626;
  --badge-rouge: #C0392B; --sur-rouge: #FFFFFF;
  --badge-ambre: #D9A520; --sur-ambre: #111111;
  --badge-bleu: #3B7DD8;  --sur-bleu: #FFFFFF;
  --badge-plan: #1E2E44;  --sur-plan: #BBD3F2;
  --badge-prune: #2E2140; --sur-prune: #D6BFF0;
  --badge-vert: #2E8B57;  --sur-vert: #FFFFFF;
  --badge-gris: #333333;  --sur-gris: #DDDDDD;
  --vert: #7CC79B;      --vert-soft: #15281D;      --vert-bord: rgba(124, 199, 155, .5);
  --ambre: #E6B84A;     --ambre-soft: #332A10;     --ambre-bord: rgba(230, 184, 74, .5);
  --ambre-fort: #E6B84A; --ambre-fort-soft: #332A10; --ambre-fort-bord: rgba(230, 184, 74, .5);
  --rouge: #F08A7A;     --rouge-soft: #3A1F1C;     --rouge-bord: rgba(240, 138, 122, .55);
  --bleu: #8FB6E8;      --bleu-soft: #182532;      --bleu-bord: rgba(143, 182, 232, .55);
  --bleu-clair: #BBD3F2; --bleu-clair-soft: #1E2E44; --bleu-clair-bord: rgba(187, 211, 242, .45);
  --bleu-fonce: #BBD3F2; --bleu-fonce-soft: #1E2E44; --bleu-fonce-bord: rgba(187, 211, 242, .45);
  --prune-etat: #D6BFF0; --prune-etat-bord: rgba(214, 191, 240, .5);
  --gris-soft: #222222;
  --plum-bg: #FFFFFF;   --plum-bg-hover: #DDDDDD;  --on-plum: #000000;
  --rouge-fort: #C0392B; --on-rouge: #FFFFFF;
  --zebra: #161616;     --zebra-doux: #171717;
  --voile: rgba(0, 0, 0, .6);
  --ombre-saisir: rgba(0, 0, 0, .6);
}
:root[data-theme="dark"] .tile-on { box-shadow: none; }

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  /* 18.8 : 15 px, interligne 1,6 — sur téléphone aussi. */
  font-size: 15px;
  line-height: 1.6;
}
a { color: var(--plum); text-decoration: none; }
a:hover { text-decoration: underline; }
code { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: 0.92em; background: var(--gris-soft); padding: 1px 5px; border-radius: 0; }
pre.code { background: #111111; color: #F2F2F2; padding: 14px 16px; border-radius: 0; overflow: auto; font-size: 13px; }

.wrap { max-width: 1240px; margin: 0 auto; padding: 0 20px; }
/* De l'air entre la barre noire et ce qui la suit, sur toutes les pages (18.9). */
.topbar + main.wrap { padding-top: 26px; }
@media (max-width: 640px) { .topbar + main.wrap { padding-top: 16px; } }
.wrap.narrow { max-width: 760px; padding-top: 32px; padding-bottom: 60px; }

/* Typographie */
.display {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 28px;
  line-height: 1.2;
  text-transform: uppercase;
  letter-spacing: .12em;
  overflow-wrap: break-word;
  margin: 0 0 6px;
}
/* 18.8 : les titres de panneaux en minuscules ; les étiquettes en minuscules grasses. */
h2 { font-family: var(--font-display); font-weight: 600; font-size: 19px; text-transform: none; letter-spacing: 0; margin: 0 0 12px; }
h3 { font-family: var(--font-body); font-size: 13px; text-transform: none; letter-spacing: 0; color: var(--etiquette); margin: 18px 0 6px; font-weight: 700; }
.lead { font-size: 16px; color: var(--muted); margin: 0 0 8px; max-width: 60ch; }
.lead-sm { color: var(--muted); margin: 0; }
.eyebrow { font-family: var(--font-body); text-transform: none; letter-spacing: 0; font-size: 13px; font-weight: 700; color: var(--etiquette); margin: 0 0 4px; }
.hint { color: var(--muted); font-size: 13.5px; }
.muted { color: var(--muted); }
.prewrap { white-space: pre-wrap; }
.nowrap { white-space: nowrap; }

/* La barre d'ancres d'une fiche longue (la cuvée en fait plus de mille lignes
   une fois le vin vendu) : on change de bloc sans remonter. `sticky` et non
   `fixed` — elle reste dans le flux, donc elle ne recouvre rien et n'oblige à
   compenser aucune hauteur. Le `top` de repli vaut la hauteur de la barre du
   haut ; app.js pose la valeur exacte, qui double quand la barre du haut passe
   sur deux lignes sur téléphone. */
.ancres {
  position: sticky; top: 76px; z-index: 9;
  display: flex; gap: 6px; overflow-x: auto;
  padding: 9px 0; margin: 0 0 18px;
  background: var(--bg); border-bottom: 1px solid var(--line);
}
.ancres a {
  flex: 0 0 auto; padding: 6px 13px; border-radius: 0;
  border: 1px solid var(--line); background: var(--surface);
  color: var(--ink); font-size: 13.5px; font-weight: 500; white-space: nowrap;
}
.ancres a:hover { background: var(--gris-soft); text-decoration: none; }

/* Barre du haut (18.6) : noire dans les deux thèmes, comme le bandeau du site.
   Le logo, puis « LUA D'ENIGMAS » au-dessus de « GESTION ». */
.topbar { background: #000; position: sticky; top: 0; z-index: 10; }
.topbar-inner { display: flex; align-items: center; gap: 24px; min-height: 76px; }
.brand { display: inline-flex; align-items: center; gap: 14px; color: #fff; white-space: nowrap; }
.brand:hover { text-decoration: none; }
.brand-logo { display: block; height: 54px; width: auto; }
.brand-texte { display: flex; flex-direction: column; line-height: 1.15; }
.brand-name { font-family: var(--font-display); font-weight: 400; font-size: 12px; text-transform: uppercase; letter-spacing: .38em; color: #fff; }
.brand-sep { color: #666; }
.brand-app { font-family: var(--font-display); font-weight: 400; font-size: 22px; text-transform: uppercase; letter-spacing: .2em; color: #fff; }
.brand-big { flex-direction: column; align-items: center; gap: 12px; margin-bottom: 22px; }
.brand-big .brand-logo { height: 72px; }
.brand-big .brand-texte { align-items: center; }
/* Huit entrées (15.4, 17.2). 19.2 : le pictogramme de la partie au-dessus du
   mot ; une partie à plusieurs écrans les déroule sous son mot (voir « 19.2 :
   les menus de la barre », en fin de fichier). */
.nav { display: flex; flex-wrap: wrap; gap: 0 15px; margin-left: auto; align-items: center; align-self: stretch; }
.nav-entree { display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  padding: 6px 0 5px; border-radius: 0; border-bottom: 1px solid transparent; color: #C0C0C0; white-space: nowrap;
  font-family: var(--font-display); font-size: 11.5px; font-weight: 400; line-height: 1; text-transform: uppercase; letter-spacing: .14em; }
.nav-entree:hover { color: #fff; text-decoration: none; }
.nav-entree.active { color: #fff; border-bottom-color: rgba(255, 255, 255, .7); }
.nav-ic { position: relative; display: inline-flex; }
/* Le compte de la Boîte IA, posé en haut à droite du pictogramme. */
.nav-ic .pastille-ambre { position: absolute; top: -7px; left: calc(100% - 7px); margin: 0; }
/* À droite : la roue des Réglages, puis le nom pour Mon compte. */
.user-box { display: flex; align-items: center; gap: 4px; }
.roue {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 0; color: #C0C0C0;
}
.roue:hover, .roue.active { color: #fff; text-decoration: none; }
.user-name { color: #C0C0C0; padding: 8px 10px; border-radius: 0;
  font-family: var(--font-display); font-size: 13.5px; font-weight: 400; text-transform: uppercase; letter-spacing: .16em; }
.user-name:hover, .user-name.active { color: #fff; text-decoration: none; }
/* Le rond de l'initiale : seulement sur téléphone, à la place du nom. */
.initiale {
  display: none; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 50%;
  background: transparent; border: 1px solid rgba(255, 255, 255, .55); color: #fff;
  font-family: var(--font-display); font-weight: 400; font-size: 15px;
}
.initiale:hover { text-decoration: none; }

/* ---------------------------------------------------------------------------
   Au pouce (15.6) : la barre du bas et ses deux feuilles. Rien de tout cela
   au-dessus de 640 px — la barre est cachée, les feuilles ne s'ouvrent que
   par elle. Sans JavaScript, Saisir et Plus sont des liens vers saisir.php et
   plus.php.
   --------------------------------------------------------------------------- */
.barre-tel { display: none; }
.feuille-bas[hidden] { display: none; }
.feuille-bas { position: fixed; inset: 0; z-index: 70; display: flex; flex-direction: column; justify-content: flex-end; }
.feuille-voile { position: absolute; inset: 0; background: var(--voile); }
.feuille-panneau {
  position: relative; max-height: 88vh; overflow-y: auto; overscroll-behavior: contain;
  background: var(--surface); border-radius: 0;
  padding: 8px 16px calc(16px + env(safe-area-inset-bottom, 0px));
}
.feuille-poignee { width: 40px; height: 4px; border-radius: 2px; background: var(--line-strong); margin: 4px auto 10px; }
.feuille-tete { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 4px; }
.feuille-tete h2 { margin: 0; }
.feuille-fermer { font-weight: 600; padding: 8px 4px; }
.feuille-liste { list-style: none; margin: 0; padding: 0; }
.feuille-liste li + li { border-top: 1px solid var(--line); }
.feuille-liste a {
  display: flex; align-items: center; gap: 14px; min-height: 64px; padding: 10px 4px;
  color: var(--ink);
}
.feuille-liste a:hover { text-decoration: none; background: var(--zebra-doux); }
.feuille-liste a.on strong { color: var(--plum); }
.feuille-icone {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: 0; background: var(--plum-soft); color: var(--plum);
}
.feuille-texte { display: flex; flex-direction: column; min-width: 0; }
.feuille-texte strong { font-weight: 600; }
.feuille-aide { font-size: 13px; color: var(--muted); }
/* saisir.php et plus.php : la même liste, dans un panneau. */
.feuille-page { padding-top: 6px; padding-bottom: 6px; }
@media (prefers-reduced-motion: no-preference) {
  .feuille-panneau { animation: feuille-monte .2s ease-out; }
}
@keyframes feuille-monte { from { transform: translateY(100%); } to { transform: none; } }

/* Boutons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 10px 16px; border-radius: 0; border: 1px solid var(--ink);
  background: var(--surface); color: var(--ink); font: inherit; font-family: var(--font-body);
  font-size: 13px; font-weight: 600; text-transform: none; letter-spacing: .01em;
  cursor: pointer; white-space: nowrap; line-height: 1.2;
}
.btn:hover { background: #000; border-color: #000; color: #fff; text-decoration: none; }
.btn-primary { background: var(--plum-bg); border-color: var(--plum-bg); color: var(--on-plum); }
.btn-primary:hover { background: var(--plum-bg-hover); border-color: var(--plum-bg-hover); color: var(--on-plum); }
.btn-ghost { background: transparent; border-color: var(--line-strong); }
.btn-danger { color: var(--rouge); border-color: var(--rouge); }
.btn-danger:hover { background: var(--rouge); border-color: var(--rouge); color: var(--on-rouge); }
.btn-sm { padding: 7px 11px; font-size: 12.5px; }
/* En sombre : un filet blanc à mi-teinte, le survol à peine éclairé ; le bouton
   principal en blanc, texte noir (ses variables). */
/* `:where()` : ces règles pèsent autant que celles du dessus, et une règle plus
   précise venue ensuite (le bouton Photo de la Boîte IA, la barre Focus) garde
   la main. */
:where(:root[data-theme="dark"]) .btn { border-color: rgba(255, 255, 255, .5); color: #fff; }
:where(:root[data-theme="dark"]) .btn:hover { background: rgba(255, 255, 255, .1); border-color: rgba(255, 255, 255, .5); color: #fff; }
:where(:root[data-theme="dark"]) .btn-primary { background: var(--plum-bg); border-color: var(--plum-bg); color: var(--on-plum); }
:where(:root[data-theme="dark"]) .btn-primary:hover { background: var(--plum-bg-hover); border-color: var(--plum-bg-hover); color: var(--on-plum); }
:where(:root[data-theme="dark"]) .btn-ghost { border-color: var(--line-strong); }
:where(:root[data-theme="dark"]) .btn-danger { color: var(--rouge); border-color: var(--rouge); }
:where(:root[data-theme="dark"]) .btn-danger:hover { background: var(--rouge-soft); color: var(--rouge); border-color: var(--rouge); }
.btn-block { width: 100%; }
/* Au clavier (18.8) : un contour bleu franc, visible sur le blanc comme sur le noir. */
:focus-visible { outline: 3px solid var(--badge-bleu); outline-offset: 2px; }
/* Un champ qui a la main : son filet passe à l'encre, sans halo (18.6). */
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--ink); }
input[type="checkbox"]:focus-visible, input[type="radio"]:focus-visible { outline: 3px solid var(--badge-bleu); outline-offset: 2px; }

/* Messages */
/* 18.8 : fond pâle, filet de la couleur pleine, texte à l'encre. */
.flash { padding: 12px 16px; border-radius: 0; margin: 16px 0; border: 1px solid transparent; color: var(--ink); font-size: 14.5px; }
.flash-ok { background: var(--vert-soft); border-color: var(--badge-vert); }
.flash-err { background: var(--rouge-soft); border-color: var(--badge-rouge); }
.flash-avert { background: var(--ambre-soft); border-color: var(--badge-ambre); }
/* Ni bon, ni mauvais : « voici ce que je viens de faire pour vous ». Le bleu
   évite qu'une copie prête à enregistrer se lise comme un avertissement. */
.flash-info { background: var(--bleu-soft); border-color: var(--badge-bleu); }

/* Panneaux */
.panel { background: var(--surface); border: 1px solid var(--line-strong); border-radius: 0; padding: 20px 22px; margin: 16px 0; }
.panel.empty { text-align: center; color: var(--muted); padding: 40px; }
.cols { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.cols > .panel { margin: 16px 0 0; }
.cols-side { grid-template-columns: 260px 1fr; }
.side-nav { display: flex; flex-direction: column; gap: 2px; padding: 10px; }
.side-nav a { padding: 8px 12px; border-radius: 0; color: var(--ink); }
.side-nav a:hover { background: var(--gris-soft); text-decoration: none; }
.side-nav a.active { background: var(--plum-soft); color: var(--plum-ink); font-weight: 600; }

/* En-tête de page */
/* 19.2 : 8 px au-dessus — la ligne « Partie › Écran » est désormais au-dessus du titre. */
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; padding: 8px 0 8px; flex-wrap: wrap; }
.actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.actions-form { padding: 8px 0 40px; }
.inline { display: inline; }
.hero { padding: 40px 0 10px; }

.tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; padding: 12px 0 50px; }
.tile {
  display: flex; flex-direction: column; gap: 6px; min-height: 220px;
  padding: 22px; border-radius: 0; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line-strong);
}
.tile:hover { text-decoration: none; }
.tile-on { border: 1px solid var(--plum); }
.tile-on:hover { background: var(--gris-soft); }
.tile-title { font-family: var(--font-display); font-size: 24px; font-weight: 600; line-height: 1.15; text-transform: none; letter-spacing: 0; }
.tile-stats { margin-top: auto; display: flex; flex-wrap: wrap; gap: 6px 14px; padding-top: 14px; border-top: 1px solid var(--line); font-size: 13px; color: var(--muted); }
.stat b { color: var(--ink); font-weight: 600; }
.stat-rouge b { color: var(--rouge); }
.stat-ambre b { color: var(--ambre-fort); }
.stat-vert b { color: var(--vert); }

/* Badges d'état (18.8) : une couleur pleine (ou pâle pour le prévu et ce qui
   arrive), et le mot qui dit l'état. En minuscules, gras, carrés, sans filet.
   (Le signe devant le texte a disparu en 19.10.)
     rouge  retard, impayé, échu, stock manquant, dormant
     ambre  aujourd'hui, cette semaine, à relancer, à livrer, à facturer
     bleu   rendez-vous — la seule chose en bleu plein
     plan   prévu, à envoyer, à organiser, à conclure, en attente, devis
     prune  reçu, nouveau, premier contact, à vérifier
     vert   fait, soldée, payée, livrée, rapprochée
     gris   plus tard, sans date, clôturé, annulée
   Les classes viennent du PHP (`alerte_classe()`…) : `ambre-fort` est un ambre,
   `bleu-clair` et `bleu-fonce` sont le bleu pâle du prévu. */
.badge { display: inline-block; padding: 4px 10px; border-radius: 0; font-family: var(--font-body); font-size: 13px; font-weight: 700;
  text-transform: none; letter-spacing: 0; white-space: nowrap; line-height: 1.35; border: 0; background: var(--badge-gris); color: var(--sur-gris); }
.badge-rouge { background: var(--badge-rouge); color: var(--sur-rouge); }
.badge-ambre, .badge-ambre-fort { background: var(--badge-ambre); color: var(--sur-ambre); }
.badge-bleu { background: var(--badge-bleu); color: var(--sur-bleu); }
.badge-bleu-clair, .badge-bleu-fonce { background: var(--badge-plan); color: var(--sur-plan); }
.badge-prune { background: var(--badge-prune); color: var(--sur-prune); }
.badge-vert { background: var(--badge-vert); color: var(--sur-vert); }
.badge-gris { background: var(--badge-gris); color: var(--sur-gris); }
/* 19.11 : un **pictogramme** devant le texte, qui dit ce que dit la couleur —
   à la place des signes géométriques de la 18.8 (retirés en 19.10). Les tracés
   sont ceux du reste du site (Lucide, `inc/icones.php`), posés en masque :
   la pastille les remplit de la couleur de son texte, en clair comme en
   sombre. Les lignes `--pic` viennent de `css_icones_badges()` — un test
   vérifie qu'elles n'ont pas divergé. Le gris n'en a pas.
     rouge      cercle « ! »   en retard, impayé, échu, épuisé, dormant
     ambre      horloge        aujourd'hui, cette semaine, à relancer, à livrer
     bleu       calendrier     un rendez-vous
     bleu pâle  sablier        prévu, en attente, à encaisser, devis
     prune      étincelles     reçu, nouveau, premier contact, à vérifier
     vert       coche          fait, payée, livrée, soldée */
.badge-rouge { --pic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' x2='12' y1='8' y2='12'/%3E%3Cline x1='12' x2='12.01' y1='16' y2='16'/%3E%3C/svg%3E"); }
.badge-ambre { --pic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpolyline points='12 6 12 12 16 14'/%3E%3C/svg%3E"); }
.badge-ambre-fort { --pic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpolyline points='12 6 12 12 16 14'/%3E%3C/svg%3E"); }
.badge-bleu { --pic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 2v4'/%3E%3Cpath d='M16 2v4'/%3E%3Crect width='18' height='18' x='3' y='4' rx='2'/%3E%3Cpath d='M3 10h18'/%3E%3C/svg%3E"); }
.badge-bleu-clair { --pic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 22h14'/%3E%3Cpath d='M5 2h14'/%3E%3Cpath d='M17 22v-4.172a2 2 0 0 0-.586-1.414L12 12l-4.414 4.414A2 2 0 0 0 7 17.828V22'/%3E%3Cpath d='M7 2v4.172a2 2 0 0 0 .586 1.414L12 12l4.414-4.414A2 2 0 0 0 17 6.172V2'/%3E%3C/svg%3E"); }
.badge-bleu-fonce { --pic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 22h14'/%3E%3Cpath d='M5 2h14'/%3E%3Cpath d='M17 22v-4.172a2 2 0 0 0-.586-1.414L12 12l-4.414 4.414A2 2 0 0 0 7 17.828V22'/%3E%3Cpath d='M7 2v4.172a2 2 0 0 0 .586 1.414L12 12l4.414-4.414A2 2 0 0 0 17 6.172V2'/%3E%3C/svg%3E"); }
.badge-prune { --pic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z'/%3E%3Cpath d='M20 3v4'/%3E%3Cpath d='M22 5h-4'/%3E%3Cpath d='M4 17v2'/%3E%3Cpath d='M5 18H3'/%3E%3C/svg%3E"); }
.badge-vert { --pic: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E"); }
.badge:is(.badge-rouge, .badge-ambre, .badge-ambre-fort, .badge-bleu, .badge-bleu-clair, .badge-bleu-fonce, .badge-prune, .badge-vert):not(.badge-neutre)::before {
  content: ""; flex: none; width: 14px; height: 14px; margin-left: -2px; background: currentColor;
  -webkit-mask: var(--pic) center / contain no-repeat; mask: var(--pic) center / contain no-repeat;
}
/* Ce qui n'est pas un état — l'intérêt, une quantité, un pourcentage, une
   nature, une source, le « quoi » du journal : neutre, sans signe. */
.badge.badge-neutre { background: var(--gris-soft); color: var(--ink); border: 1px solid var(--line-strong); padding: 3px 9px; }
.badge.badge-neutre::before { content: none; }
/* Un compte dans le titre d'un panneau (le « 6 » d'En retard) : un peu plus grand, centré. */
.panel-titre .badge { font-size: 14px; padding: 3px 11px; min-width: 34px; text-align: center; }
/* Colonne Alerte : centrée, c'est l'information qu'on cherche en premier.
   19.2 : seulement une colonne d'état — l'alerte d'un prospect, un badge d'état
   en tête de ligne. Une autre première colonne (un nom, une étape, une date) se
   lit à gauche, comme le reste du tableau. */
table.list > tbody > tr > td.cell-urgence, table.list > thead > tr > th.cell-urgence,
table.list > tbody > tr:has(> td:first-child .badge:not(.badge-neutre)) > td:first-child,
table.list:has(> tbody > tr > td:first-child .badge:not(.badge-neutre)) > thead > tr > th:first-child { text-align: center; }

/* Tableau de bord */
/* Panneaux dépliables (tableau de bord, filtres) */
/* La barre d'un bloc dépliable : voir « 19.1 : les blocs dépliables », en fin de fichier. */
.dash-table { width: 100%; border-collapse: collapse; margin-top: 16px; font-size: 14.5px; }
.dash-table th, .dash-table td { padding: 10px 12px; border-bottom: 1px solid var(--line); text-align: left; }
.dash-table thead th { font-size: 13px; text-transform: none; letter-spacing: 0; color: var(--etiquette); font-weight: 700; background: var(--surface); vertical-align: bottom; border-bottom-color: var(--ink); }
/* Un liseré de couleur sous chaque intitulé : même code que les pastilles de la liste */
.dash-table thead th.num { border-bottom: 4px solid var(--line-strong); }
.dash-table thead th.col-rouge { border-bottom-color: var(--rouge); }
.dash-table thead th.col-ambre { border-bottom-color: var(--ambre-fort); }
.dash-table thead th.col-bleu { border-bottom-color: var(--bleu); }
.dash-table thead th.col-bleu-clair { border-bottom-color: var(--bleu-clair); }
.dash-table thead th.col-bleu-fonce { border-bottom-color: var(--bleu-fonce); }
.dash-table thead th.col-prune { border-bottom-color: var(--plum-soft); }
.dash-table thead th.col-vert { border-bottom-color: var(--vert); }
.dash-table tbody tr:hover th, .dash-table tbody tr:hover td { background: var(--plum-soft); }
.dash-table tbody th { font-weight: 600; }
.dash-table tbody th a { color: var(--ink); }
.dash-table tbody th a:hover { color: var(--plum); }
.dash-table tfoot th, .dash-table tfoot td { font-weight: 700; border-bottom: none; border-top: 2px solid var(--plum); background: var(--zebra-doux); }
.dash-table .num { text-align: center; font-variant-numeric: tabular-nums; }
.dash-table .num a { font-weight: 700; font-size: 15.5px; }
.dash-table .num-rouge a { color: var(--rouge); }
.dash-table .num-ambre a { color: var(--ambre-fort); }
.dash-table .num-bleu a { color: var(--bleu); }
.dash-table .num-bleu-clair a { color: var(--bleu-clair); }
.dash-table .num-bleu-fonce a { color: var(--bleu-fonce); }
.dash-table .num-prune a { color: var(--plum); }
.dash-table .num-vert a { color: var(--vert); }
.dash-table .zero { color: var(--line-strong); }
.dash-vide th a, .dash-vide td { color: var(--muted); font-weight: 400; }

/* Filtres — les trois blocs (tableau de bord, recherche, filtres) partagent
   le même gabarit de carte pour rester à la même hauteur une fois repliés. */
.filters { margin: 12px 0 8px; }
.filters-ligne { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 15px 22px; margin: 0; }
.champ-recherche { position: relative; display: flex; align-items: center; flex: 1 1 260px; }
/* Une phrase sous la barre : dire que la recherche et les menus se cumulent. */
.hint-recherche { margin: 6px 2px 0; }
/* Un menu posé dans la barre de recherche : intitulé à gauche, sur une ligne. */
.filtre-tournee { flex: 0 0 auto; flex-direction: row; align-items: center; gap: 8px; }
.filtre-tournee select { width: auto; min-width: 130px; }
.champ-recherche input { padding-left: 40px; font-size: 15.5px; }
/* Dans un formulaire, le champ occupe toute la largeur de sa case. */
.form-grid .champ-recherche { flex: 1 1 auto; width: 100%; }
.form-grid .champ-recherche input { width: 100%; }
.icone-loupe { position: absolute; left: 13px; width: 18px; height: 18px; color: var(--muted); pointer-events: none; }
.filtres-pliant { margin: 12px 0 0; }
.filtres-pliant .form-grid { margin-top: 18px; }
.filtres-actions { display: flex; gap: 8px; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); }
.panel-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.panel-titre { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.panel-titre h2 { margin: 0; }
.dl-chiffres { margin-top: 14px; }
.chiffres { display: flex; flex-wrap: wrap; gap: 8px 26px; padding: 16px 22px; }
.chiffres .stat { font-size: 14px; color: var(--muted); }
.chiffres .stat b { font-size: 19px; color: var(--ink); font-variant-numeric: tabular-nums; }
.chiffres .stat-vert b { color: var(--vert); }
.chiffres .stat-rouge b { color: var(--rouge); }
.chiffres .stat-ambre b { color: var(--ambre-fort); }
/* Un panneau qui prévient sans bloquer : le doublon probable, avant d'écrire. */
.panel-avert { border-color: var(--ambre-bord); background: var(--ambre-soft); }
.panel-avert h2 { color: var(--ambre); }
/* « Sans suite » : son motif tient sur la même ligne que le bouton. */
.form-sans-suite { display: inline-flex; align-items: center; gap: 8px; }
.form-sans-suite select { width: auto; min-width: 130px; }
table.list .num { text-align: right; font-variant-numeric: tabular-nums; }
table.list thead th.num { text-align: right; }
.col-action { text-align: right; white-space: nowrap; }
.col-action .btn { margin-left: 4px; }
.ligne-cuvee { display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; }
.ligne-cuvee + .ligne-cuvee { margin-top: 3px; }
.ligne-nom { font-weight: 500; }
.ligne-detail { font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }
.lignes-commande td { padding: 8px 10px; }
.lignes-commande select, .lignes-commande input { min-width: 120px; }
.annee-cellule { white-space: nowrap; font-weight: 600; }
.contacts { list-style: none; margin: 0 0 4px; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.contacts li { padding-bottom: 10px; border-bottom: 1px solid var(--line); }
.contacts li:last-child { border-bottom: none; }
.contact-nom { font-weight: 600; }
.contact-fonction { font-weight: 400; font-size: 13px; color: var(--plum); background: var(--plum-soft);
                    padding: 2px 8px; border-radius: 0; margin-left: 4px; white-space: nowrap; }
.cell-certifs { white-space: normal; }
.cell-certifs .badge { margin: 2px 4px 2px 0; }
/* `.bloc-certif` encadrait le formulaire déroulé de chaque certification. Depuis
   la 13.7, les certifications sont une liste et un seul formulaire s'ouvre. */
/* Prix de revient : une addition qu'on doit pouvoir refaire de tête */
.revient { margin-top: 4px; }
.revient th { font-weight: 400; text-align: left; }
.revient td { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.revient .revient-sous-total th, .revient .revient-sous-total td { font-weight: 600; border-top: 1px solid var(--line-strong); }
.revient .revient-total th, .revient .revient-total td { font-weight: 700; border-top: 2px solid var(--plum); }
.revient .revient-cle th, .revient .revient-cle td { background: var(--plum-soft); font-size: 16px; }
.revient .revient-marge th, .revient .revient-marge td { border-top: 1px solid var(--line-strong); font-size: 16px; }
.revient .revient-bloque th, .revient .revient-bloque td { background: var(--ambre-soft); }
.revient .revient-section th { font-family: var(--font-display); font-size: 16px; color: var(--plum);
                               padding-top: 20px; border-bottom: 1px solid var(--line-strong); }
.cases-millesimes { display: flex; flex-wrap: wrap; gap: 6px 16px; padding: 9px 0; }
.cases-millesimes .check { color: var(--ink); font-size: 14px; }
.inline-date { flex-direction: row; align-items: center; gap: 8px; color: var(--ink); }
.inline-date input, .inline-date select { width: auto; }

/* Analyse : cinq à sept indicateurs, pas davantage — au-delà on ne voit plus
   celui qui est au rouge. */
.kpis { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px 26px; }
.kpi { display: flex; flex-direction: column; gap: 2px; }
.kpi-valeur { font-family: var(--font-display); font-size: 28px; font-weight: 600;
              line-height: 1.1; font-variant-numeric: tabular-nums; }
.kpi-nom { font-size: 13px; font-weight: 700; color: var(--etiquette); text-transform: none; letter-spacing: 0; }
.kpi-detail { font-size: 13.5px; color: var(--muted); }
/* Une pastille qui se clique : le statut est aussi le bouton qui le change */
.btn-pastille { background: none; border: none; padding: 0; cursor: pointer; font: inherit; }
.btn-pastille .badge { cursor: pointer; }
.btn-pastille:hover .badge { border-color: var(--plum); }
.barre { display: block; width: 100%; min-width: 90px; height: 8px; border-radius: 0;
         background: var(--gris-soft); overflow: hidden; }
.barre-part { display: block; height: 100%; background: var(--plum); border-radius: 0; }
.kpis-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) { .kpis, .kpis-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .kpis, .kpis-4 { grid-template-columns: 1fr; } }
.marge-positive { color: var(--vert); }
.marge-negative { color: var(--rouge); }
.ecotaxe { border-top: 1px solid var(--line); margin-top: 18px; padding-top: 16px; }
.ecotaxe h3 { margin-bottom: 12px; }
.suivi-form .form-grid { margin-top: 4px; }
.count { color: var(--muted); font-size: 13px; margin: 6px 0 10px; }

/* Liste */
.table-wrap { overflow-x: auto; }
table.list { width: 100%; border-collapse: collapse; background: var(--surface); border: 1px solid var(--line-strong); border-radius: 0; overflow: hidden; }
table.list th, table.list td { padding: 12px 14px; text-align: left; vertical-align: middle; border-bottom: 1px solid var(--line); }
table.list thead th { font-family: var(--font-body); font-size: 13px; text-transform: none; letter-spacing: 0; color: var(--etiquette); font-weight: 700;
  background: var(--surface); border-bottom: 1px solid var(--ink); }
table.list tbody tr:last-child td { border-bottom: none; }
.cell-nom { vertical-align: top; }
.cell-nom a { font-weight: 600; font-size: 15px; color: var(--ink); }
.cell-nom a:hover { color: var(--plum); text-decoration: underline; }
.date-retard { color: var(--rouge); font-weight: 700; font-size: 13.5px; }

/* Toute la ligne ouvre la fiche, et une barre colorée rappelle l'alerte */
table.list tbody tr[data-href] { cursor: pointer; }
table.list tbody tr[data-href]:hover td, table.list tbody tr[data-volet]:hover td { background: var(--gris-soft); }
/* 18.8 : la ligne porte son état — un trait gauche de 5 px de la couleur du badge
   de sa première cellule, et un fond pâle pour le rouge et l'ambre (voir « La
   ligne porte son état », en fin de fichier). Sans badge, le trait est
   transparent : les colonnes restent alignées. */
table.list tbody td:first-child { border-left: 5px solid transparent; }
/* Une fiche close (Clôturé, Pas intéressé), sous « Toutes » : en gris (18.5). */
tr.ligne-close td, tr.ligne-close td a, tr.ligne-close td strong { color: var(--muted); }
.sub { display: block; font-size: 13.5px; color: var(--muted); }
.show-sm { display: none; }

/* Fiche */
.dl { display: grid; grid-template-columns: 150px 1fr; gap: 6px 14px; margin: 0; }
.dl dt { color: var(--muted); font-size: 13px; padding-top: 2px; }
.dl dd { margin: 0; }
.journal { list-style: none; margin: 16px 0 0; padding: 0; }
.journal li { display: grid; grid-template-columns: 170px 1fr; gap: 12px; padding: 10px 0; border-top: 1px solid var(--line); }
.journal-meta { font-size: 12.5px; color: var(--muted); }
.journal-auto .journal-texte { color: var(--muted); font-size: 14px; }
.note-form { display: flex; gap: 10px; align-items: flex-start; }
.note-form textarea { flex: 1; }

/* Formulaires */
label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--muted); font-weight: 500; }
label.check { flex-direction: row; align-items: center; gap: 8px; color: var(--ink); font-weight: 400; }
input, select, textarea {
  font: inherit; font-family: var(--font-body); font-size: 14px; color: var(--ink); background: var(--surface);
  border: 1px solid var(--line-strong); border-radius: 0; padding: 8px 10px; width: 100%;
}
input[type="checkbox"] { width: auto; }
textarea { resize: vertical; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 14px; }
.form-grid-4 { grid-template-columns: repeat(4, 1fr); }
.form-grid .span2 { grid-column: span 2; }
.form-grid .span3 { grid-column: span 3; }
.form-grid .span4 { grid-column: 1 / -1; }
.form .panel h2 { margin-bottom: 14px; }
/* La fiche d'un millésime (15.7) : une phrase en tête — la prochaine
   opération —, puis les blocs sous trois titres. La barre de jalons d'avant
   répétait les blocs : elle est partie. */
.phrase-operation { font-size: 16px; font-weight: 600; margin: 8px 0 4px; max-width: 70ch; }
.phrase-alerte { color: var(--ambre-fort); }
/* Les titres de groupe d'une fiche (19.1) : en capitales espacées, sur un filet. */
.groupe-fiche {
  margin: 28px 0 10px; padding-bottom: 6px; border-bottom: 1px solid var(--line-strong);
  font-family: var(--font-display); font-size: 13px; font-weight: 400;
  text-transform: uppercase; letter-spacing: .24em; color: var(--muted);
}
/* La barre de saut, en trois groupes : le nom du groupe, puis ses blocs. */
.saut .saut-groupe {
  flex: 0 0 auto; align-self: center; margin-left: 6px;
  font-size: 12.5px; font-weight: 700; text-transform: none; letter-spacing: 0; color: var(--etiquette);
}
.saut .saut-groupe:first-child { margin-left: 0; }
.etape-marque.etape-prochaine { color: var(--plum); }
.menu-plus-liste .menu-danger { color: var(--rouge); }

.table-parcours .jalon-tete { font-size: 12px; font-weight: 600; line-height: 1.15;
  writing-mode: vertical-rl; transform: rotate(180deg); height: 8.5em; padding: 6px 2px; white-space: nowrap; }
.table-parcours td.jalon { font-size: 15px; font-weight: 700; padding-left: 2px; padding-right: 2px; }
.table-parcours td.jalon-fait { color: var(--vert); }
.table-parcours td.jalon-a_faire { color: var(--line-strong); }
.table-parcours td.jalon-sans_objet { color: var(--line); }

/* Le chai : une ligne par étape, chacune son propre formulaire. Sur téléphone,
   les champs passent les uns sous les autres sans rien casser. */
.etapes-chai { list-style: none; padding: 0; margin: 12px 0 0; }
.etapes-chai > li { border-top: 1px solid var(--line); }
.etapes-chai > li:first-child { border-top: none; }

/* Une étape est un bloc : ses occurrences, et de quoi le déplacer. La poignée
   et les flèches tiennent dans une colonne étroite à gauche. */
.etape-bloc { display: flex; align-items: flex-start; gap: 6px; }
.etape-bloc .etape-lignes { flex: 1 1 auto; min-width: 0; }
.etape-poignee { cursor: grab; color: var(--line-strong); font-size: 15px; padding: 14px 2px 0; user-select: none; }
.etape-bloc:hover .etape-poignee { color: var(--muted); }
.etape-portee { opacity: .5; background: var(--gris-soft); }
.etape-fleches { display: flex; flex-direction: column; gap: 1px; padding-top: 10px; }
.btn-fleche {
  border: 1px solid transparent; background: none; cursor: pointer;
  color: var(--line-strong); font-size: 12px; line-height: 1; padding: 3px 4px; border-radius: 0;
}
.btn-fleche:hover:not(:disabled) { background: var(--gris-soft); color: var(--ink); border-color: var(--line); }
.btn-fleche:disabled { opacity: .3; cursor: default; }
/* Les analyses : le résumé en tête de fiche, le tableau, et les courbes. */
.chiffres-analyse a { color: var(--plum); font-weight: 600; }
.sub-inline { color: var(--muted); font-size: 12px; font-weight: 400; }
/* Un champ absent qui explique son absence, à la place du champ. */
.hint-champ { display: block; color: var(--muted); font-size: 12.5px; font-weight: 400; line-height: 1.4; }
.table-analyses td.num, .table-analyses th.num { font-variant-numeric: tabular-nums; }
.sub-ambre { color: var(--ambre); }
/* Les courbes d'analyses (19.1) : deux par ligne, chacune dans sa carte. */
.courbes { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin: 16px 0 4px; }
.courbe { margin: 0; border: 1px solid var(--line); padding: 12px 14px; background: var(--surface); min-width: 0; }
.courbe figcaption { font-size: 13.5px; font-weight: 700; margin-bottom: 6px; }
.courbe figcaption .unite { color: var(--muted); font-weight: 400; }
.courbe svg { display: block; width: 100%; height: 120px; overflow: visible; }
.courbe .axe { stroke: var(--line-strong); stroke-width: 1; }
/* Les tailles du texte des courbes sont dans le dessin (unités du viewBox). */
.courbe .borne { fill: var(--muted); font-family: var(--font-body); }
.courbe polyline { fill: none; stroke: var(--ink); stroke-width: 2; }
.courbe circle { fill: var(--ink); }
.courbe .valeur { fill: var(--ink); font-weight: 700; font-family: var(--font-body); }
.courbe .jour { fill: var(--muted); font-family: var(--font-body); }
.courbe .seuil { stroke: var(--rouge); stroke-width: 1.5; stroke-dasharray: 5 4; }
.courbe .seuil-texte { fill: var(--rouge); font-weight: 700; font-family: var(--font-body); }
@media (max-width: 900px) { .courbes { grid-template-columns: 1fr; } }

/* La croix qui supprime une ligne d'étape. Discrète tant qu'on ne la cherche
   pas, rouge dès qu'on la survole : elle efface pour de bon. */
.btn-croix {
  border: 1px solid transparent; background: none; cursor: pointer;
  color: var(--line-strong); font-size: 13px; line-height: 1;
  padding: 6px 8px; border-radius: 0;
}
.btn-croix:hover { background: var(--rouge-soft); color: var(--rouge); border-color: var(--rouge-bord); }

/* Ajouter une étape à cette cuvée-là : **le** geste du chai depuis la 13.3.
   Le mécanisme « écarter » a disparu — ne pas ajouter une étape suffit. */
.ajout-etape { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; margin-top: 16px;
  padding-top: 14px; border-top: 1px solid var(--line); }
.ajout-etape label { margin: 0; font-size: 12px; color: var(--muted); flex: 0 1 280px; }
.ajout-etape label:nth-of-type(2) { flex: 0 1 150px; }
.ajout-etape .hint { flex: 1 1 240px; }
/* Préparer un millésime : une ligne par vin, sa case et son calendrier. */
.liste-millesimes .chai-quoi { flex: 1 1 auto; }
.liste-millesimes .check { flex: 0 1 auto; font-size: 13px; }
@media (max-width: 700px) {
  /* Au doigt, la poignée ne sert à rien : seules les flèches restent. */
  .etape-poignee { display: none; }
}
.ligne-etape { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; padding: 10px 0; }
.ligne-etape .etape-nom { flex: 1 1 190px; font-weight: 600; align-self: center; }
.ligne-etape .etape-champ { flex: 0 1 150px; margin: 0; font-size: 12px; color: var(--muted); }
.ligne-etape .etape-note { flex: 1 1 220px; }
/* Le chiffre de la cuvée saisi dans l'étape — volume, bouteilles. Il compte
   plus que la note : on le distingue, sans en faire un bouton. */
.ligne-etape .etape-chiffre { flex: 0 1 165px; color: var(--plum); font-weight: 600; }
.ligne-etape .etape-chiffre input { font-weight: 600; border-color: var(--line-strong); }
.ligne-etape .etape-champ input { font-size: 14px; }
.ligne-etape .etape-actions { display: flex; gap: 6px; margin-left: auto; align-self: center; }
.etape-marque { font-weight: 700; margin-right: 5px; }
/* Le fond de couleur porte sur la ligne, désormais imbriquée dans son bloc :
   un peu d'air sur les côtés pour qu'il ne colle pas au texte. */
.etapes-chai .etape-fait,
.etapes-chai .etape-retard { padding-left: 8px; padding-right: 8px; border-radius: 0; }
.etapes-chai .etape-fait { background: var(--vert-soft); }
.etapes-chai .etape-fait .etape-marque { color: var(--vert); }
.etapes-chai .etape-retard { background: var(--rouge-soft); }
.etapes-chai .etape-retard .etape-nom { color: var(--rouge); }
.chai-compte { font-variant-numeric: tabular-nums; }

/* Retour en 18.7 à la liste de la 17.8 : chaque ligne est son formulaire, la
   poignée et les flèches toujours visibles. La lecture de la 17.9 (crayon,
   « Reporter », poignées cachées) a disparu, avec ses règles. */
.ligne-etape .etape-marque { color: var(--muted); }
.ligne-etape .etape-marque.etape-prochaine { color: var(--plum); }
.ligne-etape .etape-nom .sub { font-weight: 400; }
/* En Focus, le lien « ses habitudes » mènerait ailleurs : il se tait (17.9). */
.mode-focus #fournisseur-connu a { display: none; }

/* « Mes fiches » : qui l'on regarde, et comment en changer. */
.bandeau-mien {
  margin: 0 0 12px; padding: 9px 14px; border-radius: 0;
  background: var(--plum-soft); color: var(--plum-ink); font-size: 14px;
}
.bandeau-mien a { margin-left: 6px; font-weight: 600; }

/* Le geste rapide de la prospection : un mini-formulaire déplié dans la ligne.
   Il tient sur une ligne à l'écran, et passe en colonne sur téléphone. */
.ligne-noter > td { background: var(--plum-soft); padding: 10px 14px; }
.form-noter { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.form-noter .noter-nom { font-weight: 600; align-self: center; flex: 0 1 auto; }
.form-noter label { margin: 0; font-size: 12px; color: var(--muted); flex: 0 1 200px; }
.form-noter select, .form-noter input { font-size: 14px; }
.form-noter .btn { margin-left: 0; }
@media (max-width: 640px) { .form-noter label { flex: 1 1 100%; } }

/* Noter un échange (15.1) : trois questions, en lignes de pastilles. */
.geste-fiche .noter-nom { display: block; font-weight: 600; margin-bottom: 2px; }
.geste-fiche .form-noter { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--line-strong); }
.form-echange .ligne-chips { margin: 8px 0; }
.form-echange .echange-note { display: flex; margin: 4px 0 2px; }
.form-echange .echange-note textarea { width: 100%; font-size: 14px; }
.form-echange [data-pour-suite].form-grid { margin-top: 8px; }
.form-echange .echange-autre { margin-top: 8px; }
.form-echange .panel-actions { margin-top: 10px; }
/* Sans JavaScript, la pastille cochée se voit quand même. */
.chip:has(input:checked) { background: var(--plum-bg); border-color: var(--plum-bg); color: var(--on-plum); }

/* Le volet (15.2) : à droite de la liste des prospects ou des clients, il
   porte tout ce qu'il faut pour agir sans quitter la liste. Fixe, 420 px, son
   propre défilement ; sous 900 px, il prend tout l'écran, le bouton fermer en
   haut. Les couleurs et les polices sont celles de l'outil. */
.volet {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 60;
  width: 420px; max-width: 100%;
  background: var(--surface); border-left: 1px solid var(--line-strong);
  box-shadow: var(--ombre-menu);
  overflow-y: auto; overscroll-behavior: contain;
}
.volet-corps { padding: 16px 18px 28px; }
.volet-tete { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px;
  position: sticky; top: -16px; margin: -16px -18px 10px; padding: 16px 18px 10px;
  background: var(--surface); border-bottom: 1px solid var(--line); z-index: 1; }
.volet-nom { margin: 0; font-family: var(--font-display); font-size: 19px; font-weight: 600; text-transform: none; letter-spacing: 0; }
.volet-tete .sub { margin: 2px 0 0; }
.volet-lien { margin: 4px 0 0; font-size: 13px; }
.volet-fermer { flex: 0 0 auto; width: 36px; height: 36px; border-radius: 50%; border: 1px solid var(--line-strong);
  background: var(--surface); color: var(--ink); font-size: 20px; line-height: 1; cursor: pointer; }
.volet-fermer:hover { border-color: var(--plum); color: var(--plum); }
.volet-contact { margin: 0 0 10px; }
.volet-boutons { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 12px; }
.volet-prochain { margin: 0 0 6px; font-weight: 600; }
.volet-bloc { margin-top: 18px; padding-top: 12px; border-top: 1px solid var(--line); }
.volet-bloc h3 { margin: 0 0 8px; }
.volet-liste { margin: 8px 0 0; padding-left: 18px; font-size: 14px; }
/* Le volet d'un article (15.9) : trois chiffres côte à côte — en stock, à
   prévoir, manque. */
.volet-chiffres { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 12px 0 4px; }
.volet-chiffres > div { background: var(--zebra-doux); border: 1px solid var(--line); border-radius: 0; padding: 8px 10px; }
.volet-chiffres dt { font-size: 12px; color: var(--muted); }
.volet-chiffres dd { margin: 2px 0 0; font-size: 19px; font-weight: 600; font-variant-numeric: tabular-nums; }
.volet-chiffres dd .sub { display: block; font-size: 12px; font-weight: 400; color: var(--muted); }
.volet .journal li { grid-template-columns: 1fr; gap: 2px; padding: 8px 0; }
.volet .form-grid-4 { grid-template-columns: 1fr 1fr; }
.volet-rares .form-noter { margin: 0; }
/* La ligne dont le volet est ouvert. */
tr.ligne-ouverte > td { background: var(--plum-soft); }
tr[data-volet] { cursor: pointer; }
.consigne-volet { margin: 6px 0 10px; }
/* Sur grand écran, la liste se pousse pour ne pas passer sous le volet. */
@media (min-width: 1280px) { body.volet-ouvert main.wrap { margin-right: 440px; } }
@media (max-width: 900px) {
  .volet { width: 100%; border-left: 0; box-shadow: none; }
  .volet-fermer { width: 44px; height: 44px; }
}

/* Le bloc « Échanges et rendez-vous » de la fiche. */
.prochain-contact { margin: 0 0 6px; font-size: 16px; font-weight: 600; }
.bloc-rdv:not(:empty) { margin-top: 16px; }
.bloc-rdv h3 { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.bloc-journal { margin-top: 22px; }
.bloc-journal .journal { margin-top: 10px; }
.journal-echange .badge { margin-right: 4px; }

/* Le numéro de facture, saisi au moment de marquer la vente facturée. */
.champ-numero { width: 8.5rem; font-size: 13px; padding: 4px 8px; }

.avancement { display: flex; align-items: center; gap: 7px; }

/* Ce qui ne se montre que d'un côté de 700 px (17.8 : l'accueil, l'agenda).
   Ces classes ne font que **cacher** : ailleurs, l'élément garde son affichage. */
@media (min-width: 701px) { .seulement-tel-700 { display: none !important; } }
@media (max-width: 700px) { .seulement-bureau-700 { display: none !important; } }

/* L'accueil (17.8) : deux tiers pour ce qui attend, un tiers pour le journal
   et les parties dès 900 px ; l'un sous l'autre en dessous. */
.accueil-grille { display: grid; grid-template-columns: 1fr; gap: 0 18px; margin: 16px 0; align-items: start; }
.accueil-grille .panel { margin: 0 0 16px; }
@media (min-width: 900px) {
  .accueil-grille { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
}

/* Une rangée sobre : l'étiquette en petites capitales, le titre et son
   sous-titre, la date à droite, puis le geste. */
.rangees { list-style: none; margin: 6px 0 0; padding: 0; }
.rangee {
  display: grid; grid-template-columns: 9rem minmax(0, 1fr) auto auto;
  align-items: center; gap: 4px 14px; padding: 10px 0; border-top: 1px solid var(--line);
}
.rangee:first-child { border-top: 0; }
.rangee-etiquette { font-size: 13px; font-weight: 700; text-transform: none; letter-spacing: 0; color: var(--etiquette); }
.rangee-titre { font-weight: 600; color: var(--ink); overflow-wrap: anywhere; }
.rangee-texte .sub { font-size: 13.5px; overflow-wrap: anywhere; }
.rangee-quand { font-size: 13.5px; color: var(--muted); white-space: nowrap; text-align: right; }
.rangee-geste.carte-gestes { margin-top: 0; justify-content: flex-end; }
.et-encore { margin: 10px 0 0; }

/* Les parties, en liste : le nom en lien, ses deux chiffres à la suite. */
.liste-parties { list-style: none; margin: 8px 0 0; padding: 0; }
.liste-parties li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 6px; padding: 8px 0; border-top: 1px solid var(--line); }
.liste-parties li:first-child { border-top: 0; }
.liste-parties a { font-weight: 600; }
.liste-parties span { color: var(--muted); font-size: 13.5px; }
.liste-parties span::before { content: "· "; }

/* Sur téléphone, la rangée devient une carte : l'étiquette et le retard en
   tête, le titre, puis le geste sur toute la largeur — et, pour une relance,
   « Appeler » à côté. « À compléter » se replie en une phrase. */
@media (max-width: 700px) {
  .rangee {
    grid-template-columns: minmax(0, 1fr) auto; margin-top: 10px; padding: 11px 12px;
    border: 1px solid var(--line-strong); border-radius: 0; background: var(--surface);
  }
  .rangee:first-child { border-top: 1px solid var(--line); }
  .rangee-retard { border-left: 5px solid var(--badge-rouge); }
  .rangee-etiquette { grid-column: 1; grid-row: 1; }
  .rangee-quand { grid-column: 2; grid-row: 1; }
  .rangee-texte { grid-column: 1 / -1; }
  .rangee-geste.carte-gestes { grid-column: 1 / -1; margin-top: 6px; flex-wrap: nowrap; justify-content: stretch; }
  .rangee-geste > * { flex: 1 1 auto; }
  .rangee-geste .btn { width: 100%; min-height: 46px; font-size: 14px; }
  .rangee-geste > .rangee-appel { flex: 0 0 auto; width: auto; padding-left: 16px; padding-right: 16px; }
  .panneau-rangees { padding: 14px 14px 16px; }
  .completer-tel > summary { flex-direction: column; align-items: stretch; gap: 4px; font-size: 17px; }
  .completer-tel > summary::before { display: none; }
  .completer-tel-apercu { font-family: var(--font-body); font-size: 14px; color: var(--muted); }
}

/* Une vente annulée reste lisible, mais s'efface visuellement : elle ne
   compte plus nulle part, et la ligne doit le dire au premier coup d'œil. */
.ligne-annulee { opacity: 0.55; }
.ligne-annulee .cell-nom a { text-decoration: line-through; }

/* Onglets d'une même partie : consulter d'un côté, saisir de l'autre. */
.onglets { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 18px; }
/* 18.6 : des intitulés en capitales espacées, sans fond ni cadre ; l'actif à
   l'encre, souligné d'un filet. Les boutons posés dans la barre (« + Prospect »)
   restent des boutons. */
.onglets a:not(.btn) {
  padding: 9px 18px; border-radius: 0; border: 1px solid transparent;
  background: none; color: var(--muted);
  font-family: var(--font-display); font-weight: 400; font-size: 14px; text-transform: none; letter-spacing: 0;
  text-decoration: none;
}
/* Les onglets d'une partie gardent les capitales espacées du site (18.8). */
.onglets-partie a:not(.btn) { text-transform: uppercase; letter-spacing: .16em; }
.onglets a:not(.btn):hover { color: var(--ink); }
.onglets a.on:not(.btn) { color: var(--ink); text-decoration: underline; text-decoration-color: var(--ink);
  text-decoration-thickness: 1px; text-underline-offset: 7px; }
/* Sur téléphone (17.8), les onglets d'une partie et les blocs d'une fiche
   millésime tiennent sur **une seule rangée** qui défile au doigt : pas de
   barre de défilement, et un fondu au bord droit pour dire qu'il y a la suite.
   Le fondu est un dernier élément collé au bord (`sticky`) : en fin de
   défilement, il n'est plus qu'une marge après le dernier bouton. */
@media (max-width: 700px) {
  .onglets-partie, .ancres {
    flex-wrap: nowrap; overflow-x: auto; white-space: nowrap;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .onglets-partie::-webkit-scrollbar, .ancres::-webkit-scrollbar { display: none; }
  .onglets-partie > *, .ancres > * { flex: 0 0 auto; }
  .onglets-partie a { padding: 8px 14px; }
  .onglets-partie .onglets-action { margin-left: 4px; }
  .onglets-partie::after, .ancres::after {
    content: ""; position: sticky; right: 0; flex: 0 0 28px; margin-left: -8px;
    background: linear-gradient(to right, transparent, var(--bg)); pointer-events: none;
  }
}
/* ---------------------------------------------------------------------------
   La saisie guidée d'une dépense : un bloc par question, dans l'ordre où l'on
   y répond une facture en main. Sur téléphone, un bloc occupe l'écran.
   --------------------------------------------------------------------------- */
.saisie-etapes .bloc-saisie {
  border: none; border-top: 1px solid var(--line);
  margin: 0; padding: 18px 0 4px;
}
.saisie-etapes .bloc-saisie:first-of-type { border-top: none; padding-top: 4px; }
.saisie-etapes legend {
  padding: 0; font-family: var(--font-display); font-size: 17px; font-weight: 500;
}
.actions-saisie { border-top: 1px solid var(--line); padding-top: 16px; margin-top: 8px; }

/* Le choix du type : trois grands boutons, un seul actif. */
.choix-large { display: flex; flex-wrap: wrap; gap: 10px; margin: 10px 0 4px; }
.choix-large .choix {
  flex: 1 1 200px; margin: 0; cursor: pointer;
  padding: 12px 14px; border: 1px solid var(--line-strong); border-radius: 0;
  background: var(--surface); display: block;
  /* 17.5 : le parent de l'input caché, sans quoi il se place par rapport à la page. */
  position: relative;
}
.choix-large .choix:hover { border-color: var(--plum); }
/* Un pixel de large et de haut : sans cela, l'input caché garde le `width: 100%`
   des champs et élargit la page (17.5). */
.choix-large .choix input { position: absolute; left: 0; top: 0; width: 1px; height: 1px; margin: 0; padding: 0; opacity: 0; pointer-events: none; }
.choix-large .choix-titre { display: block; font-weight: 600; }
.choix-large .choix-sous { display: block; font-size: 13px; color: var(--muted); margin-top: 2px; }
.choix-large .choix-actif { border-color: var(--plum); background: var(--plum-soft); }
.choix-large .choix-actif .choix-titre { color: var(--plum-ink); }

/* Les pastilles : étape, cible, IVA, paiement. Un tap, pas un menu déroulant. */
.ligne-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 10px 0; }
.chips-titre { font-size: 13px; color: var(--etiquette); text-transform: none; letter-spacing: 0; font-weight: 700; }
.chip {
  margin: 0; cursor: pointer; white-space: nowrap;
  padding: 7px 13px; border: 1px solid var(--line-strong); border-radius: 0;
  background: var(--surface); font-family: var(--font-body); font-size: 13px; font-weight: 600;
  text-transform: none; letter-spacing: 0;
  position: relative;
}
.chip:hover { border-color: var(--plum); }
/* Une chip qui est un lien (les raccourcis de période de l'export, 16.8). */
a.chip { display: inline-block; color: inherit; text-decoration: none; }
a.chip.chip-actif { color: var(--on-plum); }
.export-signal { color: var(--ambre); font-weight: 600; margin-top: 4px; }
.chip input { position: absolute; left: 0; top: 0; width: 1px; height: 1px; margin: 0; padding: 0; opacity: 0; pointer-events: none; }
.chip-actif { background: var(--plum-bg); border-color: var(--plum-bg); color: var(--on-plum); }
/* 17.8 : la pastille suit sa case même sans script, là où le navigateur
   connaît `:has()` ; ailleurs, la classe posée par le serveur et le script. */
.chip:has(input:checked) { background: var(--plum-bg); border-color: var(--plum-bg); color: var(--on-plum); }
.chip.chip-actif:has(input:not(:checked)) { background: var(--surface); border-color: var(--line-strong); color: inherit; }
.chip:has(input:focus-visible) { outline: 2px solid var(--plum); outline-offset: 2px; }
.chip-champ { margin: 0; font-size: 12px; color: var(--muted); }
.chip-champ input { font-size: 14px; max-width: 150px; }
.chips-repli { display: inline-block; }
.chips-repli summary { cursor: pointer; font-size: 14px; color: var(--muted); padding: 7px 4px; }
.chips-repli[open] { display: block; width: 100%; }
.chips-repli[open] summary { margin-bottom: 6px; }
.pour-cible { margin-top: 12px; }
/* Une aide alignée sur la ligne du champ qu'elle explique. */
.hint-aligne { align-self: end; margin: 0 0 8px; }
/* Les lots d'une facture de tonnellerie : une ligne par format. */
.lots-barriques td { padding: 6px 8px; }
.lots-barriques input { width: 100%; }
.lots-barriques th { font-size: 12px; }
.pour-cible > label { max-width: 420px; }

/* Un `<span class="pour-type">` n'enveloppe que pour grouper : il s'efface de
   la grille, sinon ses champs compteraient pour une seule colonne.
   **Le sélecteur vise `span` et rien d'autre** : posé sur un `<label>`, il
   séparerait son intitulé de son champ, chacun dans une cellule différente. */
.form-grid > span.pour-type { display: contents; }

@media (max-width: 700px) {
  .choix-large .choix { flex-basis: 100%; }
  .chip { flex: 1 1 auto; text-align: center; }
}

/* Le bandeau de série : ce qui vient d'être enregistré, et où en est la pile. */
.bandeau-serie {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 10px; margin: 0 0 14px; padding: 10px 14px;
  background: var(--vert-soft); border: 1px solid var(--vert-bord);
  border-radius: 0; font-size: 14px; color: var(--vert);
}
.bandeau-serie a { color: var(--vert); text-decoration: underline; margin-left: 6px; }
.serie-compte { font-size: 13px; white-space: nowrap; }

/* Un repli à l'intérieur d'un formulaire : les champs du nouvel article. */
.sous-bloc { margin-top: 16px; padding: 14px 16px; border: 1px solid var(--line-strong); border-radius: 0; background: var(--bg); }
.sous-bloc h3 { margin-top: 0; }
[hidden] { display: none !important; }
.narrow-form { max-width: 480px; }
.narrow-form label { margin-bottom: 12px; }
.valeurs { list-style: none; padding: 0; margin: 12px 0 0; }
.valeurs li { display: flex; justify-content: space-between; align-items: center; padding: 8px 0; border-top: 1px solid var(--line); }

/* ---------------------------------------------------------------------------
   Production : « Au chai cette semaine ». Une liste plutôt qu'un tableau —
   trois colonnes tiennent au pouce, dix non — et le geste à droite.
   --------------------------------------------------------------------------- */
.liste-chai { list-style: none; padding: 0; margin: 0; }
.liste-chai li {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 0; border-top: 1px solid var(--line);
}
.chai-date { flex: 0 0 88px; font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }
.chai-retard { color: var(--rouge); font-weight: 600; }
.chai-quoi { flex: 1 1 auto; min-width: 0; }
.chai-quoi .sub { display: block; color: var(--muted); font-size: 13px; }
.liste-chai .btn { flex: 0 0 auto; }
/* Sélection multiple et actions groupées. La case doit se viser au pouce :
   c'est le label qui porte la cible, pas la case elle-même. */
.coche-lot {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto; padding: 6px; margin: -6px; cursor: pointer;
}
/* 19.2 : une colonne de 44 px, la case au milieu, 18 px, à l'encre. */
.coche-lot input { width: 18px; height: 18px; margin: 0; accent-color: var(--ink); cursor: pointer; }
td.cell-coche, th.cell-coche { width: 44px; padding: 0; text-align: center; }
/* Un intitulé que seuls les lecteurs d'écran lisent : une colonne de cases à
   cocher n'a pas de titre à montrer, mais elle en a un à dire. */
.visuellement-cache {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
/* Un groupe de millésimes : resserré, pour qu'une liste de dix cuvées tienne
   à l'écran. Le titre du groupe est le nom de la cuvée. */
/* « Citrinitas — millésime 2024 » : la cuvée porte le titre, l'année le suit
   en retrait. Deux choses, deux poids. */
.titre-millesime { font-size: 0.62em; font-weight: 400; color: var(--muted); white-space: nowrap; }
.autres-millesimes a, .autres-millesimes strong { margin-right: 6px; }
.autres-millesimes strong { color: var(--plum); }
.groupe-cuvee { margin-bottom: 12px; }
/* Le stock sec et les barriques (15.9) : une ligne de compte en tête, puis un
   panneau par groupe. */
.ligne-compte { margin: 4px 0 14px; color: var(--muted); }
.texte-rouge { color: var(--rouge); }
/* Dans le résumé d'un bloc ou dans un tableau, une alerte se lit en gras (19.1). */
summary .texte-rouge, td .texte-rouge, .valeur-alerte { color: var(--rouge); font-weight: 700; }
.groupe-stock { margin-bottom: 12px; }
.groupe-stock h2 { margin-bottom: 6px; }
.groupe-cuvee .panel-titre { align-items: flex-start; }
.groupe-cuvee h2 { margin: 0; }
.groupe-cuvee .panel-titre .hint { margin: 2px 0 0; }
/* Les deux trous de suivi du chai, en une ligne chacun sous la semaine. */
.trou-suivi { margin: 10px 0 0; }

/* Préparer l'année (15.8) : une carte par vin, ses dates sur une grille, chacune
   corrigeable avant de créer. */
.carte-vin { margin-bottom: 12px; }
.carte-vin-tete { display: flex; align-items: center; gap: 10px; flex-direction: row; font-size: 16px; cursor: pointer; }
.carte-vin-tete input { width: 18px; height: 18px; accent-color: var(--plum); }
.grille-dates {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 10px 14px; margin: 14px 0 6px;
}
.grille-dates label { font-size: 13px; }
.ligne-volume { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 10px 0 0; }
.ligne-volume label { flex-direction: row; align-items: center; gap: 6px; }
.ligne-volume input { width: 7em; }
/* Un champ discret dans l'en-tête : l'année à préparer, la cuvée du soufre. */
.champ-annee { display: flex; align-items: center; gap: 6px; }
.champ-annee label { flex-direction: row; align-items: center; gap: 6px; font-size: 13px; color: var(--muted); }
.champ-annee input { width: 5.5em; }
/* Le soufre : la colonne du millésime encore au chai, en retrait des années. */
.table-soufre .col-au-chai { border-left: 2px solid var(--line-strong); color: var(--muted); white-space: nowrap; font-size: 13px; }
.table-soufre th.col-au-chai .sub { display: inline; margin-left: 4px; }
.barre-lot {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px;
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line);
}
.barre-lot label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--muted); }
.barre-lot select, .barre-lot input[type="date"] { min-width: 150px; }
.barre-lot .hint { flex: 1 1 220px; }
.lot-compte { align-self: center; font-weight: 600; }
.liste-reprise { margin-top: 8px; }
.liste-reprise .chai-quoi { font-weight: 500; }

/* L'agenda client : la même liste que le chai, avec une pastille de famille
   devant la précision, et le formulaire du geste rapide replié sous la ligne. */
.liste-agenda .sub .badge { margin-right: 6px; vertical-align: baseline; }
.liste-chai li.ligne-geste { display: block; padding: 0 0 10px; border-top: 0; }
.liste-chai li.ligne-geste .form-noter { margin: 0; }
/* Un chiffre cliquable reste un chiffre : il mène à la liste qu'il compte,
   sans se déguiser en lien. */
.chiffres a.stat { color: var(--muted); }
.chiffres a.stat:hover { text-decoration: none; }
.chiffres a.stat:hover b { color: var(--plum); }

/* ---------------------------------------------------------------------------
   L'agenda : sept colonnes sur un écran, sept blocs empilés sur un téléphone.
   Chaque jour est un <details> : ouvert s'il porte quelque chose ou si c'est
   aujourd'hui, replié sinon — un jour vide n'a rien à montrer.
   --------------------------------------------------------------------------- */
/* 19.2 : `minmax(0, 1fr)` — sept colonnes égales, même quand le détail d'une
   carte, sur une ligne, est plus long que la sienne. */
.semaine { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 10px; align-items: start; }
.jour {
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: 0; padding: 10px; min-height: 90px;
}
.jour > summary {
  display: flex; align-items: baseline; gap: 6px; cursor: pointer;
  font-size: 13px; color: var(--muted); list-style: none;
}
.jour > summary::-webkit-details-marker { display: none; }
.jour-nom { text-transform: capitalize; }
.jour-num { font-size: 18px; font-weight: 600; color: var(--ink); font-family: var(--font-display); }
.jour-nb {
  margin-left: auto; background: var(--gris-soft); color: var(--muted);
  border-radius: 0; padding: 0 7px; font-size: 12px; font-weight: 600;
}
.jour-aujourdhui { border-color: var(--plum); box-shadow: 0 0 0 1px var(--plum); }
.jour-aujourdhui .jour-num { color: var(--plum); }
.jour-vide { margin: 8px 0 0; font-size: 13px; }
.jour-plus {
  display: block; margin-top: 8px; text-align: center; color: var(--muted);
  border: 1px dashed var(--line-strong); border-radius: 0; padding: 2px;
}
.jour-plus:hover { color: var(--plum); border-color: var(--plum); text-decoration: none; }

.carte-jour {
  margin-top: 8px; padding: 8px 9px; border-radius: 0;
  border-left: 5px solid var(--line-strong); background: var(--zebra-doux);
  display: flex; flex-direction: column; gap: 2px;
}
.carte-jour.carte-vert { border-left-color: var(--badge-vert); }
.carte-jour.carte-bleu { border-left-color: var(--badge-bleu); }
.carte-jour.carte-bleu-clair { border-left-color: var(--bleu-clair-bord); }
.carte-jour.carte-prune { border-left-color: var(--prune-etat-bord); }
.carte-jour.carte-ambre { border-left-color: var(--badge-ambre); }
.carte-jour.carte-rouge { border-left-color: var(--badge-rouge); }
/* Rendez-vous et visites : la couleur de leur pastille. Elle manquait — la
   famille Visite tombait sur la bordure grise par défaut. */
.carte-jour.carte-ambre-fort { border-left-color: var(--badge-ambre); }
.carte-heure { font-weight: 700; font-size: 14px; color: var(--ambre-fort); font-variant-numeric: tabular-nums; }
.carte-retard { background: var(--rouge-soft); }
.carte-famille { font-size: 12.5px; font-weight: 700; text-transform: none; letter-spacing: 0; color: var(--etiquette); }
.carte-titre { font-weight: 600; color: var(--ink); overflow-wrap: anywhere; }
.carte-sous { font-size: 13.5px; color: var(--muted); overflow-wrap: anywhere; }
.carte-gestes { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 6px; }
.carte-gestes .btn { padding: 4px 9px; font-size: 12.5px; }
.reporter > summary { cursor: pointer; font-size: 12.5px; color: var(--muted); }
.reporter form { display: flex; gap: 5px; margin-top: 5px; }
.reporter input[type="date"] { font-size: 12.5px; padding: 4px 6px; }

.chip-famille { flex-direction: row; align-items: center; gap: 5px; }
/* Les familles de l'agenda en pastilles (17.8) : un point de leur couleur. */
.point-famille { display: inline-block; flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: var(--line-strong); }
.point-vert { background: var(--badge-vert); }
.point-bleu { background: var(--badge-bleu); }
.point-bleu-clair { background: var(--bleu-clair-bord); }
.point-prune { background: var(--prune-etat-bord); }
.point-ambre { background: var(--badge-ambre); }
.point-ambre-fort { background: var(--badge-ambre); }
.point-rouge { background: var(--badge-rouge); }
.chip-actif .point-famille { box-shadow: 0 0 0 2px var(--on-plum); }

/* Les Réglages sur ordinateur (17.8) : le menu à gauche, l'entrée courante
   surlignée ; le contenu prend toute la largeur restante. En dessous de
   900 px, le menu redevient la rangée de pastilles. */
@media (min-width: 900px) {
  main.menu-lateral { display: grid; grid-template-columns: 210px minmax(0, 1fr); column-gap: 32px; row-gap: 0; align-content: start; }
  main.menu-lateral > * { grid-column: 2; min-width: 0; }
  main.menu-lateral > .onglets-reglages {
    grid-column: 1; grid-row: 1 / span 30; align-self: start;
    position: sticky; top: 94px; flex-direction: column; flex-wrap: nowrap; gap: 2px; margin: 24px 0 0;
  }
  main.menu-lateral > .onglets-reglages a { border: 0; border-radius: 0; background: none; padding: 9px 12px; }
  main.menu-lateral > .onglets-reglages a:hover { background: var(--zebra-doux); }
  main.menu-lateral > .onglets-reglages a.on { background: var(--plum-soft); color: var(--plum-ink); }
  main.menu-lateral .narrow-form { max-width: none; }
}
/* Le formulaire Entreprise sur deux colonnes : Raison sociale | NIF,
   Téléphone | Courriel ; le reste sur toute la largeur. */
.form-entreprise { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; }
.form-entreprise > .large { grid-column: 1 / -1; }
@media (max-width: 640px) { .form-entreprise { grid-template-columns: 1fr; } }

/* L'aperçu de l'export comptable (17.8) : à chasse fixe, comme le fichier. */
.apercu-export h3 { margin: 14px 0 6px; }
.table-mono { border-collapse: collapse; width: 100%; }
.table-mono th, .table-mono td { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12.5px; padding: 5px 10px 5px 0; text-align: left; }
.table-mono th { font-family: var(--font-body); font-size: 12.5px; font-weight: 700; color: var(--etiquette); text-transform: none; letter-spacing: 0; }
.table-mono td { border-top: 1px solid var(--line); }
.table-mono .num { text-align: right; }
.table-mono th:last-child, .table-mono td:last-child { padding-left: 16px; }

/* « Zone, type ▾ » (17.8) : au bout de la ligne de recherche, il déplie le
   panneau des filtres rares, dont le titre s'efface. */
.bouton-repli { margin-left: auto; }
.bouton-repli.on { border-color: var(--plum); color: var(--plum); }
.filtres-pliant.pilote > summary { display: none; }
.filtres-pliant.pilote:not([open]) { display: none; }
.filtres-pliant.pilote > summary + *, .filtres-pliant.pilote .form-grid { margin-top: 0; }
.filtres-pliant.pilote { margin-top: 8px; }

/* La vue d'un jour, sur téléphone (17.8) : l'en-tête du jour, les filtres
   repliés, la bande des sept jours, puis le seul jour choisi. */
.jour-tel-tete { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 16px 0 4px; }
.jour-tel-titre { margin: 0; font-size: 26px; }
.jour-tel-resume { margin: 4px 0 0; }
.jour-tel-tete .btn { flex: 0 0 auto; }
.filtres-tel { margin: 8px 0 4px; }
.filtres-tel-ligne { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.filtres-tel .filtre-tournee { flex-direction: row; align-items: center; gap: 6px; font-size: 14px; }
.filtres-repli > summary {
  cursor: pointer; list-style: none; padding: 7px 13px; font-size: 14px; color: var(--muted);
  border: 1px solid var(--line-strong); border-radius: 0; background: var(--surface);
}
.filtres-repli > summary::-webkit-details-marker { display: none; }
.filtres-repli[open] { flex-basis: 100%; }
.filtres-repli[open] > summary { display: inline-block; }
.bande-jours { display: flex; align-items: stretch; gap: 2px; margin: 10px 0 2px; }
.bande-jour {
  flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 6px 0 5px; border-radius: 0; color: var(--muted);
}
.bande-jour:hover { text-decoration: none; background: var(--zebra-doux); }
.bande-nom { font-size: 12px; }
.bande-num { font-size: 17px; font-weight: 600; line-height: 1.1; color: var(--ink); font-family: var(--font-display); }
.bande-auj .bande-num { color: var(--plum); }
.bande-point { width: 5px; height: 5px; border-radius: 50%; }
.bande-point.plein { background: var(--plum); }
.bande-jour.on, .bande-jour.on:hover { background: var(--plum-bg); color: var(--on-plum); }
.bande-jour.on .bande-num { color: var(--on-plum); }
.bande-jour.on .bande-point.plein { background: var(--on-plum); }
.bande-fleche { flex: 0 0 26px; display: flex; align-items: center; justify-content: center; font-size: 22px; color: var(--muted); }
.bande-fleche:hover { text-decoration: none; color: var(--plum); }
.jour-tel-liens { margin: 2px 0 6px; text-align: center; }
.carte-apercu { opacity: .85; }
@media (max-width: 700px) {
  .semaine .jour:not(.jour-choisi) { display: none; }
  .semaine .jour.jour-choisi { border: 0; box-shadow: none; background: none; padding: 0; }
  .semaine .jour.jour-choisi > summary { display: none; }
  .semaine .jour-sous-titre { margin-top: 16px; font-weight: 600; }
  .semaine .jour-plus { display: none; }
}

/* La grille du mois : où la charge se concentre, pas où l'on travaille. */
.grille-mois { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.mois-entete { font-size: 12px; color: var(--muted); text-align: center; padding-bottom: 4px; }
.mois-vide { min-height: 56px; }
.mois-jour {
  min-height: 56px; border: 1px solid var(--line); border-radius: 0; padding: 6px;
  display: flex; flex-direction: column; align-items: flex-start; color: var(--ink);
}
.mois-jour:hover { border-color: var(--plum); text-decoration: none; }
.mois-numero { font-size: 13px; color: var(--muted); }
.mois-nb { margin-top: auto; font-weight: 600; font-size: 17px; color: var(--plum); }
/* « 1 rdv · 2 tâches » : plus long qu'un chiffre, il doit tenir dans un
   septième d'écran de téléphone — d'où la petite taille et le retour à la ligne. */
.mois-resume { margin-top: auto; font-weight: 600; font-size: 12px; line-height: 1.25; color: var(--plum); overflow-wrap: anywhere; }
/* Aujourd'hui dit aussi ce qui traîne (15.3). */
.mois-retard { font-weight: 600; font-size: 12px; line-height: 1.25; color: var(--rouge); }

/* La semaine lisible d'un coup d'œil (15.3) : l'étiquette d'une ligne en
   retard en rouge, un sous-titre entre les rendez-vous et le reste. */
.etiquette-retard { color: var(--rouge); font-weight: 600; }
.jour-sous-titre { margin: 10px 0 0; font-size: 12.5px; font-weight: 700; text-transform: none; letter-spacing: 0; color: var(--etiquette); }
.jour-auj { font-size: 12px; color: var(--plum); font-weight: 600; }
.filtres-tout { margin: 6px 2px 0; }
.retards-ailleurs { padding: 10px 14px; }
.retards-ailleurs a { color: var(--rouge); }

/* Le bloc Rendez-vous d'une fiche. */
.rdv-libelle { margin: 0 0 4px; font-size: 16px; }
.rdv-objet { margin: 0 0 4px; }
.rdv-gestes { flex-wrap: wrap; gap: 8px; }
.rdv-gestes input[type="date"] { width: auto; }
.mois-calme { background: var(--zebra-doux); }
.mois-aujourdhui { border-color: var(--plum); box-shadow: 0 0 0 1px var(--plum); }

@media (max-width: 900px) {
  .semaine { grid-template-columns: minmax(0, 1fr); }
  .jour { min-height: 0; }
}

/* Imprimer la semaine, **un jour après l'autre** (15.3) : sept colonnes de
   papier étaient trop étroites pour une ligne de rendez-vous. Une ou deux
   pages, sans les boutons ni le volet. */
@media print {
  .topbar, .footer, .no-print, .filters, .flash, .volet, .carte-gestes, .reporter, .onglets-partie,
  .barre-tel, .feuille-bas { display: none !important; }
  body { padding-bottom: 0 !important; }
  body { background: #fff; font-size: 11px; }
  .wrap { max-width: none; padding: 0; }
  .semaine { grid-template-columns: 1fr; gap: 4px; }
  .jour { border-color: #999; padding: 5px 8px; min-height: 0; break-inside: avoid; }
  .jour > summary { font-size: 12px; }
  .etiquette-retard { color: #000; text-decoration: underline; }
  /* Un <details> replié cacherait la moitié de la semaine sur le papier. */
  /* `:not(.no-print)` : sans lui, cette règle venue après `.no-print`
     l'emportait, et le « + » de chaque jour s'imprimait. */
  .jour > *:not(.no-print), .carte-jour { display: block !important; }
  .carte-jour { background: none; border-left-width: 2px; padding: 3px 0 3px 6px; }
  .display { font-size: 18px; }
  /* 18.6 : sur le papier, les titres gardent leur casse d'avant. */
  .display, h2 { text-transform: none; letter-spacing: normal; }
  a { color: #000; text-decoration: none; }
}

/* Le bouton de création vit dans la barre d'onglets, à droite : une seule
   entrée pour une seule action, à la même place sur les trois pages. */
.onglets-action { margin-left: auto; }

/* Un en-tête de colonne qui trie. Le menu « Trier par » était au fond des
   filtres repliés : personne ne l'y trouvait. */
.tri-entete { color: inherit; }
.tri-entete:hover { color: var(--plum); }
.tri-actif { color: var(--plum); font-weight: 700; }
.tri-actif::after { content: ' ▾'; font-size: 12px; }
.interet-points { color: var(--ambre-fort); font-size: 12px; letter-spacing: 1px; margin-left: 5px; }
.cell-urgence .sub { display: block; }
/* Un panneau qui ne demande rien : les gestes rares, en bas de fiche. */
.panel-discret { background: none; border-style: dashed; }
.actions-rares { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.actions-rares .hint { flex: 1 1 200px; }
.ligne-choix .ligne-chips { margin: 2px 0 0; }

/* ---------------------------------------------------------------------------
   Au doigt, un tableau devient une pile de cartes.
   Une ligne amputée de ses colonnes cachées ne dit plus rien : on la déplie.
   Le HTML ne change pas — `data-label` porte l'intitulé, le CSS fait le reste.
   --------------------------------------------------------------------------- */
@media (max-width: 640px) {
  .table-cartes thead { display: none; }
  .table-cartes, .table-cartes tbody, .table-cartes tr, .table-cartes td { display: block; width: auto; }
  .table-cartes tr {
    background: var(--surface); border: 1px solid var(--line-strong);
    border-radius: 0; padding: 10px 12px; margin-bottom: 10px;
  }
  .table-cartes tr::before { display: none; }
  .table-cartes td { border: 0; padding: 2px 0; }
  /* L'intitulé devant la valeur, sauf là où la valeur se suffit. */
  .table-cartes td[data-label]::before {
    content: attr(data-label) ' · '; color: var(--etiquette); font-size: 12.5px; font-weight: 700;
  }
  .table-cartes td.cell-nom::before, .table-cartes td[data-label="Où on en est"]::before,
  .table-cartes td.cell-urgence::before { content: none; }
  .table-cartes td.cell-nom { font-size: 16px; order: -1; }
  .table-cartes td.num { text-align: left; }
  .table-cartes td.cell-coche { display: none; }
  /* Le geste rapide sous le pouce : pleine largeur, en bas de la carte. */
  .table-cartes td.col-action { margin-top: 8px; }
  .table-cartes td.col-action .btn, .table-cartes td.col-action form { width: 100%; }
  .table-cartes .ligne-noter { padding: 0; border: 0; background: none; }
}

/* Les lignes de vente en cartes : les champs prennent toute la largeur, sinon
   un `select` de millésime se retrouve à 60 px. */
@media (max-width: 640px) {
  .table-cartes.lignes-commande td input,
  .table-cartes.lignes-commande td select { width: 100%; }
  .table-cartes.lignes-commande tr { padding-bottom: 14px; }
}

/* Le geste d'une ligne du tableau de bord Vente : les boutons et la date de
   report tiennent sur une ligne, et passent à la ligne sur téléphone. */
.geste-vente { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-left: auto; }
.geste-vente form { display: flex; align-items: center; gap: 4px; }
.geste-vente input[type="date"] { padding: 5px 7px; font-size: 13px; }
@media (max-width: 700px) {
  .geste-vente { width: 100%; margin-left: 0; }
}

.onglet-nb { font-weight: 400; color: var(--muted); font-size: 13px; margin-left: 4px; }
.onglets a.on .onglet-nb { color: var(--muted); }
.onglet-nb { font-family: var(--font-body); letter-spacing: 0; text-transform: none; }
@media (max-width: 700px) {
  .chai-date { flex-basis: 70px; font-size: 12px; }
}

/* Le fil d'activité de l'accueil : une ligne par geste, groupée par journée.
   L'heure et l'auteur encadrent, le contenu occupe le milieu. */
/* Importer une liste (18.1) : les trois écrans, la correspondance, l'aperçu. */
.etapes-import { display: flex; flex-wrap: wrap; gap: 6px 18px; list-style: none; margin: 0 0 12px; padding: 0; font-size: 14px; color: var(--muted); }
.etapes-import .courante { color: var(--plum-ink); font-weight: 600; }
.etapes-import .faite::before { content: "✓ "; color: var(--vert); }
.table-correspondance select { min-width: 210px; }
.table-correspondance td.hint { font-size: 13px; max-width: 360px; overflow-wrap: anywhere; }
.table-apercu-import .sub { max-width: 420px; overflow-wrap: anywhere; }

.fil-jour {
  margin: 18px 0 6px; font-size: 13px; font-weight: 700;
  text-transform: none; letter-spacing: 0; color: var(--etiquette);
}
.fil-jour:first-of-type { margin-top: 4px; }
.fil-liste { list-style: none; padding: 0; margin: 0; }
.fil-liste li {
  display: flex; align-items: baseline; gap: 10px;
  padding: 7px 0; border-top: 1px solid var(--line);
}
.fil-heure { color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; min-width: 42px; }
.fil-liste .badge { flex: 0 0 auto; }
.fil-texte { flex: 1 1 auto; min-width: 0; }
.fil-texte .sub { display: block; color: var(--muted); font-size: 13px; }
.fil-qui { color: var(--muted); font-size: 13px; white-space: nowrap; }
@media (max-width: 700px) {
  /* Sur téléphone, l'auteur passe sous le texte plutôt que de l'écraser. */
  .fil-liste li { flex-wrap: wrap; }
  .fil-texte { flex-basis: 100%; order: 3; padding-left: 52px; }
  .fil-qui { margin-left: auto; }
}

/* ---------------------------------------------------------------------------
   Le bon de livraison. À l'écran c'est un aperçu de la feuille ; à l'impression
   c'est la feuille elle-même, et tout le reste disparaît.
   --------------------------------------------------------------------------- */
.feuille {
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: 0;
  padding: 32px 34px; max-width: 820px; margin: 0 auto;
}
.feuille p { margin: 0 0 2px; }
.feuille-tete { display: flex; justify-content: space-between; gap: 28px; flex-wrap: wrap; }
.feuille-emetteur { font-size: 14px; line-height: 1.5; }
.feuille-titre { text-align: right; font-size: 14px; }
.feuille-titre h2 { margin: 0 0 4px; }
.feuille-ref { font-weight: 700; font-size: 17px; margin-bottom: 8px !important; }
.feuille-nom { font-weight: 700; font-size: 16px; }
.feuille-etiquette {
  text-transform: none; letter-spacing: 0; font-size: 12.5px;
  font-weight: 700; color: var(--etiquette); margin-bottom: 4px !important;
}
.feuille-destinataire {
  margin: 30px 0 24px; padding: 14px 16px;
  border: 1px solid var(--line); border-radius: 0; font-size: 14px; line-height: 1.5;
}
.feuille-lignes { width: 100%; border-collapse: collapse; font-size: 14px; }
.feuille-lignes th, .feuille-lignes td { padding: 9px 10px; text-align: left; }
.feuille-lignes thead th { border-bottom: 2px solid var(--ink); font-size: 12.5px; text-transform: none; letter-spacing: 0; }
.feuille-lignes tbody td { border-bottom: 1px solid var(--line); }
.feuille-lignes tfoot th, .feuille-lignes tfoot td { border-top: 1px solid var(--line); font-weight: 600; }
.feuille-lignes tfoot tr:first-child th { border-top: 2px solid var(--ink); }
.feuille-lignes .num { text-align: right; }
.feuille-notes { margin-top: 22px; font-size: 14px; }
.feuille-signatures { display: flex; gap: 24px; margin-top: 34px; }
.feuille-signatures > div { flex: 1; }
.feuille-cadre { height: 62px; border: 1px solid var(--line-strong); border-radius: 0; }

/* Plusieurs bons à la suite : une page chacun. `page-break-before` plutôt que
   `after` — le dernier bon ne doit pas entraîner une page blanche. */
.feuille + .feuille { page-break-before: always; break-before: page; margin-top: 28px; }

/* La feuille de préparation : ce qu'on emporte au chai, puis chez le client. */
.prepa-sous { color: var(--muted); font-size: 13px; }
.prepa-table { margin-bottom: 18px; }
.prepa-client { border-top: 1px solid var(--line); padding: 10px 0; break-inside: avoid; page-break-inside: avoid; }
.prepa-client-tete { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; font-size: 15px; }
.prepa-client-tete span { color: var(--muted); font-size: 13px; }
.prepa-lignes { margin: 6px 0 0; padding-left: 20px; font-size: 14px; }
.prepa-lignes li { margin-bottom: 2px; }
.prepa-note { margin-top: 6px; font-size: 13px; color: var(--muted); }

/* La saisie en quatre écrans, sur téléphone. `ecran-cache` masque sans
   désactiver : les champs des autres écrans sont remplis et doivent partir au
   serveur — on ne fait que ne pas les regarder. */
/* Le soufre ajouté à une étape, sous son nom dans le chai : le carnet se relit
   en lisant le parcours. */
.sub-so2 { color: var(--ambre); font-weight: 600; }

/* La comparaison du soufre : étapes en lignes, millésimes en colonnes. */
.bloc-soufre { break-inside: avoid; page-break-inside: avoid; }
.table-soufre tfoot th, .table-soufre tfoot td { border-top: 1px solid var(--line); }
.table-soufre tfoot .ligne-total th, .table-soufre tfoot .ligne-total td {
  border-top: 2px solid var(--ink); font-weight: 700;
}
@media print {
  .bloc-soufre { border: 0; padding: 0; margin-bottom: 24px; }
}
.sub-so2:hover { text-decoration: underline; }

/* Les marques verticales des sulfitages sur la courbe du SO₂ libre. */
.courbe .marque-so2 { stroke: var(--badge-ambre); stroke-width: 2; }
.courbe .dose-so2 { fill: var(--ambre); font-weight: 700; font-family: var(--font-body); }

.ecran-cache { display: none; }

/* Le titre d'un mois dans la liste des dépenses, avec son sous-total. */
.titre-mois th {
  background: var(--zebra-doux); font-size: 13px; font-weight: 700;
  text-transform: none; letter-spacing: 0; color: var(--etiquette);
  padding-top: 14px;
}
.titre-mois .sub { display: inline; margin-left: 10px; text-transform: none; letter-spacing: 0; }
.barre-ecrans { margin: 0 0 14px; }
.barre-ecrans-titre {
  display: block; margin-bottom: 6px; font-size: 13px; font-weight: 700;
  text-transform: none; letter-spacing: 0; color: var(--etiquette);
}
.nav-ecrans { display: flex; justify-content: space-between; gap: 10px; margin-top: 16px; }
.nav-ecrans .btn { flex: 1; }

/* Le détail sous une étape de dépense : en retrait, plus léger — c'est ce qui
   compose la ligne du dessus, pas une ligne de plus. */
.ligne-detail td { padding-top: 3px; padding-bottom: 3px; color: var(--muted); font-size: 13.5px; }
.ligne-detail .sous-etape { padding-left: 18px; }
.ligne-detail .sous-etape::before { content: '› '; color: var(--line-strong); }

/* ---------------------------------------------------------------------------
   « Ventes en cours » : des cartes, une par vente, dans la section de son
   prochain geste. Un seul bouton visible ; le reste dans le menu « … ».
   Cinq boutons par ligne, c'était illisible au pouce.
   --------------------------------------------------------------------------- */
.cols-ventes { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; align-items: start; }
@media (max-width: 900px) { .cols-ventes { grid-template-columns: 1fr; } }
.section-vente { margin-bottom: 14px; }

.cartes-ventes { list-style: none; padding: 0; margin: 0; }
.carte-vente {
  border: 1px solid var(--line-strong); border-radius: 0;
  padding: 10px 12px; margin-bottom: 8px; background: var(--surface);
}
.carte-vente.carte-retard { border-left: 3px solid var(--rouge); }
.carte-vente.carte-ambre { border-left: 3px solid var(--ambre); }
.carte-tete { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.carte-tete a { font-weight: 600; }
.carte-contenu { margin: 4px 0 8px; font-size: 14px; line-height: 1.45; }
.carte-contenu .sub { display: block; }
.carte-gestes { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.carte-gestes form { display: flex; align-items: center; gap: 4px; }
.carte-gestes .champ-numero { max-width: 150px; }
.carte-pied { margin: 6px 0 0; font-size: 12px; color: var(--muted); }

/* Le titre d'un groupe de zone dans « À livrer » : on livre en passant. */
.zone-tournee {
  margin: 12px 0 4px; font-size: 13px; font-weight: 700;
  text-transform: none; letter-spacing: 0; color: var(--etiquette);
}
.zone-tournee:first-child { margin-top: 0; }

/* Le menu « … » : tout ce qui n'est pas le geste principal. Un `details`
   plutôt qu'un script — il s'ouvre et se referme sans JavaScript. */
.menu-plus { position: relative; display: inline-block; }
.menu-plus > summary {
  list-style: none; cursor: pointer; padding: 5px 11px; border-radius: 0;
  border: 1px solid var(--line); color: var(--muted); font-weight: 700; line-height: 1;
}
.menu-plus > summary::-webkit-details-marker { display: none; }
.menu-plus[open] > summary { background: var(--gris-soft); color: var(--ink); }
.menu-plus-liste {
  position: absolute; right: 0; z-index: 5; min-width: 230px; margin-top: 6px;
  display: flex; flex-direction: column; gap: 2px; padding: 8px;
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: 0; box-shadow: var(--ombre-menu);
}
.menu-plus-liste a, .menu-plus-liste button {
  display: block; width: 100%; text-align: left; padding: 7px 10px; border: 0;
  border-radius: 0; background: none; color: var(--ink); font: inherit;
  font-size: 14px; cursor: pointer;
}
.menu-plus-liste a:hover, .menu-plus-liste button:hover { background: var(--gris-soft); text-decoration: none; }
.menu-plus-liste form { margin: 0; }
.menu-plus-liste .menu-date { padding: 6px 10px; font-size: 13px; }
.menu-plus-liste .menu-date label { display: block; margin-bottom: 4px; color: var(--muted); }
.menu-plus-liste .menu-date input { width: 100%; }
.menu-plus-note { padding: 7px 10px; font-size: 13px; color: var(--muted); }
/* Sur téléphone, le menu occupe la largeur plutôt que de déborder de l'écran. */
@media (max-width: 640px) {
  .menu-plus { position: static; }
  .menu-plus-liste { position: static; min-width: 0; width: 100%; box-shadow: none; }
  .carte-gestes > form:first-child { flex: 1 1 100%; }
  .carte-gestes > form:first-child .btn { width: 100%; }
}

/* Le bandeau d'un devis en tête de son formulaire : ses trois gestes passent
   avant la saisie, parce qu'un devis s'envoie et se transforme plus souvent
   qu'il ne se corrige. */
.panel-devis { border-left: 3px solid var(--bleu-clair); }

/* Le texte d'un rappel : assez haut pour se lire d'un coup, en pleine largeur. */
.texte-rappel {
  width: 100%; font-family: var(--font-body); font-size: 15px; line-height: 1.5;
  padding: 14px 16px; border: 1px solid var(--line); border-radius: 0;
  background: var(--zebra-doux); color: var(--ink); resize: vertical;
}

.feuille-mention {
  margin-top: 26px !important; padding-top: 12px; border-top: 1px solid var(--line);
  font-size: 12px; color: var(--muted); line-height: 1.45;
}

@media print {
  /* Le chrome de l'application n'a rien à faire sur une feuille qu'on donne. */
  .topbar, .footer, .no-print, .flash, .onglets-partie, .barre-tel, .feuille-bas { display: none !important; }
  body { padding-bottom: 0 !important; }
  main.wrap { padding: 0; margin: 0; max-width: none; }
  body { background: #fff; }
  /* L'encre coûte cher et le mode sombre imprimerait un rectangle noir. */
  .feuille {
    border: 0; border-radius: 0; padding: 0; max-width: none;
    background: #fff; color: #000;
  }
  .feuille .feuille-etiquette, .feuille .feuille-mention { color: #444; }
  /* 18.6 : la feuille s'imprime comme avant — la taille du texte et le titre
     d'avant l'habillage ; seules les polices changent. */
  .feuille { font-size: 15px; }
  .feuille h2 { font-size: 20px; font-weight: 400; text-transform: none; letter-spacing: normal; }
  /* 18.8 : à l'écran, les étiquettes passent en minuscules ; le papier garde
     ses petites capitales d'avant. */
  .feuille-etiquette { text-transform: uppercase; letter-spacing: .09em; font-size: 11px; font-weight: 600; }
  .feuille-lignes thead th { text-transform: uppercase; letter-spacing: .05em; font-size: 12px; }
  .feuille-mention { font-size: 11.5px; }
  .feuille-destinataire, .feuille-cadre { border-color: #888; }
  .feuille-lignes thead th, .feuille-lignes tfoot tr:first-child th { border-bottom-color: #000; border-top-color: #000; }
  .feuille-lignes tbody td, .feuille-lignes tfoot th, .feuille-lignes tfoot td { border-color: #bbb; }
  /* Une ligne de commande coupée entre deux pages se lit mal. */
  .feuille-lignes tr { page-break-inside: avoid; break-inside: avoid; }
  .feuille-signatures, .feuille-destinataire { page-break-inside: avoid; break-inside: avoid; }
  a { text-decoration: none; color: #000; }
}

/* Pièces jointes. Le trombone d'une ligne de liste reste discret : il ne dit
   qu'une chose, « il y a la facture ici ». */
.trombones { margin-left: 6px; white-space: nowrap; }
.trombone { text-decoration: none; font-size: 15px; opacity: .75; }
.trombone:hover { opacity: 1; }
.trombone + .trombone { margin-left: 2px; }

/* Sur une fiche, au contraire, on veut voir de quoi il s'agit sans ouvrir. */
.liste-documents { list-style: none; padding: 0; margin: 0 0 16px; display: flex; flex-wrap: wrap; gap: 14px; }
.liste-documents li {
  width: 170px; display: flex; flex-direction: column; gap: 4px;
  padding: 10px; border: 1px solid var(--line); border-radius: 0; background: var(--bg);
}
.liste-documents a { text-decoration: none; color: inherit; display: block; }
.liste-documents img,
.liste-documents .vignette-pdf {
  display: block; width: 100%; height: 110px; border-radius: 0; border: 1px solid var(--line);
  object-fit: cover; background: var(--surface);
}
.liste-documents .vignette-pdf {
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; letter-spacing: .08em; color: var(--muted);
}
.liste-documents .nom { display: block; margin-top: 6px; font-weight: 600; font-size: 13px; word-break: break-word; }
.liste-documents a:hover .nom { text-decoration: underline; }

/* Connexion et installation */
/* 18.6 : la connexion sur fond noir, le logo et la marque au-dessus de la carte. */
.page-login { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; padding: 20px; background: #000; }
.login-box { width: 100%; max-width: 380px; background: var(--surface); border: 1px solid var(--line-strong); border-radius: 0; padding: 34px 30px; }
.login-box label { margin-bottom: 14px; }
.login-box .btn { margin-top: 6px; }
.page-setup .panel h2 { margin-top: 8px; }

/* Le pied de page (18.6) : une bande noire sur toute la largeur, le texte dans
   la largeur de la page. */
.footer { padding: 18px 0; background: #000; color: #AAAAAA;
  font-family: var(--font-display); font-size: 12px; text-transform: uppercase; letter-spacing: .24em; }

/* Le message d'erreur de la connexion, sous les champs (15.4). */
.login-erreur { margin: 0 0 12px; color: var(--rouge); font-weight: 600; font-size: 14px; }

/* Densité des listes (15.4, Mon compte) : « Compacte » pose `dense` sur
   <html>, et les cellules des tableaux se resserrent. */
html.dense table.list th, html.dense table.list td { padding: 6px 10px; }
html.dense table.list td .sub { margin-top: 0; }
html.dense .carte-jour { padding: 5px 8px; margin-top: 5px; }

/* Mon compte : les choix d'affichage, en ligne. */
.choix-affichage { display: flex; flex-wrap: wrap; gap: 6px 18px; margin: 4px 0 12px; }
.choix-affichage legend { font-weight: 600; font-size: 14px; margin-bottom: 4px; padding: 0; }
.choix-affichage fieldset { border: 0; padding: 0; margin: 0 0 10px; min-width: 0; }
/* 17.8 : les choix en pastilles, côte à côte sous leur titre. */
.choix-affichage fieldset { display: flex; flex-wrap: wrap; gap: 8px; }
.choix-affichage legend { margin-bottom: 8px; }

/* Mobile */
@media (max-width: 900px) {
  .hide-md { display: none; }
  .form-grid-4 { grid-template-columns: 1fr 1fr; }
  .tiles { grid-template-columns: 1fr; }
  .tile { min-height: 0; }
  .cols, .cols-side { grid-template-columns: 1fr; }
  .side-nav { flex-direction: row; flex-wrap: wrap; }
  .journal li { grid-template-columns: 1fr; gap: 2px; }
}
@media (max-width: 640px) {
  body { font-size: 15px; }
  .hide-sm { display: none; }
  .show-sm { display: inline; }
  .display { font-size: 22px; letter-spacing: .1em; }
  /* L'en-tête sur téléphone (15.6) : la marque, et le rond de l'initiale.
     Le menu est dans la barre du bas, la roue dans Plus. */
  .topbar-inner { gap: 10px; min-height: 60px; }
  .brand-logo { height: 40px; }
  .brand-app { font-size: 18px; }
  .brand { gap: 10px; }
  .topbar .nav, .topbar .roue, .topbar .user-name, .topbar .menu-partie, .topbar .bascule-theme { display: none; }
  .initiale { display: inline-flex; }
  .user-box { margin-left: auto; }

  /* La barre du bas : cinq entrées au pouce, au-dessus du contenu mais sous
     le volet (60) et les feuilles (70). Le corps de page se pousse d'autant,
     pied de page compris, pour que rien ne se cache dessous. */
  body { padding-bottom: calc(90px + env(safe-area-inset-bottom, 0px)); }
  .barre-tel {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
    height: calc(78px + env(safe-area-inset-bottom, 0px));
    padding-bottom: env(safe-area-inset-bottom, 0px);
    background: #000; border-top: 1px solid #222;
  }
  .barre-tel > a {
    flex: 1 1 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; color: #A8A8A8; line-height: 1.1;
    font-family: var(--font-display); font-size: 12px; text-transform: uppercase; letter-spacing: .16em;
  }
  .barre-tel > a:hover { text-decoration: none; color: #fff; }
  .barre-tel > a.on { color: #fff; }
  /* Saisir : le rond blanc, un peu remonté au-dessus de la barre noire. */
  .barre-rond {
    display: inline-flex; align-items: center; justify-content: center;
    width: 46px; height: 46px; border-radius: 50%; margin-top: -24px;
    background: #fff; color: #000;
    box-shadow: 0 4px 12px var(--ombre-saisir);
  }
  .barre-saisir { color: #fff; }
  body.feuille-ouverte { overflow: hidden; }

  /* Le volet plein écran, au-dessus de la barre : « ← Retour » en tête. */
  .volet-tete { flex-direction: column; }
  .volet-fermer {
    order: -1; width: auto; height: 44px; padding: 0 16px; border-radius: 0;
    font-size: 0;
  }
  .volet-fermer::before { content: "← Retour à la liste"; font-size: 14px; font-weight: 600; }
  .volet-corps { padding-bottom: calc(28px + env(safe-area-inset-bottom, 0px)); }

  /* Les gestes d'une carte : pleine largeur, 46 px — au pouce. */
  .carte-gestes .btn, .table-cartes td.col-action .btn, .volet-boutons .btn { min-height: 46px; }
  .carte-jour .carte-gestes > form, .carte-jour .carte-gestes > a { flex: 1 1 100%; }
  .carte-jour .carte-gestes .btn { width: 100%; }
  .form-grid, .form-grid-4 { grid-template-columns: 1fr; }
  .form-grid .span2, .form-grid .span3 { grid-column: auto; }
  .dl { grid-template-columns: 1fr; gap: 0 0; }
  .dl dt { margin-top: 8px; }
  .note-form { flex-direction: column; }
  .filters-ligne { padding: 12px 14px; }
  .champ-recherche { flex: 1 1 100%; }
  table.list th, table.list td { padding: 8px; }
}
@media (prefers-reduced-motion: no-preference) {
  .tile-on, .btn { transition: box-shadow .15s ease, background .15s ease, border-color .15s ease; }
}
.steps { padding-left: 20px; } .steps li { margin-bottom: 8px; }

/* ---------------------------------------------------------------------------
   La partie Ventes (16.1) : une liste, trois colonnes, un bouton par colonne.
   --------------------------------------------------------------------------- */
/* Les filtres d'« En cours » : des liens en pastilles, l'actif en prune. */
.chips-filtres { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 14px 0; }
.chips-filtres .hint { margin-left: 4px; }
a.chip { color: var(--ink); text-decoration: none; }
a.chip.chip-actif { color: var(--on-plum); }
a.chip:hover { text-decoration: none; }
.chip-retirer { padding: 4px 11px; font-size: 13px; margin-left: 4px; }

/* La carte « en retard de paiement » : une bordure rouge, et elle mène au filtre. */
a.kpi { color: inherit; text-decoration: none; }
a.kpi:hover .kpi-nom { color: var(--plum); }
.kpi-retard { border-left: 5px solid var(--badge-rouge); padding-left: 12px; }
.kpi-retard .kpi-valeur { color: var(--rouge); }

/* Les trois colonnes d'une vente en cours. La première colonne de ces tableaux
   est un nom ou une date, pas une pastille d'alerte : alignée à gauche. */
table.list.table-en-cours thead th:first-child, table.list.table-en-cours tbody td:first-child,
table.list.table-historique thead th:first-child, table.list.table-historique tbody td:first-child,
table.list.table-services thead th:first-child, table.list.table-services tbody td:first-child,
table.list.lignes-vente thead th:first-child, table.list.lignes-vente tbody td:first-child { text-align: left; }
/* La date passée d'une sous-ligne : rouge, pas le gris de .sub. */
.sub.date-retard { color: var(--rouge); }
.table-en-cours td { vertical-align: top; }
.geste-date { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 0; }
.geste-date .champ-numero { width: 7.5rem; }
.date-faite { color: var(--vert); font-weight: 600; white-space: nowrap; }
.ligne-devis td { color: var(--muted); background: var(--gris-soft) !important; }
.ligne-devis td:first-child { border-left-color: var(--line-strong); }
.cell-devis { font-style: italic; }
.cell-devis .gestes-devis { display: inline-flex; gap: 6px; margin-left: 10px; font-style: normal; }
.geste-ligne { display: inline-flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 6px; }
td.vente-tel { display: none; }
.menu-plus-liste form.menu-tel { display: none; }
.pied-liste { margin: 12px 0 0; }

/* Les trois marques Livrée · Facturée · Payée : vert fait, ambre la prochaine,
   rouge en retard, gris pas encore. */
.marques { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.marque {
  display: inline-block; padding: 2px 8px; border-radius: 0; font-size: 12px; font-weight: 600;
  border: 1px solid var(--line-strong); background: var(--gris-soft); color: var(--muted);
}
.marque-fait { background: var(--vert-soft); color: var(--vert); border-color: var(--vert-bord); }
.marque-fait::before { content: "✓ "; }
.marque-prochaine { background: var(--ambre-soft); color: var(--ambre); border-color: var(--ambre-bord); }
.marque-retard { background: var(--rouge-soft); color: var(--rouge); border-color: var(--rouge-bord); }

/* L'Historique : le résumé, les filtres retirables, la suite. */
.resume-liste { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin: 12px 0; font-size: 14px; }
.filtres-rares { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.filtres-rares select { width: auto; }
.plus-de-lignes { display: flex; align-items: center; gap: 12px; margin: 14px 0; }
.ligne-annulee td:not(.col-action) { text-decoration: line-through; }

/* Le catalogue des prestations : une ligne s'ouvre en champs. */
.ligne-retiree td:not(.col-action) { opacity: .6; }
.ligne-edition td { background: var(--plum-soft) !important; vertical-align: top; }
.champ-court { max-width: 6.5rem; }
.champ-sous { margin-top: 6px; font-size: 13px; }

@media (max-width: 640px) {
  /* Une vente en cours, en carte : les trois marques, puis le bouton principal
     en pleine largeur. Les autres boutons sont dans « … ». */
  .table-cartes td.vente-ecran { display: none; }
  .table-cartes td.vente-tel { display: block; margin-top: 6px; }
  .vente-tel .marques { margin-bottom: 8px; }
  .geste-pouce { width: 100%; }
  .geste-pouce .champ-numero { flex: 1 1 100%; width: 100%; }
  .geste-pouce .btn { flex: 1 1 100%; width: 100%; min-height: 46px; }
  .menu-plus-liste form.menu-tel { display: flex; padding: 4px 10px; }
  .menu-plus-liste form.menu-tel .champ-numero { flex: 1 1 100%; width: 100%; }
  .cell-devis .gestes-devis { display: flex; margin: 8px 0 0; }
  .cell-devis .gestes-devis form, .cell-devis .gestes-devis .btn { flex: 1 1 auto; width: 100%; min-height: 46px; }
  .table-cartes td.col-action .geste-ligne { display: flex; width: 100%; }
  .table-cartes td.col-action .geste-ligne > .btn,
  .table-cartes td.col-action .geste-ligne > form { flex: 1 1 auto; }
  .chips-filtres .hint { flex: 1 1 100%; margin: 0; }
  /* Préparer : la case reste au pouce — cocher est tout l'écran. */
  .table-cartes td.cell-coche-garde { display: block; float: right; }
}
/* ---------------------------------------------------------------------------
   Saisir une vente (16.2) : trois étapes à gauche, le récapitulatif à droite,
   collé pendant qu'on défile. Une seule colonne sous 900 px, récapitulatif en
   bas.
   --------------------------------------------------------------------------- */
.saisie-colonnes { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 0 22px; align-items: start; }
.saisie-etapes { min-width: 0; }
.recap-vente { position: sticky; top: 92px; }
@media (max-width: 899px) {
  .saisie-colonnes { grid-template-columns: 1fr; }
  .recap-vente { position: static; }
}
.etape-vente h2 { display: flex; align-items: center; gap: 10px; }
.etape-num {
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
  width: 28px; height: 28px; border-radius: 50%; font-size: 14px; font-family: var(--font-body);
  background: var(--plum-bg); color: var(--on-plum);
}
.client-choisi { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin: 0 0 14px; font-size: 15px; }
.client-phrase { font-weight: 600; }
.lien-bouton {
  background: none; border: 0; padding: 0; font: inherit; font-size: 13px; color: var(--plum);
  text-decoration: underline; cursor: pointer;
}
.lien-bouton:hover { color: var(--ink); }

/* Les erreurs : en haut, et sous le champ fautif. */
.liste-erreurs { margin: 6px 0 0; padding-left: 20px; }
.erreur-champ { display: block; margin-top: 4px; color: var(--rouge); font-size: 13px; font-weight: 600; }

/* Les lignes : une à la fois, vin ou prestation, dans le même tableau. */
.lignes-vente td { vertical-align: top; }
.lignes-vente select { min-width: 0; }
.quantite-ligne, .cellule-cartons { display: inline-flex; align-items: center; gap: 6px; }
.cellule-cartons { margin-top: 6px; }
.lignes-vente .nb-bouteilles, .lignes-vente .nb-cartons, .lignes-vente .qte-service { width: 5.5rem; }
.lignes-vente .prix-ligne, .lignes-vente .prix-service { width: 7.5rem; }
.lignes-vente .unite { color: var(--muted); font-size: 13px; white-space: nowrap; }
.lignes-vente .total-ligne { white-space: nowrap; font-variant-numeric: tabular-nums; }
.lignes-vente .prix-habituel { display: block; margin-top: 4px; }
.col-retirer { width: 1%; text-align: right; }
.alerte-stock { color: var(--ambre); font-weight: 600; margin-top: 4px; }
.alerte-stock.alerte-manque { color: var(--rouge); }
.ajout-lignes { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 4px; }
.details-vente > summary { cursor: pointer; font-weight: 600; }
.details-vente[open] > summary { margin-bottom: 12px; }

/* Le récapitulatif. */
.recap-vente h2 { margin-bottom: 10px; }
.recap-famille { margin: 0 0 6px; font-size: 14px; }
.recap-sans-prix { margin: 4px 0 8px; color: var(--ambre); font-weight: 600; font-size: 14px; }
.recap-totaux { width: 100%; border-collapse: collapse; margin: 10px 0; font-variant-numeric: tabular-nums; }
.recap-totaux th { text-align: left; font-weight: 400; color: var(--muted); padding: 4px 0; }
.recap-totaux td { text-align: right; padding: 4px 0; white-space: nowrap; }
.recap-totaux tr:first-child th, .recap-totaux tr:first-child td { color: var(--ink); font-weight: 600; }
.recap-ttc th, .recap-ttc td { border-top: 1px solid var(--line-strong); color: var(--ink) !important; font-weight: 700; font-size: 16px; padding-top: 8px; }
.recap-phrase { margin: 8px 0 0; font-size: 13.5px; color: var(--muted); line-height: 1.45; }

/* Sur téléphone, une ligne de vente est une carte : les champs prennent la
   largeur, et la croix reste en haut à droite. */
@media (max-width: 640px) {
  .table-cartes.lignes-vente tr { position: relative; padding-right: 40px; }
  .table-cartes.lignes-vente td.col-retirer { position: absolute; top: 8px; right: 8px; padding: 0; }
  .table-cartes.lignes-vente td select, .table-cartes.lignes-vente .prix-ligne,
  .table-cartes.lignes-vente .prix-service { width: 100%; }
}

/* Les documents d'une vente (16.2) : trois blocs côte à côte, l'un sous
   l'autre au téléphone. */
.documents-vente { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 18px; align-items: start; }
@media (max-width: 900px) { .documents-vente { grid-template-columns: 1fr; } }
.document-vente p { margin: 0 0 8px; }
.feuille-lettre p { margin: 0 0 4px; line-height: 1.5; }
/* ---------------------------------------------------------------------------
   Dépenses (16.3) : à payer par échéance, à compléter en une liste ; toutes
   les dépenses par mois.
   --------------------------------------------------------------------------- */
.kpi-ambre { border-left: 5px solid var(--badge-ambre); padding-left: 12px; }
.kpi-ambre .kpi-valeur { color: var(--ambre); }
.table-factures td, .table-depenses td { vertical-align: top; }
table.list.table-factures thead th:first-child, table.list.table-factures tbody td:first-child,
table.list.table-depenses thead th:first-child, table.list.table-depenses tbody td:first-child { text-align: left; }
.geste-payer { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; justify-content: flex-end; margin: 0; }
.geste-payer input[type="date"], .geste-payer select { width: auto; padding: 5px 7px; font-size: 13px; }
.liste-completer { list-style: none; margin: 0; padding: 0; }
.ligne-completer { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; padding: 10px 0; border-top: 1px solid var(--line); }
.ligne-completer:first-child { border-top: 0; }
.ligne-completer-texte { flex: 1 1 260px; min-width: 0; }
.ligne-completer-texte a { font-weight: 600; color: var(--ink); }
.ligne-completer-geste { margin-left: auto; }
.titre-mois-total { font-weight: 400; color: var(--muted); font-size: 13px; margin-left: 4px; text-transform: none; letter-spacing: 0; }
.paiement-depense { font-size: 13px; font-weight: 600; }
.paiement-vert { color: var(--vert); }
.paiement-ambre { color: var(--ambre); }
.paiement-rouge { color: var(--rouge); }
.paiement-neutre { color: var(--muted); font-weight: 400; }
.lien-effacer { font-size: 13px; margin-left: 6px; }
@media (max-width: 640px) {
  .geste-payer { justify-content: stretch; }
  .geste-payer input[type="date"], .geste-payer select { flex: 1 1 auto; }
  .geste-payer .btn { flex: 1 1 100%; min-height: 46px; }
  .ligne-completer-geste { margin-left: 0; width: 100%; }
  .ligne-completer-geste .btn { width: 100%; min-height: 46px; }
}
/* ---------------------------------------------------------------------------
   Saisir une dépense en quatre questions (16.4). Le formulaire à gauche, « Ce
   qui sera enregistré » à droite (les classes de la saisie d'une vente).
   --------------------------------------------------------------------------- */
:root { --jaune-soft: #FFF6CC; --jaune-bord: #E9D27A; }
:root[data-theme="dark"] { --jaune-soft: #3A3315; --jaune-bord: #6B5C22; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --jaune-soft: #3A3315; --jaune-bord: #6B5C22; } }
/* Ce qui vient du fournisseur est déjà rempli, en jaune — jusqu'à ce qu'on y touche. */
.saisie-depense input.prerempli, .saisie-depense select.prerempli,
.saisie-depense .chip.prerempli, .saisie-depense .choix.prerempli { background: var(--jaune-soft); border-color: var(--jaune-bord); }
.saisie-depense .chip.chip-actif.prerempli, .saisie-depense .choix.choix-actif.prerempli .choix-titre { color: var(--ink); }
.saisie-depense .chip.chip-actif.prerempli { box-shadow: inset 0 0 0 2px var(--plum); }
.saisie-depense input.calcule { background: var(--gris-soft); }
table.list.lignes-depense thead th:first-child, table.list.lignes-depense tbody td:first-child { text-align: left; }
.saisie-depense legend { display: flex; align-items: center; gap: 10px; }
.choix-large.choix-cinq { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); }
.choix-large.choix-cinq .choix { flex-basis: auto; }
.pour-choix { margin-top: 12px; }
.phrase-affectation { margin: 12px 0 0; padding: 10px 12px; border-left: 3px solid var(--plum); background: var(--plum-soft); font-size: 14px; }
.lignes-depense input, .lots-barriques input { width: 100%; }
.lignes-depense td, .lots-barriques td { vertical-align: middle; }
.montants-facture { margin-top: 14px; align-items: end; }
.montant-calcule { margin: 6px 0; font-size: 15px; }
.chip-montant { font-weight: 400; opacity: .85; }
.piece-jointe { margin: 16px 0 8px; }
.piece-jointe-titre { margin: 0 0 6px; font-weight: 600; font-size: 14px; }
.boutons-document { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.rappel-saisie { margin: 8px 0 0; font-size: 13px; color: var(--muted); }
.actions-saisie { margin-top: 18px; }
.actions-saisie .flash { margin-bottom: 12px; }
.recap-dl { display: grid; grid-template-columns: auto 1fr; gap: 6px 12px; margin: 0 0 10px; font-size: 14px; }
.recap-dl dt { color: var(--muted); }
.recap-dl dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
@media (max-width: 640px) {
  .choix-large.choix-cinq { grid-template-columns: 1fr; }
  .boutons-document .btn { flex: 1 1 auto; min-height: 46px; }
  .actions-saisie .panel-actions .btn { flex: 1 1 100%; min-height: 46px; }
}

/* ---------------------------------------------------------------------------
   Analyse › Vins (16.7) : chaque bloc dit sur quoi il porte ; un chiffre
   inconnu est gris et en italique, jamais 0.
   --------------------------------------------------------------------------- */
.inconnu { color: var(--muted); font-style: italic; font-weight: 400; }
.kpi-valeur .inconnu { font-size: 22px; }
.titre-bloc { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 0 0 12px; }
.titre-bloc h2 { margin: 0; }
.titre-bloc select { font: inherit; font-size: 18px; padding: 2px 6px; margin-left: 4px; }
.perim { display: inline-block; padding: 3px 10px; border-radius: 0; font-size: 12px;
  color: var(--muted); background: var(--fond, transparent); border: 1px solid var(--line); white-space: nowrap; }
/* Trois chiffres, puis la carte d'action (3 + 1,5). */
.kpis-action { grid-template-columns: repeat(3, 1fr) 1.5fr; align-items: start; }
.carte-action { background: var(--ambre-soft); border: 1px solid var(--ambre-bord); border-radius: 0;
  padding: 12px 14px; font-size: 13.5px; }
.carte-action h3 { margin: 0 0 8px; color: var(--ambre); }
.carte-action .manque { margin: 0 0 10px; }
.carte-action .manque p { margin: 0 0 6px; }
.carte-action .hint { margin: 4px 0 0; }
/* Par millésime : la durée qui dort en ambre, le détail sous la ligne. */
.stock-dort { color: var(--ambre); font-weight: 600; }
.controle-ambre { color: var(--ambre); font-weight: 600; }
.detail-millesime td { background: var(--plum-soft); font-size: 13.5px; padding-top: 8px; padding-bottom: 8px; text-align: left; }
.detail-millesime p { margin: 0 0 4px; }
.table-millesimes .col-action { white-space: nowrap; }
.table-millesimes td.num, .table-clients-analyse td.num, .table-depenses-millesime td.num { white-space: nowrap; }
.ligne-total td { font-weight: 700; border-top: 2px solid var(--line-strong); }
.ligne-total .sub { font-weight: 400; }
/* Par client (1,25) et dépenses du millésime (1), côte à côte. */
.cols-analyse { display: grid; grid-template-columns: 1.25fr 1fr; gap: 0 16px; align-items: start; }
.pliant-simple { margin-top: 14px; }
.pliant-simple summary { cursor: pointer; font-weight: 600; font-size: 14px; }
.definitions-cadre { border: 1px dashed var(--line-strong); border-radius: 0; padding: 12px 16px;
  margin: 16px 0 0; font-size: 13.5px; }
.definitions-cadre p { margin: 0 0 6px; }
@media (max-width: 1100px) {
  .kpis-action { grid-template-columns: repeat(3, 1fr); }
  .kpis-action .carte-action { grid-column: 1 / -1; }
}
@media (max-width: 900px) {
  .cols-analyse { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .kpis-action { grid-template-columns: 1fr; }
  /* Le détail se lit dans la carte de son millésime, collé dessous. */
  .table-cartes tr.detail-millesime { margin-top: -12px; border-top: 0; border-radius: 0;
    background: var(--plum-soft); }
  .table-cartes tr.detail-millesime td { background: none; padding: 0; }
  .table-cartes tr.ligne-total { border-width: 2px; }
  .table-cartes tr.ligne-total td { border-top: 0; }
  .titre-bloc .perim { white-space: normal; }
}
/* ---------------------------------------------------------------------------
   Le carnet de missions (16.9) : la journée choisie le matin, cochée par les
   faits. Pas de points, pas de série : une barre, des coches, c'est tout.
   --------------------------------------------------------------------------- */
.missions-page { display: grid; grid-template-columns: minmax(0, 1fr) 280px; gap: 16px; align-items: start; }
.missions-principal > .panel { margin: 0 0 16px; }
.mission-candidat { display: flex; gap: 12px; align-items: flex-start; padding: 10px 0;
  border-bottom: 1px solid var(--line); cursor: pointer; }
.mission-candidat input { margin-top: 3px; width: 18px; height: 18px; flex: none; }
.mission-texte { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.mission-titre { font-weight: 600; }
.mission-libre { display: block; margin-top: 14px; font-size: 13px; color: var(--muted); }
.mission-libre input { display: block; width: 100%; margin-top: 4px; }
.missions-barre { height: 8px; border-radius: 0; background: var(--line); overflow: hidden; margin: 4px 0 14px; }
.missions-barre span { display: block; height: 100%; background: var(--vert); border-radius: 0; transition: width .4s ease; }
.missions-liste { list-style: none; margin: 0; padding: 0; }
.mission { display: flex; gap: 12px; align-items: center; padding: 12px 0; border-bottom: 1px solid var(--line); }
.mission-num { flex: none; width: 28px; height: 28px; border-radius: 50%; display: inline-flex; align-items: center;
  justify-content: center; border: 1px solid var(--line-strong); font-weight: 600; font-size: 14px; }
.mission-coche { flex: none; width: 28px; height: 28px; border-radius: 50%; display: inline-flex; align-items: center;
  justify-content: center; background: var(--vert-soft); color: var(--vert); }
.mission-coche svg path { stroke-dasharray: 24; stroke-dashoffset: 0; }
.mission-faite .mission-titre { color: var(--muted); font-weight: 500; }
.mission-en_cours .mission-num { border-color: var(--plum); color: var(--plum); }
.mission-gestes { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
/* La coche qui se dessine, une fois, quand la mission vient d'être faite —
   si le compte le veut, et si l'appareil ne demande pas moins de mouvement. */
.avec-animation .coche-recente .mission-coche svg path { animation: coche-dessin 400ms ease-out both; }
@keyframes coche-dessin { from { stroke-dashoffset: 24; } to { stroke-dashoffset: 0; } }
@media (prefers-reduced-motion: reduce) {
  .avec-animation .coche-recente .mission-coche svg path { animation: none; }
  .missions-barre span { transition: none; }
}
.mission-plus-tard { display: flex; gap: 12px; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--line); }
.mission-autre { flex: none; font-size: 13px; }
.missions-pied { margin: 4px 0 16px; }
@media (max-width: 900px) {
  .missions-page { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .mission, .mission-plus-tard { flex-wrap: wrap; }
  .mission-gestes { width: 100%; justify-content: stretch; }
  .mission-gestes form { flex: 1 1 auto; }
  .mission-gestes .btn { width: 100%; min-height: 44px; }
  .mission-gestes .mission-ouvrir { flex-basis: 100%; }
  .mission-plus-tard form, .mission-plus-tard form .btn { width: 100%; }
}

/* ---------------------------------------------------------------------------
   Le mode Focus (17.0) : une mission à la fois, sans menu ni barre du bas.
   Le fond et les polices de l'outil ; en haut, la marque, « Mission 2 sur 3 »
   et la pause. Pour voir le reste, on sort.
   --------------------------------------------------------------------------- */
/* 18.6 : le bandeau noir de la barre du haut ; la marque en capitales espacées,
   le rang en Raleway, la sortie en bouton blanc à filet blanc. */
.focus-barre { position: sticky; top: 0; z-index: 20; background: #000; color: #fff; }
.focus-barre-inner { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 12px; min-height: 56px; }
.focus-marque { font-family: var(--font-display); font-size: 14px; text-transform: uppercase; letter-spacing: .2em; color: #fff; }
.focus-marque strong { font-weight: 400; }
.focus-marque .brand-sep { color: #666; }
.focus-rang { font-family: var(--font-body); font-weight: 500; font-size: 13px; text-align: center; color: #fff; }
.focus-barre .btn, .focus-barre .btn:hover { background: transparent; border-color: #fff; color: #fff; }
.focus-barre .btn:hover { background: rgba(255, 255, 255, .1); }
.focus-titre-barre { color: #fff; }
.focus-sortir { justify-self: end; }
.pause-court { display: none; }
.focus-contenu { padding-top: 18px; padding-bottom: 48px; }
/* Dans le cadre, pas de fil d'Ariane : il mènerait ailleurs. */
.mode-focus .eyebrow.fil, .mode-focus .page-head .actions { display: none; }
.hint-champ.facultatif, p.facultatif { color: var(--muted); font-style: italic; font-weight: 400; }
.bandeau-reprise { margin-bottom: 14px; }
/* Les étapes de la saisie, en tête : ✓ Quoi ? › ✓ Pour quoi ? › 3 Combien ? */
.etapes-focus { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin: 0 0 10px; font-size: 14px; }
.etape-focus { border: 0; background: none; padding: 4px 2px; font: inherit; color: var(--muted); }
button.etape-focus { color: var(--vert); cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
.etape-courante { color: var(--plum-ink); font-weight: 600; }
.etape-sep { color: var(--line-strong); }
.mode-focus .barre-ecrans .barre-ecrans-titre { display: none; }
.deja-renseigne { margin: 16px 0 0; padding: 12px 16px; border: 1px dashed var(--line-strong); border-radius: 0; }
.deja-renseigne h2 { font-size: 16px; margin: 0 0 6px; }
.deja-renseigne ul { list-style: none; margin: 0; padding: 0; font-size: 14px; }
.deja-renseigne li { padding: 3px 0; }
.deja-titre { font-weight: 600; margin-right: 6px; }
/* La fin de mission : une grande coche, puis les faits. */
.fin-mission { text-align: left; }
.fin-coche .mission-coche { width: 84px; height: 84px; margin: 4px 0 12px; }
.faits { list-style: none; margin: 0; padding: 0; }
.faits li { padding: 6px 0; border-bottom: 1px solid var(--line); }
.fait-ok span { color: var(--vert); font-weight: 700; }
.fait-manque { color: var(--muted); }
.fin-journee { font-size: 17px; margin: 14px 0 0; }
.mission-ouvrir { display: inline-flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.mission-sans-focus { font-size: 12px; color: var(--muted); }
.mission-pause { color: var(--ambre); }
/* Le carnet, court (17.9) : « Voir les N autres » le matin, une ligne par
   catégorie dans « Plus tard », et « Tout voir ». */
.missions-autres { margin: 8px 0 4px; }
.missions-autres > summary { cursor: pointer; color: var(--muted); font-size: 14px; padding: 6px 0; }
.mission-groupe .mission-titre { font-weight: 600; }
.plus-tard-tout { margin: 10px 0 0; font-size: 14px; }
/* Sous le bandeau (17.9) : « MISSION 2 », le titre, une ligne de contexte ; le
   bloc seul ; puis la phrase qui dit pourquoi il n'y a rien d'autre. */
.focus-titre-barre { display: none; }
.focus-gauche { display: contents; }
.focus-tete { margin: 4px 0 14px; }
.focus-numero { margin: 0; font-size: 13px; font-weight: 700; text-transform: none; letter-spacing: 0; color: var(--etiquette); }
.focus-titre { margin: 2px 0 4px; font-size: 28px; }
.focus-contexte { margin: 0; color: var(--muted); }
.focus-contexte a { font-weight: 600; }
.focus-sep { color: var(--line-strong); }
.focus-bloc { margin-top: 0; }
.focus-bloc > h2:first-child { margin-top: 0; }
.focus-pied { margin: 22px 0 0; font-size: 13.5px; color: var(--muted); }
.mode-focus .saisie-colonnes.sans-recap { grid-template-columns: 1fr; }
@media (max-width: 640px) {
  /* Deux lignes : « MODE FOCUS · MISSION 2 SUR 3 » et la pause, puis le titre. */
  .focus-barre-inner { grid-template-columns: 1fr auto; gap: 4px 10px; min-height: 0; padding-top: 8px; padding-bottom: 8px; }
  .focus-gauche { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 6px; grid-column: 1; grid-row: 1; }
  .focus-nom { display: none; }
  .focus-marque, .focus-rang { font-size: 12px; letter-spacing: .14em; text-transform: uppercase; color: #C0C0C0; text-align: left; }
  .focus-marque strong { font-weight: 400; color: #fff; }
  .focus-rang::before { content: "· "; }
  .focus-sortir { grid-column: 2; grid-row: 1; }
  .focus-titre-barre { display: block; grid-column: 1 / -1; grid-row: 2; font-weight: 600; font-size: 15px; line-height: 1.3; }
  .focus-tete .focus-titre { display: none; }
  .pause-long { display: none; }
  .pause-court { display: inline; }
  /* Le bouton principal en bas, pleine largeur. */
  .mode-focus .panel-actions .btn-primary, .mode-focus .nav-ecrans .btn, .fin-bouton { width: 100%; min-height: 48px; }
  .mode-focus .panel-actions { flex-direction: column; align-items: stretch; }
  .mission-ouvrir { width: 100%; align-items: stretch; }
  .mission-ouvrir .btn { width: 100%; min-height: 44px; }
  .mission-sans-focus { text-align: center; }
}

/* ---------------------------------------------------------------------------
   Cette semaine et les jalons (17.1) : des faits, jamais un clic. Une coche,
   le texte, le jour — ni compteur, ni comparaison, ni pourcentage.
   --------------------------------------------------------------------------- */
.missions-cote > .panel { margin: 0 0 16px; }
.cette-semaine h2 { font-size: 18px; }
.reussites { list-style: none; margin: 0; padding: 0; font-size: 14px; }
.reussites li { display: grid; grid-template-columns: auto 1fr auto; gap: 8px; align-items: baseline;
  padding: 6px 0; border-bottom: 1px solid var(--line); }
.reussite-coche { color: var(--vert); font-weight: 700; }
.reussite-jour { color: var(--muted); font-size: 12.5px; white-space: nowrap; }
.jalon-debloque { border-left: 3px solid var(--vert); }
.jalon-debloque h2, .jalon-debloque h3 { margin: 2px 0 6px; font-size: 18px; }
.jalon-etiquette { margin: 0; font-size: 13px; text-transform: none; letter-spacing: 0; color: var(--vert); font-weight: 700; }
.jalons-liste { list-style: none; margin: 0; padding: 0; font-size: 14px; }
.jalons-liste li { padding: 6px 0; border-bottom: 1px solid var(--line); }
.bouton-mission { margin-left: 6px; }
.mission-deja { margin-left: 6px; }
/* --- Boîte IA (17.2) ------------------------------------------------------ */
.pastille-ambre { display: inline-block; min-width: 18px; padding: 0 6px; margin-left: 4px; border-radius: 0;
  background: #7B3FB5; color: #fff; border: 0; height: 20px;
  font-family: var(--font-body); font-size: 12px; font-weight: 700; line-height: 20px; letter-spacing: 0; text-align: center; vertical-align: 1px; }
.cols-ia { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; align-items: start; }
@media (max-width: 900px) { .cols-ia { grid-template-columns: 1fr; } }
.boutons-depot { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 12px; }
.bouton-depot { position: relative; flex: 1 1 150px; justify-content: center; text-align: center; cursor: pointer; }
.bouton-depot input[type="file"] { position: absolute; left: 0; top: 0; width: 1px; height: 1px; opacity: 0; overflow: hidden; }
.bouton-depot:focus-within { outline: 2px solid var(--plum); outline-offset: 2px; }
.bouton-depot.dictee-active { background: var(--rouge-soft); color: var(--rouge); border-color: var(--rouge); }
.fichiers-choisis { margin: 0 0 10px; }
.texte-depot { display: block; margin-bottom: 4px; }
.depot-ia textarea { width: 100%; }
.cartes-ia { display: flex; flex-direction: column; gap: 10px; margin: 12px 0; }
.carte-ia { border: 1px solid var(--line-strong); border-left: 3px solid var(--plum); border-radius: 0; padding: 10px 12px; background: var(--bg); }
.carte-ia-tete { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.carte-doute { margin-top: 6px; padding: 4px 8px; border-radius: 0; background: var(--ambre-soft); color: var(--ambre); font-weight: 600; font-size: 13px; }
.champs-ia { display: grid; grid-template-columns: max-content 1fr; gap: 4px 12px; margin: 10px 0 0; font-size: 14px; }
.champs-ia dt { color: var(--muted); }
.champs-ia dd { margin: 0; overflow-wrap: anywhere; }
.champs-ia dd.champ-deduit { padding: 0 6px; border-radius: 0; }
.champ-deduit, .lignes-ia tr.champ-deduit td { background: var(--ambre-soft); }
.origine { font-size: 12px; text-transform: none; letter-spacing: 0; color: var(--muted); margin-left: 6px; }
.champ-deduit .origine { color: var(--ambre); }
.lignes-ia { margin-top: 8px; font-size: 13.5px; }
.lignes-ia th:first-child, .lignes-ia td:first-child { text-align: left; }
.liste-depots { list-style: none; margin: 0; padding: 0; }
.ligne-depot { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-top: 1px solid var(--line); }
.ligne-depot:first-child { border-top: 0; }
.ligne-depot-texte { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.source-depot { flex: 0 0 66px; box-sizing: border-box; font-size: 12px; letter-spacing: .05em; text-align: center; }
@media (max-width: 640px) {
  .ligne-depot { flex-wrap: wrap; }
  .ligne-depot-texte { flex-basis: calc(100% - 80px); }
  .champs-ia { grid-template-columns: 1fr; gap: 0; }
  .champs-ia dt { margin-top: 8px; }
}
/* --- Boîte IA : vérifier et valider (17.3) --------------------------------- */
.seulement-tel { display: none; }
.chips-etats { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 14px; }
.chips-etats .chip { text-decoration: none; color: var(--ink); }
.chips-etats .chip-actif { color: var(--on-plum); }
.feuille-icone-forte { background: var(--plum-bg); color: var(--on-plum); }
.file-verif { display: flex; flex-direction: column; gap: 14px; margin: 8px 0 16px; }
.carte-verif { background: var(--surface); border: 1px solid var(--line-strong); border-left: 3px solid var(--plum);
  border-radius: 0; padding: 14px 16px; }
.carte-verif-tete { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px; margin-bottom: 12px; }
.carte-verif-tete .carte-sous { flex-basis: 100%; }
.doublon-ia { flex-basis: 100%; margin: 4px 0 0; padding: 6px 10px; border-radius: 0;
  background: var(--ambre-soft); color: var(--ambre); border: 1px solid var(--ambre-bord); font-size: 13.5px; }
.carte-verif-corps { display: grid; grid-template-columns: minmax(180px, 1fr) 2fr; gap: 18px; align-items: start; }
.carte-verif-doc img { display: block; max-width: 100%; max-height: 360px; border-radius: 0; border: 1px solid var(--line); }
.doc-carte { display: inline-block; text-decoration: none; margin-bottom: 8px; }
.doc-pdf { display: flex; align-items: center; gap: 8px; }
.texte-depot-cite { margin: 0 0 8px; padding: 8px 12px; border-left: 3px solid var(--line-strong);
  color: var(--ink); font-style: italic; white-space: pre-line; overflow-wrap: anywhere; }
.texte-entier summary { cursor: pointer; color: var(--muted); font-size: 13px; }
.rattachement { margin: 8px 0 0; padding: 6px 10px; border-radius: 0; font-size: 13.5px; }
.rattachement-vert { background: var(--vert-soft); color: var(--vert); }
.rattachement-ambre { background: var(--ambre-soft); color: var(--ambre); }
.ligne-champ { display: grid; grid-template-columns: 150px minmax(0, 1fr) 190px; gap: 2px 10px;
  align-items: center; padding: 3px 6px; border-radius: 0; }
.ligne-champ > label { font-size: 13.5px; color: var(--muted); }
.ligne-champ input, .ligne-champ select, .ligne-champ textarea { width: 100%; min-width: 0; }
.ligne-champ.champ-jaune { background: var(--ambre-soft); }
.origine-champ { font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }
.origine-lu { color: var(--vert); }
.origine-deduit { color: var(--ambre); }
.origine-toi { color: var(--plum); }
.champ-message { grid-column: 2 / 4; font-size: 13px; color: var(--muted); }
.champ-message-doute { color: var(--ambre); font-weight: 600; }
.champ-message-erreur { color: var(--rouge); font-weight: 600; }
.ligne-champ-erreur input, .ligne-champ-erreur select { border-color: var(--rouge); }
.lignes-verif { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.ligne-verif { border: 1px solid var(--line); border-radius: 0; padding: 6px 8px; margin: 0; }
.ligne-verif legend { font-size: 12px; color: var(--muted); padding: 0 4px; }
.doute-global { display: flex; gap: 8px; align-items: center; margin-top: 8px; padding: 6px 10px; border-radius: 0;
  background: var(--ambre-soft); color: var(--ambre); font-weight: 600; font-size: 13.5px; }
.carte-verif-gestes { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.form-rejet { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.form-rejet input { flex: 1 1 220px; min-width: 0; }
.carte-compacte > summary { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; cursor: pointer; list-style: none; }
.carte-compacte > summary::-webkit-details-marker { display: none; }
.carte-compacte > summary .carte-sous { flex: 1 1 200px; }
.carte-compacte[open] > summary { margin-bottom: 12px; }
.sorts-propositions { list-style: none; margin: 6px 0 0; padding: 0; font-size: 13.5px; }
.sorts-propositions li { margin: 3px 0; }
.sorts-propositions .badge { font-size: 12.5px; padding: 2px 8px; }
.gestes-depot form { margin-left: auto; }
@media (max-width: 900px) {
  .carte-verif-corps { grid-template-columns: 1fr; }
  .carte-verif-doc img { max-height: 220px; }
}
@media (max-width: 640px) {
  .seulement-tel { display: initial; }
  .seulement-bureau { display: none; }
  p.seulement-tel, .champs-ia.seulement-tel { display: grid; }
  p.seulement-tel { display: block; }
  .table-wrap.seulement-tel { display: block; }
  /* Déposer : la photo d'abord, en grand ; puis Photo · Texte · Vocal. */
  .boutons-depot .bouton-photo { flex: 1 1 100%; padding: 16px; font-size: 16px; background: var(--plum-bg); color: var(--on-plum); border-color: var(--plum-bg); }
  .boutons-depot .bouton-depot:not(.bouton-photo) { flex: 1 1 0; }
  /* Les cartes compactes de « Ce que l'IA a compris » : ligne par ligne, lu / déduit à droite. */
  .compris-ia .champs-ia { grid-template-columns: 1fr; }
  .compris-ia .champs-ia dd { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 2px 8px; }
  .gestes-depot { flex-direction: column; align-items: stretch; }
  .gestes-depot .btn, .gestes-depot form, .gestes-depot form .btn { width: 100%; margin-left: 0; text-align: center; }
  /* À vérifier : les champs empilés, l'origine à droite du libellé, Valider en pleine largeur. */
  .ligne-champ { grid-template-columns: minmax(0, 1fr) auto; padding: 6px; }
  .ligne-champ > label { grid-column: 1; }
  .origine-champ { grid-column: 2; grid-row: 1; text-align: right; max-width: 55vw; }
  .ligne-champ input, .ligne-champ select, .ligne-champ textarea { grid-column: 1 / 3; }
  .champ-message { grid-column: 1 / 3; }
  .carte-verif { padding: 12px; }
  .carte-verif-gestes .btn { flex: 1 1 100%; text-align: center; }
  .carte-verif-gestes .btn-primary { order: -1; padding: 13px; font-size: 15px; }
  .form-rejet .btn { flex: 1 1 100%; }
}
/* --- Analyse › Demander à l'IA (17.4) -------------------------------------- */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.cols-question { grid-template-columns: 1.6fr 1fr; }
.form-question textarea { width: 100%; font-size: 16px; }
.chips-question { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; }
.chips-question .chip { font-family: inherit; }
.reponse-ia .question-posee { font-family: var(--font-display); font-size: 18px; margin: 0 0 10px; }
.reponse-ia .question-posee .hint { display: block; font-family: var(--font-body, inherit); font-size: 13px; }
.reponse-texte { font-size: 16px; line-height: 1.55; margin-bottom: 12px; }
.reponse-texte strong { color: var(--plum-ink); }
.sources-ia { margin: 12px 0; padding: 10px 12px; border-radius: 0; background: var(--bg); border: 1px solid var(--line); }
.sources-ia ul { margin: 4px 0 8px; padding-left: 18px; }
.sources-ia .btn { margin: 2px 6px 2px 0; }
.liste-sobre { margin: 0 0 8px; padding-left: 18px; }
.questions-recentes { list-style: none; margin: 0 0 10px; padding: 0; }
.questions-recentes li { padding: 6px 0; border-top: 1px solid var(--line); }
.questions-recentes li:first-child { border-top: 0; }
.bandeau-question { margin: 12px 0 0; padding: 14px 16px; border-radius: 0; background: var(--plum-soft);
  border: 1px solid var(--line); }
.bandeau-question-ligne { display: flex; gap: 8px; margin: 8px 0 4px; }
.bandeau-question-ligne input { flex: 1 1 auto; min-width: 0; }
.bandeau-question .hint { margin: 4px 0 0; }
@media (max-width: 900px) { .cols-question { grid-template-columns: 1fr; } }
@media (max-width: 640px) {
  .bandeau-question-ligne { flex-direction: column; }
  .chips-question .chip { white-space: normal; text-align: left; }
}/* Une colonne de grille ne s'élargit pas pour un tableau : il défile dans son cadre. */
.cols-ia > * { min-width: 0; }

/* --- 17.5 : six défauts d'affichage --------------------------------------- */
/* Un lien dans l'en-tête prune d'un tableau (les années du Soufre comparé, les
   régions de « Par région ») : il prenait la couleur du fond, et disparaissait. */
thead th a { color: inherit; text-decoration: underline dotted; }
/* La barre des filtres de Ventes et de Dépenses : une seule ligne à 1 280 px,
   comme celle de l'Analyse. Les menus nus prenaient chacun toute la largeur. */
.filters-ligne > select, .filters-ligne > .champ-recherche { width: auto; flex: 1 1 160px; }
.filters-ligne > .champ-recherche { flex: 2 1 260px; }
@media (max-width: 700px) {
  .filters-ligne > select, .filters-ligne > .champ-recherche { flex: 1 1 100%; width: 100%; }
}
/* « Vos 10 dernières saisies » et la liste des dépenses : le tableau défile dans
   son cadre au lieu de couper Dupliquer et Supprimer ; la mention d'IVA sous le
   TTC s'efface sous 1 400 px (elle reste dans le title de la cellule). */
.table-depenses { overflow-x: auto; max-width: 100%; }
@media (max-width: 1400px) { .iva-ttc { display: none; } }
@media (max-width: 480px) { .table-depenses .col-action { white-space: normal; } }
/* --- La fiche complète et le formulaire court (17.6) ----------------------- */
.fiche-tete .lead-sm .badge { margin-left: 6px; vertical-align: 1px; }
.fiche-tete h1 .interet-points { font-size: 14px; vertical-align: middle; }
.fiche-actions { align-items: center; }
.menu-fiche { position: relative; }
.menu-fiche > summary { list-style: none; min-width: 42px; text-align: center; }
.menu-fiche > summary::-webkit-details-marker { display: none; }
.menu-fiche-liste { position: absolute; right: 0; top: calc(100% + 6px); z-index: 30; width: 300px; max-width: 86vw;
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: 0; box-shadow: var(--ombre-menu);
  padding: 6px; display: flex; flex-direction: column; }
.menu-fiche-liste a { display: block; padding: 9px 10px; border-radius: 0; color: var(--ink); text-decoration: none; }
.menu-fiche-liste a:hover, .menu-fiche-liste a:focus { background: var(--gris-soft); }
.menu-fiche-liste .sub { font-size: 12.5px; }
.menu-fiche-note { margin: 4px 10px; padding-top: 6px; border-top: 1px solid var(--line); color: var(--muted); font-size: 13px; }
.menu-fiche-liste .menu-fiche-danger { color: var(--rouge); border-top: 1px solid var(--line); margin-top: 4px; }
.identite-colonnes { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); gap: 0 28px; align-items: start; }
.table-contacts td, .table-contacts th { padding: 9px 12px; }
.cols-fiche { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: 0 16px; align-items: start; }
.cols-fiche > div > .panel:first-child { margin-top: 16px; }
.encadre-rdv { margin: 14px 0; padding: 12px 14px; border: 1px solid var(--ambre-bord); border-left: 4px solid var(--ambre-fort);
  border-radius: 0; background: var(--ambre-soft); }
.encadre-rdv h3 { margin-top: 0; }
.frise { list-style: none; margin: 12px 0 8px; padding: 0; }
.frise li { display: grid; grid-template-columns: 80px minmax(0, 1fr) auto; gap: 10px; padding: 8px 0; border-top: 1px solid var(--line); font-size: 14.5px; }
.frise li:first-child { border-top: 0; }
.frise-date { color: var(--muted); font-size: 13px; white-space: nowrap; }
.frise-qui { color: var(--muted); font-size: 13px; }
.frise-auto .frise-texte { color: var(--muted); }
.geste-rare { margin-top: 10px; }
.synthese-client { font-weight: 600; margin: 0 0 8px; }
.documents-courts { list-style: none; margin: 0 0 10px; padding: 0; }
.documents-courts li { display: flex; align-items: center; gap: 8px; padding: 7px 0; border-top: 1px solid var(--line); }
.documents-courts li:first-child { border-top: 0; }
.documents-nom { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.croix { border: 0; background: none; color: var(--muted); font-size: 20px; line-height: 1; padding: 2px 6px; cursor: pointer; border-radius: 0; }
.croix:hover { color: var(--rouge); background: var(--rouge-soft); }
.cols-court { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 16px; align-items: start; }
.form-court { margin: 0; }
.champ-rapide { display: flex; flex-direction: column; gap: 4px; margin: 14px 0 0; max-width: 520px; }
.champ-rapide input, .champ-rapide select { width: 100%; }
.libelle-champ { display: block; font-weight: 500; margin-bottom: 2px; }
.type-autre { display: inline-block; }
.type-autre > summary { list-style: none; display: inline-block; }
.type-autre > summary::-webkit-details-marker { display: none; }
.type-autre[open] select { margin-top: 8px; width: auto; min-width: 220px; }
.doublon-direct { margin: 6px 0 0; padding: 8px 12px; border-radius: 0; background: var(--ambre-soft); color: var(--ink);
  border: 1px solid var(--ambre-bord); font-size: 14px; }
.encart-ensuite p { margin: 0 0 10px; }
@media (max-width: 900px) {
  .cols-fiche, .identite-colonnes, .cols-court { grid-template-columns: minmax(0, 1fr); }
  .identite-colonnes .dl { margin-bottom: 14px; }
}
@media (max-width: 640px) {
  .fiche-actions { width: 100%; }
  .fiche-actions > .btn, .fiche-actions > form { flex: 1 1 auto; }
  .menu-fiche-liste { right: 0; }
  .frise li { grid-template-columns: 64px minmax(0, 1fr); }
  .frise-qui { grid-column: 2; }
}
/* --- 18.2 : la banque ------------------------------------------------------ */
.texte-vert { color: var(--vert); }
.texte-ambre { color: var(--ambre); }
.prop-banque { display: block; font-size: 12.5px; color: var(--ambre); }
.table-banque td { font-size: 13.5px; }
.table-banque .nom { font-weight: 600; }
.table-banque tr.ligne-a-decider > td { background: var(--ambre-soft); }
.table-banque tr.ligne-ignoree > td { color: var(--muted); }
.table-banque tr.ligne-ignoree .nom { text-decoration: line-through; }
.table-banque .col-action { min-width: 190px; text-align: right; }
.geste-banque { display: inline; margin: 0; }
/* « Autre… » : les gestes de la ligne, dépliés sous elle. */
.gestes-autres { display: inline-block; text-align: left; }
.gestes-autres > summary { list-style: none; cursor: pointer; }
.gestes-autres > summary::-webkit-details-marker { display: none; }
.gestes-autres[open] { display: block; margin-top: 6px; }
.gestes-autres-corps { display: flex; flex-direction: column; gap: 10px; padding: 10px 12px; margin-top: 6px;
  border: 1px solid var(--line-strong); border-radius: 0; background: var(--surface); }
.gestes-autres-corps form { display: flex; flex-direction: column; gap: 6px; }
.gestes-autres-corps select, .gestes-autres-corps input:not([type="checkbox"]):not([type="radio"]) { width: 100%; }
.gestes-titre { margin: 0; font-size: 13px; font-weight: 700; text-transform: none; letter-spacing: 0; color: var(--etiquette); }
.lien-changer { cursor: pointer; color: var(--plum); font-size: 13px; margin-left: 8px; }
.deux-panneaux { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 16px; align-items: start; }
.deux-panneaux > .panel { margin: 0; }
.liste-releve { list-style: none; margin: 0; padding: 0; }
.liste-releve li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px; padding: 8px 0; border-top: 1px solid var(--line); font-size: 14px; }
.liste-releve li:first-child { border-top: 0; }
.liste-releve .releve-quoi { flex: 1 1 200px; min-width: 0; }
.liste-releve .num { margin-left: auto; font-variant-numeric: tabular-nums; }
.liste-releve .sub { display: block; }
.paiement-releve { margin: 4px 0 10px; }
/* Le relevé à vérifier : une ligne, sa décision, son montant à droite. */
.releve-chiffres { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.releve-chiffres p { margin: 0; font-size: 14px; }
.section-banque > summary { cursor: pointer; }
.titre-section-banque { margin: 0 0 4px; font-size: 13px; font-weight: 700; text-transform: none; letter-spacing: 0; color: var(--etiquette); }
.titre-section-banque .hint { text-transform: none; letter-spacing: 0; font-weight: 400; margin-left: 6px; }
.ligne-banque { display: grid; grid-template-columns: 64px minmax(0, 1fr) 120px; gap: 12px; align-items: start;
  padding: 12px 0; border-top: 1px solid var(--line); }
.ligne-banque:first-of-type { border-top: 0; }
.ligne-banque-date { color: var(--muted); font-size: 13px; padding-top: 2px; }
.ligne-banque-montant { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; }
.ligne-banque .nom { font-weight: 600; margin: 0; }
.ligne-banque-erreur { background: var(--rouge-soft); border-radius: 0; padding-left: 8px; padding-right: 8px; }
.ligne-banque-repli > summary { cursor: pointer; font-size: 14px; }
.decision-banque .ligne-chips { margin: 8px 0 4px; }
.decision-banque .groupe-decision { margin-top: 8px; }
.decision-banque .champ-message { display: block; margin: 4px 0; }
.decision-banque input.prerempli, .decision-banque select.prerempli { background: var(--jaune-soft); border-color: var(--jaune-bord); }
.decision-banque .champ-large { display: flex; flex-direction: column; max-width: 640px; }
/* Les champs de la décision cochée, et eux seuls — sans script, par :has().
   Un navigateur qui ne le connaît pas les montre tous : rien ne se perd. */
.decision-banque:has(input[name$="[action]"][value=""]:checked) .groupe-decision,
.decision-banque:has(input[name$="[action]"][value="depense"]:checked) .groupe-decision:not([data-pour~="depense"]),
.decision-banque:has(input[name$="[action]"][value="recette"]:checked) .groupe-decision:not([data-pour~="recette"]),
.decision-banque:has(input[name$="[action]"][value="rattacher"]:checked) .groupe-decision:not([data-pour~="rattacher"]),
.decision-banque:has(input[name$="[action]"][value="ignorer"]:checked) .groupe-decision:not([data-pour~="ignorer"]) { display: none; }
.decision-banque:not(:has(input[name$="[action]"]:checked)) .groupe-decision { display: none; }
.actions-releve { position: sticky; bottom: 0; background: var(--bg); padding: 12px 0; z-index: 2; }
@media (max-width: 900px) {
  .deux-panneaux, .releve-chiffres { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .ligne-banque { grid-template-columns: 1fr; gap: 4px; }
  .ligne-banque-montant { text-align: left; order: -1; }
  .table-banque .col-action { min-width: 0; text-align: left; }
  .table-banque .col-action .btn, .table-banque .geste-banque, .table-banque .gestes-autres { display: block; width: 100%; }
  .table-banque .geste-banque .btn { width: 100%; min-height: 44px; margin-bottom: 6px; }
  .actions-releve .btn { flex: 1 1 100%; }
}

/* --- 18.3 : le relevé PDF, la facture qui retrouve sa ligne ------------------ */
.jonction-banque { margin: 8px 0 0; padding: 10px 12px; border-radius: 0; background: var(--jaune-soft); border: 1px solid var(--jaune-bord); font-size: 14px; }
.jonction-banque p { margin: 0 0 6px; }
.jonction-banque .hint { margin-left: 8px; }
.bandeau-ecart .gestes-ecart { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
.entree-vente { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.ligne-banque-trouvee { margin: 4px 0 0; color: var(--vert); font-weight: 600; }
.carte-releve .carte-verif-droite p { margin: 0 0 8px; }

/* --- 18.4 : les listes simplifiées, la fiche simplifiée ----------------------- */
.tete-liste { display: flex; align-items: center; justify-content: space-between; gap: 16px 20px; flex-wrap: wrap; padding: 8px 0 0; }
.tete-liste h1 { margin: 0; }
.recherche-liste { position: relative; flex: 1 1 380px; max-width: 640px; margin: 0; }
.recherche-liste input[type="search"] { width: 100%; padding: 11px 14px 11px 40px; font-size: 15px; border-radius: 0; }
.recherche-liste .icone-loupe { position: absolute; left: 13px; top: 50%; transform: translateY(-50%); width: 18px; height: 18px; color: var(--muted); pointer-events: none; }
.etats-liste { display: flex; align-items: center; gap: 8px; margin: 14px 0 8px; }
.etats-pastilles { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; flex: 1 1 auto; min-width: 0; }
.etats-menus { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.pill { display: inline-flex; align-items: center; gap: 6px; padding: 7px 13px; border-radius: 0; border: 1px solid var(--line-strong);
  background: var(--surface); font-family: var(--font-body); font-size: 13px; font-weight: 600; text-transform: none; letter-spacing: 0; color: var(--ink); white-space: nowrap; text-decoration: none; cursor: pointer; }
.pill:hover { border-color: var(--plum); text-decoration: none; }
.pill .n { font-size: 12.5px; font-weight: 700; color: var(--muted); }
.pill.on { background: var(--plum-bg); border-color: var(--plum-bg); color: var(--on-plum); }
.pill.on .n { color: var(--on-plum); opacity: .85; }
.pill-rouge { border-color: var(--rouge); background: var(--surface); color: var(--rouge); }
.pill-rouge .n { background: var(--badge-rouge); color: var(--sur-rouge); padding: 0 6px; }
.pill-rouge.on { background: var(--badge-rouge); border-color: var(--badge-rouge); color: var(--sur-rouge); }
.pill-rouge.on .n { opacity: 1; }
.menu-liste { position: relative; }
.menu-liste > summary { list-style: none; }
.menu-liste > summary::-webkit-details-marker { display: none; }
.menu-liste-corps { position: absolute; right: 0; top: calc(100% + 6px); z-index: 30; min-width: 270px; max-width: 86vw; max-height: 70vh; overflow-y: auto;
  display: flex; flex-direction: column; gap: 2px; padding: 8px; background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: 0; box-shadow: var(--ombre-menu); font-size: 14px; }
.menu-liste-corps > a { display: flex; justify-content: space-between; gap: 12px; padding: 7px 10px; border-radius: 0; color: var(--ink); text-decoration: none; }
.menu-liste-corps > a:hover, .menu-liste-corps > a.on { background: var(--gris-soft); }
.menu-liste-form { display: flex; flex-direction: column; gap: 8px; padding: 4px 6px 8px; }
.menu-liste-form select { width: 100%; }
.menu-liste-sep { display: block; height: 1px; background: var(--line); margin: 4px 0; }
.count-petit { font-size: 13px; margin: 0 4px 10px; }
/* La fiche : « À faire », teinté, une ligne par chose due. */
.a-faire-fiche { border: 1px solid var(--rouge-bord); border-left: 5px solid var(--badge-rouge); background: var(--rouge-soft); border-radius: 0; padding: 12px 18px;
  display: flex; flex-direction: column; gap: 8px; margin: 0 0 16px; }
.a-faire-ligne { display: flex; align-items: center; gap: 8px 12px; flex-wrap: wrap; }
.a-faire-quoi { font-weight: 600; }
.a-faire-detail { color: var(--muted); font-size: 13.5px; flex: 1 1 200px; }
.a-faire-gestes { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.a-faire-gestes .champ-numero { width: 130px; }
.cols-fiche-simple { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
.cols-fiche-simple > div > .panel:first-child { margin-top: 0; }
.ventes-fiche { list-style: none; margin: 6px 0 8px; padding: 0; }
.vente-fiche { display: grid; grid-template-columns: 64px minmax(0, 1fr) auto auto; gap: 10px; align-items: center;
  padding: 9px 0; border-top: 1px solid var(--line); font-size: 14px; }
.vente-fiche:first-child { border-top: 0; }
.vente-date { color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }
.vente-contenu a { color: var(--ink); }
.vente-ht { font-weight: 600; white-space: nowrap; }
.contact-titre { margin-top: 14px; }
.contact-titre h3 { margin: 0; }
.contact-fiche { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 16px; font-size: 14px; margin: 6px 0 4px; }
.contact-fiche .k { display: block; color: var(--muted); font-size: 12.5px; }
.bas-fiche { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 16px; }
.bas-fiche > details { margin: 0; }
@media (max-width: 900px) {
  .cols-fiche-simple, .bas-fiche, .contact-fiche { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
  /* Sur téléphone : la rangée de pastilles défile au doigt, les menus dessous. */
  .etats-liste { flex-wrap: wrap; }
  .etats-pastilles { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 4px; flex: 1 1 100%; }
  .etats-menus { width: 100%; }
  .menu-liste-corps { position: fixed; left: 12px; right: 12px; top: auto; bottom: 80px; max-width: none; }
  .vente-fiche { grid-template-columns: 56px minmax(0, 1fr) auto; }
  .vente-fiche .badge { grid-column: 2; justify-self: start; }
}

/* --- 18.6 : l'habillage du site ------------------------------------------------
   Les liens dans le texte : à l'encre, soulignés d'un trait gris qui fonce au
   survol. Les boutons, la navigation, les onglets, les pastilles, les tuiles et
   les noms en gras des listes ne le sont pas. À l'écran seulement : le papier
   garde ses liens noirs sans trait. */
@media screen {
  :where(p, td, .hint, .muted, .sub) a:where(:not(.btn, .chip, .pill, .badge, .tri-entete)) {
    color: var(--ink); text-decoration: underline; text-decoration-color: var(--line-strong);
    text-decoration-thickness: 1px; text-underline-offset: 3px;
  }
  :where(p, td, .hint, .muted, .sub) a:where(:not(.btn, .chip, .pill, .badge, .tri-entete)):hover { text-decoration-color: var(--ink); }
  .cell-nom a, .vente-contenu a, .rangee-titre, .carte-tete a, .ligne-completer-texte a, .liste-parties a,
  .dash-table tbody th a, .chiffres a.stat, a.kpi, .liste-documents a, .doc-carte, .trombone { text-decoration: none; }
  .cell-nom a:hover, .vente-contenu a:hover { text-decoration: underline; text-decoration-color: var(--ink); }
}
/* Les capitales espacées prennent de la place : sur un écran moyen, le menu du
   haut se resserre plutôt que de passer sur deux lignes ; sur téléphone, un
   bouton ou une pastille au libellé long passe à la ligne au lieu d'élargir la
   page. */
@media (max-width: 1180px) {
  .brand-name { letter-spacing: .3em; }
}
/* 19.2 : sous 1 100 px, les mots de la barre passent à 10,5 px, plus serrés. */
@media (max-width: 1100px) {
  .nav { gap: 10px; }
  .nav-entree { font-size: 10.5px; letter-spacing: .1em; }
  .topbar-inner { gap: 16px; }
}
@media (max-width: 640px) {
  .btn, .chip { white-space: normal; text-align: center; }
  .btn { letter-spacing: .01em; }
  .brand-name { letter-spacing: .3em; }
}

/* --- 18.8 : la ligne porte son état ---------------------------------------------
   En CSS seulement, par :has() : la couleur du badge d'une ligne se reporte sur
   un trait gauche de 5 px, et en fond pâle pour le rouge et l'ambre. Les règles
   vont du plus calme au plus pressant : si une ligne porte deux badges, la
   dernière qui s'applique — la plus pressante — l'emporte. Un badge neutre
   (quantité, intérêt…) ne colore rien. */
table.list tbody tr:has(> td:first-child .badge-gris:not(.badge-neutre)) > td:first-child { border-left-color: var(--line-strong); }
table.list tbody tr:has(> td:first-child .badge-vert:not(.badge-neutre)) > td:first-child { border-left-color: var(--badge-vert); }
table.list tbody tr:has(> td:first-child .badge-prune:not(.badge-neutre)) > td:first-child { border-left-color: var(--prune-etat-bord); }
table.list tbody tr:has(> td:first-child :is(.badge-bleu-clair, .badge-bleu-fonce):not(.badge-neutre)) > td:first-child { border-left-color: var(--bleu-clair-bord); }
table.list tbody tr:has(> td:first-child .badge-bleu:not(.badge-neutre)) > td:first-child { border-left-color: var(--badge-bleu); }
table.list tbody tr:has(> td:first-child :is(.badge-ambre, .badge-ambre-fort):not(.badge-neutre)) > td { background: var(--ambre-soft); }
table.list tbody tr:has(> td:first-child :is(.badge-ambre, .badge-ambre-fort):not(.badge-neutre)) > td:first-child { border-left-color: var(--badge-ambre); }
table.list tbody tr:has(> td:first-child .badge-rouge:not(.badge-neutre)) > td { background: var(--rouge-soft); }
table.list tbody tr:has(> td:first-child .badge-rouge:not(.badge-neutre)) > td:first-child { border-left-color: var(--badge-rouge); }
/* La Banque porte son badge dans la colonne État : toute la ligne compte. */
table.list.table-banque tbody tr:has(.badge-vert:not(.badge-neutre)) > td:first-child { border-left-color: var(--badge-vert); }
table.list.table-banque tbody tr:has(.badge-prune:not(.badge-neutre)) > td:first-child { border-left-color: var(--prune-etat-bord); }
table.list.table-banque tbody tr:has(:is(.badge-ambre, .badge-ambre-fort):not(.badge-neutre)) > td { background: var(--ambre-soft); }
table.list.table-banque tbody tr:has(:is(.badge-ambre, .badge-ambre-fort):not(.badge-neutre)) > td:first-child { border-left-color: var(--badge-ambre); }
table.list.table-banque tbody tr:has(.badge-rouge:not(.badge-neutre)) > td { background: var(--rouge-soft); }
table.list.table-banque tbody tr:has(.badge-rouge:not(.badge-neutre)) > td:first-child { border-left-color: var(--badge-rouge); }
/* Sur téléphone, la ligne devient une carte : le trait passe sur la carte. */
@media (max-width: 640px) {
  .table-cartes tbody tr:has(> td:first-child .badge-rouge:not(.badge-neutre)) { border-left: 5px solid var(--badge-rouge); background: var(--rouge-soft); }
  .table-cartes tbody tr:has(> td:first-child :is(.badge-ambre, .badge-ambre-fort):not(.badge-neutre)) { border-left: 5px solid var(--badge-ambre); background: var(--ambre-soft); }
  .table-cartes tbody tr:has(> td:first-child .badge-bleu:not(.badge-neutre)) { border-left: 5px solid var(--badge-bleu); }
}

/* Les rangées de l'accueil : la même lecture. */
@media (min-width: 701px) { .rangee { border-left: 5px solid transparent; } }
.rangee:has(.badge-vert:not(.badge-neutre)) { border-left-color: var(--badge-vert); }
.rangee:has(:is(.badge-ambre, .badge-ambre-fort):not(.badge-neutre)) { border-left: 5px solid var(--badge-ambre); background: var(--ambre-soft); }
.rangee:has(.badge-rouge:not(.badge-neutre)), .rangee.rangee-retard { border-left: 5px solid var(--badge-rouge); background: var(--rouge-soft); }
/* Le panneau « En retard » de l'accueil : un bord haut rouge, le titre en rouge. */
.panneau-retard { border-top: 4px solid var(--badge-rouge); }
.panneau-retard h2 { color: var(--rouge); }
/* Les jours de retard, partout où ils se lisent. */
@media screen {
  .rangee-quand.etiquette-retard, .chai-retard, .d.retard, .etiquette-retard { color: var(--rouge); font-weight: 700; font-size: 13.5px; }
}
/* Sur le papier, un badge n'a pas de fond (les navigateurs n'impriment pas les
   fonds) : son texte passe au noir, dans un filet gris — lisible comme avant. */
@media print {
  .badge { background: transparent !important; color: #000 !important; border: 1px solid #888 !important; }
}

/* Les cinq ventes de la fiche : trait de 4 px et fond pâle pour le rouge et
   l'ambre, trait seul pour le vert. */
.vente-fiche { border-left: 4px solid transparent; }
.vente-fiche:has(.badge-vert) { border-left-color: var(--badge-vert); }
.vente-fiche:has(:is(.badge-ambre, .badge-ambre-fort)) { border-left-color: var(--badge-ambre); background: var(--ambre-soft); }
.vente-fiche:has(.badge-rouge) { border-left-color: var(--badge-rouge); background: var(--rouge-soft); }

/* Les étapes du chai : la prochaine sur fond ambre pâle (la faite en vert pâle
   et celle en retard en rouge pâle, plus haut). */
.etapes-chai .ligne-etape:has(.etape-marque.etape-prochaine):not(.etape-retard) { background: var(--ambre-soft); padding-left: 8px; padding-right: 8px; }

/* Les familles de l'agenda, cochées : le fond de leur couleur, texte blanc
   (noir sur l'ambre). Le point reste. */
.chip-famille.chip-actif:has(.point-rouge) { background: var(--badge-rouge); border-color: var(--badge-rouge); color: var(--sur-rouge); }
.chip-famille.chip-actif:has(:is(.point-ambre, .point-ambre-fort)) { background: var(--badge-ambre); border-color: var(--badge-ambre); color: var(--sur-ambre); }
.chip-famille.chip-actif:has(.point-bleu) { background: var(--badge-bleu); border-color: var(--badge-bleu); color: var(--sur-bleu); }
.chip-famille.chip-actif:has(.point-bleu-clair) { background: var(--badge-plan); border-color: var(--bleu-clair-bord); color: var(--sur-plan); }
.chip-famille.chip-actif:has(.point-prune) { background: var(--badge-prune); border-color: var(--prune-etat-bord); color: var(--sur-prune); }
.chip-famille.chip-actif:has(.point-vert) { background: var(--badge-vert); border-color: var(--badge-vert); color: var(--sur-vert); }
.chip-famille.chip-actif:has(.point-gris) { background: var(--badge-gris); border-color: var(--line-strong); color: var(--sur-gris); }
.chip-famille.chip-actif .point-famille { box-shadow: 0 0 0 2px #fff; }

/* --- 19.0 : alignements -----------------------------------------------------------
   Dans une liste, chaque colonne a une largeur fixe, et ce qui est dans une colonne
   a la même largeur : les badges une largeur minimale commune, texte centré ; les
   boutons remplissent leur colonne ; dans un groupe de boutons côte à côte, tous
   prennent la largeur du plus large. Le texte commence à 12 px du trait de
   couleur. Sur téléphone, rien de cela : les listes y sont des cartes. */

/* 1. Les briques. Le signe d'un badge s'écarte de son texte par `gap` : dans une
   boîte flex, l'espace qui le suivait disparaissait. */
.btn { min-height: 36px; padding: 0 14px; }
.btn-sm { min-height: 32px; padding: 0 11px; }
.badge { display: inline-flex; align-items: center; justify-content: center; gap: 7px; min-height: 26px; padding: 0 10px; }
.badge.badge-neutre { padding: 0 9px; }

@media (min-width: 641px) {
  /* Les groupes de boutons côte à côte : une grille dont chaque colonne vaut la
     plus large. Seulement quand le groupe ne contient que des boutons et des
     formulaires — une aide ou un menu à côté le laisse tel qu'il était. */
  :is(.page-head .actions, .a-faire-gestes, .carte-verif-gestes):not(:has(> :not(.btn, form))) {
    display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 8px; align-items: center;
  }
  .carte-verif-gestes:not(:has(> :not(.btn, form))) { width: fit-content; max-width: 100%; }
  :is(.page-head .actions, .a-faire-gestes, .carte-verif-gestes, .rangee-geste) > .btn { width: 100%; }
  :is(.page-head .actions, .a-faire-gestes, .carte-verif-gestes, .rangee-geste) > form { display: flex; gap: 6px; align-items: center; margin: 0; }
  :is(.page-head .actions, .a-faire-gestes, .carte-verif-gestes, .rangee-geste) > form > .btn { flex: 1 1 auto; }
  /* Les boutons d'enregistrement d'un formulaire gardent leur ligne (et l'aide à
     côté) : ils prennent au moins la même largeur. */
  .panel-actions > .btn, .panel-actions > form > .btn { min-width: 140px; }

  /* L'en-tête d'une fiche : les boutons de même largeur, 140 px au moins, le
     « … » à 44 px — il est toujours le dernier. */
  .fiche-actions { display: grid; grid-auto-flow: column; gap: 8px; align-items: center; }
  .fiche-actions:has(> :nth-child(2):last-child) { grid-template-columns: repeat(1, minmax(140px, 1fr)) 44px; }
  .fiche-actions:has(> :nth-child(3):last-child) { grid-template-columns: repeat(2, minmax(140px, 1fr)) 44px; }
  .fiche-actions:has(> :nth-child(4):last-child) { grid-template-columns: repeat(3, minmax(140px, 1fr)) 44px; }
  .fiche-actions:has(> :nth-child(5):last-child) { grid-template-columns: repeat(4, minmax(140px, 1fr)) 44px; }
  .fiche-actions:has(> :nth-child(6):last-child) { grid-template-columns: repeat(5, minmax(140px, 1fr)) 44px; }
  .fiche-actions > .btn, .fiche-actions > form > .btn { width: 100%; }
  .fiche-actions > form { display: flex; margin: 0; }
  .fiche-actions > .menu-fiche > summary { width: 44px; min-width: 0; padding: 0; }

  /* L'en-tête de l'agenda : ← et → à 44 px, les autres de même largeur. */
  .page-head .actions:has(> .btn:first-child[title][href^="agenda.php"]) { grid-template-columns: 44px minmax(0, 1fr) 44px; grid-auto-columns: minmax(0, 1fr); }
  .page-head .actions:has(> .btn:first-child[title][href^="agenda.php"]) > .btn { padding: 0 8px; }
}

/* Une carte de l'agenda : les boutons remplissent la carte, l'un sous l'autre ;
   « Reporter » en dessous, sur sa ligne. */
.carte-jour .carte-gestes { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; }
.carte-jour .carte-gestes > form { display: flex; gap: 6px; margin: 0; }
.carte-jour .carte-gestes .btn { width: 100%; }

/* 2. L'accueil : quatre colonnes droites — l'étiquette, le texte, le retard, le
   geste. Le trait de 5 px reste, transparent quand la rangée n'est pas en
   retard : le texte commence toujours au même endroit. */
@media (min-width: 701px) {
  .rangee { grid-template-columns: 132px minmax(0, 1fr) 150px 168px; gap: 4px 14px; padding: 10px 18px 10px 13px;
    min-height: 60px; align-items: center; }
  .rangee-etiquette { grid-column: 1; }
  .rangee-texte { grid-column: 2; }
  .rangee-quand { grid-column: 3; justify-self: end; text-align: right; }
  .rangee-quand .badge { min-width: 140px; }
  .rangee-geste.carte-gestes { grid-column: 4; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
    gap: 6px; margin: 0; align-items: center; }
  .rangee-geste > .rangee-appel { width: 48px; }
}

/* 3. Les listes : des colonnes fixes. */
@media (min-width: 641px) {
  /* Les tableaux d'analyse, chargés de montants, et les lignes de saisie d'une
     vente ou d'une dépense gardent leurs largeurs automatiques. */
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime) { table-layout: fixed; width: 100%; }
  /* 19.2 : un mot ne se coupe que s'il ne tient pas seul dans sa colonne ; le
     texte long (`.sub`, le libellé d'une dépense) se coupe où il faut. */
  table.list.table-cartes td { overflow-wrap: break-word; }
  table.list.table-cartes td .sub, table.list.table-cartes td[data-label="Libellé"] { overflow-wrap: anywhere; }
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime) > thead > tr > th.num { width: 110px; }
  table.list .num { text-align: right; font-variant-numeric: tabular-nums; }
  /* Un montant ne se coupe pas : un peu moins de marge à gauche pour qu'il tienne. */
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime) > * > tr > .num { padding-left: 8px; overflow-wrap: normal; }
  /* La colonne d'état, quand c'est la première : 178 px, le badge à 150 px,
     la date ou le délai centré dessous. 19.2 : seulement elle — l'alerte d'un
     prospect (`.cell-urgence`) ou une ligne qui commence par un badge d'état.
     (Le sélecteur de l'en-tête avait perdu son début en 19.0 : la règle ne
     s'appliquait pas.) */
  table.list:has(> tbody > tr > td:first-child .badge:not(.badge-neutre)) > thead > tr > th:first-child,
  table.list > thead > tr > th.cell-urgence { width: 178px; padding-left: 17px; padding-right: 8px; text-align: center; }
  table.list > tbody > tr > td.cell-urgence,
  table.list > tbody > tr:has(> td:first-child .badge:not(.badge-neutre)) > td:first-child { padding-left: 17px; padding-right: 8px; text-align: center; vertical-align: middle; }
  table.list > tbody > tr > td:first-child .badge:not(.badge-neutre) { min-width: 150px; }
  table.list > tbody > tr > td.cell-urgence :is(.sub, .d),
  table.list > tbody > tr:has(> td:first-child .badge:not(.badge-neutre)) > td:first-child :is(.sub, .d) { display: block; text-align: center; }
  /* Une autre première colonne — un nom, une étape, une date : à gauche, en
     mots entiers, 160 px au moins. */
  table.list > thead > tr > th:first-child:not(.cell-coche, .cell-urgence),
  table.list > tbody > tr > td:first-child:not(.cell-coche, .cell-urgence) { min-width: 160px; overflow-wrap: normal; hyphens: none; }
  /* La colonne des gestes : 168 px, ses boutons pleine largeur, empilés. */
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime) > thead > tr > th.col-action { width: 168px; }
  table.list > tbody > tr > td.col-action { padding: 8px 12px; text-align: right; vertical-align: middle; }
  table.list > tbody > tr > td.col-action .btn { width: 100%; margin: 0; }
  table.list > tbody > tr > td.col-action > :is(form, .btn, .geste-banque) { display: flex; width: 100%; margin: 0; }
  table.list > tbody > tr > td.col-action > * + * { margin-top: 6px; }
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime).table-banque > thead > tr > th.col-action { width: 200px; }

  /* 5. Dépenses à faire : l'échéance, le reste, et la date et « Payée » sur une ligne. */
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime).table-factures > thead > tr > th:first-child { width: 130px; }
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime).table-factures > thead > tr > th.num { width: 130px; }
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime).table-factures > thead > tr > th.col-action { width: 240px; }
  table.list > tbody > tr > td.col-action > form.geste-payer { display: grid; }
  .geste-payer { display: grid; grid-template-columns: 130px 100px; gap: 8px; align-items: center; justify-content: end; }
  .geste-payer input[type="date"], .geste-payer select { width: 100%; }
  .geste-payer .btn { width: 100%; }

  /* 6. Ventes en cours : Livraison, Facture, Paiement à 170 px, leurs boutons et
     leurs champs de même largeur, empilés ; le HT à 100 px ; le « … » à 60 px. */
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime).table-en-cours > thead > tr > th:nth-child(4),
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime).table-en-cours > thead > tr > th:nth-child(5),
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime).table-en-cours > thead > tr > th:nth-child(6) { width: 170px; }
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime).table-en-cours > thead > tr > th.num { width: 100px; }
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime).table-en-cours > thead > tr > th.col-action { width: 60px; }
  .table-en-cours td.vente-ecran { vertical-align: middle; }
  .table-en-cours td.vente-ecran .geste-date { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .table-en-cours td.vente-ecran :is(.btn, .champ-numero, input[type="date"]) { width: 100%; }
  table.list.table-en-cours > tbody > tr > td.col-action { padding-left: 6px; padding-right: 6px; text-align: center; }
  /* L'Historique : la même largeur pour ses gestes, ses montants à 100 px. */
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime).table-historique > thead > tr > th.num { width: 100px; }
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime).table-historique > thead > tr > th.col-action { width: 230px; }
  .table-historique td.col-action .geste-ligne { display: grid; grid-template-columns: minmax(0, 1fr) 44px; gap: 6px; align-items: center; }
  .table-historique td.col-action .geste-date { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .table-historique td.col-action :is(.btn, .champ-numero) { width: 100%; }

  /* 4. La fiche. « À faire » : le badge, le texte, les gestes — en trois colonnes. */
  .a-faire-fiche { padding-left: 12px; }
  /* 19.2 : la colonne du badge à 190 px ; un badge plus long (« Relance en
     retard de 12 j ») passe à la ligne dans sa colonne plutôt que de déborder. */
  .a-faire-ligne { display: grid; grid-template-columns: 190px minmax(0, 1fr) auto; gap: 2px 14px; align-items: center; }
  .a-faire-ligne > .badge { grid-column: 1; grid-row: 1 / span 2; min-width: 160px; justify-self: start; }
  .a-faire-quoi { grid-column: 2; grid-row: 1; }
  .a-faire-detail { grid-column: 2; grid-row: 2; }
  .a-faire-gestes { grid-column: 3; grid-row: 1 / span 2; grid-auto-columns: minmax(168px, 1fr); }
  .a-faire-gestes .champ-numero { width: 130px; flex: 0 0 130px; }
  /* « Ses ventes » : la date, le contenu, le montant, le badge. */
  .vente-fiche { grid-template-columns: 70px minmax(0, 1fr) 90px 116px; padding-left: 10px; }
  .vente-fiche .vente-ht { text-align: right; }
  .vente-fiche > .badge { min-width: 110px; justify-self: end; }
}

/* --- 19.1 : les blocs dépliables ---------------------------------------------------
   Une seule forme pour tous les <details> qui portent un bloc : une barre — la
   flèche, le titre à gauche, le résumé à droite —, puis un corps en retrait. Les
   menus (« … », Région, Autre…, Reporter) ne sont pas des blocs : ils ne changent pas. */

/* 1. Le bloc et sa barre. */
.panel.pliant { padding: 0; margin: 0 0 14px; background: var(--surface); border: 1px solid var(--line-strong); }
.pliant > summary {
  display: flex; align-items: center; justify-content: flex-start; gap: 12px;
  padding: 14px 18px; min-height: 56px; cursor: pointer; list-style: none;
  font-family: var(--font-display); font-size: 19px; font-weight: 600; text-transform: none; letter-spacing: 0; color: var(--ink);
}
.pliant > summary::-webkit-details-marker { display: none; }
.pliant > summary::before {
  content: ""; flex: 0 0 auto; width: 0; height: 0; margin: 0;
  border-left: 8px solid var(--ink); border-top: 6px solid transparent; border-bottom: 6px solid transparent;
  transition: transform .15s ease;
}
.pliant[open] > summary::before { transform: rotate(90deg); }
.pliant > summary > .hint {
  margin-left: auto; text-align: right; max-width: 55%;
  font-family: var(--font-body); font-size: 13.5px; font-weight: 400; color: var(--muted);
}
.pliant > summary .hint :is(b, strong) { color: var(--ink); }
.pliant > summary:hover { background: var(--gris-soft); }
.pliant[open] > summary { background: var(--bg); border-bottom: 1px solid var(--line); }
/* Le corps : 18 px tout autour, par une marge sur chaque enfant — aucun
   formulaire n'est enveloppé. */
.panel.pliant > :not(summary) { margin-left: 18px; margin-right: 18px; }
.panel.pliant > summary + * { margin-top: 18px; }
.panel.pliant > :last-child:not(summary) { margin-bottom: 18px; }

/* 3. Les sous-blocs : la même barre, en plus bas. */
:is(details.sous-bloc, .panel.pliant details:not([class])) {
  margin-top: 16px; padding: 0; background: var(--bg); border: 1px solid var(--line-strong);
}
:is(details.sous-bloc, .panel.pliant details:not([class])) > summary {
  display: flex; align-items: center; justify-content: flex-start; gap: 10px;
  min-height: 44px; padding: 11px 16px; cursor: pointer; list-style: none;
  font-family: var(--font-body); font-size: 15px; font-weight: 600; text-transform: none; letter-spacing: 0; color: var(--ink);
}
:is(details.sous-bloc, .panel.pliant details:not([class])) > summary::-webkit-details-marker { display: none; }
:is(details.sous-bloc, .panel.pliant details:not([class])) > summary::before {
  content: ""; flex: 0 0 auto; width: 0; height: 0; margin: 0;
  border-left: 7px solid var(--ink); border-top: 5px solid transparent; border-bottom: 5px solid transparent;
  transition: transform .15s ease;
}
:is(details.sous-bloc, .panel.pliant details:not([class]))[open] > summary::before { transform: rotate(90deg); }
:is(details.sous-bloc, .panel.pliant details:not([class])) > summary > .hint {
  margin-left: auto; text-align: right; max-width: 55%; font-size: 13.5px; font-weight: 400; color: var(--muted);
}
:is(details.sous-bloc, .panel.pliant details:not([class])) > summary:hover { background: var(--gris-soft); }
:is(details.sous-bloc, .panel.pliant details:not([class]))[open] > summary { background: var(--surface); border-bottom: 1px solid var(--line); }
:is(details.sous-bloc, .panel.pliant details:not([class])) > :not(summary) { margin-left: 16px; margin-right: 16px; }
:is(details.sous-bloc, .panel.pliant details:not([class])) > summary + * { margin-top: 16px; }
:is(details.sous-bloc, .panel.pliant details:not([class])) > :last-child:not(summary) { margin-bottom: 16px; }
@media (prefers-reduced-motion: reduce) {
  .pliant > summary::before, details.sous-bloc > summary::before { transition: none; }
}
/* Sur téléphone : la flèche et le titre, puis le résumé dessous, à gauche. */
@media (max-width: 640px) {
  .pliant > summary, details.sous-bloc > summary { flex-wrap: wrap; row-gap: 4px; }
  .pliant > summary > .hint, details.sous-bloc > summary > .hint {
    flex-basis: 100%; margin-left: 20px; text-align: left; max-width: none; font-size: 13px;
  }
}

/* 4. Les formulaires d'un bloc : une grille de quatre colonnes (deux dans la
   colonne étroite de la fiche et dans le volet ; une sur téléphone). */
@media (min-width: 641px) {
  :is(.pliant, details.sous-bloc) .form-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px 16px; }
  :is(.fiche-droite, .volet) .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  :is(.fiche-droite, .volet) .form-grid > :is(.span3, .span4) { grid-column: 1 / -1; }
}
:is(.pliant, details.sous-bloc) label:not(.chip, .check, .coche-lot, .moyen) { gap: 5px; font-size: 13px; font-weight: 700; color: var(--etiquette); }
:is(.pliant, details.sous-bloc) :is(input:not([type="checkbox"], [type="radio"], [type="hidden"], [type="file"]), select) {
  height: 40px; width: 100%; padding: 0 12px; font-size: 14.5px; border: 1px solid var(--line-strong);
}
:is(.pliant, details.sous-bloc) textarea { min-height: 72px; width: 100%; padding: 9px 12px; font-size: 14.5px; }
/* Un champ de fichier habillé par le script : un bouton et le nom du fichier ;
   sans script, le champ du navigateur reste visible. */
.fichier-habille { display: flex; align-items: center; gap: 10px; min-height: 40px; }
.fichier-habille .nom-fichier { font-size: 13.5px; font-weight: 400; color: var(--muted); overflow-wrap: anywhere; }
/* Le rythme des visites : le champ (100 px) et son bouton sur une ligne. */
#visites .form-grid { display: flex; align-items: flex-end; gap: 10px; }
#visites .form-grid input { width: 100px; }

/* Les groupes de choix : des cases de même largeur, le titre au-dessus. */
.ligne-chips { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 8px; align-items: stretch; }
.ligne-chips > .chips-titre { grid-column: 1 / -1; font-size: 13px; font-weight: 700; margin: 0; }
.ligne-chips > .chip, .ligne-chips > a.chip {
  display: flex; align-items: center; justify-content: center; text-align: center;
  min-height: 38px; padding: 4px 8px; white-space: normal; line-height: 1.2;
}
.ligne-chips > :is(.chips-repli, .hint, details, p) { grid-column: 1 / -1; }
/* « Le » et « Quand » : des champs ordinaires, sur leur ligne. */
.ligne-chips > .chip-champ { grid-column: 1 / span 2; display: flex; flex-direction: column; gap: 5px;
  font-size: 13px; font-weight: 700; color: var(--etiquette); }
.ligne-chips > .chip-champ input { max-width: none; width: 100%; }
/* Noter un échange : les cinq moyens sur une ligne ; la suite par trois dans une colonne étroite. */
.form-echange .ligne-chips:has(input[name="mode"]) { grid-template-columns: repeat(5, minmax(0, 1fr)); }
:is(.fiche-droite, .volet) .form-echange .ligne-chips:has(input[name="suite"]) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 640px) {
  .form-echange .ligne-chips:has(input[name="mode"]), .form-echange .ligne-chips:has(input[name="suite"]) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* 5. L'aide d'un bloc : un seul paragraphe, en bas. */
.aide { font-family: var(--font-body); font-size: 13.5px; color: var(--muted); line-height: 1.55; max-width: 90ch; margin: 14px 0 0; }
.aide :is(b, strong) { color: var(--ink); }

/* 6. Les tableaux d'un bloc : colonnes fixes. */
@media (min-width: 641px) {
  .pliant table.list:not(.revient) { table-layout: fixed; width: 100%; }
  .pliant table.list > thead > tr > th { font-size: 12.5px; font-weight: 700; border-bottom: 1px solid var(--ink); }
  .pliant table.list > thead > tr > th.col-date { width: 130px; }
  .pliant table.list > thead > tr > th.num { width: 96px; }
  .pliant table.list > thead > tr > th.col-action { width: 110px; }
  .pliant table.list:has(> tbody > tr > td.col-action > :nth-child(2)) > thead > tr > th.col-action { width: 212px; }
  .pliant table.list > tbody > tr > td.col-action { white-space: nowrap; }
  .pliant table.list > tbody > tr > td.col-action > :is(form, .btn) { display: inline-flex; width: 92px; margin: 0; vertical-align: middle; }
  .pliant table.list > tbody > tr > td.col-action > :is(form, .btn) + :is(form, .btn) { margin-left: 6px; margin-top: 0; }
  .pliant table.list > tbody > tr > td.col-action > form > .btn { width: 100%; }
}

/* Le résumé du Soufre : quatre cartes, une valeur chacune. */
.cles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin: 0; }
.cle { border: 1px solid var(--line); border-left: 4px solid var(--line-strong); background: var(--surface); padding: 10px 12px; }
.cle-vert { border-left-color: var(--badge-vert); }
.cle-ambre { border-left-color: var(--badge-ambre); }
.cle-rouge { border-left-color: var(--badge-rouge); }
.cle-valeur { display: block; font-family: var(--font-display); font-size: 24px; font-weight: 600; line-height: 1.1; font-variant-numeric: tabular-nums; }
.cle-valeur small { font-family: var(--font-body); font-size: 13px; font-weight: 400; color: var(--muted); }
.cle-nom { display: block; margin-top: 4px; font-size: 13px; font-weight: 700; color: var(--etiquette); }
@media (max-width: 900px) { .cles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* 9. L'en-tête d'un millésime : la prochaine étape en gras, son retard en rouge. */
.ligne-millesime strong { color: var(--ink); }

/* --- 19.2 : les menus de la barre, les pictogrammes, la lune --------------------
   Chaque partie de la barre : son pictogramme au-dessus du mot ; une partie à
   plusieurs écrans les déroule sous son mot — au survol, au clavier, ou par
   son chevron (un <details>, qui marche sans script). Les onglets ont quitté le
   haut des pages : sur ordinateur, une page de liste ne garde que ses boutons
   de création, à droite du titre ; sur téléphone, les écrans de la partie
   passent en pastilles sous le titre. Les pictogrammes viennent de Lucide
   (inc/icones.php) : du trait, de la couleur du texte. */

/* 1. Le menu déroulé. L'entrée occupe toute la hauteur de la barre : le
   panneau s'ouvre juste dessous, 8 px plus bas. */
.menu-partie { position: relative; display: flex; align-items: center; }
.nav > .menu-partie, .user-box > .menu-partie, .user-box { align-self: stretch; }
/* Le chevron, à droite du mot (sous la roue, qui n'a pas de mot) : sans
   script, ou au clavier, c'est lui qui ouvre le menu ; le mot mène à la page. */
.menu-partie-ouvrir { position: absolute; left: 100%; top: calc(50% + 5px); z-index: 1; margin: 0 0 0 1px; }
.menu-reglages > .menu-partie-ouvrir { left: 50%; top: calc(50% + 19px); margin: 0 0 0 -7px; }
.menu-partie-ouvrir > summary {
  display: flex; align-items: center; justify-content: center; width: 14px; height: 14px; padding: 0;
  list-style: none; cursor: pointer; color: #C0C0C0;
}
.menu-partie-ouvrir > summary::-webkit-details-marker { display: none; }
.menu-partie-ouvrir > summary:hover, .menu-partie-ouvrir[open] > summary { color: #fff; }
.menu-partie-ouvrir[open] > summary .ic { transform: rotate(180deg); }
/* Avec le script et une souris, le survol suffit : le chevron s'efface, sauf
   quand le clavier l'atteint. Au doigt, il reste visible. */
@media (hover: hover) {
  html.js .menu-partie-ouvrir > summary:not(:focus-visible) { opacity: 0; }
}
/* Quand il se voit, le chevron a sa place avant l'entrée suivante. */
html:not(.js) .nav > .menu-partie { margin-right: 12px; }
@media (hover: none) {
  .nav > .menu-partie { margin-right: 12px; }
}
.deroule {
  display: none; position: absolute; z-index: 40; left: 50%; top: calc(100% + 8px); transform: translateX(-50%);
  width: max-content; min-width: 250px; max-width: calc(100vw - 32px); padding: 8px;
  background: var(--surface); border: 1px solid var(--line-strong); box-shadow: 0 10px 28px rgba(0, 0, 0, .18);
  color: var(--ink); font-family: var(--font-body); font-size: 14.5px; font-weight: 400; line-height: 1.3;
  text-align: left; text-transform: none; letter-spacing: 0; white-space: nowrap;
}
/* Un pont invisible de 10 px : la souris passe du mot au panneau sans le refermer. */
.deroule::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: 10px; }
.menu-partie:hover > .deroule, .menu-partie:focus-within > .deroule, .menu-partie-ouvrir[open] ~ .deroule { display: block; }
/* Échap, ou un clic ailleurs (app.js) : refermé jusqu'à ce que la souris ou le
   clavier en sorte. */
.menu-partie.ferme > .deroule { display: none; }
/* La roue est au bord droit : son panneau s'aligne à droite. */
.menu-reglages > .deroule { left: auto; right: 0; transform: none; }
.deroule > a { display: flex; align-items: center; gap: 10px; min-height: 40px; padding: 8px 10px; color: var(--ink); text-decoration: none; }
.deroule > a:hover { background: var(--gris-soft); text-decoration: none; }
.deroule > a.on { background: var(--ink); color: var(--on-plum); }
.deroule-nom { flex: 1 1 auto; }
.deroule .n { margin-left: 16px; font-size: 12.5px; font-weight: 700; color: var(--muted); font-variant-numeric: tabular-nums; }
.deroule .n:empty { display: none; }
.deroule > a.on .n { color: var(--on-plum); opacity: .85; }
/* Les boutons de création, sous un filet : deux par ligne, de même largeur, le
   premier en noir ; un bouton seul prend la ligne. */
.deroule-boutons { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line); }
.deroule-boutons > .btn { width: 100%; }
.deroule-boutons > .btn:last-child:nth-child(odd) { grid-column: 1 / -1; }

/* 2. La lune : le mode sombre d'un clic — la lune en clair, le soleil en sombre.
   Sans script, le bouton reste caché (`hidden`) : Mon compte suffit. */
.btn-icone {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 38px; height: 38px; padding: 0; border: 0; border-radius: 0;
  background: none; color: #C0C0C0; font: inherit; cursor: pointer;
}
.btn-icone:hover { color: #fff; }
.btn-icone[hidden] { display: none; }
.bascule-theme > span { display: inline-flex; }
.bascule-theme > .ic-soleil, :root[data-theme="dark"] .bascule-theme > .ic-lune { display: none; }
:root[data-theme="dark"] .bascule-theme > .ic-soleil { display: inline-flex; }

/* 3. La ligne « Partie › Écran », au-dessus du titre d'une page de liste. */
.sous-page { margin: 0 0 2px; font-family: var(--font-body); font-size: 12.5px; font-weight: 600; line-height: 1.4;
  text-transform: uppercase; letter-spacing: .07em; color: var(--muted); }
.sous-page a { color: var(--muted); text-decoration: none; }
.sous-page a:hover { color: var(--ink); text-decoration: underline; }
.sous-page > .ic { margin-right: 7px; }
/* Le fil d'une fiche : le pictogramme de la partie devant. */
.eyebrow > .ic { margin-right: 6px; color: var(--muted); }

/* 4. La partie, sur la ligne du titre (`partie_html()`). */
.partie { display: none; }
.gestes-partie { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 8px; align-items: center; }
.gestes-partie > .btn { width: 100%; }
@media (min-width: 641px) {
  /* Sur ordinateur : rien sur une fiche ni sur une saisie ; sur une page de
     liste, ses boutons à droite du titre, à la hauteur des autres. */
  .partie.partie-liste { display: block; }
  .partie-liste > .ecrans-partie { display: none; }
  .page-head > .partie { margin-left: auto; }
  .tete-liste > .partie { margin-right: auto; }
  .gestes-partie > .btn { min-height: 36px; padding: 0 14px; font-size: 13px; }
}
@media (max-width: 640px) {
  /* Sur téléphone : les écrans en pastilles sous le titre, qui défilent au
     doigt, l'actif en noir ; puis les boutons. */
  .partie { display: flex; flex-direction: column; gap: 10px; flex: 1 1 100%; min-width: 0; margin: 2px 0 4px; }
  .ecrans-partie { display: flex; flex-wrap: nowrap; gap: 8px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
  .ecrans-partie::-webkit-scrollbar { display: none; }
  .ecrans-partie > .pill { flex: 0 0 auto; min-height: 40px; }
  .gestes-partie > .btn { min-height: 44px; }
}
@media print {
  .partie, .sous-page { display: none !important; }
}

/* 5. Les boutons d'un en-tête : côte à côte, de même largeur, jamais empilés.
   L'en-tête d'un millésime aussi, avec son « … » à 44 px au bout. */
@media (min-width: 641px) {
  .page-head .actions:has(> .menu-plus:last-child):not(:has(> :not(.btn, form, .menu-plus))) {
    display: grid; grid-auto-flow: column; gap: 8px; align-items: center;
  }
  .page-head .actions:has(> .menu-plus:last-child):has(> :nth-child(2):last-child) { grid-template-columns: minmax(140px, 1fr) 44px; }
  .page-head .actions:has(> .menu-plus:last-child):has(> :nth-child(3):last-child) { grid-template-columns: repeat(2, minmax(140px, 1fr)) 44px; }
  .page-head .actions:has(> .menu-plus:last-child):has(> :nth-child(4):last-child) { grid-template-columns: repeat(3, minmax(140px, 1fr)) 44px; }
  .page-head .actions > .menu-plus > summary { display: flex; align-items: center; justify-content: center; width: 44px; min-height: 36px; padding: 0; }
  /* Hors d'une grille, un bouton garde sa largeur : il ne prend plus toute la
     ligne (d'où les boutons empilés). */
  .page-head .actions:has(> :not(.btn, form, .menu-plus)) > .btn { width: auto; }
}

/* 6. Les pictogrammes : de la couleur du texte, posés sur sa ligne. */
.ic { flex: none; vertical-align: -3px; }
.btn { gap: 7px; }
/* Un titre de bloc : 20 px, le gris des étiquettes, 9 px avant le mot. */
.ic-titre { margin-right: 9px; color: var(--etiquette); vertical-align: -4px; }
summary > span:first-child > .ic:first-child { margin-right: 9px; }
/* Un chiffre clé : 18 px, gris, devant la valeur. */
.kpi-valeur > .ic, .cle-valeur > .ic { margin-right: 8px; color: var(--muted); vertical-align: -1px; }
/* Un lien qui commence par un pictogramme (« Tout le journal → », « Vente ») ;
   pas ceux dont la mise en page fait déjà l'écart. */
a:not(.btn) > .ic:first-child { margin-right: 5px; }
.deroule > a > .ic:first-child, .barre-tel > a > .ic:first-child, .roue > .ic:first-child,
:is(.croix, .btn-croix) > .ic:first-child { margin-right: 0; }
/* Les Réglages : leur menu latéral, chaque entrée son pictogramme. */
.onglets-reglages a { display: inline-flex; align-items: center; }
.onglets-reglages a > .ic:first-child { margin-right: 9px; color: var(--muted); }
.onglets-reglages a.on > .ic:first-child { color: currentColor; }

/* 7. Les derniers alignements. */
/* Une quantité en badge : même largeur, chiffres à droite. */
.badge.badge-nombre, table.list td.num .badge { min-width: 78px; justify-content: flex-end; font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; }
@media (min-width: 641px) {
  /* La fiche, « À faire » : un badge long passe à la ligne dans sa colonne. */
  .a-faire-ligne > .badge { max-width: 100%; white-space: normal; text-align: center; }
  /* Toutes les ventes : la colonne État à 240 px, ses marques sur une ligne. */
  table.list.table-historique > thead > tr > th:nth-child(5) { width: 240px; }
  .table-historique td[data-label="État"] { padding-left: 10px; padding-right: 8px; }
  .table-historique .marques { flex-wrap: nowrap; gap: 6px; white-space: nowrap; }
  .table-historique .marque { padding: 2px 6px; }
  /* Les tableaux d'analyse, larges : ils défilent de côté plutôt que de couper
     leurs mots ; les montants à 90 px. Dans « Dépenses du millésime », chaque
     colonne porte le nom d'une cuvée : 90 px au moins, davantage s'il le faut. */
  .table-depenses-millesime, .table-clients-analyse { min-width: 1020px; }
  .table-clients-analyse > thead > tr > th.num { width: 90px; }
  .table-depenses-millesime > thead > tr > th.num { min-width: 90px; }
}
@media screen {
  /* Une carte de l'agenda : son titre sur deux lignes au plus (le nom entier
     au survol et dans le volet), le détail sur une ligne. */
  .carte-jour .carte-titre { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
  .carte-jour .carte-sous { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}

/* --- 19.3 : les moyens de paiement, l'export à la carte --------------------------
   « Paiement reçu » et « Payée » n'enregistrent plus d'un clic : ils ouvrent un
   cadre — les cases des moyens, la date, Valider et Annuler. Sans script, c'est
   un <details> qui s'ouvre sous son bouton ; avec, app.js pose le cadre sous la
   ligne et, sur téléphone, le fait monter du bas comme une feuille. */

/* 1. Les cases des moyens : de même largeur, le pictogramme au-dessus du nom,
   la case cochée en noir (en blanc dans le mode sombre). Toutes sur une ligne
   quand la place le permet (`--n` : leur nombre, posé par le serveur) ; dans
   une colonne étroite, `--case-min` au moins chacune, sur plusieurs lignes. */
.moyens {
  --case-min: 64px;
  display: grid; gap: 6px; margin: 0; min-width: 0;
  grid-template-columns: repeat(auto-fit, minmax(max(var(--case-min), calc((100% - (var(--n, 5) - 1) * 6px) / var(--n, 5) - 1px)), 1fr));
}
.moyens > label.moyen {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  min-width: 0; min-height: 52px; margin: 0; padding: 6px 4px; cursor: pointer;
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink);
  font-family: var(--font-body); font-size: 13px; font-weight: 600; line-height: 1.2; text-align: center; white-space: normal;
}
.moyens > label.moyen:hover { border-color: var(--ink); }
/* La case ronde reste dans la page (le clavier et le lecteur d'écran la
   trouvent), invisible : c'est l'étiquette qui se coche. */
.moyen > input { position: absolute; left: 0; top: 0; width: 1px; height: 1px; margin: 0; padding: 0; opacity: 0; pointer-events: none; }
.moyen > .ic { color: var(--muted); }
.moyen-nom { display: block; max-width: 100%; overflow-wrap: anywhere; }
.moyens > label.moyen:has(input:checked) { background: var(--plum-bg); border-color: var(--plum-bg); color: var(--on-plum); }
.moyen:has(input:checked) > .ic { color: currentColor; }
.moyen:has(input:focus-visible) { outline: 3px solid var(--badge-bleu); outline-offset: 2px; }
/* La version d'une ligne de dépense, d'un formulaire : plus basse. */
.moyens-compacts { --case-min: 58px; gap: 4px; }
.moyens-compacts > label.moyen { min-height: 44px; padding: 4px 2px; gap: 2px; font-size: 12px; }

/* 2. Le bouton qui ouvre le cadre : le `summary` d'un <details>, habillé en
   bouton — ou en lien, « moyen non renseigné ». */
.encaisser-pli { display: block; margin: 0; }
.encaisser-pli > summary { list-style: none; cursor: pointer; }
.encaisser-pli > summary::-webkit-details-marker { display: none; }
.encaisser-pli > summary.btn { width: 100%; }
.encaisser-pli[open] > summary.btn:not(.btn-primary) { background: var(--gris-soft); }
/* Le lien reste dans sa phrase : une boîte en ligne, que la partie repliée
   du <details> ne coupe pas. */
.encaisser-lien { display: inline-block; max-width: 100%; vertical-align: baseline; }
.encaisser-lien > summary { display: inline; }
/* Dans le menu « … » : une entrée comme les autres. */
.menu-plus-liste .encaisser-pli > summary.menu-pli { display: block; width: 100%; padding: 7px 10px; font-size: 14px; color: var(--ink); text-align: left; }
.menu-plus-liste .encaisser-pli > summary.menu-pli:hover { background: var(--gris-soft); }
/* « Paiement reçu » du menu, réservé au téléphone, comme les autres dates. */
.menu-plus-liste div.menu-tel { display: none; }
/* La fiche, « À faire » : le bouton dans la grille des gestes. */
@media (min-width: 641px) {
  .a-faire-gestes:has(> .encaisser-pli):not(:has(> :not(.btn, form, .encaisser-pli))) {
    display: grid; grid-auto-flow: column; gap: 8px; align-items: center;
  }
}

/* 3. Le cadre : un filet noir, le titre, les cases, puis « Reçu le » et les
   deux boutons sur une ligne. Il garde son alignement où qu'il soit posé. */
.encaisser {
  margin: 8px 0 0; padding: 14px 16px; background: var(--surface); color: var(--ink);
  border: 1px solid var(--ink); text-align: left; white-space: normal;
  font-family: var(--font-body); font-size: 14px; font-weight: 400; line-height: 1.4;
}
.encaisser-titre { margin: 0 0 10px; font-size: 14px; overflow-wrap: anywhere; }
.encaisser-titre strong { font-weight: 700; }
.encaisser-vu { display: flex; align-items: center; gap: 6px; margin: 8px 0 0; font-size: 13px; color: var(--vert); overflow-wrap: anywhere; }
.encaisser-pied { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin-top: 12px; }
.encaisser-pied > label.encaisser-date {
  display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 6px 8px; max-width: 100%; margin: 0 auto 0 0;
  font-size: 13px; font-weight: 700; color: var(--etiquette); white-space: nowrap;
}
.encaisser-pied > label.encaisser-date > input { width: 150px; max-width: 100%; height: 36px; padding: 0 8px; }
.encaisser-pied > .btn { min-width: 110px; }
/* Posé sous sa ligne par le script : à droite, sous les gestes. */
.encaisser.encaisser-pose { max-width: 760px; margin: 4px 0 4px auto; }
tr.ligne-encaisser > td { padding: 0 12px 14px; border-top: 0; }
table.list > tbody > tr:has(+ tr.ligne-encaisser) > td { border-bottom-color: transparent; }
:is(.a-faire-ligne, .vente-fiche, .rangee) > .encaisser { grid-column: 1 / -1; flex: 1 1 100%; width: 100%; }
.a-faire-ligne > .encaisser.encaisser-pose { margin-top: 10px; }
/* Dans une colonne étroite — une carte de l'agenda, le volet —, les cases par deux. */
:is(.carte-jour, .volet) .encaisser { padding: 12px; }
.carte-jour .encaisser .moyens { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.carte-jour .encaisser-pied > label.encaisser-date { flex: 1 1 100%; flex-wrap: wrap; white-space: normal; }
.carte-jour .encaisser-pied > label.encaisser-date > input { width: 100%; }
.carte-jour .encaisser-pied > .btn { flex: 1 1 auto; min-width: 0; }

/* 4. Sur téléphone : le cadre monte du bas, par-dessus un voile ; les cases
   par deux, le pictogramme à côté du nom ; Valider et Annuler au pouce. */
.encaisser-voile { position: fixed; inset: 0; z-index: 80; background: var(--voile); }
.encaisser.encaisser-feuille {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 81; max-width: none; max-height: 88vh; margin: 0;
  overflow-y: auto; overscroll-behavior: contain; padding: 10px 16px calc(16px + env(safe-area-inset-bottom, 0px));
  border: 0; border-top: 1px solid var(--line-strong); box-shadow: 0 -8px 24px rgba(0, 0, 0, .18);
}
.encaisser-feuille::before { content: ""; display: block; width: 40px; height: 4px; margin: 0 auto 12px; border-radius: 2px; background: var(--line-strong); }
@media (prefers-reduced-motion: no-preference) {
  .encaisser-feuille { animation: feuille-monte .2s ease-out; }
}
@media (max-width: 640px) {
  .encaisser .moyens { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .encaisser .moyens > label.moyen { flex-direction: row; justify-content: flex-start; gap: 10px; padding: 8px 12px; font-size: 14px; text-align: left; }
  .encaisser-pied { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .encaisser-pied > label.encaisser-date { grid-column: 1 / -1; margin: 0; justify-content: space-between; }
  .encaisser-pied > label.encaisser-date > input { flex: 1 1 auto; width: auto; max-width: 220px; height: 44px; }
  .encaisser-pied > .btn { width: 100%; min-width: 0; min-height: 46px; }
  .encaisser-pli > summary.geste-pouce { min-height: 46px; }
  .menu-plus-liste div.menu-tel { display: block; padding: 4px 10px; }
  .moyens-compacts { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* 5. Un paiement lu : « ✓ Payée », puis le moyen et la date ; sans moyen, de
   quoi le dire. Le moyen seul, en petit, dans les autres listes. */
.moyen-lu > .ic, .moyen-court > .ic { margin-right: 5px; vertical-align: -2px; color: var(--muted); }
.moyen-court { white-space: nowrap; }
.moyen-manquant { color: var(--muted); text-decoration: underline dotted; text-underline-offset: 3px; cursor: pointer; }
.moyen-manquant:hover { color: var(--ink); }
.faits .ic { margin-right: 6px; vertical-align: -3px; }

/* 6. Ventes en cours : cinq chiffres ; « Encaissé ce mois », les espèces
   détaillées au survol. Le menu « Moyen de paiement », à droite des états. */
.kpis-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
@media (max-width: 1100px) { .kpis-5 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 900px) { .kpis-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .kpis-5 { grid-template-columns: minmax(0, 1fr); } }
.kpi-encaisse .encaisse-detail { text-decoration: underline dotted; text-underline-offset: 3px; cursor: help; }
.menu-moyen .menu-liste-corps > a > span:first-child { display: inline-flex; align-items: center; gap: 8px; }

/* 7. Dépenses › À payer : la date, les cases, « Payée » — sur une ligne dès
   1 200 px ; en dessous, les cases passent sous la date et le bouton. */
@media (min-width: 641px) {
  .geste-payer.geste-payer-moyens { grid-template-columns: minmax(0, 1fr) 130px 100px; }
  .geste-payer-moyens > input[type="date"] { grid-column: 2; grid-row: 1; }
  .geste-payer-moyens > .btn { grid-column: 3; grid-row: 1; }
  .geste-payer-moyens > .moyens { grid-column: 1 / -1; grid-row: 2; }
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime).table-factures:has(.geste-payer-moyens) > thead > tr > th.col-action { width: 340px; }
}
@media (min-width: 1200px) {
  .geste-payer.geste-payer-moyens { grid-template-columns: 130px minmax(0, 1fr) 100px; }
  .geste-payer-moyens > input[type="date"] { grid-column: 1; }
  .geste-payer-moyens > .moyens { grid-column: 2; grid-row: 1; }
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime).table-factures:has(.geste-payer-moyens) > thead > tr > th.num { width: 112px; }
  table.list.table-cartes:not(.lignes-vente, .lignes-depense, .table-millesimes, .table-clients-analyse, .table-depenses-millesime).table-factures:has(.geste-payer-moyens) > thead > tr > th.col-action { width: 620px; }
}
@media (max-width: 640px) {
  .geste-payer-moyens > input[type="date"] { flex: 1 1 100%; }
  .geste-payer-moyens > .moyens { flex: 1 1 100%; }
}
/* La saisie d'une dépense, une recette : le titre, puis les cases. */
.champ-moyen { display: flex; flex-direction: column; gap: 6px; min-width: 0; margin: 0 0 12px; }
.form-grid > .champ-moyen { margin: 0; }
.champ-moyen > .moyens { max-width: 560px; }

/* 8. L'export à la carte : deux groupes de cases sous la période, puis la
   ligne de récapitulatif — un trait noir à gauche, la part « non incluses »
   en ambre gras. */
.groupes-export { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 18px; padding: 4px 22px 0; }
.groupe-export { min-width: 0; margin: 0; padding: 10px 14px 12px; border: 1px solid var(--line-strong); background: var(--surface); }
.groupe-export > legend { padding: 0 6px; font-size: 13px; font-weight: 700; color: var(--etiquette); }
.groupe-export > label.case-export {
  display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; align-items: center; gap: 2px 10px;
  min-height: 38px; margin: 0; padding: 4px 0; border-top: 1px solid var(--line);
  font-size: 14px; font-weight: 500; color: var(--ink); cursor: pointer;
}
.groupe-export > label.case-export:first-of-type { border-top: 0; }
.case-export > input { width: 18px; height: 18px; margin: 0; accent-color: var(--ink); cursor: pointer; }
.case-export-nom { display: inline-flex; align-items: center; gap: 7px; min-width: 0; }
.case-export-nom > .ic { color: var(--muted); }
.case-export-compte { font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.groupe-export > .hint { margin: 8px 0 0; }
.choix-export .filtres-actions { align-items: center; margin-left: 22px; margin-right: 22px; }
.recap { margin: 18px 0 14px; padding: 10px 14px; border-left: 4px solid var(--ink); background: var(--bg); font-size: 14.5px; line-height: 1.55; }
.recap-exclu { color: var(--ambre); font-weight: 700; }
@media (max-width: 640px) {
  .groupes-export { grid-template-columns: minmax(0, 1fr); padding: 4px 14px 0; }
  .groupe-export > label.case-export { grid-template-columns: 20px minmax(0, 1fr); }
  .case-export-compte { grid-column: 2; text-align: left; white-space: normal; }
  .choix-export .filtres-actions { flex-wrap: wrap; margin-left: 14px; margin-right: 14px; }
}

/* 9. Réglages › Listes, les moyens : le pictogramme devant le nom ; un moyen
   masqué en gris. */
.valeurs-moyens li > span:first-child > .ic { margin-right: 8px; color: var(--muted); vertical-align: -4px; }
.valeurs-moyens .badge { margin-left: 6px; }
.valeur-masquee > span:first-child { color: var(--muted); }

@media print {
  .encaisser-pli > .encaisser, .encaisser-voile, tr.ligne-encaisser { display: none !important; }
}

/* --- 19.5 : lots de mise et traçabilité ------------------------------------------
   Une mise en bouteille est un lot numéroté. Le millésime les liste ; la fiche
   d'un lot montre ses matières (une carte chacune) et où il est parti ; la
   livraison, quand plusieurs lots sont en stock, demande lequel part — le même
   cadre que « Paiement reçu ». */

/* 1. La fiche du millésime : le tableau des lots, la ligne d'écart dessous. */
.table-lots td.cell-nom > a { font-weight: 700; }
.ecart-lots { margin: 8px 0 0; }
#lots > .sous-bloc { margin-top: 14px; }

/* 2. Le formulaire d'une mise : quatre champs, puis une ligne par matière. */
.form-mise .table-wrap { margin: 12px 0; }
.table-matieres-mise td { vertical-align: middle; }
.table-matieres-mise select, .table-matieres-mise input { width: 100%; min-width: 0; }
.table-matieres-mise td.num { white-space: nowrap; font-variant-numeric: tabular-nums; }

/* 3. La fiche d'un lot : une carte par matière — la catégorie, l'article, le
   fournisseur, le lot du fournisseur en gras, la quantité. */
.cartes-matieres { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px; margin: 4px 0 12px; }
.carte-matiere { display: flex; flex-direction: column; gap: 3px; min-width: 0; padding: 10px 12px; border: 1px solid var(--line-strong); background: var(--surface); }
.carte-matiere-nom { font-weight: 700; overflow-wrap: anywhere; }
.carte-matiere-lot { font-size: 14px; overflow-wrap: anywhere; }
.carte-matiere-lot strong { font-variant-numeric: tabular-nums; }

/* 4. Le cadre « quel lot part ? » : une rangée de cases par ligne de vin, comme
   les moyens de paiement, puis « sur le premier » pour « Deux lots ». */
.choix-lot { min-width: 0; margin: 0 0 12px; padding: 0; border: 0; }
.choix-lot > legend { padding: 0; margin: 0 0 6px; font-size: 13px; font-weight: 700; color: var(--etiquette); }
.choix-lot-cases { display: grid; gap: 6px; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
.choix-lot-cases > label.moyen {
  position: relative; display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 2px;
  min-width: 0; min-height: 52px; margin: 0; padding: 6px 10px; cursor: pointer;
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink);
  font-family: var(--font-body); font-size: 14px; font-weight: 600; line-height: 1.2; text-align: left; white-space: normal;
}
.choix-lot-cases > label.moyen:hover { border-color: var(--ink); }
.choix-lot-cases > label.moyen > .sub { font-weight: 400; }
.choix-lot-cases > label.moyen:has(input:checked) { background: var(--plum-bg); border-color: var(--plum-bg); color: var(--on-plum); }
.choix-lot-cases > label.moyen:has(input:checked) > .sub { color: inherit; }
label.choix-lot-deux, label.choix-lot-numero {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin: 8px 0 0;
  font-size: 13px; font-weight: 700; color: var(--etiquette);
}
label.choix-lot-deux > input { width: 90px; height: 36px; padding: 0 8px; }
label.choix-lot-numero > input { width: 180px; max-width: 100%; height: 36px; padding: 0 8px; }
/* Avec le script, « sur le premier » n'apparaît que si « Deux lots » est coché. */
.choix-lot-deux[hidden] { display: none; }
@media (max-width: 640px) {
  .choix-lot-cases { grid-template-columns: minmax(0, 1fr); }
  label.choix-lot-deux > input, label.choix-lot-numero > input { height: 44px; }
}

/* 5. La vente : les lots livrés, sous les lignes ; « Changer de lot ». */
.lots-livres { margin: 14px 0 0; padding: 10px 14px; border-left: 4px solid var(--line-strong); background: var(--bg); }
.lots-livres > h3 { margin: 0 0 6px; font-size: 14px; }
.lots-livres-liste { margin: 0 0 8px; padding-left: 18px; }
.lots-changer { margin: 8px 0 0; }
.lot-vente { color: var(--muted); }

@media print {
  .lots-changer, .choix-lots { display: none !important; }
}

/* --- 19.6 : supprimer un rendez-vous depuis l'agenda ---------------------------
   Sur la carte, un lien discret comme « Reporter » : gris, rouge au survol. */
.lien-supprimer {
  padding: 0; border: 0; background: none; cursor: pointer;
  font-family: var(--font-body); font-size: 12.5px; color: var(--muted);
  text-decoration: underline dotted; text-underline-offset: 3px;
}
.lien-supprimer:hover, .lien-supprimer:focus-visible { color: var(--rouge); }
.carte-jour .carte-gestes > form:has(> .lien-supprimer) { justify-content: flex-start; }