/* ============================================================
   OTRA Studio — components.css
   Kit de composants du livrable 1. Consomme uniquement les
   tokens de tokens.css. Aucune couleur, police ou rayon en dur.
   Aucun état hover-only : chaque hover a son équivalent :active.
   ============================================================ */

/* --- base --- */
* { box-sizing: border-box; }
html, body {
  margin: 0; padding: 0;
  background: var(--surface);
  color: var(--txt);
  font-family: var(--ff);
  font-size: var(--fs-sm);            /* bureau */
  line-height: 1.45;
}
.terrain { font-size: var(--fs-md); }   /* variante terrain */
h1, h2 { font-family: var(--ff-display); font-weight: 600; margin: 0; }
h3, h4 { margin: 0; font-weight: 600; }
a { color: var(--accent-text); }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
::selection { background: var(--accent-soft); }
.num { font-variant-numeric: tabular-nums; }
.hero { font-family: var(--ff-display); font-weight: 600; font-size: var(--fs-2xl); line-height: 1.1; }
.dim { color: var(--txt-dim); }
.kicker {
  font-size: var(--fs-xs); font-weight: 600; letter-spacing: .09em;
  text-transform: uppercase; color: var(--txt-dim);
}

/* --- boutons --- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--tap); padding: 0 16px;
  border-radius: var(--r-sm); border: 1px solid transparent;
  font: 600 var(--fs-sm)/1 var(--ff); cursor: pointer;
  background: transparent; color: var(--txt);
  text-decoration: none;
}
.btn-primary { background: var(--accent); color: var(--on-accent); }
.btn-primary:hover { background: var(--accent-strong); }
.btn-primary:active { background: hsl(var(--brand-h) var(--brand-s) calc(var(--brand-l) - 8%)); }
.btn-secondary { border-color: var(--line); background: var(--surface-2); }
.btn-secondary:hover, .btn-secondary:active { background: var(--surface-3); }
.btn-ghost { color: var(--txt-dim); }
.btn-ghost:hover, .btn-ghost:active { background: var(--surface-3); color: var(--txt); }
.btn-danger { border-color: var(--danger); color: var(--danger); background: transparent; }
.btn-danger:hover, .btn-danger:active { background: var(--danger-soft); }
.btn[disabled] { opacity: .45; pointer-events: none; }
.btn-terrain { min-height: var(--tap-primary); font-size: var(--fs-md); padding: 0 20px; }
.btn-block { width: 100%; }

/* --- badges & états — le libellé porte toujours l'information,
       la couleur n'est qu'un renfort (daltonisme) --- */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 999px;
  font: 600 var(--fs-xs)/1.5 var(--ff);
  border: 1px solid var(--line); color: var(--txt-dim);
  white-space: nowrap;
}
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge-brouillon { border-style: dashed; }
.badge-envoye  { border-color: var(--accent-line); color: var(--accent-text); background: var(--accent-soft); }
.badge-confirme { border-color: transparent; color: var(--bio); background: var(--bio-soft); }
.badge-refuse  { border-color: transparent; color: var(--danger); background: var(--danger-soft); }
.badge-expire  { border-color: transparent; color: var(--warn); background: var(--warn-soft); }
.badge-bio     { border-color: transparent; color: var(--bio); background: var(--bio-soft); }
.badge-bio::before { content: "🌿"; width: auto; height: auto; background: none; font-size: var(--fs-xs); }
.badge-plain::before { display: none; }

/* --- alerte-phrase actionnable (cover) --- */
.alert {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border-radius: var(--r);
  background: var(--surface-2); border: 1px solid var(--line);
  border-left: 3px solid var(--warn);
}
.alert.alert-danger { border-left-color: var(--danger); }
.alert .spacer { flex: 1; }

/* --- formulaires --- */
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.field label { font-weight: 600; font-size: var(--fs-sm); }
.input {
  min-height: var(--tap); padding: 0 12px;
  border-radius: var(--r-sm); border: 1px solid var(--txt-dim);
  background: var(--surface-2); color: var(--txt);
  font: 400 var(--fs-sm) var(--ff);
}
.input:focus { border-color: var(--focus); outline: 2px solid var(--focus); outline-offset: 1px; }
.field-error .input { border-color: var(--danger); }
.field-error .msg { color: var(--danger); font-size: var(--fs-xs); }


/* --- bouton compact : la seule dérogation aux 44 px, et elle se referme ---
   Les barres denses de bureau ont besoin d'un bouton court. La contrainte
   « cible tactile ≥ 44 px » du brief reste vraie là où elle compte : sous
   640 px, le bouton compact redevient un bouton. */
.btn-compact { min-height: 36px; padding: 0 12px; font-size: var(--fs-sm); }
@media (max-width: 640px) { .btn-compact { min-height: var(--tap); padding: 0 16px; font-size: var(--fs-sm); } }

/* --- segments (états) --- */
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden; }
.seg-opt {
  min-height: 36px; padding: 0 14px; display: inline-flex; align-items: center;
  background: var(--surface-2); color: var(--txt-dim); border: 0; cursor: pointer;
  font: 600 var(--fs-sm) var(--ff);
}
.seg-opt + .seg-opt { border-left: 1px solid var(--line); }
.seg-opt.on { background: var(--surface-3); color: var(--txt); box-shadow: inset 0 -2px 0 var(--accent); }
.seg-opt:hover, .seg-opt:active { color: var(--txt); }

/* --- cartes & KPI --- */
/* Denis, 23/08 : « change le style dans devis c'est pas bon, fait à
   l'apple », puis « adapte le style ». Ce qui a été essayé sur l'éditeur
   descend ici, dans les composants que 36 écrans partagent.

   Une carte ne se dessine plus au trait : elle se POSE. Le filet gris qui
   l'entourait la faisait ressembler à une cellule de tableur ; une ombre
   courte et un rayon plus franc la font ressembler à un objet. */
.card {
  background: var(--surface-2); border: 0;
  border-radius: var(--r-lg); padding: 20px;
  box-shadow: var(--shadow);
}
.kpi .kicker { margin-bottom: 6px; }
.kpi .hero { color: var(--txt); }
.kpi .meta { color: var(--txt-dim); font-size: var(--fs-xs); margin-top: 4px; }
.kpi-bio .hero { color: var(--bio); }

/* --- ligne de liste canonique : 60px, 2 lignes max, badges à droite.
       Sous 640px elle devient carte empilée (jamais une grille 2 col.). --- */
.rowlist { display: flex; flex-direction: column; }
.row {
  display: flex; align-items: center; gap: 14px;
  min-height: 60px; padding: 12px 16px;
  border-bottom: 1px solid var(--line-soft);
  background: var(--surface-2);
}
.row:hover, .row:active { background: var(--surface-3); }
.row .main { flex: 1; min-width: 0; }
.row .t { font-weight: 600; line-height: 1.35;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.row .s { color: var(--txt-dim); font-size: var(--fs-sm); line-height: 1.4;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* les chiffres s'alignent sur leurs colonnes : un montant qui danse d'une
   ligne à l'autre ne se compare pas d'un coup d'œil */
.row .num { text-align: right; font-variant-numeric: tabular-nums; }
.rowlist.card { padding: 0; overflow: hidden; }
@media (max-width: 640px) {
  .row { flex-wrap: wrap; row-gap: 8px; }
  .row .num { text-align: left; }
  .row .act { width: 100%; }
  .row .act .btn { width: 100%; min-height: 48px; }
}


/* --- densité de liste : UNE décision du kit, pas une par écran ---------
   Le kit fixe la ligne canonique à 60 px. Deux situations la resserrent
   légitimement : une liste dans une modale (on choisit vite, on ferme), et
   une liste de choix dense signalée par `.rowlist.dense`. Aucun écran ne
   règle plus une hauteur à la main : les écarts se voyaient. */
.dialog .row, .rowlist.dense .row { min-height: 44px; padding: 6px 12px; gap: 10px; }
.dialog .row .t, .rowlist.dense .row .t { font-size: var(--fs-sm); }

/* --- barre de filtres (anatomie fixe du kit §6) --- */
.filters { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 10px 0; }
.filters .search { flex: 1 1 200px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: 999px;
  background: var(--surface-3); border: 1px solid var(--line);
  font-size: var(--fs-xs); color: var(--txt);
}
.chip button { border: 0; background: none; color: var(--txt-dim); cursor: pointer; font-size: var(--fs-xs);
  min-width: 24px; min-height: 24px; }

/* --- onglets de page --- */
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); }
.tab {
  min-height: var(--tap); padding: 0 16px;
  display: inline-flex; align-items: center; gap: 6px;
  border: 0; background: none; color: var(--txt-dim); cursor: pointer;
  font: 600 var(--fs-sm) var(--ff);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tab.on { color: var(--txt); border-bottom-color: var(--accent); }
.tab:hover, .tab:active { color: var(--txt); }
.tab .count {
  background: var(--accent-soft); color: var(--accent-text);
  border-radius: 999px; font-size: var(--fs-xs); padding: 1px 7px;
}

/* --- barre basse mobile — 4 destinations, 56px, pouce --- */
.tabbar {
  position: sticky; bottom: 0; z-index: 10;
  display: grid; grid-template-columns: repeat(4, 1fr);
  background: var(--surface-2); border-top: 1px solid var(--line);
}
.tabbar a {
  min-height: var(--tap-primary);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  color: var(--txt-dim); text-decoration: none; font: 600 var(--fs-xs) var(--ff);
  position: relative;
}
.tabbar a.on { color: var(--accent-text); }
.tabbar a:active { background: var(--surface-3); }
.tabbar .ico { font-size: var(--fs-lg); line-height: 1; }
.tabbar .dot {
  position: absolute; top: 8px; right: calc(50% - 16px);
  min-width: 16px; height: 16px; border-radius: 999px;
  background: var(--danger); color: var(--surface);
  font-size: var(--fs-xs); font-weight: 700; display: flex; align-items: center; justify-content: center;
}

/* --- modale & toast (remplacent confirm()/alert()) --- */
/* ---------- les dialogues ----------

   Denis, 23/08 : « les fenêtres de contexte type mail ne sont pas bonnes,
   trop étroites, pas adaptables au mode ordi, tablette, mobile first ».

   Il y avait UNE largeur — 440 px — pour tous les dialogues et tous les
   écrans. Sur un écran de 1600 px, écrire un mot au client dans une fente
   de 440 px ; sur un téléphone, une carte flottante avec du vide autour
   alors que l'écran entier est disponible.

   Mobile d'abord : le dialogue est une FEUILLE qui monte du bas, pleine
   largeur, collée au bord, coins arrondis en haut seulement — le geste
   qu'attend un pouce. À partir de la tablette il redevient une carte
   centrée, et il s'élargit avec l'écran.

   Chaque dialogue peut demander plus : `.dialog.large` pour ceux qui
   portent du texte long — écrire au client, déposer des pièces, une photo
   et sa légende. La largeur est un jeton, pas une valeur en dur. */
.dialog-backdrop {
  position: fixed; inset: 0; background: rgb(0 0 0 / .5);
  display: flex; align-items: flex-end; justify-content: center; padding: 0;
  --dlg-max: 100%;
}
.dialog {
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-lg) var(--r-lg) 0 0; border-bottom: 0;
  padding: 20px 18px calc(18px + env(safe-area-inset-bottom, 0px));
  max-width: var(--dlg-max); width: 100%;
  box-shadow: var(--shadow-lg);
  /* Un popup plus haut que l'écran (le remplissage client, sur téléphone)
     enterrait Enregistrer/Annuler hors de portée — Denis, 19/08. Le corps
     défile, les boutons restent visibles, TOUS les dialogues en héritent. */
  max-height: 92dvh; display: flex; flex-direction: column;
}

/* tablette : la carte revient au centre */
@media (min-width: 600px) {
  .dialog-backdrop { align-items: center; padding: 24px; --dlg-max: 620px; }
  .dialog { border-radius: var(--r-lg); border-bottom: 1px solid var(--line);
    padding: 22px; max-height: calc(100dvh - 48px); }
  .dialog-backdrop:has(.dialog.large) { --dlg-max: 760px; }
}

/* ordinateur : on cesse d'écrire dans une fente */
@media (min-width: 1024px) {
  .dialog-backdrop { --dlg-max: 720px; padding: 32px; }
  .dialog-backdrop:has(.dialog.large) { --dlg-max: 960px; }
  .dialog { padding: 26px; }
}

/* le repli pour les navigateurs sans :has() — la classe est aussi posée
   sur le fond, en JS, au moment du rendu */
.dialog-backdrop.grand { --dlg-max: 760px; }
@media (min-width: 1024px) { .dialog-backdrop.grand { --dlg-max: 960px; } }

/* un texte long mérite de la place : la zone de saisie grandit avec la
   fenêtre au lieu de rester sur ses 16 lignes */
/* Élargir la fenêtre ne servait à rien : les champs ne suivaient pas.
   Un <textarea> sans largeur prend ses 20 colonnes par défaut — 210 px —
   quelle que soit la place autour. Dans un dialogue de 960 px, on écrivait
   toujours dans une colonne de 210. C'était vrai depuis le début, à toutes
   les tailles ; l'élargissement l'a seulement rendu visible.

   Et `padding: 0 12px` convient à une ligne de saisie, pas à un pavé de
   texte : les mots commençaient collés au bord haut. */
.dialog .input, .dialog select.input, .dialog textarea.input {
  width: 100%; box-sizing: border-box;
}
.dialog textarea.input { padding: 10px 12px; line-height: 1.5; min-height: 96px; }
.dialog.large textarea.input { min-height: 34vh; resize: vertical; }
/* la ligne de saisie garde sa hauteur de cible ; le pavé la dépasse */
.dialog input.input, .dialog select.input { min-height: var(--tap); }
.dialog h3 { font-family: var(--ff-display); font-size: var(--fs-lg); margin-bottom: 8px; flex: none; }
.dialog .corps-defile { overflow-y: auto; min-height: 0; flex: 1;
  margin: 0 -6px; padding: 0 6px; overscroll-behavior: contain; }
.dialog .actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px;
  flex: none; border-top: 1px solid var(--line-soft); padding-top: 12px; }
.toast {
  display: inline-flex; align-items: center; gap: 14px;
  background: var(--surface-3); border: 1px solid var(--line);
  border-radius: var(--r); padding: 10px 14px; box-shadow: var(--shadow);
}
.toast .undo { color: var(--accent-text); font-weight: 600; background: none; border: 0; cursor: pointer; min-height: var(--tap); }

/* --- topbar simple (fil d'ariane + état de sauvegarde) --- */
.topbar {
  display: flex; align-items: center; gap: 12px;
  min-height: 52px; padding: 0 16px;
  background: var(--surface-2); border-bottom: 1px solid var(--line);
}
.crumb { color: var(--txt-dim); }
.crumb b { color: var(--txt); font-weight: 600; }
.savebadge { margin-left: auto; color: var(--bio); font-size: var(--fs-xs); font-weight: 600; }

/* ============================================================
   Coquille — sidebar par profil + contenu (livrable 2)
   L'espace du profil est déplié au chargement, les autres repliés,
   jamais masqués. Sous 900px la sidebar laisse place à la barre basse.
   ============================================================ */
.app { display: grid; grid-template-columns: 248px 1fr; min-height: 100vh; }
.app > main, .app > .zone-main { min-width: 0; display: flex; flex-direction: column; }
.side {
  position: sticky; top: 0; height: 100vh;
  display: flex; flex-direction: column;
  background: var(--surface-2); border-right: 1px solid var(--line);
  overflow-y: auto;
}
.side-brand { display: flex; align-items: center; gap: 10px; padding: 18px 16px 14px; border-bottom: 1px solid var(--line-soft); }
.side-brand .logo {
  width: 34px; height: 34px; border-radius: 10px;
  background: var(--accent); color: var(--on-accent);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--ff-display); font-weight: 600; font-size: var(--fs-lg);
}
.side-brand .t1 { font-family: var(--ff-display); font-size: var(--fs-md); line-height: 1.1; }
.side-brand .t2 { font-size: var(--fs-xs); color: var(--txt-dim); letter-spacing: .06em; text-transform: uppercase; }
.side-nav { flex: 1; padding: 10px 8px; }
.acc { margin-bottom: 2px; }
.acc-h {
  display: flex; align-items: center; justify-content: space-between; width: 100%;
  border: 0; background: none; cursor: pointer;
  padding: 9px 10px; border-radius: var(--r-sm);
  gap: 9px;
  color: var(--txt-dim); font: 600 var(--fs-xs)/1 var(--ff);
  letter-spacing: .09em; text-transform: uppercase;
}
.acc-h .acc-ht { display: flex; align-items: center; gap: 9px; min-width: 0; }
.acc-h .ico { flex: none; width: var(--ico-rail); text-align: center; font-size: var(--fs-xs); line-height: 1; opacity: .8; }
.acc-h:hover, .acc-h:active { background: var(--surface-3); color: var(--txt); }
.acc-h .chev { transition: transform .18s; font-size: var(--fs-xs); }
.acc.open .acc-h { color: var(--txt); }
.acc.open .acc-h .chev { transform: rotate(90deg); }
.acc-b { display: none; padding: 2px 0 6px; }
.acc.open .acc-b { display: block; }
.acc-i {
  display: flex; align-items: center; gap: 9px;
  min-height: var(--nav-h); padding: 0 10px; border-radius: var(--r-sm);
  color: var(--txt-dim); text-decoration: none; font-size: var(--fs-nav);
}
/* Le pictogramme n'est pas une décoration : c'est une COLONNE. Largeur fixe,
   donc tous les libellés démarrent au même x et l'œil descend le rail au lieu
   de relire douze mots. C'est le seul écart de fond entre notre barre et celle
   que Denis trouve plus lisible (.ot-sb-link .ico, /otra/entrepreneur).
   Il ne porte jamais l'information seul — le libellé reste, toujours. */
.acc-i .ico {
  flex: none; width: var(--ico-rail); text-align: center;
  font-size: var(--fs-md); line-height: 1; opacity: .85;
}
.acc-i.on .ico, .acc-i:hover .ico { opacity: 1; }
.acc-i:hover, .acc-i:active { background: var(--surface-3); color: var(--txt); }
.acc-i.on { background: var(--accent-soft); color: var(--txt); font-weight: 600; }
.acc-i .count {
  margin-left: auto; background: var(--accent-soft); color: var(--accent-text);
  border-radius: 999px; font-size: var(--fs-xs); font-weight: 700; padding: 1px 7px;
}
.acc-i .v2 { margin-left: auto; font-size: var(--fs-xs); color: var(--txt-dim); letter-spacing: .06em; }
.side-foot { padding: 12px 14px; border-top: 1px solid var(--line-soft); display: flex; align-items: center; gap: 10px; }
.side-foot .ava {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--surface-3); border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-xs); font-weight: 700;
}
.side-foot .who { flex: 1; min-width: 0; }
.side-foot .who .n { font-weight: 600; font-size: var(--fs-sm); }
.side-foot .who .r { color: var(--txt-dim); font-size: var(--fs-xs); }
.contenu { padding: 20px; max-width: 1280px; width: 100%; margin: 0 auto; flex: 1; }
@media (max-width: 900px) {
  .app { grid-template-columns: 1fr; }
  .side { display: none; }
  .contenu { padding: 14px; }
}
@media (min-width: 901px) { .tabbar { display: none; } }

/* --- Plan complet (☰) — grille plate cherchable, remplace les accordéons --- */
.plan-overlay {
  position: fixed; inset: 0; z-index: 60;
  background: var(--surface); overflow-y: auto; padding: 18px 16px 40px;
}
.plan-overlay .head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.plan-overlay h2 { font-size: var(--fs-xl); flex: 1; }
.plan-grp { margin: 18px 0 6px; }
.plan-i {
  display: flex; align-items: center; gap: 10px;
  min-height: var(--tap); padding: 0 10px; border-radius: var(--r-sm);
  color: var(--txt); text-decoration: none; font-size: var(--fs-md);
}
.plan-i:hover, .plan-i:active { background: var(--surface-3); }

/* --- bandeau IA — une suggestion à la fois, jamais une modale --- */
.ia-band {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  border: 1px solid var(--accent-line); background: var(--accent-soft);
  border-radius: var(--r); padding: 12px 14px;
}
.ia-tag {
  background: var(--accent); color: var(--on-accent);
  font: 700 var(--fs-xs)/1 var(--ff); letter-spacing: .08em;
  padding: 4px 7px; border-radius: var(--r-sm); flex: none;
}
.ia-band .txt { flex: 1; min-width: 200px; }
.ia-band .acts { display: flex; gap: 8px; }

/* --- tables de données (éditeur, synthèse, quantitatif) --- */
/* Le tableau cesse d'être un tableau de GESTION — lignes serrées, filets
   partout, tout au même poids — pour devenir un DOCUMENT : de l'air entre
   les lignes, un seul filet horizontal, les montants alignés sur leurs
   chiffres, et la section qui se détache sans crier.
   Essayé sur l'éditeur de devis le 23/08, adopté partout ensuite. */
.table { width: 100%; border-collapse: separate; border-spacing: 0; }
.table th {
  text-align: left; padding: 10px 12px;
  font-size: var(--fs-xs); font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--txt-dim); border-bottom: 1px solid var(--line);
  white-space: nowrap; background: transparent;
}
.table td { padding: 12px; border-bottom: 1px solid var(--line-soft);
  vertical-align: top; font-size: var(--fs-sm); line-height: 1.45; }
.table tbody tr:hover > td { background: var(--surface-3); }
.table .num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.table th.num { text-align: right; }
/* une section n'est pas une bande grise : c'est un titre, et un trait */
.table tr.sec td { background: transparent; font-weight: 600;
  padding-top: 22px; border-bottom: 1.5px solid var(--txt); }
.table tr.sec b { font-size: var(--fs-md); letter-spacing: -.01em; }
.table tr.sous-sec > td { background: transparent; padding-top: 14px;
  padding-left: 26px; border-bottom: 1px solid var(--line); }
.table tr.tot td { font-weight: 700; border-top: 2px solid var(--line); border-bottom: 0;
  padding-top: 14px; }
.table .drag { color: var(--txt-faint); cursor: grab; user-select: none; width: 26px; }
.table .plus-ici { padding: 6px 12px 14px; }
.table .plus-ici button { min-height: 34px; padding: 0 12px;
  border: 1px dashed var(--line); border-radius: var(--r-sm);
  background: transparent; color: var(--txt-dim); font-size: var(--fs-xs); cursor: pointer; }
.table .plus-ici button:hover { border-color: var(--accent); color: var(--accent-text); }
.pa-manquant {
  display: inline-flex; padding: 2px 8px; border-radius: var(--r-sm);
  background: var(--danger-soft); color: var(--danger); font-weight: 600; font-size: var(--fs-xs);
  white-space: nowrap;
}
.auto-tag { font-size: var(--fs-xs); color: var(--txt-dim); border: 1px solid var(--line); border-radius: 999px; padding: 1px 6px; margin-left: 4px; }

/* --- barres d'avancement --- */
.bar { height: 8px; border-radius: 999px; background: var(--surface-3); overflow: hidden; }
.bar > i { display: block; height: 100%; background: var(--accent); }
.bar-l { display: flex; justify-content: space-between; font-size: var(--fs-xs); color: var(--txt-dim); margin-top: 4px; }

/* --- kanban (pipeline chantiers, tâches) --- */
.kb { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(230px, 1fr); gap: 12px; overflow-x: auto; align-items: start; padding-bottom: 6px; }
.kb-col { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r); padding: 10px; }
.kb-col > .kicker { display: flex; justify-content: space-between; margin-bottom: 8px; }
.kb-card {
  background: var(--surface-3); border: 1px solid var(--line-soft);
  border-radius: var(--r-sm); padding: 10px 12px; margin-bottom: 8px;
}
.kb-card .t { font-weight: 600; }
.kb-card .s { color: var(--txt-dim); font-size: var(--fs-sm); margin-top: 2px; }
.kb-drop { border: 2px dashed var(--accent-line); border-radius: var(--r-sm); padding: 10px; text-align: center; color: var(--txt-dim); font-size: var(--fs-xs); }

/* --- timeline --- */
.tl { display: grid; grid-template-columns: 200px repeat(4, 1fr); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.tl > div { padding: 10px 12px; border-bottom: 1px solid var(--line-soft); border-right: 1px solid var(--line-soft); background: var(--surface-2); min-height: 52px; }
.tl > .h { background: var(--surface-3); font-size: var(--fs-xs); font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--txt-dim); min-height: 0; }
.tl-bar { position: relative; height: 24px; border-radius: 999px; background: var(--surface-3); overflow: hidden; margin-top: 4px; }
.tl-bar > i { position: absolute; inset: 0; background: var(--accent-soft); }
.tl-bar > b { position: absolute; inset: 0; display: flex; align-items: center; padding: 0 10px; font-size: var(--fs-xs); font-weight: 600; white-space: nowrap; }
.tl-bar > i.fill { background: var(--accent); opacity: .55; }

/* --- semaine équipe --- */
.wk { display: grid; grid-template-columns: 110px repeat(5, 1fr); gap: 1px; background: var(--line-soft); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.wk > div { background: var(--surface-2); padding: 8px 10px; min-height: 46px; font-size: var(--fs-sm); }
.wk > .h { background: var(--surface-3); font-weight: 600; min-height: 0; }
.wk .cell-conge { color: var(--txt-dim); font-style: italic; }
.wk .cell-conflit { outline: 2px solid var(--danger); outline-offset: -2px; color: var(--danger); font-weight: 600; }
.wk .cell-libre { color: var(--txt-faint); }

/* --- journal de chantier --- */
.jr-day { display: flex; gap: 10px; align-items: baseline; margin: 16px 0 6px; }
.jr {
  display: flex; gap: 12px; padding: 10px 0;
  border-bottom: 1px solid var(--line-soft);
}
.jr .ico {
  flex: none; width: 34px; height: 34px; border-radius: var(--r-sm);
  background: var(--surface-3); border: 1px solid var(--line-soft);
  display: flex; align-items: center; justify-content: center; font-size: var(--fs-md);
}
.jr .main { flex: 1; min-width: 0; }
.jr .meta { color: var(--txt-dim); font-size: var(--fs-xs); margin-top: 2px; }

/* --- barre d'actions terrain collée en bas (cockpit mobile) --- */
.actbar {
  position: sticky; bottom: 0; z-index: 10;
  display: flex; gap: 8px; padding: 10px 12px;
  background: var(--surface-2); border-top: 1px solid var(--line);
}
.actbar .btn { flex: 1; min-height: var(--tap-primary); }

/* --- documents / dossier --- */
.doc-row {
  display: flex; align-items: center; gap: 12px;
  min-height: 48px; padding: 6px 12px;
  border-bottom: 1px solid var(--line-soft);
}
.doc-row .t { flex: 1; min-width: 0; }
.doc-row .s { color: var(--txt-dim); font-size: var(--fs-xs); }

/* ============================================================
   Cohabitation avec le Bootstrap d'Odoo (website.layout).
   Nos classes partagent des noms avec lui (.alert, .row, .table,
   .badge, .btn, .toast) ; chargées après, elles gagnent à
   spécificité égale — ces règles neutralisent ce que Bootstrap
   ajoute et que nous ne déclarions pas, y compris sa règle de
   cellules « .table > :not(caption) > * > * » plus spécifique
   que « .table td ».
   ============================================================ */
.alert { color: var(--txt); background-image: none; margin-bottom: 0; }
.row { margin: 0; }
.row > * { padding: 0; width: auto; max-width: none; flex: initial; }
.row .main { flex: 1; }
.table { color: var(--txt); margin-bottom: 0; }
.table > :not(caption) > * > * {
  background-color: transparent; box-shadow: none; color: inherit;
  padding: 9px 10px; border-bottom: 1px solid var(--line-soft);
}
.table thead th { border-bottom: 1px solid var(--line); }
.table tr.sec > * { background: var(--surface-3); }
.table tr.tot > * { border-top: 2px solid var(--line); border-bottom: 0; }
.toast { width: auto; max-width: none; font-size: inherit; }
.badge { line-height: 1.5; }

/* --- note de chantier (méta : source des données, périmètres, gaps) --- */
.note-pv {
  border-left: 3px solid var(--accent); padding: 10px 14px;
  background: var(--surface-2); border-radius: 0 var(--r) var(--r) 0;
  color: var(--txt-dim); font-size: var(--fs-sm); max-width: 88ch;
}

/* --- en-tête de page standard --- */
.page-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 14px; }
.page-head h1 { font-size: var(--fs-xl); }
.page-head .sub { color: var(--txt-dim); }
.page-head .acts { margin-left: auto; display: flex; gap: 8px; }

