/* ============================================================================
   Lavanty.mg — UI Foundation (normalisation UX)
   Fichier additif : chargé EN PLUS de lavanty.css / lavanty-app.css / common.css.
   Namespace strict : tokens --lv-*, classes .lv-*, global JS window.LvUI.

   Les valeurs sont ANCRÉES sur l'existant (lavanty.css, lavanty-app.css,
   common.css) pour ne PAS introduire de palette qui jure ni casser le visuel.
   Aucun override agressif des sélecteurs globaux (body, a, table, .btn…).
   ========================================================================== */

/* ----------------------------------------------------------------------------
   1. TOKENS  (:root, préfixe --lv-*)
   -------------------------------------------------------------------------- */
:root {
  /* Marque (= --color-brand-blue / --accent existants) */
  --lv-brand:        #004a99;
  --lv-brand-dark:   #003d80;
  --lv-brand-soft:   #dbeafe;

  /* Statuts fonctionnels (alignés lavanty-app.css / common.css) */
  --lv-success:      #16a34a;
  --lv-success-soft: #dcfce7;
  --lv-success-text: #166534;
  --lv-danger:       #dc2626;
  --lv-danger-soft:  #fee2e2;
  --lv-danger-text:  #991b1b;
  --lv-warning:      #f59e0b;
  --lv-warning-soft: #fef3c7;
  --lv-warning-text: #92400e;
  --lv-info:         #2563eb;
  --lv-info-soft:    #dbeafe;
  --lv-info-text:    #1e40af;

  /* Surfaces & texte (= --app-* / --card-*) */
  --lv-surface:      #ffffff;
  --lv-bg:           #f8f9fa;
  --lv-border:       #e5e7eb;
  --lv-border-soft:  #f3f4f6;
  --lv-text:         #0f172a;
  --lv-muted:        #6b7280;

  /* Espacements (échelle 4px) */
  --lv-space-1: 0.25rem;   /*  4px */
  --lv-space-2: 0.5rem;    /*  8px */
  --lv-space-3: 0.75rem;   /* 12px */
  --lv-space-4: 1rem;      /* 16px */
  --lv-space-5: 1.5rem;    /* 24px */
  --lv-space-6: 2rem;      /* 32px */

  /* Rayon, ombre, typo (= existant : 0.5rem boutons, ombres cartes) */
  --lv-radius:    0.5rem;
  --lv-radius-sm: 0.375rem;
  --lv-radius-lg: 0.75rem;
  --lv-radius-pill: 999px;
  --lv-shadow:    0 1px 3px rgba(0, 0, 0, 0.08);
  --lv-shadow-md: 0 10px 25px rgba(0, 0, 0, 0.15);
  --lv-shadow-lg: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
  --lv-font:      'Inter', system-ui, -apple-system, sans-serif;

  /* Couches z (toasts au-dessus des modales) */
  --lv-z-modal: 1000;
  --lv-z-toast: 1100;
}

/* ----------------------------------------------------------------------------
   2. BOUTONS  .lv-btn (+ --primary/--danger/--ghost/--sm)
   -------------------------------------------------------------------------- */
.lv-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--lv-space-2);
  padding: 0.6rem 1.25rem;
  border-radius: var(--lv-radius);
  font-family: var(--lv-font);
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.2;
  color: var(--lv-text);
  background: var(--lv-surface);
  border: 1.5px solid var(--lv-border);
  cursor: pointer;
  text-decoration: none;
  transition: transform 0.15s ease, background-color 0.2s ease,
              box-shadow 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.lv-btn:hover { background: var(--lv-border-soft); }
.lv-btn:focus-visible {
  outline: 2px solid var(--lv-brand);
  outline-offset: 2px;
}
.lv-btn:disabled,
.lv-btn[aria-disabled="true"],
.lv-btn.is-loading {
  opacity: 0.6;
  cursor: not-allowed;
  pointer-events: none;
}

.lv-btn--primary {
  background: var(--lv-brand);
  border-color: var(--lv-brand);
  color: #fff;
}
.lv-btn--primary:hover {
  background: var(--lv-brand-dark);
  border-color: var(--lv-brand-dark);
  transform: translateY(-1px);
  box-shadow: 0 6px 14px rgba(0, 74, 153, 0.25);
}

