/* =====================================================================
   Composants communs aux deux consoles kelWINE (lot B2)
   =====================================================================

   Chargé après /design.css, qui pose les jetons, et avant la feuille propre
   à chaque console, qui ne garde plus que ses particularités.

   Les deux consoles employaient déjà les mêmes noms de classe avec deux
   définitions divergentes. Elles sont réunies ici : un bouton, un tableau ou
   un champ se comporte désormais pareil des deux côtés, et seule la palette
   change. Aucune classe n'est renommée, aucun balisage n'est déplacé.

   ===================================================================== */

/* =====================================================================
   1. Navigation : barre latérale fixe et barre supérieure
   Les rubriques passent d'un bandeau horizontal à une colonne à gauche.
   Elles y tiennent toutes sans se replier, elles restent visibles pendant
   le défilement, et le haut de l'écran est rendu au titre de la page.
   L'arborescence et les libellés sont inchangés ; seul l'ordre suit
   maintenant l'usage réel.
   ===================================================================== */
.shell { display: flex; min-height: 100dvh; align-items: stretch; }
/* La colonne reste un bloc ordinaire. En faire un conteneur flexible
   annulerait le centrage de .container : dans un flex, une marge automatique
   sur l'axe transversal supprime l'étirement, et le contenu reprend sa
   largeur naturelle en débordant. */
.shell > .colonne { flex: 1; min-width: 0; }

/* Avant connexion, il n'y a rien à naviguer : la coquille s'efface et
   l'écran de login occupe la page. */
.shell[data-chrome="off"] > .sidebar,
.shell[data-chrome="off"] > .colonne > .topbar { display: none; }

