/* =============================================================================
   SESAME — CRM interne VIVAPROD
   Charte reprise du site vitrine, transposée en interface d'application.
   ========================================================================== */

/* ─── POLICES (locales, aucun CDN) ────────────────────────────────────────── */
@font-face { font-family:'Red Hat Display'; src:url('../fonts/RedHatDisplay/RedHatDisplay-Regular.ttf') format('truetype'); font-weight:400; font-display:swap; }
@font-face { font-family:'Red Hat Display'; src:url('../fonts/RedHatDisplay/RedHatDisplay-Bold.ttf') format('truetype'); font-weight:700; font-display:swap; }
@font-face { font-family:'Red Hat Display'; src:url('../fonts/RedHatDisplay/RedHatDisplay-ExtraBold.ttf') format('truetype'); font-weight:800; font-display:swap; }
@font-face { font-family:'Red Hat Display'; src:url('../fonts/RedHatDisplay/RedHatDisplay-Black.ttf') format('truetype'); font-weight:900; font-display:swap; }
@font-face { font-family:'Plus Jakarta Sans'; src:url('../fonts/PlusJakartaSans/PlusJakartaSans-Regular.ttf') format('truetype'); font-weight:400; font-display:swap; }
@font-face { font-family:'Plus Jakarta Sans'; src:url('../fonts/PlusJakartaSans/PlusJakartaSans-Medium.ttf') format('truetype'); font-weight:500; font-display:swap; }
@font-face { font-family:'Plus Jakarta Sans'; src:url('../fonts/PlusJakartaSans/PlusJakartaSans-Bold.ttf') format('truetype'); font-weight:700; font-display:swap; }

/* ─── JETONS ──────────────────────────────────────────────────────────────── */
:root {
  --vert-fonce:#1A5C3A; --vert-mid:#2E7D52; --vert-clair:#4CAF7D;
  --vert-sauge:#8FBF9F; --vert-pale:#D4EDE0;
  --orange:#E8612A; --orange-clair:#F5956A; --orange-pale:#FDE8DC;
  --jaune:#F5A623; --jaune-pale:#FEF3DC;
  --fond-nuit:#0F2E1E; --fond-clair:#F0F0EC; --fond-blanc:#FFFFFF;
  /*
   * --texte-clair sert au texte secondaire : poids de fichiers, dates,
   * compteurs, aides de champ — presque toujours en petit corps, là où la
   * lisibilité se joue. L'ancien #8A9590 ne donnait que 3,10:1 sur blanc,
   * sous le seuil de 4,5 attendu. Même teinte vert-gris, simplement assombrie :
   * 5,52:1 sur blanc, 4,83:1 sur le fond clair, et toujours nettement plus
   * pâle que --texte-mid.
   */
  --texte-fonce:#1A2E28; --texte-mid:#4A5550; --texte-clair:#616B66;

  --col-devis:#7C3AED; --col-valide:#0EA5E9; --col-todo:#E8612A;
  --col-attente:#6B7280; --col-facturation:#2E7D52; --col-archives:#1A2E28;

  --font-titre:'Red Hat Display', system-ui, -apple-system, sans-serif;
  --font-texte:'Plus Jakarta Sans', system-ui, -apple-system, sans-serif;

  --r-sm:6px; --r-md:12px; --r-lg:20px; --r-xl:32px; --r-full:9999px;
  --ombre-sm:0 1px 3px rgba(0,0,0,.06), 0 1px 2px rgba(0,0,0,.04);
  --ombre-md:0 4px 16px rgba(0,0,0,.08), 0 2px 8px rgba(0,0,0,.04);
  --ombre-lg:0 10px 40px rgba(0,0,0,.12), 0 4px 16px rgba(0,0,0,.06);
  --ombre-verte:0 8px 32px rgba(26,92,58,.25);

  --t-rapide:150ms cubic-bezier(.4,0,.2,1);
  --t-base:300ms cubic-bezier(.4,0,.2,1);
  --t-ressort:400ms cubic-bezier(.34,1.56,.64,1);
  /* Ressort discret de l'ouverture des modales. */
  --e-modale:cubic-bezier(.34,1.56,.64,1);

  --barre-l:264px;        /* barre latérale dépliée */
  --barre-l-repliee:76px; /* barre latérale repliée : icônes seules */
  --nav-bas-h:64px;     /* hauteur de la barre d'onglets mobile */
}

/* ─── BASE ────────────────────────────────────────────────────────────────── */
* { box-sizing:border-box; }
/* L'attribut hidden prime sur toute règle d'affichage : sans ce garde-fou,
   un display: posé plus loin le rend inopérant. */
[hidden] { display:none !important; }
html { -webkit-text-size-adjust:100%; }
body {
  margin:0; font-family:var(--font-texte); font-size:15px; line-height:1.55;
  color:var(--texte-fonce); background:var(--fond-clair);
  -webkit-font-smoothing:antialiased;
  /* Encoche et barre gestuelle iOS */
  padding-bottom:env(safe-area-inset-bottom);
}
h1,h2,h3,h4,h5 { font-family:var(--font-titre); font-weight:800; letter-spacing:-.02em; margin:0; }
a { color:var(--vert-fonce); text-decoration:none; }
button { font-family:inherit; }
:focus-visible { outline:3px solid var(--vert-clair); outline-offset:2px; border-radius:var(--r-sm); }

/* Zone tactile confortable partout sur mobile.
   La case à cocher en est exclue : un min-height l'étirerait en ovale.
   Sa surface cliquable est agrandie par un pseudo-élément (voir .tache__case). */
@media (max-width:991.98px) {
  .btn, .nav-lien, .icone-btn { min-height:44px; }

  /* La hauteur était garantie, la largeur non : dans une ligne serrée un
     bouton d'icône se laissait comprimer jusqu'à 28 px. */
  .icone-btn:not(.icone-btn--mini) { min-width:44px; }

  /* Les flèches d'ordre échappent à la règle : compactes et empilées par
     deux, elles forment ensemble une cible de la bonne taille. */
  .icone-btn--mini { min-height:0; }

  .onglet { min-height:44px; }
  .chiffres__basculer { width:40px; height:40px; }
}

