/* components.css — boutons, champs, tableaux, cartes, badges, alertes, tuiles.
   Une seule définition par composant ; aucune surcharge dans les pages. */

/* --- Boutons -------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: var(--control-h); padding: 0 var(--sp-4); border-radius: var(--radius-sm);
  border: 1px solid transparent; font-weight: 500; font-size: var(--fs-sm); cursor: pointer;
  text-decoration: none; white-space: nowrap; transition: background .15s, border-color .15s;
}
.btn:hover { text-decoration: none; }
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn-primary   { background: var(--c-primary); color: var(--c-text-invert); }
.btn-primary:hover { background: var(--c-primary-hover); color: var(--c-text-invert); }
.btn-secondary { background: var(--c-surface); color: var(--c-text); border-color: var(--c-border-strong); }
.btn-secondary:hover { background: var(--c-surface-2); }
.btn-danger    { background: var(--c-danger); color: var(--c-text-invert); }
.btn-ghost     { background: transparent; color: var(--c-text-muted); }
.btn-ghost:hover { background: var(--c-surface-2); color: var(--c-text); }
.btn-sm { min-height: 30px; padding: 0 var(--sp-3); font-size: var(--fs-xs); }
.btn-lg { min-height: 48px; padding: 0 var(--sp-5); font-size: var(--fs-md); }
.btn-block { width: 100%; }

/* Action discrète : se lit comme un lien, s'utilise indifféremment sur <a> ou <button>.
   Pour « Retirer », « Vider le panier », « Tout effacer », « Annuler » — ces gestes
   secondaires qui ne doivent pas peser autant qu'un bouton plein à côté de l'action
   principale, mais qui restent de vraies commandes.

   Le chrome natif du <button> est explicitement neutralisé (appearance, background,
   border, padding, font) : sans cela le navigateur dessine son fond gris et sa bordure
   dès qu'on pose une classe de lien sur un bouton, et les deux ne se ressemblent plus.
   Le soulignement n'apparaît qu'au survol : au repos la ligne resterait du bruit. */
.btn-link {
  display: inline-flex; align-items: center; gap: var(--sp-1);
  min-height: 0; margin: 0; padding: 0;
  -webkit-appearance: none; appearance: none;
  background: none; border: 0; border-radius: var(--radius-sm);
  color: var(--c-text-muted); font: inherit; font-size: var(--fs-sm); line-height: 1.5;
  text-align: left; text-decoration: none; cursor: pointer;
  transition: color .15s;
}
.btn-link:hover { color: var(--c-primary); text-decoration: underline; text-underline-offset: 3px; }
.btn-link:focus-visible { outline: 2px solid var(--c-primary); outline-offset: 3px; }
.btn-link:disabled { opacity: .55; cursor: not-allowed; text-decoration: none; color: var(--c-text-muted); }
.btn-link .bi { font-size: 1em; }
/* Geste destructeur (retirer, vider, supprimer) : neutre au repos, rouge à l'intention —
   la couleur prévient au moment du survol, elle n'alarme pas en permanence. */
.btn-link-danger:hover, .btn-link-danger:focus-visible { color: var(--c-danger); }
/* Action posée au milieu d'une phrase (« Gérer mes cookies », « Renvoyer le code ») :
   là, rien d'autre ne signale qu'on peut cliquer, donc couleur d'enseigne et soulignement
   permanents — exactement ce qu'on attend d'un lien dans du texte courant. */
.btn-link-accent { color: var(--c-primary); text-decoration: underline; text-underline-offset: 3px; }
.btn-link-accent:hover { color: var(--c-primary-hover); }

/* --- Formulaires ----------------------------------------------------------- */
.form-stack { display: flex; flex-direction: column; gap: var(--sp-4); }
.form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--sp-4); }
.field { display: flex; flex-direction: column; gap: var(--sp-1); }
.field label { font-size: var(--fs-sm); font-weight: 500; }
.field .hint { font-size: var(--fs-xs); color: var(--c-text-muted); }
.field .error { font-size: var(--fs-xs); color: var(--c-danger); }
input[type="text"], input[type="email"], input[type="password"], input[type="number"], input[type="search"],
input[type="date"], input[type="tel"], input[type="url"], select, textarea {
  width: 100%; min-height: var(--control-h); padding: var(--sp-2) var(--sp-3);
  background: var(--c-surface); border: 1px solid var(--c-border-strong); border-radius: var(--radius-sm);
  transition: border-color .15s, box-shadow .15s;
}
select { padding-right: 2rem; }
textarea { min-height: 96px; resize: vertical; }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--c-primary); box-shadow: 0 0 0 3px var(--c-primary-soft); }
input[aria-invalid="true"], .field.is-invalid input, .field.is-invalid select { border-color: var(--c-danger); }
.checkbox { display: inline-flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-sm); }
form.inline { display: inline; }

/* --- Cartes ---------------------------------------------------------------- */
.card { background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius); box-shadow: var(--shadow-sm); }
.card-header { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--c-border); background: linear-gradient(90deg, var(--c-primary-soft), var(--c-surface) 65%); border-radius: var(--radius) var(--radius) 0 0; }
.card-header h2 .bi { color: var(--c-primary); margin-right: var(--sp-1); }
.card-header h2 { margin: 0; font-size: var(--fs-md); }
.card-body { padding: var(--sp-4); }
.card-footer { padding: var(--sp-3) var(--sp-4); border-top: 1px solid var(--c-border); background: var(--c-surface-2); border-radius: 0 0 var(--radius) var(--radius); }