.lv-btn--danger {
  background: var(--lv-danger);
  border-color: var(--lv-danger);
  color: #fff;
}
.lv-btn--danger:hover {
  background: #b91c1c;
  border-color: #b91c1c;
  transform: translateY(-1px);
  box-shadow: 0 6px 14px rgba(220, 38, 38, 0.25);
}

.lv-btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--lv-text);
}
.lv-btn--ghost:hover { background: var(--lv-border-soft); }

.lv-btn--sm {
  padding: 0.35rem 0.75rem;
  font-size: 0.825rem;
  border-radius: var(--lv-radius-sm);
}

/* ----------------------------------------------------------------------------
   Bouton-ICÔNE — CONVENTION colonnes Actions (décision produit EP-19) :
   toute action de ligne = icône seule + tooltip au survol (title/aria-label,
   posés par le partial action-button quand iconOnly=true). Rendu fantôme
   uniforme : la VARIANTE ne colore que l'icône (fini les pavés pleins rouges) ;
   le contexte chiffré vit dans la modale de confirmation, pas dans le bouton.
   -------------------------------------------------------------------------- */
.lv-btn--icon {
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  justify-content: center;
  background: transparent;
  border-color: transparent;
  color: var(--lv-muted);
}
.lv-btn--icon .lv-btn__icon { width: 1.05rem; height: 1.05rem; }
.lv-btn--icon:hover { background: var(--lv-border-soft); color: var(--lv-text); }
.lv-btn--icon.lv-btn--primary { background: transparent; border-color: transparent; color: var(--lv-brand); box-shadow: none; }
.lv-btn--icon.lv-btn--primary:hover { background: var(--lv-brand-soft); transform: none; box-shadow: none; }
.lv-btn--icon.lv-btn--danger { background: transparent; border-color: transparent; color: var(--lv-danger); box-shadow: none; }
.lv-btn--icon.lv-btn--danger:hover { background: var(--lv-danger-soft); transform: none; box-shadow: none; }
.lv-btn--icon.lv-btn--success { background: transparent; border-color: transparent; color: var(--lv-success); }
.lv-btn--icon.lv-btn--success:hover { background: var(--lv-success-soft); }

.lv-btn .lv-spinner { width: 1em; height: 1em; }

/* ----------------------------------------------------------------------------
   3. PILLS DE STATUT  .lv-pill (+ --success/--danger/--warning/--info/--muted)
   -------------------------------------------------------------------------- */
.lv-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--lv-space-1);
  padding: 0.2rem 0.6rem;
  border-radius: var(--lv-radius-pill);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
  background: var(--lv-border-soft);
  color: #374151;
}
.lv-pill::before {
  content: "";
  width: 0.45em;
  height: 0.45em;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.85;
  flex-shrink: 0;
}
.lv-pill--success { background: var(--lv-success-soft); color: var(--lv-success-text); }
.lv-pill--danger  { background: var(--lv-danger-soft);  color: var(--lv-danger-text); }
.lv-pill--warning { background: var(--lv-warning-soft); color: var(--lv-warning-text); }
.lv-pill--info    { background: var(--lv-info-soft);    color: var(--lv-info-text); }
.lv-pill--muted   { background: var(--lv-border-soft);  color: var(--lv-muted); }

/* ----------------------------------------------------------------------------
   4. TOASTS  .lv-toast + .lv-toast-stack  (pilotés par LvUI.toast)
   -------------------------------------------------------------------------- */