/* --- Barre latérale --------------------------------------------------- */
.sidebar {
  width: 232px; flex-shrink: 0;
  background: var(--barre-fond); color: var(--barre-texte);
  padding: var(--esp-5) var(--esp-3) var(--esp-4);
  display: flex; flex-direction: column;
  position: sticky; top: 0; align-self: flex-start;
  height: 100dvh; overflow-y: auto;
}
.sidebar .brand { padding: 0 var(--esp-2) var(--esp-5); cursor: pointer; }
.brand { font-size: var(--txt-lg); font-weight: 700; letter-spacing: .3px; color: #fff; }
.brand span { font-weight: 300; }
.brand small {
  font-weight: 400; opacity: .7; font-size: var(--txt-xs);
  text-transform: uppercase; letter-spacing: .06em;
  display: block; margin-top: 2px; color: var(--barre-texte);
}

/* Le geste le plus fréquent de chaque console, à portée permanente. */
.cta {
  display: flex; align-items: center; justify-content: center; gap: var(--esp-2);
  background: rgba(255, 255, 255, .10);
  border: 1px solid rgba(255, 255, 255, .18);
  color: #fff; text-decoration: none;
  border-radius: var(--r-md); padding: var(--esp-3);
  font-size: var(--txt-sm); font-weight: 600;
  margin-bottom: var(--esp-5); transition: background .12s;
}
.cta:hover { background: rgba(255, 255, 255, .18); }

.nav-groupe {
  font-size: var(--txt-xs); text-transform: uppercase; letter-spacing: .1em;
  color: var(--barre-muted); padding: 0 var(--esp-3) var(--esp-2); margin: 0;
}
.mainnav { display: flex; flex-direction: column; gap: 2px; }
.mainnav a {
  display: flex; align-items: center; gap: var(--esp-3);
  color: var(--barre-texte); text-decoration: none;
  padding: var(--esp-3) var(--esp-3);
  border-radius: var(--r-sm);
  font-size: var(--txt-sm); font-weight: 500;
  transition: background .12s, color .12s;
}
.mainnav a > i { width: 18px; text-align: center; font-size: .95em; opacity: .85; }
.mainnav a:hover { background: rgba(255, 255, 255, .08); color: #fff; }
/* La rubrique courante porte un filet en plus du fond : la couleur seule
   ne suffit pas à signaler où l'on se trouve. */
.mainnav a.active {
  background: rgba(255, 255, 255, .14); color: #fff;
  box-shadow: inset 3px 0 0 var(--barre-actif);
}
.mainnav a.active > i { opacity: 1; }
/* Compteur d'attente, par exemple les vins à valider. */
.nav-badge {
  margin-left: auto; background: var(--attention); color: #fff;
  font-size: var(--txt-xs); font-weight: 700; line-height: 1;
  padding: 3px 7px; border-radius: var(--r-plein);
}
.mainnav a.active .nav-badge { background: rgba(255, 255, 255, .28); }

/* Le compte reste en bas, séparé des rubriques de travail. */
.side-bas { margin-top: auto; padding-top: var(--esp-5); }
.userbox { display: flex; align-items: center; gap: var(--esp-3); }
.side-bas .userbox { flex-direction: column; align-items: stretch; gap: var(--esp-2); }
.user-email {
  color: var(--barre-texte); font-size: var(--txt-xs);
  padding: 0 var(--esp-3); overflow-wrap: anywhere;
}
/* Un lien discret de la zone Compte, a la taille et au ton de la ligne
   d'adresse. Ce n'est pas une rubrique de travail quotidien : elle n'a pas sa
   place dans le menu principal, mais elle doit rester atteignable. */
.user-lien {
  color: var(--barre-texte); font-size: var(--txt-xs);
  padding: 0 var(--esp-3);
  text-decoration: none;
}
.user-lien:hover { color: #fff; text-decoration: underline; }
/* La rubrique ouverte se signale, comme le fait le menu principal. */
.user-lien.active { color: #fff; font-weight: 600; }
.side-bas .btn.secondary {
  background: transparent; color: var(--barre-texte);
  border-color: rgba(255, 255, 255, .22);
}
.side-bas .btn.secondary:hover { background: rgba(255, 255, 255, .10); color: #fff; }

/* --- Barre supérieure -------------------------------------------------- */
/* Elle suit le défilement : sur un long tableau, on garde le titre, la
   recherche et le compte sous la main sans remonter. */
.topbar {
  display: flex; align-items: center; gap: var(--esp-4); flex-wrap: wrap;
  background: var(--surface); color: var(--ink);
  border-bottom: 1px solid var(--line);
  padding: var(--esp-3) var(--esp-5);
  position: sticky; top: 0; z-index: 30;
}
.topbar h2 { font-size: var(--txt-xl); font-weight: 700; margin: 0; }
.recherche {
  margin-left: auto; display: flex; align-items: center; gap: var(--esp-2);
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--r-plein); padding: 0 var(--esp-4);
  color: var(--muted); max-width: 260px; flex: 1 1 160px;
}
/* Voir sa carte comme un client : le lien public, celui du QR code. Il ouvre
   un autre onglet, l'etablissement ne perd pas sa console en cours. Le libelle
   ne se coupe jamais ; sur petit ecran il cede la place a la seule icone, le
   bouton gardant son nom pour les aides techniques. */
.voir-carte { text-decoration: none; white-space: nowrap; }
.recherche i { font-size: var(--txt-sm); }
.recherche input {
  border: 0; background: none; outline: none; font: inherit;
  font-size: var(--txt-sm); color: var(--ink);
  padding: var(--esp-2) 0; width: 100%; min-width: 0;
}
.recherche:focus-within { border-color: var(--accent-fort); }
.user-chip { display: flex; align-items: center; gap: var(--esp-2); }
.user-chip .avatar {
  width: 32px; height: 32px; border-radius: var(--r-plein);
  background: var(--tint); color: var(--accent-fort);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: var(--txt-sm);
}
.user-chip .qui { font-size: var(--txt-xs); line-height: 1.3; }
.user-chip .qui b { display: block; color: var(--ink); font-weight: 600; }
.user-chip .qui span { color: var(--muted); }

/* Sur mobile la colonne passerait devant le contenu : elle repasse en
   bandeau horizontal défilable, ce qui garde toutes les rubriques. */
@media (max-width: 860px) {
  .shell { flex-direction: column; }
  .sidebar {
    width: auto; height: auto; position: static;
    align-self: stretch; flex-direction: row; align-items: center;
    gap: var(--esp-3); padding: var(--esp-3) var(--esp-4); overflow-x: auto;
  }
  .sidebar .brand { padding: 0; flex-shrink: 0; }
  .sidebar .brand small { display: none; }
  .cta { margin-bottom: 0; flex-shrink: 0; }
  .nav-groupe { display: none; }
  .mainnav { flex-direction: row; }
  .mainnav a { white-space: nowrap; }
  .mainnav a.active { box-shadow: inset 0 -3px 0 var(--barre-actif); }
  .side-bas { margin-top: 0; padding-top: 0; margin-left: auto; }
  .side-bas .userbox { flex-direction: row; align-items: center; }
  .user-email { display: none; }
  /* L'adresse disparait faute de place, pas le lien : ce serait le seul
     acces au contrat depuis le menu. */
  .user-lien { padding: 0 var(--esp-2); white-space: nowrap; }
  .topbar h2 { font-size: var(--txt-lg); }
  .voir-carte-txt { display: none; }
}

/* min-width: 0 est indispensable : la colonne est un conteneur flexible, et
   sans cela un large tableau la pousserait au lieu de défiler. */
.container { max-width: 1180px; margin: var(--esp-5) auto var(--esp-6); padding: 0 var(--esp-5); min-width: 0; }

/* =====================================================================
   2. En-tête de page et sections
   Hiérarchie nette : titre, contenu, actions. Le titre porte, le reste suit.
   ===================================================================== */
.pagehead {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--esp-4); flex-wrap: wrap;
  margin-bottom: var(--esp-5);
  padding-bottom: var(--esp-3);
  border-bottom: 1px solid var(--line);
}
.pagehead h1 { font-size: var(--txt-xl); margin: 0; letter-spacing: -.01em; }
/* Le titre est remonté dans la barre supérieure. Si l'en-tête ne portait que
   lui, il ne reste qu'un filet : on l'enlève. */
.pagehead.vide { display: none; }
h2 { font-size: var(--txt-lg); letter-spacing: -.01em; }
.crumb { color: var(--muted); font-size: var(--txt-sm); margin-bottom: var(--esp-2); }
.crumb a { color: var(--accent-fort); }

/* =====================================================================
   3. Cartes de contenu
   ===================================================================== */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--ombre-1);
}
/* Un tableau plus large que la colonne défile dans son propre cadre. La page
   reste en place : c'est elle qui partait de côté quand la navigation occupait
   toute la largeur, et la colonne a maintenant 232 px de moins. */
.container :is(div, section):has(> table) {
  overflow: auto;
  max-height: calc(100dvh - 11rem);
  overscroll-behavior: contain;
}
.card > table:first-child thead th:first-child { border-top-left-radius: var(--r-md); }
.card > table:first-child thead th:last-child { border-top-right-radius: var(--r-md); }
.card > table:last-child tbody tr:last-child td { border-bottom: 0; }

/* =====================================================================
   4. Boutons
   Un seul style, quatre intentions, et tous les états visibles.
   ===================================================================== */
.btn {
  font: inherit; font-size: var(--txt-sm); font-weight: 500;
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  gap: var(--esp-2);
  border: 1px solid var(--accent-fort);
  background: var(--accent-fort); color: var(--on-accent);
  padding: var(--esp-2) var(--esp-4);
  min-height: 38px;                  /* zone cliquable confortable */
  border-radius: var(--r-sm);
  text-decoration: none; white-space: nowrap;
  transition: background .12s, border-color .12s, transform .06s;
}
.btn:hover { background: var(--accent-sombre); border-color: var(--accent-sombre); }
.btn:active { transform: translateY(1px); }

/* Un champ fichier ne se declenche que par son label : c'est pourquoi certains
   boutons sont des <label>. Ils heritent alors de la regle des libelles de
   formulaire, dont un margin-bottom qui les remonte de deux pixels au-dessus
   de leurs voisins. Un label deguise en bouton est un bouton. */
label.btn { display: inline-flex; margin-bottom: 0; }

.btn.secondary {
  background: var(--surface); color: var(--accent-fort); border-color: var(--line);
}
.btn.secondary:hover { background: var(--tint); border-color: var(--accent-fort); }

.btn.ok { background: var(--succes); border-color: var(--succes); color: #fff; }
.btn.ok:hover { background: #14683a; border-color: #14683a; }

.btn.danger { background: var(--erreur); border-color: var(--erreur); color: #fff; }
.btn.danger:hover { background: #921e18; border-color: #921e18; }

.btn.small { padding: var(--esp-1) var(--esp-3); min-height: 30px; font-size: var(--txt-xs); }

.btn:disabled, .btn[aria-disabled="true"] {
  opacity: .45; cursor: not-allowed; transform: none;
}
.btn:disabled:hover { background: var(--accent-fort); border-color: var(--accent-fort); }
.btn.secondary:disabled:hover { background: var(--surface); border-color: var(--line); }

/* Chargement : le bouton reste à sa taille et dit ce qu'il fait, plutôt que
   de se figer sans explication. */
.btn.chargement { cursor: progress; }
.btn.chargement::before {
  content: ''; width: 13px; height: 13px; flex: none;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%; animation: kw-tourne .7s linear infinite;
}
@keyframes kw-tourne { to { transform: rotate(360deg); } }

/* =====================================================================
   5. Formulaires
   Libellé au-dessus, aide dessous, erreurs lisibles.
   ===================================================================== */
label {
  display: block; font-size: var(--txt-sm); font-weight: 500;
  color: var(--ink); margin-bottom: var(--esp-1);
}
input, select, textarea {
  font: inherit; font-size: var(--txt-md); width: 100%;
  padding: var(--esp-2) var(--esp-3);
  min-height: 38px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink);
  transition: border-color .12s, box-shadow .12s;
}
input:hover, select:hover, textarea:hover { border-color: var(--muted); }
input:focus, select:focus, textarea:focus {
  border-color: var(--accent-fort);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-fort) 18%, transparent);
}
input[type="checkbox"], input[type="radio"] { width: auto; min-height: 0; }
input[type="color"] { padding: 2px; }
textarea { resize: vertical; min-height: 84px; }
input::placeholder, textarea::placeholder { color: var(--muted); opacity: .75; }

/* Aide sous un champ. Toujours sous le champ, jamais au-dessus du libellé. */
.hint { display: block; color: var(--muted); font-size: var(--txt-xs); margin-top: var(--esp-1); }

/* Groupes de champs : de l'air entre les blocs, pas entre les lignes. */
.grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--esp-4) var(--esp-5); }
.grid .full { grid-column: 1 / -1; }
.field-check { display: flex; align-items: center; gap: var(--esp-2); }
.field-check label { margin: 0; font-weight: 400; }