/* --- picker unifié — balisage repris de la maquette (livrable 12,
       section « Dans l'éditeur — un picker, tout le catalogue ») --- */
.pk-barre { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 12px; }
.pk-barre .input { height: 44px; flex: 1; min-width: 200px; }
.pk-seg { display: flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; flex: none; }
.pk-seg button { height: 44px; padding: 0 14px; font-size: var(--fs-sm); font-weight: 600; border: 0;
  border-left: 1px solid var(--line); background: none; color: var(--txt-dim); cursor: pointer; white-space: nowrap; }
.pk-seg button:first-child { border-left: 0; }
.pk-seg button.on { background: var(--accent); color: var(--on-accent); font-weight: 700; }
.pk-liste { background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px;
  overflow: hidden auto; max-height: 300px; }
.pk-row { display: flex; align-items: center; gap: 12px; padding: 0 16px; min-height: var(--row-h); width: 100%;
  border: 0; border-bottom: 1px solid var(--line-soft); background: none; color: inherit;
  cursor: pointer; text-align: left; font: inherit; }
.pk-row:last-child { border-bottom: 0; }
.pk-row:hover, .pk-row:focus-visible { background: var(--surface-3); }
.pk-badge { flex: none; font-size: var(--fs-xs); font-weight: 800; padding: 3px 8px; border-radius: 6px;
  white-space: nowrap; background: var(--surface-3); color: var(--txt-dim); }