/* --- Tuiles statistiques ---------------------------------------------------- */
.stat-tile { position: relative; display: flex; flex-direction: column; gap: var(--sp-1); padding: var(--sp-4) var(--sp-4) var(--sp-4) calc(var(--sp-4) + 6px); background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow-sm); }
.stat-tile::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 6px; background: var(--c-primary); }
.stat-grid > .stat-tile:nth-child(4n+2)::before { background: var(--c-accent); }
.stat-grid > .stat-tile:nth-child(4n+3)::before { background: var(--c-success); }
.stat-grid > .stat-tile:nth-child(4n+4)::before { background: var(--c-warning); }
.stat-tile .stat-value { color: var(--c-text); }
.stat-label { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .04em; color: var(--c-text-muted); }
.stat-value { font-size: var(--fs-2xl); font-weight: 600; line-height: 1.1; font-variant-numeric: tabular-nums; }
.stat-delta { font-size: var(--fs-sm); }
.stat-delta.up { color: var(--c-success); } .stat-delta.down { color: var(--c-danger); }

/* --- Tableaux --------------------------------------------------------------- */
.table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.table th, .table td { padding: var(--sp-2) var(--sp-3); text-align: left; border-bottom: 1px solid var(--c-border); vertical-align: middle; }
.table thead th { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .04em; color: var(--c-primary); font-weight: 600; background: var(--c-primary-soft); border-bottom-color: color-mix(in srgb, var(--c-primary) 25%, var(--c-border)); }
.table tbody tr:hover td { background: var(--c-surface-2); }
.table tbody tr:hover { background: var(--c-surface-2); }
.table tbody tr.row-active { background: var(--c-primary-soft); }
/* Ligne cliquable en entier (voir app.js) : elle doit l'annoncer avant qu'on clique.
   Le survol existe déjà au-dessus ; il ne reste que le curseur à poser. */
.table tbody tr.is-rowlink { cursor: pointer; }
/* Le lien principal ne se souligne plus au survol de la ligne entière : c'est toute la
   ligne qui réagit, souligner un seul mot laisserait croire qu'elle seule est la cible. */
.table tbody tr.is-rowlink:hover a:not(.btn) { text-decoration: none; }
.table-compact th, .table-compact td { padding: var(--sp-1) var(--sp-2); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }
.table-wrap { overflow-x: auto; }

/* --- Badges ---------------------------------------------------------------- */
.badge { display: inline-block; padding: .15em .55em; border-radius: 999px; font-size: var(--fs-xs); font-weight: 600; line-height: 1.4; white-space: nowrap; }
.badge-muted   { background: var(--c-surface-2); color: var(--c-text-muted); border: 1px solid var(--c-border); }
.badge-success { background: var(--c-success-soft); color: var(--c-success); }
.badge-warning { background: var(--c-warning-soft); color: var(--c-warning); }
.badge-danger  { background: var(--c-danger-soft);  color: var(--c-danger); }
.badge-info    { background: var(--c-info-soft);    color: var(--c-info); }

/* --- Alertes ---------------------------------------------------------------- */
.alert { padding: var(--sp-3) var(--sp-4); border-radius: var(--radius-sm); border: 1px solid transparent; margin-bottom: var(--sp-4); font-size: var(--fs-sm); }
.alert-success { background: var(--c-success-soft); color: var(--c-success); border-color: #bfe6cc; }
.alert-warning { background: var(--c-warning-soft); color: var(--c-warning); border-color: #f3dfae; }
.alert-danger  { background: var(--c-danger-soft);  color: var(--c-danger);  border-color: #f2bcbc; }
.alert-info    { background: var(--c-info-soft);    color: var(--c-info);    border-color: #bcd3f0; }

/* --- Tuiles de modules (accueil POS / raccourcis) ------------------------------- */
.tile-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: var(--sp-4); }
.tile { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-2); min-height: 120px; padding: var(--sp-4); background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius); color: var(--c-text); text-align: center; }
.tile:hover { border-color: var(--c-primary); text-decoration: none; box-shadow: var(--shadow-sm); }
.tile i { font-size: 2rem; color: var(--c-primary); }

/* --- Vide / chargement ------------------------------------------------------------ */
.empty { padding: var(--sp-6); text-align: center; color: var(--c-text-muted); }

/* --- Onglets ------------------------------------------------------------------ */
.tabs { display: flex; gap: var(--sp-1); border-bottom: 1px solid var(--c-border); margin-bottom: var(--sp-5); overflow-x: auto; }
.tabs-sm { margin-bottom: var(--sp-3); } .tabs-sm a { padding: var(--sp-1) var(--sp-3); font-size: var(--fs-sm); }
.tabs a { padding: var(--sp-2) var(--sp-4); margin-bottom: -1px; border-bottom: 2px solid transparent; color: var(--c-text-muted); font-weight: 500; font-size: var(--fs-sm); white-space: nowrap; }
.tabs a:hover { color: var(--c-text); text-decoration: none; }
.tabs a.active { color: var(--c-primary); border-bottom-color: var(--c-primary); background: linear-gradient(transparent, var(--c-primary-soft)); border-radius: var(--radius-sm) var(--radius-sm) 0 0; }

/* --- Grille d'horaires ---------------------------------------------------------- */
.hours-grid { display: grid; grid-template-columns: 7rem auto 1fr 1fr; gap: var(--sp-2) var(--sp-3); align-items: center; }
.hours-grid .day { font-weight: 500; }
.hours-grid input[type="time"] { min-height: 34px; }

/* --- Bannière d'installation (PWA) --------------------------------------------- */
/* Bannière « Installer l'application » : au-dessus de la barre supérieure, dans le flux (elle défile, la barre reste) */
.pwa-banner { position: relative; z-index: 60; display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2) var(--sp-3); padding: var(--sp-2) var(--sp-4); background: var(--c-primary-soft); border-bottom: 1px solid color-mix(in srgb, var(--c-primary) 30%, var(--c-border)); font-size: var(--fs-sm); }
.pwa-banner .pwa-icon { color: var(--c-primary); font-size: 1.5rem; line-height: 1; }
.pwa-banner .pwa-body { flex: 1; min-width: 200px; display: flex; flex-direction: column; }
.pwa-banner .pwa-title { color: var(--c-primary); }
.pwa-banner .pwa-text { color: var(--c-text-muted); }
.ctx-pos .pwa-banner { background: var(--c-surface-2); }
@media (max-width: 600px) { .pwa-banner { padding: var(--sp-2) var(--sp-3); } .pwa-banner .pwa-body { min-width: 0; flex: 1 0 100%; } }
.card[data-collapsible] > .card-header { user-select: none; }
.card[data-collapsible].collapsed > :not(.card-header) { display: none; }
.card[data-collapsible].collapsed > .card-header { border-bottom: none; }
.card-toggle i { transition: transform .15s; }
.card.collapsed .card-toggle i { transform: rotate(-90deg); }
.geo-suggest { position: absolute; z-index: 1050; background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius-sm); box-shadow: var(--shadow); max-height: 260px; overflow-y: auto; }
.geo-suggest button { display: block; width: 100%; text-align: left; padding: var(--sp-2) var(--sp-3); border: 0; background: none; font-size: var(--fs-sm); color: var(--c-text); cursor: pointer; }
.geo-suggest button:hover, .geo-suggest button.active { background: var(--c-surface-2); }
input.is-invalid { border-color: var(--c-danger); }