fieldset {
  border: 1px solid var(--line); border-radius: var(--r-md);
  margin: var(--esp-5) 0; padding: var(--esp-5);
}
legend { font-weight: 600; font-size: var(--txt-sm); padding: 0 var(--esp-2); color: var(--muted); }

.actions { display: flex; gap: var(--esp-3); flex-wrap: wrap; margin-top: var(--esp-5); }
.actions .spacer { flex: 1; }

.filters { display: flex; gap: var(--esp-3); flex-wrap: wrap; margin-bottom: var(--esp-4); }
.filters input, .filters select { min-width: 150px; }

/* =====================================================================
   6. Tableaux
   Plus d'air, en-têtes lisibles et collants, actions en fin de ligne.
   ===================================================================== */
table { width: 100%; border-collapse: collapse; font-size: var(--txt-md); }
th, td {
  text-align: left;
  padding: var(--esp-3) var(--esp-4);
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
th {
  background: var(--tint);
  font-size: var(--txt-xs); font-weight: 600;
  text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted);
  white-space: nowrap;
}
tbody tr { transition: background .1s; }
tbody tr:hover { background: var(--tint); }
tbody tr:last-child td { border-bottom: 0; }

/* Actions groupées en fin de ligne, discrètes tant qu'on ne survole pas. */
td.col-act, th.col-act { text-align: right; white-space: nowrap; width: 1%; }
td.col-act > * + * { margin-left: var(--esp-1); }
.col-check { width: 2.4rem; text-align: center; }
.col-check input { width: auto; }

