/* =========================================================
   ENTRETIENS — dépôt de tickets & facturation (Direction C)
   Patron visuel : missions.css. Tokens : base.css (:root).
   Mobile-first 375 px · encoches via env(safe-area-inset-*).

   Le dark mode arrive PAR LES TOKENS : base.css redéfinit --surface, --ink-*,
   --line-* dans son propre @media (prefers-color-scheme: dark). Tout ce qui est
   écrit ici en var(--…) bascule donc tout seul. Le bloc dark de fin de fichier
   ne traite que le résiduel : les valeurs en dur (ombres, calques translucides,
   images) qu'aucun token ne couvre.
   ========================================================= */

/* ===== Keyframes — préfixées `ent` pour ne rien écraser ailleurs ===== */
@keyframes entSlideUp    { from { transform: translateY(100%); } to { transform: translateY(0); } }
@keyframes entSlideRight { from { transform: translateX(0); }    to { transform: translateX(100%); } }
@keyframes entSlideDown  { from { transform: translateY(0); }    to { transform: translateY(100%); } }
@keyframes entFadeIn     { from { opacity: 0; } to { opacity: 1; } }
@keyframes entFadeOut    { from { opacity: 1; } to { opacity: 0; } }
@keyframes entPopIn      { from { transform: scale(0.94); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@keyframes entToastIn    { from { transform: translateY(16px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }

/* Barre indéterminée. POURQUOI indéterminée et non un pourcentage : auth.js ne
   patche que window.fetch, pas XMLHttpRequest — un upload en XHR partirait sans
   JWT et serait rejeté par le gardien n8n. On reste donc sur fetch, qui n'expose
   aucun octet envoyé. Afficher un pourcentage ici serait une valeur inventée. */
@keyframes entBarIndet {
  0%   { transform: translateX(-110%); }
  100% { transform: translateX(260%); }
}

/* =========================================================
   1. BOUTON DE FICHE (#grid, posé par showProperties)
   ========================================================= */
.entretiens-action-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: var(--surface);
  border: 1px solid var(--line-1);
  border-left: 3px solid var(--gold);
  border-radius: var(--r-md);
  padding: 12px 14px;
  cursor: pointer;
  color: var(--ink-1);
  box-shadow: var(--sh-1);
  transition: background var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
  font-family: inherit;
}
.entretiens-action-btn:active { transform: scale(0.98); background: var(--surface-2); }
.entretiens-btn-title {
  font-size: var(--t-11);
  font-weight: var(--w-semibold);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  color: var(--ink-3);
}
.entretiens-btn-value {
  display: flex;
  align-items: baseline;
  gap: 6px;
  min-height: 22px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.ent-btn-label {
  font-size: var(--t-11);
  font-weight: var(--w-medium);
  color: var(--ink-3);
  white-space: nowrap;
}
.ent-btn-total {
  font-size: var(--t-17, 17px);
  font-weight: var(--w-semibold);
  color: var(--ink-1);
  line-height: 1;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
/* Le compteur « à vérifier » est la seule chose qui réclame une action : il
   passe devant le montant, en rouge. */
.ent-btn-alert {
  font-size: var(--t-10);
  font-weight: var(--w-semibold);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  color: var(--danger);
  background: var(--danger-soft);
  border-radius: var(--r-xs);
  padding: 2px 7px;
  white-space: nowrap;
}

/* =========================================================
   2. PAGE PLEIN ÉCRAN
   ========================================================= */
.ent-page {
  position: fixed;
  inset: 0;
  z-index: 12000;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: entSlideUp 0.3s cubic-bezier(0.22,1,0.36,1) forwards;
}
.ent-page.closing      { animation: entSlideRight 0.25s cubic-bezier(0.55,0,1,0.45) forwards; }
.ent-page.closing-down { animation: entSlideDown  0.25s cubic-bezier(0.55,0,1,0.45) forwards; }

.ent-page-header {
  background: var(--surface);
  border-bottom: 1px solid var(--line-1);
  padding: 12px 14px;
  padding-top: calc(12px + env(safe-area-inset-top, 0px));
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}
.ent-page-back {
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  width: 32px; height: 32px;
  color: var(--ink-2);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  transition: background var(--dur-fast) var(--ease);
}
.ent-page-back:active { background: var(--surface-sunken); }
.ent-page-titles { flex: 1; min-width: 0; }
.ent-page-title {
  font-size: var(--t-15);
  font-weight: var(--w-semibold);
  color: var(--ink-1);
  letter-spacing: -0.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ent-page-subtitle {
  font-size: var(--t-11);
  color: var(--ink-3);
  font-weight: var(--w-semibold);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  margin-top: 2px;
}
.ent-page-add-btn {
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--r-md);
  width: 32px; height: 32px;
  color: #fff;
  font-size: 18px; line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  transition: transform var(--dur-fast) var(--ease);
}
.ent-page-add-btn:active { transform: scale(0.92); }

/* ===== Onglets ===== */
.ent-tabs {
  display: flex;
  gap: 4px;
  padding: 8px 12px;
  background: var(--surface);
  border-bottom: 1px solid var(--line-1);
  flex-shrink: 0;
}
.ent-tab {
  flex: 1;
  min-width: 0;
  padding: 8px 4px;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--ink-3);
  font-family: inherit;
  font-size: var(--t-11);
  font-weight: var(--w-semibold);
  letter-spacing: 0.02em;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 5px;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
  white-space: nowrap;
}
.ent-tab.active {
  background: var(--surface-2);
  border-color: var(--line-1);
  color: var(--ink-1);
}
.ent-tab-count {
  font-size: var(--t-10);
  font-weight: var(--w-semibold);
  background: var(--surface-sunken);
  color: var(--ink-3);
  border-radius: var(--r-pill);
  padding: 1px 6px;
  min-width: 18px;
  font-variant-numeric: tabular-nums;
}
.ent-tab.active .ent-tab-count { background: var(--surface); color: var(--ink-2); }
/* Une file « À vérifier » non vide bloque toute la facturation en aval :
   l'onglet le dit sans qu'on ait à l'ouvrir. */
.ent-tab.has-alert { color: var(--danger); }
.ent-tab.has-alert .ent-tab-count { background: var(--danger-soft); color: var(--danger); }

/* ===== Corps ===== */
.ent-page-body {
  flex: 1;
  overflow-y: auto;
  padding: 12px;
  padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  gap: 12px;
  -webkit-overflow-scrolling: touch;
}
.ent-bandeau-slot:empty { display: none; }
.ent-tab-content { display: flex; flex-direction: column; gap: 12px; }

.ent-loading { display: flex; justify-content: center; padding: 40px; }
.ent-empty {
  text-align: center;
  padding: 40px 16px;
  color: var(--ink-3);
  font-size: var(--t-13);
  font-weight: var(--w-medium);
}
.ent-empty-error { color: var(--danger); }
.ent-note {
  font-size: var(--t-12);
  line-height: 1.5;
  color: var(--ink-3);
  background: var(--surface-2);
  border: 1px solid var(--line-1);
  border-radius: var(--r-md);
  padding: 10px 12px;
}

/* =========================================================
   3. BANDEAU DOUBLONS
   ========================================================= */
.ent-doublon-banner {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 11px 13px;
  border-radius: var(--r-md);
  background: var(--warn-soft);
  border: 1px solid var(--warn);
  color: var(--warn);
  font-family: inherit;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease);
}
.ent-doublon-banner:active { transform: scale(0.99); }
.ent-doublon-banner-txt {
  font-size: var(--t-12);
  font-weight: var(--w-semibold);
  text-align: left;
}
.ent-doublon-banner-cta {
  font-size: var(--t-11);
  font-weight: var(--w-semibold);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  flex-shrink: 0;
}

/* =========================================================
   4. VIGNETTES DE JUSTIFICATIF
   ========================================================= */
.ent-vignette {
  position: relative;
  flex-shrink: 0;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--surface-sunken);
  border: 1px solid var(--line-1);
  display: flex;
  align-items: center;
  justify-content: center;
}
.ent-vignette img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ent-vignette-fallback { font-size: 20px; }
.ent-vignette-xs { width: 40px; height: 40px; }
.ent-vignette-sm { width: 56px; height: 56px; }
.ent-vignette-lg {
  width: 100%;
  height: 190px;
  background: var(--surface-2);
}
/* L'image du ticket est le document de référence : on la montre entière
   (`contain`), jamais recadrée — un montant coupé serait pire que pas d'image. */
.ent-vignette-lg img { object-fit: contain; }
/* Aperçu agrandissable au clic (fiche « à vérifier ») : le curseur l'annonce. */
.ent-vignette-zoomable,
.ent-vignette-zoomable img { cursor: zoom-in; }
/* Boutons d'action de la vignette : ⬇ télécharger + ⤢ ouvrir (coin bas-droit). */
.ent-vignette-actions {
  position: absolute;
  right: 4px; bottom: 4px;
  display: flex;
  gap: 4px;
}
.ent-vignette-btn {
  width: 22px; height: 22px;
  border: none;
  padding: 0;
  border-radius: var(--r-xs);
  background: rgba(0,0,0,0.55);
  color: #fff;
  font-size: 11px;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.ent-vignette-btn:hover { background: rgba(0,0,0,0.78); }
.ent-vignette-dl-busy { opacity: 0.5; pointer-events: none; }
.ent-vignette-xs .ent-vignette-actions { display: none; }

/* =========================================================
   Classement par logement : barre de recherche + groupes dépliables
   ========================================================= */
.ent-search { position: relative; margin-bottom: 12px; }
.ent-search-icon {
  position: absolute;
  left: 12px; top: 50%;
  transform: translateY(-50%);
  font-size: 13px;
  opacity: 0.6;
  pointer-events: none;
}
.ent-search-input {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 12px 10px 36px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-1);
  background: var(--surface);
  color: inherit;
  font-size: var(--t-14);
  -webkit-appearance: none;
  appearance: none;
}
.ent-search-input::placeholder { color: var(--text-secondary); opacity: 0.8; }
.ent-search-input:focus { outline: none; border-color: var(--accent); }

.ent-logement-groups { display: flex; flex-direction: column; gap: 8px; }
.ent-logement-group {
  border: 1px solid var(--line-1);
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--surface);
}
.ent-logement-header {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 14px;
  background: transparent;
  border: none;
  cursor: pointer;
  text-align: left;
  color: inherit;
  font: inherit;
}
.ent-logement-header:hover { background: var(--surface-sunken); }
/* La flèche de dépliage/repliage : un vrai bouton rond, visible et cliquable,
   et non plus un chevron pâle de 11 px qu'on ne voyait pas. Une seule glyphe
   `▸` qui PIVOTE de 90° à l'ouverture (transition) — plus lisible qu'un
   remplacement ▸/▾, et centrée à coup sûr quel que soit l'état. */
.ent-logement-caret {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 1px solid var(--line-2);
  background: var(--surface-sunken);
  color: var(--text-secondary);
  font-size: 12px;
  line-height: 1;
  transition: transform 0.2s var(--ease), color 0.15s ease,
              border-color 0.15s ease, background 0.15s ease;
}
.ent-logement-header:hover .ent-logement-caret {
  color: var(--accent);
  border-color: var(--accent);
}
.ent-logement-group.ent-open > .ent-logement-header .ent-logement-caret {
  transform: rotate(90deg);
  color: var(--accent);
  border-color: var(--accent);
  background: var(--surface);
}
.ent-logement-name { font-weight: var(--w-semibold); font-size: var(--t-15); }
.ent-logement-count {
  font-size: var(--t-12);
  color: var(--text-secondary);
  background: var(--surface-sunken);
  border-radius: var(--r-pill);
  padding: 1px 8px;
  font-variant-numeric: tabular-nums;
}
.ent-logement-alert-dot { font-size: 12px; line-height: 1; }
.ent-logement-total {
  margin-left: auto;
  font-weight: var(--w-semibold);
  font-variant-numeric: tabular-nums;
}
.ent-logement-group.ent-open > .ent-logement-header { border-bottom: 1px solid var(--line-1); }
/* Espacement uniforme entre les items d'un groupe, quel que soit leur type
   (carte « à vérifier », ligne « à facturer », carte facture, pied). */
.ent-logement-body { display: flex; flex-direction: column; gap: 8px; padding: 10px; }
/* ⚠️ INDISPENSABLE : `display: flex` ci-dessus l'emporte sur la règle UA
   `[hidden] { display: none }`. Sans ce sélecteur plus spécifique, `body.hidden
   = true` (repliage) ne masquait RIEN une fois le groupe ouvert puis refermé —
   les tickets restaient à l'écran, flèche pointée ou pas. */
.ent-logement-body[hidden] { display: none; }
/* Les lignes « à facturer » sont ici des items autonomes : le filet du bas de
   `.ent-row` fait doublon avec l'écart flex → on le retire dans ce contexte. */
.ent-logement-body > .ent-row { border-bottom: none; padding: 8px 4px; }

/* =========================================================
   5. CARTES « À VÉRIFIER »
   ========================================================= */
.ent-card {
  display: flex;
  gap: 10px;
  padding: 12px;
  background: var(--surface);
  border: 1px solid var(--line-1);
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.ent-card:active { transform: scale(0.995); background: var(--surface-2); }
.ent-card-verif { border-left: 3px solid var(--danger); }
.ent-card-info { flex: 1; min-width: 0; }
.ent-card-title {
  font-size: var(--t-13);
  font-weight: var(--w-semibold);
  color: var(--ink-1);
  line-height: 1.35;
  word-break: break-word;
}
.ent-card-meta { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.ent-card-desc {
  font-size: var(--t-12);
  color: var(--ink-3);
  margin-top: 6px;
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-word;
}
.ent-card-alert {
  margin-top: 8px;
  font-size: var(--t-11);
  font-weight: var(--w-medium);
  color: var(--danger);
  background: var(--danger-soft);
  border-radius: var(--r-xs);
  padding: 5px 8px;
  line-height: 1.4;
  word-break: break-word;
}
.ent-card-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: space-between;
  gap: 8px;
  flex-shrink: 0;
}
.ent-card-amount {
  font-size: var(--t-13);
  font-weight: var(--w-semibold);
  color: var(--ink-1);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.ent-card-amount-warn { color: var(--warn); }
.ent-card-cta {
  border: 1px solid var(--accent);
  background: var(--accent);
  color: #fff;
  border-radius: var(--r-sm);
  padding: 6px 11px;
  font-family: inherit;
  font-size: var(--t-11);
  font-weight: var(--w-semibold);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  cursor: pointer;
  white-space: nowrap;
  transition: transform var(--dur-fast) var(--ease);
}
.ent-card-cta:active { transform: scale(0.94); }

/* ===== Chips ===== */
.ent-chip {
  font-size: var(--t-10);
  font-weight: var(--w-semibold);
  color: var(--ink-3);
  background: var(--surface-2);
  border: 1px solid var(--line-1);
  padding: 2px 7px;
  border-radius: var(--r-xs);
  display: inline-flex;
  align-items: center;
  line-height: 1.3;
  letter-spacing: var(--ls-wider);
  text-transform: uppercase;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ent-chip-date { font-variant-numeric: tabular-nums; }
.ent-chip-logement { color: var(--accent); background: var(--accent-soft); border-color: transparent; }
.ent-chip-conf-haute   { color: var(--ok);     background: var(--ok-soft);     border-color: transparent; }
.ent-chip-conf-moyenne { color: var(--warn);   background: var(--warn-soft);   border-color: transparent; }
.ent-chip-conf-basse   { color: var(--danger); background: var(--danger-soft); border-color: transparent; }

/* =========================================================
   6. SECTIONS (groupées par logement) + LIGNES
   ========================================================= */
.ent-section {
  background: var(--surface);
  border: 1px solid var(--line-1);
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--sh-1);
}
.ent-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 14px 9px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line-1);
}
.ent-section-header-left { display: flex; align-items: center; gap: 8px; min-width: 0; }
.ent-section-label {
  font-size: var(--t-11);
  font-weight: var(--w-semibold);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  color: var(--ink-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ent-section-count {
  font-size: var(--t-10);
  font-weight: var(--w-semibold);
  color: var(--ink-3);
  background: var(--surface);
  border: 1px solid var(--line-1);
  padding: 2px 7px;
  border-radius: var(--r-xs);
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}
.ent-section-total {
  font-size: var(--t-15);
  font-weight: var(--w-semibold);
  color: var(--ink-1);
  flex-shrink: 0;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}

.ent-list { display: flex; flex-direction: column; }
.ent-list-lies { border-top: 1px solid var(--line-1); }
.ent-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line-1);
}
.ent-row:last-child { border-bottom: none; }
.ent-row-info { flex: 1; min-width: 0; }
.ent-row-title {
  font-size: var(--t-13);
  font-weight: var(--w-semibold);
  color: var(--ink-1);
  line-height: 1.35;
  word-break: break-word;
}
.ent-row-desc {
  font-size: var(--t-12);
  color: var(--ink-3);
  margin-top: 4px;
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-word;
}
.ent-row-price {
  font-size: var(--t-12);
  font-weight: var(--w-semibold);
  color: var(--ink-1);
  background: var(--surface-2);
  border-radius: var(--r-xs);
  padding: 4px 9px;
  flex-shrink: 0;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* ===== Pied de section : la régulation à venir ===== */
.ent-section-footer {
  padding: 12px 14px;
  padding-bottom: 12px;
  background: var(--surface-2);
  border-top: 1px solid var(--line-1);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.ent-section-footer-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.ent-section-footer-label {
  font-size: var(--t-11);
  font-weight: var(--w-semibold);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  color: var(--ink-3);
}
.ent-section-footer-value {
  font-size: var(--t-18);
  font-weight: var(--w-bold);
  color: var(--ink-1);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.ent-btn-facturer {
  width: 100%;
  padding: 11px;
  border-radius: var(--r-md);
  background: var(--accent);
  border: 1px solid var(--accent);
  color: #fff;
  font-family: inherit;
  font-size: var(--t-13);
  font-weight: var(--w-semibold);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease);
}
.ent-btn-facturer:active { transform: scale(0.98); }

/* =========================================================
   7. ONGLET « FACTURÉ » (lecture seule)
   ========================================================= */
.ent-section-facture { border-left: 3px solid var(--ok); }
.ent-facture-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 14px 8px;
}
.ent-facture-head-left { min-width: 0; }
.ent-facture-num {
  font-size: var(--t-14);
  font-weight: var(--w-bold);
  color: var(--ink-1);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.ent-facture-sub {
  font-size: var(--t-11);
  color: var(--ink-3);
  margin-top: 2px;
}
.ent-facture-total {
  font-size: var(--t-15);
  font-weight: var(--w-semibold);
  color: var(--ok);
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}
.ent-facture-client {
  padding: 0 14px 10px;
  font-size: var(--t-12);
  font-weight: var(--w-medium);
  color: var(--ink-2);
  word-break: break-word;
}
.ent-facture-detail {
  margin: 0 14px 12px;
  padding: 8px 10px;
  background: var(--surface-2);
  border-radius: var(--r-sm);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ent-facture-detail-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: var(--t-11);
  color: var(--ink-3);
}
.ent-facture-detail-row:last-child {
  border-top: 1px solid var(--line-1);
  margin-top: 3px;
  padding-top: 5px;
  color: var(--ink-1);
  font-weight: var(--w-semibold);
}
.ent-facture-detail-val { font-variant-numeric: tabular-nums; }
.ent-facture-pdf {
  display: block;
  margin: 0 14px 12px;
  padding: 9px;
  text-align: center;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-2);
  background: var(--surface);
  color: var(--ink-2);
  font-size: var(--t-12);
  font-weight: var(--w-semibold);
  text-decoration: none;
}
.ent-facture-pdf:active { background: var(--surface-2); }

/* =========================================================
   8. FORMULAIRES — champs communs
   ========================================================= */
.ent-form-field { display: flex; flex-direction: column; gap: 5px; }
.ent-form-label {
  font-size: var(--t-11);
  font-weight: var(--w-semibold);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  color: var(--ink-3);
}
.ent-form-input,
.ent-form-textarea,
.ent-form-select {
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  padding: 10px 12px;
  /* 16px : en dessous, iOS Safari zoome à la mise au point du champ et casse
     la mise en page de la feuille. Ne pas descendre. */
  font-size: 16px;
  color: var(--ink-1);
  font-family: inherit;
  outline: none;
  width: 100%;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.ent-form-input:focus,
.ent-form-textarea:focus,
.ent-form-select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.ent-form-textarea { resize: none; min-height: 66px; line-height: 1.45; }
.ent-input-money { font-variant-numeric: tabular-nums; }
.ent-form-select {
  cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-4) 50%),
                    linear-gradient(135deg, var(--ink-4) 50%, transparent 50%);
  background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 32px;
}
.ent-form-hint {
  font-size: var(--t-11);
  color: var(--ink-3);
  line-height: 1.4;
}
.ent-form-hint-warn { color: var(--danger); font-weight: var(--w-semibold); }

.ent-form-submit {
  width: 100%;
  padding: 13px;
  border-radius: var(--r-md);
  background: var(--accent);
  border: 1px solid var(--accent);
  color: #fff;
  font-family: inherit;
  font-size: var(--t-14);
  font-weight: var(--w-semibold);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin-top: 4px;
  transition: transform var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.ent-form-submit:active:not(:disabled) { transform: scale(0.98); }
/* Le désactivé doit se LIRE comme désactivé : c'est l'état d'un contrôle
   arithmétique qui ne tombe pas juste, pas un bouton simplement pâle. */
.ent-form-submit:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
  background: var(--ink-4);
  border-color: var(--ink-4);
}
.ent-form-submit.success { background: var(--ok); border-color: var(--ok); opacity: 1; }
.ent-form-submit.error   { background: var(--danger); border-color: var(--danger); opacity: 1; }
.ent-form-submit .spinner {
  width: 16px; height: 16px;
  border-width: 2px;
  border-color: rgba(255,255,255,0.3);
  border-top-color: #fff;
}
.ent-form-danger {
  width: 100%;
  padding: 11px;
  border-radius: var(--r-md);
  background: transparent;
  border: 1px solid var(--danger);
  color: var(--danger);
  font-family: inherit;
  font-size: var(--t-12);
  font-weight: var(--w-semibold);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.ent-form-danger:active { background: var(--danger-soft); }

/* =========================================================
   9. LE CONTRÔLE ARITHMÉTIQUE (bandeau vert / rouge)
   ========================================================= */
.ent-controle {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 12px;
  border-radius: var(--r-md);
  font-size: var(--t-12);
  font-weight: var(--w-medium);
  line-height: 1.45;
  border: 1px solid var(--line-1);
  background: var(--surface-2);
  color: var(--ink-3);
}
.ent-controle.ok { background: var(--ok-soft); border-color: var(--ok); color: var(--ok); }
.ent-controle.ko { background: var(--danger-soft); border-color: var(--danger); color: var(--danger); }
.ent-controle-icon { flex-shrink: 0; line-height: 1.4; }
.ent-controle-msg { min-width: 0; word-break: break-word; font-variant-numeric: tabular-nums; }

/* Suggestion de montant : volontairement discrète et SECONDAIRE. Elle propose,
   elle n'applique pas — c'est un clic humain qui écrit la valeur. */
.ent-suggest-btn {
  align-self: flex-start;
  padding: 7px 11px;
  border-radius: var(--r-sm);
  border: 1px dashed var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
  font-family: inherit;
  font-size: var(--t-11);
  font-weight: var(--w-semibold);
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.ent-suggest-btn:active { transform: scale(0.96); }
.ent-suggest-btn[hidden] { display: none; }

/* ===== Lignes de TVA multi-taux (lecture) ===== */
.ent-lignes-tva {
  border: 1px solid var(--line-1);
  border-radius: var(--r-md);
  padding: 10px 12px;
  background: var(--surface-2);
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.ent-lignes-tva[hidden] { display: none; }
.ent-lignes-tva-title {
  font-size: var(--t-10);
  font-weight: var(--w-semibold);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  color: var(--warn);
}
.ent-lignes-tva-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: var(--t-11);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.ent-lignes-tva-ttc { font-weight: var(--w-semibold); color: var(--ink-2); }

/* =========================================================
   10. FEUILLE DE DÉPÔT
   ========================================================= */
.ent-depot-overlay,
.ent-verif-overlay,
.ent-facture-overlay,
.ent-doublon-overlay {
  position: fixed;
  inset: 0;
  z-index: 16000;
  background: rgba(0,0,0,0.5);
  display: flex;
  align-items: flex-end;
  animation: entFadeIn 0.2s ease forwards;
}
.ent-depot-overlay.closing,
.ent-verif-overlay.closing,
.ent-facture-overlay.closing,
.ent-doublon-overlay.closing { animation: entFadeOut 0.2s ease forwards; }

.ent-depot-sheet,
.ent-verif-sheet,
.ent-facture-sheet,
.ent-doublon-sheet {
  width: 100%;
  max-height: 93vh;
  background: var(--surface);
  border-top: 1px solid var(--line-1);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: var(--sh-4);
  animation: entSlideUp 0.3s cubic-bezier(0.22,1,0.36,1) forwards;
}
.ent-depot-overlay.closing .ent-depot-sheet,
.ent-verif-overlay.closing .ent-verif-sheet,
.ent-facture-overlay.closing .ent-facture-sheet,
.ent-doublon-overlay.closing .ent-doublon-sheet {
  animation: entSlideDown 0.25s cubic-bezier(0.55,0,1,0.45) forwards;
}

.ent-depot-header,
.ent-verif-header,
.ent-facture-header,
.ent-doublon-header {
  background: var(--surface);
  border-bottom: 1px solid var(--line-1);
  padding: 14px 16px 12px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  flex-shrink: 0;
}
/* Conteneur titre+sous-titre des en-têtes de feuille. Le `min-width: 0` n'est pas
   décoratif : sans lui, un enfant flex refuse de rétrécir sous sa largeur de
   contenu et le bouton de fermeture se fait pousser hors de l'écran par un nom
   de logement un peu long. */
.ent-depot-titles,
.ent-verif-titles,
.ent-facture-titles,
.ent-doublon-titles {
  flex: 1;
  min-width: 0;
}
.ent-depot-title,
.ent-verif-title,
.ent-facture-title,
.ent-doublon-title {
  font-size: var(--t-15);
  font-weight: var(--w-semibold);
  color: var(--ink-1);
  letter-spacing: -0.01em;
}
.ent-verif-sub,
.ent-facture-subtitle,
.ent-doublon-sub {
  font-size: var(--t-11);
  color: var(--ink-3);
  margin-top: 3px;
  line-height: 1.4;
}
.ent-depot-close,
.ent-verif-close,
.ent-facture-close,
.ent-doublon-close {
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  width: 30px; height: 30px;
  color: var(--ink-2);
  font-size: 14px;
  cursor: pointer;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  transition: background var(--dur-fast) var(--ease);
}
.ent-depot-close:active,
.ent-verif-close:active,
.ent-facture-close:active,
.ent-doublon-close:active { background: var(--surface-2); }

.ent-depot-body,
.ent-verif-body,
.ent-facture-body {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 14px 14px calc(20px + env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* ===== Zone de dépôt ===== */
.ent-dropzone {
  position: relative;
  border: 2px dashed var(--line-2);
  border-radius: var(--r-lg);
  background: var(--surface-2);
  padding: 22px 14px;
  text-align: center;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.ent-dropzone input[type="file"] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
  width: 100%; height: 100%;
}
.ent-dropzone.dragover,
.ent-depot-sheet.dragover .ent-dropzone {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.ent-dropzone-icon { font-size: 26px; line-height: 1; }
.ent-dropzone-text {
  margin-top: 8px;
  font-size: var(--t-13);
  font-weight: var(--w-semibold);
  color: var(--ink-2);
  line-height: 1.5;
}
.ent-dropzone-text span { font-weight: var(--w-regular); color: var(--ink-3); font-size: var(--t-12); }
.ent-dropzone-sub {
  margin-top: 6px;
  font-size: var(--t-10);
  color: var(--ink-4);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  font-weight: var(--w-semibold);
}

/* ===== File d'envoi — une ligne, une barre, un sort ===== */
.ent-file-list { display: flex; flex-direction: column; gap: 8px; }
.ent-file-list:empty { display: none; }
.ent-file-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px;
  border: 1px solid var(--line-1);
  border-radius: var(--r-md);
  background: var(--surface);
  animation: entPopIn 0.18s var(--ease-out) forwards;
}
/* La bordure gauche porte le sort du fichier : lisible d'un coup d'œil sur une
   file de douze tickets, sans lire un seul libellé. */
.ent-file-row.is-ok     { border-left: 3px solid var(--ok); }
.ent-file-row.is-erreur { border-left: 3px solid var(--danger); background: var(--danger-soft); }
.ent-file-row.is-envoi  { border-left: 3px solid var(--accent); }

.ent-file-thumb {
  width: 44px; height: 44px;
  flex-shrink: 0;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--surface-sunken);
  display: flex; align-items: center; justify-content: center;
}
.ent-file-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ent-file-thumb-pdf {
  font-size: var(--t-10);
  font-weight: var(--w-bold);
  color: var(--ink-3);
  letter-spacing: 0.06em;
}
.ent-file-mid { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.ent-file-name {
  font-size: var(--t-12);
  font-weight: var(--w-semibold);
  color: var(--ink-1);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ent-file-meta {
  font-size: var(--t-10);
  color: var(--ink-4);
  font-variant-numeric: tabular-nums;
}
.ent-file-bar {
  height: 3px;
  border-radius: var(--r-pill);
  background: var(--surface-sunken);
  overflow: hidden;
  margin-top: 2px;
}
.ent-file-bar-fill {
  height: 100%;
  width: 0;
  border-radius: var(--r-pill);
  background: var(--accent);
  transition: width var(--dur-base) var(--ease);
}
.ent-file-row.is-envoi .ent-file-bar-fill {
  width: 40%;
  animation: entBarIndet 1.1s ease-in-out infinite;
}
.ent-file-row.is-ok     .ent-file-bar-fill { width: 100%; background: var(--ok); }
.ent-file-row.is-erreur .ent-file-bar-fill { width: 100%; background: var(--danger); }
.ent-file-state {
  font-size: var(--t-10);
  font-weight: var(--w-medium);
  color: var(--ink-3);
  line-height: 1.4;
  word-break: break-word;
}
.ent-file-row.is-ok     .ent-file-state { color: var(--ok); }
.ent-file-row.is-erreur .ent-file-state { color: var(--danger); font-weight: var(--w-semibold); }
/* « À vérifier » n'est pas un échec — mais ce n'est pas un feu vert non plus.
   Un ticket lu de travers puis créé en « À vérifier » ne doit pas porter le même
   vert qu'un ticket dont les montants sont sûrs, sinon le déposant range les
   deux dans la même case mentale : « c'est fait ». */
.ent-file-row.is-ok.is-averifier { border-left-color: var(--warn); }
.ent-file-row.is-ok.is-averifier .ent-file-state { color: var(--warn); }
.ent-file-row.is-ok.is-averifier .ent-file-bar-fill { background: var(--warn); }

/* Le détail : le texte que le SERVEUR a rédigé (`arbitrage`) et que personne
   n'affichait. Il est long par nature (« …demandez au Chef de l'enregistrer ») :
   il s'enroule, il ne s'ellipse pas. Un motif tronqué ne se lit pas. */
.ent-file-detail {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 3px;
}
.ent-file-detail-txt {
  font-size: var(--t-10);
  line-height: 1.45;
  color: var(--ink-3);
  white-space: pre-line;
  word-break: break-word;
}
.ent-file-row.is-erreur .ent-file-detail-txt { color: var(--ink-2); }

/* Le fichier orphelin : le SEUL refus qui laisse une trace physique sur le
   Drive. Son id doit pouvoir être sélectionné et recopié — c'est avec lui que le
   Chef retrouvera, dans six mois, à quoi correspond ce fichier sans ligne. */
.ent-file-orphelin {
  font-size: var(--t-10);
  line-height: 1.4;
  font-weight: var(--w-semibold);
  color: var(--warn);
  background: var(--warn-soft);
  border-radius: var(--r-sm);
  padding: 4px 6px;
  word-break: break-all;
  user-select: all;
  -webkit-user-select: all;
}

/* Les lignes en échec portent un pavé de texte : la vignette et le bouton
   « Réessayer » se calent en haut, sinon ils flottent au milieu d'un paragraphe. */
.ent-file-row.is-erreur,
.ent-file-row.is-orphelin { align-items: flex-start; }

.ent-file-actions { flex-shrink: 0; display: flex; align-items: center; }
.ent-file-remove {
  width: 24px; height: 24px;
  border-radius: 50%;
  border: none;
  background: var(--surface-2);
  color: var(--ink-3);
  font-size: 12px;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background var(--dur-fast) var(--ease);
}
.ent-file-remove:active { background: var(--danger-soft); color: var(--danger); }
.ent-file-retry {
  border: 1px solid var(--danger);
  background: transparent;
  color: var(--danger);
  border-radius: var(--r-sm);
  padding: 5px 9px;
  font-family: inherit;
  font-size: var(--t-10);
  font-weight: var(--w-semibold);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  cursor: pointer;
  white-space: nowrap;
}

/* ===== Récapitulatif du lot — persistant, pas un toast =====
   Le toast dure 2,6 s. Un verdict d'échec qui s'efface tout seul n'a pas été lu :
   celui-ci reste tant que le formulaire est ouvert, et le formulaire ne se
   referme pas de lui-même dès qu'il reste un échec à lire. */
.ent-depot-recap {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 10px 12px;
  border-radius: var(--r-md);
  border: 1px solid var(--line-1);
  border-left: 3px solid var(--ok);
  background: var(--surface-sunken);
  animation: entPopIn 0.18s var(--ease-out) forwards;
}
.ent-depot-recap[hidden] { display: none; }
.ent-depot-recap-ko {
  border-left-color: var(--danger);
  border-color: var(--danger);
  background: var(--danger-soft);
}
.ent-depot-recap-title {
  font-size: var(--t-12);
  font-weight: var(--w-semibold);
  color: var(--ink-1);
  line-height: 1.4;
}
.ent-depot-recap-sub {
  font-size: var(--t-10);
  line-height: 1.45;
  color: var(--ink-2);
}
.ent-depot-recap-ko .ent-depot-recap-sub { color: var(--danger); font-weight: var(--w-semibold); }
.ent-depot-recap-list {
  margin: 2px 0 0;
  padding-left: 16px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.ent-depot-recap-list li {
  font-size: var(--t-10);
  line-height: 1.4;
  color: var(--ink-2);
  word-break: break-word;
}

/* =========================================================
   11. FORMULAIRE DE VÉRIFICATION
   ========================================================= */
.ent-verif-apercu { display: flex; flex-direction: column; }
/* Nom du fichier sous l'aperçu — toujours lisible pour retrouver le justificatif
   dans Drive, y compris quand le thumbnail ne se charge pas. Le nom peut être
   long (« AAAA-MM-JJ_fournisseur_TTC.ext ») : on le laisse aller à la ligne. */
.ent-apercu-nom {
  margin-top: 8px;
  font-size: var(--t-12);
  color: var(--text-secondary);
  text-align: center;
  word-break: break-all;
  line-height: 1.35;
  -webkit-user-select: text;
  user-select: text;
}
/* 2 colonnes dès 375 px : les quatre montants doivent tenir dans un seul
   coup d'œil pour qu'un écart HT/TVA/TTC se voie. */
.ent-montants {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

/* =========================================================
   12. POPUP DE DOUBLON
   ========================================================= */
.ent-doublon-sheet { max-height: 95vh; }
.ent-doublon-intro {
  padding: 10px 16px;
  font-size: var(--t-11);
  color: var(--ink-3);
  line-height: 1.45;
  background: var(--warn-soft);
  border-bottom: 1px solid var(--line-1);
  flex-shrink: 0;
}
.ent-doublon-grid {
  flex: 1;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  padding: 12px;
  display: flex;
  gap: 10px;
  align-items: flex-start;
}
/* Le cas normal, deux tickets : CÔTE À CÔTE, sans défilement. Les empiler
   forcerait à comparer deux images de mémoire — c'est précisément la décision
   qu'on demande à l'humain de prendre à l'œil. */
.ent-doublon-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  overflow-x: hidden;
  /* `stretch` (et non le flex-start hérité) : les deux colonnes prennent la même
     hauteur, ce qui aligne les deux boutons « Garder celui-ci » sur la même ligne.
     Décalés, ils suggèrent une asymétrie entre deux options qui sont à égalité —
     et c'est un choix binaire qu'on demande à l'œil. */
  align-items: stretch;
}
.ent-doublon-grid:not(.ent-doublon-grid-2) > .ent-doublon-col {
  min-width: 62vw;
  flex-shrink: 0;
}
.ent-doublon-col {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  border: 1px solid var(--line-1);
  border-radius: var(--r-md);
  background: var(--surface-2);
  min-width: 0;
}
.ent-doublon-col .ent-vignette-lg { height: 150px; }
.ent-doublon-infos { display: flex; flex-direction: column; gap: 4px; }
.ent-doublon-info-row {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.ent-doublon-info-label {
  font-size: var(--t-10);
  font-weight: var(--w-semibold);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  color: var(--ink-4);
}
.ent-doublon-info-val {
  font-size: var(--t-11);
  color: var(--ink-1);
  word-break: break-word;
  line-height: 1.35;
}
.ent-doublon-keep {
  margin-top: auto;
  padding: 10px;
  border-radius: var(--r-sm);
  background: var(--accent);
  border: 1px solid var(--accent);
  color: #fff;
  font-family: inherit;
  font-size: var(--t-11);
  font-weight: var(--w-semibold);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: transform var(--dur-fast) var(--ease);
}
.ent-doublon-keep:active { transform: scale(0.96); }

/* Le bouton qui NE PEUT PAS aboutir (l'autre ticket est « Facturé », donc
   immuable côté serveur). Éteint et nommé, plutôt que cliquable et menteur.
   `margin-top: auto` est repris ici : sans lui, la note explicative qui le suit
   décollerait le bouton du bas de sa colonne. */
.ent-doublon-keep-mort {
  background: var(--surface-2);
  border-color: var(--line-2);
  color: var(--ink-4);
  cursor: not-allowed;
  /* Le libellé du bouton mort est une PHRASE (« Impossible : l'autre est
     facturé »), pas une étiquette : en capitales espacées, elle ne se lirait
     plus et déborderait d'une colonne de 170 px à 375 px. */
  text-transform: none;
  letter-spacing: 0;
}
.ent-doublon-keep-mort:active { transform: none; }
.ent-doublon-mort-note {
  margin-top: 6px;
  font-size: var(--t-10);
  line-height: 1.45;
  color: var(--ink-3);
}

/* Le doublon dont l'un est DÉJÀ FACTURÉ : ce n'est plus un doublon, c'est un
   second remboursement à un clic. Rouge, pas orange. */
.ent-doublon-alerte {
  padding: 10px 16px;
  font-size: var(--t-11);
  line-height: 1.45;
  font-weight: var(--w-semibold);
  color: var(--danger);
  background: var(--danger-soft);
  border-bottom: 1px solid var(--danger);
  flex-shrink: 0;
}
.ent-doublon-keep .spinner {
  width: 14px; height: 14px; border-width: 2px;
  border-color: rgba(255,255,255,0.3); border-top-color: #fff;
}
.ent-doublon-footer {
  padding: 10px 14px calc(14px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--line-1);
  background: var(--surface);
  flex-shrink: 0;
}
.ent-doublon-keepall {
  width: 100%;
  padding: 10px;
  border-radius: var(--r-md);
  background: var(--surface);
  border: 1px solid var(--line-2);
  color: var(--ink-2);
  font-family: inherit;
  font-size: var(--t-12);
  font-weight: var(--w-semibold);
  cursor: pointer;
}
.ent-doublon-keepall:active { background: var(--surface-2); }

/* =========================================================
   13. PRÉPARATION DE FACTURE
   ========================================================= */
.ent-client-card {
  padding: 12px;
  border-radius: var(--r-md);
  border: 1px solid var(--line-1);
  background: var(--surface-2);
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.ent-client-card-ko { border-color: var(--danger); background: var(--danger-soft); }
.ent-client-nom {
  font-size: var(--t-13);
  font-weight: var(--w-bold);
  color: var(--ink-1);
  word-break: break-word;
}
.ent-client-adresse {
  font-size: var(--t-11);
  color: var(--ink-3);
  line-height: 1.4;
  word-break: break-word;
}
.ent-client-ids {
  font-size: var(--t-10);
  color: var(--ink-4);
  font-variant-numeric: tabular-nums;
}
.ent-client-warn {
  margin-top: 6px;
  font-size: var(--t-11);
  font-weight: var(--w-semibold);
  color: var(--danger);
  line-height: 1.45;
}

.ent-bloc {
  border: 1px solid var(--line-1);
  border-radius: var(--r-md);
  background: var(--surface);
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ent-bloc-title {
  font-size: var(--t-11);
  font-weight: var(--w-semibold);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  color: var(--ink-2);
}
.ent-bloc-sub {
  font-size: var(--t-11);
  color: var(--ink-3);
  line-height: 1.4;
  margin-top: -4px;
}

/* ===== Ticket décochable ===== */
.ent-check-row {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px;
  border: 1px solid var(--line-1);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  cursor: pointer;
  margin-bottom: 6px;
  transition: opacity var(--dur-fast) var(--ease);
}
/* Décoché ≠ supprimé : le ticket reste visible, juste éteint. Il repart sur la
   prochaine facture, et l'humain doit pouvoir le vérifier d'un regard. */
.ent-check-row.unchecked { opacity: 0.45; }
.ent-check {
  width: 20px; height: 20px;
  flex-shrink: 0;
  accent-color: var(--accent);
  cursor: pointer;
}
.ent-check-info { flex: 1; min-width: 0; }
.ent-check-title {
  font-size: var(--t-12);
  font-weight: var(--w-semibold);
  color: var(--ink-1);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ent-check-sub {
  font-size: var(--t-10);
  color: var(--ink-3);
  margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Ticket dont l'arithmétique ne tombe pas juste : signalé AVANT le clic, pas
   seulement dans le message de refus du contrôle final. */
.ent-check-row-ko {
  border-color: var(--danger);
  background: var(--danger-soft);
}
.ent-check-warn {
  margin-top: 3px;
  font-size: var(--t-10);
  font-weight: var(--w-semibold);
  color: var(--danger);
  line-height: 1.35;
  white-space: normal;
  word-break: break-word;
}
.ent-check-price {
  font-size: var(--t-12);
  font-weight: var(--w-semibold);
  color: var(--ink-1);
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}
.ent-check-price-ko { color: var(--danger); }

/* ===== Lignes de prestation ===== */
.ent-ligne {
  border: 1px solid var(--line-1);
  border-radius: var(--r-sm);
  padding: 9px;
  background: var(--surface-2);
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 8px;
  animation: entPopIn 0.16s var(--ease-out) forwards;
}
.ent-ligne-head { display: flex; align-items: center; gap: 8px; }
.ent-ligne-libelle { flex: 1; min-width: 0; }
.ent-ligne-del {
  width: 26px; height: 26px;
  flex-shrink: 0;
  border-radius: 50%;
  border: none;
  background: var(--surface);
  color: var(--ink-3);
  font-size: 12px;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.ent-ligne-del:active { background: var(--danger-soft); color: var(--danger); }
.ent-ligne-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.ent-ligne-calc {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  align-items: baseline;
  font-size: var(--t-10);
  color: var(--ink-3);
  padding-top: 2px;
  font-variant-numeric: tabular-nums;
}
.ent-ligne-calc strong { color: var(--ink-1); font-size: var(--t-11); font-weight: var(--w-semibold); }
.ent-ligne-calc-ko { color: var(--warn); font-weight: var(--w-semibold); }

.ent-add-ligne {
  width: 100%;
  padding: 10px;
  border-radius: var(--r-sm);
  border: 1px dashed var(--line-3);
  background: transparent;
  color: var(--accent);
  font-family: inherit;
  font-size: var(--t-12);
  font-weight: var(--w-semibold);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.ent-add-ligne:active { background: var(--accent-soft); }

/* ===== Totaux ===== */
.ent-totaux {
  border: 1px solid var(--line-1);
  border-radius: var(--r-md);
  background: var(--surface-2);
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ent-totaux-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  font-size: var(--t-12);
  color: var(--ink-3);
}
.ent-totaux-val { font-variant-numeric: tabular-nums; color: var(--ink-2); font-weight: var(--w-medium); }
.ent-totaux-grand {
  border-top: 1px solid var(--line-2);
  margin-top: 4px;
  padding-top: 8px;
  font-size: var(--t-13);
  font-weight: var(--w-semibold);
  color: var(--ink-1);
}
.ent-totaux-grand .ent-totaux-val {
  font-size: var(--t-18);
  font-weight: var(--w-bold);
  color: var(--ink-1);
  letter-spacing: -0.02em;
}

/* =========================================================
   14. CONFIRMATION + TOAST
   ========================================================= */
.ent-confirm-overlay {
  position: fixed;
  inset: 0;
  z-index: 20000;
  background: rgba(0,0,0,0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  animation: entFadeIn 0.15s ease forwards;
}
.ent-confirm-overlay.closing { animation: entFadeOut 0.15s ease forwards; }
.ent-confirm-box {
  background: var(--surface);
  border: 1px solid var(--line-1);
  border-radius: var(--r-lg);
  padding: 22px 20px 16px;
  width: 100%;
  max-width: 320px;
  text-align: center;
  box-shadow: var(--sh-4);
  animation: entPopIn 0.18s var(--ease-out) forwards;
}
.ent-confirm-title {
  font-size: var(--t-15);
  font-weight: var(--w-semibold);
  color: var(--ink-1);
  margin-bottom: 6px;
  letter-spacing: -0.01em;
}
.ent-confirm-sub {
  font-size: var(--t-13);
  color: var(--ink-3);
  margin-bottom: 18px;
  line-height: 1.45;
}
.ent-confirm-actions { display: flex; gap: 10px; }
.ent-confirm-no, .ent-confirm-yes {
  flex: 1;
  padding: 11px;
  border-radius: var(--r-md);
  font-family: inherit;
  font-size: var(--t-13);
  font-weight: var(--w-semibold);
  cursor: pointer;
}
.ent-confirm-no {
  background: var(--surface);
  border: 1px solid var(--line-2);
  color: var(--ink-1);
}
.ent-confirm-yes {
  background: var(--danger);
  border: 1px solid var(--danger);
  color: #fff;
}
.ent-confirm-no:active  { background: var(--surface-2); }
.ent-confirm-yes:active { opacity: 0.8; }

.ent-toast {
  position: fixed;
  left: 50%;
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 24000;
  max-width: calc(100vw - 32px);
  padding: 11px 16px;
  border-radius: var(--r-pill);
  background: var(--ink-1);
  color: var(--bg);
  font-size: var(--t-12);
  font-weight: var(--w-semibold);
  box-shadow: var(--sh-3);
  animation: entToastIn 0.22s var(--ease-out) forwards;
  text-align: center;
}
.ent-toast.closing { animation: entFadeOut 0.2s ease forwards; }
.ent-toast-error { background: var(--danger); color: #fff; }

/* =========================================================
   15. ÉCRANS PLUS LARGES
   Le module est conçu à 375 px ; au-delà on centre plutôt que d'étirer des
   champs de saisie à 900 px de large.
   ========================================================= */
@media (min-width: 700px) {
  .ent-depot-overlay, .ent-verif-overlay, .ent-facture-overlay, .ent-doublon-overlay {
    align-items: center;
    justify-content: center;
    padding: 24px;
  }
  .ent-depot-sheet, .ent-verif-sheet, .ent-facture-sheet, .ent-doublon-sheet {
    max-width: 620px;
    border-radius: var(--r-lg);
    border: 1px solid var(--line-1);
    max-height: 88vh;
  }
  .ent-page-body { padding: 16px; }
  .ent-tab-content, .ent-bandeau-slot { max-width: 820px; width: 100%; margin: 0 auto; }
  .ent-montants { grid-template-columns: repeat(4, 1fr); }
  .ent-doublon-grid:not(.ent-doublon-grid-2) > .ent-doublon-col { min-width: 260px; }
  .ent-doublon-col .ent-vignette-lg { height: 220px; }
}

/* =========================================================
   15 bis. LECTURE CONTESTÉE
   Le désaccord entre les deux lectures d'un même ticket.

   POURQUOI CETTE SECTION EXISTE : le formulaire de vérification pré-remplissait
   le montant que le back-end venait de REJETER, sous une coche verte, bouton
   actif — et rangeait son propre avertissement dans un <input> d'une ligne
   étiqueté « (optionnel) ». Un Chef qui vide sa file un vendredi soir voyait un
   écran vert et complet. Un clic = 100 € de trop sur la facture d'un vrai client.

   Ce que ces règles font tenir :
     · le litige se voit dans la LISTE, avant l'ouverture (.ent-card-conteste) ;
     · à l'ouverture il est un BANDEAU de premier plan, pas une note de bas de
       page, et il montre les deux lectures CÔTE À CÔTE, en entier ;
     · un champ contesté est VIDE et rouge — il se demande, il ne se propose pas.

   Tout est en var(--…) : le dark mode bascule par les tokens de base.css (§16
   ne reprend que le résiduel).
   ========================================================= */

.ent-desaccord {
  border: 1px solid var(--danger);
  /* Le trait épais à gauche : c'est ce qui se voit avant d'avoir lu un mot. */
  border-left: 4px solid var(--danger);
  background: var(--danger-soft);
  border-radius: var(--r-md);
  padding: 12px;
  margin-bottom: 14px;
}
.ent-desaccord-head {
  font-size: var(--t-13);
  font-weight: var(--w-semibold);
  color: var(--danger);
  line-height: 1.35;
  word-break: break-word;
}
.ent-desaccord-intro {
  margin-top: 6px;
  font-size: var(--t-12);
  color: var(--ink-1);
  line-height: 1.5;
  word-break: break-word;
}

/* Une carte par champ en litige. Fond « surface » et non transparent : les
   lectures doivent se détacher du rouge, ce sont elles qu'on vient lire. */
.ent-desaccord-champ {
  margin-top: 10px;
  background: var(--surface);
  border: 1px solid var(--line-1);
  border-radius: var(--r-sm);
  padding: 8px;
}
.ent-desaccord-champ-nom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-size: var(--t-11);
  font-weight: var(--w-semibold);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  color: var(--ink-3);
}
.ent-desaccord-badge-argent {
  text-transform: none;
  letter-spacing: 0;
  font-size: var(--t-10);
  font-weight: var(--w-semibold);
  color: var(--danger);
  background: var(--danger-soft);
  border: 1px solid var(--danger);
  border-radius: var(--r-xs);
  padding: 1px 6px;
}

/* Les lectures côte à côte. auto-fit + minmax : à 375 px deux colonnes tiennent
   (≈150 px chacune) ; une 3e lecture passe à la ligne PLUTÔT que de rogner un
   montant. On n'arbitre pas sur un chiffre tronqué — c'est tout l'objet de
   l'écran. */
.ent-desaccord-lectures {
  margin-top: 6px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: 6px;
}
.ent-desaccord-lecture {
  border: 1px solid var(--line-1);
  border-radius: var(--r-xs);
  background: var(--surface-2);
  padding: 6px 8px;
  min-width: 0;
}
.ent-desaccord-lecture-nom {
  font-size: var(--t-10);
  font-weight: var(--w-semibold);
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
}
.ent-desaccord-lecture-val {
  margin-top: 2px;
  font-size: var(--t-13);
  font-weight: var(--w-semibold);
  color: var(--ink-1);
  /* tabular-nums : deux montants alignés au chiffre près se comparent d'un coup
     d'œil — 147,90 sous 47,90, c'est là que l'écart saute aux yeux.
     break-word : un nom de fournisseur ne se coupe pas au milieu de l'écran. */
  font-variant-numeric: tabular-nums;
  word-break: break-word;
  line-height: 1.35;
}

/* La trace machine : lecture seule, à part de la note du Chef, inneffaçable. */
.ent-desaccord-trace {
  margin-top: 10px;
  font-size: var(--t-11);
  color: var(--ink-3);
  line-height: 1.45;
  word-break: break-word;
  border-top: 1px dashed var(--danger);
  padding-top: 8px;
}
.ent-desaccord-trace-label {
  font-weight: var(--w-semibold);
  color: var(--danger);
}

/* ---- Le champ contesté lui-même ---- */
.ent-input-conteste {
  border-color: var(--danger) !important;
  background: var(--danger-soft) !important;
  color: var(--ink-1);
}
.ent-input-conteste::placeholder { color: var(--danger); opacity: 0.85; }
.ent-input-conteste:focus {
  border-color: var(--danger) !important;
  box-shadow: 0 0 0 3px var(--danger-soft);
}
.ent-form-field-conteste .ent-form-label { color: var(--danger); }

/* ---- Repérage dans la LISTE, avant ouverture ---- */
.ent-card-conteste { border-left: 3px solid var(--danger); }
.ent-chip-conteste {
  color: var(--danger);
  background: var(--danger-soft);
  border-color: var(--danger);
}
.ent-card-alert-conteste {
  color: var(--danger);
  background: var(--danger-soft);
  font-weight: var(--w-semibold);
}
/* Le TTC d'un ticket contesté est une des deux lectures, pas un montant : barré,
   il cesse d'être une affirmation. */
.ent-card-amount-conteste {
  text-decoration: line-through;
  text-decoration-color: var(--danger);
  opacity: 0.65;
}

/* ---- Technicien : miroir de la règle Chef-seulement (règle 13) ---- */
.ent-verif-lecture-seule {
  margin-top: 12px;
  border: 1px solid var(--line-1);
  border-left: 3px solid var(--warn);
  background: var(--warn-soft);
  color: var(--ink-1);
  border-radius: var(--r-md);
  padding: 10px 12px;
  font-size: var(--t-12);
  line-height: 1.45;
  word-break: break-word;
}

/* ---- Note de vérification dans la fenêtre de facturation ---- */
.ent-check-note {
  margin-top: 3px;
  font-size: var(--t-10);
  color: var(--ink-3);
  line-height: 1.35;
  white-space: normal;
  word-break: break-word;
}
/* « DOUBLON FORCÉ — tickets voisins : #N » : quelqu'un est passé outre un
   doublon. Ça ne se lit pas en gris à côté d'une case à cocher. */
.ent-check-note-alerte {
  color: var(--warn);
  font-weight: var(--w-semibold);
}

/* =========================================================
   16. DARK MODE (règle 6)
   Les tokens de base.css basculent seuls ; ne restent ici que les valeurs qui
   n'en dépendent pas.
   ========================================================= */
@media (prefers-color-scheme: dark) {
  /* Les calques noirs translucides écrasent un fond déjà sombre : on remonte
     l'opacité pour que la feuille se détache toujours du fond. */
  .ent-depot-overlay,
  .ent-verif-overlay,
  .ent-facture-overlay,
  .ent-doublon-overlay,
  .ent-confirm-overlay { background: rgba(0,0,0,0.68); }

  .ent-depot-sheet,
  .ent-verif-sheet,
  .ent-facture-sheet,
  .ent-doublon-sheet,
  .ent-confirm-box { box-shadow: 0 -4px 30px rgba(0,0,0,0.55); }

  .ent-page-header,
  .ent-tabs { box-shadow: 0 1px 0 rgba(0,0,0,0.3); }

  /* ---- Lecture contestée (§15 bis) ----
     Le gros du bandeau bascule par les tokens (--danger / --danger-soft sont
     redéfinis dans base.css). Ne restent ici que deux résiduels : */

  /* 1. L'anneau de focus. En clair, --danger-soft (#eed4d4) tranche sur le blanc
        de la feuille ; en sombre (#3a1e1e) il se confond avec --surface (#161b22)
        et l'anneau disparaît — or c'est le champ qu'on demande expressément au
        Chef de retaper. On le repasse en rouge franc translucide. */
  .ent-input-conteste:focus { box-shadow: 0 0 0 3px rgba(224,103,103,0.35); }

  /* 2. Le montant barré. line-through à 0.65 d'opacité sur un fond sombre passe
        sous le seuil de lisibilité : on remonte, le chiffre doit rester lisible
        — barré ne veut pas dire caché, il veut dire « non corroboré ». */
  .ent-card-amount-conteste { opacity: 0.8; }

  /* Une photo de ticket est un aplat blanc : à pleine luminosité elle éblouit
     dans une interface sombre. On la calme, et on la rend au survol/focus. */
  .ent-vignette img { filter: brightness(0.92); }
  .ent-vignette-lg img { filter: none; }

  /* Le fond blanc des vignettes de justificatif reste blanc en dark : c'est du
     papier scanné, pas une surface d'interface. */
  .ent-vignette-lg { background: var(--surface-sunken); }

  .ent-vignette-btn { background: rgba(0,0,0,0.7); }

  .ent-card-cta,
  .ent-btn-facturer,
  .ent-doublon-keep,
  .ent-page-add-btn,
  .ent-form-submit { color: var(--accent-foreground); }
  .ent-form-submit.success,
  .ent-form-submit.error,
  .ent-confirm-yes { color: #0d1117; }

  .ent-toast { background: var(--surface-2); color: var(--ink-1); border: 1px solid var(--line-2); }
  .ent-toast-error { background: var(--danger); color: #0d1117; border-color: var(--danger); }

  /* Le pointillé de la suggestion disparaît sur fond sombre : on l'appuie. */
  .ent-suggest-btn { border-color: var(--accent); }
  .ent-add-ligne { border-color: var(--line-3); }

  .ent-file-row.is-erreur { background: var(--danger-soft); }
  .ent-file-thumb img { filter: brightness(0.92); }

  /* Sur fond sombre, --danger-soft/--warn-soft sont des calques translucides :
     le texte du motif et l'id du fichier orphelin doivent rester lisibles
     par-dessus — ce sont eux qui portent la consigne. */
  .ent-depot-recap-ko { background: var(--danger-soft); }
  .ent-depot-recap-ko .ent-depot-recap-sub { color: var(--ink-1); }
  .ent-file-row.is-erreur .ent-file-detail-txt { color: var(--ink-2); }
  .ent-file-orphelin { background: var(--warn-soft); color: var(--warn); }
}

/* =========================================================
   17. ACCESSIBILITÉ — mouvement réduit
   ========================================================= */
@media (prefers-reduced-motion: reduce) {
  .ent-page,
  .ent-page.closing,
  .ent-page.closing-down,
  .ent-depot-sheet, .ent-verif-sheet, .ent-facture-sheet, .ent-doublon-sheet,
  .ent-confirm-box, .ent-file-row, .ent-ligne, .ent-toast, .ent-depot-recap {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
  /* Exception : la barre indéterminée EST l'information « envoi en cours ».
     La figer ferait passer un upload en vol pour un upload bloqué. On la garde,
     simplement plus lente. */
  .ent-file-row.is-envoi .ent-file-bar-fill {
    animation-duration: 2.4s !important;
    animation-iteration-count: infinite !important;
  }
}