.lv-toast-stack {
  position: fixed;
  top: 5rem;
  right: 1rem;
  z-index: var(--lv-z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--lv-space-2);
  pointer-events: none;
  max-width: min(360px, calc(100vw - 2rem));
}
.lv-toast {
  display: flex;
  align-items: flex-start;
  gap: var(--lv-space-3);
  padding: 0.85rem 1.1rem;
  background: var(--lv-surface);
  color: var(--lv-text);
  border-radius: var(--lv-radius-lg);
  border-left: 4px solid var(--lv-brand);
  box-shadow: var(--lv-shadow-md);
  pointer-events: auto;
  animation: lv-toast-in 0.3s ease both;
}
.lv-toast.is-leaving { animation: lv-toast-out 0.25s ease both; }
.lv-toast__icon { flex-shrink: 0; line-height: 1; margin-top: 1px; }
.lv-toast__body,
.lv-toast__msg { flex: 1; font-size: 0.9rem; line-height: 1.4; }
.lv-toast__close {
  flex-shrink: 0;
  background: none;
  border: none;
  color: var(--lv-muted);
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
  padding: 0;
}
.lv-toast__close:hover { color: var(--lv-text); }
.lv-toast--success { border-left-color: var(--lv-success); }
.lv-toast--error   { border-left-color: var(--lv-danger); }
.lv-toast--warning { border-left-color: var(--lv-warning); }
.lv-toast--info    { border-left-color: var(--lv-info); }
.lv-toast--success .lv-toast__icon { color: var(--lv-success); }
.lv-toast--error   .lv-toast__icon { color: var(--lv-danger); }
.lv-toast--warning .lv-toast__icon { color: var(--lv-warning); }
.lv-toast--info    .lv-toast__icon { color: var(--lv-info); }

@keyframes lv-toast-in {
  from { opacity: 0; transform: translateY(-20px) scale(0.95); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes lv-toast-out {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(-12px); }
}

/* ----------------------------------------------------------------------------
   5. MODALE  .lv-modal + .lv-modal__backdrop  (pilotée par LvUI.confirm)
   -------------------------------------------------------------------------- */
.lv-modal {
  position: fixed;
  inset: 0;
  z-index: var(--lv-z-modal);
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--lv-space-4);
}
.lv-modal.is-open { display: flex; }
.lv-modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  animation: lv-fade-in 0.2s ease both;
}
.lv-modal__dialog,
.lv-modal__panel {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 460px;
  max-height: 90vh;
  overflow-y: auto;
  background: var(--lv-surface);
  border-radius: var(--lv-radius-lg);
  box-shadow: var(--lv-shadow-lg);
  animation: lv-slide-up 0.25s ease both;
}
.lv-modal__header {
  padding: var(--lv-space-5) var(--lv-space-5) var(--lv-space-2);
}
.lv-modal__title {
  margin: 0;
  font-family: var(--lv-font);
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--lv-text);
}
/* Le partial canonique met le titre en enfant direct du panel (sans __header) :
   on lui rend le padding qu'aurait porté .lv-modal__header. */
.lv-modal__panel > .lv-modal__title {
  padding: var(--lv-space-5) var(--lv-space-5) var(--lv-space-2);
}
.lv-modal__body {
  padding: 0 var(--lv-space-5) var(--lv-space-4);
  color: var(--lv-muted);
  font-size: 0.925rem;
  line-height: 1.55;
}
.lv-modal__footer,
.lv-modal__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--lv-space-2);
  padding: var(--lv-space-3) var(--lv-space-5) var(--lv-space-5);
}
.lv-modal--danger .lv-modal__title { color: var(--lv-danger); }

@keyframes lv-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes lv-slide-up {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ----------------------------------------------------------------------------
   6. ÉTAT VIDE  .lv-empty  (jamais de cul-de-sac : CTA recommandé)
   -------------------------------------------------------------------------- */
.lv-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--lv-space-3);
  padding: var(--lv-space-6) var(--lv-space-4);
  color: var(--lv-muted);
}
.lv-empty__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--lv-border-soft);
  color: var(--lv-muted);
}
.lv-empty__title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--lv-text);
}
.lv-empty__message { margin: 0; max-width: 38ch; font-size: 0.9rem; line-height: 1.5; }

/* ----------------------------------------------------------------------------
   7. MONTANT  .lv-money  (formaté par LvUI.money)
   -------------------------------------------------------------------------- */
.lv-money {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
  color: var(--lv-text);
}
.lv-money__currency {
  font-weight: 500;
  color: var(--lv-muted);
  margin-left: 0.15em;
}

/* ----------------------------------------------------------------------------
   8. COUNTDOWN  .lv-countdown (+ .is-urgent / .is-ended)  (LvUI.initCountdowns)
   -------------------------------------------------------------------------- */