/* L'en-tête se cale sur le haut du cadre, plus sur la barre supérieure : il
   reste lisible quelle que soit la largeur de l'écran, et sur un long tableau
   on garde le nom des colonnes sous les yeux. */
thead th { position: sticky; top: 0; z-index: 2; }

/* =====================================================================
   7. Badges d'état
   Un statut se lit à la couleur et au mot, jamais à la couleur seule.
   ===================================================================== */
.badge {
  display: inline-block; padding: .15rem var(--esp-2);
  border-radius: var(--r-plein);
  font-size: var(--txt-xs); font-weight: 600;
  line-height: 1.5; white-space: nowrap;
  background: var(--tint); color: var(--muted);
}
.badge.succes, .badge.valide, .badge.actif { background: var(--succes-fond); color: var(--succes); }
.badge.attention, .badge.a_revoir, .badge.en_attente,
.badge.en_pause, .badge.en_pause_demandee { background: var(--attention-fond); color: var(--attention); }
.badge.erreur, .badge.resilie, .badge.resiliation_demandee { background: var(--erreur-fond); color: var(--erreur); }
.badge.information, .badge.en_cours_signature { background: var(--information-fond); color: var(--information); }
.badge.inactif { background: var(--tint); color: var(--muted); }

/* =====================================================================
   8. Bandeaux
   ===================================================================== */