/* --- Jauges, listes de définitions, figures de graphique ------------------ */
.meter { height: 6px; background: var(--c-border); border-radius: 3px; overflow: hidden; }
.meter-bar { height: 100%; border-radius: 3px; background: var(--c-primary); transition: width .4s, background-color .4s; }
.meter-bar.bg-success { background: var(--c-success); } .meter-bar.bg-warning { background: var(--c-warning); }
.meter-bar.bg-danger { background: var(--c-danger); }   .meter-bar.bg-muted { background: var(--c-border-strong); }
.dl-grid { display: grid; grid-template-columns: max-content 1fr; gap: var(--sp-1) var(--sp-3); margin: 0; font-size: var(--fs-sm); }
.dl-grid dt { color: var(--c-text-muted); font-weight: 500; white-space: nowrap; }
.dl-grid dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.h6 { font-size: var(--fs-sm); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--c-text-muted); margin: 0 0 var(--sp-2); }
.mt-1 { margin-top: var(--sp-1); } .mt-3 { margin-top: var(--sp-3); } .mb-3 { margin-bottom: var(--sp-3); }
.fw-600 { font-weight: 600; }
.chart-figure { margin: 0; }
.chart-title { font-size: var(--fs-sm); font-weight: 600; margin-bottom: var(--sp-2); }
.chart-box { position: relative; width: 100%; }
.chart-box canvas { width: 100% !important; height: 100% !important; }