.pk-badge-ouvrage { background: var(--accent-soft); color: var(--accent-text); }
.pk-badge-verrou { background: hsl(210 47% 44% / .16); color: hsl(210 40% 38%); }
[data-theme="dark"] .pk-badge-verrou { color: hsl(210 45% 66%); }
.pk-corps { flex: 1; min-width: 0; }
.pk-titre { font-size: var(--fs-sm); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pk-info { font-size: var(--fs-xs); color: var(--txt-dim); }
.pk-alerte { color: var(--accent-text); }
.pk-prix { flex: none; font-size: var(--fs-sm); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ============================================================
   Paquet 2 · document 1 — « Tokens & composants nouveaux »
   (design/v2/OTRA Tokens Additions.dc.html — codé au pixel)
   ============================================================ */

/* -- 1 · case de liste .otra-check --------------------------------
   20×20 visuel, zone tactile 44×44 (pseudo-élément), coche ✓ et
   tiret − DESSINÉS. En clair, l'or passe au bronze #8A6F4B. */
.otra-check {
  --oc-acc: var(--accent);
  appearance: none; -webkit-appearance: none;
  position: relative; flex: none;
  width: 20px; height: 20px; margin: 0;
  border: 1.5px solid var(--txt-dim); border-radius: 5px;
  background: transparent; cursor: pointer;
  display: inline-grid; place-items: center; vertical-align: middle;
}
[data-theme="light"] .otra-check { --oc-acc: #8A6F4B; }
.otra-check::before {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 44px; height: 44px; transform: translate(-50%, -50%);
}
.otra-check:hover, .otra-check:focus-visible { border-color: var(--oc-acc); }
.otra-check:focus-visible { outline: 2px solid var(--oc-acc); outline-offset: 2px; }
.otra-check:checked, .otra-check.partielle {
  border-color: var(--oc-acc); background: var(--oc-acc);
}
.otra-check:checked::after {
  content: ""; width: 10px; height: 5px; margin-top: -2px;
  border: 2px solid var(--on-accent); border-top: 0; border-right: 0;
  transform: rotate(-45deg);
}
[data-theme="light"] .otra-check:checked::after { border-color: #fff; }
.otra-check.partielle::after {
  content: ""; width: 10px; height: 2px; background: var(--on-accent);
}
[data-theme="light"] .otra-check.partielle::after { background: #fff; }
.otra-check:disabled { opacity: .4; cursor: not-allowed; }
/* ligne cochée = TROIS signaux : case ✓ + fond + filet gauche 3px */
.row.otra-sel { background: rgba(201, 169, 125, .07); box-shadow: inset 3px 0 0 var(--accent); }
tr.otra-sel { background: rgba(201, 169, 125, .07); }
tr.otra-sel > td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
[data-theme="light"] .row.otra-sel { box-shadow: inset 3px 0 0 #8A6F4B; }
[data-theme="light"] tr.otra-sel > td:first-child { box-shadow: inset 3px 0 0 #8A6F4B; }

/* -- 2 · barre d'actions de masse .otra-bulkbar -------------------
   REMPLACE la barre de filtres au même emplacement — jamais un layer
   flottant. Filet bas or 2px, apparition 120 ms. */
.otra-bulkbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--surface-3); border-bottom: 2px solid var(--accent);
  border-radius: var(--r-sm, 8px); padding: 8px 12px; min-height: 56px;
  animation: otra-bulk-in 120ms ease-out;
}
[data-theme="light"] .otra-bulkbar { background: #E9E4D8; border-bottom-color: #8A6F4B; }
@keyframes otra-bulk-in { from { opacity: 0; } to { opacity: 1; } }
.otra-bulkbar .compte { display: inline-flex; align-items: center; gap: 8px; font-weight: 700; font-size: var(--fs-sm); }
.otra-bulkbar .pastille {
  display: inline-grid; place-items: center; min-width: 26px; height: 26px;
  padding: 0 7px; border-radius: 13px; background: var(--accent);
  color: var(--on-accent); font-variant-numeric: tabular-nums; font-size: var(--fs-sm); font-weight: 800;
}
[data-theme="light"] .otra-bulkbar .pastille { background: #8A6F4B; color: #fff; }
.otra-bulkbar .btn.destructive { border: 1px solid #E07856; color: #E07856; background: none; }
[data-theme="light"] .otra-bulkbar .btn.destructive { border-color: #B4532F; color: #B4532F; }
@media (max-width: 640px) {
  .otra-bulkbar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    border-radius: 0; border-top: 1px solid var(--line); }
}

/* -- 3 · cellule éditable .otra-cell ------------------------------
   Contrat clavier unique (clic/F2 · Entrée · Tab · ↑↓ · Échap) porté
   par OTRA.celluleEditable (core.js). Coin ambre = non persisté. */
.otra-cell {
  position: relative; padding: 4px 8px; border-radius: 6px;
  border: 1px solid transparent; cursor: text; min-height: 32px;
  display: inline-flex; align-items: center; min-width: 64px;
  font-variant-numeric: tabular-nums;
}
.otra-cell:not(.edition):not(.verrou):not(.recalcul):hover { border-color: var(--line); }
.otra-cell:not(.edition):not(.verrou):not(.recalcul):not(.adaptee):hover::after {
  content: "✎"; position: absolute; right: 4px; top: 50%;
  transform: translateY(-50%); font-size: var(--fs-xs); color: var(--txt-faint);
}
.otra-cell.edition { border: 2px solid var(--accent); padding: 3px 7px; cursor: auto; }
[data-theme="light"] .otra-cell.edition { border-color: #8A6F4B; }
.otra-cell input {
  border: 0; background: none; color: inherit; font: inherit;
  width: 100%; min-width: 48px; padding: 0; outline: none;
  font-variant-numeric: tabular-nums;
}
.otra-cell.non-persiste::before {
  content: ""; position: absolute; top: 0; right: 0;
  border-style: solid; border-width: 0 6px 6px 0;
  border-color: transparent #C9A961 transparent transparent;
}
.otra-cell.recalcul { color: var(--txt-dim); }
.otra-cell.recalcul::after {
  content: "⟳"; position: absolute; right: 4px; top: 50%;
  transform: translateY(-50%); font-size: var(--fs-xs);
}
.otra-cell.verrou { cursor: not-allowed; color: var(--txt-dim); }
.otra-cell.verrou::after {
  content: "🔒"; position: absolute; right: 4px; top: 50%;
  transform: translateY(-50%); font-size: var(--fs-xs);
}
.otra-cell.adaptee::after { content: "◇"; margin-left: 5px; color: #C9A961; font-size: var(--fs-xs); }
[data-theme="light"] .otra-cell.adaptee::after { color: #7A6524; }
.otra-cell.erreur { border: 2px solid #E07856; }
.otra-cell .msg-erreur {
  position: absolute; left: 0; top: calc(100% + 2px); z-index: 5;
  background: var(--surface-2); border: 1px solid #E07856; color: #E07856;
  font-size: var(--fs-xs); padding: 2px 8px; border-radius: 6px; white-space: nowrap;
}
[data-theme="light"] .otra-cell.erreur { border-color: #B4532F; }
[data-theme="light"] .otra-cell .msg-erreur { border-color: #B4532F; color: #B4532F; }

/* -- 4 · badge « adapté » .otra-badge-adapted ---------------------
   Le losange ◇ est LA forme de la déviation — la couleur n'est
   jamais seule. Ambre = dévie, terracotta = retiré, vert = ajouté. */
.otra-badge-adapted {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: var(--fs-xs); font-weight: 700; padding: 2px 8px; border-radius: 6px;
  background: rgba(201, 169, 97, .14); color: #C9A961; cursor: pointer;
  border: 1px solid rgba(201, 169, 97, .5);
}
.otra-badge-adapted.retiree, .otra-badge-adapted.ajoutee { border-color: transparent; }
.otra-badge-adapted.retiree { background: rgba(224, 120, 86, .14); color: #E07856; text-decoration: line-through; }
.otra-badge-adapted.ajoutee { background: rgba(143, 201, 160, .16); color: #8FC9A0; }
[data-theme="light"] .otra-badge-adapted { color: #7A6524; }
[data-theme="light"] .otra-badge-adapted.retiree { color: #B4532F; }
[data-theme="light"] .otra-badge-adapted.ajoutee { color: #3F7A54; }
.otra-badge-version { font-size: var(--fs-xs); color: var(--txt-dim); font-weight: 600; }

/* -- 5 · coupe en couches .otra-layers ----------------------------
   COUPE (barres ∝ épaisseur, min 8px, décalage progressif) + TABLE
   côte à côte — les numéros ①…⑨ portés DES DEUX CÔTÉS, le lien ne
   dépend jamais de la couleur. Motifs par famille (tiennent en n&b) :
   maçonnerie ⟋ gris · liaison ∥ brun-or · biosourcé ≡ vert ·
   enduit uni taupe · membrane ⟍ fine bleue. */
.otra-layers { display: flex; gap: 18px; align-items: flex-start; }
.otra-layers .coupe { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }
.otra-layers .couche {
  position: relative; display: flex; align-items: center;
  min-height: 26px; min-width: 8px; border-radius: 4px;
  border: 1px solid var(--line); padding: 2px 6px; cursor: pointer;
  background-color: var(--surface-2);
}
.otra-layers .couche:hover, .otra-layers .couche:focus-visible {
  border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent);
}
.otra-layers .couche.fam-maconnerie { background-image: repeating-linear-gradient(45deg, transparent 0 5px, rgba(166, 169, 174, .35) 5px 7px); }
.otra-layers .couche.fam-liaison { background-image: repeating-linear-gradient(90deg, transparent 0 4px, rgba(201, 169, 125, .40) 4px 6px); }
.otra-layers .couche.fam-biosource { background-image: repeating-linear-gradient(0deg, transparent 0 4px, rgba(143, 201, 160, .38) 4px 6px); }
.otra-layers .couche.fam-enduit { background-color: rgba(183, 169, 138, .30); }
.otra-layers .couche.fam-membrane { background-image: repeating-linear-gradient(135deg, transparent 0 7px, rgba(108, 145, 180, .55) 7px 8px); }
.otra-layers .num {
  /* les glyphes ①…⑨ sont déjà cerclés — pas de second cercle */
  flex: none; font-size: var(--fs-md); line-height: 1; z-index: 1;
  background: var(--surface); border-radius: 50%;
}
.otra-layers .legende { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.otra-layers .legende .lg {
  display: flex; align-items: center; gap: 8px; min-height: 26px;
  font-size: var(--fs-sm); cursor: pointer; border-radius: 4px; padding: 2px 6px;
}
.otra-layers .legende .lg:hover { background: var(--surface-3); }
.otra-layers .legende .ep { margin-left: auto; font-variant-numeric: tabular-nums; color: var(--txt-dim); font-size: var(--fs-xs); white-space: nowrap; }
.otra-layers.static { filter: grayscale(1); }
.otra-layers.static .couche, .otra-layers.static .lg { cursor: default; pointer-events: none; }

/* ============================================================
   Paquet 2 · document 3 — « Composition d'ouvrage : le tableur »
   (design/v2/OTRA Composition Tableur.dc.html — codé au pixel)
   Arithmétique de la maquette, vérifiée sur ses chiffres :
   PV/m² = PA × qté × (1 + marge/100) ; déboursé sec = Σ PA×qté ;
   marge modèle = (PV − déboursé) / déboursé.
   ============================================================ */
.otra-tableur { border: 1px solid var(--line); border-radius: 14px; overflow: hidden; background: var(--surface); }
.tb-head {
  display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap;
  padding: 12px 16px; background: var(--surface);
}
.tb-titre { font-size: var(--fs-md); font-weight: 700; }
.tb-sous { font-size: var(--fs-xs); color: var(--txt-dim); margin-top: 2px; }
.tb-verif { margin-left: auto; display: flex; border-radius: 8px; overflow: hidden; border: 1px solid var(--accent-line); }
.tb-verif .drapeau {
  display: flex; align-items: center; padding: 0 10px; min-height: 34px;
  background: var(--accent-soft); color: var(--accent-text); font-size: var(--fs-xs); font-weight: 700; white-space: nowrap;
}
.tb-verif button {
  min-height: 34px; padding: 0 12px; border: 0; border-left: 1px solid var(--accent-line);
  background: none; color: var(--txt); font-size: var(--fs-xs); font-weight: 600; cursor: pointer; white-space: nowrap;
}
.tb-verif button:hover { background: var(--surface-3); }
.tb-groupe { padding: 0 0 4px; }
.tb-kicker {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 10px 16px 6px; font-size: var(--fs-xs); font-weight: 800;
  letter-spacing: .06em; text-transform: uppercase; color: var(--accent-text);
}
.tb-kicker .meta { font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--txt-dim); font-size: var(--fs-xs); }
.tb-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.tb-table thead th {
  text-align: left; padding: 5px 10px; font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: var(--txt-dim);
  background: var(--surface-3); border: 0; white-space: nowrap;
}
.tb-table thead th.num, .tb-table td.num { text-align: right; }
.tb-table tbody td {
  padding: 2px 10px; border-bottom: 1px solid var(--line-soft);
  vertical-align: middle; font-variant-numeric: tabular-nums;
}
.tb-table tbody tr:hover { background: var(--surface-2); }
.tb-table .col-lib { width: 42%; }
.tb-table .col-prod { width: 16%; }
.tb-table .col-min { width: 8%; }
.tb-table .col-act { width: 34px; }
.tb-prod { color: hsl(210 45% 66%); }
[data-theme="light"] .tb-prod { color: hsl(210 45% 38%); }
.tb-sans-prod { color: #E07856; font-size: var(--fs-xs); cursor: pointer; }
[data-theme="light"] .tb-sans-prod { color: #B4532F; }
.tb-pa-manquant {
  display: inline-flex; align-items: center; justify-content: flex-end;
  background: rgba(224, 120, 86, .12); color: #E07856; border-radius: 5px;
  padding: 2px 8px; font-weight: 700; cursor: pointer;
}
[data-theme="light"] .tb-pa-manquant { color: #B4532F; }
.tb-pv { color: var(--accent-text); font-weight: 600; }
.tb-ajout { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 6px 16px 10px; }
.tb-ajout button {
  border: 0; background: none; color: var(--accent-text);
  font-size: var(--fs-sm); font-weight: 700; cursor: pointer; min-height: 32px; padding: 0;
}
.tb-ajout .aide { font-size: var(--fs-xs); color: var(--txt-dim); }
.tb-note-groupes { padding: 4px 16px 10px; font-size: var(--fs-xs); color: var(--txt-dim); }
.tb-footer {
  display: flex; align-items: center; gap: 26px; flex-wrap: wrap;
  padding: 12px 16px; border-top: 2px solid var(--accent);
  background: var(--surface-2);
}
.tb-footer .tot .k { display: block; font-size: var(--fs-xs); color: var(--txt-dim); }
.tb-footer .tot b { font-size: var(--fs-lg); font-variant-numeric: tabular-nums; }
.tb-footer .tot.pv b { color: var(--accent-text); }
.tb-footer .fixe { margin-left: auto; display: flex; align-items: center; gap: 8px; font-size: var(--fs-xs); color: var(--txt-dim); }
/* options & résolution — édités au même endroit (maquette §2) */
.tb-opts { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 12px; }
@media (max-width: 860px) { .tb-opts { grid-template-columns: 1fr; } }
.tb-opt-ligne { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 6px 0; }
.tb-opt-ligne .nom { font-weight: 600; font-size: var(--fs-sm); flex: 1; min-width: 90px; }
.tb-chip {
  display: inline-flex; align-items: center; gap: 4px; min-height: 30px; padding: 0 10px;
  border: 1px solid var(--line); border-radius: 7px; background: var(--surface-2);
  font-size: var(--fs-sm); cursor: pointer;
}
.tb-chip.defaut { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-text); font-weight: 700; }
.tb-chip.plus { color: var(--txt-dim); font-weight: 700; }
.tb-reso { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.tb-reso th {
  text-align: left; padding: 5px 10px; font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: var(--txt-dim); background: var(--surface-3);
}
.tb-reso td { padding: 4px 10px; border-bottom: 1px solid var(--line-soft); }
.tb-non-resolu { color: #E07856; font-weight: 600; }
[data-theme="light"] .tb-non-resolu { color: #B4532F; }
/* badge d'enregistrement (haut de page) */
.tb-etat-enr { font-size: var(--fs-xs); color: var(--txt-dim); }
.tb-etat-enr.enr { color: var(--accent-text); }
.tb-etat-enr.ko { color: #E07856; font-weight: 600; }
/* mobile : la grille devient liste ; l'édition passe par le tiroir */
@media (max-width: 640px) {
  .tb-table .col-prod, .tb-table .col-min, .tb-table thead { display: none; }
  .tb-table tbody td:not(.col-lib):not(.col-pv):not(.col-act) { display: none; }
  .tb-table tbody td { padding: 8px 10px; }
}

/* doc 3 — compléments relevés en recette croisée (analyse parallèle) */
.tb-poignee { color: var(--txt-faint); cursor: grab; margin-right: 6px; font-size: var(--fs-xs); user-select: none; }
.tb-poignee:active { cursor: grabbing; }
.tb-fx { color: var(--txt-faint); font-size: var(--fs-xs); margin-left: 6px; opacity: .55; cursor: help; font-style: italic; }
.tb-bandeau {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--surface-3); border: 1px solid var(--line); border-radius: 10px;
  padding: 8px 12px; margin-bottom: 8px; font-size: var(--fs-sm);
}
.tb-bandeau.demo { background: rgba(201, 169, 97, .16); color: var(--accent-text); font-weight: 600; border-color: var(--accent-line); }
.tb-footer .tot b.recalc-tot { color: #C9A961; }
.tb-footer .tot b.recalc-tot::after { content: " ⟳"; font-size: var(--fs-xs); }
[data-theme="light"] .tb-footer .tot b.recalc-tot { color: #7A6524; }
.tb-chip .etoile { border: 0; background: none; cursor: pointer; color: inherit; font-size: var(--fs-xs); padding: 0 0 0 2px; line-height: 1; }
.tb-chip [data-chip-lib] { cursor: text; }
.tb-reso td [data-reso-prod], .tb-reso td [data-reso-vide] { cursor: pointer; }
tr[draggable="true"] { cursor: default; }

/* ============================================================
   Bibliothèque — CARTES d'ouvrages et d'origines produits
   (design/v2/OTRA Bibliotheque.dc.html, livrable 12 — au pixel :
   carte 12px de rayon, 16/18 de marge, badges 10,5px/800, prix
   16px tabulaires, bouton 38px ; la paramétrique porte la bordure
   or et le bouton plein.)
   ============================================================ */
.biblio-grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; }
.ouv-carte {
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px;
  padding: 16px 18px; display: flex; flex-direction: column;
}
.ouv-carte.parametrique { border-color: var(--accent-line); }
.ouv-carte .haut { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 8px; }
.ouv-badge {
  background: var(--surface-3); color: var(--txt-dim); font-size: var(--fs-xs); font-weight: 800;
  letter-spacing: .05em; padding: 3px 8px; border-radius: 6px; white-space: nowrap;
}
.ouv-badge.param { background: var(--accent-soft); color: var(--accent-text); }
.ouv-badge.bio { background: rgba(143, 201, 160, .16); color: #8FC9A0; font-weight: 700; font-size: var(--fs-xs); letter-spacing: 0; }
[data-theme="light"] .ouv-badge.bio { color: #3F7A54; }
.ouv-badge.verif { background: rgba(224, 120, 86, .14); color: #E07856; letter-spacing: 0; font-size: var(--fs-xs); }
[data-theme="light"] .ouv-badge.verif { color: #B4532F; }
.ouv-carte .ouv-tete { display: flex; align-items: center; gap: 11px; min-width: 0; }
.ouv-carte .ouv-tete .titre { flex: 1; min-width: 0; }
.ouv-carte .titre { font-size: var(--fs-md); font-weight: 700; line-height: 1.3; }
.ouv-carte .recette { font-size: var(--fs-xs); color: var(--txt-dim); margin: 6px 0 12px; }
.ouv-carte .recette .tech { color: hsl(210 45% 66%); }
[data-theme="light"] .ouv-carte .recette .tech { color: hsl(210 45% 38%); }
.ouv-chips { display: flex; gap: 6px; flex-wrap: wrap; margin: 10px 0 12px; }
.ouv-chip {
  background: var(--surface-3); font-size: var(--fs-xs); padding: 5px 9px; border-radius: 7px;
  white-space: nowrap; border: 0; color: inherit; cursor: pointer; font-family: inherit;
}
.ouv-chip:hover { background: var(--accent-soft); color: var(--accent-text); }
.ouv-carte .pied { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-top: auto; }
.ouv-carte .prix { font-size: var(--fs-lg); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ouv-carte.parametrique .prix { color: var(--accent-text); }
.ouv-carte .meta { font-size: var(--fs-xs); color: var(--txt-dim); }
.ouv-actions { display: flex; gap: 8px; margin-top: 12px; }
.ouv-actions .btn { flex: 1; min-height: 38px; justify-content: center; font-size: var(--fs-sm); }
.ouv-actions .btn-secondary { color: var(--accent-text); font-weight: 600; }
/* les quatre origines de produits (maquette : « quatre origines, quatre règles de PA ») */
.origines { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; margin-bottom: 14px; }
.origine-carte {
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px;
  padding: 12px 14px; cursor: pointer; text-align: left; color: inherit; font-family: inherit;
}
.origine-carte:hover { border-color: var(--accent-line); }
.origine-carte.on { border-color: var(--accent); background: var(--accent-soft); }
.origine-carte .cle { font-size: var(--fs-xs); font-weight: 800; letter-spacing: .05em; color: var(--accent-text); }
.origine-carte .nb { font-size: var(--fs-lg); font-weight: 700; font-variant-numeric: tabular-nums; margin: 2px 0; }
.origine-carte .regle { font-size: var(--fs-xs); color: var(--txt-dim); line-height: 1.45; }


/* EA — la grille du document 5 (10 colonnes, largeurs de la maquette) */
.ea-row {
  display: grid; grid-template-columns: 44px 70px 90px 1fr 120px 80px 110px 110px 110px 110px;
  gap: 10px; padding: 0 20px; min-height: 50px; align-items: center;
  border-bottom: 1px solid var(--line-soft); font-size: var(--fs-sm); cursor: pointer;
}
.ea-row:hover { background: var(--surface-2); }
.ea-row.ea-head {
  min-height: 38px; font-size: var(--fs-xs); letter-spacing: .06em; text-transform: uppercase;
  color: var(--txt-dim); font-weight: 700; cursor: default; background: none;
}
.ea-row.otra-sel { background: rgba(201, 169, 125, .07); box-shadow: inset 3px 0 0 var(--accent); }
[data-theme="light"] .ea-row.otra-sel { box-shadow: inset 3px 0 0 #8A6F4B; }
.ea-groupe {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  min-height: 44px; padding: 0 20px; background: var(--surface-2);
  border-bottom: 1px solid var(--line-soft); font-size: var(--fs-sm);
}
@media (max-width: 900px) {
  .ea-row { grid-template-columns: 36px 1fr 100px; row-gap: 4px; padding: 10px 14px; }
  .ea-row > span:nth-child(n+5):nth-child(-n+6) { grid-column: 2; }
  .ea-row.ea-head { display: none; }
}
.ea-row > span { min-width: 0; }
.ea-row .otra-check { align-self: center; height: 20px; flex: none; }
.ea-row .otra-cell.verrou { cursor: default; }
.ea-row .otra-cell.verrou::after { content: none; } /* pas de cadenas dans la grille EA */

/* ── document 8 · Espace IA ──────────────────────────────────────────
   La grille des agents est un registre : une carte = un contrat.
   L'état se lit à la forme (● ⚑ ○) et au mot, jamais à la couleur seule. */
.ia-grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 14px; }
.ia-carte {
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 16px 18px; display: flex; flex-direction: column; gap: 10px;
}
.ia-carte.veille { opacity: .82; }
.ia-carte .haut { display: flex; align-items: center; gap: 10px; }
.ia-jeton {
  width: 38px; height: 38px; border-radius: 10px; flex: none;
  display: flex; align-items: center; justify-content: center; font-size: var(--fs-lg);
  background: var(--accent-soft); border: 1px solid var(--accent-line);
}
.ia-jeton.mesure { background: hsl(210 45% 66% / .14); border-color: hsl(210 45% 66% / .4); }
.ia-jeton.texte  { background: var(--danger-soft); border-color: hsl(14 70% 61% / .4); }
.ia-jeton.doc    { background: var(--bio-soft); border-color: hsl(136 37% 68% / .4); }
.ia-carte .nom { font-size: var(--fs-md); font-weight: 700; }
.ia-carte .dom { font-size: var(--fs-xs); color: var(--txt-dim); }
.ia-etat {
  margin-left: auto; flex: none; font-size: var(--fs-xs); font-weight: 800;
  padding: 3px 8px; border-radius: 7px; white-space: nowrap;
  background: var(--surface-3); color: var(--txt-dim); border: 1px solid var(--line);
}
.ia-etat.actif  { background: var(--bio-soft); color: var(--bio); border-color: hsl(136 37% 68% / .4); }
.ia-etat.verif  { background: var(--warn-soft); color: var(--accent-text); border-color: var(--accent-line); }
.ia-carte .contrat { font-size: var(--fs-sm); color: var(--txt-dim); line-height: 1.55; }
.ia-carte .contrat b { color: var(--txt); }
.ia-carte .pied { display: flex; gap: 8px; margin-top: auto; align-items: center; flex-wrap: wrap; }
.ia-carte .pied .btn { min-height: 40px; font-size: var(--fs-sm); }
.ia-lien-agent {
  font-size: var(--fs-xs); color: var(--txt-dim); border: 1px solid var(--line);
  border-radius: 9px; min-height: 40px; display: flex; align-items: center;
  padding: 0 12px; background: none; cursor: pointer; font-family: inherit;
}
.ia-lien-agent.vide { color: var(--accent-text); border-color: var(--accent-line); }

/* le fil d'un travail — une extraction, son verdict, sa source */
.ia-fil { display: flex; flex-direction: column; gap: 8px; }
.ia-trouve {
  background: var(--surface-2); border: 1px solid var(--line-soft);
  border-left: 3px solid var(--line); border-radius: 10px; padding: 11px 14px;
}
.ia-trouve.couvert  { border-left-color: var(--bio); }
.ia-trouve.manquant { border-left-color: var(--danger); }
.ia-trouve.risque   { border-left-color: var(--accent); }
.ia-trouve.rejetee  { opacity: .45; }
.ia-trouve .verdict { font-size: var(--fs-xs); font-weight: 800; flex: none; }
.ia-trouve.couvert  .verdict { color: var(--bio); }
.ia-trouve.manquant .verdict { color: var(--danger); }
.ia-trouve.risque   .verdict { color: var(--accent-text); }
.ia-trouve .dit { font-size: var(--fs-sm); min-width: 0; }
.ia-trouve .src { font-size: var(--fs-xs); color: var(--txt-dim); margin-top: 4px; }
.ia-trouve .rangee { display: flex; gap: 8px; align-items: baseline; }
.ia-trouve .choix { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
.ia-trouve .choix button {
  min-height: 32px; padding: 0 11px; border-radius: 8px; font-size: var(--fs-xs); font-weight: 600;
  border: 1px solid var(--line); background: none; color: var(--txt); cursor: pointer; font-family: inherit;
}
.ia-trouve .choix button.on { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.ia-etape { font-size: var(--fs-sm); color: var(--txt-dim); display: flex; align-items: center; gap: 8px; }
.ia-etape .barre { flex: 1; height: 4px; background: var(--surface-3); border-radius: 3px; overflow: hidden; }
.ia-etape .barre i { display: block; height: 100%; background: var(--accent); width: 30%; animation: ia-va 1.1s ease-in-out infinite alternate; }
@keyframes ia-va { from { margin-left: 0 } to { margin-left: 70% } }

/* la synthèse et le texte rédigé — de la prose, pas un tableau */
.ia-synthese { border-left: 3px solid var(--accent); }
.ia-synthese p { font-size: var(--fs-md); line-height: 1.65; margin: 0; }
.ia-texte { font-size: var(--fs-md); line-height: 1.7; white-space: normal; }

/* ── document 9 · boîte de réception, courrier, audit ───────────────── */
.bo-ligne {
  display: flex; align-items: center; gap: 12px; padding: 0 16px;
  min-height: 56px; border-bottom: 1px solid var(--line-soft);
}
.bo-ligne:last-child { border-bottom: 0; }
.bo-ligne .main { flex: 1; min-width: 0; }
.bo-ligne .t { font-size: var(--fs-sm); font-weight: 600; }
.bo-ligne .s { font-size: var(--fs-xs); color: var(--txt-dim); margin-top: 2px; }
.bo-ligne .btn { flex: none; min-height: 36px; font-size: var(--fs-sm); }
.bo-jeton {
  width: 30px; height: 30px; border-radius: 8px; flex: none;
  display: flex; align-items: center; justify-content: center; font-size: var(--fs-sm);
  background: var(--surface-3); border: 1px solid var(--line);
}
.bo-jeton.ia         { background: var(--warn-soft); border-color: var(--accent-line); color: var(--accent-text); }
.bo-jeton.courrier   { background: hsl(210 45% 66% / .14); border-color: hsl(210 45% 66% / .4); }
.bo-jeton.alerte     { background: var(--danger-soft); border-color: hsl(14 70% 61% / .4); color: var(--danger); }
.bo-jeton.relance    { background: var(--bio-soft); border-color: hsl(136 37% 68% / .4); color: var(--bio); }
.bo-jeton.validation { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-text); }
.bo-total {
  background: var(--accent); color: var(--on-accent); font-size: var(--fs-md); font-weight: 800;
  padding: 2px 10px; border-radius: 9px; vertical-align: 3px;
}
/* La marge n'est pas décorative : le parent est en flex, et l'espace
   écrite dans le gabarit y est avalée. Sans elle : « Ouvertes2 ». */
.bo-n { opacity: .7; font-variant-numeric: tabular-nums; margin-left: 6px; }
.lien-nu { background: none; border: 0; color: var(--accent-text); cursor: pointer; font: inherit; padding: 0; text-decoration: underline; }

.bo-regles { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.bo-regles th {
  text-align: left; padding: 10px 14px; font-size: var(--fs-xs); font-weight: 800;
  letter-spacing: .05em; text-transform: uppercase; color: var(--txt-dim);
  border-bottom: 1px solid var(--line); background: var(--surface-3);
}
.bo-regles td { padding: 9px 14px; border-bottom: 1px solid var(--line-soft); color: var(--txt-dim); }
.bo-regles td:first-child { color: var(--txt); font-weight: 600; }
.bo-regles td.ok { color: var(--bio); font-weight: 600; }

.bo-alias { border-left: 3px solid var(--accent); }
.bo-alias .adr {
  display: inline-block; font-size: var(--fs-md); font-weight: 600; color: var(--accent-text);
  background: var(--surface-3); border: 1px solid var(--line); border-radius: 9px;
  padding: 8px 13px; cursor: pointer; font-variant-numeric: tabular-nums;
}
.bo-msg { display: flex; gap: 12px; padding: 13px 16px; border-bottom: 1px solid var(--line-soft); }
.bo-msg:last-child { border-bottom: 0; }
.bo-msg .rond {
  width: 34px; height: 34px; border-radius: 50%; flex: none; background: var(--surface-3);
  display: flex; align-items: center; justify-content: center; font-size: var(--fs-xs); font-weight: 700;
}
.bo-msg .main { min-width: 0; flex: 1; }
.bo-msg .t { font-size: var(--fs-sm); font-weight: 700; display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.bo-msg .s { font-size: var(--fs-sm); color: var(--txt-dim); margin-top: 3px; line-height: 1.5; }
.bo-role { font-size: var(--fs-xs); font-weight: 800; padding: 2px 7px; border-radius: 5px; }
.bo-role.connu   { background: var(--accent-soft); color: var(--accent-text); }
.bo-role.inconnu { background: var(--surface-3); color: var(--txt-dim); border: 1px solid var(--line); }

.bo-audit { font-size: var(--fs-sm); line-height: 1.9; color: var(--txt-dim); }
.bo-audit .bo-a { padding: 2px 0; border-bottom: 1px solid var(--line-soft); }
.bo-audit .bo-a:last-child { border-bottom: 0; }
.bo-audit .q { color: var(--txt-faint); font-variant-numeric: tabular-nums; }
.bo-audit b { color: var(--txt); }
.bo-piste { display: inline; }

/* ── espace client (livrable « Espaces externes ») ────────────────────
   Thème clair imposé par l'écran : un maître d'ouvrage lit et imprime. */
.cl-entete {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 0 0 18px; border-bottom: 2px solid var(--txt); margin-bottom: 20px;
}
.cl-entete .marque {
  width: 46px; height: 46px; border-radius: 13px; flex: none;
  background: var(--accent); color: var(--on-accent);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--ff-display); font-weight: 600; font-size: var(--fs-xl);
}
.cl-entete .min { min-width: 0; flex: 1 1 240px; }
.cl-entete h1 { font-family: var(--ff-display); font-size: var(--fs-xl); font-weight: 600; margin: 0; }
.cl-entete .sub { font-size: var(--fs-sm); color: var(--txt-dim); margin-top: 2px; }
.cl-entete .qui { font-size: var(--fs-md); font-weight: 600; }
.cl-bandeau {
  background: var(--bio-soft); border: 1px solid hsl(136 37% 45% / .4);
  color: hsl(136 42% 28%); border-radius: 10px; padding: 8px 14px; font-size: var(--fs-sm);
}
:root:not([data-theme="light"]) .cl-bandeau { color: var(--bio); }
.cl-bandeau .part { display: block; font-size: var(--fs-xs); opacity: .85; font-weight: 400; margin-top: 2px; }
.cl-relecture {
  background: var(--accent-soft); border: 1px solid var(--accent-line); border-radius: 10px;
  padding: 9px 14px; font-size: var(--fs-sm); color: var(--accent-text); margin-bottom: 18px;
}
.cl-h2 { font-family: var(--ff-display); font-size: var(--fs-lg); font-weight: 600; margin: 24px 0 10px; }
.cl-valider { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 12px; }
.cl-carte {
  background: var(--surface-2); border: 1px solid var(--line);
  border-left: 3px solid var(--accent); border-radius: var(--r); padding: 15px 17px;
}
.cl-carte .haut { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.cl-carte .haut b { font-size: var(--fs-md); }
.cl-carte .quand { font-size: var(--fs-xs); font-weight: 700; color: var(--danger); }
.cl-carte p { font-size: var(--fs-sm); line-height: 1.6; color: var(--txt-dim); margin: 8px 0 12px; }
.cl-carte p b { color: var(--txt); }
.cl-carte .actes { display: flex; gap: 8px; flex-wrap: wrap; }
.cl-jauge { height: 12px; background: var(--surface-3); border-radius: 7px; overflow: hidden; }
.cl-jauge i { display: block; height: 100%; background: var(--accent); }
.cl-jauge-lib { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; margin-top: 8px; font-size: var(--fs-md); }
.cl-lots { margin-top: 14px; display: flex; flex-direction: column; gap: 6px; }
.cl-lot { display: flex; align-items: center; gap: 10px; font-size: var(--fs-sm); }
.cl-lot .n { flex: 0 0 190px; color: var(--txt-dim); }
.cl-lot .b { flex: 1; height: 7px; background: var(--surface-3); border-radius: 4px; overflow: hidden; }
.cl-lot .b i { display: block; height: 100%; background: var(--accent); opacity: .75; }
.cl-lot .p { flex: 0 0 42px; text-align: right; font-variant-numeric: tabular-nums; }
.cl-post { display: flex; gap: 12px; padding: 13px 16px; border-bottom: 1px solid var(--line-soft); }
.cl-post:last-child { border-bottom: 0; }
.cl-post .g { font-size: var(--fs-lg); flex: none; }
.cl-post .main { min-width: 0; flex: 1; }
.cl-post .t { font-size: var(--fs-sm); line-height: 1.55; }
.cl-post .s { font-size: var(--fs-xs); color: var(--txt-dim); margin-top: 3px; }
.cl-photos { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.cl-photos img { width: 96px; height: 72px; object-fit: cover; border-radius: 8px; border: 1px solid var(--line); }
.cl-ico { font-size: var(--fs-lg); flex: none; width: 24px; text-align: center; }
@media (max-width: 640px) { .cl-lot .n { flex: 0 0 120px; } }
.cl-bandeau.muet { background: var(--surface-3); border-color: var(--line); color: var(--txt-dim); }

/* ── espace ouvrier — « la journée dans la poche » ────────────────────
   Mobile d'abord (390 px), sombre imposé, cibles ≥ 44 px partout. */
.te-tete { margin-bottom: 16px; }
.te-tete .salut { font-family: var(--ff-display); font-size: var(--fs-xl); font-weight: 600; }
.te-tete .date { font-size: var(--fs-sm); color: var(--txt-dim); margin-top: 2px; text-transform: capitalize; }
.te-carte {
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 15px 17px; margin-bottom: 12px;
}
.te-carte.auj { border-color: var(--accent-line); border-left: 3px solid var(--accent); }
.te-carte .haut { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.te-carte .haut b { font-size: var(--fs-lg); }
.te-carte .quand { font-size: var(--fs-sm); color: var(--txt-dim); margin-left: auto; white-space: nowrap; }
.te-carte .genre { font-size: var(--fs-sm); margin-top: 4px; }
.te-carte .ou { font-size: var(--fs-sm); color: var(--txt-dim); margin-top: 6px; }
.te-carte .ou a { color: var(--accent-text); font-weight: 600; margin-left: 6px; }
.te-carte .consigne {
  background: var(--accent-soft); border: 1px solid var(--accent-line); border-radius: 10px;
  padding: 9px 12px; margin-top: 10px; font-size: var(--fs-sm); line-height: 1.5;
}
.te-carte .consigne .k {
  display: block; font-size: var(--fs-xs); font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--accent-text); margin-bottom: 3px;
}
.te-carte .actes { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.te-gestes { display: flex; gap: 8px; margin: 4px 0 18px; }
.te-gestes .btn { flex: 1; }
.te-h2 { font-size: var(--fs-lg); font-weight: 700; margin: 20px 0 8px; display: flex; align-items: baseline; gap: 8px; }
.te-h2 .n {
  font-size: var(--fs-xs); font-weight: 800; background: var(--surface-3); color: var(--txt-dim);
  padding: 2px 8px; border-radius: 7px;
}
.te-taches { display: flex; flex-direction: column; gap: 8px; }
.te-tache {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  min-height: var(--tap); padding: 10px 14px; font-family: inherit; cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r); color: var(--txt);
}
.te-tache:hover, .te-tache:active { background: var(--surface-3); }
.te-tache .coche {
  width: 28px; height: 28px; flex: none; border-radius: 50%; border: 1.5px solid var(--line);
  display: flex; align-items: center; justify-content: center; font-size: var(--fs-sm); font-weight: 800;
  color: var(--txt-dim);
}
.te-tache.fait .coche { border-color: var(--bio); color: var(--bio); background: var(--bio-soft); }
.te-tache.urgent .coche { border-color: var(--danger); color: var(--danger); background: var(--danger-soft); }
.te-tache .main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.te-tache .t { font-size: var(--fs-sm); font-weight: 600; }
.te-tache .s { font-size: var(--fs-xs); color: var(--txt-dim); }
.te-tache .s.rem { font-style: italic; }
.te-tache.fait .t { color: var(--txt-dim); }
.te-tache .pct { flex: 0 0 74px; text-align: right; position: relative; }
.te-tache .pct b { font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }
.te-tache .pct i {
  display: block; height: 4px; background: var(--accent); border-radius: 3px;
  margin: 0 0 4px auto; min-width: 3px;
}
.te-tache.fait .pct i { background: var(--bio); }

/* ── espace sous-traitant ─────────────────────────────────────────────
   Une commande = une carte dépliable. Les seuls montants sont les siens. */
.st-carte {
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r); margin-bottom: 10px; overflow: hidden;
}
.st-carte .haut {
  display: flex; align-items: center; gap: 12px; width: 100%;
  min-height: 58px; padding: 10px 16px; background: none; border: 0;
  font-family: inherit; color: var(--txt); cursor: pointer; text-align: left;
}
.st-carte .haut:hover { background: var(--surface-3); }
.st-carte .min { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.st-carte .no { font-size: var(--fs-md); font-weight: 700; }
.st-carte .s { font-size: var(--fs-xs); color: var(--txt-dim); }
.st-carte .etat {
  flex: none; font-size: var(--fs-xs); font-weight: 800; padding: 3px 9px; border-radius: 7px;
  background: var(--surface-3); color: var(--txt-dim); border: 1px solid var(--line);
}
.st-carte .etat.on { background: var(--accent-soft); color: var(--accent-text); border-color: var(--accent-line); }
.st-carte .etat.fini { background: var(--bio-soft); color: var(--bio); border-color: hsl(136 37% 45% / .4); }
.st-carte .mt { flex: none; font-size: var(--fs-md); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.st-carte .chev { flex: none; color: var(--txt-dim); font-size: var(--fs-xs); }
.st-carte .rowlist { border-top: 1px solid var(--line-soft); }
.st-carte .pied { padding: 12px 16px; border-top: 1px solid var(--line-soft); }

/* ── types de compte ──────────────────────────────────────────────────
   L'état d'un compte se lit à la forme (● ○ !) autant qu'à la couleur. */
.cp-pastille {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-sm); font-weight: 800; border: 1.5px solid var(--line); color: var(--txt-dim);
}
.cp-pastille.ok     { border-color: hsl(136 37% 45% / .5); color: var(--bio); background: var(--bio-soft); }
.cp-pastille.manque { border-color: var(--accent-line); color: var(--accent-text); background: var(--accent-soft); }
.cp-pastille.faute  { border-color: hsl(14 70% 55% / .5); color: var(--danger); background: var(--danger-soft); }
.cp-type { flex: none; font-size: var(--fs-xs); color: var(--txt-dim); min-width: 150px; text-align: right; }
.cp-type.manque { color: var(--accent-text); font-weight: 600; }
.cp-type.faute  { color: var(--danger); font-weight: 600; }
.cp-alerte { border-left: 3px solid var(--accent); margin-bottom: 12px; }
.bo-regles td.cp-non { color: var(--danger); font-weight: 700; }
.tc-liste { display: flex; flex-direction: column; gap: 6px; }
.tc-choix {
  display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface-2);
}
.tc-choix.on { border-color: var(--accent); background: var(--accent-soft); }
.tc-choix input { margin-top: 3px; flex: none; }
.tc-choix b { font-size: var(--fs-sm); display: block; }
.tc-choix .s { font-size: var(--fs-xs); color: var(--txt-dim); line-height: 1.5; display: block; margin-top: 2px; }

/* ── avertir les intervenants · inviter au portail · documents ───────── */
.av-gens { display: flex; flex-direction: column; gap: 6px; max-height: 210px; overflow: auto; }
.av-g {
  display: flex; gap: 10px; align-items: flex-start; padding: 9px 11px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface-2);
}
.av-g input { margin-top: 3px; flex: none; }
.av-g b { font-size: var(--fs-sm); }
.av-g .s { font-size: var(--fs-xs); color: var(--txt-dim); display: block; margin-top: 1px; }
.av-ext {
  font-size: var(--fs-xs); font-weight: 800; padding: 1px 6px; border-radius: 5px;
  background: var(--warn-soft); color: var(--accent-text);
}
.inv-recap {
  background: var(--surface-3); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 12px 14px;
}
.inv-recap .l { display: flex; gap: 10px; align-items: baseline; padding: 3px 0; font-size: var(--fs-sm); }
.inv-recap .k { flex: 0 0 120px; color: var(--txt-dim); font-size: var(--fs-xs); }
.doc-ico { flex: none; font-size: var(--fs-lg); width: 26px; text-align: center; }

/* blocs de texte réutilisables · devis rapide */
.bl-liste { display: flex; flex-direction: column; gap: 6px; max-height: 300px; overflow: auto; }
.bl-b {
  display: flex; gap: 10px; align-items: flex-start; padding: 9px 11px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface-2);
}
.bl-b input { margin-top: 3px; flex: none; }
.bl-b b { font-size: var(--fs-sm); display: block; }
.bl-b .s { font-size: var(--fs-xs); color: var(--txt-dim); line-height: 1.5; display: block; margin-top: 2px; }

/* la croix qui retire une ligne d'ouvrage — elle doit se VOIR */
.tb-actes { display: inline-flex; gap: 2px; align-items: center; }
.tb-act {
  min-width: 26px; min-height: 26px; padding: 0 5px; border-radius: 6px;
  border: 1px solid transparent; background: none; cursor: pointer;
  color: var(--txt-dim); font-family: inherit; font-size: var(--fs-sm); line-height: 1;
}
.tb-act:hover { background: var(--surface-3); color: var(--txt); border-color: var(--line); }
.tb-act.sup { color: var(--danger); font-weight: 700; }
.tb-act.sup:hover { background: var(--danger-soft); border-color: var(--danger); }

/* contrôle des épaisseurs — ce que l'ouvrage promet vs ce que le catalogue permet */
.ep-ok {
  background: var(--bio-soft); border: 1px solid hsl(136 37% 45% / .4); color: var(--bio);
  border-radius: var(--r-sm); padding: 9px 12px; font-size: var(--fs-sm); font-weight: 600;
}
.ep-ko {
  background: var(--danger-soft); border: 1px solid hsl(14 70% 55% / .45);
  border-left: 3px solid var(--danger); border-radius: var(--r-sm); padding: 11px 14px;
}
.ep-ko b { color: var(--danger); font-size: var(--fs-sm); }
.ep-ko .s { font-size: var(--fs-xs); color: var(--txt-dim); margin: 4px 0 8px; }
.ep-ko ul { margin: 0; padding-left: 16px; font-size: var(--fs-xs); line-height: 1.7; }
.ep-ko li { color: var(--txt); }
.ep-ko .g {
  display: inline-block; font-size: var(--fs-xs); font-weight: 800; text-transform: uppercase;
  letter-spacing: .04em; background: var(--surface-3); color: var(--txt-dim);
  padding: 1px 6px; border-radius: 5px; margin-right: 6px;
}

/* ── la bulle de remarques ────────────────────────────────────────────
   Flottante, réductible, déplaçable, et elle survit au changement de
   page parce que son état vit dans le navigateur, pas dans le DOM. */
.otra-bulle { position: fixed; right: 18px; bottom: 18px; z-index: 75; }
.otra-bulle .bulle-pastille {
  width: 52px; height: 52px; border-radius: 50%; border: 0; cursor: pointer;
  background: var(--accent); color: var(--on-accent); font-size: var(--fs-xl);
  box-shadow: var(--shadow-lg); position: relative; font-family: inherit;
}
.otra-bulle .bulle-pastille:hover { background: var(--accent-strong); }
.otra-bulle .bulle-pastille .n {
  position: absolute; top: -3px; right: -3px; min-width: 20px; height: 20px;
  border-radius: 10px; background: var(--bio); color: #0d2a15;
  font-size: var(--fs-xs); font-weight: 800; display: flex; align-items: center; justify-content: center; padding: 0 5px;
}
.bulle-corps {
  width: 330px; max-width: calc(100vw - 24px); background: var(--surface-2);
  border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-lg); overflow: hidden;
}
.bulle-tete {
  display: flex; align-items: center; gap: 8px; padding: 10px 12px;
  background: var(--surface-3); border-bottom: 1px solid var(--line); cursor: grab; user-select: none;
}
.bulle-tete:active { cursor: grabbing; }
.bulle-tete b { font-size: var(--fs-sm); }
.bulle-tete .ou {
  font-size: var(--fs-xs); color: var(--txt-dim); flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bulle-x {
  border: 0; background: none; color: var(--txt-dim); cursor: pointer;
  font-size: var(--fs-lg); line-height: 1; padding: 0 4px; font-family: inherit;
}
.bulle-x:hover { color: var(--txt); }
.bulle-dedans { padding: 12px; }
.bulle-genres { display: flex; gap: 5px; flex-wrap: wrap; margin-bottom: 8px; }
.bulle-g {
  border: 1px solid var(--line); background: none; color: var(--txt-dim);
  border-radius: 20px; padding: 4px 10px; font-size: var(--fs-xs); cursor: pointer; font-family: inherit;
}
.bulle-g.on { background: var(--accent); color: var(--on-accent); border-color: var(--accent); font-weight: 600; }
.bulle-dedans textarea { width: 100%; font-size: var(--fs-sm); resize: vertical; }
.bulle-pied { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.bulle-note { font-size: var(--fs-xs); color: var(--txt-dim); margin: 8px 0 0; line-height: 1.5; }
.bulle-liste { max-height: 220px; overflow: auto; border-top: 1px solid var(--line); padding: 8px 12px 12px; }
.bulle-r { border-left: 2px solid var(--line); padding: 6px 0 6px 9px; margin-bottom: 8px; }
.bulle-r.faite { border-left-color: var(--bio); }
.bulle-r.ecartee { border-left-color: var(--txt-faint); opacity: .6; }
.bulle-r .h { display: flex; gap: 8px; align-items: baseline; }
.bulle-r .e { font-size: var(--fs-xs); font-weight: 800; color: var(--txt-dim); }
.bulle-r.faite .e { color: var(--bio); }
.bulle-r .p { font-size: var(--fs-xs); color: var(--txt-faint); flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bulle-r .t { font-size: var(--fs-xs); line-height: 1.5; margin-top: 2px; }
.bulle-r .rep { font-size: var(--fs-xs); color: var(--accent-text); margin-top: 4px; line-height: 1.5; }
@media (max-width: 640px) { .otra-bulle { right: 10px; bottom: 70px; } .bulle-corps { width: calc(100vw - 20px); } }

/* l'écran des remarques — le rapport, groupé par page */
.rq { background: var(--surface-2); border: 1px solid var(--line); border-left: 3px solid var(--line);
  border-radius: var(--r); padding: 12px 15px; margin-bottom: 8px; }
.rq.nouvelle { border-left-color: var(--accent); }
.rq.faite { border-left-color: var(--bio); }
.rq.ecartee { opacity: .55; }
.rq .haut { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; margin-bottom: 6px; }
.rq-genre { font-size: var(--fs-xs); font-weight: 800; text-transform: uppercase; letter-spacing: .04em;
  padding: 2px 7px; border-radius: 5px; background: var(--surface-3); color: var(--txt-dim); }
.rq-genre.bug { background: var(--danger-soft); color: var(--danger); }
.rq-genre.manque { background: var(--warn-soft); color: var(--accent-text); }
.rq-genre.idee { background: var(--bio-soft); color: var(--bio); }
.rq-page { font-size: var(--fs-xs); font-weight: 600; }
.rq-qui { font-size: var(--fs-xs); color: var(--txt-dim); margin-left: auto; }
.rq-etat { font-size: var(--fs-xs); font-weight: 700; color: var(--txt-dim); }
.rq-etat.faite { color: var(--bio); }
.rq-txt { font-size: var(--fs-sm); line-height: 1.6; margin: 0; }
.rq-rep { font-size: var(--fs-sm); color: var(--accent-text); margin: 6px 0 0; line-height: 1.5; }
.rq-actes { display: flex; gap: 6px; margin-top: 10px; flex-wrap: wrap; }

/* l'acompte : des pourcentages qu'on choisit d'un doigt */
.ac-vite { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; }
.ac-p {
  border: 1px solid var(--line); background: var(--surface-2); color: var(--txt-dim);
  border-radius: 8px; padding: 6px 12px; font-size: var(--fs-sm); cursor: pointer; font-family: inherit;
}
.ac-p.on { background: var(--accent); color: var(--on-accent); border-color: var(--accent); font-weight: 700; }

/* EA : la saisie à trois niveaux — la ligne, la section, tout */
.ea-sec td { background: var(--surface-3); }
.ea-sec .col-lib { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ea-sec-vite, .ea-tout { display: inline-flex; gap: 4px; align-items: center; }
.ea-tout { margin-left: auto; font-size: var(--fs-xs); color: var(--txt-dim); text-transform: none; font-weight: 400; }
.ea-v {
  border: 1px solid var(--line); background: var(--surface-2); color: var(--txt-dim);
  border-radius: 6px; padding: 2px 8px; font-size: var(--fs-xs); font-weight: 700;
  cursor: pointer; font-family: inherit; line-height: 1.6;
}
.ea-v:hover { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.ea-v.raz:hover { background: var(--surface-3); color: var(--txt); border-color: var(--line); }

/* les contacts d'un chantier — un jeton par personne, avec son rôle */
.ch-liste { display: flex; gap: 6px; flex-wrap: wrap; margin: 8px 0 12px; }
.ch-jeton {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 8px 5px 11px;
  border: 1px solid var(--accent-line); background: var(--accent-soft);
  border-radius: 20px; font-size: var(--fs-sm);
}
.ch-jeton .r { color: var(--txt-dim); font-size: var(--fs-xs); }
.ch-jeton button {
  border: 0; background: none; color: var(--txt-dim); cursor: pointer;
  font-size: var(--fs-sm); line-height: 1; padding: 0 2px; font-family: inherit;
}
.ch-jeton button:hover { color: var(--danger); }

/* les points de suivi joints à une facture */
.ps-liste { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; }
.ps-p {
  display: flex; gap: 10px; align-items: flex-start; padding: 9px 11px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface-2);
}
.ps-p input { margin-top: 3px; flex: none; }
.ps-p b { font-size: var(--fs-sm); display: block; }
.ps-p .s { font-size: var(--fs-xs); color: var(--txt-dim); line-height: 1.5; display: block; margin-top: 2px; }

/* ── le chat de chantier ──────────────────────────────────────────────
   Deux colonnes : les chantiers, la conversation. Sous 900 px, la liste
   passe au-dessus — on parle aussi depuis un téléphone. */
.ch-duo { display: grid; grid-template-columns: 300px 1fr; gap: 14px; align-items: start; }
.ch-liste {
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r); overflow: hidden; max-height: 68vh; overflow-y: auto;
}
.ch-kicker {
  display: flex; justify-content: space-between; padding: 10px 13px 6px;
  font-size: var(--fs-xs); font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
  color: var(--txt-dim); background: var(--surface-3);
}
.ch-canal {
  display: flex; flex-direction: column; gap: 2px; width: 100%; text-align: left;
  padding: 10px 13px; border: 0; border-bottom: 1px solid var(--line-soft);
  background: none; color: var(--txt); cursor: pointer; font-family: inherit;
}
.ch-canal:hover { background: var(--surface-3); }
.ch-canal.on { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.ch-canal .n { font-size: var(--fs-sm); font-weight: 600; }
.ch-canal .s { font-size: var(--fs-xs); color: var(--txt-dim); }
.ch-fil {
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r);
  display: flex; flex-direction: column; min-height: 420px; max-height: 68vh; overflow: hidden;
}
.ch-vide { margin: auto; text-align: center; padding: 30px; max-width: 44ch; }
.ch-vide p { margin: 8px 0 0; }
.ch-tete {
  display: flex; align-items: center; gap: 10px; padding: 11px 15px;
  border-bottom: 1px solid var(--line); background: var(--surface-3);
}
.ch-tete .min { flex: 1; min-width: 0; }
.ch-tete b { font-size: var(--fs-md); }
.ch-tete .s { display: block; font-size: var(--fs-xs); color: var(--txt-dim); margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ch-messages { flex: 1; overflow-y: auto; padding: 12px 15px; display: flex; flex-direction: column; gap: 12px; }
.ch-m { display: flex; gap: 10px; }
.ch-m .rond {
  width: 32px; height: 32px; border-radius: 50%; flex: none; background: var(--surface-3);
  display: flex; align-items: center; justify-content: center; font-size: var(--fs-xs); font-weight: 700;
  color: var(--txt-dim);
}
.ch-m .corps { min-width: 0; flex: 1; }
.ch-m .h { display: flex; gap: 8px; align-items: baseline; }
.ch-m .h b { font-size: var(--fs-sm); }
.ch-m .q { font-size: var(--fs-xs); color: var(--txt-faint); }
.ch-m .t { font-size: var(--fs-sm); line-height: 1.55; margin-top: 2px; }
.ch-m .p { font-size: var(--fs-xs); color: var(--accent-text); margin-top: 3px; }
.ch-ecrire { display: flex; gap: 8px; padding: 11px 15px; border-top: 1px solid var(--line); align-items: flex-end; }
.ch-ecrire textarea { flex: 1; resize: none; font-size: var(--fs-sm); }
@media (max-width: 900px) {
  .ch-duo { grid-template-columns: 1fr; }
  .ch-liste { max-height: 200px; }
}

/* ===== « Comment on fait » — la fiche de mise en œuvre d'un poste =====
   Écrite pour l'équipe sur le chantier : gros repères, doigt plutôt que
   souris, une ligne qui s'ouvre. Jamais la couleur seule — chaque état
   porte aussi un signe et un mot. */
.fa-liste { display: flex; flex-direction: column; gap: 10px; }
.fa-poste { background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.fa-poste.on { border-color: var(--accent); }
.fa-poste-t { width: 100%; display: grid; grid-template-columns: 1fr auto auto;
  grid-template-areas: "t etat chev" "s etat chev"; gap: 2px 12px; align-items: center;
  padding: 14px 16px; background: none; border: 0; text-align: left; cursor: pointer; color: inherit; }
.fa-poste-t:hover { background: var(--surface-3); }
.fa-poste-t .t { grid-area: t; font-weight: 600; font-size: var(--fs-md); line-height: 1.35; }
.fa-poste-t .s { grid-area: s; font-size: var(--fs-sm); color: var(--txt-dim); }
.fa-poste-t .etat { grid-area: etat; font-size: var(--fs-xs); color: var(--txt-dim); white-space: nowrap; }
.fa-poste-t .chev { grid-area: chev; color: var(--txt-dim); font-size: var(--fs-sm); }

.fa-fiche { padding: 0 16px 16px; }
.fa-resume { background: var(--surface-3); border-radius: 10px; padding: 12px 14px; margin-bottom: 14px; }
.fa-resume p { margin: 0; font-size: var(--fs-md); line-height: 1.5; }
.fa-avance { display: flex; align-items: center; gap: 10px; margin-top: 10px; font-size: var(--fs-sm); }
.fa-avance .bar { flex: 1; height: 6px; background: var(--line); border-radius: 3px; overflow: hidden; }
.fa-avance .bar i { display: block; height: 100%; background: var(--accent); }

.fa-phase { margin-bottom: 14px; }
.fa-phase-t { display: flex; align-items: center; gap: 8px; font-size: var(--fs-xs); letter-spacing: .06em;
  text-transform: uppercase; font-weight: 700; color: var(--txt-dim); margin: 0 0 6px; }
.fa-phase-t .ico { font-size: var(--fs-sm); }
.fa-phase-t .meta { font-weight: 400; text-transform: none; letter-spacing: 0; }

.fa-etape { display: flex; gap: 10px; padding: 8px 0; border-top: 1px solid var(--line); }
.fa-etape:first-of-type { border-top: 0; }
.fa-case { flex: 0 0 26px; width: 26px; height: 26px; margin-top: 2px; border-radius: 7px;
  border: 2px solid var(--line); background: var(--surface-1); cursor: pointer;
  font-size: var(--fs-md); line-height: 1; color: var(--accent-text); font-weight: 700; }
.fa-case[aria-pressed="true"] { border-color: var(--accent); background: var(--accent); color: #fff; }
.fa-etape.faite .fa-titre { text-decoration: line-through; color: var(--txt-dim); }
.fa-corps { flex: 1; min-width: 0; }
.fa-titre { width: 100%; text-align: left; background: none; border: 0; padding: 3px 0; cursor: pointer;
  color: inherit; font-size: var(--fs-md); line-height: 1.4; display: flex; gap: 8px; align-items: baseline; }
.fa-titre .chev { margin-left: auto; color: var(--txt-dim); font-size: var(--fs-xs); }
.fa-detail { padding: 6px 0 8px; font-size: var(--fs-sm); line-height: 1.55; color: var(--txt-dim); }
.fa-detail p { margin: 0 0 6px; }
.fa-vig { color: var(--txt-1); background: var(--surface-3); border-radius: 8px; padding: 8px 10px; }

.fa-bloc { border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; margin-top: 10px; }
.fa-bloc.manque { border-style: dashed; }
.fa-bloc-t { font-size: var(--fs-xs); letter-spacing: .05em; text-transform: uppercase; font-weight: 700;
  color: var(--txt-dim); margin-bottom: 6px; }
.fa-bloc ul { margin: 0; padding-left: 18px; font-size: var(--fs-sm); line-height: 1.6; }

.fa-attente { padding: 16px; text-align: center; color: var(--txt-dim); font-size: var(--fs-sm); }
.fa-pouls { display: inline-block; width: 9px; height: 9px; border-radius: 50%; background: var(--accent);
  margin-right: 8px; animation: fa-pouls 1.1s ease-in-out infinite; }
@keyframes fa-pouls { 0%, 100% { opacity: .25; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .fa-pouls { animation: none; opacity: .7; } }

@media (max-width: 640px) {
  .fa-poste-t { grid-template-columns: 1fr auto; grid-template-areas: "t chev" "s chev" "etat chev"; }
  .fa-fiche { padding: 0 12px 14px; }
  .fa-case { flex-basis: 30px; width: 30px; height: 30px; }
}

/* ===== Le Gantt =====
   Denis est daltonien : chaque barre porte le NOM de son intervenant en
   toutes lettres, et une trame (pleine, hachurée, pointillée, quadrillée,
   ondulée) double la teinte. La couleur ne porte jamais l'information
   seule. Le cadre défile horizontalement — jamais la page. */
.gt-cadre { display: flex; border: 1px solid var(--line); border-radius: 12px;
  overflow: hidden; background: var(--surface-2); }
.gt-noms { flex: 0 0 220px; border-right: 1px solid var(--line); background: var(--surface-2); z-index: 2; }
.gt-noms-tete { height: 44px; border-bottom: 1px solid var(--line); }
.gt-nom { display: block; padding: 5px 12px; border-bottom: 1px solid var(--line);
  text-decoration: none; color: inherit; overflow: hidden; }
.gt-nom:hover { background: var(--surface-3); }
.gt-nom .t { display: block; font-size: var(--fs-sm); font-weight: 600; line-height: 1.2;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gt-nom .s { display: block; font-size: var(--fs-xs); color: var(--txt-dim); }

.gt-defile { flex: 1; overflow-x: auto; overflow-y: hidden; }
.gt-piste { position: relative; }
.gt-tete { position: relative; height: 44px; border-bottom: 1px solid var(--line); }
.gt-mois, .gt-sem { position: relative; height: 22px; }
.gt-mois span { position: absolute; top: 3px; font-size: var(--fs-xs); font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--txt-dim); padding-left: 5px;
  border-left: 1px solid var(--line); white-space: nowrap; overflow: hidden; }
.gt-sem span { position: absolute; top: 2px; font-size: var(--fs-xs); color: var(--txt-dim);
  padding-left: 3px; white-space: nowrap; }

.gt-fond { position: absolute; top: 44px; bottom: 0; left: 0; right: 0; pointer-events: none; }
.gt-we { position: absolute; top: 0; bottom: 0; background: var(--surface-3); opacity: .55; }
.gt-trait { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--line); }
.gt-auj { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--accent); z-index: 3; }
.gt-auj::before { content: "aujourd'hui"; position: absolute; top: -42px; left: 3px; font-size: var(--fs-xs);
  font-weight: 700; color: var(--accent-text); white-space: nowrap; }

.gt-ligne { position: relative; border-bottom: 1px solid var(--line); }
/* Pas d'overflow:hidden ici — il ferait de la barre son propre conteneur
   de défilement et tuerait le `sticky` de l'étiquette. Le rognage se fait
   sur l'étiquette, et le fond est clippé par le border-radius. */
.gt-barre { position: absolute; height: 19px; border-radius: 7px;
  display: flex; align-items: center; font-size: var(--fs-xs);
  border: 1px solid var(--line); background: var(--surface-3); color: var(--txt-1);
  white-space: nowrap; background-clip: padding-box; }
/* L'étiquette suit le défilement DANS sa barre : une intervention de trois
   mois garde son nom sous les yeux, où qu'on en soit dans le calendrier. */
.gt-barre .lb { position: sticky; left: 0; display: inline-flex; gap: 6px; align-items: baseline;
  padding: 0 8px; max-width: 100%; overflow: hidden; z-index: 1; }
.gt-barre b { font-weight: 700; }
.gt-barre .nm { color: var(--txt-1); overflow: hidden; text-overflow: ellipsis; }
.gt-barre b + .nm { color: var(--txt-dim); }
.gt-barre .av { position: absolute; left: 0; top: 0; bottom: 0; background: var(--accent); opacity: .22; border-radius: 6px 0 0 6px; }
.gt-barre.faite { opacity: .62; }
.gt-barre.creuse { border-style: dashed; background: transparent; color: var(--txt-dim); padding: 0 8px; }

/* les cinq trames — lisibles sans distinguer les teintes */
.gt-barre.t-plein, .gt-lg.t-plein i { background: color-mix(in srgb, var(--accent) 24%, var(--surface-3)); }
.gt-barre.t-hachure, .gt-lg.t-hachure i { background-image: repeating-linear-gradient(45deg,
  var(--line) 0 3px, transparent 3px 8px); }
.gt-barre.t-pointille, .gt-lg.t-pointille i { background-image: radial-gradient(var(--line) 1.2px, transparent 1.3px);
  background-size: 7px 7px; }
.gt-barre.t-quadrille, .gt-lg.t-quadrille i { background-image: linear-gradient(var(--line) 1px, transparent 1px),
  linear-gradient(90deg, var(--line) 1px, transparent 1px); background-size: 8px 8px; }
.gt-barre.t-vague, .gt-lg.t-vague i { background-image: repeating-linear-gradient(-45deg,
  var(--line) 0 2px, transparent 2px 7px); }
.gt-barre.t-vide, .gt-lg.t-vide i { background: transparent; border-style: dashed; }

.gt-legende { display: flex; flex-wrap: wrap; gap: 8px 16px; margin-top: 10px; font-size: var(--fs-xs); }
.gt-lg { display: inline-flex; align-items: center; gap: 6px; color: var(--txt-dim); }
.gt-lg i { width: 22px; height: 12px; border-radius: 4px; border: 1px solid var(--line); display: inline-block; }

.gt-alerte { border: 1px solid var(--line); border-left: 4px solid var(--accent); border-radius: 10px;
  padding: 12px 14px; margin-bottom: 12px; background: var(--surface-2); font-size: var(--fs-sm); }
.gt-alerte ul { margin: 6px 0 0; padding-left: 18px; line-height: 1.6; }

@media (max-width: 700px) {
  .gt-noms { flex-basis: 128px; }
  .gt-nom .t { font-size: var(--fs-xs); }
  .gt-barre .nm { display: none; }
}
.gt-barre .coupe { color: var(--txt-dim); font-weight: 700; }

/* Le chantier d'une facture. Un lien certain (posé par l'analytique) et
   une supposition (le client n'a qu'un chantier) ne se ressemblent pas :
   le second est en pointillés ET porte le mot « supposé » — jamais un
   signal porté par le seul trait. */
.fi-ch { color: var(--accent-text); text-decoration: none; font-weight: 600; }
.fi-ch:hover { text-decoration: underline; }
.fi-ch.suppose { color: var(--txt-dim); font-weight: 400; border-bottom: 1px dashed var(--line); }

/* Le n° de chantier devant son nom — il se lit avant le nom, et se
   cherche : c'est par lui qu'on désigne un dossier au téléphone. */
.ch-no { display: inline-block; font-variant-numeric: tabular-nums; font-weight: 700;
  font-size: var(--fs-sm); color: var(--accent-text); background: var(--surface-3);
  border-radius: 6px; padding: 1px 6px; margin-right: 2px; }

/* ===== Le dossier de chantier — des cadres qui s'ouvrent et se referment =====
   Pour Pierre, Éric et Laurent : ce qu'il y a à faire, jamais un montant.
   Les alertes portent un SIGNE et leur motif écrit — jamais la couleur
   seule (Denis est daltonien). */
.dc-grille { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 12px; align-items: start; }
.dc-cadre { background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.dc-cadre.large { grid-column: 1 / -1; }
.dc-cadre.on { border-color: var(--line); }
.dc-tete { width: 100%; display: flex; align-items: center; gap: 10px; padding: 12px 14px;
  background: none; border: 0; cursor: pointer; color: inherit; text-align: left; }
.dc-tete:hover { background: var(--surface-3); }
.dc-tete .ico { font-size: var(--fs-md); opacity: .75; }
.dc-tete .t { font-weight: 700; font-size: var(--fs-md); }
.dc-tete .n { font-variant-numeric: tabular-nums; font-size: var(--fs-xs); font-weight: 700;
  background: var(--surface-3); border-radius: 20px; padding: 1px 8px; color: var(--txt-dim); }
.dc-tete .s { font-size: var(--fs-xs); color: var(--txt-dim); }
.dc-tete .chev { margin-left: auto; color: var(--txt-dim); }
.dc-corps { padding: 0 14px 14px; }

.dc-ok { padding: 10px 0; color: var(--txt-dim); }
.dc-alertes { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 8px; }
.dc-al { display: flex; gap: 10px; padding: 10px 12px; border-radius: 10px; background: var(--surface-3);
  border-left: 3px solid var(--line); font-size: var(--fs-sm); }
.dc-al.g0 { border-left-color: var(--accent); }
.dc-al .sg { font-size: var(--fs-sm); line-height: 1.5; }
.dc-al .mot { color: var(--txt-dim); font-size: var(--fs-xs); }
.dc-al .s { color: var(--txt-dim); font-size: var(--fs-sm); margin-top: 2px; }

.dc-kick { font-size: var(--fs-xs); letter-spacing: .05em; text-transform: uppercase; font-weight: 700;
  color: var(--txt-dim); margin: 12px 0 6px; }
.dc-kick span { font-weight: 400; text-transform: none; letter-spacing: 0; }
.dc-tache { display: flex; gap: 10px; align-items: center; padding: 7px 0; border-top: 1px solid var(--line); }
.dc-tache .pt { width: 18px; text-align: center; color: var(--txt-dim); }
.dc-tache .c { flex: 1; min-width: 0; }
.dc-tache .t { font-size: var(--fs-sm); line-height: 1.35; }
.dc-tache .s { font-size: var(--fs-xs); color: var(--txt-dim); }
.dc-tache.faite .t { text-decoration: line-through; color: var(--txt-dim); }

.dc-pl-tete { display: flex; justify-content: space-between; font-size: var(--fs-xs); color: var(--txt-dim); padding-bottom: 6px; }
.dc-pl-l { display: grid; grid-template-columns: 1fr 46% 62px; gap: 8px; align-items: center; padding: 4px 0; font-size: var(--fs-sm); }
.dc-pl-l .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dc-pl-l .pi { position: relative; height: 12px; background: var(--surface-3); border-radius: 6px; }
.dc-pl-l .pi i { position: absolute; top: 0; bottom: 0; border-radius: 6px;
  background: color-mix(in srgb, var(--accent) 45%, var(--surface-3)); }
.dc-pl-l .pi i.faite { background: var(--line); }
.dc-pl-l .pi i.retard { background-image: repeating-linear-gradient(45deg, var(--line) 0 3px, transparent 3px 7px); }
.dc-pl-l .q { color: var(--txt-dim); font-size: var(--fs-xs); overflow: hidden; text-overflow: ellipsis; }
.dc-pl-auj { font-size: var(--fs-xs); color: var(--accent-text); font-weight: 600; margin-top: 6px; }

.dc-cls { display: flex; flex-wrap: wrap; gap: 6px; }
.dc-cl { font-size: var(--fs-xs); padding: 3px 9px; border-radius: 20px; background: var(--surface-3); }
.dc-cl.vide { opacity: .55; border: 1px dashed var(--line); background: transparent; }
.dc-cl b { font-variant-numeric: tabular-nums; }
.dc-docs { margin-top: 10px; border-top: 1px solid var(--line); }
.dc-doc { display: block; padding: 7px 0; border-bottom: 1px solid var(--line); text-decoration: none; color: inherit; }
.dc-doc .t { font-size: var(--fs-sm); }
.dc-doc .s { font-size: var(--fs-xs); color: var(--txt-dim); }

.dc-gens { display: flex; flex-wrap: wrap; gap: 6px; }
.dc-g { font-size: var(--fs-sm); padding: 4px 10px; border-radius: 20px; background: var(--surface-3); }
.dc-g.ext { border: 1px dashed var(--line); background: transparent; }
.dc-g i { font-style: normal; color: var(--txt-dim); font-size: var(--fs-xs); margin-left: 5px; }
.dc-resp { margin-top: 10px; font-size: var(--fs-sm); }
.dc-actes { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }

.dc-jr { border-top: 1px solid var(--line); }
.dc-jl { display: flex; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.dc-jl .d { color: var(--txt-dim); font-size: var(--fs-xs); min-width: 42px; }
.dc-jl .s { color: var(--txt-dim); font-size: var(--fs-xs); }

.dc-devis { display: flex; flex-direction: column; gap: 6px; }
.dc-dv { display: flex; align-items: center; gap: 8px; font-size: var(--fs-sm); }
.dc-dv a { color: var(--accent-text); text-decoration: none; font-weight: 600; }

@media (max-width: 640px) {
  .dc-grille { grid-template-columns: 1fr; }
  .dc-pl-l { grid-template-columns: 1fr 40% 44px; }
}
.dc-postes { border-top: 1px solid var(--line); }
.dc-poste { display: flex; align-items: center; gap: 10px; padding: 8px 0;
  border-bottom: 1px solid var(--line); text-decoration: none; color: inherit; font-size: var(--fs-sm); }
.dc-poste:hover { background: var(--surface-3); }
.dc-poste .t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dc-poste .go { color: var(--accent-text); font-size: var(--fs-xs); font-weight: 600; white-space: nowrap; }
.dc-ft { border-top: 1px solid var(--line); }
.dc-ftl { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--line); }
.dc-ftl .c { flex: 1; min-width: 0; }
.dc-ftl .t { font-size: var(--fs-sm); }
.dc-ftl .s { font-size: var(--fs-xs); color: var(--txt-dim); }
.dc-g.gest { background: color-mix(in srgb, var(--accent) 16%, var(--surface-3)); font-weight: 600; }
.dc-resp { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line); font-size: var(--fs-sm); }
.dc-resp .s { font-size: var(--fs-xs); margin-top: 2px; }

/* La référence chantier à donner au comptoir du négoce. Gros, contrasté,
   copiable d'un doigt : elle se lit à bout de bras, dans un dépôt, avec
   des gants. */
.te-ref { display: flex; align-items: center; gap: 12px; margin: 10px 0;
  padding: 10px 12px; border-radius: 10px; background: var(--surface-3); border: 1px dashed var(--line); }
.te-ref .c { flex: 1; min-width: 0; }
.te-ref .k { display: block; font-size: var(--fs-xs); letter-spacing: .05em; text-transform: uppercase;
  color: var(--txt-dim); font-weight: 700; }
.te-ref .r { display: block; font-size: var(--fs-lg); font-weight: 800; letter-spacing: .01em;
  font-variant-numeric: tabular-nums; margin-top: 2px; }

/* ===== Centre de contrôle de chantier (maquette doc 10) =====
   L'ordre vertical de Pilotage EST l'ordre des cinq questions du matin.
   « À valider » passe en tête tant qu'il y a des bons — et disparaît
   plutôt que d'annoncer « rien à valider ».
   Jamais la couleur seule : signe + mot partout. */
.cc-head { display: flex; align-items: center; gap: 12px; padding: 4px 0 14px; flex-wrap: wrap; }
.cc-no { font-variant-numeric: tabular-nums; font-weight: 800; font-size: var(--fs-md);
  color: var(--accent-text); background: var(--surface-3); border: 1px solid var(--line);
  border-radius: 9px; padding: 5px 11px; flex: none; }
.cc-ident { min-width: 0; flex: 1; }
.cc-ident .t { font-size: var(--fs-lg); font-weight: 700; line-height: 1.25; }
.cc-ident .s { font-size: var(--fs-sm); color: var(--txt-dim); }

.cc-onglets { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 10px;
  border-bottom: 1px solid var(--line); margin-bottom: 14px; }
.cc-o { display: inline-flex; align-items: center; gap: 7px; min-height: var(--tab-h); padding: 0 15px; border: 1px solid var(--line); background: var(--surface-2);
  border-radius: 9px; font-size: var(--fs-sm); font-weight: 600; color: inherit; cursor: pointer; white-space: nowrap; }
.cc-o.on { background: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: 700; }
.cc-o .b { display: inline-block; background: var(--accent); color: var(--on-accent); font-size: var(--fs-xs); font-weight: 800;
  border-radius: 6px; padding: 1px 7px; margin-left: 5px; }
.cc-o.on .b { background: rgba(255,255,255,.34); }

.cc-bloc { background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px;
  padding: 14px 16px; margin-bottom: 12px; }
.cc-bloc.cc-valider { border-color: var(--accent); }
.cc-tete { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.cc-tete .k { font-size: var(--fs-xs); letter-spacing: .06em; font-weight: 800; color: var(--txt-dim); }
.cc-valider .cc-tete .k { color: var(--accent-text); }

.cc-bon { display: flex; align-items: center; gap: 12px; padding: 10px 0;
  border-top: 1px solid var(--line); flex-wrap: wrap; }
.cc-bon:first-of-type { border-top: 0; }
.cc-bon .c { flex: 1; min-width: 220px; }
.cc-bon .t { font-size: var(--fs-md); font-weight: 600; line-height: 1.35; }
.cc-bon .s { font-size: var(--fs-xs); color: var(--txt-dim); }
.cc-bon .cc-seuil { color: var(--txt-1); font-weight: 600; margin-top: 3px; }
.cc-agir { flex: none; min-height: 44px; }

.cc-lot { margin-bottom: 10px; }
.cc-lot .h { display: flex; justify-content: space-between; gap: 10px; font-size: var(--fs-sm); margin-bottom: 4px; }
.cc-lot .ba { position: relative; height: 10px; background: var(--surface-3); border-radius: 5px; }
.cc-lot .ba.vide { border: 1px dashed var(--line); background: transparent; }
.cc-lot .ba i { display: block; height: 10px; border-radius: 5px;
  background: color-mix(in srgb, var(--accent) 55%, var(--surface-3)); }
.cc-lot .ba u { position: absolute; top: -3px; width: 2px; height: 16px; background: var(--txt-1); }

.cc-bl { display: flex; gap: 10px; align-items: baseline; padding: 5px 0; font-size: var(--fs-sm); }
.cc-bl .sg { font-weight: 800; font-size: var(--fs-xs); white-space: nowrap; flex: none; color: var(--txt-dim); }

.cc-trois { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.cc-trois .l { display: block; font-size: var(--fs-xs); color: var(--txt-dim); }
.cc-trois b { display: block; font-size: var(--fs-2xl); font-weight: 700; line-height: 1.15;
  font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
/* Le montant est le seul chiffre qu'on vient chercher sur cet écran : il domine,
   ou l'écran n'a pas de point d'entrée. Mesuré le 20/08 — il sortait à 17px, la
   même taille que le nom du chantier et que huit autres choses. */
.cc-trois b.neg { color: var(--refuse-text, #B4543A); }
.cc-trois .d { display: block; font-size: var(--fs-xs); color: var(--txt-dim); }
.cc-sentinelle { margin-top: 12px; padding: 10px 12px; border-radius: 9px;
  background: var(--surface-3); border: 1px solid var(--line); font-size: var(--fs-sm); line-height: 1.5; }

.cc-gens { display: flex; flex-wrap: wrap; gap: 6px; }
.cc-p { font-size: var(--fs-sm); padding: 4px 10px; border-radius: 20px; background: var(--surface-3); }
.cc-p.resp { background: color-mix(in srgb, var(--accent) 18%, var(--surface-3)); font-weight: 700; }
.cc-p.ext { border: 1px dashed var(--line); background: transparent; }
.cc-p i { font-style: normal; color: var(--txt-dim); font-size: var(--fs-xs); margin-left: 5px; }
.cc-actes { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.cc-note { font-size: var(--fs-xs); color: var(--txt-dim); line-height: 1.55; margin: 10px 0 0; }

.cc-supp { border: 1px solid var(--line); border-radius: 11px; padding: 12px 14px; margin-bottom: 8px;
  background: var(--surface-2); }
.cc-supp .h { display: flex; gap: 12px; align-items: flex-start; flex-wrap: wrap; }
.cc-supp .c { flex: 1; min-width: 200px; }
.cc-supp .t { font-size: var(--fs-md); font-weight: 600; }
.cc-supp .s { font-size: var(--fs-xs); color: var(--txt-dim); }
.cc-supp .s .nonchiffre { color: var(--refuse-text, #B4543A); }
.cc-supp .d { font-size: var(--fs-sm); color: var(--txt-dim); margin: 8px 0 0; }
.cc-cyc { display: flex; flex-wrap: wrap; gap: 3px; align-items: center; margin-top: 9px; font-size: var(--fs-xs); font-weight: 700; }
.cc-cyc .e { padding: 3px 8px; border-radius: 6px; border: 1px dashed var(--line); color: var(--txt-dim); }
.cc-cyc .e.fait { border-style: solid; background: var(--surface-3); color: var(--txt-1); }
.cc-cyc .e.on { border-style: solid; border-color: var(--accent); color: var(--accent-text);
  background: color-mix(in srgb, var(--accent) 12%, transparent); }
.cc-cyc .e.refuse { border-style: solid; }
.cc-cyc .fl { color: var(--txt-dim); }

.cc-tache { display: flex; gap: 10px; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--line); }
.cc-tache .pt { width: 18px; text-align: center; color: var(--txt-dim); }
.cc-tache .c { flex: 1; min-width: 0; }
.cc-tache .t { font-size: var(--fs-sm); }
.cc-tache .s { font-size: var(--fs-xs); color: var(--txt-dim); }
.cc-tache.faite .t { text-decoration: line-through; color: var(--txt-dim); }
.cc-jl { display: flex; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.cc-jl .d { color: var(--txt-dim); font-size: var(--fs-xs); min-width: 42px; }
.cc-jl .s { color: var(--txt-dim); font-size: var(--fs-xs); }
.cc-cls { display: flex; flex-wrap: wrap; gap: 6px; }
.cc-cl { font-size: var(--fs-xs); padding: 3px 9px; border-radius: 20px; background: var(--surface-3); }
.cc-cl.vide { opacity: .55; border: 1px dashed var(--line); background: transparent; }
.cc-docs, .cc-postes { margin-top: 10px; border-top: 1px solid var(--line); }
.cc-doc, .cc-poste { display: flex; align-items: center; gap: 10px; padding: 8px 0;
  border-bottom: 1px solid var(--line); text-decoration: none; color: inherit; }
.cc-doc .t, .cc-poste .t { flex: 1; min-width: 0; font-size: var(--fs-sm); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.cc-doc .s { font-size: var(--fs-xs); color: var(--txt-dim); }
.cc-poste .go { color: var(--accent-text); font-size: var(--fs-xs); font-weight: 600; }

/* le geste « constater » suit sur tous les onglets — c'est celui qui protège la marge */
.cc-flottant { position: fixed; right: 18px; bottom: 78px; z-index: 40; min-height: 48px;
  padding: 0 18px; border-radius: 24px; border: 0; background: var(--accent); color: var(--on-accent);
  font-size: var(--fs-md); font-weight: 700; cursor: pointer; box-shadow: 0 6px 20px rgba(0,0,0,.22); }

.bap-choix { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 10px; }
.bap-b { min-height: 52px; font-size: var(--fs-md); }
.bap-litige { border: 1px solid var(--line); }

@media (max-width: 640px) {
  .cc-trois { grid-template-columns: 1fr; gap: 6px; }
  .cc-bon .c { min-width: 100%; }
  .cc-agir { width: 100%; }
  .cc-flottant { right: 12px; bottom: 84px; }
}

/* La prise de photo au journal. Sur le chantier on ne cherche pas dans une
   galerie : `capture="environment"` ouvre l'appareil arrière directement.
   Cible large — on l'atteint avec des gants. */
.nj-photos { margin-top: 10px; }
.nj-prendre { display: flex; align-items: center; justify-content: center; min-height: 52px;
  border: 1px dashed var(--line); border-radius: 11px; cursor: pointer; font-size: var(--fs-md);
  font-weight: 600; color: var(--accent-text); background: var(--surface-3); }
.nj-prendre:hover { border-color: var(--accent); }
.nj-vignettes { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.nj-v { width: 108px; display: flex; flex-direction: column; gap: 4px; }
.nj-img { position: relative; width: 108px; height: 78px; border-radius: 9px; overflow: hidden;
  border: 1px solid var(--line); display: block; }
.nj-v img { width: 100%; height: 100%; object-fit: cover; display: block; }
.nj-leg { width: 100%; min-height: 30px; padding: 4px 7px; border: 1px solid var(--line);
  border-radius: 7px; background: var(--surface-2); color: var(--txt); font: 400 var(--fs-xs) var(--ff); }
.nj-leg::placeholder { color: var(--txt-dim); }
.nj-leg:focus { outline: 2px solid var(--focus); outline-offset: 1px; }
.nj-ou { display: block; margin-top: 10px; }
.nj-ou .k { display: block; font-size: var(--fs-xs); font-weight: 600; letter-spacing: .05em;
  text-transform: uppercase; color: var(--txt-dim); margin-bottom: 4px; }
.nj-ou select { width: 100%; min-height: var(--tap); }
/* Les trois natures. Grandes cibles : on choisit avec le pouce, sur un
   chantier. Le mot ET le glyphe ET le fond : jamais la couleur seule. */
.nj-nature { display: flex; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
.nj-n { flex: 1 1 30%; min-width: 104px; min-height: var(--tap-primary);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  padding: 8px 6px; border: 1.5px solid var(--line); border-radius: 10px;
  background: var(--surface-2); color: var(--txt-dim); cursor: pointer; font: inherit; text-align: center; }
.nj-n .g { font-size: var(--fs-lg); line-height: 1; }
.nj-n b { font-size: var(--fs-sm); font-weight: 600; }
.nj-n i { font-style: normal; font-size: var(--fs-xs); color: var(--txt-dim); }
.nj-n.on { border-color: var(--accent); background: var(--accent-soft); color: var(--txt); }
.nj-n.on b { font-weight: 700; }
.nj-n:hover { border-color: var(--line-strong, var(--accent-line)); }
.nj-bloque { margin: 0 0 10px; padding: 8px 10px; border-radius: 8px; background: var(--surface-3);
  font-size: var(--fs-sm); }
.nj-bloque label { display: flex; align-items: center; gap: 8px; cursor: pointer; min-height: var(--tap); }
.nj-demande { margin-top: 10px; padding: 10px 12px; border-radius: 10px;
  background: var(--surface-3); border: 1px solid var(--line); }
.nj-demande .nj-ou { margin-top: 0; margin-bottom: 8px; }
.nj-demande .nj-ou:last-of-type { margin-bottom: 0; }
.nj-devine { margin: 6px 0 0; font-size: var(--fs-sm); color: var(--txt-dim); line-height: 1.5; }
.nj-rappel { margin: 6px 0 0; padding: 8px 10px; border-radius: 8px; background: var(--surface-3);
  border-left: 3px solid var(--accent); border-radius: 0 8px 8px 0;
  font-size: var(--fs-sm); line-height: 1.5; color: var(--txt); }
.nj-v .x { position: absolute; top: 2px; right: 2px; width: 26px; height: 26px; border-radius: 50%;
  border: 0; background: rgba(0,0,0,.62); color: #fff; font-size: var(--fs-sm); cursor: pointer; line-height: 1; }
.cc-bande { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; }
.cc-ph { position: relative; flex: none; width: 128px; height: 96px; border-radius: 10px;
  overflow: hidden; border: 1px solid var(--line); display: block; }
.cc-ph img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cc-ph .lg { position: absolute; left: 0; right: 0; bottom: 0; padding: 3px 6px;
  font-size: var(--fs-xs); color: #fff; background: linear-gradient(transparent, rgba(0,0,0,.72)); }

/* ===== L'aide de chantier =====
   Écran de terrain : gros caractères, cibles larges, lisible à bout de
   bras avec des gants. Le lien humain est EN HAUT — on appelle un homme,
   pas un modèle, quand ça compte. */
.ai-tete { background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px;
  padding: 12px 14px; margin-bottom: 12px; }
.ai-qui .k { font-size: var(--fs-xs); letter-spacing: .05em; text-transform: uppercase; font-weight: 700;
  color: var(--txt-dim); }
.ai-qui .n { font-size: var(--fs-lg); font-weight: 700; margin: 2px 0 8px; }
.ai-ch { font-size: var(--fs-sm); color: var(--txt-dim); margin-top: 8px;
  padding-top: 8px; border-top: 1px solid var(--line); }

.ai-fil { display: flex; flex-direction: column; gap: 10px; max-height: 52vh; overflow-y: auto;
  padding: 2px; margin-bottom: 12px; }
.ai-m { display: flex; flex-direction: column; }
.ai-m.moi { align-items: flex-end; }
.ai-m .b { max-width: 92%; border-radius: 14px; padding: 11px 13px; font-size: var(--fs-md); line-height: 1.5; }
.ai-m.moi .b { background: var(--accent); color: #fff; border-bottom-right-radius: 5px; }
.ai-m.lui .b { background: var(--surface-2); border: 1px solid var(--line); border-bottom-left-radius: 5px; }
.ai-m.lui p { margin: 0; }
.ai-m .cert { font-size: var(--fs-xs); font-weight: 800; letter-spacing: .04em; margin-bottom: 6px; }
.ai-m .cert.sur { color: var(--accent-text); }
.ai-m .cert.verif { color: var(--txt-dim); }
.ai-m .cert.non { color: var(--refuse-text, #B4543A); }
.ai-m .verif { margin-top: 9px; padding-top: 8px; border-top: 1px solid var(--line); font-size: var(--fs-sm); }
.ai-m .verif ul { margin: 5px 0 0; padding-left: 18px; line-height: 1.55; }
.ai-m .demander { margin-top: 9px; padding: 8px 10px; border-radius: 8px; background: var(--surface-3);
  font-size: var(--fs-sm); line-height: 1.5; }
.ai-actes { display: flex; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
.ai-vide { text-align: center; padding: 26px 12px; color: var(--txt-dim); }
.ai-vide p { margin: 6px 0 0; }

.ai-raccourcis { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 12px; }
.ai-r { min-height: 44px; padding: 0 13px; border: 1px solid var(--line); background: var(--surface-2);
  border-radius: 22px; font-size: var(--fs-sm); color: inherit; cursor: pointer; text-align: left; }
.ai-r:hover { border-color: var(--accent); }

.ai-saisie { display: flex; gap: 8px; align-items: flex-end; }
.ai-saisie textarea { flex: 1; font-size: var(--fs-lg); }   /* 16px : iOS ne zoome pas */
.ai-micro { min-width: 52px; min-height: 52px; font-size: var(--fs-lg); }
.ai-env { min-height: 52px; padding: 0 18px; font-size: var(--fs-md); }

@media (max-width: 640px) {
  .ai-fil { max-height: none; }
  .ai-m .b { max-width: 96%; font-size: var(--fs-md); }
  .ai-r { width: 100%; }
}

/* ===== Mon centre — ouvrier et sous-traitant =====
   Écran de poche : gros, contrasté, atteignable avec des gants. L'ordre
   est celui du matin — avant de partir, aujourd'hui, où je vais. */
.mc-bloc { background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px;
  padding: 13px 15px; margin-bottom: 12px; }
.mc-bloc.urgent { border-color: var(--accent); }
.mc-k { display: flex; align-items: center; gap: 9px; font-size: var(--fs-xs); letter-spacing: .06em;
  text-transform: uppercase; font-weight: 800; color: var(--txt-dim); margin-bottom: 10px; }
.mc-k span { font-weight: 400; }
.mc-ok { font-size: var(--fs-md); color: var(--txt-dim); }
.mc-al { display: flex; flex-direction: column; gap: 8px; }
.mc-a { display: flex; gap: 10px; padding: 10px 12px; border-radius: 10px; background: var(--surface-3);
  border-left: 3px solid var(--line); font-size: var(--fs-sm); }
.mc-a.g0 { border-left-color: var(--accent); }
.mc-a .sg { font-weight: 800; font-size: var(--fs-xs); white-space: nowrap; flex: none; color: var(--txt-dim); }
.mc-a .s { font-size: var(--fs-sm); color: var(--txt-dim); margin-top: 2px; }

.mc-t { display: flex; gap: 10px; align-items: flex-start; padding: 10px 0;
  border-top: 1px solid var(--line); flex-wrap: wrap; }
.mc-t:first-of-type { border-top: 0; }
.mc-t.gros .t { font-size: var(--fs-md); font-weight: 700; }
.mc-t .c { flex: 1; min-width: 200px; }
.mc-t .t { font-size: var(--fs-md); font-weight: 600; line-height: 1.35; }
.mc-t .s { font-size: var(--fs-xs); color: var(--txt-dim); }
.mc-t .s.note { font-style: italic; }
.mc-t .s.st { color: var(--txt-1); margin-top: 3px; }
.mc-t.faite .t { text-decoration: line-through; color: var(--txt-dim); }
.mc-actes { display: flex; gap: 7px; flex-wrap: wrap; flex: none; }
.mc-actes .btn { min-height: 44px; }

.mc-chs { display: flex; flex-direction: column; gap: 10px; }
.mc-ch { display: flex; gap: 10px; align-items: flex-start; padding: 10px 0;
  border-top: 1px solid var(--line); flex-wrap: wrap; }
.mc-ch:first-child { border-top: 0; }
.mc-ch .c { flex: 1; min-width: 190px; }
.mc-ch .t { font-size: var(--fs-md); font-weight: 600; }
.mc-ch .s { font-size: var(--fs-sm); color: var(--txt-dim); }

.mc-gestes { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.mc-gestes .btn { min-height: 52px; font-size: var(--fs-md); }
.mc-bdc, .mc-sp { display: flex; gap: 10px; align-items: center; padding: 9px 0;
  border-top: 1px solid var(--line); }
.mc-bdc:first-of-type, .mc-sp:first-of-type { border-top: 0; }
.mc-bdc .c, .mc-sp .c { flex: 1; min-width: 0; }
.mc-bdc .t, .mc-sp .t { font-size: var(--fs-sm); font-weight: 600; }
.mc-bdc .s, .mc-sp .s { font-size: var(--fs-xs); color: var(--txt-dim); }
.mc-note { font-size: var(--fs-xs); color: var(--txt-dim); line-height: 1.5; margin: 10px 0 0; }

@media (max-width: 640px) {
  .mc-t .c, .mc-ch .c { min-width: 100%; }
  .mc-actes { width: 100%; }
  .mc-actes .btn { flex: 1; }
}

/* ===== Tableau de bord planning =====
   Il explique, documente, informe — il ne bloque pas. La règle des 15
   jours est écrite en tête, et chaque état porte un signe ET un mot. */
.pb-regle { background: var(--surface-2); border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: 12px; padding: 14px 16px; margin-bottom: 12px; }
.pb-regle .k { font-size: var(--fs-xs); letter-spacing: .06em; text-transform: uppercase; font-weight: 800;
  color: var(--accent-text); margin-bottom: 6px; }
.pb-regle p { margin: 0 0 6px; font-size: var(--fs-md); line-height: 1.55; }
.pb-regle p.s { font-size: var(--fs-sm); color: var(--txt-dim); margin: 0; }

.pb-alerte, .pb-info { border: 1px solid var(--line); border-radius: 11px; padding: 11px 14px;
  margin-bottom: 10px; font-size: var(--fs-sm); background: var(--surface-2); }
.pb-alerte { border-left: 3px solid var(--accent); }
.pb-alerte .s, .pb-info .s { font-size: var(--fs-sm); color: var(--txt-dim); margin-top: 3px; }

.pb-liste { display: flex; flex-direction: column; gap: 10px; }
.pb-l { display: flex; gap: 12px; align-items: flex-start; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; flex-wrap: wrap; }
.pb-l .c { flex: 1; min-width: 240px; }
.pb-l .t { font-size: var(--fs-md); font-weight: 600; line-height: 1.3; }
.pb-l .s { font-size: var(--fs-sm); color: var(--txt-dim); margin-top: 2px; }
.pb-l .s.manque { color: var(--txt-1); }
.pb-l .s.gliss { font-weight: 600; color: var(--txt-1); }
.pb-l .s.ok { color: var(--accent-text); }
.pb-etat { flex: none; }
.pb-p { display: inline-block; font-size: var(--fs-xs); font-weight: 700; padding: 4px 10px; border-radius: 20px;
  background: var(--surface-3); border: 1px solid var(--line); white-space: nowrap; }
.pb-p.pret { border-color: var(--accent); color: var(--accent-text); }
.pb-p.non_verifie { border-style: dashed; color: var(--txt-dim); }
.pb-p.reporte { border-style: dotted; }
.pb-actes { display: flex; gap: 6px; flex-wrap: wrap; flex: none; }
.pb-actes .btn { min-height: 40px; }

.gl-impact { margin-top: 10px; }
.gl-warn { border: 1px solid var(--line); border-left: 3px solid var(--accent); border-radius: 9px;
  padding: 10px 12px; font-size: var(--fs-sm); line-height: 1.5; background: var(--surface-3); }
.gl-warn ul { margin: 6px 0; padding-left: 18px; }
.gl-ok { font-size: var(--fs-sm); color: var(--txt-dim); padding: 8px 0; }

@media (max-width: 700px) {
  .pb-l .c { min-width: 100%; }
  .pb-actes { width: 100%; }
  .pb-actes .btn { flex: 1; }
}

/* ===== Les centres par rôle — deviseur, client, admin =====
   Même colonne vertébrale que le centre de chantier : ce qui attend une
   décision passe devant, et disparaît quand la file est vide. */
.cr-bloc { background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px;
  padding: 13px 15px; margin-bottom: 12px; }
.cr-bloc.urgent { border-color: var(--accent); }
.cr-k { display: flex; align-items: center; gap: 9px; font-size: var(--fs-xs); letter-spacing: .06em;
  text-transform: uppercase; font-weight: 800; color: var(--txt-dim); margin-bottom: 10px; }
.cr-bloc.urgent .cr-k { color: var(--accent-text); }
.cr-k span { font-weight: 400; }
.cr-k2 { font-size: var(--fs-xs); font-weight: 700; color: var(--txt-dim); margin: 12px 0 6px; }

.cr-l { display: flex; gap: 12px; align-items: center; padding: 9px 0;
  border-top: 1px solid var(--line); flex-wrap: wrap; }
.cr-l:first-of-type { border-top: 0; }
.cr-l .c { flex: 1; min-width: 220px; }
.cr-l .t { font-size: var(--fs-md); font-weight: 600; line-height: 1.35; }
.cr-l .t a { color: var(--accent-text); text-decoration: none; }
.cr-l .s { font-size: var(--fs-xs); color: var(--txt-dim); }
.cr-l .s .rouge { color: var(--refuse-text, #B4543A); }
.cr-actes { display: flex; gap: 6px; flex-wrap: wrap; flex: none; }
.cr-actes .btn { min-height: 40px; }

.cr-trois { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.cr-kpi { display: block; padding: 10px 12px; border-radius: 10px; background: var(--surface-3);
  text-decoration: none; color: inherit; }
.cr-kpi b { display: block; font-size: var(--fs-xl); font-variant-numeric: tabular-nums; }
.cr-kpi span { font-size: var(--fs-xs); color: var(--txt-dim); }

.cr-gros { font-size: var(--fs-3xl); font-weight: 800; font-variant-numeric: tabular-nums; line-height: 1; }
.cr-ba { height: 12px; background: var(--surface-3); border-radius: 6px; margin: 10px 0 12px; }
.cr-ba i { display: block; height: 12px; border-radius: 6px; background: var(--accent); }
.cr-lots { display: flex; flex-direction: column; gap: 6px; }
.cr-lot { display: flex; justify-content: space-between; font-size: var(--fs-sm);
  padding: 5px 0; border-bottom: 1px solid var(--line); }
.cr-lot .p { font-variant-numeric: tabular-nums; color: var(--txt-dim); }

.cr-j { display: flex; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.cr-j .d { color: var(--txt-dim); font-size: var(--fs-xs); min-width: 44px; }
.cr-j .s { color: var(--txt-dim); font-size: var(--fs-xs); }
.cr-note { font-size: var(--fs-xs); color: var(--txt-dim); line-height: 1.55; margin: 10px 0 0; }
.cr-info { border: 1px solid var(--line); border-left: 3px solid var(--accent); border-radius: 10px;
  padding: 11px 13px; margin-bottom: 12px; font-size: var(--fs-sm); line-height: 1.55; background: var(--surface-2); }

@media (max-width: 640px) {
  .cr-l .c { min-width: 100%; }
  .cr-actes { width: 100%; }
  .cr-actes .btn { flex: 1; }
}
.cr-choix { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-bottom: 12px; }
.cr-choix .k { font-size: var(--fs-xs); letter-spacing: .05em; text-transform: uppercase; font-weight: 800;
  color: var(--txt-dim); margin-right: 4px; }
.cr-c { font-size: var(--fs-sm); padding: 6px 12px; border-radius: 20px; border: 1px solid var(--line);
  background: var(--surface-2); text-decoration: none; color: inherit; }
.cr-c.on { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }

/* ===== Ce qui relie les cinq centres =====
   (préfixe `lien-` et non `ch-` : `.ch-fil` appartient déjà au fil du
   chat, en colonne — la collision dessinait la chaîne à la verticale)
   Le trajet d'un objet, avec le RÔLE de chaque étape — c'est le rôle qui
   fait le lien. Fait ✓, ici ■, à venir ○ : forme + mot, jamais couleur
   seule. Une étape faite ou courante est cliquable : elle ouvre le centre
   de celui qui l'a tenue. */
.lien-fil { display: flex; flex-wrap: wrap; align-items: center; gap: 3px; margin: 8px 0 0; }
/* inline-flex, sinon chaque étape prend toute la largeur et la chaîne
   se dessine en colonne — elle doit se lire d'un trait, de gauche à droite. */
.lien-e { display: inline-flex; text-decoration: none; color: inherit; }
.lien-fil .e { display: inline-flex; flex-direction: column; gap: 0; padding: 4px 9px; border-radius: 8px;
  border: 1px dashed var(--line); min-width: 72px; line-height: 1.25; }
.lien-fil .e .p { font-size: var(--fs-xs); font-weight: 800; line-height: 1.1; }
.lien-fil .e .t { font-size: var(--fs-xs); font-weight: 700; line-height: 1.2; }
.lien-fil .e .r { font-size: var(--fs-xs); color: var(--txt-dim); text-transform: uppercase; letter-spacing: .04em; }
.lien-fil .e.fait { border-style: solid; background: var(--surface-3); }
.lien-fil .e.ici { border-style: solid; border-color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.lien-fil .e.ici .t { color: var(--accent-text); }
.lien-fil .e.apres { opacity: .6; }
.lien-fil .e.rompu { border-style: solid; }
.lien-fil .fl { align-self: center; color: var(--txt-dim); font-size: var(--fs-sm); }
.lien-fil.compact .e { min-width: 0; padding: 4px 7px; }
.lien-fil.compact .e .r { display: none; }
.ch-ph { font-size: var(--fs-sm); color: var(--txt-dim); margin-top: 6px; }
a.lien-e:hover .e { border-color: var(--accent); }

.vu-par { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 0 0 12px; }
.vu-par .k { font-size: var(--fs-xs); letter-spacing: .05em; text-transform: uppercase; font-weight: 800;
  color: var(--txt-dim); margin-right: 2px; }
.vu { font-size: var(--fs-sm); padding: 5px 11px; border-radius: 20px; border: 1px solid var(--line);
  background: var(--surface-2); text-decoration: none; color: inherit; }
.vu:hover { border-color: var(--accent); }
.vu.on { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }

/* ===== Les équipes =====
   L'équipe d'un chef est durable ; les actifs d'un chantier changent
   chaque semaine. L'écran doit rendre la différence évidente. */
.eq-bloc { background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px;
  margin-bottom: 12px; overflow: hidden; }
.eq-bloc.urgent { border-color: var(--accent); }
.eq-tete { width: 100%; display: flex; align-items: center; gap: 12px; padding: 12px 15px;
  background: none; border: 0; cursor: pointer; color: inherit; text-align: left; flex-wrap: wrap; }
.eq-tete.statique { cursor: default; }
.eq-tete:not(.statique):hover { background: var(--surface-3); }
.eq-tete .n { font-size: var(--fs-md); font-weight: 700; }
.eq-tete .m { font-size: var(--fs-sm); color: var(--txt-dim); }
.eq-tete .al { display: flex; gap: 8px; flex-wrap: wrap; margin-left: auto; }
.eq-tete .w { font-size: var(--fs-xs); font-weight: 700; color: var(--txt-dim); }
.eq-tete .chev { color: var(--txt-dim); }

.eq-gens { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 15px 12px; }
.eq-p { display: inline-flex; flex-direction: column; gap: 1px; font-size: var(--fs-sm); padding: 5px 11px;
  border-radius: 12px; background: var(--surface-3); border: 1px solid transparent; }
.eq-p.chef { background: color-mix(in srgb, var(--accent) 18%, var(--surface-3)); font-weight: 700; }
.eq-p.ext { border-style: dashed; border-color: var(--line); background: transparent; }
.eq-p.libre { cursor: pointer; border: 1px dashed var(--line); background: transparent; color: inherit;
  text-align: left; font-family: inherit; }
.eq-p.libre:hover { border-color: var(--accent); }
.eq-p i { font-style: normal; color: var(--txt-dim); font-size: var(--fs-xs); }

.eq-ch { padding: 0 15px 12px; font-size: var(--fs-sm); color: var(--txt-dim); }
.eq-ch a { color: var(--accent-text); text-decoration: none; }
.eq-taches { padding: 0 15px 12px; border-top: 1px solid var(--line); }
.eq-t { display: flex; gap: 12px; align-items: flex-start; padding: 10px 0;
  border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.eq-t .c { flex: 1; min-width: 230px; }
.eq-t .t { font-size: var(--fs-md); font-weight: 600; line-height: 1.35; }
.eq-t .s { font-size: var(--fs-xs); color: var(--txt-dim); }
.eq-t .s.manque { font-style: italic; }
.eq-actes { display: flex; gap: 6px; flex-wrap: wrap; flex: none; }
.eq-actes .btn { min-height: 40px; }

.eq-bs { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; margin-top: 5px; }
.eq-bs .k { font-size: var(--fs-xs); letter-spacing: .05em; text-transform: uppercase; font-weight: 800;
  color: var(--txt-dim); }
.eq-bs .b { font-size: var(--fs-xs); padding: 2px 8px; border-radius: 10px; background: var(--surface-3); }

.eq-note { font-size: var(--fs-xs); color: var(--txt-dim); line-height: 1.5; padding: 0 15px 12px; margin: 0; }
.eq-ranger { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 14px 0; }
.eq-ranger .k { font-size: var(--fs-xs); letter-spacing: .05em; text-transform: uppercase; font-weight: 800;
  color: var(--txt-dim); width: 100%; }
.eq-c { font-size: var(--fs-sm); padding: 6px 12px; border-radius: 20px; border: 1px solid var(--line);
  background: var(--surface-2); cursor: pointer; color: inherit; }
.eq-c:hover { border-color: var(--accent); }

@media (max-width: 640px) {
  .eq-t .c { min-width: 100%; }
  .eq-actes { width: 100%; }
  .eq-actes .btn { flex: 1; }
  .eq-tete .al { margin-left: 0; width: 100%; }
}

/* ===== La planche à signer =====
   Le client signe au doigt, sur le téléphone de l'ouvrier. Le texte lu
   est au-dessus — c'est lui qui fait foi, pas une reformulation. */
.sg-texte { background: var(--surface-3); border: 1px solid var(--line); border-radius: 10px;
  padding: 12px 14px; font-size: var(--fs-md); line-height: 1.6; margin-bottom: 10px; }
.sg-zone { position: relative; margin-top: 8px; }
.sg-zone canvas { width: 100%; height: 190px; display: block; border: 1px dashed var(--line);
  border-radius: 11px; background: var(--surface-1); touch-action: none; cursor: crosshair; }
.sg-eff { position: absolute; top: 8px; right: 10px; min-height: 34px; padding: 0 12px;
  border-radius: 8px; border: 1px solid var(--line); background: var(--surface-2);
  font-size: var(--fs-xs); cursor: pointer; color: var(--txt-dim); }

/* Sortie de la console — Odoo, Knowledge. La flèche dit « nouvel onglet »
   sans dépendre de la couleur : Denis est daltonien, un lien bleu ne
   signale rien pour lui. (18/08) */
.acc-i .ext, .plan-i .ext { margin-left: auto; font-size: var(--fs-xs); color: var(--txt-faint); }
.plan-i .ext { margin-left: 4px; }

/* ── Onglet Travaux du centre de contrôle : filtres et kanban ───────────
   Repris de l'ancienne application (/otra/planning). Le statut se lit au
   signe et au mot ; la couleur ne porte jamais l'information seule. */
.cc-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 12px; }
.cc-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface-2);
  color: var(--txt-2); font-size: var(--fs-sm); line-height: 1.6;
}
.cc-chip:hover { border-color: var(--line-strong); color: var(--txt); }
.cc-chip.on { background: var(--surface-3); border-color: var(--txt-3); color: var(--txt); font-weight: 600; }
.cc-chip i { font-style: normal; color: var(--txt-faint); font-variant-numeric: tabular-nums; }
.cc-chip.on i { color: var(--txt-2); }

.cc-kb { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 6px; }
.cc-kbc {
  flex: 1 0 240px; min-width: 240px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--surface-2);
}
.cc-kbc > .h {
  padding: 8px 10px; font-size: var(--fs-xs); letter-spacing: .04em; text-transform: uppercase;
  color: var(--txt-2); border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 6px;
}
.cc-kbc > .h i { font-style: normal; margin-left: auto; color: var(--txt-faint); font-variant-numeric: tabular-nums; }
.cc-kbc > .b { max-height: 62vh; overflow-y: auto; }
.cc-tache.kb { padding: 8px 10px; }
.cc-tache.kb .pt { margin-top: 2px; }

/* En colonne kanban, la carte n'a plus la largeur d'une ligne de liste :
   le bouton « confier » passe dessous au lieu d'être rogné. */
.cc-tache.kb { flex-wrap: wrap; align-items: flex-start; gap: 6px; }
.cc-tache.kb .c { flex: 1 1 0; min-width: 0; }           /* reste sur la ligne du signe */
.cc-tache.kb .btn { flex-basis: 100%; margin-left: 24px; margin-top: 4px; align-self: flex-start; }
.cc-tache.kb .t { white-space: normal; overflow-wrap: anywhere; }
/* quatre colonnes doivent tenir dans la zone : 200 px suffisent pour un
   intitulé de tâche sur deux lignes */
.cc-kbc { flex: 1 1 0; min-width: 200px; }

/* ── Accès directs : le voisinage de l'objet ouvert ─────────────────────
   Denis, 18/08 : « est-ce que dans les pages ici on peut avoir les liens
   vers les autres directement ». Ce n'est pas un menu de plus, c'est ce qui
   entoure l'objet : le chantier porte son devis, sa synthèse, son bon. */
.acces {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 8px 0 12px; border-bottom: 1px solid var(--line); margin-bottom: 14px;
}
.acces .k {
  font-size: var(--fs-xs); letter-spacing: .06em; text-transform: uppercase;
  color: var(--txt-faint); margin-right: 4px;
}
.acces-i {
  display: inline-flex; align-items: center;
  padding: 3px 9px; border-radius: 999px; font-size: var(--fs-sm); line-height: 1.7;
  border: 1px solid var(--line); background: var(--surface-2);
  color: var(--txt-2); text-decoration: none;
}
.acces-i:hover { border-color: var(--line-strong); color: var(--txt); }
/* La page courante se marque au trait ET au mot (aria-current), jamais à la
   seule couleur — Denis est daltonien. */
.acces-i.on {
  background: var(--surface-3); border-color: var(--txt-3);
  color: var(--txt); font-weight: 600; cursor: default;
}
.acces-i.on::before { content: "▸ "; color: var(--txt-faint); }
@media (max-width: 700px) {
  .acces { overflow-x: auto; flex-wrap: nowrap; padding-bottom: 10px; }
  .acces-i { white-space: nowrap; }
}

/* Le rappel de référence de dossier. Denis, 18/08 : « dans tous les
   documents, les messages, on retrouve la réf chantier ; on rappelle
   l'importance de la nommer aux différents protagonistes ». 482 factures
   fournisseurs sur 525 n'ont pas de bon de commande — cette référence est
   le seul fil qui reste pour les rattacher. */
.rappel-ref {
  border: 1px solid var(--line-strong); border-left-width: 3px;
  background: var(--surface-2); border-radius: 6px;
  padding: 9px 12px; margin: 10px 0; font-size: var(--fs-sm); line-height: 1.55;
  color: var(--txt-2);
}
.rappel-ref b { color: var(--txt); }

/* ── La visite de chantier ──────────────────────────────────────────────
   Écran de terrain : cibles larges, une main, parfois des gants. Un constat
   se coche d'un geste et se lit au signe ✓ autant qu'au fond — Denis est
   daltonien, la couleur ne dit jamais seule qu'une case est cochée. */
.vi-fam { margin-bottom: 18px; }
.vi-grille { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.vi-c {
  display: flex; align-items: flex-start; gap: 10px; text-align: left;
  padding: 11px 12px; border-radius: 10px; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--txt-2);
  min-height: 52px; line-height: 1.35;
}
.vi-c:hover { border-color: var(--line-strong); }
.vi-c.on { background: var(--surface-3); border-color: var(--txt-3); color: var(--txt); }
.vi-c .ck {
  flex: 0 0 22px; height: 22px; border-radius: 5px; margin-top: 1px;
  border: 1.5px solid var(--txt-faint); display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-sm); font-weight: 700;
}
.vi-c.on .ck { border-color: var(--txt); background: var(--txt); color: var(--surface); }
.vi-c .l { display: flex; flex-direction: column; gap: 2px; }
.vi-c .l b { font-weight: 600; font-size: var(--fs-sm); }
.vi-c .l i { font-style: normal; font-size: var(--fs-xs); color: var(--txt-faint); }

.vi-mesures { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
.vi-dictee { margin-bottom: 4px; }

.vi-angle { margin-bottom: 20px; }
.vi-p { display: flex; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--line); }
.vi-p .g {
  flex: 0 0 92px; font-size: var(--fs-xs); letter-spacing: .03em; text-transform: uppercase;
  color: var(--txt-faint); padding-top: 2px;
}
.vi-p .t { font-size: var(--fs-sm); font-weight: 600; }
.vi-p .s { font-size: var(--fs-sm); color: var(--txt-dim); line-height: 1.5; }

/* sur téléphone, une colonne et des cibles plus hautes */
@media (max-width: 700px) {
  .vi-grille, .vi-mesures { grid-template-columns: 1fr; }
  .vi-c { min-height: 58px; padding: 13px 12px; }
  .vi-p { flex-direction: column; gap: 2px; }
  .vi-p .g { flex: none; }
}

/* La recherche de client dans le dialogue de visite : une liste courte,
   cliquable, qui remplace la saisie plutôt que de s'y ajouter. */
.vi-res { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.vi-r {
  display: flex; flex-direction: column; gap: 1px; text-align: left; cursor: pointer;
  padding: 7px 10px; border-radius: 8px; border: 1px solid var(--line);
  background: var(--surface-2); color: var(--txt-2);
}
.vi-r:hover { border-color: var(--txt-3); color: var(--txt); }
.vi-r b { font-size: var(--fs-sm); font-weight: 600; }
.vi-r i { font-style: normal; font-size: var(--fs-xs); color: var(--txt-faint); }

/* Le guide et l'état de santé. Le statut se lit au signe ET au mot —
   jamais à la couleur seule. */
.gd-tete { margin: 4px 0 14px; }
.gd-tete .k { font-size: var(--fs-xs); letter-spacing: .05em; text-transform: uppercase; color: var(--txt-faint); }
.gd-tete .ph { font-size: var(--fs-lg); margin: 4px 0 0; }
.gd-etapes { display: flex; flex-direction: column; gap: 2px; }
.gd-e { display: flex; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.gd-e .n {
  flex: 0 0 26px; height: 26px; border-radius: 50%; border: 1px solid var(--line-strong);
  display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-xs); color: var(--txt-2); font-variant-numeric: tabular-nums;
}
.gd-e .t { font-size: var(--fs-md); font-weight: 600; margin-bottom: 2px; }
.gd-e .d { font-size: var(--fs-sm); color: var(--txt-2); line-height: 1.55; }
.gd-crayon, .gd-manque {
  margin-top: 20px; padding: 14px 16px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--surface-2);
}
.gd-crayon .k, .gd-manque .k {
  font-size: var(--fs-xs); letter-spacing: .05em; text-transform: uppercase;
  color: var(--txt-faint); margin-bottom: 6px;
}
.gd-crayon p { font-size: var(--fs-sm); margin: 0 0 8px; }
.gd-crayon .fort { border-left: 3px solid var(--txt-3); padding-left: 10px; margin-top: 12px; }
.gd-manque ul { margin: 0 0 8px; padding-left: 18px; font-size: var(--fs-sm); }

.sa-g { margin-bottom: 18px; }
.sa-l { display: flex; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--line); }
.sa-l .sg {
  flex: 0 0 152px; font-size: var(--fs-xs); letter-spacing: .03em; text-transform: uppercase;
  color: var(--txt-faint); padding-top: 2px;
}
.sa-l.casse .sg { color: var(--txt); font-weight: 700; }
.sa-l .t { font-size: var(--fs-sm); }
.sa-l .t code { font-size: var(--fs-sm); }
.sa-l .s { font-size: var(--fs-sm); color: var(--txt-dim); }
@media (max-width: 700px) { .sa-l { flex-direction: column; gap: 2px; } .sa-l .sg { flex: none; } }

/* Les outils de la barre du haut : les discussions et le guide. Ils sont là
   sur tous les écrans — ce qu'on cherche quand on est perdu ou qu'on a
   quelque chose à dire ne se range pas au fond d'un menu replié. */
.tb-outils { display: inline-flex; align-items: center; gap: 6px; }
.tb-o {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 8px; cursor: pointer; text-decoration: none;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--txt-2);
  font-size: var(--fs-md); line-height: 1;
}
.tb-o:hover { border-color: var(--line-strong); color: var(--txt); }
.tb-o .n {
  position: absolute; top: -5px; right: -5px; min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 9px; background: var(--txt); color: var(--surface);
  font-size: var(--fs-xs); font-weight: 700; display: flex; align-items: center; justify-content: center;
}

.tb-panneau {
  position: fixed; top: 54px; right: 14px; z-index: 80; width: min(340px, calc(100vw - 28px));
  max-height: 70vh; overflow: auto; border-radius: 12px;
  border: 1px solid var(--line-strong); background: var(--surface); box-shadow: 0 12px 40px rgba(0,0,0,.28);
}
.tb-panneau .tete {
  display: flex; align-items: center; padding: 10px 12px; border-bottom: 1px solid var(--line);
  position: sticky; top: 0; background: var(--surface);
}
.tb-panneau .tete .x {
  margin-left: auto; border: 0; background: none; cursor: pointer;
  color: var(--txt-faint); font-size: var(--fs-lg); line-height: 1; padding: 0 4px;
}
.tb-c {
  display: flex; align-items: center; gap: 8px; padding: 10px 12px; text-decoration: none;
  border-bottom: 1px solid var(--line); color: var(--txt-2); font-size: var(--fs-sm);
}
.tb-c:hover { background: var(--surface-2); color: var(--txt); }
.tb-c.neuf .t { font-weight: 700; color: var(--txt); }
.tb-c .t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tb-c .n {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--txt); color: var(--surface);
  font-size: var(--fs-xs); font-weight: 700; display: flex; align-items: center; justify-content: center;
}

/* La fiche du chantier : ce qu'on lit d'un coup d'œil, et les puces
   d'intervenants qu'on retire d'un geste. */
.fi-grille { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.fi-grille > div { display: flex; flex-direction: column; gap: 2px; }
.fi-grille .l { font-size: var(--fs-xs); letter-spacing: .04em; text-transform: uppercase; color: var(--txt-dim); }
.fi-grille b { font-size: var(--fs-md); }
.fi-grille .s { font-size: var(--fs-xs); color: var(--txt-dim); }
.fi-grille .manque { color: var(--txt-dim); font-weight: 400; font-style: italic; }

.fi-l { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.fi-p {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 6px 4px 10px;
  border-radius: 999px; border: 1px solid var(--line); background: var(--surface-2);
  font-size: var(--fs-sm); color: var(--txt-2);
}
.fi-p button {
  border: 0; background: none; cursor: pointer; color: var(--txt-faint);
  font-size: var(--fs-xs); line-height: 1; padding: 2px 4px;
}
.fi-p button:hover { color: var(--txt); }
.fi-cl { border-left: 3px solid var(--line-strong); padding-left: 12px; }

/* Le comparatif. Le score se lit aux barres ET au chiffre : un dégradé de
   couleurs ne dirait rien à un daltonien, et c'est le lecteur principal. */
.cp-doms { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 14px; }
.cp-f {
  border: 1px solid var(--line); border-radius: 10px; background: var(--surface-2);
  padding: 12px 14px; margin-bottom: 10px;
}
.cp-f.d-faire { border-left: 3px solid var(--txt); }
.cp-f.d-plus_tard { border-left: 3px solid var(--txt-3); }
.cp-f.d-non { opacity: .62; }
.cp-t { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.cp-t b { font-size: var(--fs-md); }
.cp-e, .cp-a {
  font-size: var(--fs-xs); letter-spacing: .03em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 999px; border: 1px solid var(--line-strong); color: var(--txt-2);
}
.cp-a { border-style: dashed; }

.cp-s { display: flex; flex-wrap: wrap; gap: 16px; margin-bottom: 10px; }
.cp-c { display: inline-flex; align-items: center; gap: 7px; }
.cp-c .n { font-size: var(--fs-xs); color: var(--txt-faint); min-width: 58px; }
.cp-c.nous .n { color: var(--txt-2); font-weight: 600; }
.cp-j { display: inline-flex; align-items: center; gap: 3px; }
.cp-j i { width: 13px; height: 8px; border-radius: 2px; background: var(--surface-3); display: block; }
.cp-j i.on { background: var(--txt-3); }
.cp-c.nous .cp-j i.on { background: var(--txt); }
.cp-j b { font-size: var(--fs-xs); color: var(--txt-faint); margin-left: 3px; font-variant-numeric: tabular-nums; }

.cp-avis { display: grid; gap: 8px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); margin-bottom: 10px; }
.cp-avis > div { font-size: var(--fs-sm); line-height: 1.55; color: var(--txt-2); padding-left: 10px; }
.cp-avis .g { border-left: 2px solid var(--txt-3); }
.cp-avis .m { border-left: 2px dashed var(--txt-faint); }
.cp-avis .q {
  display: block; font-size: var(--fs-xs); letter-spacing: .06em; text-transform: uppercase;
  color: var(--txt-faint); margin-bottom: 2px;
}
.cp-d { display: flex; flex-wrap: wrap; gap: 6px; }
.cp-b {
  padding: 5px 11px; border-radius: 999px; cursor: pointer; font-size: var(--fs-sm);
  border: 1px solid var(--line); background: var(--surface); color: var(--txt-2);
}
.cp-b:hover { border-color: var(--line-strong); color: var(--txt); }
.cp-b.on { background: var(--txt); color: var(--surface); border-color: var(--txt); font-weight: 600; }
.cp-b.eff { border: 0; color: var(--txt-faint); }
@media (max-width: 700px) { .cp-avis { grid-template-columns: 1fr; } }

/* L'état d'enregistrement du comparatif. Il se lit au signe et au mot :
   un point de couleur ne dit pas si c'est parti. */
.cp-etat { font-size: var(--fs-sm); color: var(--txt-faint); white-space: nowrap; align-self: center; }
.cp-etat.ecrit { color: var(--txt-2); }
.cp-etat.echec { color: var(--txt); font-weight: 700; }
.cp-etat.en_cours { font-style: italic; }

/* Les calculettes : des cartes qu'on choisit, puis des champs et un tableau.
   Cibles larges — on s'en sert aussi une tablette à la main sur un chantier. */
.ca-grille { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); }
.ca-c {
  display: flex; flex-direction: column; gap: 3px; text-align: left; cursor: pointer;
  padding: 12px 14px; border-radius: 10px; min-height: 62px;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--txt-2);
}
.ca-c:hover { border-color: var(--txt-3); color: var(--txt); }
.ca-c b { font-size: var(--fs-md); font-weight: 600; }
.ca-c i { font-style: normal; font-size: var(--fs-xs); color: var(--txt-faint); line-height: 1.45; }
.ca-champs { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
@media (max-width: 700px) { .ca-grille, .ca-champs { grid-template-columns: 1fr; } }

/* La commande fournisseur : des lignes qu'on coche, quantité d'abord —
   c'est ce qu'on lit en premier au comptoir. */
.cf-lignes { max-height: 260px; overflow: auto; border: 1px solid var(--line); border-radius: 8px; }
.cf-l {
  display: grid; grid-template-columns: 24px 64px 54px 1fr; gap: 8px; align-items: center;
  padding: 7px 10px; border-bottom: 1px solid var(--line); cursor: pointer; font-size: var(--fs-sm);
}
.cf-l:last-child { border-bottom: 0; }
.cf-l.off { opacity: .45; }
.cf-l .q { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
.cf-l .u { color: var(--txt-faint); font-size: var(--fs-xs); }
.cf-l .d { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* La réception : une ligne par article, la quantité à droite, et le cas
   « piloté par le stock » dit au lieu d'un champ qui ne prendrait pas. */
.re-l {
  display: grid; grid-template-columns: 1fr 200px 110px; gap: 10px; align-items: center;
  padding: 9px 10px; border-bottom: 1px solid var(--line); font-size: var(--fs-sm);
}
.re-l:last-child { border-bottom: 0; }
.re-l.auto { opacity: .6; }
.re-l .d { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.re-l .c { font-size: var(--fs-xs); color: var(--txt-dim); }
.re-l input { text-align: right; }
@media (max-width: 700px) { .re-l { grid-template-columns: 1fr; gap: 4px; } }

/* ═══ L'arbre des lots, la sélection et la fiche latérale ═══════════════
   Denis, 18/08 : « permettre de glisser des tâches, de sélectionner par
   section de lot, de mettre un pourcentage global sur les différents lots,
   et une fiche onglet à droite qui apparaissait — très facile ».

   Contrainte de toujours : la couleur ne dit rien seule. Un lot sélectionné
   porte une barre à gauche ET sa case cochée ; une colonne qui accueille un
   glissé porte un liseré ET un décalage ; l'avancement se lit à la jauge ET
   au chiffre écrit à côté. */

.cc-lot { border: 1px solid var(--line); border-radius: 10px; margin: 0 0 8px; background: var(--surface); }
.cc-lot.n2 { margin: 6px 0 6px 14px; background: var(--surface-2); }
.cc-lot.n3 { margin-left: 14px; }
.cc-lot > .h {
  display: flex; align-items: center; gap: 8px; padding: 8px 10px;
  border-bottom: 1px solid var(--line);
}
.cc-lot.replie > .h { border-bottom: 0; }
.cc-lot.n1 > .h { background: var(--surface-3); border-radius: 9px 9px 0 0; }
.cc-lot.n1.replie > .h { border-radius: 9px; }
.cc-lot > .h .t { flex: 1 1 auto; min-width: 0; font-weight: 600; font-size: var(--fs-sm);
  overflow-wrap: anywhere; }
.cc-lot.n2 > .h .t { font-weight: 500; font-size: var(--fs-sm); }
.cc-lot > .h .n { font-size: var(--fs-xs); color: var(--txt-2); white-space: nowrap;
  font-variant-numeric: tabular-nums; }
.cc-lot > .h .j { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.cc-lot > .h .j b { font-variant-numeric: tabular-nums; font-size: var(--fs-sm); min-width: 40px;
  text-align: right; }
.cc-lot > .b { padding: 6px 8px 8px; }
.cc-lot .pli {
  border: 0; background: none; cursor: pointer; color: var(--txt-2);
  font-size: var(--fs-sm); padding: 2px 4px; line-height: 1;
}
.cc-lot .pli:hover { color: var(--txt); }

.cc-jauge { display: inline-block; width: 74px; height: 7px; border-radius: 999px;
  background: var(--surface-3); border: 1px solid var(--line); overflow: hidden; vertical-align: middle; }
.cc-jauge i { display: block; height: 100%; background: var(--accent); }

.cc-code { font-variant-numeric: tabular-nums; color: var(--txt-2); font-weight: 600;
  font-size: var(--fs-xs); margin-right: 2px; }

.cc-diverge { margin: 0; padding: 6px 10px 8px 34px; font-size: var(--fs-sm); color: var(--txt-2);
  border-bottom: 1px solid var(--line); }

.cc-ck { display: inline-flex; align-items: center; cursor: pointer; padding: 2px; }
.cc-ck input { width: 15px; height: 15px; cursor: pointer; accent-color: var(--accent); }
.cc-tache.sel { box-shadow: inset 3px 0 0 var(--accent); background: var(--accent-soft); }
.cc-tache.ouverte { outline: 2px solid var(--accent-line); outline-offset: -2px; }

.cc-selbar {
  position: sticky; top: 0; z-index: 5;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 12px; margin: 0 0 10px;
  border: 1px solid var(--accent-line); border-radius: 10px; background: var(--accent-soft);
}

/* la fiche à droite — en dessous quand l'écran est étroit, jamais un
   panneau flottant qui masque ce qu'on vient de cliquer */
.cc-avec-fiche { display: block; }
.cc-avec-fiche.ouverte { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 12px;
  align-items: start; }
.cc-corps { min-width: 0; }
.cc-fiche {
  position: sticky; top: 8px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--surface-2);
  padding: 12px; font-size: var(--fs-sm);
}
.cc-fiche .tete { display: flex; align-items: center; margin: -2px 0 8px;
  font-size: var(--fs-xs); letter-spacing: .04em; text-transform: uppercase; color: var(--txt-2); }
.cc-fiche .tete .btn { margin-left: auto; }
.cc-fiche .fil { font-size: var(--fs-xs); color: var(--txt-2); margin-bottom: 6px; overflow-wrap: anywhere; }
.cc-fiche h3 { font-size: var(--fs-md); margin: 0 0 8px; overflow-wrap: anywhere; }
.cc-fiche .j { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
.cc-fiche .j b { font-variant-numeric: tabular-nums; }
.cc-fiche .l { display: flex; gap: 8px; padding: 5px 0; border-top: 1px solid var(--line); }
.cc-fiche .l.col { display: block; }
.cc-fiche .l .k { flex: 0 0 96px; color: var(--txt-2); font-size: var(--fs-xs); }
.cc-fiche .l .v { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.cc-fiche .l .v.jr { margin-top: 4px; font-size: var(--fs-sm); color: var(--txt-2); }
.cc-fiche .acts { margin-top: 10px; display: grid; gap: 6px; }

@media (max-width: 900px) {
  .cc-avec-fiche.ouverte { grid-template-columns: minmax(0, 1fr); }
  .cc-fiche { position: static; }
  .cc-lot.n2, .cc-lot.n3 { margin-left: 8px; }
}

/* le glissé : la carte s'efface, la colonne s'annonce */
.cc-tache.kb[draggable] { cursor: grab; }
.cc-tache.kb.glisse { opacity: .4; }
.cc-kbc.survol { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent-line); }
.cc-kbc.survol > .h::after { content: "déposer ici"; margin-left: 6px; text-transform: none;
  letter-spacing: 0; font-size: var(--fs-xs); color: var(--accent-text); }

/* L'invite d'un chantier sans tâches, et l'aperçu de ce qui sera repris du
   devis. Montrer avant d'écrire : 40 lignes créées d'un coup sans les avoir
   vues, ça ne se rattrape pas à la main. */
.cc-vide { border: 1px dashed var(--line-strong); border-radius: 10px; padding: 20px;
  text-align: center; background: var(--surface-2); }
.cc-vide p { margin: 0 0 8px; }
.cc-vide .dim { max-width: 58ch; margin: 0 auto 14px; }
.gt-liste { max-height: 46vh; overflow-y: auto; border: 1px solid var(--line);
  border-radius: 8px; padding: 6px; background: var(--surface); }
label.ck.gt { display: flex; gap: 8px; align-items: flex-start; padding: 5px 6px;
  border-radius: 6px; font-size: var(--fs-sm); line-height: 1.45; cursor: pointer; }
label.ck.gt:hover { background: var(--surface-2); }
label.ck.gt.sous { padding-left: 30px; font-size: var(--fs-sm); color: var(--txt-2); }
label.ck.gt.deja { opacity: .55; text-decoration: line-through; cursor: default; }
label.ck.gt.deja i { text-decoration: none; }
label.ck.gt input { margin-top: 3px; flex: 0 0 auto; accent-color: var(--accent); }


/* « Ma journée » passe en mode terrain (15 px) : les sous-textes fixés en px
   suivent, sinon la page annonce du 15 et sert du 12. (18/08, audit UX) */
.terrain .mc-a { font-size: var(--fs-md); }
.terrain .mc-a .s, .terrain .mc-ch .s { font-size: var(--fs-sm); }
.terrain .mc-t .s { font-size: var(--fs-sm); }
.terrain .mc-t .t { font-size: var(--fs-md); }
.terrain .mc-ch .t { font-size: var(--fs-md); }

/* le mode d'emploi dans le guide : trois dépliants sobres */
.gd-me { border: 1px solid var(--line); border-radius: 10px; margin: 8px 0; background: var(--surface-2); }
.gd-me summary { padding: 10px 14px; cursor: pointer; font-size: var(--fs-md); }
.gd-me .corps { padding: 4px 16px 14px; font-size: var(--fs-sm); line-height: 1.65; }
.gd-me .corps h2 { font-size: var(--fs-md); margin: 14px 0 6px; }
.gd-me .corps ul { padding-left: 20px; margin: 6px 0; }
.gd-me .corps table td { padding: 4px 8px; border-top: 1px solid var(--line); vertical-align: top; }

/* ═══ Le widget de discussion : l'équipe, la présence, le tête-à-tête ═══
   La présence se lit au signe ET au mot — ● en ligne · ◐ absent · ○ hors
   ligne. La couleur appuie, elle ne porte jamais seule (Denis, daltonien). */
.tb-k { padding: 10px 12px 4px; font-size: var(--fs-xs); font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--txt-dim); }
.tb-p { display: flex; gap: 9px; align-items: center; width: 100%; padding: 7px 12px;
  border: 0; background: none; cursor: pointer; text-align: left; color: var(--txt); }
.tb-p:hover { background: var(--surface-3); }
.tb-p.attente { opacity: .5; pointer-events: none; }
.tb-p .pr { flex: none; width: 16px; text-align: center; }
.tb-p .pr-ligne { color: var(--bio); }
.tb-p .pr-absent { color: var(--warn); }
.tb-p .pr-hors { color: var(--txt-dim); }
.tb-p .c { min-width: 0; }
.tb-p .t { display: block; font-size: var(--fs-sm); font-weight: 600; }
.tb-p .s { display: block; font-size: var(--fs-xs); color: var(--txt-dim); }
.tb-c { width: 100%; border: 0; background: none; text-align: left; cursor: pointer; color: var(--txt); }
.tb-retour { border: 0; background: none; color: var(--accent-text); cursor: pointer;
  padding: 8px 12px; font-size: var(--fs-sm); text-align: left; }
.tb-msgs { max-height: 300px; min-height: 140px; overflow-y: auto; padding: 4px 10px;
  display: flex; flex-direction: column; gap: 7px; }
.tb-m { max-width: 88%; align-self: flex-start; }
.tb-m.moi { align-self: flex-end; text-align: right; }
.tb-m .q { display: block; font-size: var(--fs-xs); color: var(--txt-dim); margin-bottom: 1px; }
.tb-m .b { display: inline-block; background: var(--surface-3); border-radius: 10px;
  padding: 6px 10px; font-size: var(--fs-sm); white-space: pre-wrap; overflow-wrap: anywhere; text-align: left; }
.tb-m.moi .b { background: var(--accent-soft); }
.tb-saisie { display: flex; gap: 6px; padding: 8px 10px; border-top: 1px solid var(--line); }
.tb-saisie textarea { flex: 1; min-height: 40px; resize: none; }
.tb-saisie .btn { min-width: 44px; }

/* la préparation hors devis — cochable, jamais comptée */
.pp-l { display: flex; gap: 9px; align-items: center; padding: 6px 2px;
  border-bottom: 1px solid var(--line-soft); font-size: var(--fs-sm); }
.pp-l.fait .d { text-decoration: line-through; color: var(--txt-dim); }
.pp-l .q { min-width: 44px; text-align: right; font-weight: 600; }
.pp-l .u { min-width: 44px; color: var(--txt-dim); }
.pp-l .d { flex: 1; }
.pp-l .d.note { font-style: italic; }
.pp-l input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--accent); }
.pp-ajout { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin-top: 10px; }

/* ============================================================
   LA CARTE DES CHANTIERS  (19/08 — « je n'ai pas de carte de vue
   comme sur Odoo »). Plan glissant maison : OpenStreetMap, aucune
   bibliothèque. Les tuiles sont des <img> placées à l'absolu ;
   `.mp-monde` ne sert qu'à les contenir.
   ============================================================ */
.mp-grille { display: grid; grid-template-columns: 1fr 340px; gap: 14px; align-items: start; }
@media (max-width: 900px) { .mp-grille { grid-template-columns: 1fr; } }

.mp-plan { position: relative; overflow: hidden; height: 62vh; min-height: 360px;
  background: var(--surface-3); border: 1px solid var(--line); border-radius: var(--r);
  cursor: grab; touch-action: none; user-select: none; }
.mp-plan.tire { cursor: grabbing; }
.mp-monde, .mp-pins { position: absolute; inset: 0; }
.mp-pins { pointer-events: none; }
.mp-pin { pointer-events: auto; }
.mp-t { position: absolute; width: 256px; height: 256px; }

/* La punaise porte le NUMÉRO du chantier : la couleur ne dit rien à elle
   seule (Denis est daltonien). Cible ≥ 44 px avec sa zone de clic. */
.mp-pin { position: absolute; transform: translate(-50%, -100%); border: 0; background: none;
  cursor: pointer; padding: 0 0 10px; min-width: 44px; min-height: 44px;
  display: flex; align-items: flex-end; justify-content: center; }
.mp-pin .n { display: inline-block; background: var(--surface); color: var(--txt);
  border: 2px solid var(--accent); border-radius: 999px; padding: 3px 9px;
  font-size: var(--fs-xs); font-weight: 700; white-space: nowrap; box-shadow: var(--shadow-lg); }
.mp-pin::after { content: ""; position: absolute; bottom: 2px; left: 50%; transform: translateX(-50%);
  width: 0; height: 0; border: 6px solid transparent; border-top-color: var(--accent); }
.mp-pin.on .n { background: var(--accent); color: var(--on-accent); border-color: var(--accent-strong); }
.mp-pin:focus-visible .n { outline: 3px solid var(--focus); outline-offset: 2px; }

.mp-zoom { position: absolute; top: 10px; right: 10px; display: flex; flex-direction: column; gap: 4px; }
.mp-zoom button { width: 40px; height: 40px; border-radius: var(--r-sm); cursor: pointer;
  border: 1px solid var(--line); background: var(--surface); color: var(--txt);
  font-size: var(--fs-lg); line-height: 1; box-shadow: var(--shadow); }
.mp-credit { position: absolute; bottom: 4px; right: 6px; font-size: var(--fs-xs);
  background: var(--surface); color: var(--txt-dim); padding: 2px 6px; border-radius: 4px; }
.mp-phase { position: absolute; bottom: 8px; left: 8px; font-size: var(--fs-xs); font-weight: 600;
  background: var(--surface); color: var(--txt); border: 1px solid var(--accent-line);
  padding: 5px 10px; border-radius: 999px; box-shadow: var(--shadow); }

.mp-cote { padding: 0; overflow: hidden; }
.mp-fiche { padding: 12px; border-bottom: 1px solid var(--line); }
.mp-fiche .t { font-weight: 700; font-size: var(--fs-md); }
.mp-fiche .s { display: block; font-size: var(--fs-sm); color: var(--txt-dim); margin-top: 2px; }
.mp-actes { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.mp-liste { max-height: 46vh; overflow-y: auto; }
.mp-k { padding: 8px 10px 4px; font-size: var(--fs-xs); font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--txt-dim); background: var(--surface-3); }
.mp-k span { color: var(--txt); }
.mp-l { display: flex; width: 100%; text-align: left; gap: 8px; cursor: pointer;
  border: 0; border-bottom: 1px solid var(--line-soft); background: none; color: var(--txt);
  padding: 9px 10px; min-height: var(--tap); }
.mp-l:hover { background: var(--surface-3); }
.mp-l.on { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.mp-l .t { display: block; font-size: var(--fs-sm); font-weight: 600; }
.mp-l .s { display: block; font-size: var(--fs-xs); color: var(--txt-dim); }

/* ---- les liaisons d'un chantier : devis, factures (19/08) ---- */
.cc-liaison { display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  padding: 10px 0; border-bottom: 1px solid var(--line-soft); }
.cc-liaison:last-of-type { border-bottom: 0; }
.cc-liaison .c { flex: 1; min-width: 200px; }
.cc-liaison .t { font-size: var(--fs-md); font-weight: 600; }
.cc-liaison .s { font-size: var(--fs-sm); color: var(--txt-dim); }
.cc-adr { font-size: var(--fs-md); font-weight: 600; margin: 2px 0 6px; }

/* ---- le choix d'une facture à relier ---- */
.rf-liste { max-height: 42vh; overflow-y: auto; margin-top: 6px; }
.rf-l { display: flex; gap: 9px; align-items: flex-start; padding: 9px 4px;
  border-bottom: 1px solid var(--line-soft); cursor: pointer; min-height: var(--tap); }
.rf-l:hover { background: var(--surface-3); }
.rf-l.deja { opacity: .6; cursor: default; }
.rf-l input { margin-top: 3px; width: 18px; height: 18px; accent-color: var(--accent); }
.rf-l .c { flex: 1; font-size: var(--fs-sm); }
.rf-l .s { display: block; font-size: var(--fs-xs); color: var(--txt-dim); }

/* l'équipe de base — deux états de plus que le typage des comptes :
   « introuvable » (aucun compte, aucun contact) et « à nommer » (Denis ne
   se rappelait plus du nom de l'électricien). Le signe porte l'information,
   la couleur ne fait que doubler. */
.cp-pastille.absent  { border-color: var(--line); color: var(--txt-dim); background: var(--surface-3); }
.cp-pastille.anommer { border-color: var(--accent-line); color: var(--accent-text); background: var(--accent-soft); }
.cp-type.absent  { color: var(--txt-dim); }
.cp-type.anommer { color: var(--accent-text); }
.cp-type.attention { color: var(--danger); }
.cp-pastille.attention { border-color: hsl(14 70% 55% / .5); color: var(--danger); background: var(--danger-soft); }

/* Les lignes de l'équipe de base portent un MOTIF, pas un courriel : tronqué
   à une ligne, « Ni compte, ni contact à ce nom — cherchez une C… » ne dit
   plus rien. Ici, le texte passe à la ligne. */
.row.cp-eq .s { white-space: normal; overflow: visible; text-overflow: clip; }

/* ============================================================
   « OUVRIR… » — huit pastilles repliées en un bouton (19/08)

   « Aller à » posait une deuxième barre de navigation en travers de
   l'écran, au-dessus des onglets, pour des destinations qu'on ouvre une
   fois par semaine. Un <details> natif : fermé par défaut, pas d'état à
   retenir, et le clavier le traverse tout seul.
   ============================================================ */
.cc-ouvrir { margin: 0 0 12px; }
.cc-ouvrir > summary { display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  list-style: none; min-height: 36px; padding: 6px 14px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--txt);
  font-size: var(--fs-sm); font-weight: 600; }
.cc-ouvrir > summary::-webkit-details-marker { display: none; }
.cc-ouvrir > summary::after { content: "▸"; color: var(--txt-dim); font-size: var(--fs-xs); }
.cc-ouvrir[open] > summary::after { content: "▾"; }
.cc-ouvrir > summary:hover { border-color: var(--accent-line); }
.cc-ouvrir > summary:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.cc-ouvrir > summary .n { font-weight: 700; color: var(--txt-dim); font-size: var(--fs-xs); }
.cc-ouvrir-b { display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  margin-top: 10px; padding: 10px; border: 1px solid var(--line-soft);
  border-radius: var(--r); background: var(--surface-2); }
.cc-ouvrir-k { flex-basis: 100%; margin-top: 4px; font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--txt-dim); }

/* ============================================================
   LES CLIENTS — listing et fiche (19/08, « une vraie fiche client
   à la ProgBat, avec un listing client à part »)
   ============================================================ */
.cl-r { align-items: center; }
.cl-n { min-width: 96px; text-align: right; }
.cl-n .l { display: block; font-size: var(--fs-xs); letter-spacing: .05em; text-transform: uppercase;
  color: var(--txt-dim); }
.cl-n b { font-size: var(--fs-md); }
/* Le reste dû ne se signale pas QUE par la couleur — Denis est daltonien :
   la colonne porte son intitulé, et un montant nul s'écrit « — ». */
.cl-n b.du { color: var(--danger); }
@media (max-width: 720px) { .cl-n { min-width: 74px; } .cl-n b { font-size: var(--fs-sm); } }

.cl-joindre { display: flex; gap: 8px; flex-wrap: wrap; }
.cl-ct { display: flex; gap: 10px; align-items: center; padding: 8px 0;
  border-bottom: 1px solid var(--line-soft); }
.cl-ct:last-child { border-bottom: 0; }
.cl-ct .c { flex: 1; min-width: 0; }
.cl-ct .t { font-size: var(--fs-sm); font-weight: 600; }
.cl-ct .s { font-size: var(--fs-xs); color: var(--txt-dim); }

.cl-l { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
  padding: 7px 0; border-bottom: 1px solid var(--line-soft); font-size: var(--fs-sm); }
.cl-l:last-of-type { border-bottom: 0; }
.cl-l .s { color: var(--txt-dim); font-size: var(--fs-xs); flex: 1; }
.cl-l b { font-variant-numeric: tabular-nums; }
.cl-l.retard { box-shadow: inset 3px 0 0 var(--danger); padding-left: 9px; }

/* la part d'un client sur un chantier partagé — l'exception, jamais la règle */
.cc-part { display: inline-block; margin-left: 6px; padding: 1px 8px; border-radius: 999px;
  background: var(--accent-soft); border: 1px solid var(--accent-line);
  color: var(--accent-text); font-size: var(--fs-xs); font-weight: 700; vertical-align: middle; }

/* ============================================================
   20/08 — Vignette de matière, et le réglage « Repères »
   Denis, 20/08 : « les vignettes ». Pour un métier de matières,
   l'image EST l'identifiant : « BASE NHL 5 » et « ADHERECAL NHL 5 »
   ne se distinguent pas par leur code, mais par le sac. C'est ce que
   fait le sélecteur de l'ancienne console, et c'est le plus gros
   écart de lisibilité qu'on avait avec elle.
   La boîte porte le repli : le glyphe est DÉJÀ dans le DOM, l'image
   se pose par-dessus. Si elle manque (aperçus locaux, produit sans
   photo), rien ne casse et rien ne clignote.
   ============================================================ */
.vign-boite {
  flex: none; width: var(--vign); height: var(--vign);
  border-radius: var(--r-sm); border: 1px solid var(--line);
  background: var(--surface-3); overflow: hidden; position: relative;
  display: flex; align-items: center; justify-content: center;
}
.vign-boite img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; display: block;
  background: var(--surface-2);
}
.vign-boite .rien { font-size: calc(var(--vign) * .40); line-height: 1; opacity: .45; }
/* sur une carte, la vignette est un bandeau : on voit la matière, pas un timbre */
.vign-bandeau { width: 100%; height: calc(var(--vign) * 1.6); border-radius: var(--r-sm) var(--r-sm) 0 0; }

/* Repères — l'image et le pictogramme aident la plupart des gens et en
   gênent d'autres. Ni l'un ni l'autre ne porte JAMAIS une information à
   lui seul : on ne masque que le renfort, le libellé reste intact. */
[data-reperes="texte"] .ico,
[data-reperes="texte"] .vign-boite { display: none !important; }
[data-reperes="icones"] .tabbar a { font-size: 0; gap: 0; }
[data-reperes="icones"] .tabbar .ico { font-size: var(--fs-xl); }

/* --- le panneau « Affichage » (thème · densité · repères) --- */
.aff-pop {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 70;
  min-width: 264px; padding: 12px; border-radius: var(--r);
  background: var(--surface-2); border: 1px solid var(--line); box-shadow: var(--shadow-lg);
}
.aff-pop .k {
  display: block; margin: 10px 0 6px;
  font: 700 var(--fs-xs)/1 var(--ff); letter-spacing: .09em; text-transform: uppercase; color: var(--txt-dim);
}
.aff-pop .k:first-child { margin-top: 0; }
.aff-seg { display: flex; gap: 4px; }
.aff-seg button {
  flex: 1; min-height: 34px; padding: 0 8px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); color: var(--txt); font: 600 var(--fs-xs)/1 var(--ff);
  white-space: nowrap;
}
.aff-seg button:hover { background: var(--surface-3); }
/* l'option retenue se dit de trois façons — fond, contour, coche — parce
   qu'un seul signal de couleur ne se voit pas de tous les yeux */
.aff-seg button[aria-pressed="true"] {
  background: var(--accent-soft); border-color: var(--accent-line);
  color: var(--txt); font-weight: 800;
}
.aff-seg button[aria-pressed="true"]::before { content: "✓ "; }
.aff-pop .note { display: block; margin-top: 10px; font-size: var(--fs-xs); color: var(--txt-dim); line-height: 1.45; }
.tb-outils { position: relative; }

/* ---------- LE DOSSIER AS-BUILT / DIU ----------
   Rangé par lot, puis par tâche. « Général » est en dernier et se voit :
   ce qui n'est pas rangé doit gêner un peu, sinon rien ne se range jamais. */
.ab-compte { margin-left: auto; font-size: var(--fs-xs); color: var(--txt-dim);
  font-variant-numeric: tabular-nums; }
.ab { display: flex; flex-direction: column; gap: 12px; margin-top: 10px; }
.ab-lot { border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px;
  background: var(--surface-1); }
.ab-lot.gen { border-style: dashed; background: var(--surface-2); }
.ab-lot-k { font-size: var(--fs-sm); font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--txt-dim); margin-bottom: 10px; }
.ab-t { padding: 8px 0; border-top: 1px solid var(--line-soft); }
.ab-t:first-of-type { border-top: 0; padding-top: 0; }
.ab-t-k { font-size: var(--fs-md); font-weight: 600; margin-bottom: 6px; }
.ab-phs { display: flex; flex-wrap: wrap; gap: 8px; margin: 6px 0; }
.ab-ph { width: 132px; display: flex; flex-direction: column; gap: 3px; text-decoration: none; color: inherit; }
.ab-ph img { width: 132px; height: 94px; object-fit: cover; border-radius: 9px;
  border: 1px solid var(--line); display: block; background: var(--surface-3); }
.ab-ph .l { font-size: var(--fs-xs); color: var(--txt-dim); line-height: 1.35; }
.ab-ph .l i { font-style: italic; }
.ab-ph:hover img { border-color: var(--accent); }
.ab-l { margin: 6px 0 0; padding-left: 18px; font-size: var(--fs-sm); line-height: 1.6; }
.ab-l li { margin-bottom: 4px; }
.ab-notes { color: var(--txt-dim); }
.ab-ok { color: var(--bio); font-weight: 600; }
.ab-manque { color: var(--txt-dim); font-style: italic; }

/* ---------- L'ÉCRAN DU TERRAIN — téléphone d'abord ----------
   Denis, 23/08 : « écran de GSM first !!! pour l'ouvrier / sous-traitant,
   c'est le même job ». Une colonne, des cibles qu'un pouce ganté atteint,
   et rien qui demande à être appris. La complexité reste derrière : la photo
   porte sa légende et sa tâche, et entre au dossier as-built. */
.tr { display: flex; flex-direction: column; gap: 14px; padding-bottom: 24px; }
.tr-h { font-size: var(--fs-xl); margin: 0; }
.tr-sel { min-height: var(--tap-primary); font-size: var(--fs-md); }
.tr-vide { padding: 24px 4px; }
.tr-vide h1 { font-size: var(--fs-xl); margin: 0 0 8px; }

.tr-ou { border: 1px solid var(--line); border-radius: 14px; padding: 14px;
  background: var(--surface-1); display: flex; flex-direction: column; gap: 8px; }
.tr-nom { font-size: var(--fs-lg); font-weight: 700; line-height: 1.25; }
.tr-adr { font-size: var(--fs-md); color: var(--txt-dim); line-height: 1.4; }
.tr-b { min-height: var(--tap); align-self: flex-start; }
.tr-gens { display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  border-top: 1px solid var(--line-soft); padding-top: 10px; margin-top: 2px; }
.tr-q { font-size: var(--fs-md); font-weight: 600; }
.tr-q i { font-style: normal; font-weight: 400; color: var(--txt-dim); font-size: var(--fs-sm); margin-left: 5px; }

/* le geste principal : il ne se cherche pas */
.tr-photo { width: 100%; min-height: 76px; border: 0; border-radius: 14px; cursor: pointer;
  background: var(--accent); color: var(--on-accent); font: 700 var(--fs-lg) var(--ff);
  display: flex; align-items: center; justify-content: center; gap: 12px; }
.tr-photo span { font-size: 26px; line-height: 1; }
.tr-photo:active { background: var(--accent-strong); }

.tr-bloc { border: 1px solid var(--line); border-radius: 14px; padding: 12px 14px; background: var(--surface-1); }
.tr-k { font-size: var(--fs-xs); font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--txt-dim); margin-bottom: 8px; }
.tr-l { display: flex; align-items: center; gap: 10px; min-height: var(--tap);
  border-top: 1px solid var(--line-soft); padding: 6px 0; }
.tr-l:first-of-type { border-top: 0; }
.tr-l .t { flex: 1; font-size: var(--fs-md); line-height: 1.35; }
.tr-mini { min-height: var(--tap); white-space: nowrap; font-size: var(--fs-sm); }

.tr-liste { display: flex; align-items: center; gap: 12px; min-height: var(--tap-primary);
  padding: 0 16px; border: 1.5px solid var(--accent-line); border-radius: 14px;
  background: var(--accent-soft); color: var(--txt); font-size: var(--fs-md); font-weight: 600;
  text-decoration: none; }
.tr-liste span { font-size: 22px; }

.tr-grille { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.tr-c { min-height: 84px; border: 1px solid var(--line); border-radius: 14px; background: var(--surface-1);
  color: var(--txt); text-decoration: none; cursor: pointer; font: 600 var(--fs-md) var(--ff);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; }
.tr-c span { font-size: 24px; line-height: 1; }
.tr-c:active { background: var(--surface-3); }
.tr-note { font-size: var(--fs-sm); color: var(--txt-dim); line-height: 1.5; margin: 0; }

@media (min-width: 720px) { .tr { max-width: 560px; } }

/* le choix du chantier, quand on arrive au dossier sans en avoir désigné un */
.dc-choix { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.dc-ch { display: flex; align-items: center; gap: 10px; min-height: var(--tap-primary);
  padding: 10px 14px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--surface-1); color: var(--txt); text-decoration: none; }
.dc-ch:hover { border-color: var(--accent); background: var(--accent-soft); }
.dc-ch .n { font-size: var(--fs-md); font-weight: 600; }
.dc-ch .s { font-size: var(--fs-sm); color: var(--txt-dim); }
.dc-ch .go { margin-left: auto; color: var(--txt-dim); font-size: var(--fs-lg); }

/* ═══════════ LA LANGUE DE L'APP STORE ═══════════
   Denis, 23/08 : « le style App Store, l'app est très bonne visuellement,
   on s'en inspire » — puis « si, l'apparence du site !!! ».

   Ce qu'on lui prend, et pourquoi :
   — LES CARTES N'ONT PAS DE BORDURE. Elles se détachent par leur fond et
     une ombre à peine visible. Une bordure sur chaque bloc fabrique une
     grille de traits ; l'App Store n'en a aucune, et c'est ce qui donne
     l'impression de calme.
   — LES COINS SONT LARGES : 18 px. En dessous, ça fait « fenêtre » ;
     au-dessus, ça fait « bouton ».
   — LES TITRES DE SECTION SONT EN GRAS LISIBLE, pas en micro-capitales
     grises. Apple écrit « Jeux que vous allez adorer » en 22 gras, pas
     « JEUX » en 11 px espacé. Une section se lit, elle ne s'épelle pas.
   — L'ACTION EST UNE PASTILLE à droite de la ligne, comme « OBTENIR ».
     Compacte, arrondie, toujours à la même place. */

.tr-ou, .tr-bloc, .dc-ch, .cc-bloc, .cr-bloc {
  border: 0;
  border-radius: 18px;
  background: var(--surface-1);
  box-shadow: 0 1px 2px rgb(0 0 0 / .10), 0 6px 18px rgb(0 0 0 / .06);
}
.tr-ou, .tr-bloc { padding: 18px; }

/* le titre de section se lit */
.tr-k, .cc-tete .k, .cr-k {
  font-size: var(--fs-lg);
  font-weight: 700;
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--txt);
  margin-bottom: 12px;
}

/* la ligne : intitulé lisible, action en pastille à droite */
.tr-l { border-top: 0; padding: 12px 0; gap: 14px; align-items: center; }
.tr-l + .tr-l { border-top: 1px solid var(--line-soft); }
.tr-l .t { font-size: var(--fs-md); font-weight: 500; line-height: 1.35; }
.tr-mini {
  border-radius: 999px; padding: 0 16px; min-height: 34px;
  background: var(--accent-soft); color: var(--accent-text);
  font-size: var(--fs-sm); font-weight: 600; border: 0; white-space: nowrap;
}
.tr-mini:hover { background: var(--accent); color: var(--on-accent); }

/* les quatre tuiles, et la carte de chantier : mêmes coins, même absence de trait */
.tr-c { border: 0; border-radius: 18px; background: var(--surface-1); min-height: 96px;
  box-shadow: 0 1px 2px rgb(0 0 0 / .10), 0 6px 18px rgb(0 0 0 / .06); }
.tr-photo { border-radius: 18px; min-height: 84px; }
.tr-liste { border: 0; border-radius: 18px; min-height: 64px; }
.dc-ch { padding: 16px 18px; }
.dc-ch .n { font-size: var(--fs-md); }

/* les gens : jamais de retour à la ligne au milieu d'un nom et de son bouton */
.tr-gens { border-top: 1px solid var(--line-soft); padding-top: 14px; gap: 10px; }
.tr-gens .tr-b { min-height: 38px; border-radius: 999px; padding: 0 18px;
  background: var(--surface-3); border: 0; font-weight: 600; }

/* le nom sur sa ligne, les deux gestes en dessous : à 375 px et 17 px de
   corps, « Pierre gestionnaire · Appeler · Écrire » ne tient pas sur une
   ligne — et un bouton qui passe seul à la ligne suivante a l'air cassé. */
.tr-gens { flex-direction: column; align-items: stretch; }
.tr-gens .tr-q { margin-bottom: 2px; }
.tr-gens-b { display: flex; gap: 10px; }
.tr-gens .tr-b { flex: 1; justify-content: center; }
.tr-ou > .btn.tr-b { border-radius: 999px; padding: 0 20px; min-height: 40px;
  background: var(--surface-3); border: 0; font-weight: 600; align-self: flex-start; }

/* 44 px, SANS EXCEPTION, sur l'écran du terrain. Apple pose 44 pt comme
   minimum absolu et ne le contourne jamais — un pouce ganté non plus.
   Mesuré ici avant la pose : Y aller 40, Appeler 38, Écrire 38, c'est fait
   34, comment on fait 34. Toutes remontées. */
.tr .btn, .tr a.btn, .tr button, .tr-mini, .tr-gens .tr-b, .tr-ou > .btn.tr-b {
  min-height: 44px;
}
.tr-mini { padding: 0 18px; }

/* ═══════════ LE CLAVIER DOIT SE VOIR ═══════════
   P1 n°4 de l'audit du 17/08 : « aucun style de focus clavier, zéro règle
   :focus-visible dans les quatre fichiers de l'app ». Sept règles existent
   depuis, mais aucune ne couvre le cas général : un lien, une carte, une
   pastille, un onglet restaient invisibles au clavier.
   Une règle globale, et tout le clavier redevient utilisable — c'est aussi
   ce dont se sert un lecteur d'écran pour dire où l'on est. WCAG 2.4.7.
   `:focus-visible` et non `:focus` : la souris ne déclenche rien, seul le
   clavier allume l'anneau. */
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: 6px;
}
/* sur un fond accentué, l'anneau or disparaîtrait dans l'or */
.btn-primary:focus-visible, .tr-photo:focus-visible, .nj-n.on:focus-visible {
  outline-color: var(--txt);
}

/* ═══════════ LE MENU, FAÇON KEYNOTE ═══════════
   Denis, 23/08 : « le menu en mobile first, inspire-toi de Keynote, et sur
   ordinateur aussi dans la lisibilité des éléments ».

   Ce que fait Keynote, et pourquoi :
   — L'ACTIF EST NEUTRE. Keynote ne colorie pas l'élément sélectionné : il
     l'assoit sur un gris. La couleur est réservée à ce qui agit, pas à ce
     qui est. Notre entrée active était en or : elle criait plus fort que le
     bouton principal de la page.
     On garde une barre or de 3 px à gauche — la position est un signal qui
     ne dépend d'aucune couleur, et ça compte ici.
   — LES TITRES DE GROUPE SE LISENT. « Gestion chantier », pas
     « GESTION CHANTIER » en 9 px espacé. Keynote écrit « Diapositive »,
     « Texte », « Disposition » — en clair.
   — L'AIR EST DU CONTENU. Keynote respire ; une barre latérale serrée se
     parcourt moins vite, pas plus. */

.acc-h {
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--txt-dim);
  min-height: 40px;
}
.acc-i {
  font-size: var(--fs-sm);
  min-height: 40px;
  border-radius: 8px;
  margin: 1px 6px;
  padding-left: 12px;
  border-left: 3px solid transparent;
}
.acc-i.on {
  background: var(--surface-3);
  color: var(--txt);
  font-weight: 600;
  border-left-color: var(--accent);
}
.acc-b { padding-bottom: 6px; }
.side { padding-top: 6px; }

/* la barre du bas, sur téléphone : calme aussi. L'actif n'est pas doré, il
   est net — le libellé passe en gras et reprend l'encre pleine. */
.tabbar a.on, .tabbar button.on { color: var(--txt); font-weight: 700; }
.tabbar a, .tabbar button { font-size: var(--fs-xs); }


/* ---------- le courrier du chantier (23/08) ----------
   L'adresse est le point d'entrée : elle se lit de loin, elle se copie d'un
   geste. Tout le reste de ce bloc est de la conversation, donc du second
   plan. */
.cc-mail { display:flex; align-items:center; gap: 14px;
  background:var(--surface-2); border-radius:var(--r-lg); padding: 16px;
  box-shadow: var(--shadow); margin-top: 10px; }
.cc-mail-a { min-width:0; flex:1 }
.cc-mail-a .l { display:block; font-size:var(--fs-xs); letter-spacing:.06em;
  text-transform:uppercase; color:var(--txt-dim) }
.cc-mail-a b { display:block; font-size:var(--fs-lg); line-height:1.25;
  margin:2px 0 4px; word-break:break-all; color:var(--txt) }
.cc-mail-a .d { display:block; font-size:var(--fs-sm); line-height:1.45; color:var(--txt-dim) }
.cc-mail .btn { flex:none; min-height:var(--tap) }
@media (max-width:520px) { .cc-mail { flex-direction:column; align-items:stretch }
  .cc-mail .btn { width:100% } }


/* ---------- Pilotage : la liste d'actions (23/08) ----------
   Une ligne = une chose à faire = un geste. Le signe porte la gravité, la
   couleur ne la porte JAMAIS seule — Denis est daltonien, et un rouge qui
   dit « urgent » à lui seul ne dit rien. */
.cc-agir .cc-ag { display:flex; align-items:flex-start; gap:12px; padding:14px 0;
  border-bottom:1px solid var(--line-soft); }
.cc-agir .cc-ag:last-of-type { border-bottom:0 }
.cc-agir .cc-ag .sg { flex:none; width:20px; text-align:center; font-size:var(--fs-md);
  line-height:1.5; color:var(--txt-dim) }
.cc-agir .cc-ag.g0 .sg { color:var(--danger) }
.cc-agir .cc-ag.g1 .sg { color:var(--warn) }
.cc-agir .cc-ag .c { flex:1; min-width:0 }
.cc-agir .cc-ag .c b { display:block; font-size:var(--fs-md); line-height:1.35; color:var(--txt) }
.cc-agir .cc-ag .c .d { display:block; font-size:var(--fs-sm); line-height:1.45;
  color:var(--txt-dim); margin-top:2px }
.cc-agir .cc-ag .btn { flex:none; min-height:var(--tap); white-space:nowrap }
.cc-agir .cc-plus { display:block; margin-top:14px; font-size:var(--fs-sm);
  min-height:var(--tap); text-align:left }
@media (max-width:560px) {
  .cc-agir .cc-ag { flex-wrap:wrap }
  .cc-agir .cc-ag .btn { width:100%; margin-left:32px; margin-top:8px; width:calc(100% - 32px) }
}


/* ---------- le classeur en arbre (23/08) ----------
   L'indentation porte la hiérarchie ; le chevron dit ce qui s'ouvre. Un
   dossier vide est grisé ET désactivé — deux signaux, jamais la couleur
   seule. */
.cl-arbre { margin-top: 10px }
.cl-l { --prof: 0 }
.cl-t, .cl-p { display:flex; align-items:center; gap:10px; width:100%;
  min-height: var(--tap); padding: 6px 8px 6px calc(8px + var(--prof) * 20px);
  border:0; background:transparent; text-align:left; cursor:pointer;
  border-bottom:1px solid var(--line-soft); color:var(--txt); text-decoration:none }
.cl-t:hover, .cl-p:hover { background:var(--surface-3) }
.cl-t .ch { flex:none; width:14px; color:var(--txt-dim); font-size:var(--fs-xs) }
.cl-p .ic { flex:none; width:14px; font-size:var(--fs-xs) }
.cl-t .n { flex:1; min-width:0; font-size:var(--fs-sm); font-weight:600;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.cl-p .n { flex:1; min-width:0; font-size:var(--fs-sm); font-weight:400;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.cl-t .q, .cl-p .q { flex:none; font-size:var(--fs-xs); color:var(--txt-dim); font-variant-numeric:tabular-nums }
.cl-l.vide > .cl-t { cursor:default }
.cl-l.vide > .cl-t .n, .cl-l.vide > .cl-t .q { color:var(--txt-dim) }


/* ---------- emporter le dossier (23/08) ---------- */
.cc-emporter { background: var(--surface-2); border-radius: var(--r-lg); padding: 16px;
  box-shadow: var(--shadow); margin-top: 10px; }
.cc-emporter .s { font-size: var(--fs-sm); line-height: 1.5; color: var(--txt-dim); margin: 0 0 12px; }
.cc-emporter .btn { min-height: var(--tap); }

/* ---------- l'impression du dossier ----------
   Denis voulait un PDF. Le navigateur en fait un vrai, sans qu'on charge
   300 Ko de bibliotheque sur un chantier en 4G — a condition qu'on lui
   donne une page a imprimer, pas une application. On enleve donc tout ce
   qui n'est pas le dossier : la navigation, les onglets, les boutons.
   Ce qui reste est un document. */
@media print {
  body.impression-dossier .side,
  body.impression-dossier .topbar,
  body.impression-dossier .tabbar,
  body.impression-dossier .cc-onglets,
  body.impression-dossier .cc-emporter,
  body.impression-dossier .cc-flottant,
  body.impression-dossier .pv-bar,
  body.impression-dossier .dialog-backdrop,
  body.impression-dossier .btn,
  body.impression-dossier .seg,
  body.impression-dossier .lien-nu { display: none !important; }

  body.impression-dossier { background: #fff !important; }
  body.impression-dossier .app,
  body.impression-dossier .zone-main,
  body.impression-dossier main,
  body.impression-dossier .contenu { display: block !important; margin: 0 !important;
    padding: 0 !important; width: auto !important; max-width: none !important; }

  /* les couleurs d'ecran ne s'impriment pas : de l'encre sur du papier */
  body.impression-dossier .cc-bloc { break-inside: avoid; box-shadow: none !important;
    background: #fff !important; border: 0 !important; }
  body.impression-dossier .cc-tete .k { border-bottom: 1.5px solid #000; display: block;
    padding-bottom: 4px; }
  body.impression-dossier a { text-decoration: none; color: #000 !important; }
  body.impression-dossier .cl-t, body.impression-dossier .cl-p { min-height: 0 !important;
    padding-top: 2px !important; padding-bottom: 2px !important; }

  @page { margin: 18mm 16mm; }
}


/* la bande de vignettes du dialogue « classer les photos » */
.cp-bande { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; }
.cp-bande img { flex: none; width: 92px; height: 92px; object-fit: cover;
  border-radius: var(--r-sm); border: 1px solid var(--line); }
@media (min-width: 600px) { .cp-bande img { width: 116px; height: 116px; } }


/* ---------- la liste en fil, façon messagerie (23/08) ----------
   Denis a montré son WhatsApp : un fil par chantier, des étiquettes, le
   dernier message en sous-ligne. « Pour Isopure c'est clair pour lui comme
   cela. » Une ligne dit à qui c'est, ce qui s'y est passé, et ce qu'il faut
   en faire — sans l'ouvrir.

   Chaque étiquette porte son MOT autant que sa couleur : Denis est
   daltonien, un pastel qui dirait « paiement » à lui seul ne dirait rien. */
.fil { display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px;
  border-bottom: 1px solid var(--line-soft); text-decoration: none; color: var(--txt);
  min-height: var(--tap); }
.fil:hover { background: var(--surface-3); }
.fil:last-child { border-bottom: 0; }
.fil-a { flex: none; width: 44px; height: 44px; border-radius: 50%;
  background: var(--surface-3); color: var(--txt-dim); border: 1px solid transparent;
  display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-sm); font-weight: 700; letter-spacing: .02em; }
/* l'avatar EST le responsable, et il se change : on le dit au survol */
button.fil-a { cursor: pointer; border-style: dashed; border-color: var(--line); }
button.fil-a:hover { border-color: var(--accent); color: var(--txt); }
.fil-c { flex: 1; min-width: 0; text-decoration: none; color: inherit; }
.fil-h { display: flex; align-items: baseline; gap: 10px; }
.fil-h b { flex: 1; min-width: 0; font-size: var(--fs-md); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fil-q { flex: none; font-size: var(--fs-xs); color: var(--txt-dim); }
.fil-s { display: block; font-size: var(--fs-sm); color: var(--txt-dim); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fil-e { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; }

.et { display: inline-block; padding: 2px 8px; border-radius: 999px;
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .03em;
  border: 1px solid; white-space: nowrap; }
.et-fini      { color: #1D6F42; border-color: #1D6F42; background: #1D6F4212; }
.et-suivi     { color: #1F5F8B; border-color: #1F5F8B; background: #1F5F8B12; }
.et-afacturer { color: #8A5A00; border-color: #8A5A00; background: #8A5A0012; }
.et-paiement  { color: #A63D3D; border-color: #A63D3D; background: #A63D3D12; }
.et-adecouper { color: var(--txt-dim); border-color: var(--line); background: transparent; }
@media (prefers-color-scheme: dark) {
  .et-fini      { color: #6FCF97; border-color: #3E7F5A; background: #6FCF9714; }
  .et-suivi     { color: #7FB6E0; border-color: #4A7591; background: #7FB6E014; }
  .et-afacturer { color: #E0B871; border-color: #8A6E36; background: #E0B87114; }
  .et-paiement  { color: #E88A8A; border-color: #8E4C4C; background: #E88A8A14; }
}


/* la sous-section du devis : un cran sous la section, un cran au-dessus
   d'une ligne. Odoo 19 la porte nativement (line_subsection) — l'éditeur
   l'ignorait, et elle disparaissait de l'écran tout en s'imprimant sur le
   devis envoyé au client. */
.table tr.sous-sec > td { background: var(--surface-3); padding-left: 26px;
  border-top: 1px solid var(--line-soft); }
.table tr.sous-sec b { font-size: var(--fs-sm); letter-spacing: .01em; }


/* ---------- insérer un ouvrage (23/08) ----------
   Denis : « l'outil ouvrage paramétrique n'est pas bon, c'est compliqué,
   pas clair, pas intuitif, il faut du style Apple ».

   Le dialogue montrait le modèle de données : un menu de trente entrées
   tronquées, des sélecteurs de 13 px larges de 90, et une ligne de
   débogage sous eux. Il montre maintenant la décision — laquelle, quel
   choix, ce que ça pose, combien — dans cet ordre et rien d'autre.

   Les choix sont des CIBLES, pas des menus : 44 px de haut, le mot en
   entier. Sur un chantier comme au bureau, on désigne, on ne déroule pas. */
.ov-q { width: 100%; margin-bottom: 10px; }

.ov-liste { max-height: 34vh; overflow-y: auto; overscroll-behavior: contain;
  border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); }
.ov-f { position: sticky; top: 0; z-index: 1; padding: 7px 12px;
  background: var(--surface-3); color: var(--txt-dim);
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.ov-i { display: flex; align-items: baseline; gap: 12px; width: 100%;
  min-height: var(--tap); padding: 9px 12px; border: 0; background: transparent;
  text-align: left; cursor: pointer; color: var(--txt);
  border-bottom: 1px solid var(--line-soft); }
.ov-i:last-child { border-bottom: 0; }
.ov-i:hover { background: var(--surface-3); }
.ov-i.on { background: var(--accent-soft); }
.ov-i.on .n { font-weight: 700; }
.ov-i .n { flex: 1; min-width: 0; font-size: var(--fs-sm); line-height: 1.35; }
.ov-i .m { flex: none; font-size: var(--fs-xs); color: var(--txt-dim); font-variant-numeric: tabular-nums; }

.ov-detail { margin-top: 16px; }
.ov-t { font-size: var(--fs-lg); font-weight: 600; line-height: 1.3; margin-bottom: 14px; }

/* un choix = une ligne, un libellé, des boutons qu'on désigne */
.ov-op { margin-bottom: 14px; }
.ov-op > .l { display: block; font-size: var(--fs-xs); letter-spacing: .05em;
  text-transform: uppercase; color: var(--txt-dim); margin-bottom: 6px; }
.ov-op .seg { display: flex; flex-wrap: wrap; gap: 8px; }
.ov-op .seg-opt { min-height: var(--tap); padding: 0 18px; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--surface-2); color: var(--txt);
  font-size: var(--fs-md); font-weight: 500; cursor: pointer; }
.ov-op .seg-opt:hover { border-color: var(--txt-dim); }
.ov-op .seg-opt.on { background: var(--accent); color: var(--on-accent);
  border-color: var(--accent); font-weight: 700; }

/* ce que ça pose : la seule chose qui compte après le choix */
.ov-pose { background: var(--surface-3); border-radius: var(--r); padding: 12px 14px;
  margin: 16px 0; }
.ov-pose-k { font-size: var(--fs-xs); letter-spacing: .05em; text-transform: uppercase;
  color: var(--txt-dim); margin-bottom: 6px; }
.ov-p { font-size: var(--fs-sm); line-height: 1.45; padding: 2px 0; }
.ov-p.manque { color: var(--danger); }

/* le compte, en bas, et le total en grand */
.ov-compte { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px;
  border-top: 1px solid var(--line); padding-top: 14px; }
.ov-compte > .l { flex: 1 1 130px; display: block; font-size: var(--fs-xs);
  letter-spacing: .05em; text-transform: uppercase; color: var(--txt-dim); }
.ov-compte .input { margin-top: 4px; }
.ov-compte .tot { flex: 1 1 130px; text-align: right; }
.ov-compte .tot .l { display: block; font-size: var(--fs-xs); letter-spacing: .05em;
  text-transform: uppercase; color: var(--txt-dim); }
.ov-compte .tot b { font-size: var(--fs-xl); line-height: 1.2;
  font-variant-numeric: tabular-nums; }
@media (max-width: 560px) {
  .ov-compte .tot { flex-basis: 100%; text-align: left; }
}


/* La carte d'ouvrage a été dégraissée le 23/08 puis RENDUE le même soir :
   « la présentation était mieux avant ». Ses règles d'origine, plus haut
   dans ce fichier, reprennent la main — badges, chips, métadonnées, deux
   boutons. Seul le ROUTAGE des deux boutons a changé, et lui reste. */

/* Les familles ont été des boutons ronds une heure durant, puis Denis :
   « les familles tu les mets en menu déroulant c'est plus facile ». Le menu
   est revenu, avec le compte de chaque famille dans son libellé. */


/* ---------- écrire une ligne en clair (23/08) ----------
   Denis : « travaille sur les devis et comment les construire avec ce que
   l'on a ou pas, il faut que cela soit facile, intuitif, avec IA
   intégrée ».

   Une seule barre. On y écrit la ligne comme on la dirait, la console
   cherche dans la bibliothèque et le catalogue, lit la quantité et
   l'épaisseur au passage, et propose. Ce qu'elle ne trouve pas part quand
   même — mais mesuré. */
.lc-q { width: 100%; font-size: var(--fs-lg); min-height: 56px; padding: 0 16px; }
.lc-res { margin-top: 14px; max-height: 42vh; overflow-y: auto; overscroll-behavior: contain; }
.lc-k { font-size: var(--fs-xs); letter-spacing: .06em; text-transform: uppercase;
  color: var(--txt-dim); margin: 14px 0 6px; }
.lc-k:first-child { margin-top: 0; }
.lc-i { display: flex; align-items: baseline; gap: 12px; width: 100%;
  min-height: var(--tap); padding: 10px 14px; border: 1px solid var(--line);
  border-radius: var(--r); background: var(--surface-2); color: var(--txt);
  text-align: left; cursor: pointer; margin-bottom: 6px; }
.lc-i:hover { border-color: var(--txt-dim); }
.lc-i.on { border-color: var(--accent); background: var(--accent-soft); }
.lc-i.on .n { font-weight: 700; }
.lc-i .n { flex: 1; min-width: 0; font-size: var(--fs-sm); line-height: 1.4; }
.lc-i .m { flex: none; font-size: var(--fs-xs); color: var(--txt-dim);
  font-variant-numeric: tabular-nums; }
.lc-libre { border-style: dashed; }

/* Le traitement essayé ici sur l'éditeur de devis est passé dans les
   composants de base (.card, .row, .table) : tous les écrans en héritent.
   Ce bloc n'a plus lieu d'être — Denis, 23/08 : « adapte le style ». */


/* ---------- le passeport promis au devis (23/08) ----------
   Denis : « dans devis un estimatif, et s'il accepte il recevra le
   passeport à la fin du chantier ». Le bloc annonce un livrable, pas un
   chiffre de gestion : il se lit comme une promesse tenue d'avance. */
.pp { margin: 14px 0; }
.pp-k { font-size: var(--fs-xs); letter-spacing: .06em; text-transform: uppercase;
  color: var(--txt-dim); display: flex; flex-wrap: wrap; gap: 10px; align-items: baseline; }
.pp-v { text-transform: none; letter-spacing: 0; font-size: var(--fs-xs); color: var(--bio); }
.pp-h { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 10px; align-items: baseline; }
.pp-h b { font-size: var(--fs-lg); }
.pp-h .dim { font-size: var(--fs-sm); }
.pp-l { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.pp-c { font-size: var(--fs-xs); padding: 3px 9px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--txt-dim); white-space: nowrap; }
.pp-c b { color: var(--txt); font-variant-numeric: tabular-nums; }


/* le stock biogénique : le chiffre qui distingue OTRA, donc il se voit */
.pp-stock { margin-top: 12px; padding: 12px 14px; border-radius: var(--r);
  background: var(--bio-soft); border-left: 3px solid var(--bio); }
.pp-stock b { display: block; font-size: var(--fs-lg); color: var(--bio);
  font-variant-numeric: tabular-nums; }
.pp-stock .dim { font-size: var(--fs-xs); line-height: 1.4; }

/* une donnée fausse qui partirait chez le client : ça se voit, et ça se dit */
.pp-alerte { margin-top: 10px; padding: 10px 12px; border-radius: var(--r);
  background: var(--warn-soft); border-left: 3px solid var(--warn);
  font-size: var(--fs-xs); line-height: 1.45; color: var(--txt); }

/* ---- les trois mécanismes carbone : lisibles séparément, jamais fondus ----
   chaque rangée porte son chiffre, son assiette et sa source ; le signe est
   porté par la couleur ET par le caractère + / −, jamais par la couleur
   seule (Denis est daltonien) */
.cb { margin-top: 14px; border-radius: var(--r); overflow: hidden;
  border: 1px solid var(--line); }
.cb-r { display: grid; grid-template-columns: 1fr auto; gap: 2px 12px;
  padding: 11px 14px; align-items: baseline; border-bottom: 1px solid var(--line); }
.cb-r:last-child { border-bottom: 0; }
.cb-l { font-size: var(--fs-sm); color: var(--txt); }
.cb-r b { font-size: var(--fs-lg); font-variant-numeric: tabular-nums; text-align: right; }
.cb-a, .cb-s { grid-column: 1 / -1; font-size: var(--fs-xs); color: var(--txt-dim); }
.cb-a { margin-top: -2px; }
.cb-plus b { color: var(--danger); }
.cb-moins b { color: var(--bio); }
.cb-net { background: var(--surface-2); }
.cb-net b { color: var(--txt); }
.cb-net .cb-l { font-weight: 600; }
.cb-manque { padding: 10px 14px; margin: 0; background: var(--surface-2); }
.cb .pp-alerte { margin: 0; border-radius: 0; border-left-width: 3px; }
@media (max-width: 520px) {
  .cb-r { grid-template-columns: 1fr; }
  .cb-r b { text-align: left; }
}

/* ---- deux entrées : l'appareil photo, et tout le reste ----
   Denis, 24/08 : la galerie et les fichiers, pas seulement l'appareil.
   Côte à côte sur un écran large, empilées sur un téléphone — c'est là
   qu'on s'en sert, et le pouce ne vise pas deux boutons de 30 px. */
.nj-entrees { display: flex; gap: 8px; }
.nj-entrees > .nj-prendre { flex: 1 1 0; }
.nj-importer { font-weight: 500; }
@media (max-width: 480px) { .nj-entrees { flex-direction: column; } }

/* un fichier qui n'est pas une image : son nom EST sa vignette */
.nj-doc { display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; padding: 6px; background: var(--surface-2); text-align: center; }
.nj-doc b { font-size: var(--fs-xs); letter-spacing: .06em; color: var(--accent-text); }
.nj-doc i { font-style: normal; font-size: 10px; line-height: 1.2; color: var(--txt-dim);
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  word-break: break-all; }

/* le drapeau « au planning / hors planning » dans la liste des chantiers */
.fil-p { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--line);
  background: var(--surface-2); color: var(--txt-dim); cursor: pointer; font-size: 15px;
  display: flex; align-items: center; justify-content: center; }
.fil-p:hover { border-color: var(--accent); color: var(--accent-text); }
.fil-p.off { border-style: dashed; color: var(--txt-faint); }
.et-gris { background: var(--surface-3); color: var(--txt-dim); border: 1px dashed var(--line); }

/* ---- « comment on fait » : la provenance se lit avant le texte ----
   Une réponse d'IA jamais relue ne doit pas se présenter du même ton qu'une
   méthode validée après trois chantiers. */
.cf-cle { padding: 10px 12px; border-radius: var(--r); background: var(--surface-2);
  border-left: 3px solid var(--accent); margin-bottom: 12px; }
.cf-cle .k { display: block; font-size: var(--fs-xs); letter-spacing: .05em;
  text-transform: uppercase; color: var(--txt-dim); }
.cf-cle b { display: block; font-size: var(--fs-md); font-family: var(--ff-display, var(--ff)); }
.cf-cle .dim { display: block; margin-top: 3px; }
.cf-voisines { margin: 12px 0; padding: 10px 12px; border: 1px dashed var(--line);
  border-radius: var(--r); background: var(--surface); }
.cf-v { padding: 8px 0; border-top: 1px solid var(--line-soft); }
.cf-v:first-of-type { border-top: 0; }
.cf-v b { font-size: var(--fs-sm); }
.cf-v p { margin: 4px 0; color: var(--txt-dim); }

/* ---- le Gantt d'un chantier : les étapes dans leur ordre ----
   L'avancement se lit dans la barre (remplissage) ET en chiffres ; le retard
   porte un ⚠ en toutes lettres, jamais la couleur seule. */
.gc { border: 1px solid var(--line); border-radius: var(--r); overflow-x: auto; }
.gc-ech, .gc-l { display: grid; grid-template-columns: 250px 1fr; min-width: 720px; }
.gc-ech { background: var(--surface-3); border-bottom: 1px solid var(--line); height: 26px; }
.gc-ech .gc-p { position: relative; }
.gc-ech .gc-p span { position: absolute; top: 5px; font-size: 10px; color: var(--txt-dim);
  transform: translateX(-50%); white-space: nowrap; }
.gc-l { border-bottom: 1px solid var(--line-soft); min-height: 40px; align-items: center; }
.gc-l:last-child { border-bottom: 0; }
.gc-n { padding: 6px 10px; font-size: var(--fs-xs); border-right: 1px solid var(--line);
  background: var(--surface-2); }
.gc-n b { display: block; font-weight: 600; }
.gc-n .dim { font-size: 11px; }
.gc-p { position: relative; min-height: 40px; }
.gc-b { position: absolute; top: 8px; height: 24px; border-radius: 5px; cursor: pointer;
  background: var(--surface-3); border: 1px solid var(--line); border-left: 3px solid var(--accent);
  overflow: hidden; min-width: 26px; }
.gc-b .av { position: absolute; inset: 0 auto 0 0; background: var(--accent-soft); }
.gc-b .tx { position: relative; display: block; padding: 0 7px; font: 600 11px/22px var(--ff);
  color: var(--txt); white-space: nowrap; }
.gc-b.encours { border-left-color: var(--bio); border-left-width: 4px; }
.gc-b.fait { border-left-style: dotted; opacity: .65; }
.gc-b.urgent, .gc-b.retard { border-left-color: var(--danger); border-left-width: 5px; }

/* ---- ce que contient une facture, avant de dire où elle va ---- */
.rt-contenu, .rt-pistes { margin: 10px 0; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--surface-2); overflow: hidden; }
.rt-contenu .k, .rt-pistes .k { padding: 7px 10px; background: var(--surface-3);
  font-size: var(--fs-xs); font-weight: 600; letter-spacing: .04em; color: var(--txt-dim);
  border-bottom: 1px solid var(--line); }
.rt-l { display: grid; grid-template-columns: 1fr 78px 84px; gap: 8px; align-items: baseline;
  padding: 5px 10px; border-bottom: 1px solid var(--line-soft); font-size: var(--fs-xs); }
.rt-l:last-child { border-bottom: 0; }
.rt-l .n i { display: block; font-style: normal; color: var(--txt-dim); font-size: 11px; }
.rt-l .q, .rt-l .m { text-align: right; color: var(--txt-dim); font-variant-numeric: tabular-nums; }
.rt-piste { display: block; width: 100%; text-align: left; border: 0; cursor: pointer;
  padding: 8px 10px; border-bottom: 1px solid var(--line-soft); background: none; color: var(--txt);
  font: 400 var(--fs-xs) var(--ff); }
.rt-piste:last-of-type { border-bottom: 0; }
.rt-piste:hover { background: var(--accent-soft); }
.rt-piste b { display: block; font-weight: 600; }
.rt-piste .dim { display: block; font-size: 11px; }
.rt-pistes p { margin: 0; padding: 8px 10px; border-top: 1px solid var(--line-soft); }
@media (max-width: 520px) { .rt-l { grid-template-columns: 1fr 70px; } .rt-l .q { display: none; } }

/* la barre de réglage du Gantt d'un chantier */
.gc-barre { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 10px 0; }
.gc-barre .dim { flex: 1 1 240px; }
/* le trait d'aujourd'hui : on se repère par rapport à lui, toujours */
.gc-auj { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--accent);
  opacity: .55; pointer-events: none; }
.gc .gc-p { overflow: visible; }
.gc-b { min-width: 34px; }
.gc-b.bougeable { cursor: grab; }
.gc-b.bougeable:hover { box-shadow: 0 0 0 2px var(--accent); }
.gc-b.glisse { opacity: .4; }
.gc-b.lot { cursor: default; opacity: .9; border-style: dashed; }
.gc-b.court .tx { padding: 0 4px; font-size: 10px; }
.gc-b .poi { position: absolute; top: 0; right: 0; width: 8px; height: 100%; cursor: ew-resize;
  border-radius: 0 5px 5px 0; }
.gc-b .poi:hover { background: var(--accent); opacity: .5; }

/* ---- la console d'écriture : à qui, quoi, quelles pièces ---- */
.ec-dest, .ec-pieces { margin-top: 12px; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--surface-2); overflow: hidden; }
.ec-dest .k, .ec-pieces .k { padding: 7px 10px; background: var(--surface-3); font-size: var(--fs-xs);
  font-weight: 600; letter-spacing: .04em; color: var(--txt-dim); border-bottom: 1px solid var(--line); }
.ec-l { display: flex; gap: 9px; align-items: flex-start; padding: 7px 10px;
  border-bottom: 1px solid var(--line-soft); cursor: pointer; font-size: var(--fs-xs); }
.ec-l:last-child { border-bottom: 0; }
.ec-l:hover { background: var(--surface-3); }
.ec-l input { margin-top: 2px; min-width: 16px; min-height: 16px; }
.ec-l b { font-weight: 600; }
.ec-l i { font-style: normal; color: var(--accent-text); font-size: 11px; }
.ec-l em { display: block; font-style: normal; color: var(--txt-dim); font-size: 11px; }
/* sans adresse : la case est morte, et ça se voit avant de cliquer */
.ec-l.sans { cursor: not-allowed; opacity: .6; }
.ec-l.sans em { color: var(--warn); }
.ec-pj { max-height: 220px; overflow: auto; }
.ec-pieces p { margin: 0; padding: 8px 10px; border-top: 1px solid var(--line-soft); }

/* ---- un panneau qui se replie : montrer peu, dire assez ----
   Apple ne cache pas pour faire joli — il cache ce qui ne demande rien, et
   laisse en surface de quoi savoir s'il faut ouvrir. */
.cc-repli { border: 1px solid var(--line); border-radius: var(--r); overflow: hidden;
  background: var(--surface-2); }
.cc-repli-t { display: flex; gap: 10px; align-items: center; width: 100%; text-align: left;
  border: 0; background: none; cursor: pointer; padding: 13px 16px; color: var(--txt);
  font: 400 var(--fs-sm) var(--ff); min-height: var(--tap); }
.cc-repli-t:hover { background: var(--surface-3); }
.cc-repli-t .ch { color: var(--txt-dim); width: 12px; }
.cc-repli-t .tx b { display: block; font-weight: 600; }
.cc-repli-t .tx i { font-style: normal; font-size: var(--fs-xs); color: var(--txt-dim); }
.cc-repli-c { padding: 0 16px 14px; border-top: 1px solid var(--line-soft); }
.cc-repli-c .cc-bloc:first-child { margin-top: 12px; }

/* ---- la carte dépouillée : un glyphe, un chiffre, un mot ----

   Denis, 29/08, devant le tableau de bord b2u : « j'adore comme c'est épuré,
   comment on a l'information ».

   C'est un VARIANT, pas un remplacement : les écrans qui ont besoin d'une
   méta la gardent. On ne dépouille que là où le chiffre se suffit. */
.kpi-nu { text-align: center; }
.kpi-nu .g { display: block; font-size: 24px; line-height: 1; margin-bottom: 8px; opacity: .75; }
.kpi-nu .n { font-size: 30px; font-weight: 700; line-height: 1.05;
  font-variant-numeric: tabular-nums; color: var(--txt); }
.kpi-nu .l { font-size: var(--fs-xs); color: var(--txt-dim); margin-top: 4px; }
.kpi-nu.bio .n { color: var(--bio); }
.kpi-nu.neg .n { color: var(--danger); }

/* ---- la chaîne de l'argent ----

   Quatre pavés donnent quatre nombres justes et aucun lien entre eux : pour
   savoir s'il reste à facturer, il faut faire la soustraction de tête.

   La flèche montre le SENS — l'argent va du devis à la banque, et chaque
   étape en perd un peu. Sur Hovine, « facturé 22 222 € » ne disait rien ;
   « 26 % » et la barre à un quart disent tout, sans qu'on cherche.

   Le taux se lit ET se voit : jamais la couleur seule. */
.cha { display: grid; grid-template-columns: 1fr auto 1fr auto 1fr auto 1fr;
  align-items: start; padding: 22px 20px 16px; }
.cha-e { padding: 0 4px; text-align: center; }
.cha-e .n { font-size: 26px; font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.cha-e .l { font-size: var(--fs-xs); color: var(--txt-dim); margin-top: 3px; }
.cha-e .p { font-size: 11px; font-weight: 600; color: var(--accent-text); margin-top: 5px; }
.cha-e.bio .n { color: var(--bio); }
.cha-e.neg .n { color: var(--danger); }
.cha-f { color: var(--txt-faint); font-size: 17px; padding: 0 6px; margin-top: 9px; }
.cha-f.trou { color: var(--danger); opacity: .85; }
@media (max-width: 700px) {
  .cha { grid-template-columns: 1fr auto 1fr; row-gap: 16px; }
  .cha-f:nth-of-type(2) { display: none; }
}
/* la barre : elle dit la même chose sans un chiffre, et c'est le BLANC
   qui appelle un geste */
.cha-b { height: 6px; border-radius: 3px; background: var(--surface-3);
  overflow: hidden; margin: 0 20px 12px; display: flex; }
.cha-b span { display: block; height: 100%; }
.cha-b .pay { background: var(--bio); }
.cha-b .fac { background: var(--accent-text); }
.cha-l { display: flex; gap: 16px; padding: 0 20px 16px; font-size: 11px;
  color: var(--txt-dim); flex-wrap: wrap; }
.cha-l i { font-style: normal; display: inline-flex; align-items: center; gap: 5px; }
.cha-pt { width: 9px; height: 9px; border-radius: 2px; display: inline-block; }
.cha-pied { display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  border-top: 1px solid var(--line-soft); padding: 14px 20px; }
.cha-pied b { font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; }
.cha-pied .l { color: var(--txt-dim); font-size: var(--fs-xs); }