.alert {
  padding: var(--esp-3) var(--esp-4);
  border-radius: var(--r-sm);
  margin-bottom: var(--esp-4);
  font-size: var(--txt-sm);
  background: var(--information-fond); border: 1px solid transparent; color: var(--ink);
}
.alert.error { background: var(--erreur-fond); border-color: color-mix(in srgb, var(--erreur) 25%, transparent); color: var(--erreur); }
.alert.succes { background: var(--succes-fond); border-color: color-mix(in srgb, var(--succes) 25%, transparent); color: var(--succes); }
.alert.attention { background: var(--attention-fond); border-color: color-mix(in srgb, var(--attention) 25%, transparent); color: var(--attention); }
.alert ul { margin: var(--esp-1) 0 0; padding-left: var(--esp-5); }

/* =====================================================================
   9. États vides et chargements
   Un écran vide dit quoi faire. Un chargement se voit.
   ===================================================================== */
.empty, td.empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--esp-2);
  color: var(--muted); text-align: center;
  padding: var(--esp-6) var(--esp-4);
  font-size: var(--txt-sm);
}
.empty .vide-titre { color: var(--ink); font-weight: 600; font-size: var(--txt-md); }
.empty .vide-ic { font-size: 1.6rem; color: var(--accent); opacity: .55; line-height: 1; }
.empty .btn { margin-top: var(--esp-2); }

.chargement-bloc {
  display: flex; align-items: center; justify-content: center; gap: var(--esp-3);
  color: var(--muted); padding: var(--esp-6) var(--esp-4); font-size: var(--txt-sm);
}
.chargement-bloc::before {
  content: ''; width: 16px; height: 16px; flex: none;
  border: 2px solid var(--line); border-top-color: var(--accent-fort);
  border-radius: 50%; animation: kw-tourne .7s linear infinite;
}

/* =====================================================================
   10. Toast
   ===================================================================== */