.lv-countdown {
  display: inline-flex;
  align-items: baseline;
  gap: var(--lv-space-1);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--lv-text);
  white-space: nowrap;            /* jamais « 06h / 40m / 08s » sur 3 lignes */
  transition: color 0.2s ease;
}
.lv-countdown__seg { display: inline-flex; align-items: baseline; }
.lv-countdown__val { font-weight: 700; }
.lv-countdown__lbl {
  font-size: 0.75em;
  font-weight: 500;
  color: var(--lv-muted);
  margin-left: 0.1em;
}
/* Variante --blocks rendue par LvUI.initCountdowns (block/num/unit). */
.lv-countdown__block { display: inline-flex; align-items: baseline; }
.lv-countdown__num { font-weight: 700; }
.lv-countdown__unit {
  font-size: 0.75em;
  font-weight: 500;
  color: var(--lv-muted);
  margin-left: 0.1em;
}
.lv-countdown.is-urgent .lv-countdown__unit { color: var(--lv-danger); opacity: 0.75; }
.lv-countdown.is-urgent {
  color: var(--lv-danger);
  animation: lv-pulse 1.4s ease-in-out infinite;
}
.lv-countdown.is-urgent .lv-countdown__lbl { color: var(--lv-danger); opacity: 0.75; }
.lv-countdown.is-ended {
  color: var(--lv-muted);
  font-weight: 500;
}

@keyframes lv-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}

/* ----------------------------------------------------------------------------
   9. TOOLBAR  .lv-toolbar
   -------------------------------------------------------------------------- */
.lv-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--lv-space-2) var(--lv-space-3);
  padding: var(--lv-space-3) var(--lv-space-4);
  background: var(--lv-surface);
  border: 1px solid var(--lv-border);
  border-radius: var(--lv-radius-lg);
}
/* Barre de FILTRES de liste : le flex de .lv-toolbar rétrécissait le <form> à
   son contenu → la grille auto-fit ne s'étirait que sur cette largeur (« vide »
   à droite sur toutes les recherches). En mode liste, le conteneur redevient
   bloc et le form occupe 100 % — la norme 07 (remplir toute la largeur) tient. */
.lv-toolbar.list-toolbar { display: block; }
.list-toolbar .list-filters { width: 100%; }
.lv-toolbar__title {
  font-weight: 700;
  color: var(--lv-text);
  margin-right: auto;
}
.lv-toolbar__spacer { margin-left: auto; }
.lv-toolbar__group { display: inline-flex; align-items: center; gap: var(--lv-space-2); }

/* ----------------------------------------------------------------------------
   10. TABLE  .lv-table
   -------------------------------------------------------------------------- */