/* --- Documents : classeurs et visualisateur -------------------------------- */
.binder-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--sp-4); }
.binder-card { --binder-color: var(--c-primary); position: relative; display: flex; gap: var(--sp-3); padding: var(--sp-4); background: var(--c-surface); border: 1px solid var(--c-border); border-left: 4px solid var(--binder-color); border-radius: var(--radius); color: var(--c-text); box-shadow: var(--shadow-sm); transition: box-shadow .15s, transform .15s; }
.binder-card:hover { text-decoration: none; box-shadow: var(--shadow); transform: translateY(-1px); }
.binder-icon { display: inline-grid; place-items: center; width: 44px; height: 44px; flex: 0 0 auto; border-radius: 10px; background: color-mix(in srgb, var(--binder-color) 12%, transparent); color: var(--binder-color); font-size: 1.4rem; }
.binder-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.binder-desc { font-size: var(--fs-sm); }
.binder-meta { display: flex; flex-wrap: wrap; gap: var(--sp-1); align-items: center; margin-top: var(--sp-1); font-size: var(--fs-xs); }
.binder-edit { position: absolute; top: var(--sp-2); right: var(--sp-2); padding: var(--sp-1); color: var(--c-text-muted); border-radius: var(--radius-sm); }
.binder-edit:hover { background: var(--c-surface-2); color: var(--c-text); }
.doc-icon { font-size: 1.25rem; color: var(--c-text-muted); }
.doc-pdf { color: #c62828; } .doc-doc, .doc-docx { color: #1f4fd8; } .doc-xls, .doc-xlsx, .doc-csv { color: #1a8f4a; } .doc-ppt, .doc-pptx { color: #b7791f; }
.doc-jpg, .doc-jpeg, .doc-png, .doc-gif, .doc-webp, .doc-bmp, .doc-svg { color: #7c3aed; }
.viewer .modal-body { padding: 0; background: var(--c-surface-2); }
.viewer-body { min-height: 60vh; height: calc(100vh - 140px); overflow: auto; }
.modal-fullscreen-lg-down .viewer-body { height: auto; flex: 1; }
.viewer-frame { display: block; width: 100%; height: 100%; min-height: 60vh; border: 0; background: #525659; }
.viewer-image { display: grid; place-items: center; min-height: 60vh; padding: var(--sp-4); }
.viewer-image img { max-width: 100%; max-height: calc(100vh - 180px); box-shadow: var(--shadow); background: #fff; }
.viewer-doc { max-width: 900px; margin: var(--sp-4) auto; padding: var(--sp-6); background: var(--c-surface); box-shadow: var(--shadow); line-height: 1.6; }
.viewer-doc img { max-width: 100%; } .viewer-doc table { border-collapse: collapse; margin: var(--sp-3) 0; } .viewer-doc td, .viewer-doc th { border: 1px solid var(--c-border); padding: 4px 8px; }
.viewer-text { margin: var(--sp-4); padding: var(--sp-4); background: var(--c-surface); white-space: pre-wrap; font-size: var(--fs-sm); }
.viewer-tabs { margin: 0; padding: 0 var(--sp-3); background: var(--c-surface); position: sticky; top: 0; z-index: 2; }
.viewer-sheet { padding: var(--sp-3); }
.table-sheet { background: var(--c-surface); font-size: var(--fs-xs); width: auto; min-width: 100%; }
.table-sheet td { border: 1px solid var(--c-border); padding: 2px 6px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.viewer-message { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-3); min-height: 40vh; padding: var(--sp-6); color: var(--c-text-muted); text-align: center; }

/* --- Liste déroulante avec saisie (combo.js : select > 10 options) ----------- */
.combo { position: relative; }
.combo-native { position: absolute !important; width: 1px; height: 1px; opacity: 0; pointer-events: none; margin: 0; }
.combo-input { padding-right: 2rem; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right .6rem center; background-size: 12px; }
.combo-clear { position: absolute; right: 1.6rem; top: 50%; transform: translateY(-50%); border: 0; background: none; color: var(--c-text-muted); font-size: 1.1rem; line-height: 1; padding: 0 4px; cursor: pointer; }
.combo-clear:hover { color: var(--c-text); }
.combo-list { position: absolute; left: 0; right: 0; top: calc(100% + 2px); z-index: 1060; background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius-sm); box-shadow: var(--shadow); max-height: 280px; overflow-y: auto; }
.combo-list button { display: block; width: 100%; text-align: left; padding: var(--sp-2) var(--sp-3); border: 0; background: none; font-size: var(--fs-sm); color: var(--c-text); cursor: pointer; }
.combo-list button:hover, .combo-list button.active { background: var(--c-surface-2); }
.combo-list button.selected { font-weight: 600; color: var(--c-primary); }
.combo-empty { padding: var(--sp-2) var(--sp-3); color: var(--c-text-muted); font-size: var(--fs-sm); }
.modal .combo-list { z-index: 1060; }

/* --- Logos des fiches (marque, fournisseur, boutique, société) -------------- */
.logo-row { display: flex; gap: var(--sp-3); align-items: flex-start; }
.logo-preview { flex: 0 0 auto; width: 96px; height: 96px; display: grid; place-items: center; padding: 6px; background: #fff; border: 1px solid var(--c-border); border-radius: var(--radius-sm); }
.logo-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }
.logo-thumb { width: 36px; height: 36px; object-fit: contain; background: #fff; border: 1px solid var(--c-border); border-radius: 6px; padding: 2px; vertical-align: middle; }
.logo-thumb-placeholder { display: inline-grid; place-items: center; width: 36px; height: 36px; border-radius: 6px; background: var(--c-surface-2); color: var(--c-text-muted); font-weight: 600; font-size: var(--fs-sm); vertical-align: middle; }

/* --- Galerie d'images d'un modèle -------------------------------------------- */
.img-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--sp-3); }
.img-card { position: relative; margin: 0; display: flex; flex-direction: column; gap: var(--sp-1); padding: var(--sp-2); background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius-sm); }
.img-card.is-main { border-color: var(--c-success); box-shadow: 0 0 0 2px var(--c-success-soft); }
.img-card-pic, .img-card > img { display: block; aspect-ratio: 1; width: 100%; object-fit: contain; background: #fff; border-radius: 4px; overflow: hidden; }
.img-card-pic img { width: 100%; height: 100%; object-fit: contain; }
.img-card-badge { position: absolute; top: var(--sp-2); left: var(--sp-2); }
.img-card-alt { font-size: var(--fs-xs); min-height: 28px; padding: 2px 6px; }
.img-card-actions { display: flex; justify-content: space-between; gap: 2px; }
.img-card-actions .btn { padding: 2px 6px; }
.img-card figcaption { font-size: var(--fs-xs); color: var(--c-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* --- Marge nette (fiche produit) ----------------------------------------- */
.margin-box { display: flex; flex-direction: column; gap: var(--sp-1); padding: var(--sp-2) var(--sp-3); background: var(--c-surface-2); border: 1px solid var(--c-border); border-radius: var(--radius-sm); font-size: var(--fs-sm); }
.margin-line { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: baseline; font-variant-numeric: tabular-nums; }
.margin-line .margin-label { min-width: 220px; color: var(--c-text-muted); }
.margin-line.is-ok strong { color: var(--c-success); } .margin-line.is-low strong { color: var(--c-warning); } .margin-line.is-negative strong { color: var(--c-danger); }

/* --- Kanban (modèles par statut) ----------------------------------------- */
.kanban { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-4); align-items: start; }
.kanban-col { background: var(--c-surface-2); border: 1px solid var(--c-border); border-radius: var(--radius); min-height: 200px; transition: box-shadow .15s; }
.kanban-col.over { box-shadow: 0 0 0 2px var(--c-primary); }
.kanban-head { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--c-border); font-weight: 600; }
.kanban-body { display: flex; flex-direction: column; gap: var(--sp-2); padding: var(--sp-2); min-height: 120px; }
.kanban-card { display: grid; grid-template-columns: 56px 1fr; gap: var(--sp-2) var(--sp-3); padding: var(--sp-2); background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius-sm); box-shadow: var(--shadow-sm); cursor: grab; }
.kanban-card.dragging { opacity: .5; }
.kanban-pic { width: 56px; height: 56px; display: grid; place-items: center; background: #fff; border: 1px solid var(--c-border); border-radius: 6px; color: var(--c-text-muted); overflow: hidden; }
.kanban-pic img { width: 100%; height: 100%; object-fit: contain; }
.kanban-info { display: flex; flex-direction: column; gap: 1px; min-width: 0; font-size: var(--fs-sm); }
.kanban-info strong { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kanban-price { font-weight: 600; }
.kanban-actions { grid-column: 1 / -1; display: flex; gap: var(--sp-1); justify-content: flex-end; }
@media (max-width: 900px) { .kanban { grid-template-columns: 1fr; } }

/* --- To-Do ------------------------------------------------------------------- */
.todo-list { display: flex; flex-direction: column; }
.todo-item { display: grid; grid-template-columns: auto 1fr auto; gap: var(--sp-3); align-items: start; padding: var(--sp-3) var(--sp-4); border-top: 1px solid var(--c-border); }
.todo-item:first-child { border-top: 0; }
.todo-item.status-done .todo-title strong { text-decoration: line-through; color: var(--c-text-muted); }
.todo-item.is-late { background: color-mix(in srgb, var(--c-danger) 4%, transparent); }
.todo-check { display: flex; padding-top: 3px; cursor: pointer; }
.todo-check input { width: 20px; height: 20px; cursor: pointer; accent-color: var(--c-success); }
.todo-title { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.todo-desc { font-size: var(--fs-sm); margin-top: 2px; white-space: pre-line; }
.todo-meta { display: flex; flex-wrap: wrap; gap: var(--sp-3); font-size: var(--fs-xs); margin-top: var(--sp-1); }
.todo-actions { display: flex; gap: var(--sp-1); align-items: center; }
.todo-userlist { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--sp-1) var(--sp-3); max-height: 220px; overflow: auto; padding: var(--sp-2); border: 1px solid var(--c-border); border-radius: var(--radius-sm); }
.sidebar-badge { margin-left: auto; font-size: var(--fs-xs); background: var(--c-primary); color: var(--c-text-invert); border-radius: 999px; padding: 0 7px; line-height: 18px; }

/* --- Messagerie interne ------------------------------------------------------ */
.mail-layout { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: var(--sp-4); align-items: start; }
.mail-folders { display: flex; flex-direction: column; gap: 2px; background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius); padding: var(--sp-2); }
.mail-folders a { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2) var(--sp-3); border-radius: var(--radius-sm); color: var(--c-text); font-weight: 500; }
.mail-folders a:hover { background: var(--c-surface-2); text-decoration: none; }
.mail-folders a.active { background: var(--c-primary-soft); color: var(--c-primary); }
.mail-folders .badge { margin-left: auto; }
.mail-rows { display: flex; flex-direction: column; }
.mail-row { display: grid; grid-template-columns: auto 200px minmax(0, 1fr) auto; gap: var(--sp-3); align-items: center; padding: var(--sp-2) var(--sp-4); border-top: 1px solid var(--c-border); cursor: pointer; font-size: var(--fs-sm); }
.mail-row:hover { background: var(--c-surface-2); }
.mail-row.unread { background: color-mix(in srgb, var(--c-primary) 5%, transparent); }
.mail-row.unread .mail-from, .mail-row.unread .mail-subject a { font-weight: 700; }
.mail-from { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mail-subject { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mail-subject a { color: var(--c-text); }
.mail-date { font-size: var(--fs-xs); }
.mail-picker { border: 1px solid var(--c-border); border-radius: var(--radius-sm); }
.mail-picker-search { border: 0; border-bottom: 1px solid var(--c-border); border-radius: 0; min-height: 32px; }
.mail-picker-list { display: flex; flex-direction: column; gap: 2px; max-height: 190px; overflow: auto; padding: var(--sp-2); }
.mail-head { align-items: flex-start; }
.mail-body { white-space: pre-line; line-height: 1.6; }
.mail-msg-prev .mail-body { color: var(--c-text-muted); }
@media (max-width: 900px) { .mail-layout { grid-template-columns: 1fr; } .mail-folders { flex-direction: row; } .mail-row { grid-template-columns: auto minmax(0, 1fr) auto; } .mail-from { display: none; } }
.sidebar-badge-danger { background: var(--c-danger); }
.mail-attachments { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.mail-att { display: inline-flex; align-items: center; gap: var(--sp-2); padding: var(--sp-1) var(--sp-2); border: 1px solid var(--c-border); border-radius: var(--radius-sm); background: var(--c-surface-2); color: var(--c-text); font-size: var(--fs-sm); max-width: 320px; }
.mail-att:hover { text-decoration: none; border-color: var(--c-primary); }
.mail-att img { width: 40px; height: 40px; object-fit: cover; border-radius: 4px; }
.mail-att .doc-icon { font-size: 1.5rem; }
.mail-att-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 180px; }

/* Champ date jj/mm/aaaa (forms.js) : texte + bouton calendrier, natif caché mais focusable par showPicker() */
.date-field { display: flex; align-items: stretch; position: relative; }
.date-field input[type="text"] { flex: 1; min-width: 0; border-top-right-radius: 0; border-bottom-right-radius: 0; }
.date-field .date-btn { border-top-left-radius: 0; border-bottom-left-radius: 0; padding: 0 .6rem; }
.date-field .date-native { position: absolute; left: 0; bottom: 0; width: 1px; height: 1px; opacity: 0; pointer-events: none; border: 0; padding: 0; margin: 0; }

/* Barre d'actions groupées (sélection multiple dans un tableau) */
.bulk-bar { position: sticky; top: .5rem; z-index: 5; display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; padding: .6rem .9rem; margin-bottom: .75rem; background: var(--c-primary-soft, #fde8e8); border: 1px solid var(--c-primary, #c62828); border-radius: var(--radius, 8px); }
.bulk-bar.hidden { display: none; }
tr.row-selected td { background: var(--c-primary-soft, #fde8e8); }

/* Écrans — diaporama (vignettes triables) */
.scr-playlist { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: var(--sp-3, .75rem); }
.scr-item { position: relative; display: flex; flex-direction: column; gap: .4rem; padding: .6rem; border: 1px solid var(--c-border, #e3e6ee); border-radius: var(--radius, 10px); background: var(--c-surface, #fff); cursor: grab; }
.scr-item.dragging { opacity: .4; }
.scr-item.is-off { opacity: .55; }
.scr-item.is-expired .scr-thumb { filter: grayscale(1); }
.scr-pos { position: absolute; top: .4rem; left: .4rem; z-index: 2; min-width: 1.6rem; height: 1.6rem; padding: 0 .4rem; border-radius: 999px; background: var(--c-primary, #c62828); color: #fff; font-weight: 700; font-size: .8rem; display: grid; place-items: center; }
.scr-thumb { position: relative; aspect-ratio: 16 / 9; border-radius: var(--radius-sm, 6px); overflow: hidden; background: #111; display: grid; place-items: center; }
.scr-thumb img, .scr-thumb video { width: 100%; height: 100%; object-fit: cover; }
.scr-thumb-icon { position: absolute; right: .5rem; bottom: .4rem; color: #fff; font-size: 1.4rem; text-shadow: 0 0 6px #000; }
.scr-thumb-text { color: #fff; padding: .6rem; font-size: .8rem; line-height: 1.3; text-align: center; overflow: hidden; max-height: 100%; }
.scr-info { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.scr-info strong { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.scr-actions { display: flex; align-items: center; gap: .4rem; justify-content: space-between; }

/* Page « Installer l'application » : marche à suivre repliable */
.pwa-guide { border: 1px solid var(--c-border); border-radius: var(--radius-sm); padding: var(--sp-2) var(--sp-3); }
.pwa-guide + .pwa-guide { margin-top: var(--sp-2); }
.pwa-guide summary { cursor: pointer; font-weight: 600; display: flex; align-items: center; gap: var(--sp-2); }
.pwa-guide summary i { color: var(--c-primary); }
.pwa-guide ol { margin: var(--sp-3) 0 var(--sp-2); padding-left: 1.4rem; display: grid; gap: .4rem; font-size: var(--fs-sm); }
.pwa-banner .pwa-help { text-decoration: none; }

/* ---- Infolettre : barre de progression d'envoi et aperçu du message ---- */
.progress { height: 10px; border-radius: 999px; background: var(--c-surface-2); overflow: hidden; }
.progress-bar { height: 100%; width: 0; border-radius: 999px; background: var(--c-primary); transition: width .3s ease; }

.card-header .card-actions { display: flex; gap: .25rem; margin-left: auto; }

.mail-preview-meta { display: grid; gap: .2rem; padding: var(--sp-3); margin-bottom: var(--sp-3); background: var(--c-surface-2); border-radius: var(--radius-sm); font-size: var(--fs-sm); }
.mail-preview { background: #f4f5f8; border: 1px solid var(--c-border); border-radius: var(--radius); padding: var(--sp-2); }
.mail-preview iframe { display: block; width: 100%; max-width: 100%; height: 620px; margin-inline: auto; border: 0; border-radius: calc(var(--radius) - 2px); background: #f4f5f8; transition: max-width .2s; }

/* --- Tiroir latéral ---------------------------------------------------------
   Panneau qui glisse depuis la droite, pour un contenu secondaire qu'on consulte
   sans quitter la page : historique d'un document, aperçu, aide. Même composant
   que le tiroir du panier du webshop, pour que les deux interfaces se ressemblent. */
.side-drawer { position: fixed; z-index: 1060; top: 0; right: 0; bottom: 0; display: flex; flex-direction: column; width: min(420px, 92vw); background: var(--c-surface); border-left: 1px solid var(--c-border); box-shadow: -12px 0 40px rgba(15, 19, 32, .14); transform: translateX(100%); transition: transform .25s ease; }
.side-drawer.open { transform: none; }
.side-drawer[hidden] { display: none; }
.side-drawer-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); padding: var(--sp-4); border-bottom: 1px solid var(--c-border); }
.side-drawer-head h2 { margin: 0; font-size: var(--fs-md); }
.side-drawer-body { flex: 1; overflow-y: auto; padding: var(--sp-4); }
.side-drawer-overlay { position: fixed; z-index: 1059; inset: 0; background: rgba(15, 19, 32, .35); }
.side-drawer-overlay[hidden] { display: none; }
body.side-drawer-open { overflow: hidden; }

/* --- Journal d'actions ------------------------------------------------------
   Liste verticale reliée par un filet : chaque entrée dit quoi, qui, quand. */
.timeline { display: grid; gap: var(--sp-4); margin: 0; padding: 0; list-style: none; }
.timeline li { position: relative; display: grid; grid-template-columns: 1.7rem 1fr; gap: var(--sp-2); font-size: var(--fs-sm); }
.timeline li > i { display: grid; place-items: center; width: 1.7rem; height: 1.7rem; border-radius: 999px; background: var(--c-primary-soft); color: var(--c-primary); font-size: .8rem; }
.timeline li:not(:last-child)::before { content: ""; position: absolute; left: .82rem; top: 1.9rem; bottom: calc(-1 * var(--sp-4)); width: 1px; background: var(--c-border); }
.timeline li > div { display: grid; gap: .1rem; }
.timeline-who { color: var(--c-text); }
.timeline-when, .timeline-ip { font-size: var(--fs-xs); color: var(--c-text-muted); }
.timeline-detail { color: var(--c-text-muted); overflow-wrap: anywhere; }

/* --- Zone de livraison (Système › Pages légales) -----------------------------
   Quarante-six pays : en colonnes serrées dans un cadre qui défile, on les
   embrasse d'un coup d'œil — une liste déroulante obligerait à chercher. */
.ship-zone { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: .15rem var(--sp-4); max-height: 15rem; margin-top: var(--sp-2); padding: var(--sp-3); overflow-y: auto; border: 1px solid var(--c-border); border-radius: var(--radius-sm); background: var(--c-surface-2); }
.ship-zone .checkbox { margin: 0; font-size: var(--fs-sm); }

/* --- Écran de vente ----------------------------------------------------------
   Le ticket à gauche, le client et le paiement à droite : on compose en regardant
   le total monter, sans faire défiler la page à chaque article. */
.sale-layout { display: grid; grid-template-columns: minmax(0, 1fr) 22rem; gap: var(--sp-4); align-items: start; }
.sale-layout > aside { position: sticky; top: var(--sp-4); display: grid; gap: var(--sp-4); }
/* `minmax(0, 1fr)` plutôt que `1fr` : une colonne de grille prend par défaut la largeur
   **minimale de son contenu**, donc un tableau large déborde de l'écran au lieu de le
   faire défiler — l'`overflow-x` du tableau ne se déclenche jamais, et la moitié droite
   du ticket, corbeille comprise, devient inatteignable sur téléphone. */
@media (max-width: 1100px) { .sale-layout { grid-template-columns: minmax(0, 1fr); } .sale-layout > aside { position: static; } }
.sale-ticket .cell-in { width: 5.5rem; text-align: right; }
.sale-ticket .cell-in-sm { width: 4rem; }
.sale-customer { display: grid; gap: .15rem; margin: 0 0 var(--sp-3); }
.sale-totals .totals { display: grid; gap: .35rem; margin: 0; }
.sale-totals .totals > div { display: flex; justify-content: space-between; gap: var(--sp-3); }
.sale-totals .totals dt, .sale-totals .totals dd { margin: 0; }
.sale-totals .totals dd { font-variant-numeric: tabular-nums; }
.sale-totals .totals-strong { padding-top: .35rem; border-top: 1px solid var(--c-border); font-weight: 600; }
.suggest-list { display: grid; gap: 2px; margin-top: .25rem; border: 1px solid var(--c-border); border-radius: var(--radius-sm); overflow: hidden; }
.suggest-item { display: grid; gap: .1rem; padding: var(--sp-2) var(--sp-3); border: 0; background: var(--c-surface); text-align: left; cursor: pointer; }
.suggest-item:hover { background: var(--c-surface-2); }
.suggest-item span { font-size: var(--fs-xs); color: var(--c-text-muted); }
/* Une déclinaison en rupture reste cochable — on vend parfois sur commande — mais elle
   ne doit pas se confondre avec ce qui est en rayon. */
.po-variant.is-out { opacity: .55; }
/* Sauf le libellé de l'article, rien ne se coupe dans le ticket : un « 79,95 € » suivi de
   « TVA 21 % » sur deux lignes se lit comme deux montants. */
.sale-ticket td:not(:first-child) { white-space: nowrap; }

/* Sous 900 px, le ticket cesse d'être un tableau : chaque ligne devient une fiche.
   Faire défiler huit colonnes latéralement pour atteindre une corbeille est un geste
   qu'on ne devrait pas demander — et au comptoir, il se fait d'une seule main. La bascule
   est à 900 px et non à 720 : à 768 px (tablette en portrait) les huit colonnes tiennent
   encore, mais tout juste, et la corbeille passait sous le bord. */
@media (max-width: 900px) {
  .sale-ticket, .sale-ticket tbody, .sale-ticket tr, .sale-ticket td { display: block; width: auto; }
  .sale-ticket thead { display: none; }
  .sale-ticket tr {
    position: relative; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: .4rem var(--sp-3); padding: var(--sp-3) 0; border-bottom: 1px solid var(--c-border);
  }
  .sale-ticket td { padding: 0; border: 0; text-align: left; white-space: normal; }
  /* Le nom de l'article et sa référence tiennent toute la largeur ; le reste se range en
     trois colonnes : quantité, prix, remise — puis total et marge. */
  .sale-ticket td:first-child, .sale-ticket td:nth-child(2), .sale-ticket td.empty { grid-column: 1 / -1; }
  .sale-ticket td:first-child { padding-right: 2.75rem; }
  /* L'intitulé de la colonne revient devant la valeur : sans en-tête de tableau, « 0 »
     seul ne veut plus rien dire. */
  .sale-ticket td[data-label]::before {
    content: attr(data-label); display: block; margin-bottom: .1rem;
    font-size: var(--fs-xs); color: var(--c-text-muted);
  }
  .sale-ticket .cell-in, .sale-ticket .cell-in-sm { width: 100%; }
  .sale-ticket .cell-del { position: absolute; top: var(--sp-3); right: 0; }
  .sale-ticket .cell-del::before { content: none; }
}

/* --- Bons et cartes d'un client ----------------------------------------------
   Une pastille verte à côté du nom, et un bandeau qui la met en phrase. Un bon
   cadeau découvert au bas de la fiche, dans une section repliée, l'est trop tard :
   la vente est encaissée. */
.badge-lg { padding: .25em .7em; font-size: var(--fs-sm); vertical-align: middle; }
a.badge { text-decoration: none; }
a.badge:hover { filter: brightness(.95); }
.wallet-strip { display: flex; align-items: baseline; gap: var(--sp-3); flex-wrap: wrap; }
.wallet-strip > span { display: flex; gap: var(--sp-3); flex-wrap: wrap; align-items: baseline; }
.wallet-strip .btn-link { margin-left: auto; }

/* --- Commandes du webshop -----------------------------------------------------
   Expédier demande deux informations (transporteur, numéro) : le formulaire s'ouvre
   dans la ligne plutôt que d'envoyer sur une autre page — on traite dix colis à la
   suite sans jamais quitter la liste. */
.wo-actions { display: flex; gap: var(--sp-2); justify-content: flex-end; align-items: flex-start; flex-wrap: wrap; }
.wo-ship { position: relative; }
.wo-ship > summary { list-style: none; cursor: pointer; }
.wo-ship > summary::-webkit-details-marker { display: none; }
.wo-ship-form { position: absolute; right: 0; z-index: 20; display: grid; gap: var(--sp-2); width: 17rem; margin-top: var(--sp-2); padding: var(--sp-3); background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius-sm); box-shadow: var(--shadow); text-align: left; }
.wo-ship-form label { display: grid; gap: .15rem; font-size: var(--fs-xs); color: var(--c-text-muted); }
.wo-ship-form input, .wo-ship-form select { width: 100%; }
@media (max-width: 900px) { .wo-ship-form { position: static; width: auto; } }

/* Case à cocher dans une barre de filtres : alignée sur le bas des champs voisins, et non
   sur leur étiquette — sinon elle flotte au-dessus de la ligne des contrôles. */
.field-check { justify-content: flex-end; }
.field-check label { display: inline-flex; align-items: center; gap: var(--sp-2); min-height: var(--control-h); font-weight: 500; cursor: pointer; }
.field-check input { width: 18px; height: 18px; }

/* ------------------------------------------------------------------ caisse (management) */

/* `start` et non l'étirement par défaut : sinon la carte du lien, plus courte, se dilate
   à la hauteur de la marche à suivre et laisse un grand vide au-dessus du QR. */
.cash-app-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr)); gap: var(--sp-4); margin-bottom: var(--sp-4); align-items: start; }
.cash-app-link { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-4); align-items: center; }
.cash-app-url { margin: var(--sp-3) 0 var(--sp-1); }
.cash-app-url code { font-size: var(--fs-md); }
.cash-qr { line-height: 0; padding: var(--sp-2); background: #fff; border-radius: var(--radius-sm); border: 1px solid var(--c-border); }
.cash-howto { margin-bottom: var(--sp-4); }
.cash-howto h3 { display: flex; align-items: center; gap: var(--sp-2); margin: 0 0 var(--sp-2); font-size: var(--fs-md); }
.cash-howto ol { margin: 0; padding-left: 1.25rem; display: grid; gap: var(--sp-1); }
.cash-howto-foot { margin: 0; }
.cash-sellers { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--sp-1); }

.cash-now { display: grid; grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr)); gap: var(--sp-4); margin-bottom: var(--sp-4); }
.cash-now-card h3 { margin: 0 0 var(--sp-2); font-size: var(--fs-md); }
/* Un liseré sur la tranche plutôt qu'un fond teinté : sur une rangée de boutiques, c'est
   ce qui se repère le plus vite sans colorer toute la carte. */
.cash-now-card.is-open { border-left: 3px solid var(--c-success); }
.cash-now-state { margin: 0 0 var(--sp-2); display: flex; align-items: center; gap: var(--sp-2); }
.cash-now-figure { margin: 0 0 var(--sp-1); font-size: var(--fs-2xl); font-weight: 700; letter-spacing: -.02em; }

@media (max-width: 700px) {
  .cash-app-link { grid-template-columns: minmax(0, 1fr); justify-items: center; text-align: center; }
}