.toast {
  position: fixed; bottom: var(--esp-5); left: 50%;
  transform: translateX(-50%) translateY(1.5rem);
  background: var(--ink); color: var(--bg);
  padding: var(--esp-3) var(--esp-5);
  border-radius: var(--r-sm); box-shadow: var(--ombre-3);
  font-size: var(--txt-sm);
  opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s;
  max-width: 90vw; z-index: 60;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast.ok { background: var(--succes); color: #fff; }
.toast.err { background: var(--erreur); color: #fff; }

/* =====================================================================
   11. Pastilles de couleur du vin
   Elles décrivent le vin, pas le thème : valeurs fixes des deux côtés.
   ===================================================================== */
.dot {
  display: inline-block; width: .7rem; height: .7rem; border-radius: 50%;
  margin-right: var(--esp-1); vertical-align: -1px;
  border: 1px solid rgba(0, 0, 0, .15);
}
.dot.Rouge { background: #7b1e2b; }
.dot.Rosé { background: #e8a0b4; }
.dot.Blanc { background: #efe7b8; }
.dot.Orange { background: #e08a2e; }

/* =====================================================================
   12. Tableaux de bord (lot B3)
   Communs aux deux consoles : mêmes briques, contenus différents.
   ===================================================================== */

/* La bannière de tête : une seule action mise en avant, celle qui attend.
   Un tableau de bord qui hiérarchise tout au même niveau ne hiérarchise rien. */
.tdb-priorite {
  display: flex; align-items: center; gap: var(--esp-4);
  background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--attention) 35%, var(--line));
  border-left: 4px solid var(--attention);
  border-radius: var(--r-md); box-shadow: var(--ombre-1);
  padding: var(--esp-5);
  margin-bottom: var(--esp-5);
  color: inherit; text-decoration: none;
  transition: box-shadow .12s, transform .12s;
}
a.tdb-priorite:hover { box-shadow: var(--ombre-2); transform: translateY(-1px); }
.tdb-priorite--calme { border-color: var(--line); border-left-color: var(--succes); }
.tdb-priorite-num {
  font-size: var(--txt-2xl); font-weight: 700; line-height: 1;
  color: var(--attention); flex: none; min-width: 2.2ch; text-align: center;
}
.tdb-priorite--calme .tdb-priorite-num { color: var(--succes); font-size: 1.7rem; }
.tdb-priorite-txt { flex: 1; display: flex; flex-direction: column; gap: var(--esp-1); min-width: 0; }
.tdb-priorite-txt .crumb { margin: 0; }
.tdb-priorite-fleche { color: var(--muted); flex: none; }

/* Chiffres clés. Communs aux deux tableaux de bord : ils étaient définis dans
   la seule feuille super-admin, l'espace établissement les aurait affichés
   sans aucun style. */
.stats-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--esp-4); margin-bottom: var(--esp-6);
}
.stat-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: var(--ombre-1); padding: var(--esp-5) var(--esp-4); text-align: center;
}
.stat-num { font-size: var(--txt-2xl); font-weight: 700; color: var(--accent-sombre); line-height: var(--interligne-serre); }
.stat-lbl { color: var(--muted); font-size: var(--txt-sm); margin-top: var(--esp-1); }

/* Un chiffre clé qui appelle une correction se signale, sans crier. */
.stat-card--alerte { border-color: color-mix(in srgb, var(--attention) 45%, var(--line)); }
.stat-card--alerte .stat-num { color: var(--attention); }
.tdb-maj { margin: calc(-1 * var(--esp-4)) 0 var(--esp-5); }

/* Deux colonnes sur écran large, une seule dès que ça serre. */
.tdb-colonnes { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: var(--esp-4); margin-bottom: var(--esp-4); }
.tdb-bloc { padding: var(--esp-5); margin-bottom: var(--esp-4); }
.tdb-bloc h2 { margin: 0 0 var(--esp-2); font-size: var(--txt-lg); }
.tdb-bloc > .crumb { margin-bottom: var(--esp-3); }
.tdb-sous { font-size: var(--txt-sm); color: var(--muted); margin: var(--esp-4) 0 var(--esp-2); font-weight: 600; }
.tdb-badges { display: flex; gap: var(--esp-2); flex-wrap: wrap; }
.tdb-titre-raccourcis { margin: var(--esp-6) 0 var(--esp-3); font-size: var(--txt-lg); }
.tdb-plus { display: inline-block; margin-top: var(--esp-3); font-size: var(--txt-sm); color: var(--accent-fort); }

/* Listes courtes : un titre, une ligne de contexte, un état à droite. */
.tdb-liste { list-style: none; margin: 0; padding: 0; }
.tdb-liste li {
  display: flex; align-items: center; gap: var(--esp-3);
  padding: var(--esp-3) 0; border-bottom: 1px solid var(--line);
}
.tdb-liste li:last-child { border-bottom: 0; }
.tdb-liste li > a { flex: 1; min-width: 0; color: inherit; text-decoration: none; display: block; }
.tdb-liste li > a:hover .tdb-liste-titre { color: var(--accent-fort); text-decoration: underline; }
.tdb-liste-titre { display: block; font-size: var(--txt-md); font-weight: 500; }
.tdb-liste .crumb { margin: 0; }

/* Fil d'activité : une icône, un fait, une date relative. */
.tdb-fil { list-style: none; margin: 0; padding: 0; }
.tdb-fil li { display: flex; align-items: flex-start; gap: var(--esp-3); padding: var(--esp-2) 0; }
.tdb-fil li > a { color: inherit; text-decoration: none; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tdb-fil li > a:hover span:first-child { color: var(--accent-fort); text-decoration: underline; }
.tdb-fil-ic { color: var(--accent); opacity: .6; margin-top: 3px; flex: none; width: 1rem; text-align: center; }
.tdb-fil .crumb { margin: 0; }

/* Répartition : des barres, pas un camembert. On compare des longueurs bien
   mieux que des angles. */
.tdb-barres { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--esp-3); }
.tdb-barres li { display: grid; grid-template-columns: 7rem 1fr 2.5rem; align-items: center; gap: var(--esp-3); }
.tdb-barre-lbl { font-size: var(--txt-sm); display: flex; align-items: center; }
.tdb-barre { background: var(--tint); border-radius: var(--r-plein); height: 10px; overflow: hidden; }
.tdb-barre-part { display: block; height: 100%; background: var(--accent); border-radius: var(--r-plein); }
.tdb-barre-num { font-size: var(--txt-sm); font-weight: 600; text-align: right; color: var(--muted); }

/* Bloc en attente : annonce ce qui viendra, sans faux chiffres. */
.tdb-attente { border-style: dashed; background: var(--tint-soft); }
.tdb-attente h2 { color: var(--muted); }
.tdb-attente p { font-size: var(--txt-sm); margin: 0 0 var(--esp-2); }

/* Accueil des deux consoles : titre d'accueil et tuiles de raccourcis.
   Communs eux aussi, chaque console les définissait de son côté. */
.accueil-hi { margin: var(--esp-5) 0 var(--esp-1); font-size: var(--txt-xl); }
.accueil-sub { color: var(--muted); margin: 0 0 var(--esp-6); }
.accueil-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: var(--esp-4); }
.accueil-btn {
  display: flex; flex-direction: column; align-items: center; gap: var(--esp-3);
  text-align: center; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-md); box-shadow: var(--ombre-1);
  padding: var(--esp-6) var(--esp-4);
  color: inherit; text-decoration: none; cursor: pointer;
  transition: border-color .12s, transform .12s, box-shadow .12s;
}
.accueil-btn:hover { border-color: var(--accent); transform: translateY(-2px); box-shadow: var(--ombre-2); }
.accueil-btn .ic { font-size: 1.9rem; color: var(--accent); }
.accueil-btn.disabled { opacity: .5; cursor: not-allowed; pointer-events: none; }
.accueil-btn small { color: var(--muted); font-size: var(--txt-xs); }