/* ─── BOUTONS (repris du site vitrine) ────────────────────────────────────── */
.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:.5rem;
  padding:.6rem 1.25rem; border-radius:var(--r-full);
  font-family:var(--font-texte); font-size:.875rem; font-weight:600; letter-spacing:.01em;
  border:2px solid transparent; cursor:pointer; white-space:nowrap;
  transition:all var(--t-base);
}
.btn--primaire { background:var(--vert-fonce); color:#fff; border-color:var(--vert-fonce); box-shadow:var(--ombre-verte); }
.btn--primaire:hover { background:var(--vert-mid); border-color:var(--vert-mid); transform:translateY(-2px); color:#fff; }
.btn--primaire:active { transform:translateY(0); }
.btn--contour { background:transparent; color:var(--vert-fonce); border-color:var(--vert-fonce); }
.btn--contour:hover { background:var(--vert-fonce); color:#fff; transform:translateY(-2px); }
.btn--discret { background:transparent; color:var(--texte-mid); border-color:transparent; }
.btn--discret:hover { background:rgba(0,0,0,.05); color:var(--texte-fonce); }
.btn--bloc { width:100%; }
.btn--sm { padding:.4rem .85rem; font-size:.8125rem; }
.btn[disabled] { opacity:.55; cursor:not-allowed; transform:none !important; }

.icone-btn {
  display:inline-flex; align-items:center; justify-content:center;
  width:38px; height:38px; border:0; border-radius:var(--r-full);
  background:transparent; color:var(--texte-mid); cursor:pointer;
  transition:background var(--t-rapide), color var(--t-rapide);
}
.icone-btn:hover { background:rgba(0,0,0,.06); color:var(--texte-fonce); }
/* Sans cela, un bouton d'icône se laisse écraser à 28 px dans une ligne serrée. */
.icone-btn { flex-shrink:0; }


/* ─── COQUE / BARRE LATÉRALE ──────────────────────────────────────────────── */
.coque { min-height:100dvh; }

.barre {
  position:fixed; inset:0 auto 0 0; width:var(--barre-l); z-index:1040;
  display:flex; flex-direction:column;
  background:var(--fond-nuit); color:#fff;
  padding:1.5rem 1rem calc(1rem + env(safe-area-inset-bottom));
}
.barre__logo { display:block; padding:.25rem .5rem; overflow:hidden; }
.barre__logo img { width:140px; height:auto; display:block; }

.barre__nav { display:flex; flex-direction:column; gap:.25rem; flex:1; }
.nav-lien {
  display:flex; align-items:center; gap:.85rem;
  padding:.7rem .85rem; border-radius:var(--r-md);
  color:rgba(255,255,255,.72); font-weight:500; font-size:.9375rem;
  transition:background var(--t-rapide), color var(--t-rapide);
}
.nav-lien:hover { background:rgba(255,255,255,.08); color:#fff; }
.nav-lien.est-actif { background:var(--vert-fonce); color:#fff; font-weight:600; }
.nav-lien svg { flex-shrink:0; }
.nav-lien__pastille {
  margin-left:auto; min-width:22px; padding:0 .4rem; height:22px;
  display:inline-flex; align-items:center; justify-content:center;
  border-radius:var(--r-full); background:var(--orange); color:#fff;
  font-size:.6875rem; font-weight:700;
}

.barre__pied { border-top:1px solid rgba(255,255,255,.12); padding-top:1rem; margin-top:1rem; }

/* ─── CONTENU ─────────────────────────────────────────────────────────────── */
.principal { margin-left:var(--barre-l); min-height:100dvh; display:flex; flex-direction:column; }
.principal--large { padding:0; }
.zone { padding:1.25rem 2.5rem 3rem; flex:1; }
/* Les cartes d'une zone respirent entre elles, sur tous les écrans. */
.zone > .carte + .carte,
.zone > section.carte { margin-top:1.25rem; }
.zone > .carte:first-of-type { margin-top:0; }

.entete { display:flex; align-items:flex-start; gap:1rem; padding:2rem 2.5rem 0; }
.entete__salut { font-size:clamp(1.6rem, 3.2vw, 2.25rem); line-height:1.15; }
.entete__date { color:var(--texte-clair); font-size:.9375rem; margin-top:.35rem; }
.entete__droite { margin-left:auto; display:flex; align-items:center; gap:.5rem; }

/* ─── AVATAR ──────────────────────────────────────────────────────────────── */
.avatar {
  display:inline-flex; align-items:center; justify-content:center;
  width:40px; height:40px; border-radius:var(--r-full);
  background:var(--vert-fonce); color:#fff;
  font-family:var(--font-titre); font-weight:800; font-size:.8125rem;
  letter-spacing:.02em; flex-shrink:0; border:2px solid #fff;
}
.avatar--sm { width:28px; height:28px; font-size:.6875rem; border-width:1.5px; }
.avatar--lg { width:56px; height:56px; font-size:1.125rem; }

/* ─── CARTES / WIDGETS ────────────────────────────────────────────────────── */
.carte {
  background:var(--fond-blanc); border-radius:var(--r-lg);
  box-shadow:var(--ombre-sm); overflow:hidden;
}
.carte__tete {
  display:flex; align-items:center; gap:.75rem;
  padding:1.25rem 1.5rem .75rem;
}
.carte__titre { font-size:1.0625rem; font-weight:800; }
.carte__corps { padding:0 1.5rem 1.25rem; }
/*
 * Sans marge haute, parce que le corps suit d'ordinaire un en-tête qui l'a
 * déjà donnée. Quand il n'y en a pas, le contenu venait se coller au bord
 * supérieur de la carte : on lui rend alors le même retrait que l'en-tête
 * aurait apporté. Une vingtaine de cartes de l'application sont dans ce cas.
 */
.carte__corps:first-child { padding-top:1.25rem; }
/*
 * Une case seule dans sa carte se cale sur le seul retrait de celle-ci : ses
 * marges propres, prévues pour l'espacer de champs voisins, la décentraient
 * faute de voisins.
 */
.carte__corps > .case-memo:only-child { margin:0; }
.carte__pied { padding:.75rem 1.5rem 1.25rem; border-top:1px solid rgba(0,0,0,.05); }

/* ─── TUILES CHIFFRÉES ────────────────────────────────────────────────────── */
.chiffres {
  margin-top:2.25rem;
  background:var(--fond-blanc); border-radius:var(--r-lg);
  box-shadow:var(--ombre-sm); overflow:hidden;
}
.chiffres__tete {
  display:flex; align-items:center; gap:.75rem;
  padding:1.25rem 1.5rem .25rem;
}
.chiffres__titre { font-size:1.0625rem; font-weight:800; }

/* Pendant clair du bouton de repli de la barre latérale, posé sur fond blanc. */
.chiffres__basculer {
  display:inline-flex; align-items:center; justify-content:center;
  width:34px; height:34px; flex-shrink:0; margin-left:auto;
  border:0; border-radius:var(--r-md); cursor:pointer;
  background:rgba(0,0,0,.05); color:var(--texte-clair);
  transition:background var(--t-rapide), color var(--t-rapide);
}
.chiffres__basculer:hover { background:rgba(0,0,0,.10); color:var(--texte-fonce); }
.chiffres__icone-voir { display:none; }

.chiffres__corps { display:grid; grid-template-columns:repeat(3, 1fr); gap:0; }

/* ─── Chiffres masqués ────────────────────────────────────────────────────── */
html.chiffres-replies .chiffres__corps         { display:none; }
/* Replié, l'en-tête n'est plus une en-tête : il est toute la carte. Son
   padding bas de 4px, calculé pour venir au contact des tuiles, laisserait
   le contenu collé en bas. On rend la respiration symétrique, à hauteur
   de carte inchangée. */
html.chiffres-replies .chiffres__tete          { padding-block:.75rem; }
html.chiffres-replies .chiffres__icone-voir    { display:inline-flex; }
html.chiffres-replies .chiffres__icone-masquer { display:none; }
.chiffre { padding:1.35rem 1.5rem; position:relative; }
.chiffre + .chiffre::before {
  content:''; position:absolute; left:0; top:22%; bottom:22%;
  width:1px; background:rgba(0,0,0,.08);
}
.chiffre__etiquette {
  display:flex; align-items:center; gap:.45rem;
  font-size:.8125rem; font-weight:600; color:var(--texte-clair);
  text-transform:uppercase; letter-spacing:.06em;
}
.chiffre__point { width:8px; height:8px; border-radius:var(--r-full); flex-shrink:0; }
.chiffre__valeur {
  font-family:var(--font-titre); font-weight:900; letter-spacing:-.03em;
  font-size:clamp(1.5rem, 3.5vw, 2.125rem); margin-top:.3rem; line-height:1.1;
}
.chiffre__detail { font-size:.8125rem; color:var(--texte-clair); }

/* ─── TODO LIST ───────────────────────────────────────────────────────────── */
.taches { list-style:none; margin:0; padding:0; }
/* Une respiration entre les lignes, comme pour les échéances. Elle compte
   surtout pour les tâches épinglées : leur fond coloré les soude en un seul
   bloc dès qu'elles se touchent. */
.tache + .tache { margin-top:.5rem; }
.tache {
  display:flex; align-items:center; gap:.75rem;
  padding:.6rem .5rem; border-radius:var(--r-md);
  transition:background var(--t-rapide);
}
.tache:hover { background:var(--fond-clair); }
.tache.est-glissee { opacity:.4; }
.tache__poignee {
  cursor:grab; color:var(--texte-clair); opacity:0; flex-shrink:0;
  transition:opacity var(--t-rapide); touch-action:none;
}
.tache:hover .tache__poignee { opacity:1; }
@media (hover:none) { .tache__poignee { opacity:.5; } }

.tache__case {
  appearance:none; width:22px; height:22px; flex-shrink:0; cursor:pointer;
  border:2px solid var(--vert-sauge); border-radius:var(--r-full);
  background:transparent; transition:all var(--t-ressort); position:relative;
}
/* Cible tactile de 44px débordant du rond visible de 22px */
.tache__case::before {
  content:''; position:absolute; inset:-11px;
}
.tache__case:checked { background:var(--vert-fonce); border-color:var(--vert-fonce); }
.tache__case:checked::after {
  content:''; position:absolute; left:6px; top:2px;
  width:5px; height:10px; border:solid #fff; border-width:0 2.5px 2.5px 0;
  transform:rotate(45deg);
}
.tache__texte {
  flex:1; border:0; background:transparent; padding:.15rem 0;
  font:inherit; color:var(--texte-fonce); min-width:0;
  display:block; resize:none; overflow:hidden; line-height:1.35;
}
.tache__texte:focus { outline:none; border-bottom:2px solid var(--vert-clair); }
.tache.est-faite .tache__texte { text-decoration:line-through; color:var(--texte-clair); }

/*
 * Sur téléphone, la ligne est très meublée : poignée, case, épingle et
 * corbeille laissaient 90 px à l'intitulé sur les 287 disponibles. On rend
 * à celui-ci tout ce qui peut l'être — écarts, marges de la ligne et marges
 * intérieures de la carte, que le doigt ne vise jamais.
 */
@media (max-width:575.98px) {
  .tache { gap:.5rem; padding-left:.25rem; padding-right:.25rem; }
  .taches, .tache-ajout { margin-inline:-.5rem; }
  .carte__corps { padding-left:1rem; padding-right:1rem; }
}
.tache__suppr { opacity:0; transition:opacity var(--t-rapide); }
.tache:hover .tache__suppr, .tache:focus-within .tache__suppr { opacity:1; }
@media (hover:none) { .tache__suppr { opacity:.6; } }

.tache-ajout {
  display:flex; align-items:center; gap:.75rem;
  padding:.7rem .5rem; margin-top:.25rem;
  border-top:1px dashed rgba(0,0,0,.1);
}
.tache-ajout__champ {
  flex:1; border:0; background:transparent; font:inherit; padding:.2rem 0;
  color:var(--texte-fonce);
}
.tache-ajout__champ::placeholder { color:var(--texte-clair); }
.tache-ajout__champ:focus { outline:none; }

/* ─── ÉCHÉANCES ───────────────────────────────────────────────────────────── */
.echeances { display:flex; flex-direction:column; gap:.6rem; }
.echeance {
  display:flex; align-items:center; gap:.75rem;
  padding:.85rem 1rem; border-radius:var(--r-md);
  background:var(--fond-clair); border-left:4px solid var(--vert-sauge);
  transition:transform var(--t-rapide), box-shadow var(--t-rapide);
}
.echeance:hover { transform:translateX(3px); box-shadow:var(--ombre-sm); }
.echeance--proche { border-left-color:var(--jaune); background:var(--jaune-pale); }
.echeance--retard { border-left-color:var(--orange); background:var(--orange-pale); }
.echeance__titre { font-weight:600; font-size:.9375rem; line-height:1.3; }
.echeance__meta { font-size:.8125rem; color:var(--texte-mid); }
.echeance__jours { margin-left:auto; text-align:right; flex-shrink:0; }
.echeance__nb { font-family:var(--font-titre); font-weight:800; font-size:1.125rem; line-height:1; }
.echeance__unite { font-size:.6875rem; color:var(--texte-clair); text-transform:uppercase; letter-spacing:.05em; }

/* ─── ÉTAT VIDE ───────────────────────────────────────────────────────────── */
.vide { text-align:center; padding:2rem 1rem; color:var(--texte-clair); }
.vide svg { opacity:.35; margin-bottom:.75rem; }
.vide p { margin:0; font-size:.9375rem; }

/* =============================================================================
   KANBAN — colonnes pleine couleur, façon MeisterTask
   ========================================================================== */
.kanban {
  display:flex; gap:0; align-items:stretch;
  overflow-x:auto; overflow-y:hidden; flex:1;
  scroll-snap-type:x proximity;
  -webkit-overflow-scrolling:touch;
}
.kanban::-webkit-scrollbar { height:10px; }
.kanban::-webkit-scrollbar-thumb { background:rgba(0,0,0,.2); border-radius:var(--r-full); }

.colonne {
  --teinte:var(--col-attente);
  flex:1 0 300px; min-width:300px; max-width:1fr;
  display:flex; flex-direction:column;
  background:var(--teinte); scroll-snap-align:start;
}

.colonne__tete {
  display:flex; align-items:center; gap:.6rem;
  padding:1.1rem 1.15rem .9rem; color:#fff;
  position:sticky; top:0; z-index:2; background:var(--teinte);
}
.colonne__titre {
  font-family:var(--font-titre); font-weight:800; font-size:1.0625rem;
  letter-spacing:-.01em; color:#fff;
}
.colonne__compteur {
  margin-left:auto; min-width:24px; height:24px; padding:0 .45rem;
  display:inline-flex; align-items:center; justify-content:center;
  border-radius:var(--r-full); background:rgba(255,255,255,.22); color:#fff;
  font-size:.75rem; font-weight:700;
}
.colonne__total {
  padding:0 1.15rem .75rem; color:rgba(255,255,255,.85);
  font-size:.8125rem; font-weight:600; letter-spacing:.02em;
}

.colonne__liste {
  flex:1; overflow-y:auto; padding:0 .75rem .75rem;
  display:flex; flex-direction:column; gap:.6rem;
  min-height:60px;
}
.colonne__liste::-webkit-scrollbar { width:8px; }
.colonne__liste::-webkit-scrollbar-thumb { background:rgba(255,255,255,.3); border-radius:var(--r-full); }

/* Cible de dépôt mise en évidence pendant un glisser */
.colonne__liste.est-survolee { background:rgba(255,255,255,.12); border-radius:var(--r-md); }

.colonne__ajout {
  margin:0 .75rem 1.25rem; padding:.7rem; border-radius:var(--r-md);
  display:flex; align-items:center; justify-content:center; gap:.4rem;
  background:rgba(255,255,255,.16); color:#fff; border:0; cursor:pointer;
  font-size:.875rem; font-weight:600;
  transition:background var(--t-rapide);
}
.colonne__ajout:hover { background:rgba(255,255,255,.28); }

/* ─── FICHE PROJET ────────────────────────────────────────────────────────── */
.fiche {
  background:#fff; border-radius:var(--r-md); padding:.85rem .9rem;
  box-shadow:var(--ombre-sm); cursor:pointer; position:relative;
  transition:box-shadow var(--t-rapide), transform var(--t-rapide);
  touch-action:manipulation;
}
.fiche:hover { box-shadow:var(--ombre-md); transform:translateY(-1px); }
.fiche:active { cursor:grabbing; }
.fiche.est-glissee { opacity:.35; }
.fiche.est-fantome { box-shadow:var(--ombre-lg); transform:rotate(2deg); }

.fiche__haut { display:flex; align-items:flex-start; gap:.6rem; }
.fiche__titre {
  font-weight:600; font-size:.9375rem; line-height:1.3; flex:1;
  color:var(--texte-fonce); overflow-wrap:anywhere;
}
.fiche__client {
  font-size:.75rem; color:var(--texte-clair); font-weight:600;
  text-transform:uppercase; letter-spacing:.04em; margin-bottom:.15rem;
}
.fiche__bas {
  display:flex; align-items:center; gap:.5rem; flex-wrap:wrap;
  margin-top:.6rem;
}
.fiche__bas:empty { display:none; }

.jeton {
  display:inline-flex; align-items:center; gap:.3rem;
  padding:.2rem .5rem; border-radius:var(--r-sm);
  font-size:.6875rem; font-weight:700; letter-spacing:.03em;
}
.jeton--date { background:var(--fond-clair); color:var(--texte-mid); }
.jeton--retard { background:var(--orange-pale); color:#B33F12; }
.jeton--urgent { background:var(--orange); color:#fff; text-transform:uppercase; }
.jeton--partage { background:#EDE9FE; color:#5B21B6; }
/* Checklist : neutre tant qu'il reste des éléments à faire, vert une fois
   la liste bouclée — c'est le seul état qui mérite d'attirer l'œil. */
.jeton--checklist { background:var(--fond-clair); color:var(--texte-mid); }
.jeton--checklist.est-complete { background:var(--vert-pale); color:var(--vert-fonce); }

/* ─── BARRE D'OUTILS DU KANBAN ────────────────────────────────────────────── */
.outils {
  display:flex; align-items:center; gap:.6rem; flex-wrap:wrap;
  padding:1rem 2.5rem; background:var(--fond-blanc);
  border-bottom:1px solid rgba(0,0,0,.06);
}
.recherche { position:relative; flex:0 1 320px; }
.recherche input {
  width:100%; padding:.55rem .9rem .55rem 2.4rem;
  border:2px solid transparent; border-radius:var(--r-full);
  background:var(--fond-clair); font:inherit; font-size:.875rem;
}
.recherche input:focus { outline:none; border-color:var(--vert-clair); background:#fff; }
.recherche svg { position:absolute; left:.85rem; top:50%; transform:translateY(-50%); color:var(--texte-clair); }

/* =============================================================================
   RESPONSIVE — l'application doit rester rapide au pouce
   ========================================================================== */

/* Barre d'onglets du bas : masquée sur grand écran */
.nav-bas { display:none; }

@media (max-width:991.98px) {
  .barre { transform:translateX(-100%); transition:transform var(--t-base); box-shadow:var(--ombre-lg); }
  .barre.est-ouverte { transform:translateX(0); }
  .principal { margin-left:0; padding-bottom:var(--nav-bas-h); }
  .entete { padding:1.25rem 1.25rem 0; }
  .zone { padding:1.25rem 1.25rem 2rem; }
  .outils { padding:.75rem 1.25rem; }

  .voile {
    position:fixed; inset:0; z-index:1035;
    background:rgba(15,46,30,.5); opacity:0; pointer-events:none;
    transition:opacity var(--t-base);
  }
  .voile.est-visible { opacity:1; pointer-events:auto; }

  /* Barre d'onglets fixe, atteignable au pouce */
  .nav-bas {
    display:flex; position:fixed; left:0; right:0; bottom:0; z-index:1030;
    background:var(--fond-blanc); border-top:1px solid rgba(0,0,0,.08);
    padding-bottom:env(safe-area-inset-bottom);
    box-shadow:0 -2px 12px rgba(0,0,0,.06);
  }
  .nav-bas__lien {
    flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center;
    gap:.15rem; padding:.5rem .25rem; height:var(--nav-bas-h);
    color:var(--texte-clair); font-size:.6875rem; font-weight:600;
  }
  .nav-bas__lien.est-actif { color:var(--vert-fonce); }
  .nav-bas__lien.est-actif svg { transform:translateY(-1px); }

  /*
   * La barre d'onglets défile pour elle-même. Sans cela, cinq onglets
   * élargissent la page entière — et une page qui déborde horizontalement
   * décroche les éléments en « position:fixed » : la barre de navigation
   * du bas se retrouve calée sur la largeur du document, hors de l'écran.
   * On garde « inline-flex » pour que la pastille reste ajustée au contenu
   * là où les onglets tiennent (deux onglets sur la page Clients).
   */
  .onglets {
    max-width:100%; overflow-x:auto; overflow-y:hidden;
    scrollbar-width:none;
  }
  .onglets::-webkit-scrollbar { display:none; }
  .onglet { flex:0 0 auto; }

  /* Les tuiles chiffrées passent en pile lisible */
  .chiffres__corps { grid-template-columns:1fr; }
  .chiffre + .chiffre::before { left:1.5rem; right:1.5rem; top:0; bottom:auto; width:auto; height:1px; }

  /* Une colonne de kanban par écran, on fait défiler au doigt.
     Largeur en %, calculée sur la boîte du kanban : « 100vw » inclurait
     une éventuelle barre de défilement verticale et décalerait l'aimantation. */
  .kanban { scroll-snap-type:x mandatory; }
  .colonne { flex:0 0 100%; min-width:100%; }
}

@media (min-width:992px) {
  .barre-bascule { display:none; }
}

/*
 * Cartes de l'accueil repliables — sur mobile seulement. Côte à côte sur grand
 * écran, elles tiennent à l'écran ; empilées, la todo list repousse les projets
 * hors de vue. Le chevron n'existe donc que là où le repli sert.
 */
.carte__replier { display:none; margin-left:auto; }
.carte__compte + .carte__replier, .carte__titre + .btn + .carte__replier { margin-left:0; }
.carte__replier svg { transition:transform var(--t-rapide); }
@media (max-width:991.98px) {
  .carte--repliable .carte__replier { display:inline-flex; }
  .carte--repliable .carte__tete { cursor:pointer; user-select:none; }
  .carte--repliable .carte__tete a { cursor:pointer; }
  .carte--repliable .carte__tete > :nth-last-child(2) { margin-left:auto; }
  .carte--repliable.est-replie .carte__replier svg { transform:rotate(-90deg); }
  .carte--repliable.est-replie .carte__corps { display:none; }
  /* Replié, l'en-tête est toute la carte : respiration symétrique. */
  .carte--repliable.est-replie .carte__tete { padding-block:1rem; }
  .carte--repliable:not(.est-replie) .carte__corps { animation:bloc-ouvre 200ms ease; }
}

/* ─── GRILLE DU TABLEAU DE BORD ───────────────────────────────────────────── */
.grille-bord {
  display:grid; gap:1.25rem;
  grid-template-columns:1fr;
}
@media (min-width:992px) {
  .grille-bord { grid-template-columns:1.15fr .85fr; }
}

/* ─── MOUVEMENT RÉDUIT ────────────────────────────────────────────────────── */
@media (prefers-reduced-motion:reduce) {
  *, *::before, *::after { animation-duration:.01ms !important; transition-duration:.01ms !important; }
}

/* Les styles de colonne « Archives » n'ont plus d'objet : la colonne a été
   retirée du kanban. L'archivage se fait par projets.archive_at. */

/* Un bouton utilisé comme lien de navigation (déconnexion) */
button.nav-lien {
  width:100%; border:0; background:transparent; cursor:pointer;
  font:inherit; font-size:.9375rem; text-align:left;
}
button.nav-lien:hover { background:rgba(255,255,255,.08); color:#fff; }
.barre__pied form { margin:0; }

/* =============================================================================
   AUTHENTIFICATION
   ========================================================================== */
.auth {
  min-height:100dvh; display:flex; align-items:center; justify-content:center;
  padding:1.5rem; background:var(--fond-nuit);
  background-image:radial-gradient(ellipse at 20% 0%, rgba(46,125,82,.55), transparent 55%),
                   radial-gradient(ellipse at 100% 100%, rgba(26,92,58,.5), transparent 50%);
}
.auth__boite {
  width:100%; max-width:420px; background:#fff;
  border-radius:var(--r-xl); padding:2.5rem 2rem;
  box-shadow:var(--ombre-lg);
}
.auth__logo { display:block; width:150px; margin:0 auto 1.75rem; }
.auth__titre { font-size:1.5rem; text-align:center; margin-bottom:.4rem; }
.auth__sous { text-align:center; color:var(--texte-clair); font-size:.9375rem; margin:0 0 1.75rem; }

.champ { margin-bottom:1rem; }
/*
 * Un seul traitement pour tout ce qui nomme une section, quel que soit
 * l'élément : <label> quand un champ est associé, .champ__legende pour un
 * groupe sans champ unique, .fiche-sous-titre quand une valeur l'accompagne.
 * Les trois étaient déclarés séparément, à 2,4 px de marge près.
 */
/*
 * « :not([class]) » n'est pas une coquetterie.
 *
 * Cette règle habille l'intitulé d'un champ. Mais « .champ label » est plus
 * spécifique que n'importe quelle classe seule : elle écrasait donc le dessin
 * de tout <label> portant la sienne — case à cocher, interrupteur, zone de
 * dépôt —, leur imposant display:block là où ils se veulent flex. Le symptôme
 * était discret et constant : contenu collé en haut à gauche au lieu d'être
 * centré, graisse et marge inattendues.
 *
 * Limiter la règle aux <label> sans classe résout la famille entière d'un
 * coup : un intitulé ordinaire n'en porte jamais, et un label qui en porte une
 * sait ce qu'il veut.
 */
.champ label:not([class]), .champ__legende, .fiche-sous-titre {
  display:block; font-size:.8125rem; font-weight:700; color:var(--texte-mid);
  margin-bottom:.35rem; letter-spacing:.02em;
}
.champ input, .champ select, .champ textarea {
  width:100%; padding:.7rem .9rem; font:inherit; font-size:.9375rem;
  line-height:1.5;
  border:2px solid #E3E3DD; border-radius:var(--r-md);
  background:#fff; color:var(--texte-fonce);
  transition:border-color var(--t-rapide);
}
/*
 * Hauteur imposée aux contrôles d'une seule ligne. Avec le seul padding,
 * un menu déroulant tombait à 47 px, un champ texte à 49 et un sélecteur
 * de date à 51 : empilés dans la colonne, les bords ne s'alignaient pas.
 * La hauteur de ligne n'y suffit pas — ces widgets natifs gardent la leur.
 *
 * Cases à cocher et boutons radio sont exclus, en plus du textarea qui doit
 * pouvoir grandir : ce ne sont pas des champs pleine largeur. Sans cette
 * exclusion, les cases des listes à cocher du descriptif passaient de 14 à
 * 49 px de haut — la règle l'emportait sur celle qui les dimensionne.
 */
.champ input:not([type="file"]):not([type="checkbox"]):not([type="radio"]),
.champ select { height:49px; }

/*
 * Chevron des menus déroulants.
 *
 * Celui du navigateur est dessiné par lui, à sa propre distance du bord : il
 * ignore le padding du champ et venait coller la bordure. On le remplace par
 * le chevron du jeu d'icônes, posé en image de fond — une URL « data: », que
 * la CSP autorise (img-src 'self' data: blob:) et qui n'ajoute aucune requête.
 * Il s'aligne ainsi sur la marge intérieure gauche du champ, à .9rem du bord,
 * et le padding de droite réserve sa place pour qu'aucun intitulé ne passe
 * dessous.
 */
.champ select {
  appearance:none; -webkit-appearance:none;
  padding-right:2.5rem;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='24'%20height='24'%20fill='none'%20stroke='%234A5550'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='m6%209%206%206%206-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right .9rem center;
  background-size:16px 16px;
}

.champ input:focus, .champ select:focus, .champ textarea:focus {
  outline:none; border-color:var(--vert-clair);
}
.champ__aide { font-size:.75rem; color:var(--texte-clair); margin-top:.3rem; }

/* Saisie du code 2FA : gros chiffres espacés, clavier numérique sur mobile */
.champ--code input {
  text-align:center; font-family:var(--font-titre); font-weight:800;
  font-size:1.75rem; letter-spacing:.5em; text-indent:.5em; padding:.75rem .5rem;
}

.case-memo {
  display:flex; align-items:center; gap:.6rem; margin:1rem 0 1.25rem;
  font-size:.875rem; color:var(--texte-mid); cursor:pointer;
}
.case-memo input {
  appearance:none; width:20px; height:20px; flex-shrink:0; cursor:pointer;
  border:2px solid var(--vert-sauge); border-radius:var(--r-sm);
  background:#fff; position:relative; transition:all var(--t-rapide);
}
.case-memo input:checked { background:var(--vert-fonce); border-color:var(--vert-fonce); }
.case-memo input:checked::after {
  content:''; position:absolute; left:5px; top:1px; width:5px; height:10px;
  border:solid #fff; border-width:0 2.5px 2.5px 0; transform:rotate(45deg);
}

.alerte {
  display:flex; align-items:flex-start; gap:.6rem;
  padding:.8rem 1rem; border-radius:var(--r-md); margin-bottom:1.25rem;
  font-size:.875rem; line-height:1.45;
}
.alerte--erreur { background:var(--orange-pale); color:#9A3412; }
.alerte--info   { background:var(--vert-pale);   color:var(--vert-fonce); }
.alerte svg { flex-shrink:0; margin-top:1px; }

.auth__lien {
  display:block; text-align:center; margin-top:1.25rem;
  font-size:.8125rem; color:var(--texte-clair);
}
.auth__lien a { color:var(--vert-mid); font-weight:600; }

/* Masque à l'écran sans masquer aux lecteurs d'écran */
/*
 * Utilitaire « lu par les lecteurs d'écran, invisible à l'œil ». Les
 * dimensions portent « !important » parce que des règles plus spécifiques
 * les écrasaient : « .champ input { width:100% } » redonnait 339 px de large
 * au champ de fichier de la fiche projet, qui débordait alors la modale et y
 * provoquait un défilement horizontal — invisible, mais bien présent.
 */
.visuellement-cache {
  position:absolute; width:1px !important; height:1px !important;
  padding:0 !important; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* Pastilles de couleur des tuiles chiffrées */
.pt-devise      { background:var(--col-devis); }
.pt-en_cours    { background:var(--col-todo); }
.pt-a_facturer  { background:var(--col-facturation); }

.carte__compte { margin-left:auto; font-size:.8125rem; color:var(--texte-clair); font-weight:600; }

/* Bandeau d'erreur non bloquant */
.bandeau-erreur {
  position:fixed; left:50%; bottom:calc(1.25rem + env(safe-area-inset-bottom));
  transform:translate(-50%, 150%); z-index:1080;
  max-width:min(90vw, 420px); padding:.8rem 1.25rem;
  background:var(--texte-fonce); color:#fff; border-radius:var(--r-full);
  font-size:.875rem; font-weight:600; box-shadow:var(--ombre-lg);
  transition:transform var(--t-ressort); pointer-events:none;
}
.bandeau-erreur.est-visible { transform:translate(-50%, 0); }
@media (max-width:991.98px) {
  .bandeau-erreur { bottom:calc(var(--nav-bas-h) + 1rem + env(safe-area-inset-bottom)); }
}

/* ─── Glisser-déposer ─────────────────────────────────────────────────────── */
.repere-depot {
  border:2px dashed rgba(255,255,255,.55); border-radius:var(--r-md);
  background:rgba(255,255,255,.1); flex-shrink:0;
}
.taches .repere-depot { border-color:var(--vert-sauge); background:var(--vert-pale); }
body.en-glissement { user-select:none; -webkit-user-select:none; cursor:grabbing; }
body.en-glissement * { cursor:grabbing !important; }
.est-fantome { pointer-events:none; }

/* Saisie rapide d'une nouvelle fiche */
.fiche-saisie {
  font:inherit; font-size:.9375rem; color:var(--texte-fonce);
  border:2px solid var(--vert-clair); resize:none; width:100%;
  font-family:var(--font-texte);
}
.fiche-saisie:focus { outline:none; }
.fiche[hidden] { display:none !important; }

/* =============================================================================
   PROFIL
   ========================================================================== */
.zone--etroite { max-width:720px; }
.zone--etroite .carte { margin-bottom:1.25rem; }

.carte--souligne { border:2px solid var(--jaune); }

.etat {
  margin-left:auto; padding:.25rem .7rem; border-radius:var(--r-full);
  font-size:.75rem; font-weight:700; letter-spacing:.03em;
}
.etat--actif   { background:var(--vert-pale); color:var(--vert-fonce); }
.etat--inactif { background:var(--fond-clair); color:var(--texte-clair); }

.note { color:var(--texte-mid); font-size:.9375rem; margin:0 0 1rem; line-height:1.55; }

.etapes { margin:0 0 1.25rem; padding-left:1.25rem; color:var(--texte-mid); }
.etapes li { margin-bottom:.85rem; line-height:1.55; }
.etapes .note { margin:.3rem 0 0; font-size:.8125rem; }

.cle-totp {
  display:block; margin:.5rem 0 .25rem; padding:.7rem .9rem;
  background:var(--fond-clair); border-radius:var(--r-md);
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size:1.0625rem; font-weight:700; letter-spacing:.08em;
  color:var(--texte-fonce); word-break:break-all; user-select:all;
}

.codes {
  list-style:none; margin:0; padding:0;
  display:grid; grid-template-columns:repeat(auto-fill, minmax(140px, 1fr)); gap:.5rem;
}
.codes li {
  padding:.6rem .8rem; background:var(--fond-clair); border-radius:var(--r-md);
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size:.9375rem; font-weight:700; text-align:center; user-select:all;
}

.ligne-form { display:flex; align-items:flex-end; gap:.75rem; flex-wrap:wrap; }
.ligne-form .champ { margin-bottom:0; flex:1 1 220px; }
.ligne-form .champ--code { flex:0 1 240px; }

/* =============================================================================
   TODO LIST — épinglage et suppression différée
   ========================================================================== */

/* ─── Épingle ─────────────────────────────────────────────────────────────── */
.tache__epingle { opacity:0; transition:opacity var(--t-rapide), color var(--t-rapide); }
.tache:hover .tache__epingle,
.tache:focus-within .tache__epingle { opacity:1; }
/* Une tâche épinglée garde son bouton visible : c'est l'indice de son état. */
.tache.est-epinglee .tache__epingle { opacity:1; color:var(--jaune); }
.tache.est-epinglee .tache__epingle svg { fill:var(--jaune); }
@media (hover:none) { .tache__epingle { opacity:.6; } }

.tache.est-epinglee {
  background:var(--jaune-pale);
  box-shadow:inset 3px 0 0 var(--jaune);
}
.tache.est-epinglee:hover { background:#FDEBC8; }

/* ─── Sursis avant suppression ────────────────────────────────────────────── */
.tache.est-en-sursis { position:relative; background:var(--vert-pale); }

.tache__annuler {
  border:0; background:transparent; cursor:pointer;
  color:var(--vert-fonce); font:inherit; font-size:.8125rem; font-weight:700;
  padding:.25rem .6rem; border-radius:var(--r-full); flex-shrink:0;
  text-decoration:underline; text-underline-offset:2px;
}
.tache__annuler:hover { background:rgba(26,92,58,.1); text-decoration:none; }

/* Barre qui se vide : rend le délai lisible plutôt que de faire disparaître
   la tâche sans prévenir. */
.tache__compte {
  position:absolute; left:0; bottom:0; height:2px;
  background:var(--vert-mid); border-radius:var(--r-full);
  animation:compte-a-rebours linear forwards;
}
@keyframes compte-a-rebours {
  from { width:100%; }
  to   { width:0%; }
}

/* En sursis, l'épingle et la corbeille laissent la place au bouton « Annuler ». */
.tache.est-en-sursis .tache__epingle,
.tache.est-en-sursis .tache__suppr { display:none; }

/* Sortie de la ligne */
.tache.est-partie {
  opacity:0; transform:translateX(24px);
  transition:opacity 200ms ease, transform 200ms ease;
}

@media (prefers-reduced-motion:reduce) {
  .tache__compte { animation:none; width:100%; }
  .tache.est-partie { transition:none; }
}

/* =============================================================================
   PHOTO DE PROFIL
   ========================================================================== */

/* Une photo remplace le fond coloré : plus de couleur ni de lettres dessous. */
.avatar--photo {
  object-fit:cover; background:var(--fond-clair); padding:0;
}
.avatar--xl { width:96px; height:96px; font-size:1.75rem; }

.avatar-lien { display:inline-flex; border-radius:var(--r-full); }
.avatar-lien:hover .avatar { box-shadow:0 0 0 3px var(--vert-pale); }

.photo-bloc { display:flex; gap:1.5rem; align-items:flex-start; flex-wrap:wrap; }
.photo-bloc__actions { flex:1 1 260px; min-width:0; }
.photo-bloc .note { margin-bottom:1rem; }

.photo-form {
  display:flex; align-items:center; gap:.75rem; flex-wrap:wrap;
  margin-bottom:.6rem;
}
/* Le <label> pilote le champ fichier, masqué car impossible à styler. */
.photo-form label.btn { cursor:pointer; margin:0; }

.photo-form__nom {
  font-size:.8125rem; color:var(--texte-mid);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:100%;
}
.photo-form__nom.est-erreur { color:#9A3412; font-weight:600; }

@media (max-width:575.98px) {
  .photo-bloc { gap:1rem; }
  .avatar--xl { width:72px; height:72px; font-size:1.375rem; }
  .photo-form .btn { flex:1 1 auto; justify-content:center; }
}

/*
 * Arrivée des cartes, au seul chargement de la page.
 *
 * La classe est posée par le serveur et retirée par kanban.js une fois
 * l'animation jouée : sans cela, chaque carte déposée après un glisser
 * rejouerait son entrée — elle change de place dans le document, ce qui
 * relance une animation CSS — et le dépôt clignoterait.
 *
 * Le décalage s'échelonne sur les huit premières cartes d'une colonne, puis
 * s'arrête : au-delà, l'effet ne se perçoit plus et ne fait qu'attendre.
 */
.kanban.est-neuf .fiche { animation:carte-arrive 260ms ease both; }
@keyframes carte-arrive {
  from { opacity:0; transform:translateY(6px); }
}
.kanban.est-neuf .fiche:nth-child(1) { animation-delay:0ms; }
.kanban.est-neuf .fiche:nth-child(2) { animation-delay:25ms; }
.kanban.est-neuf .fiche:nth-child(3) { animation-delay:50ms; }
.kanban.est-neuf .fiche:nth-child(4) { animation-delay:75ms; }
.kanban.est-neuf .fiche:nth-child(5) { animation-delay:100ms; }
.kanban.est-neuf .fiche:nth-child(6) { animation-delay:125ms; }
.kanban.est-neuf .fiche:nth-child(7) { animation-delay:150ms; }
.kanban.est-neuf .fiche:nth-child(n+8) { animation-delay:175ms; }

/* =============================================================================
   BARRE LATÉRALE REPLIABLE
   ========================================================================== */
.barre__haut {
  display:flex; align-items:center; gap:.25rem;
  padding-bottom:1.5rem;
}
.barre__logo img { transition:opacity var(--t-rapide); }

.barre__replier {
  display:inline-flex; align-items:center; justify-content:center;
  width:34px; height:34px; flex-shrink:0; margin-left:auto;
  border:0; border-radius:var(--r-md); cursor:pointer;
  background:rgba(255,255,255,.08); color:rgba(255,255,255,.75);
  transition:background var(--t-rapide), color var(--t-rapide);
}
.barre__replier:hover { background:rgba(255,255,255,.18); color:#fff; }
.barre__deplier-icone { display:none; }

/* ─── État replié (grand écran uniquement) ────────────────────────────────── */
@media (min-width:992px) {
  html.barre-repliee .barre { width:var(--barre-l-repliee); padding-left:.6rem; padding-right:.6rem; }
  html.barre-repliee .principal { margin-left:var(--barre-l-repliee); }

  /* Le logo disparaît, le bouton prend toute la largeur et se centre. */
  html.barre-repliee .barre__logo { display:none; }
  html.barre-repliee .barre__haut { justify-content:center; padding-bottom:1rem; }
  html.barre-repliee .barre__replier { margin:0 auto; }
  html.barre-repliee .barre__replier-icone { display:none; }
  html.barre-repliee .barre__deplier-icone { display:inline-flex; }

  /* Icônes seules, centrées, la zone cliquable reste pleine largeur. */
  html.barre-repliee .nav-lien { justify-content:center; padding-left:0; padding-right:0; }
  html.barre-repliee .nav-lien__texte { display:none; }
  html.barre-repliee .nav-lien__pastille {
    position:absolute; top:.3rem; right:.3rem; margin:0;
    min-width:18px; height:18px; font-size:.625rem;
  }
  html.barre-repliee .nav-lien { position:relative; }
  html.barre-repliee button.nav-lien { text-align:center; }
}

/* La barre garde sa largeur pleine quand elle s'ouvre en superposition mobile. */
@media (max-width:991.98px) {
  .barre { width:var(--barre-l); }
  .barre__replier { display:none; }
}

/* Transition douce, sauf pour qui préfère le mouvement réduit. */
.barre { transition:width var(--t-base), transform var(--t-base); }
.principal { transition:margin-left var(--t-base); }

/* =============================================================================
   EN-TÊTE PORTANT LES OUTILS (page Projets)
   ========================================================================== */
.entete--outils {
  align-items:center; gap:1rem; flex-wrap:wrap;
  padding:1.25rem 2.5rem;
  background:var(--fond-blanc);
  border-bottom:1px solid rgba(0,0,0,.06);
}
.entete--outils .entete__salut { font-size:1.5rem; }
.entete--outils .entete__date { margin-top:.1rem; font-size:.8125rem; }

.entete__titre { display:flex; align-items:center; gap:.6rem; flex-shrink:0; }
/* Accueil : le salut et la date, plus longs qu'un titre d'outil, peuvent se resserrer. */
.entete:not(.entete--outils) > .entete__titre { flex-shrink:1; min-width:0; }

/* flex:1 1 auto plutôt qu'un margin-left:auto : le bloc reçoit l'espace
   disponible au lieu d'être réduit à sa largeur de contenu, ce qui faisait
   passer « Mes projets » à la ligne dès 1280 px. */
.entete__outils {
  display:flex; align-items:center; justify-content:flex-end;
  gap:.6rem; flex-wrap:wrap;
  flex:1 1 auto; min-width:0;
}
.entete__outils .recherche { flex:0 1 300px; min-width:170px; }
/*
 * L'avatar tient le bord droit, avec ou sans bloc d'outils.
 *
 * Il y était poussé par « .entete__outils { flex:1 1 auto } », qui absorbe
 * l'espace libre. Mais ce bloc n'existe pas partout — ni sur Envois, ni sur
 * l'onglet « Nouvelle offre » — et l'avatar se retrouvait alors collé au
 * titre. La marge automatique le cale dans tous les cas : là où les outils
 * sont présents, ils ont déjà pris la place et elle ne change rien.
 */
.entete__moi { flex-shrink:0; margin-left:auto; }

@media (max-width:1199.98px) {
  /* Les outils passent sous le titre plutôt que de comprimer la recherche. */
  .entete__outils { order:3; flex-basis:100%; }
}
@media (max-width:991.98px) {
  .entete--outils { padding:1rem 1.25rem; }
  /*
   * Le titre prend la place restante au lieu de celle de son sous-titre : un
   * sous-titre long (« Envoi de devis et signature électronique ») le rendait
   * assez large pour repousser l'avatar sur une seconde ligne. Il passe à la
   * ligne dans le titre, et l'avatar reste au bord droit comme ailleurs.
   */
  .entete--outils > .entete__titre { flex:1 1 0; min-width:0; }
  .entete__outils .recherche { flex:1 1 100%; }
}

/* =============================================================================
   ICÔNE D'EN-TÊTE DE COLONNE
   ========================================================================== */
.colonne__icone {
  display:inline-flex; align-items:center; justify-content:center;
  flex-shrink:0; color:#fff;
}

/* =============================================================================
   CARNET D'ADRESSES — onglets, tableau, modales
   ========================================================================== */

/* ─── Onglets Entreprises / Contacts ──────────────────────────────────────── */
.onglets {
  display:inline-flex; gap:.25rem; margin-bottom:1.25rem;
  padding:.3rem; border-radius:var(--r-full); background:rgba(0,0,0,.05);
}
.onglet {
  display:inline-flex; align-items:center; gap:.45rem;
  padding:.5rem 1.1rem; border-radius:var(--r-full);
  font-size:.875rem; font-weight:600; color:var(--texte-mid);
  transition:background var(--t-rapide), color var(--t-rapide);
}
.onglet:hover { color:var(--texte-fonce); }
.onglet.est-actif {
  background:var(--fond-blanc); color:var(--vert-fonce);
  box-shadow:var(--ombre-sm);
}

/* ─── Tableau ─────────────────────────────────────────────────────────────── */
.tableau-boite { overflow-x:auto; }
.tableau { width:100%; border-collapse:collapse; font-size:.9375rem; }

.tableau thead th {
  text-align:left; padding:.85rem 1.25rem;
  font-size:.75rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  color:var(--texte-clair); white-space:nowrap;
  border-bottom:1px solid rgba(0,0,0,.08);
}
.tableau tbody td,
.tableau tbody th {
  padding:.85rem 1.25rem; text-align:left; font-weight:400;
  border-bottom:1px solid rgba(0,0,0,.05); vertical-align:middle;
}
.tableau tbody tr:last-child td,
.tableau tbody tr:last-child th { border-bottom:0; }
.tableau tbody tr { transition:background var(--t-rapide); }
.tableau tbody tr:hover { background:var(--fond-clair); }

.cellule-titre { font-weight:600; color:var(--texte-fonce); }
.cellule-mono {
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size:.875rem; white-space:nowrap;
}
.col-nombre { text-align:right; width:1%; white-space:nowrap; }
.tableau thead th.col-nombre { text-align:right; }
.col-actions { width:1%; white-space:nowrap; text-align:right; }
.col-actions .icone-btn { opacity:.4; transition:opacity var(--t-rapide), color var(--t-rapide); }
.tableau tbody tr:hover .col-actions .icone-btn,
.tableau tbody tr:focus-within .col-actions .icone-btn { opacity:1; }
@media (hover:none) { .col-actions .icone-btn { opacity:.75; } }

.icone-btn--danger:hover { background:var(--orange-pale); color:#9A3412; }

/* Sur téléphone, chaque ligne devient une fiche lisible sans défilement latéral. */
@media (max-width:767.98px) {
  .tableau, .tableau tbody, .tableau tr, .tableau td, .tableau th { display:block; }
  .tableau thead { display:none; }
  .tableau tbody tr {
    padding:.9rem 1.1rem; border-bottom:1px solid rgba(0,0,0,.07); position:relative;
  }
  .tableau tbody td, .tableau tbody th { padding:.15rem 0; border:0; }
  .tableau tbody .cellule-titre { font-size:1rem; padding-right:5rem; }
  /* Le libellé de colonne réapparaît devant la valeur */
  .tableau tbody td[data-libelle]::before {
    content:attr(data-libelle) ' : ';
    color:var(--texte-clair); font-size:.8125rem;
  }
  .col-nombre, .tableau thead th.col-nombre { text-align:left; }
  .col-actions { position:absolute; top:.7rem; right:.8rem; width:auto; }
}

/* ─── Modales (élément <dialog> natif) ────────────────────────────────────── */
/*
 * Ouverture ET fermeture en fondu, sans une ligne de JavaScript.
 *
 * Un <dialog> passe de display:none à sa couche supérieure d'un seul coup :
 * sans précaution, il n'y a rien à animer. Trois mécanismes y pourvoient —
 * @starting-style donne l'état d'où partir à l'ouverture, et les transitions
 * « allow-discrete » sur display et overlay retiennent l'élément le temps que
 * le fondu de sortie se joue. Les navigateurs qui les ignorent gardent la
 * première déclaration `transition`, plus courte : la modale paraît et
 * disparaît sèchement, comme avant, mais rien ne casse.
 *
 * L'entrée prend son temps avec un léger ressort ; la sortie est plus brève
 * et sans rebond — on ne fait pas patienter quelqu'un qui ferme une fenêtre.
 */
.modale {
  width:min(92vw, 520px); padding:0; border:0;
  border-radius:var(--r-lg); box-shadow:var(--ombre-xl, var(--ombre-lg));
  background:var(--fond-blanc); color:var(--texte-fonce);

  opacity:0; transform:translateY(8px) scale(.98);
  transition:opacity 140ms ease, transform 140ms ease;
  transition:opacity 140ms ease, transform 140ms ease,
             overlay 140ms ease allow-discrete, display 140ms ease allow-discrete;
}
.modale[open] {
  opacity:1; transform:none;
  transition:opacity 200ms var(--e-modale), transform 200ms var(--e-modale);
  transition:opacity 200ms var(--e-modale), transform 200ms var(--e-modale),
             overlay 200ms allow-discrete, display 200ms allow-discrete;
}
@starting-style {
  .modale[open] { opacity:0; transform:translateY(8px) scale(.98); }
}

.modale--etroite { width:min(92vw, 420px); }

/* Le voile ne tombait pas en fondu : il apparaissait d'un bloc, flou compris,
   ce qui est le geste le plus brutal de l'ouverture. Il suit désormais la
   modale. (::backdrop n'hérite de rien : tout se redéclare ici.) */
.modale::backdrop {
  background:rgba(15,46,30,.55); backdrop-filter:blur(2px);
  opacity:0;
  transition:opacity 140ms ease;
  transition:opacity 140ms ease,
             overlay 140ms ease allow-discrete, display 140ms ease allow-discrete;
}
.modale[open]::backdrop {
  opacity:1;
  transition:opacity 200ms ease;
  transition:opacity 200ms ease,
             overlay 200ms allow-discrete, display 200ms allow-discrete;
}
@starting-style {
  .modale[open]::backdrop { opacity:0; }
}

/* Visionneuse de pièce jointe : plein cadre sombre, pas de chrome de modale
   habituel — l'image, la vidéo ou le PDF doit occuper tout l'espace. */
.modale--apercu {
  width:min(96vw, 1200px); height:min(92vh, 860px);
  background:var(--fond-nuit); position:relative;
}
.modale-apercu__fermer {
  position:absolute; top:.75rem; right:.75rem; z-index:1;
  background:rgba(255,255,255,.12); color:#fff;
}
.modale-apercu__fermer:hover { background:rgba(255,255,255,.22); color:#fff; }
.modale-apercu__corps {
  width:100%; height:100%;
  display:flex; align-items:center; justify-content:center; overflow:hidden;
}
.modale-apercu__corps img,
.modale-apercu__corps video {
  max-width:100%; max-height:100%; object-fit:contain;
}
.modale-apercu__corps iframe { width:100%; height:100%; border:0; background:#fff; }

.modale__tete {
  display:flex; align-items:center; gap:1rem;
  padding:1.35rem 1.5rem .75rem;
}
.modale__titre { font-size:1.125rem; }
.modale__tete .icone-btn { margin-left:auto; }

.modale__corps { padding:.5rem 1.5rem 1rem; max-height:65vh; overflow-y:auto; }

.modale__pied {
  display:flex; justify-content:flex-end; gap:.6rem;
  padding:1rem 1.5rem 1.35rem; border-top:1px solid rgba(0,0,0,.06);
}

.champ-duo { display:grid; grid-template-columns:1fr 1fr; gap:.75rem; }
@media (max-width:479.98px) { .champ-duo { grid-template-columns:1fr; } }

/*
 * Sur un écran étroit, les quatre boutons de la fiche ne tiennent pas côte à
 * côte en toutes lettres. Ils passaient donc sur deux lignes — un pied de
 * 133 px qui débordait du bas de la fenêtre, avec des alignements opposés.
 *
 * « Supprimer » et « Archiver » gardent leur seule icône : leur libellé reste
 * lu par les lecteurs d'écran (voir .visuellement-cache) et s'affiche au
 * survol. Tout revient ainsi sur une ligne.
 */
@media (max-width:479.98px) {
  .modale__pied { flex-wrap:wrap; row-gap:.6rem; padding-left:1rem; padding-right:1rem; }

  .fiche-pied__mot {
    position:absolute; width:1px; height:1px; padding:0; margin:-1px;
    overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
  }
  /* Sans libellé, le bouton doit rester une cible tactile confortable. */
  .fiche-pied #supprimerFiche, .fiche-pied #archiverFiche {
    padding:.6rem; min-width:44px;
  }
  /*
   * Le vrai coupable du repli : le témoin « Enregistré », même vide, porte
   * une marge gauche automatique qui absorbait 198 px pour pousser les
   * actions à droite — ne leur laissant plus la place sur la ligne. C'est
   * au dernier bloc de se coller à droite : lui n'a personne à repousser.
   * Sélecteur redoublé, sinon la règle d'origine l'emporte par son rang.
   */
  /*
   * Sorti du flux : même vide il consommait un espacement, et il ne
   * restait alors plus qu'un pixel — insuffisant pour tenir la ligne.
   * En absolu, il ne pousse plus rien, et l'apparition de « Enregistré »
   * ne fait plus sauter la mise en page.
   */
  .fiche-pied { position:relative; padding-top:1.9rem; }
  /* Le retrait haut ci-dessus lui réserve sa bande : sans elle, le message
     mordait de trois pixels sur le haut des boutons. */
  .fiche-pied .fiche-pied__etat {
    position:absolute; left:1rem; top:.35rem; margin:0;
  }
  .fiche-pied .fiche-pied__actions { margin-left:auto; }

  .fiche-pied { gap:.4rem; }
  .fiche-pied__actions { gap:.4rem; }
  .fiche-pied__actions .btn { padding-left:.9rem; padding-right:.9rem; }
}

.oblig { color:var(--orange); margin-left:.15rem; }

.champ__erreur {
  margin:.3rem 0 0; font-size:.8125rem; font-weight:600; color:#9A3412;
  display:none;
}
.champ__erreur.est-visible { display:block; }
.champ input.est-fautif, .champ select.est-fautif { border-color:var(--orange); }

.btn--danger {
  background:var(--orange); color:#fff; border-color:var(--orange);
}
.btn--danger:hover {
  background:#C9501F; border-color:#C9501F; color:#fff; transform:translateY(-2px);
}

/* Mouvement réduit : la modale paraît et disparaît sans transition. */
@media (prefers-reduced-motion:reduce) {
  .modale, .modale[open], .modale::backdrop, .modale[open]::backdrop { transition:none; }
  .modale { transform:none; }
}

/* =============================================================================
   RECHERCHE DANS LE RÉPERTOIRE OFFICIEL DES ENTREPRISES
   ========================================================================== */
.champ--sirene { position:relative; margin-bottom:.75rem; }

.sirene-boite { position:relative; display:flex; align-items:center; }
.sirene-boite svg {
  position:absolute; left:.85rem; color:var(--texte-clair); pointer-events:none;
}
.sirene-boite input {
  width:100%; padding:.7rem 4.5rem .7rem 2.5rem; font:inherit; font-size:.9375rem;
  border:2px solid var(--vert-sauge); border-radius:var(--r-md);
  background:var(--vert-pale); color:var(--texte-fonce);
  transition:border-color var(--t-rapide), background var(--t-rapide);
}
.sirene-boite input:focus {
  outline:none; border-color:var(--vert-mid); background:#fff;
}
.sirene-boite input::placeholder { color:var(--texte-clair); }

.sirene-etat {
  position:absolute; right:.85rem; font-size:.75rem; color:var(--texte-clair);
  pointer-events:none; white-space:nowrap;
}

.sirene-liste {
  list-style:none; margin:.35rem 0 0; padding:.3rem;
  position:absolute; left:0; right:0; z-index:5;
  max-height:260px; overflow-y:auto;
  background:var(--fond-blanc); border-radius:var(--r-md);
  box-shadow:var(--ombre-lg); border:1px solid rgba(0,0,0,.08);
}
.sirene-item {
  display:flex; flex-direction:column; gap:.1rem;
  padding:.55rem .7rem; border-radius:var(--r-sm); cursor:pointer;
}
.sirene-item:hover, .sirene-item.est-actif { background:var(--vert-pale); }
.sirene-item__nom { font-weight:600; font-size:.9375rem; line-height:1.25; }
.sirene-item__meta { font-size:.75rem; color:var(--texte-clair); }

.separateur {
  border:0; border-top:1px solid rgba(0,0,0,.08);
  margin:.25rem 0 1rem;
}

.champ-duo--cp { grid-template-columns:.55fr 1fr; }
@media (max-width:479.98px) { .champ-duo--cp { grid-template-columns:1fr; } }

/* =============================================================================
   FICHE PROJET
   ========================================================================== */
.modale--fiche { width:min(94vw, 900px); }

.fiche-tete {
  display:flex; align-items:flex-start; gap:.75rem;
  padding:1.25rem 1.5rem .5rem;
}
.fiche-tete__titre {
  flex:1; min-width:0; border:0; background:transparent; padding:.25rem .35rem;
  font-family:var(--font-titre); font-size:1.375rem; font-weight:800;
  letter-spacing:-.02em; color:var(--texte-fonce);
  border-radius:var(--r-sm);
}
.fiche-tete__titre:hover { background:var(--fond-clair); }
/*
 * Sur mobile, le titre reste sur la ligne des boutons d'action (partage,
 * fermeture) : on resserre ceux-ci pour lui laisser le plus de place, et un
 * titre trop long se termine par « … » plutôt que d'être rogné net.
 */
.fiche-tete { align-items:center; }
.fiche-tete__titre { text-overflow:ellipsis; }
@media (max-width:575.98px) {
  .fiche-tete { gap:.25rem; padding-inline:1rem; }
  .fiche-tete__titre { font-size:1.0625rem; }
}
.fiche-tete__titre:focus { outline:none; background:var(--fond-clair); box-shadow:inset 0 -2px 0 var(--vert-clair); }
.fiche-tete__titre::placeholder { color:var(--texte-clair); font-weight:700; }

.fiche-corps {
  display:grid; grid-template-columns:1fr 260px; gap:1.5rem;
  padding:.5rem 1.5rem 1rem; max-height:64vh; overflow-y:auto;
}
.fiche-principale { min-width:0; }
.fiche-cote { min-width:0; }
.fiche-cote .champ { margin-bottom:1rem; }

@media (max-width:767.98px) {
  /*
   * La modale se contraint, et le contenu prend ce qui reste entre la tête
   * et le pied. Auparavant c'était le corps qui portait un plafond en
   * pourcentage d'écran, calculé sans rien savoir des deux autres : dès que
   * le pied grandissait, l'ensemble débordait du bas de la fenêtre.
   */
  .modale--fiche { max-height:92dvh; }
  /*
   * Un seul défilement : celui du corps. Un <dialog> défile de lui-même par
   * défaut, et le navigateur s'en sert pour amener un champ au-dessus du
   * clavier — la fiche glissait alors dans sa propre fenêtre, en plus du
   * défilement du corps. « clip » (et non « hidden ») interdit aussi ce
   * défilement commandé par le navigateur.
   */
  .modale--fiche { overflow:clip; }
  /*
   * Conditionné à [open] : le navigateur masque un <dialog> fermé par un
   * « display:none » que tout display déclaré ici écraserait. Sans cette
   * garde, la fiche restait affichée après fermeture — un grand cadre vide
   * superposé au tableau.
   */
  .modale--fiche[open] { display:flex; flex-direction:column; }
  .modale--fiche[open] .modale__forme { display:flex; flex-direction:column; min-height:0; }
  .fiche-corps { grid-template-columns:1fr; gap:1rem; max-height:none; flex:1; min-height:0;
                 overscroll-behavior:contain; }
  /* Les métadonnées passent avant la description : sur téléphone on consulte
     plus souvent l'échéance et l'étiquette que le brief complet. */
  .fiche-cote { order:-1; }
}

/* Ne garde que ce qui lui est propre : la valeur qui accompagne le titre. */
.fiche-sous-titre { display:flex; align-items:baseline; gap:.5rem; }
.fiche-sous-titre__compte { font-weight:400; color:var(--texte-clair); font-size:.75rem; }

/*
 * Blocs repliables de la fiche : pièces jointes, frais, checklist, temps passé.
 * Le chevron ferme le bloc par la droite de l'en-tête, sur la même ligne que
 * le titre et son compteur. Sa rotation porte seule l'état : pas de second
 * dessin à charger pour le sens inverse.
 *
 * Chacun s'ouvre de lui-même quand il a quelque chose à montrer, et reste
 * replié sinon — voir reglerReplis() dans fiche.js. Une fiche sans frais ni
 * pièce jointe tient ainsi sur un écran, au lieu d'empiler quatre blocs vides.
 */
/* Tout l'en-tête bascule le bloc : le curseur l'annonce, et la sélection de
   texte est neutralisée pour qu'un double-clic ne surligne pas le titre. */
.repliable > .fiche-sous-titre { cursor:pointer; user-select:none; }
/* Les commandes de l'en-tête gardent la leur — « Tout télécharger ». */
.repliable > .fiche-sous-titre a { cursor:pointer; }

.repliable__replier { margin-left:auto; }
.repliable__replier svg { transition:transform var(--t-rapide); }
.repliable.est-replie .repliable__replier svg { transform:rotate(-90deg); }
.repliable.est-replie .repliable__corps { display:none; }

/*
 * Le dépli se fait en fondu, le repli reste net.
 *
 * On ne peut pas animer un passage à display:none sans artifices ; on ne gagne
 * d'ailleurs rien à faire patienter qui vient de fermer un bloc. L'ouverture,
 * elle, mérite d'être accompagnée : c'est là que le regard doit retrouver
 * quelque chose qui n'était pas là. Le décalage est de quatre pixels, assez
 * pour suggérer le mouvement, trop peu pour qu'on l'attende.
 */
.repliable:not(.est-replie) .repliable__corps { animation:bloc-ouvre 200ms ease; }
@keyframes bloc-ouvre {
  from { opacity:0; transform:translateY(-4px); }
}

.fiche-pied { justify-content:flex-start; align-items:center; }
.fiche-pied__actions { display:flex; gap:.6rem; }
.fiche-pied__etat {
  margin-left:auto; margin-right:.5rem;
  font-size:.8125rem; color:var(--texte-clair); font-weight:600;
}
#supprimerFiche:hover { background:var(--orange-pale); color:#9A3412; }

/* ─── Champ avec unité ou action ──────────────────────────────────────────── */
.champ-unite, .champ-lien, .champ-action { position:relative; display:flex; align-items:center; }
.champ-unite input { padding-right:2.2rem; }
.champ-unite__suffixe {
  position:absolute; right:.85rem; color:var(--texte-clair);
  font-weight:600; pointer-events:none;
}
/* « € HT » est bien plus large qu'un simple « € » : sans cette marge propre,
   il chevauchait les derniers chiffres saisis dans ce champ plus étroit. */
.frais-forme__montant input { padding-right:3.4rem; }
.frais-forme__montant .champ-unite__suffixe { font-size:.8125rem; }
.champ-lien input, .champ-action input { flex:1; min-width:0; }
.champ-lien .icone-btn, .champ-action .icone-btn { flex-shrink:0; margin-left:.35rem; }

/* ─── Éditeur Markdown ────────────────────────────────────────────────────── */
.editeur { border:2px solid #E3E3DD; border-radius:var(--r-md); overflow:hidden; }
.editeur:focus-within { border-color:var(--vert-clair); }

.editeur__barre {
  display:flex; align-items:center; gap:.15rem; flex-wrap:wrap;
  padding:.3rem .35rem; background:var(--fond-clair);
  border-bottom:1px solid rgba(0,0,0,.06);
}
.editeur__barre button {
  display:inline-flex; align-items:center; justify-content:center;
  min-width:30px; height:30px; padding:0 .45rem;
  border:0; border-radius:var(--r-sm); background:transparent;
  color:var(--texte-mid); cursor:pointer; font-size:.875rem;
  transition:background var(--t-rapide);
}
.editeur__barre button:hover { background:rgba(0,0,0,.07); color:var(--texte-fonce); }
.editeur__separateur { flex:1; }
.editeur__apercu { font-size:.75rem !important; font-weight:700; }
.editeur__apercu[aria-pressed="true"] { background:var(--vert-pale); color:var(--vert-fonce); }

.editeur textarea {
  width:100%; border:0; padding:.75rem .9rem; font:inherit; font-size:.9375rem;
  line-height:1.6; resize:vertical; min-height:150px; display:block;
}
.editeur textarea:focus { outline:none; }
.editeur textarea::placeholder { color:var(--texte-clair); }

.editeur__rendu {
  padding:.75rem .9rem; min-height:150px; font-size:.9375rem; line-height:1.6;
}
.md-apercu-attente { color:var(--texte-clair); font-size:.875rem; }

/* ─── Rendu du Markdown ───────────────────────────────────────────────────── */
.editeur__rendu p { margin:0 0 .7rem; }
.editeur__rendu > :last-child { margin-bottom:0; }
.md-titre { font-size:1rem; margin:1rem 0 .4rem; }
.md-titre:first-child { margin-top:0; }
.md-liste { margin:0 0 .7rem; padding-left:1.35rem; }
.md-liste li { margin-bottom:.2rem; }
/*
 * Le retrait d'une liste de cases se compte deux fois si l'on n'y prend garde.
 * La liste perd déjà son retrait de puces, et chaque case était en plus tirée
 * d'un cran vers la gauche : les cases sortaient de la colonne de texte et
 * venaient frôler la bordure du cadre.
 *
 * Une liste entièrement composée de cases s'aligne donc simplement sur le
 * texte courant. Le décalage ne sert que dans une liste mêlant puces et
 * cases, où la case prend la place de la puce qu'elle remplace.
 */
.md-liste--taches { list-style:none; padding-left:0; }
.md-liste--taches > .md-tache { margin-left:0; }
.md-liste:not(.md-liste--taches) > .md-tache { margin-left:-1.2rem; }

.md-tache { list-style:none; display:flex; align-items:flex-start; gap:.45rem; }
.md-tache.est-faite { color:var(--texte-clair); text-decoration:line-through; }
/* Centrée sur la première ligne : (24 px d'interligne − 14 px de case) / 2. */
.md-tache input {
  margin:5px 0 0; flex-shrink:0; width:14px; height:14px; accent-color:var(--vert-mid);
}
.md-cite {
  margin:0 0 .7rem; padding:.4rem .85rem;
  border-left:3px solid var(--vert-sauge); background:var(--fond-clair);
  color:var(--texte-mid); border-radius:0 var(--r-sm) var(--r-sm) 0;
}
.md-code {
  background:var(--fond-clair); padding:.1rem .35rem; border-radius:var(--r-sm);
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace; font-size:.875em;
}
.md-bloc {
  background:var(--fond-nuit); color:#E8F0EA; padding:.75rem .9rem;
  border-radius:var(--r-md); overflow-x:auto; margin:0 0 .7rem;
}
.md-bloc code { font-family:ui-monospace, SFMono-Regular, Menlo, monospace; font-size:.8125rem; }
.md-hr { border:0; border-top:1px solid rgba(0,0,0,.1); margin:1rem 0; }

/* ─── Étiquettes ──────────────────────────────────────────────────────────── */
.etiq {
  --teinte-etiq:var(--col-attente);
  display:inline-flex; align-items:center; gap:.3rem;
  padding:.25rem .5rem; border:0; border-radius:var(--r-sm);
  background:var(--teinte-etiq); color:#fff; cursor:pointer;
  font-size:.75rem; font-weight:700; line-height:1;
  transition:opacity var(--t-rapide), transform var(--t-rapide);
}
.etiq__emoji { font-size:.9375rem; line-height:1; }
.etiq__texte { letter-spacing:.03em; }

.etiq-choix { display:flex; flex-wrap:wrap; gap:.35rem; }
.etiq-choix .etiq { opacity:.32; }
.etiq-choix .etiq:hover { opacity:.7; }
.etiq-choix .etiq.est-choisie { opacity:1; transform:scale(1.04); }

/* Sur les cartes, l'étiquette n'est pas cliquable */
.etiq--carte { cursor:default; padding:.2rem .45rem; }

/* Étiquettes posées, rappelées dans l'en-tête du bloc replié. Le compteur
   habituel ne conviendrait pas : c'est la couleur qu'on cherche du regard,
   pas un nombre. */
.etiq-resume { display:inline-flex; flex-wrap:wrap; gap:.25rem; }
.etiq-resume:empty { display:none; }
.etiq-resume .etiq { pointer-events:none; }
/* Déplié, le sélecteur montre déjà les étiquettes posées, en évidence parmi
   les autres : le rappel de l'en-tête ferait doublon deux lignes plus haut. */
.repliable:not(.est-replie) .etiq-resume { display:none; }

.jeton--pj { background:var(--fond-clair); color:var(--texte-mid); }

/* ─── Pièces jointes ──────────────────────────────────────────────────────── */
.pj-grille {
  display:grid; gap:.6rem;
  grid-template-columns:repeat(auto-fill, minmax(110px, 1fr));
}

.pj { position:relative; min-width:0; }
.pj__apercu {
  display:flex; align-items:center; justify-content:center;
  aspect-ratio:4 / 3; border-radius:var(--r-md); overflow:hidden;
  background:var(--fond-clair); border:1px solid rgba(0,0,0,.07);
  transition:border-color var(--t-rapide), transform var(--t-rapide);
}
.pj__apercu:hover { border-color:var(--vert-clair); transform:translateY(-2px); }
.pj__apercu img { width:100%; height:100%; object-fit:cover; display:block; }

.pj__type {
  font-family:var(--font-titre); font-weight:800; font-size:.8125rem;
  letter-spacing:.04em; color:#fff; padding:.3rem .5rem; border-radius:var(--r-sm);
  background:var(--texte-clair);
}
.pj__type--pdf      { background:#D93025; }
.pj__type--tableur  { background:#1E8E3E; }
.pj__type--document { background:#1A73E8; }
.pj__type--video    { background:#7C3AED; }
.pj__type--audio    { background:#F5A623; }
.pj__type--archive  { background:#5F6368; }

.pj__nom {
  display:block; margin-top:.3rem; font-size:.75rem; font-weight:600;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.pj__poids { display:block; font-size:.6875rem; color:var(--texte-clair); }

.pj__suppr, .pj__telecharger {
  position:absolute; top:-6px; width:22px; height:22px;
  border:0; border-radius:var(--r-full); cursor:pointer;
  background:var(--texte-fonce); color:#fff;
  opacity:0; transition:opacity var(--t-rapide);
  display:flex; align-items:center; justify-content:center;
  padding:0;
}
/*
 * Les deux icônes sont des SVG clonés depuis un bouton source de taille
 * différente (fermeture de fiche : 20px : téléchargement groupé : 14px).
 * Sans cette règle elles hériteraient de cette taille d'origine et
 * déborderaient de la pastille de 22px, ou la rempliraient inégalement.
 */
.pj__suppr svg, .pj__telecharger svg { width:12px; height:12px; display:block; }
.pj__suppr { right:-6px; }
/* À l'opposé de la suppression : les deux gestes ne se confondent pas. */
.pj__telecharger {
  left:-6px;
  background:var(--vert-fonce);
}
.pj__telecharger:hover { background:var(--vert-clair); }
.pj__suppr:hover { background:var(--orange); }
.pj:hover .pj__suppr, .pj:focus-within .pj__suppr,
.pj:hover .pj__telecharger, .pj:focus-within .pj__telecharger { opacity:1; }
@media (hover:none) {
  /*
   * Toujours visibles faute de survol : on les rentre dans la vignette.
   * À cheval sur le bord, l'icône de gauche d'une tuile venait toucher la
   * croix de sa voisine, et l'on ne savait plus à laquelle elle appartenait.
   */
  .pj__suppr, .pj__telecharger { opacity:.9; top:4px; }
  .pj__suppr { right:4px; }
  .pj__telecharger { left:4px; }
}

/* Bouton « Tout télécharger », dans l'en-tête des pièces jointes. */
.pj-tout {
  display:inline-flex; align-items:center; gap:.3rem; margin-left:auto;
  font-size:.75rem; font-weight:600; color:var(--vert-fonce);
}
.pj-tout:hover { text-decoration:underline; }
.pj-tout[hidden] { display:none; }

.pj--attente {
  display:flex; align-items:center; justify-content:center;
  aspect-ratio:4 / 3; border-radius:var(--r-md);
  background:var(--vert-pale); color:var(--vert-fonce);
  font-size:.6875rem; font-weight:600; padding:.4rem; text-align:center;
  overflow:hidden; animation:pulse 1.2s ease-in-out infinite;
}
@keyframes pulse { 0%,100% { opacity:1; } 50% { opacity:.55; } }
.pj.est-partie { opacity:.35; pointer-events:none; }

/* ─── Zone de dépôt ───────────────────────────────────────────────────────── */
/*
 * Elle occupe une cellule de la grille des pièces jointes, en dernière
 * position. Seule — fiche sans pièce jointe — elle s'étale sur toute la
 * largeur et invite d'une phrase entière. Dès qu'elle suit des vignettes,
 * elle en prend le format : même proportion, même arrondi, alignée sur le
 * haut de la rangée, puisque les vignettes voisines portent sous elles un
 * nom et un poids qui les font plus hautes.
 */
.pj-grille .pj-depot { grid-column:1 / -1; }

/*
 * La proportion est portée par la cellule, et le cadre la remplit entièrement
 * (height:100%). Posée sur le cadre lui-même, elle entrait en concurrence avec
 * la hauteur naturelle de son contenu : selon la largeur de colonne, le cadre
 * pouvait grandir sans que l'icône et le texte suivent, et le groupe se
 * retrouvait haut perché. Ici la hauteur est franche, et le centrage avec.
 */
.pj-grille.a-des-fichiers .pj-depot { grid-column:auto; align-self:start; aspect-ratio:4 / 3; }
.pj-grille.a-des-fichiers .pj-depot__zone {
  height:100%; padding:.5rem; gap:.15rem; font-size:.75rem; line-height:1.3;
}
/* À la taille d'une vignette, la phrase entière ne tient plus : le dépôt par
   glisser reste possible, il n'a simplement plus à être annoncé — la bordure
   en pointillés le dit déjà. */
.pj-grille.a-des-fichiers .pj-depot__suite { display:none; }
.pj-grille.a-des-fichiers .pj-depot__principal { flex-direction:column; gap:.25rem; }

/*
 * Préfixé par .pj-grille, et ce n'est pas décoratif.
 *
 * La zone de dépôt est un <label>, et le bloc des pièces jointes porte la
 * classe « champ ». La règle « .champ label », plus spécifique que
 * « .pj-depot__zone » seul, l'emportait donc et lui imposait display:block :
 * le flex ne s'appliquait pas, justify-content:center non plus, et l'icône
 * comme le texte restaient en haut du cadre. D'où le préfixe, qui rend la main
 * à cette règle — et la remise à zéro de ce que « .champ label » impose par
 * ailleurs (graisse, marge basse), destiné aux intitulés de champ, pas à ceci.
 */
.pj-grille .pj-depot__zone {
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:.25rem; padding:1.1rem; cursor:pointer; text-align:center;
  border:2px dashed rgba(0,0,0,.14); border-radius:var(--r-md);
  color:var(--texte-mid); font-size:.875rem; font-weight:400;
  letter-spacing:normal; margin-bottom:0;
  transition:border-color var(--t-rapide), background var(--t-rapide);
}
/* Icône et texte forment un même groupe centré : un flex en ligne les aligne
   sur leur milieu, plutôt que sur la ligne de base par défaut du navigateur
   qui décalait le « + » vers le bas. */
.pj-depot__principal { display:inline-flex; align-items:center; gap:.4rem; }
.pj-depot__zone:hover { border-color:var(--vert-clair); background:var(--vert-pale); }
.pj-depot.est-survole .pj-depot__zone {
  border-color:var(--vert-mid); background:var(--vert-pale); border-style:solid;
}

@media (prefers-reduced-motion:reduce) { .pj--attente { animation:none; } }


/* ─── Titre en lecture, description en aperçu ─────────────────────────────── */
/* Verrouillé, le titre se lit comme un titre : pas de bord de champ, mais un
   survol qui indique qu'il est modifiable.
 *
 * Le focus demande une précaution. À l'ouverture, le navigateur le donne au
 * premier élément focalisable de la modale — c'est-à-dire au titre, verrouillé
 * ou non. Il se peignait alors en gris sans être modifiable pour autant : la
 * fiche s'ouvrait sur un titre d'apparence grisée. En lecture, le focus ne
 * change donc plus rien à son dessin ; seul le focus *visible*, celui qu'on
 * obtient au clavier, trace son contour. */
/* Le formulaire reçoit le focus à l'ouverture (voir son autofocus) : c'est un
   conteneur, pas une commande — il ne porte donc aucun contour. */
.modale__forme:focus, .modale__forme:focus-visible { outline:none; }

.fiche-tete__titre[readonly] { cursor:text; }
.fiche-tete__titre[readonly]:focus { background:transparent; box-shadow:none; }
.fiche-tete__titre[readonly]:focus-visible {
  outline:3px solid var(--vert-clair); outline-offset:2px;
}
.fiche-tete__titre[readonly]:hover { background:var(--fond-clair); }
.fiche-tete__titre.est-en-edition {
  background:var(--fond-clair);
  box-shadow:inset 0 -2px 0 var(--vert-clair);
}

/*
 * État de lecture de la description : le cadre reste, comme pour les champs
 * de la colonne latérale auxquels il répond, mais la barre d'outils s'efface.
 * Elle ne revient qu'une fois le texte ouvert à la saisie — c'est le survol,
 * plus bas, qui signale qu'un clic l'y ouvre.
 */
.editeur.est-en-lecture .editeur__barre { display:none; }

/* Le rendu de la description se comporte comme une zone de saisie au survol :
   c'est ce qui signale qu'un clic l'ouvre à l'édition. */
.editeur__rendu {
  cursor:text;
  transition:background var(--t-rapide);
  border-radius:calc(var(--r-md) - 2px);
}
.editeur__rendu:hover { background:var(--fond-clair); }
.editeur__rendu a { cursor:pointer; }
.editeur__rendu:empty::before {
  content:'Cliquez pour ajouter une description';
  color:var(--texte-clair);
}
/* Sans description, le bloc se réduit à son invite : les 150 px prévus pour
   la saisie laissaient un grand vide dans le cadre. Même marge intérieure que
   la zone de saisie, pour que le cadre vide ait la tenue d'un champ. */
.editeur.est-en-lecture .editeur__rendu:empty { min-height:0; padding:.75rem .9rem; }

/* =============================================================================
   RÉGLAGES
   ========================================================================== */
.compte-ligne { display:flex; align-items:flex-start; gap:.6rem; }
.cellule-secondaire { font-size:.8125rem; color:var(--texte-clair); font-weight:400; }
/*
 * Ce que montre un lien de partage, dans le tableau des Réglages. Les trois
 * libellés s'affichaient en texte nu, faute de règle, là où la même information
 * est portée par des pastilles partout ailleurs.
 */
.mini-jetons { display:inline-flex; flex-wrap:wrap; gap:.25rem; }
.mini-jeton {
  padding:.15rem .4rem; border-radius:var(--r-sm);
  background:var(--vert-pale); color:var(--vert-fonce);
  font-size:.625rem; font-weight:700; letter-spacing:.03em; text-transform:uppercase;
}
.cellule-note { font-size:.75rem; color:var(--texte-clair); }
.cellule-note--alerte { color:#9A3412; font-weight:600; }
.tableau tbody tr.est-inactif { opacity:.55; }

.badge-role {
  display:inline-block; padding:.25rem .6rem; border-radius:var(--r-full);
  font-size:.75rem; font-weight:700; letter-spacing:.02em; white-space:nowrap;
}
.badge-role--admin   { background:var(--vert-fonce); color:#fff; }
.badge-role--editeur { background:var(--fond-clair); color:var(--texte-mid); }

.jeton--moi     { background:var(--vert-pale); color:var(--vert-fonce); }
.jeton--inactif { background:var(--fond-clair); color:var(--texte-clair); }

.note--pied { margin-top:1rem; font-size:.8125rem; }
/*
 * Avertissement : même dessin que .alerte, en plus discret — c'est une mise en
 * garde posée dans le fil d'un réglage, pas un message bloquant en tête de page.
 * Le modificateur était employé dans Réglages sans qu'aucune règle existe :
 * l'avertissement se lisait comme une note ordinaire.
 */
.note--avertissement {
  display:flex; align-items:flex-start; gap:.5rem;
  padding:.6rem .8rem; border-radius:var(--r-sm);
  background:var(--jaune-pale); color:#8A6100;
  font-size:.8125rem; font-weight:600;
}
.note--avertissement svg { flex-shrink:0; margin-top:2px; }

/* ─── Choix du rôle ───────────────────────────────────────────────────────── */
.choix-role { display:flex; flex-direction:column; gap:.5rem; }
.choix-role__option {
  display:flex; align-items:flex-start; gap:.7rem; cursor:pointer;
  padding:.8rem .9rem; border:2px solid #E3E3DD; border-radius:var(--r-md);
  transition:border-color var(--t-rapide), background var(--t-rapide);
}
.choix-role__option:hover { border-color:var(--vert-sauge); }
.choix-role__option:has(input:checked) {
  border-color:var(--vert-mid); background:var(--vert-pale);
}
.choix-role__option input { margin-top:.2rem; accent-color:var(--vert-fonce); flex-shrink:0; }
.choix-role__option strong { display:block; font-size:.9375rem; }
.choix-role__detail {
  display:block; font-size:.8125rem; color:var(--texte-mid); line-height:1.45; margin-top:.15rem;
}

/* ─── Mot de passe temporaire ─────────────────────────────────────────────── */
.mdp-boite {
  display:flex; align-items:center; gap:.6rem; flex-wrap:wrap;
  padding:.85rem 1rem; margin:.75rem 0 .5rem;
  background:var(--fond-nuit); border-radius:var(--r-md);
}
.mdp-boite code {
  flex:1; min-width:0; color:#fff; user-select:all;
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size:1.0625rem; font-weight:700; letter-spacing:.06em; word-break:break-all;
}
.mdp-boite .btn { flex-shrink:0; border-color:rgba(255,255,255,.4); color:#fff; }
.mdp-boite .btn:hover { background:rgba(255,255,255,.15); color:#fff; }

/* ─── Liste d'actions ─────────────────────────────────────────────────────── */
.actions-liste { display:flex; flex-direction:column; gap:.35rem; }
.action-item {
  display:flex; align-items:flex-start; gap:.7rem; width:100%; text-align:left;
  padding:.75rem .85rem; border:0; border-radius:var(--r-md);
  background:transparent; cursor:pointer; font:inherit;
  transition:background var(--t-rapide);
}
.action-item:hover { background:var(--fond-clair); }
.action-item svg { flex-shrink:0; margin-top:.1rem; color:var(--texte-mid); }
.action-item strong { display:block; font-size:.9375rem; }
.action-item span span { display:block; font-size:.8125rem; color:var(--texte-clair); }
.action-item--danger:hover { background:var(--orange-pale); }
.action-item--danger:hover svg,
.action-item--danger:hover strong { color:#9A3412; }

/* ─── Réglages de la plateforme ───────────────────────────────────────────── */
/*
 * Lignes de réglage (colonnes du kanban, étiquettes).
 * Ces parties n'avaient aucune règle : les flèches d'ordre étaient deux
 * boutons pleine taille qui se repliaient faute de place, et la note
 * s'écoulait à la suite du libellé — « Devis » suivi de « compte dans
 * "Devisé" » se lisait comme un seul nom de colonne.
 */
.reglage-liste { display:flex; flex-direction:column; gap:.5rem; }
.reglage-ordre { display:flex; flex-direction:column; gap:2px; flex-shrink:0; }
.icone-btn--mini {
  width:28px; height:22px; font-size:.65rem; line-height:1;
  color:var(--texte-clair); border-radius:var(--r-sm);
}
.icone-btn--mini:disabled { opacity:.3; cursor:not-allowed; }
/*
 * Ligne d'un réglage à bascule : le libellé et sa précision d'un côté,
 * l'interrupteur de l'autre. Sans cette règle, le <label> restait en ligne et
 * l'interrupteur se retrouvait collé à la fin du texte.
 */
.reglage-bascule {
  display:flex; align-items:flex-start; justify-content:space-between; gap:1rem;
  cursor:pointer; padding:.25rem 0;
}
.reglage-bascule > span:first-child { min-width:0; }
.reglage-bascule strong { font-size:.9375rem; }

.reglage-pastille {
  display:inline-flex; align-items:center; justify-content:center;
  width:28px; flex-shrink:0; color:var(--texte-mid);
}
.reglage-ligne__nom { flex:1; min-width:0; font-size:.9375rem; font-weight:600; }
/* La note passe sur sa propre ligne : c'est une précision, pas la suite du nom. */
.reglage-ligne__note {
  display:block; font-size:.8125rem; font-weight:400; color:var(--texte-clair);
}
.reglage-ligne__actions { display:flex; gap:.15rem; margin-left:auto; flex-shrink:0; }

/* Sur téléphone, les deux actions passent en dessous : le nom et sa note
   récupèrent ainsi près du double de largeur (112 px → 212 px). */
@media (max-width:575.98px) {
  /* Alignement en haut : centrés, les flèches et la pastille flottaient au
     milieu d'une ligne devenue haute, loin du nom qu'elles désignent. */
  .reglage-ligne { flex-wrap:wrap; row-gap:.35rem; align-items:flex-start; }
  .reglage-ligne__actions { flex-basis:100%; justify-content:flex-end; }
}
.reglage-ligne {
  display:flex; align-items:center; gap:.6rem;
  padding:.5rem .6rem; border-radius:var(--r-md); background:var(--fond-clair);
}
.reglage-ligne__icone {
  display:inline-flex; align-items:center; justify-content:center;
  width:30px; height:30px; flex-shrink:0; color:var(--texte-mid);
}
.reglage-ligne__emoji {
  width:44px; flex-shrink:0; text-align:center; font-size:1.125rem;
  border:1px solid transparent; border-radius:var(--r-sm); background:#fff;
  padding:.35rem .2rem;
}
.reglage-ligne__libelle {
  flex:1; min-width:0; border:1px solid transparent; border-radius:var(--r-sm);
  background:#fff; padding:.4rem .6rem; font:inherit; font-size:.9375rem;
}
.reglage-ligne__libelle:focus, .reglage-ligne__emoji:focus {
  outline:none; border-color:var(--vert-clair);
}
.reglage-ligne__couleur {
  width:38px; height:32px; flex-shrink:0; padding:2px; cursor:pointer;
  border:1px solid rgba(0,0,0,.12); border-radius:var(--r-sm); background:#fff;
}
.reglage-ligne__etat {
  min-width:70px; font-size:.75rem; color:var(--texte-clair); text-align:right;
}

@media (max-width:575.98px) {
  .reglage-ligne__etat { display:none; }
}

/* =============================================================================
   CHRONOMÈTRE
   ========================================================================== */
/* Le total a rejoint l'en-tête de section, où le bloc Frais met le sien.
   Le bouton occupe donc toute la largeur : c'est l'action du bloc. */
.chrono__bouton { width:100%; font-variant-numeric:tabular-nums; }
/* Le compteur actif se voit d'un coup d'œil : c'est ce qu'on cherche du regard. */
.chrono__bouton.est-actif {
  background:var(--orange-pale); border-color:var(--orange); color:#9A3412;
}

.chrono__ailleurs {
  margin-top:.5rem; padding:.5rem .65rem; border-radius:var(--r-sm);
  background:var(--jaune-pale); font-size:.8125rem; line-height:1.4;
}
.chrono__ailleurs.est-annonce { background:var(--vert-pale); }

.chrono__sessions { list-style:none; margin:.75rem 0 0; padding:0; }
.chrono__session {
  display:flex; align-items:center; gap:.5rem;
  padding:.35rem 0; font-size:.8125rem;
  border-top:1px solid rgba(0,0,0,.05);
}
.chrono__session-quoi { flex:1; min-width:0; color:var(--texte-clair); }
.chrono__session-duree { font-weight:700; font-variant-numeric:tabular-nums; }
.chrono__session.est-active .chrono__session-duree { color:var(--orange); }
.chrono__session-suppr { font-size:1rem; line-height:1; }

/* Encart de saisie identique à celui des frais — même fond, même retrait,
   mêmes champs : les deux blocs se lisent désormais de la même façon. */
.chrono__manuel {
  margin-top:.6rem; padding:.65rem; border-radius:var(--r-md);
  background:var(--fond-clair);
}
/* La date réclame plus de place que « 1h30 », d'où le 2 pour 1. */
.chrono__manuel-champs { display:grid; grid-template-columns:2fr 1fr; gap:.5rem; }
.chrono__manuel-date, .chrono__manuel-duree { min-width:0; }
.chrono__manuel-actions { display:flex; gap:.4rem; margin-top:.5rem; }
.chrono__manuel .champ__aide { margin-top:.45rem; }

/* =============================================================================
   CHECKLIST DE LA FICHE
   ========================================================================== */
/* Pastille d'avancement, à la manière du compteur d'une colonne du kanban.
   Masquée tant que la liste est vide : « 0/0 » n'apprend rien. */
.checklist__compte:not(:empty) {
  padding:.1rem .45rem; border-radius:var(--r-full);
  background:var(--fond-clair); color:var(--texte-mid);
  font-size:.6875rem; font-weight:700; font-variant-numeric:tabular-nums;
}
.checklist.est-complete .checklist__compte { background:var(--vert-pale); color:var(--vert-fonce); }

.checklist__liste { list-style:none; margin:0; padding:0; }

/* La ligne reprend le dessin de la todo list de l'accueil — même rond, même
   barré — mais plus compacte : la fiche en empile davantage dans moins de place. */
.checklist-item {
  display:flex; align-items:center; gap:.5rem;
  padding:.3rem .35rem; border-radius:var(--r-sm);
  transition:background var(--t-rapide);
}
.checklist-item:hover { background:var(--fond-clair); }
.checklist-item.est-glissee { opacity:.4; }

.checklist-item__poignee {
  cursor:grab; color:var(--texte-clair); opacity:0; flex-shrink:0;
  display:flex; transition:opacity var(--t-rapide); touch-action:none;
}
.checklist-item:hover .checklist-item__poignee { opacity:1; }
@media (hover:none) { .checklist-item__poignee { opacity:.5; } }

/*
 * Le bloc porte la classe « champ », pour son interligne et son en-tête. Il
 * hérite donc de « .champ input / textarea » : bordure, fond blanc, pleine
 * largeur, 49 px de haut. Rien de tout cela ici, où les contrôles doivent
 * disparaître dans la ligne — d'où le préfixe « .checklist », qui donne à ces
 * règles la spécificité nécessaire pour l'emporter.
 */
.checklist .checklist-item__case {
  appearance:none; width:18px; height:18px; flex-shrink:0; cursor:pointer;
  padding:0; border:2px solid var(--vert-sauge); border-radius:var(--r-full);
  background:transparent; transition:all var(--t-ressort); position:relative;
}
/* Cible tactile de 44px débordant du rond visible de 18px */
.checklist .checklist-item__case::before { content:''; position:absolute; inset:-13px; }
.checklist .checklist-item__case:checked {
  background:var(--vert-fonce); border-color:var(--vert-fonce);
}
.checklist .checklist-item__case:checked::after {
  content:''; position:absolute; left:5px; top:1px;
  width:4px; height:9px; border:solid #fff; border-width:0 2px 2px 0;
  transform:rotate(45deg);
}

.checklist .checklist-item__texte {
  flex:1; width:auto; border:0; border-radius:0; background:transparent;
  padding:.1rem 0; font:inherit; font-size:.875rem;
  color:var(--texte-fonce); min-width:0;
  display:block; resize:none; overflow:hidden; line-height:1.35;
}
.checklist .checklist-item__texte:focus {
  outline:none; border-bottom:2px solid var(--vert-clair);
}
/* Coché, l'élément reste lisible : une checklist se relit pour voir ce qui
   a été fait, pas seulement ce qui reste. */
.checklist-item.est-fait .checklist-item__texte {
  text-decoration:line-through; color:var(--texte-clair);
}

.checklist-item__suppr { opacity:0; flex-shrink:0; transition:opacity var(--t-rapide); }
.checklist-item:hover .checklist-item__suppr,
.checklist-item:focus-within .checklist-item__suppr { opacity:1; }
@media (hover:none) { .checklist-item__suppr { opacity:.6; } }

/* Saisie en bas de liste, alignée sur les lignes au-dessus : le « + » occupe
   la place de la poignée et du rond réunis. */
.checklist__ajout {
  display:flex; align-items:center; gap:.5rem;
  padding:.35rem .35rem; margin-top:.15rem;
  border-top:1px dashed rgba(0,0,0,.1);
}
.checklist__ajout-icone { display:flex; color:var(--texte-clair); flex-shrink:0; }
.checklist .checklist__ajout-champ {
  flex:1; width:auto; height:auto; min-width:0;
  border:0; border-radius:0; background:transparent;
  font:inherit; font-size:.875rem; padding:.15rem 0; color:var(--texte-fonce);
}
.checklist .checklist__ajout-champ::placeholder { color:var(--texte-clair); }
.checklist .checklist__ajout-champ:focus { outline:none; }

/*
 * Ce qui vient d'être ajouté se signale une seconde, puis se tait.
 *
 * Une pièce jointe atterrit en bout de grille, un élément de checklist en bas
 * d'une liste déjà longue : sans ce bref éclat, on cherche des yeux ce que
 * l'on vient pourtant de créer soi-même.
 */
.est-nouvelle { animation:ligne-neuve 1s ease; }
@keyframes ligne-neuve {
  0%   { background:var(--vert-pale); }
  60%  { background:var(--vert-pale); }
  100% { background:transparent; }
}

/* =============================================================================
   FRAIS
   ========================================================================== */
.frais-liste { list-style:none; margin:0 0 .6rem; padding:0; }
.frais {
  display:flex; align-items:center; gap:.4rem;
  padding:.35rem 0; font-size:.8125rem;
  border-top:1px solid rgba(0,0,0,.05);
}
.frais__libelle {
  flex:1; min-width:0; color:var(--texte-clair);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.frais__montant { font-weight:700; font-variant-numeric:tabular-nums; flex-shrink:0; }

/*
 * Encart distinct du reste (fond clair, coins arrondis) : sans lui, le
 * formulaire flottait entre la liste et le bord du bloc, sans en faire
 * clairement partie. Les champs eux-mêmes reprennent le style riche de
 * .champ input (bordure 2px, padding généreux) — aucune règle ici ne le
 * redéfinit, pour qu'ils restent identiques à Titre ou Budget HT.
 */
.frais-forme {
  margin-top:.6rem; padding:.65rem; border-radius:var(--r-md);
  background:var(--fond-clair);
}
/*
 * Grille plutôt que flex : avec flex, la base fixe du champ montant (pour
 * accueillir « € HT ») absorbait presque tout l'avantage du ratio de
 * grow, et les deux colonnes finissaient quasi égales. Une grille fixe le
 * ratio indépendamment de ce que chaque champ contient.
 */
.frais-forme__champs { display:grid; grid-template-columns:3fr 1fr; gap:.5rem; }
.frais-forme__libelle, .frais-forme__montant { min-width:0; }
.frais-forme__actions { display:flex; gap:.4rem; margin-top:.5rem; }

/* En dessous, deux colonnes à 1fr le montant deviendrait trop étroit pour
   « € HT » : les champs s'empilent plutôt. */
@media (max-width:575.98px) {
  .frais-forme__champs { grid-template-columns:1fr; }
}

/* Marge sous le Budget HT : chiffre lisible, mais pas plus proéminent que
   le champ dont elle découle — c'est une lecture dérivée, pas la donnée. */
.fiche-marge:not(:empty) { font-weight:600; color:var(--texte-fonce); }
.fiche-marge__montant { color:var(--vert-mid); }
.fiche-marge.est-negative .fiche-marge__montant { color:var(--orange); }

/* ─── Rappel dans la barre latérale ───────────────────────────────────────── */
.barre__chrono {
  display:flex; align-items:center; gap:.6rem;
  margin:0 0 .75rem; padding:.55rem .7rem; border-radius:var(--r-md);
  background:rgba(232,97,42,.18); color:#fff;
  transition:background var(--t-rapide);
}
.barre__chrono:hover { background:rgba(232,97,42,.3); }
.barre__chrono-point {
  width:8px; height:8px; border-radius:var(--r-full); flex-shrink:0;
  background:var(--orange); animation:chrono-battement 2s ease-in-out infinite;
}
@keyframes chrono-battement { 50% { opacity:.25; } }
.barre__chrono-corps { min-width:0; }
.barre__chrono-temps {
  display:block; font-weight:700; font-size:.875rem; font-variant-numeric:tabular-nums;
}
.barre__chrono-projet {
  display:block; font-size:.75rem; color:rgba(255,255,255,.7);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* Barre repliée : le point suffit à signaler qu'un compteur tourne. */
@media (min-width:992px) {
  html.barre-repliee .barre__chrono { justify-content:center; padding-left:0; padding-right:0; }
  html.barre-repliee .barre__chrono-corps { display:none; }
}

/* =============================================================================
   ARCHIVES
   ========================================================================== */
.archives { display:flex; flex-direction:column; gap:1.25rem; }

.archive__tete { align-items:flex-start; }
.archive__identite { flex:1; min-width:0; }
.archive__meta { margin-top:.2rem; font-size:.875rem; color:var(--texte-clair); }
.archive__restaurer { margin-left:auto; flex-shrink:0; }

/* Les quelques faits de la fiche, sur une grille qui se replie d'elle-même. */
.archive__faits {
  list-style:none; margin:0 0 .5rem; padding:0;
  display:grid; grid-template-columns:repeat(auto-fit, minmax(140px, 1fr)); gap:.85rem;
  font-size:.9375rem;
}
.archive__fait-cle {
  display:block; margin-bottom:.2rem;
  font-size:.75rem; font-weight:600; letter-spacing:.06em;
  text-transform:uppercase; color:var(--texte-clair);
}

.archive__contenu { border-top:1px solid rgba(0,0,0,.06); }
.archive__contenu > summary {
  display:flex; align-items:center; gap:.6rem; cursor:pointer;
  padding:.75rem 0 .25rem; font-size:.9375rem; font-weight:600;
}
.archive__contenu > summary::-webkit-details-marker { display:none; }
/* Chevron maison : le marqueur natif diffère d'un navigateur à l'autre. */
.archive__contenu > summary::before {
  content:''; width:0; height:0; flex-shrink:0;
  border-left:5px solid var(--texte-clair);
  border-top:4px solid transparent; border-bottom:4px solid transparent;
  transition:transform var(--t-rapide);
}
.archive__contenu[open] > summary::before { transform:rotate(90deg); }
.archive__compte {
  font-weight:400; font-size:.8125rem; color:var(--texte-clair);
}
.archive__contenu .editeur__rendu { margin:.5rem 0 1rem; }

@media (max-width:575.98px) {
  /* Le bouton ne doit pas comprimer le titre : il passe sous l'en-tête. */
  .archive__tete { flex-wrap:wrap; row-gap:.6rem; }
  .archive__restaurer { flex-basis:100%; justify-content:center; }
}

/* =============================================================================
   PARTAGE PUBLIC — panneau interne
   ========================================================================== */
.pastille-partage {
  position:absolute; top:-2px; right:-2px;
  min-width:16px; height:16px; padding:0 .2rem;
  display:inline-flex; align-items:center; justify-content:center;
  border-radius:var(--r-full); background:var(--vert-mid); color:#fff;
  font-size:.625rem; font-weight:800; line-height:1;
}
#ouvrirPartage { position:relative; }

.partage {
  border:1px solid rgba(0,0,0,.1); border-radius:var(--r-md);
  padding:.85rem; margin-bottom:.75rem;
  transition:opacity var(--t-rapide), border-color var(--t-rapide);
}
.partage.est-ferme { opacity:.62; border-style:dashed; }

.partage__tete { display:flex; align-items:center; gap:.6rem; margin-bottom:.6rem; }
.partage__libelle {
  flex:1; min-width:0; border:0; border-bottom:1px solid transparent;
  background:transparent; font:inherit; font-size:.9375rem; font-weight:600;
  padding:.2rem 0;
}
.partage__libelle:focus { outline:none; border-bottom-color:var(--vert-clair); }
.partage__libelle::placeholder { color:var(--texte-clair); font-weight:400; }

/* ─── Interrupteur actif / fermé ──────────────────────────────────────────── */
.bascule { display:inline-flex; align-items:center; gap:.45rem; cursor:pointer; flex-shrink:0; }
.bascule input { position:absolute; opacity:0; width:0; height:0; }
.bascule__piste {
  width:38px; height:22px; border-radius:var(--r-full);
  background:#C9CCC6; position:relative; transition:background var(--t-base);
}
.bascule__pouce {
  position:absolute; top:2px; left:2px; width:18px; height:18px;
  border-radius:var(--r-full); background:#fff;
  box-shadow:0 1px 3px rgba(0,0,0,.25); transition:transform var(--t-ressort);
}
.bascule input:checked + .bascule__piste { background:var(--vert-mid); }
.bascule input:checked + .bascule__piste .bascule__pouce { transform:translateX(16px); }
.bascule input:focus-visible + .bascule__piste { outline:3px solid var(--vert-clair); outline-offset:2px; }
.bascule__texte { font-size:.75rem; font-weight:700; color:var(--texte-mid); min-width:38px; }

.partage__url { display:flex; align-items:center; gap:.4rem; margin-bottom:.7rem; }
.partage__adresse {
  flex:1; min-width:0; padding:.5rem .7rem; font-size:.8125rem;
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
  border:1px solid rgba(0,0,0,.1); border-radius:var(--r-sm);
  background:var(--fond-clair); color:var(--texte-mid);
}
.partage__copier { flex-shrink:0; }

.partage__options { display:flex; flex-direction:column; gap:.15rem; margin-bottom:.6rem; }
.partage__options .case-memo { margin:0; font-size:.8125rem; }
.partage__fin {
  display:flex; align-items:center; gap:.5rem; flex-wrap:wrap;
  font-size:.8125rem; color:var(--texte-mid); margin-top:.35rem;
}
.partage__fin input { padding:.3rem .5rem; font-size:.8125rem; border:1px solid rgba(0,0,0,.12);
  border-radius:var(--r-sm); font-family:inherit; }

.partage__pied {
  display:flex; align-items:center; gap:.5rem;
  border-top:1px solid rgba(0,0,0,.06); padding-top:.5rem;
}
.partage__stats { flex:1; font-size:.75rem; color:var(--texte-clair); }
.partage__suppr:hover { background:var(--orange-pale); color:#9A3412; }

/* =============================================================================
   PAGE PUBLIQUE
   ========================================================================== */
body.public { background:var(--fond-clair); }

.public-large { max-width:1000px; margin:0 auto; padding:0 1.5rem; }

.public-tete { background:var(--fond-nuit); padding:1rem 0; }
.public-tete .public-large { display:flex; align-items:center; gap:1rem; }
.public-tete__mention {
  margin-left:auto; color:rgba(255,255,255,.65); font-size:.75rem;
  font-weight:600; letter-spacing:.06em; text-transform:uppercase;
}

.public-corps { padding-top:2rem; padding-bottom:3rem; }

.public-chapeau { margin-bottom:1.5rem; }
.public-client {
  margin:0 0 .3rem; font-size:.8125rem; font-weight:700; color:var(--vert-mid);
  text-transform:uppercase; letter-spacing:.06em;
}
.public-titre { font-size:clamp(1.6rem, 4vw, 2.25rem); line-height:1.15; margin:0; }
.public-etiquettes { display:flex; flex-wrap:wrap; gap:.35rem; margin-top:.75rem; }

.public-grille { display:grid; gap:1.25rem; grid-template-columns:1fr; }
@media (min-width:768px) { .public-grille { grid-template-columns:1fr 280px; } }

.public-rendu { padding:0; }

.public-info {
  display:flex; flex-direction:column; gap:.15rem;
  padding:.7rem 0; border-bottom:1px solid rgba(0,0,0,.06);
}
.public-info:last-child { border-bottom:0; }
.public-info__etiquette {
  display:flex; align-items:center; gap:.35rem;
  font-size:.75rem; font-weight:700; color:var(--texte-clair);
  text-transform:uppercase; letter-spacing:.05em;
}
.public-info__valeur { font-size:.9375rem; font-weight:600; }
.public-info__note { display:block; font-size:.8125rem; font-weight:400; color:var(--texte-clair); }

.public-pied {
  margin-top:2.5rem; padding-top:1.25rem; border-top:1px solid rgba(0,0,0,.08);
  font-size:.8125rem; color:var(--texte-mid); text-align:center;
}
.public-pied p { margin:.2rem 0; }
.public-pied__note { color:var(--texte-clair); font-size:.75rem; }

/* Mot de passe facultatif d'un lien de partage */
.partage__fin-note { font-size:.6875rem; color:var(--texte-clair); }
.partage__protection { margin-top:.4rem !important; }
.partage__mdp { margin:.35rem 0 0 1.75rem; }
.partage__mdp input {
  width:100%; padding:.45rem .6rem; font-size:.8125rem; font-family:inherit;
  border:1px solid rgba(0,0,0,.14); border-radius:var(--r-sm);
}
.partage__mdp input:focus { outline:none; border-color:var(--vert-clair); }
.partage__mdp-note { display:block; font-size:.6875rem; color:var(--texte-clair); margin-top:.2rem; }

/* ─── Champs d'un modèle d'envoi ──────────────────────────────────────────── */
/*
 * Une ligne par variable du template : la variable, son intitulé, sa nature,
 * et de quoi la retirer. Encart grisé pour détacher la liste du reste du
 * formulaire, comme l'encart de saisie des frais sur la fiche.
 */
.modele-champs { display:flex; flex-direction:column; gap:.5rem; margin-bottom:.6rem; }

.modele-champ {
  padding:.65rem; border-radius:var(--r-md); background:var(--fond-clair);
}
/* La variable prend plus de place : « {{ params.projet_num_facture }} » est
   bien plus long que l'intitulé qu'on lui donne. */
.modele-champ__grille {
  display:grid; grid-template-columns:1.4fr 1fr 8rem auto;
  gap:.4rem; align-items:center;
}
.modele-champ__grille > * { min-width:0; }
/* Champs compacts : quatre contrôles sur une ligne ne tiendraient pas à la
   hauteur généreuse des champs ordinaires. */
.modele-champ__grille input,
.modele-champ__grille select { height:40px; padding:.45rem .6rem; font-size:.875rem; }
.modele-champ__suppr { flex-shrink:0; }

.modele-champ__obligatoire { margin:.4rem 0 0; font-size:.8125rem; }

@media (max-width:767.98px) {
  /* Empilés : à cette largeur, quatre colonnes rendaient la variable illisible. */
  .modele-champ__grille { grid-template-columns:1fr auto; }
  .modele-champ__grille > :nth-child(1) { grid-column:1 / -1; }
}

/* =============================================================================
   RÉGLAGES — onglet Données
   ========================================================================== */
.export-liste { display:flex; flex-direction:column; gap:.5rem; margin-bottom:.75rem; }

.export-item {
  display:flex; align-items:center; gap:.85rem;
  padding:.9rem 1rem; border-radius:var(--r-md);
  border:1px solid rgba(0,0,0,.08); background:var(--fond-blanc);
  color:var(--texte-fonce); text-decoration:none;
  transition:border-color var(--t-rapide), background var(--t-rapide), transform var(--t-rapide);
}
.export-item:hover {
  border-color:var(--vert-clair); background:var(--vert-pale);
  transform:translateY(-1px); color:var(--texte-fonce);
}
/* Première icône : le type de données. Dernière : l'action de téléchargement. */
.export-item > svg:first-child { flex-shrink:0; color:var(--vert-mid); }
.export-item > svg:last-child  { flex-shrink:0; margin-left:auto; color:var(--texte-clair); }
.export-item:hover > svg:last-child { color:var(--vert-fonce); }

.export-item > span { min-width:0; }
.export-item strong { display:block; font-size:.9375rem; }
.export-item span span {
  display:block; font-size:.8125rem; color:var(--texte-mid); line-height:1.4; margin-top:.1rem;
}

@media (max-width:479.98px) {
  .export-item { gap:.6rem; padding:.75rem .8rem; }
  .export-item span span { font-size:.75rem; }
}

/* Les cartes de la page Réglages ont besoin d'air entre elles, comme celles
   du profil : la règle n'existait que pour .zone--etroite. */

/* =============================================================================
   PAGE D'INSTALLATION
   ========================================================================== */
.diag-liste { display:flex; flex-direction:column; gap:.15rem; margin-bottom:1.25rem; }

.diag-ligne {
  display:flex; align-items:baseline; gap:.75rem;
  padding:.4rem .6rem; border-radius:var(--r-sm); font-size:.875rem;
}
.diag-ligne--ok    { background:var(--vert-pale); }
.diag-ligne--avert { background:var(--jaune-pale); }
.diag-ligne--echec { background:var(--orange-pale); }

.diag-etat {
  flex-shrink:0; width:52px; font-size:.6875rem; font-weight:800;
  letter-spacing:.04em; text-transform:uppercase;
}
.diag-ligne--ok    .diag-etat { color:var(--vert-fonce); }
.diag-ligne--avert .diag-etat { color:#8A6100; }
.diag-ligne--echec .diag-etat { color:#9A3412; }

.diag-quoi   { flex:0 0 auto; font-weight:600; min-width:0; }
.diag-detail { flex:1; min-width:0; color:var(--texte-mid); font-size:.8125rem; }

@media (max-width:575.98px) {
  .diag-ligne { flex-wrap:wrap; gap:.25rem .6rem; }
  .diag-detail { flex-basis:100%; }
}

/* =============================================================================
   OFFRES ET SIGNATURE ÉLECTRONIQUE
   ========================================================================== */

/* La police manuscrite du mode « taper mon nom ». Caveat, sous licence OFL,
   servie en local comme les deux autres : la CSP interdit tout CDN.
   C'est une police variable, d'où la plage de graisses plutôt qu'une valeur
   unique — un seul fichier couvre 400 à 700. Si le fichier venait à manquer,
   la pile cursive du système prend le relais et la signature reste manuscrite,
   simplement moins homogène d'un appareil à l'autre. */
@font-face {
  font-family:'Caveat';
  src:url('../fonts/Caveat/Caveat-Variable.ttf') format('truetype');
  font-weight:400 700; font-display:swap;
}

/* ─── Page publique d'une offre ───────────────────────────────────────────── */
.offre-large { max-width:1360px; margin:0 auto; padding:0 1.5rem; }
.offre-tete .offre-large { display:flex; align-items:center; gap:1rem; }
.offre-corps { padding-top:1.75rem; padding-bottom:3rem; }

.offre-grille { display:grid; gap:1.5rem; grid-template-columns:2fr 1fr; align-items:start; }

.offre-doc { position:relative; }
.offre-doc__cadre {
  width:100%; height:calc(100dvh - 190px); min-height:560px;
  border:1px solid rgba(0,0,0,.08); border-radius:var(--r-md);
  background:var(--fond-blanc); box-shadow:var(--ombre-sm);
}
/* Les visionneuses PDF intégrées des navigateurs mobiles rendent mal dans un
   cadre étroit : on leur préfère le lecteur du système. */
.offre-doc__mobile { display:none; }
.offre-doc__telecharger {
  display:inline-flex; align-items:center; gap:.4rem; margin-top:.75rem;
  font-size:.8125rem; font-weight:600; color:var(--texte-mid);
}
.offre-doc__telecharger:hover { color:var(--vert-fonce); }

.offre-cote { display:flex; flex-direction:column; gap:1rem; }
.offre-cote .carte { margin:0; }

.offre-reference {
  font-size:.6875rem; font-weight:700; letter-spacing:.1em;
  color:var(--texte-clair); text-transform:uppercase; margin:0 0 .35rem;
}
.offre-titre { font-size:1.375rem; line-height:1.25; margin:0 0 1rem; }

.offre-montant {
  display:flex; align-items:baseline; gap:.4rem;
  padding:.9rem 1.1rem; margin-bottom:1rem;
  background:var(--vert-pale); border-radius:var(--r-md);
}
.offre-montant__valeur {
  font-family:var(--font-titre); font-size:1.75rem; font-weight:800;
  letter-spacing:-.02em; color:var(--vert-fonce);
}
.offre-montant__mention { font-size:.8125rem; font-weight:700; color:var(--vert-mid); }

.offre-message {
  padding:.9rem 1.1rem; margin-bottom:1rem;
  background:var(--fond-clair); border-left:3px solid var(--vert-clair);
  border-radius:0 var(--r-sm) var(--r-sm) 0;
  font-size:.9375rem; line-height:1.65; color:var(--texte-mid);
}

.offre-contact__intro { margin:0; font-size:.9375rem; font-weight:700; }
.offre-contact__nom { margin:.2rem 0 .75rem; font-size:.875rem; color:var(--texte-mid); }
.offre-contact__liens { display:flex; flex-direction:column; gap:.4rem; }
.offre-contact__liens a {
  display:inline-flex; align-items:center; gap:.45rem;
  font-size:.875rem; font-weight:600;
}

.offre-valider {
  justify-content:center; gap:.5rem; padding:1rem; font-size:1rem;
}
.offre-valider__note {
  margin:.6rem 0 0; text-align:center;
  font-size:.75rem; color:var(--texte-clair);
}

.offre-signee { border:2px solid var(--vert-clair); }
.offre-signee__titre {
  display:flex; align-items:center; gap:.5rem; margin:0 0 .5rem;
  font-family:var(--font-titre); font-size:1rem; font-weight:800; color:var(--vert-fonce);
}
.offre-signee__detail { margin:0 0 .6rem; font-size:.875rem; color:var(--texte-mid); }

/* ─── Page de signature ───────────────────────────────────────────────────── */
.signer-large { max-width:760px; margin:0 auto; padding:0 1.5rem; }
.signer-large .public-tete__mention { margin-left:auto; }
.signer-corps { padding-top:1.5rem; padding-bottom:3rem; }

.signer-retour {
  display:inline-flex; align-items:center; gap:.35rem; margin-bottom:1rem;
  font-size:.8125rem; font-weight:600; color:var(--texte-mid);
}
.signer-retour:hover { color:var(--vert-fonce); }
.signer-retour svg { transform:rotate(90deg); }

.signer-titre { font-size:clamp(1.5rem, 4vw, 2rem); margin:0 0 1.25rem; }
.signer-form .carte { margin-bottom:1.25rem; }

.signer-recap { border:2px solid var(--vert-pale); margin-bottom:1.25rem; }
.signer-recap__reference {
  font-size:.6875rem; font-weight:700; letter-spacing:.1em;
  color:var(--texte-clair); text-transform:uppercase; margin:0 0 .3rem;
}
.signer-recap__designation { font-size:1.1875rem; margin:0 0 1rem; }
.signer-recap__faits { display:grid; grid-template-columns:1fr 1fr; gap:.85rem 1.25rem; margin:0; }
.signer-recap__faits dt {
  font-size:.6875rem; font-weight:700; letter-spacing:.05em;
  color:var(--texte-clair); text-transform:uppercase; margin-bottom:.15rem;
}
.signer-recap__faits dd { margin:0; font-size:.9375rem; font-weight:600; }
.signer-recap__montant {
  font-family:var(--font-titre); font-size:1.25rem !important;
  font-weight:800 !important; color:var(--vert-fonce);
}

/* ─── Le canevas ──────────────────────────────────────────────────────────── */
.signer-modes {
  display:inline-flex; gap:.25rem; margin-bottom:.85rem;
  padding:.25rem; border-radius:var(--r-full); background:rgba(0,0,0,.05);
}
.signer-mode {
  display:inline-flex; align-items:center; gap:.35rem;
  padding:.45rem .9rem; border:0; border-radius:var(--r-full);
  background:transparent; color:var(--texte-mid); cursor:pointer;
  font-size:.8125rem; font-weight:700;
  transition:background var(--t-rapide), color var(--t-rapide);
}
.signer-mode.est-actif { background:var(--fond-blanc); color:var(--vert-fonce); box-shadow:var(--ombre-sm); }

.signer-toile {
  position:relative; border:2px dashed rgba(0,0,0,.14); border-radius:var(--r-md);
  background:
    linear-gradient(var(--fond-blanc), var(--fond-blanc)) padding-box,
    repeating-linear-gradient(0deg, transparent 0 31px, rgba(0,0,0,.04) 31px 32px);
  overflow:hidden; transition:border-color var(--t-rapide);
}
.signer-toile.est-fautive { border-color:var(--orange); }
.signer-toile canvas {
  display:block; width:100%; height:200px;
  /* Sans cela, un glissement du doigt fait défiler la page au lieu de tracer. */
  touch-action:none; cursor:crosshair;
}
.signer-toile canvas.est-saisie { cursor:default; }
.signer-toile__invite {
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  margin:0; pointer-events:none; color:var(--texte-clair); font-size:.875rem;
}
.signer-toile__outils { display:flex; justify-content:flex-end; margin-top:.5rem; }

.signer-horloge {
  display:flex; flex-wrap:wrap; align-items:baseline; gap:.5rem;
  margin-top:1.25rem; padding:.85rem 1.1rem;
  background:var(--fond-clair); border-radius:var(--r-md);
}
.signer-horloge__etiquette {
  font-size:.6875rem; font-weight:700; letter-spacing:.05em;
  color:var(--texte-clair); text-transform:uppercase; width:100%;
}
.signer-horloge__valeur {
  font-family:var(--font-titre); font-size:1rem; font-weight:800;
  color:var(--vert-fonce); font-variant-numeric:tabular-nums;
}
.signer-horloge__fuseau { font-size:.75rem; color:var(--texte-clair); }

.signer-case {
  display:flex; align-items:flex-start; gap:.7rem; padding:.7rem 0;
  font-size:.9375rem; line-height:1.55; cursor:pointer;
}
.signer-case + .signer-case { border-top:1px solid rgba(0,0,0,.06); }
.signer-case input { margin-top:.25rem; width:18px; height:18px; accent-color:var(--vert-fonce); flex-shrink:0; }
.signer-case.est-fautive { color:#9A3412; }
.signer-case a { text-decoration:underline; }

.signer-envoyer { justify-content:center; gap:.5rem; padding:1.05rem; font-size:1rem; }
.signer-mention {
  margin:.85rem 0 0; text-align:center; line-height:1.6;
  font-size:.75rem; color:var(--texte-clair);
}

/* ─── Écran interne : formulaire d'envoi ──────────────────────────────────── */
.offres-form__grille { display:grid; gap:1.25rem; grid-template-columns:1fr 1fr; align-items:start; }
.offres-form .carte { margin-bottom:1.25rem; }
.offres-form__grille .carte { margin-bottom:0; }
.offres-form__pied {
  display:flex; align-items:center; justify-content:space-between;
  gap:1rem; flex-wrap:wrap;
}
.offres-form__note {
  display:flex; align-items:center; gap:.45rem; margin:0;
  font-size:.8125rem; color:var(--texte-clair);
}

.offres-bascule {
  display:flex; align-items:flex-start; gap:.7rem; padding:.85rem 1rem;
  background:var(--fond-clair); border-radius:var(--r-md); cursor:pointer;
  transition:opacity var(--t-rapide);
}
.offres-bascule.est-inactive { opacity:.55; cursor:not-allowed; }
.offres-bascule input { margin-top:.2rem; width:18px; height:18px; accent-color:var(--vert-fonce); flex-shrink:0; }
.offres-bascule strong { display:block; font-size:.875rem; }
.offres-bascule__note { display:block; font-size:.75rem; color:var(--texte-clair); margin-top:.15rem; }

.offres-source { display:flex; gap:.5rem; flex-wrap:wrap; margin-bottom:1rem; }
.offres-source__choix { flex:1 1 220px; cursor:pointer; }
.offres-source__choix input { position:absolute; opacity:0; pointer-events:none; }
.offres-source__choix span {
  display:flex; align-items:center; gap:.5rem; padding:.7rem 1rem;
  border:2px solid rgba(0,0,0,.1); border-radius:var(--r-md);
  font-size:.875rem; font-weight:600; color:var(--texte-mid);
  transition:border-color var(--t-rapide), color var(--t-rapide), background var(--t-rapide);
}
.offres-source__choix input:checked + span {
  border-color:var(--vert-fonce); color:var(--vert-fonce); background:var(--vert-pale);
}
.offres-source__choix input:focus-visible + span { outline:2px solid var(--vert-clair); outline-offset:2px; }

/* ─── Écran interne : suivi et archives ───────────────────────────────────── */
.offres-liste { display:flex; flex-direction:column; gap:1.25rem; }
.offre-ligne { margin:0; }
.offre-ligne__tete { align-items:flex-start; gap:1rem; }
.offre-ligne__identite { min-width:0; flex:1; }
.offre-ligne__reference {
  display:flex; align-items:center; gap:.5rem; margin:0 0 .25rem;
  font-size:.6875rem; font-weight:700; letter-spacing:.08em;
  color:var(--texte-clair); text-transform:uppercase;
}
.offre-ligne__client { margin:.3rem 0 0; font-size:.8125rem; color:var(--texte-clair); }
.offre-ligne__montant {
  margin:0; flex-shrink:0; text-align:right;
  font-family:var(--font-titre); font-size:1.25rem; font-weight:800;
  letter-spacing:-.02em; color:var(--vert-fonce);
}
.offre-ligne__montant small { font-size:.6875rem; font-weight:700; color:var(--texte-clair); }

.offre-ligne__faits {
  list-style:none; margin:0 0 1rem; padding:0;
  display:grid; gap:.6rem 1.5rem; grid-template-columns:repeat(auto-fit, minmax(190px, 1fr));
  font-size:.875rem;
}
.offre-ligne__faits--empreintes { grid-template-columns:1fr; }
.offre-ligne__faits code {
  display:block; font-size:.6875rem; word-break:break-all;
  color:var(--texte-mid); line-height:1.5;
}
.offre-ligne__cle {
  display:block; font-size:.6875rem; font-weight:700; letter-spacing:.05em;
  color:var(--texte-clair); text-transform:uppercase; margin-bottom:.1rem;
}

.offre-ligne__lien { display:flex; align-items:center; gap:.35rem; margin-bottom:1rem; }
.offre-ligne__lien input {
  flex:1; min-width:0; padding:.5rem .75rem;
  border:1px solid rgba(0,0,0,.1); border-radius:var(--r-sm);
  background:var(--fond-clair); font-size:.75rem; color:var(--texte-mid);
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
}
.offre-ligne__lien .icone-btn.est-copie { background:var(--vert-pale); color:var(--vert-fonce); }

.offre-ligne__journal summary {
  cursor:pointer; font-size:.8125rem; font-weight:700; color:var(--texte-mid);
  padding:.5rem 0;
}
.offre-ligne__compte {
  display:inline-block; margin-left:.35rem; padding:.05rem .4rem;
  border-radius:var(--r-full); background:var(--fond-clair);
  font-size:.6875rem; color:var(--texte-clair);
}
.offre-ligne__actions { display:flex; gap:.5rem; flex-wrap:wrap; }
.offre-ligne__actions form { margin:0; }

.journal { list-style:none; margin:.5rem 0 0; padding:0; font-size:.8125rem; }
.journal li {
  display:flex; gap:.75rem; align-items:baseline; padding:.4rem 0;
  border-bottom:1px solid rgba(0,0,0,.05);
}
.journal li:last-child { border-bottom:0; }
.journal__quand {
  flex-shrink:0; width:130px; color:var(--texte-clair);
  font-variant-numeric:tabular-nums; font-size:.75rem;
}
.journal__quoi { flex:1; font-weight:600; }
.journal__ip { color:var(--texte-clair); font-size:.6875rem; }

.offre-signature { margin-bottom:1rem; }
.offre-signature__ligne {
  display:flex; align-items:center; gap:.5rem; margin:0 0 .25rem;
  font-size:.9375rem; color:var(--vert-fonce);
}
.offre-signature__detail { margin:0; font-size:.8125rem; color:var(--texte-clair); }

.offre-preuve {
  display:flex; align-items:flex-start; gap:.6rem; padding:.75rem 1rem;
  margin-bottom:1rem; border-radius:var(--r-md); font-size:.8125rem;
}
.offre-preuve strong { display:block; font-size:.875rem; }
.offre-preuve.est-intacte { background:var(--vert-pale); color:var(--vert-fonce); }
.offre-preuve.est-rompue  { background:var(--orange-pale); color:#9A3412; }

.jeton--attente { background:var(--jaune-pale); color:#92400E; }
.jeton--info    { background:#DBEAFE; color:#1E40AF; }
.jeton--succes  { background:var(--vert-pale); color:var(--vert-fonce); }
.jeton--neutre  { background:var(--fond-clair); color:var(--texte-mid); }

.onglet__compte {
  margin-left:.35rem; padding:.05rem .4rem; border-radius:var(--r-full);
  background:rgba(0,0,0,.08); font-size:.6875rem; font-weight:700;
}
.onglet.est-actif .onglet__compte { background:var(--vert-pale); color:var(--vert-fonce); }

/* ─── Adaptations ─────────────────────────────────────────────────────────── */
@media (max-width:1100px) {
  .offre-grille { grid-template-columns:1fr; }
  .offres-form__grille { grid-template-columns:1fr; }
}
@media (max-width:900px) {
  /* Le cadre PDF cède la place à une carte d'ouverture. */
  .offre-doc__cadre { display:none; }
  .offre-doc__mobile {
    display:flex; flex-direction:column; align-items:center; gap:.5rem;
    padding:2.5rem 1.5rem; text-align:center;
    background:var(--fond-blanc); border-radius:var(--r-md); box-shadow:var(--ombre-sm);
  }
  .offre-doc__mobile p { margin:0; }
  .offre-doc__mobile svg { color:var(--vert-clair); }
  .offre-doc__mobile .btn { margin-top:.5rem; }
}
@media (max-width:640px) {
  .offre-large, .signer-large { padding:0 1rem; }
  .signer-recap__faits { grid-template-columns:1fr; }
  .offre-ligne__tete { flex-direction:column; }
  .offre-ligne__montant { text-align:left; }
  .journal li { flex-wrap:wrap; gap:.25rem .75rem; }
  .journal__quand { width:auto; }
}