.lv-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--lv-surface);
  border-radius: var(--lv-radius-lg);
  overflow: hidden;
  box-shadow: var(--lv-shadow);
  font-size: 0.92rem;
}
.lv-table th {
  padding: 0.85rem 1rem;
  text-align: left;
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--lv-muted);
  background: #f9fafb;
  border-bottom: 1px solid var(--lv-border);
}
.lv-table td {
  padding: 0.85rem 1rem;
  border-bottom: 1px solid var(--lv-border-soft);
  color: var(--lv-text);
}
.lv-table tr:last-child td { border-bottom: none; }
.lv-table tbody tr:hover td { background: #f9fafb; }

/* Défilement horizontal mobile (évite le débordement). */
@media (max-width: 768px) {
  .lv-table {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
    -webkit-overflow-scrolling: touch;
  }
}

/* ----------------------------------------------------------------------------
   11. SKELETON  .lv-skeleton  (placeholder de chargement)
   -------------------------------------------------------------------------- */
.lv-skeleton {
  display: block;
  width: 100%;
  height: 1em;
  border-radius: var(--lv-radius-sm);
  background: linear-gradient(90deg, #eef1f4 25%, #e2e6ea 37%, #eef1f4 63%);
  background-size: 400% 100%;
  animation: lv-shimmer 1.4s ease infinite;
}
.lv-skeleton--text { height: 0.8em; margin: 0.35em 0; }
.lv-skeleton--title { height: 1.4em; width: 45%; }
.lv-skeleton--block { height: 3rem; }
.lv-skeleton--circle { width: 2.5rem; height: 2.5rem; border-radius: 50%; }

@keyframes lv-shimmer {
  0%   { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}

/* ----------------------------------------------------------------------------
   12. SPINNER  .lv-spinner  (état de chargement inline)
   -------------------------------------------------------------------------- */
.lv-spinner {
  display: inline-block;
  width: 1.1em;
  height: 1.1em;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  vertical-align: -0.15em;
  animation: lv-spin 0.7s linear infinite;
}
.lv-spinner--lg { width: 2rem; height: 2rem; border-width: 3px; }

@keyframes lv-spin { to { transform: rotate(360deg); } }

/* ----------------------------------------------------------------------------
   13. RÉSUMÉ D'ERREURS  .lv-form-errors  (ancré au-dessus du formulaire)
   -------------------------------------------------------------------------- */
.lv-form-errors {
  border: 1px solid var(--lv-danger-soft);
  border-left: 4px solid var(--lv-danger);
  background: #fef2f2;
  border-radius: var(--lv-radius);
  padding: var(--lv-space-3) var(--lv-space-4);
  margin-bottom: var(--lv-space-4);
  color: var(--lv-danger-text);
}
.lv-form-errors__title {
  margin: 0 0 var(--lv-space-2);
  font-weight: 700;
  font-size: 0.925rem;
}
.lv-form-errors__list {
  margin: 0;
  padding-left: 1.25rem;
  font-size: 0.875rem;
  line-height: 1.5;
}

/* ----------------------------------------------------------------------------
   14. ACCESSIBILITÉ & MOUVEMENT RÉDUIT
   -------------------------------------------------------------------------- */
.lv-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;
}

/* ----------------------------------------------------------------------------
   9. TIMELINE  .lv-timeline  (frise qui/quand/pourquoi des fiches d'arbitrage)
   -------------------------------------------------------------------------- */
.lv-timeline__list { list-style: none; margin: 0; padding: 0; }
.lv-timeline__item {
  position: relative;
  display: flex;
  gap: var(--lv-space-3);
  padding: 0 0 var(--lv-space-4) var(--lv-space-4);
  border-left: 2px solid var(--lv-border);
  margin-left: 5px;
}
.lv-timeline__item:last-child { padding-bottom: 0; border-left-color: transparent; }
.lv-timeline__dot {
  position: absolute;
  left: -7px;
  top: 2px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--lv-muted);
  box-shadow: 0 0 0 3px var(--lv-bg);
}
.lv-timeline__dot--success { background: var(--lv-success); }
.lv-timeline__dot--danger  { background: var(--lv-danger); }
.lv-timeline__dot--warning { background: var(--lv-warning); }
.lv-timeline__dot--info    { background: var(--lv-info); }
.lv-timeline__dot--muted   { background: var(--lv-muted); }
.lv-timeline__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--lv-space-2);
}
.lv-timeline__label { font-weight: 600; color: var(--lv-text); }
.lv-timeline__date  { font-size: 0.8rem; color: var(--lv-muted); }
.lv-timeline__meta  { font-size: 0.85rem; color: var(--lv-muted); margin-top: 1px; }
.lv-timeline__motif {
  margin: var(--lv-space-1) 0 0;
  padding: var(--lv-space-2) var(--lv-space-3);
  background: var(--lv-surface);
  border-radius: var(--lv-radius);
  font-style: italic;
  font-size: 0.9rem;
  color: var(--lv-text);
}

/* ----------------------------------------------------------------------------
   10. TABLEAUX — disposition normalisée (alignement par type de donnée)
   --------------------------------------------------------------------------
   Règle : texte -> gauche ; nombres/montants/quantités/dates -> DROITE (chiffres
   tabulaires, comparaison visuelle des ordres de grandeur) ; actions -> droite.
   L'en-tête s'aligne comme sa colonne. À poser sur le <th> ET le <td>. */