/* =====================================================================
   13. Statistiques (lot B4)
   ===================================================================== */

/* Sélecteur de période, dans l'en-tête de page. */
.stat-periodes { display: flex; gap: var(--esp-1); }
.stat-periodes button {
  font: inherit; font-size: var(--txt-sm); cursor: pointer;
  background: var(--surface); color: var(--muted);
  border: 1px solid var(--line); border-radius: var(--r-plein);
  padding: var(--esp-1) var(--esp-3);
}
.stat-periodes button:hover { border-color: var(--accent-fort); color: var(--ink); }
.stat-periodes button.on { background: var(--accent-fort); border-color: var(--accent-fort); color: var(--on-accent); font-weight: 600; }

/* Histogramme de fréquentation. En SVG et sans bibliothèque : deux courbes ne
   justifient pas une dépendance de plus. preserveAspectRatio none étire les
   barres à la largeur disponible, la hauteur reste lisible. */
.stat-graphe {
  width: 100%; height: 120px; display: block;
  margin: var(--esp-3) 0 var(--esp-4);
  overflow: visible;
}
.stat-graphe rect { fill: var(--accent); transition: fill .12s; }
.stat-graphe rect:hover { fill: var(--accent-fort); }
/* Ligne de base : sans elle, une période creuse n'affiche rien du tout et on
   ne sait plus si le graphe est vide ou cassé. */
.stat-graphe .stat-graphe-axe { fill: var(--line); }
.stat-graphe .stat-graphe-axe:hover { fill: var(--line); }

.stat-creneaux {
  display: flex; gap: var(--esp-5); flex-wrap: wrap;
  padding-top: var(--esp-3); border-top: 1px solid var(--line);
  font-size: var(--txt-sm);
}
.stat-creneaux strong { font-size: var(--txt-lg); color: var(--accent-sombre); margin-right: var(--esp-1); }
.stat-creneaux .crumb { margin: 0; display: inline; }

/* Tendance : la flèche et le mot, jamais la couleur seule. */
.stat-tendance { font-size: var(--txt-sm); font-weight: 500; color: var(--muted); margin-left: var(--esp-2); }
.stat-tendance.up { color: var(--succes); }
.stat-tendance.down { color: var(--attention); }

.stat-rang {
  flex: none; width: 1.6rem; height: 1.6rem; border-radius: 50%;
  background: var(--tint); color: var(--muted);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--txt-xs); font-weight: 700;
}
.stat-gros { font-size: 2.4rem; font-weight: 700; color: var(--accent-sombre); margin: var(--esp-3) 0 var(--esp-1); line-height: 1; }
.stat-note { margin-top: var(--esp-5); font-style: italic; }

/* Usage global des filtres, côté super-admin. */
.stat-familles { display: flex; gap: var(--esp-2); flex-wrap: wrap; margin-bottom: var(--esp-3); }

/* =====================================================================
   14. Interrupteur
   Une case à cocher qui commande un comportement, pas une valeur. Le
   libellé fait partie de la zone cliquable.
   ===================================================================== */
label.interrupteur {
  display: inline-flex; align-items: center; gap: var(--esp-3);
  cursor: pointer; font-weight: 500; margin-bottom: var(--esp-1);
}
label.interrupteur input { width: auto; margin: 0; accent-color: var(--accent-fort); }
label.interrupteur + .hint { display: block; margin-top: 0; }

/* =====================================================================
   15. Champ assorti d'un bouton
   Le bouton reste à hauteur du champ, sans le rétrécir sur mobile.
   ===================================================================== */
.champ-genere { display: flex; gap: var(--esp-2); align-items: center; }
.champ-genere input { flex: 1; min-width: 0; }
.champ-genere .btn { flex-shrink: 0; }