.lv-num,
th.lv-num,
td.lv-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* En-tête triable numérique : pousse le libellé + chevron à droite. */
.lv-num .list-sort-link { justify-content: flex-end; }
.lv-col-actions,
th.lv-col-actions,
td.lv-col-actions {
  text-align: right;
  white-space: nowrap;
}
.lv-col-center,
th.lv-col-center,
td.lv-col-center { text-align: center; }
/* Texte secondaire d'une cellule (email sous le nom, référence...). */
.lv-cell-sub { font-size: 0.8rem; color: var(--lv-muted); line-height: 1.2; }
/* Texte long tronqué proprement (title = tooltip) plutôt que wrap incontrôlé. */
.lv-truncate {
  max-width: 22ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Le .sr-only (position absolue) d'une colonne « Actions » dans un tableau défilant n'est pas rogné par le conteneur (son bloc englobant est
   extérieur) : il élargissait toute la page (1086 px pour un écran de 390 px) et faisait dézoomer le navigateur mobile. Fixé, il sort du calcul.
   Volontairement limité à .sr-only : changer le repère de TOUS les descendants rognerait les popovers placés dans les cellules. */
.data-table .sr-only, .overflow-x-auto .sr-only { position: fixed; }

/* ----------------------------------------------------------------------------
   15. CHAMPS  .lv-field — états normalisés NT-13
   (repos / focus / erreur / désactivé+explication / chargement / aide)
   Complète .form-input (lavanty.css) sans le remplacer.
   -------------------------------------------------------------------------- */
.lv-field { display: block; }
.lv-field + .lv-field { margin-top: var(--lv-space-4); }
/* Formulaire pleine largeur : les champs se répartissent en colonnes de 18 rem minimum (1 colonne sur mobile,
   2 dans un grand panneau) au lieu d'une colonne étroite à gauche. Pas de space-y-* sur la même balise. */
.lv-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr));
  gap: var(--lv-space-4) 1.5rem;
  align-items: start;
}
.lv-form-grid > .lv-field + .lv-field { margin-top: 0; }
.lv-form-grid > .lv-form-full,
.lv-form-grid > :is(p, h2, h3, h4, hr, ul, dl, [role="note"], [role="alert"]),
.lv-form-grid > button[type="submit"] { grid-column: 1 / -1; }
/* Règle à part : un navigateur sans :has() ignorerait TOUTE la règle qui le contient. */
.lv-form-grid > :has(> button[type="submit"]) { grid-column: 1 / -1; }
.lv-field__label {
  display: block;
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--lv-text);
  margin-bottom: var(--lv-space-1);
}
.lv-field__label .lv-field__req { color: var(--lv-danger); margin-left: 0.15em; }
.lv-field__help {
  margin: var(--lv-space-1) 0 0;
  font-size: 0.8rem;
  color: var(--lv-muted);
  line-height: 1.4;
}
.lv-field__error {
  margin: var(--lv-space-1) 0 0;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--lv-danger-text);
  line-height: 1.4;
}
.lv-field__money-preview {
  margin: var(--lv-space-1) 0 0;
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--lv-muted);
}
/* Input générique du DS (utilisable seul ou en plus de .form-input). */
.lv-input {
  display: block;
  width: 100%;
  padding: 0.6rem 0.85rem;
  font-family: var(--lv-font);
  font-size: 0.95rem;
  color: var(--lv-text);
  background: var(--lv-surface);
  border: 1.5px solid var(--lv-border);
  border-radius: var(--lv-radius);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.lv-input:focus-visible {
  outline: none;
  border-color: var(--lv-brand);
  box-shadow: 0 0 0 3px rgba(0, 74, 153, 0.15);
}
.lv-input.is-invalid,
.form-input.is-invalid,
[aria-invalid="true"].lv-input,
[aria-invalid="true"].form-input {
  border-color: var(--lv-danger);
  box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.12);
}
.lv-input:disabled,
.lv-input[readonly][data-locked],
.form-input:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  background: var(--lv-border-soft);
}

/* ----------------------------------------------------------------------------
   16. COMBOBOX  .lv-combobox  (ELM-AUTOCOMPLETE, piloté par LvUI)
   -------------------------------------------------------------------------- */
.lv-combobox { position: relative; }
.lv-combobox__list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 50;
  max-height: 280px;
  overflow-y: auto;
  margin: 0;
  padding: var(--lv-space-1);
  list-style: none;
  background: var(--lv-surface);
  border: 1px solid var(--lv-border);
  border-radius: var(--lv-radius);
  box-shadow: var(--lv-shadow-md);
}
.lv-combobox__option {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 0.5rem 0.7rem;
  border-radius: var(--lv-radius-sm);
  cursor: pointer;
}
.lv-combobox__option:hover,
.lv-combobox__option.is-active { background: var(--lv-brand-soft); }
.lv-combobox__label { font-weight: 600; font-size: 0.9rem; color: var(--lv-text); }
.lv-combobox__sub { font-size: 0.78rem; color: var(--lv-muted); }
.lv-combobox__empty {
  padding: 0.6rem 0.7rem;
  font-size: 0.85rem;
  color: var(--lv-muted);
}

/* ----------------------------------------------------------------------------
   17. CHIPS DE MOTIF  .lv-chips  (ELM-MOTIF)
   -------------------------------------------------------------------------- */
.lv-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--lv-space-2);
  margin-bottom: var(--lv-space-2);
}
.lv-chip {
  display: inline-flex;
  align-items: center;
  padding: 0.3rem 0.75rem;
  border-radius: var(--lv-radius-pill);
  border: 1.5px solid var(--lv-border);
  background: var(--lv-surface);
  font-size: 0.825rem;
  font-weight: 600;
  color: var(--lv-text);
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}
.lv-chip:hover { background: var(--lv-border-soft); }
.lv-chip:focus-visible { outline: 2px solid var(--lv-brand); outline-offset: 2px; }
.lv-chip.is-selected {
  background: var(--lv-brand-soft);
  border-color: var(--lv-brand);
  color: var(--lv-brand);
}

/* ----------------------------------------------------------------------------
   18. JAUGE DE FORCE  .lv-meter  (ELM-PASSWORD)
   -------------------------------------------------------------------------- */
.lv-meter {
  display: flex;
  align-items: center;
  gap: var(--lv-space-1);
  margin-top: var(--lv-space-1);
}
.lv-meter__bar {
  height: 4px;
  flex: 1;
  max-width: 48px;
  border-radius: 2px;
  background: var(--lv-border);
  transition: background-color 0.2s ease;
}
.lv-meter__label {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--lv-muted);
  margin-left: var(--lv-space-1);
}
.lv-meter--1 .lv-meter__bar:nth-child(-n+1) { background: var(--lv-danger); }
.lv-meter--2 .lv-meter__bar:nth-child(-n+2) { background: var(--lv-warning); }
.lv-meter--3 .lv-meter__bar:nth-child(-n+3) { background: var(--lv-info); }
.lv-meter--4 .lv-meter__bar:nth-child(-n+4) { background: var(--lv-success); }
.lv-meter--1 .lv-meter__label { color: var(--lv-danger-text); }
.lv-meter--2 .lv-meter__label { color: var(--lv-warning-text); }
.lv-meter--3 .lv-meter__label { color: var(--lv-info-text); }
.lv-meter--4 .lv-meter__label { color: var(--lv-success-text); }

/* ----------------------------------------------------------------------------
   19. DROPZONE  .lv-dropzone  (ELM-FILE / ELM-IMAGE-GALLERY)
   -------------------------------------------------------------------------- */