/* =====================================================================
   16. Bandeau d'accès délégué
   Il traverse toute la largeur et ne défile pas : on ne doit jamais oublier
   qu'on travaille dans l'espace de quelqu'un d'autre.
   ===================================================================== */
.bandeau-delegation {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--esp-4); flex-wrap: wrap;
  width: 100%;
  background: var(--attention-fond); color: var(--attention);
  border-bottom: 2px solid var(--attention);
  padding: var(--esp-3) var(--esp-5);
  font-size: var(--txt-sm);
}
.bandeau-delegation .btn.secondary {
  background: var(--surface); color: var(--attention); border-color: var(--attention);
}
/* Le bandeau est un enfant direct de la coquille, qui est en ligne : il doit
   prendre la largeur entière et pousser le reste vers le bas. */
.shell:has(> .bandeau-delegation) { flex-wrap: wrap; }

/* =====================================================================
   17. Modale
   Sert à l'aperçu d'une sélection avant validation en masse. Le fond
   assombri ferme au clic, la touche Échap aussi : une modale dont on ne
   sort qu'en visant un bouton est une modale piégeuse.
   ===================================================================== */
.modale-fond {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(0, 0, 0, .45);
  display: flex; align-items: center; justify-content: center;
  padding: var(--esp-5);
}
.modale {
  background: var(--surface); color: var(--ink);
  border-radius: var(--r-lg); box-shadow: var(--ombre-3);
  padding: var(--esp-5);
  width: min(760px, 100%);
  max-height: min(80dvh, 100%);
  display: flex; flex-direction: column;
}
.modale .pagehead { margin-bottom: var(--esp-2); }
/* Le tableau défile dans la modale, jamais la modale elle-même : les actions
   restent sous les yeux quelle que soit la longueur de la sélection. */
.modale-corps { overflow: auto; flex: 1; margin: var(--esp-3) 0; border: 1px solid var(--line); border-radius: var(--r-md); }
.modale-corps table { margin: 0; }
.modale-corps thead th { position: sticky; top: 0; z-index: 2; }
.modale .actions { margin-top: 0; display: flex; align-items: center; gap: var(--esp-3); }
.modale .spacer { flex: 1; }

/* Intertitre dans un bloc de tableau de bord. Sert à distinguer deux signaux
   d'une même rubrique : les mots cherchés et les combinaisons de filtres. */
.tdb-sous-titre {
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 1rem 0 .2rem;
}
.tdb-sous-titre:first-child { margin-top: 0; }

/* Texte réservé aux lecteurs d'écran. Une icône sans libellé visible doit
   quand même se nommer. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* --- Bascule « suggérer à l'apéritif » -------------------------------- */
/* Une icône, pas un bouton texte : ces lignes portent déjà beaucoup. Éteinte,
   elle est en contour simple et se fond dans la ligne. Active, elle est pleine
   dans la couleur de marque et se voit d'un coup d'œil.
   Le contour, lui, ne se fond pas : sans lui, l'icône seule ne se lisait pas
   comme un bouton et on ne savait pas qu'elle se touchait. C'est le même trait
   que les boutons secondaires de la console. */
.apero-bascule {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 0;
  border: 1px solid var(--line); background: none; cursor: pointer;
  color: var(--muted);
  border-radius: var(--radius);
  transition: color .12s ease, background-color .12s ease, border-color .12s ease;
}
.apero-bascule:hover { color: var(--accent); border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, transparent); }
.apero-bascule.on { color: var(--accent); border-color: var(--accent); }
.apero-bascule:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* --- Bascule « suggérer des vins » ------------------------------------ */
/* Même geste que la bascule d'apéritif, juste à côté d'elle : une icône, deux
   états, la couleur de marque quand c'est actif. Elle porte en plus le nombre
   de vins conseillés, car « un » et « trois » ne se lisent pas pareil. */
.vins-bascule {
  display: inline-flex; align-items: center; justify-content: center; gap: .15rem;
  min-width: 32px; height: 32px; padding: 0 .25rem;
  border: 1px solid var(--line); background: none; cursor: pointer;
  color: var(--muted);
  border-radius: var(--radius);
  transition: color .12s ease, background-color .12s ease, border-color .12s ease;
}
.vins-bascule:hover { color: var(--accent); border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, transparent); }
.vins-bascule.on { color: var(--accent); border-color: var(--accent); }
.vins-bascule:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.vins-compte { font-size: .7rem; font-weight: 700; line-height: 1; }