.lv-dropzone {
  display: block;
  padding: var(--lv-space-4);
  border: 2px dashed var(--lv-border);
  border-radius: var(--lv-radius-lg);
  background: var(--lv-bg);
  text-align: center;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.lv-dropzone.is-dragover {
  border-color: var(--lv-brand);
  background: var(--lv-brand-soft);
}
/* Un champ fichier natif a une largeur propre (« Choisir des fichiers  Aucun fichier… ») qui dépassait la carte sur écran étroit : +30 px à 390, +60 px à 360. */
.lv-dropzone input[type="file"], [data-dropzone] input[type="file"] { max-width: 100%; }
.lv-dropzone__hint {
  margin: var(--lv-space-1) 0 0;
  font-size: 0.8rem;
  color: var(--lv-muted);
}
.lv-dropzone__error {
  margin: var(--lv-space-3) 0 0;
  padding: var(--lv-space-2) var(--lv-space-3);
  border: 1px solid var(--lv-danger);
  border-radius: var(--lv-radius-lg);
  font-size: 0.85rem;
  text-align: left;
  color: var(--lv-danger);
}
.lv-dropzone__error[hidden] { display: none; }
.lv-dropzone__files {
  list-style: none;
  margin: var(--lv-space-3) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--lv-space-2);
  text-align: left;
}
.lv-dropzone__file {
  display: flex;
  align-items: center;
  gap: var(--lv-space-2);
  padding: var(--lv-space-2) var(--lv-space-3);
  background: var(--lv-surface);
  border: 1px solid var(--lv-border-soft);
  border-radius: var(--lv-radius);
}
.lv-dropzone__thumb {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: var(--lv-radius-sm);
  background: var(--lv-border-soft);
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.lv-dropzone__thumb img { width: 100%; height: 100%; object-fit: cover; }
.lv-dropzone__name {
  flex: 1;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--lv-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lv-dropzone__size { font-size: 0.78rem; color: var(--lv-muted); white-space: nowrap; }
.lv-dropzone__remove {
  flex-shrink: 0;
  background: none;
  border: none;
  color: var(--lv-muted);
  cursor: pointer;
  font-size: 1rem;
  line-height: 1;
  padding: 0.25rem;
}
.lv-dropzone__remove:hover { color: var(--lv-danger); }

/* ----------------------------------------------------------------------------
   20. ICON PICKER  .lv-iconpicker  (ELM-ICON)
   -------------------------------------------------------------------------- */
.lv-iconpicker {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--lv-space-2);
}
.lv-iconpicker__preview {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--lv-border);
  border-radius: var(--lv-radius);
  background: var(--lv-surface);
  color: var(--lv-brand);
}
.lv-iconpicker__panel {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 50;
  max-height: 240px;
  overflow-y: auto;
  background: var(--lv-surface);
  border: 1px solid var(--lv-border);
  border-radius: var(--lv-radius);
  box-shadow: var(--lv-shadow-md);
  padding: var(--lv-space-2);
}
.lv-iconpicker__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(40px, 1fr));
  gap: var(--lv-space-1);
}
.lv-iconpicker__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 1;
  border: 1px solid transparent;
  border-radius: var(--lv-radius-sm);
  background: none;
  color: var(--lv-text);
  cursor: pointer;
}
.lv-iconpicker__item:hover { background: var(--lv-border-soft); }
.lv-iconpicker__item.is-active {
  background: var(--lv-brand-soft);
  border-color: var(--lv-brand);
  color: var(--lv-brand);
}

/* ----------------------------------------------------------------------------
   21. DIVERS — action de toast (undo), body modal-open, repeater
   -------------------------------------------------------------------------- */
.lv-toast__action {
  flex-shrink: 0;
  background: none;
  border: none;
  padding: 0;
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--lv-brand);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.lv-toast__action:hover { color: var(--lv-brand-dark); }

body.lv-modal-open { overflow: hidden; }

/* Barre d'actions de masse (CMP bulk, listes admin) — visible dès 1 sélection. */
.lv-bulkbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--lv-space-2) var(--lv-space-3);
  padding: var(--lv-space-2) var(--lv-space-4);
  margin-bottom: var(--lv-space-2);
  background: var(--lv-brand-soft);
  border: 1px solid var(--lv-brand);
  border-radius: var(--lv-radius);
}
.lv-bulkbar__count {
  font-size: 0.875rem;
  color: var(--lv-brand);
  margin-right: auto;
  font-variant-numeric: tabular-nums;
}

[data-repeater-item] + [data-repeater-item] { margin-top: var(--lv-space-2); }

@media (prefers-reduced-motion: reduce) {
  .lv-toast,
  .lv-modal__backdrop,
  .lv-modal__dialog,
  .lv-modal__panel,
  .lv-skeleton,
  .lv-spinner,
  .lv-countdown.is-urgent,
  .lv-btn,
  .lv-input,
  .lv-dropzone,
  .lv-chip,
  .lv-meter__bar {
    animation: none !important;
    transition: none !important;
  }
}

/* Cibles tactiles : 44 px minimum sur écran tactile (WCAG 2.5.5), sans alourdir le bureau à la souris. */
@media (pointer: coarse) {
  .lv-btn, .btn, .nav-item, .subnav-pill, .subtab, [data-tab],
  .list-filters-grid .form-input, .list-filters-grid select { min-height: 44px; }
  #togglePwd { width: 44px !important; height: 44px !important; }
}
