/* ============================================================================
   BIBLIOTHEQUE UI JABS  -  documents.css
   Depend de : theme.css (jetons) et buttons.css (classes .btn)
   Copier ces trois fichiers pour disposer des galeries completes.

   Convention : .doc-<bloc> pour un conteneur, .doc-<bloc>__<partie> pour ses
   parties, .is-<etat> pour un etat porte par le serveur ou le JS.
   ========================================================================= */

/* ---------------------------------------------------------------------------
   SOCLE : la vignette
   Une vignette de document repond a trois questions dans cet ordre :
   quel type de fichier, dans quel etat, et quel nom.
   ------------------------------------------------------------------------ */
.doc-vignette {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-md);
  background: var(--c-surface-2);
  overflow: hidden;
}
.doc-vignette svg { width: 34px; height: 34px; }

/* Apercus simules : aucune image n'est chargee, tout est peint en CSS.
   Dans un vrai projet, remplacer par <img src="..." alt="..." loading="lazy">. */
.doc-photo { background-size: cover; background-position: center; }
.doc-photo--1 { background-image: linear-gradient(160deg, #4a6fa5 0%, #7ba3c9 45%, #c9d9e8 100%); }
.doc-photo--2 { background-image: linear-gradient(160deg, #a8643c 0%, #d49a63 50%, #f0d9b5 100%); }
.doc-photo--3 { background-image: linear-gradient(160deg, #3d6b4f 0%, #6ba37c 50%, #c3ddc9 100%); }
.doc-photo--4 { background-image: linear-gradient(160deg, #6b4a72 0%, #a1789f 50%, #ddc9dc 100%); }
.doc-photo--5 { background-image: linear-gradient(160deg, #8a3b3b 0%, #c07070 50%, #e8c4c4 100%); }
.doc-photo--6 { background-image: linear-gradient(160deg, #35485c 0%, #66808f 50%, #b9c6cd 100%); }

/* Apercu de page : un feuillet blanc et des lignes de texte simulees. */
.doc-page {
  width: 100%;
  height: 100%;
  padding: 14% 16%;
  background: #fff;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.06);
  display: flex;
  flex-direction: column;
  gap: 7%;
}
.doc-page::before {
  content: "";
  height: 10%;
  width: 55%;
  border-radius: 2px;
  background: #cbd2dc;
}
.doc-page__lignes {
  flex: 1;
  background: repeating-linear-gradient(#e4e8ee 0 8%, transparent 8% 16%);
  border-radius: 1px;
}
.doc-page--rouge::before { background: #e8453c; }

/* ===========================================================================
   FAMILLE A  -  GRILLES DE VIGNETTES
   ======================================================================== */

/* @v DOC-A1
@nom Grille de photos
@usage Photos de chantier, avant / apres, plans. La grille se resserre toute seule : aucune media query a ecrire.
@html
<div class="doc-grille">
  <figure class="doc-carte"><div class="doc-vignette doc-photo doc-photo--1"></div><figcaption>Facade avant travaux</figcaption></figure>
  <figure class="doc-carte"><div class="doc-vignette doc-photo doc-photo--2"></div><figcaption>Combles isolation</figcaption></figure>
  <figure class="doc-carte"><div class="doc-vignette doc-photo doc-photo--3"></div><figcaption>Local technique</figcaption></figure>
  <figure class="doc-carte"><div class="doc-vignette doc-photo doc-photo--4"></div><figcaption>Groupe exterieur</figcaption></figure>
</div>
@tw grid grid-cols-[repeat(auto-fill,minmax(150px,1fr))] gap-3
@end */
.doc-grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--sp-3);
  width: 100%;
}
.doc-carte { margin: 0; display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; }
.doc-carte figcaption {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--c-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* @endv */

/* @v DOC-A2
@nom Grille de documents
@usage Devis, factures, attestations. L'apercu de la premiere page vaut mieux qu'une icone : on reconnait un document a sa mise en page.
@html
<div class="doc-grille">
  <a href="#" class="doc-carte doc-carte--lien">
    <div class="doc-vignette"><div class="doc-page doc-page--rouge"><div class="doc-page__lignes"></div></div></div>
    <span class="doc-carte__nom">Devis LTP-2026-103.pdf</span>
    <span class="doc-carte__meta">248 Ko - 12 aout</span>
  </a>
  <a href="#" class="doc-carte doc-carte--lien">
    <div class="doc-vignette"><div class="doc-page"><div class="doc-page__lignes"></div></div></div>
    <span class="doc-carte__nom">Attestation TVA 5,5.pdf</span>
    <span class="doc-carte__meta">96 Ko - 12 aout</span>
  </a>
  <a href="#" class="doc-carte doc-carte--lien">
    <div class="doc-vignette">{{icon:f-xls}}</div>
    <span class="doc-carte__nom">Recensement BAR-TH-174.xlsx</span>
    <span class="doc-carte__meta">1,2 Mo - 3 sept.</span>
  </a>
</div>
@tw group block rounded-lg p-2 hover:bg-slate-50 [&_figcaption]:truncate
@end */
.doc-carte--lien {
  text-decoration: none;
  color: inherit;
  padding: var(--sp-2);
  margin: calc(var(--sp-2) * -1);
  border-radius: var(--r-md);
  transition: background-color var(--t-fast);
}
.doc-carte--lien:hover { background: var(--c-surface-2); }
.doc-carte--lien:focus-visible { outline: 2px solid var(--c-focus); outline-offset: 2px; }
.doc-carte__nom {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
  color: var(--c-text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.doc-carte__meta { font-size: var(--fs-xs); color: var(--c-text-muted); }
/* @endv */

/* @v DOC-A3
@nom Vignette avec statut
@usage Quand l'etat compte autant que le fichier : signe, en attente, refuse. La pastille porte un mot, pas seulement une couleur.
@html
<div class="doc-grille">
  <figure class="doc-carte">
    <div class="doc-vignette"><div class="doc-page doc-page--rouge"><div class="doc-page__lignes"></div></div>
      <span class="doc-etat doc-etat--ok">Signe</span></div>
    <figcaption>Devis LTP-2026-103</figcaption>
  </figure>
  <figure class="doc-carte">
    <div class="doc-vignette"><div class="doc-page"><div class="doc-page__lignes"></div></div>
      <span class="doc-etat doc-etat--attente">En attente</span></div>
    <figcaption>Mandat MaPrimeRenov</figcaption>
  </figure>
  <figure class="doc-carte">
    <div class="doc-vignette"><div class="doc-page"><div class="doc-page__lignes"></div></div>
      <span class="doc-etat doc-etat--ko">Refuse</span></div>
    <figcaption>Avis d'imposition</figcaption>
  </figure>
</div>
@tw absolute left-2 top-2 rounded-full px-2 py-0.5 text-[11px] font-bold
@end */
.doc-etat {
  position: absolute;
  top: var(--sp-2);
  left: var(--sp-2);
  padding: 3px 8px;
  border-radius: var(--r-full);
  font-size: 11px;
  font-weight: var(--fw-bold);
  letter-spacing: .01em;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.doc-etat--ok      { background: var(--c-success); color: #fff; }
.doc-etat--attente { background: var(--c-warn);    color: #fff; }
.doc-etat--ko      { background: var(--c-danger);  color: #fff; }
.doc-etat--info    { background: var(--c-info);    color: #fff; }
/* @endv */

/* @v DOC-A4
@nom Grille avec actions au survol
@usage Les actions n'encombrent pas la grille au repos. Sur mobile, ou il n'y a pas de survol, elles restent visibles en permanence.
@html
<div class="doc-grille">
  <figure class="doc-carte doc-carte--actions">
    <div class="doc-vignette doc-photo doc-photo--1">
      <div class="doc-actions">
        <button class="btn btn--icone btn--verre-sombre btn--sm" aria-label="Agrandir">{{icon:zoom}}</button>
        <button class="btn btn--icone btn--verre-sombre btn--sm" aria-label="Telecharger">{{icon:download}}</button>
        <button class="btn btn--icone btn--verre-sombre btn--sm" aria-label="Supprimer">{{icon:trash}}</button>
      </div>
    </div>
    <figcaption>Facade avant travaux</figcaption>
  </figure>
  <figure class="doc-carte doc-carte--actions is-ouvert">
    <div class="doc-vignette doc-photo doc-photo--3">
      <div class="doc-actions">
        <button class="btn btn--icone btn--verre-sombre btn--sm" aria-label="Agrandir">{{icon:zoom}}</button>
        <button class="btn btn--icone btn--verre-sombre btn--sm" aria-label="Telecharger">{{icon:download}}</button>
        <button class="btn btn--icone btn--verre-sombre btn--sm" aria-label="Supprimer">{{icon:trash}}</button>
      </div>
    </div>
    <figcaption>Local technique</figcaption>
  </figure>
</div>
@tw opacity-0 transition group-hover:opacity-100 max-md:opacity-100
@end */
.doc-actions {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: var(--sp-2);
  background: linear-gradient(transparent, rgba(0,0,0,.55));
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--t-base), transform var(--t-base);
}
.doc-carte--actions:hover .doc-actions,
.doc-carte--actions:focus-within .doc-actions { opacity: 1; transform: translateY(0); }
/* Sans survol (tactile), les actions restent visibles : sinon elles sont perdues. */
@media (hover: none) {
  .doc-actions { opacity: 1; transform: none; }
}
/* is-ouvert force l'affichage, pour une demonstration ou un mode edition. */
.doc-carte--actions.is-ouvert .doc-actions { opacity: 1; transform: none; }
/* @endv */

/* @v DOC-A5
@nom Grille selectionnable
@usage Selection multiple pour une action de masse. La case reste affichee des qu'un element est coche, sinon on ne sait plus ou on en est.
@html
<div class="doc-grille">
  <label class="doc-carte doc-carte--select is-choisi">
    <input type="checkbox" checked>
    <div class="doc-vignette doc-photo doc-photo--2"><span class="doc-case"></span></div>
    <span class="doc-carte__nom">Combles isolation</span>
  </label>
  <label class="doc-carte doc-carte--select">
    <input type="checkbox">
    <div class="doc-vignette doc-photo doc-photo--4"><span class="doc-case"></span></div>
    <span class="doc-carte__nom">Groupe exterieur</span>
  </label>
  <label class="doc-carte doc-carte--select is-choisi">
    <input type="checkbox" checked>
    <div class="doc-vignette doc-photo doc-photo--6"><span class="doc-case"></span></div>
    <span class="doc-carte__nom">Tableau electrique</span>
  </label>
</div>
@tw has-[:checked]:ring-2 has-[:checked]:ring-blue-600
@end */
.doc-carte--select { cursor: pointer; }
.doc-carte--select input { position: absolute; opacity: 0; width: 0; height: 0; }
.doc-carte--select .doc-vignette { transition: box-shadow var(--t-fast); }
.doc-case {
  position: absolute;
  top: var(--sp-2); right: var(--sp-2);
  width: 22px; height: 22px;
  border-radius: var(--r-full);
  border: 2px solid #fff;
  background: rgba(0,0,0,.25);
  box-shadow: 0 1px 4px rgba(0,0,0,.3);
  opacity: 0;
  transition: opacity var(--t-fast), background-color var(--t-fast);
}
.doc-carte--select:hover .doc-case,
.doc-carte--select:has(input:checked) .doc-case { opacity: 1; }
.doc-carte--select:has(input:checked) .doc-case { background: var(--c-primary); }
.doc-carte--select:has(input:checked) .doc-case::after {
  content: "";
  position: absolute;
  top: 4px; left: 6.5px;
  width: 4px; height: 8px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.doc-carte--select:has(input:checked) .doc-vignette { box-shadow: 0 0 0 3px var(--c-primary); }
.doc-carte--select input:focus-visible ~ .doc-vignette { outline: 2px solid var(--c-focus); outline-offset: 3px; }
/* @endv */

/* @v DOC-A6
@nom Grille par sections
@usage Le classement automatique par categorie : chaque section porte son compte et se replie. Evite le mur de 200 vignettes.
@html
<details class="doc-section" open>
  <summary>Photos avant travaux <span class="doc-section__compte">4</span></summary>
  <div class="doc-grille">
    <figure class="doc-carte"><div class="doc-vignette doc-photo doc-photo--1"></div><figcaption>Facade</figcaption></figure>
    <figure class="doc-carte"><div class="doc-vignette doc-photo doc-photo--6"></div><figcaption>Toiture</figcaption></figure>
  </div>
</details>
<details class="doc-section">
  <summary>Documents administratifs <span class="doc-section__compte">7</span></summary>
  <div class="doc-grille">
    <figure class="doc-carte"><div class="doc-vignette"><div class="doc-page doc-page--rouge"><div class="doc-page__lignes"></div></div></div><figcaption>Devis</figcaption></figure>
  </div>
</details>
@tw [&>summary]:flex [&>summary]:cursor-pointer [&>summary]:items-center [&>summary]:gap-2 [&>summary]:py-2 [&>summary]:font-semibold
@end */
.doc-section { width: 100%; border-bottom: 1px solid var(--c-border); }
.doc-section > summary {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-semi);
  color: var(--c-text);
  cursor: pointer;
  list-style: none;
}
.doc-section > summary::-webkit-details-marker { display: none; }
.doc-section > summary::before {
  content: "";
  width: 7px; height: 7px;
  border-right: 2px solid var(--c-text-muted);
  border-bottom: 2px solid var(--c-text-muted);
  transform: rotate(-45deg);
  transition: transform var(--t-base);
}
.doc-section[open] > summary::before { transform: rotate(45deg); }
.doc-section__compte {
  min-width: 20px;
  padding: 2px 7px;
  border-radius: var(--r-full);
  background: var(--c-surface-3);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  color: var(--c-text-soft);
}
.doc-section > .doc-grille { padding-bottom: var(--sp-4); }
/* @endv */

/* @v DOC-A7
@nom Mosaique irreguliere
@usage Galerie de realisations d'un site vitrine, ou les proportions varient. Le premier element occupe deux colonnes.
@html
<div class="doc-mosaique">
  <figure class="doc-carte doc-carte--large"><div class="doc-vignette doc-photo doc-photo--1"></div></figure>
  <figure class="doc-carte"><div class="doc-vignette doc-photo doc-photo--2"></div></figure>
  <figure class="doc-carte"><div class="doc-vignette doc-photo doc-photo--3"></div></figure>
  <figure class="doc-carte"><div class="doc-vignette doc-photo doc-photo--4"></div></figure>
  <figure class="doc-carte doc-carte--haute"><div class="doc-vignette doc-photo doc-photo--5"></div></figure>
</div>
@tw grid grid-cols-4 gap-2 [&>*:first-child]:col-span-2 [&>*:first-child]:row-span-2
@end */
.doc-mosaique {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 110px;
  gap: var(--sp-2);
  width: 100%;
}
.doc-mosaique .doc-carte { height: 100%; }
.doc-mosaique .doc-vignette { aspect-ratio: auto; height: 100%; }
.doc-carte--large { grid-column: span 2; grid-row: span 2; }
.doc-carte--haute { grid-row: span 2; }
@media (max-width: 560px) {
  .doc-mosaique { grid-template-columns: repeat(2, 1fr); }
  .doc-carte--large { grid-column: span 2; grid-row: span 1; }
}
/* @endv */

/* Bascule grille -> liste : une seule colonne, vignette reduite a gauche.
   Le meme balisage sert aux deux vues, c'est tout l'interet. */
.doc-grille--liste { grid-template-columns: 1fr; gap: 0; }
.doc-grille--liste .doc-carte {
  flex-direction: row;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-bottom: 1px solid var(--c-border);
}
.doc-grille--liste .doc-vignette { width: 48px; aspect-ratio: 1; flex: none; border-radius: var(--r-sm); }
.doc-grille--liste .doc-vignette svg { width: 22px; height: 22px; }
.doc-grille--liste figcaption,
.doc-grille--liste .doc-carte__nom { flex: 1; }
.doc-grille--liste .doc-actions,
.doc-grille--liste .doc-etat { display: none; }

/* ===========================================================================
   FAMILLE B  -  LISTES ET TABLEAUX
   ======================================================================== */

/* @v DOC-B1
@nom Liste simple
@usage Pieces jointes d'un devis, d'un courriel, d'une fiche. Le type de fichier est porte par l'icone, pas par l'extension du nom.
@html
<ul class="doc-liste">
  <li><a href="#">{{icon:f-pdf}}<span class="doc-liste__nom">Devis LTP-2026-103.pdf</span><span class="doc-liste__taille">248 Ko</span>{{icon:download}}</a></li>
  <li><a href="#">{{icon:f-img}}<span class="doc-liste__nom">Photo avant travaux.jpg</span><span class="doc-liste__taille">1,8 Mo</span>{{icon:download}}</a></li>
  <li><a href="#">{{icon:f-xls}}<span class="doc-liste__nom">Recensement BAR-TH-174.xlsx</span><span class="doc-liste__taille">1,2 Mo</span>{{icon:download}}</a></li>
</ul>
@tw divide-y rounded-lg border [&_a]:flex [&_a]:items-center [&_a]:gap-3 [&_a]:p-3 hover:[&_a]:bg-slate-50
@end */
.doc-liste { list-style: none; margin: 0; padding: 0; width: 100%; border: 1px solid var(--c-border); border-radius: var(--r-md); overflow: hidden; background: var(--c-surface); }
.doc-liste > li + li { border-top: 1px solid var(--c-border); }
.doc-liste a, .doc-liste > li > .doc-liste__ligne {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3);
  text-decoration: none;
  color: var(--c-text);
  transition: background-color var(--t-fast);
}
.doc-liste a:hover { background: var(--c-surface-2); }
.doc-liste a:focus-visible { outline: 2px solid var(--c-focus); outline-offset: -2px; }
.doc-liste svg { width: 24px; height: 24px; flex: none; }
.doc-liste a > svg:last-child { width: 18px; height: 18px; color: var(--c-text-muted); }
.doc-liste__nom { flex: 1; min-width: 0; font-size: var(--fs-md); font-weight: var(--fw-medium); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-liste__taille { font-size: var(--fs-xs); color: var(--c-text-muted); white-space: nowrap; }
/* @endv */

/* @v DOC-B2
@nom Liste detaillee
@usage Le mode par defaut d'un CRM. Deux lignes par fichier : le nom, puis les metadonnees qui servent a le retrouver.
@html
<ul class="doc-liste doc-liste--detail">
  <li><a href="#">{{icon:f-pdf}}
    <span class="doc-liste__bloc"><strong>Devis LTP-2026-103.pdf</strong><small>Ajoute par Julien K. - 12 aout 2026 - 248 Ko</small></span>
    <span class="doc-etiq doc-etiq--ok">Signe</span>
    <button class="btn btn--icone btn--fantome btn--sm" aria-label="Actions">{{icon:chevron-down}}</button>
  </a></li>
  <li><a href="#">{{icon:f-doc}}
    <span class="doc-liste__bloc"><strong>Mandat MaPrimeRenov.docx</strong><small>Ajoute par Sophie M. - 9 aout 2026 - 84 Ko</small></span>
    <span class="doc-etiq doc-etiq--attente">A signer</span>
    <button class="btn btn--icone btn--fantome btn--sm" aria-label="Actions">{{icon:chevron-down}}</button>
  </a></li>
</ul>
@tw [&_strong]:block [&_small]:text-xs [&_small]:text-slate-500
@end */
.doc-liste__bloc { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.doc-liste__bloc strong { font-size: var(--fs-md); font-weight: var(--fw-semi); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-liste__bloc small  { font-size: var(--fs-xs); color: var(--c-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-etiq {
  padding: 3px 9px;
  border-radius: var(--r-full);
  font-size: 11px;
  font-weight: var(--fw-bold);
  white-space: nowrap;
}
.doc-etiq--ok      { background: var(--c-success-soft); color: var(--c-success); }
.doc-etiq--attente { background: var(--c-warn-soft);    color: var(--c-warn); }
.doc-etiq--ko      { background: var(--c-danger-soft);  color: var(--c-danger); }
.doc-etiq--neutre  { background: var(--c-surface-3);    color: var(--c-text-soft); }
/* @endv */

/* @v DOC-B3
@nom Tableau de documents
@usage Volume important, tri par colonne, selection multiple. Sur mobile le tableau bascule en cartes plutot que de defiler.
@html
<table class="doc-table">
  <thead><tr>
    <th class="doc-table__case"><label class="coche"><input type="checkbox"><span class="coche__boite"></span></label></th>
    <th>Document</th><th>Type</th><th>Ajoute le</th><th>Taille</th><th></th>
  </tr></thead>
  <tbody>
    <tr>
      <td class="doc-table__case"><label class="coche"><input type="checkbox" checked><span class="coche__boite"></span></label></td>
      <td data-col="Document"><span class="doc-table__nom">{{icon:f-pdf}} Devis LTP-2026-103.pdf</span></td>
      <td data-col="Type">Devis</td><td data-col="Ajoute le">12/08/2026</td><td data-col="Taille">248 Ko</td>
      <td><button class="btn btn--icone btn--fantome btn--sm" aria-label="Telecharger">{{icon:download}}</button></td>
    </tr>
    <tr>
      <td class="doc-table__case"><label class="coche"><input type="checkbox"><span class="coche__boite"></span></label></td>
      <td data-col="Document"><span class="doc-table__nom">{{icon:f-img}} Photo toiture.jpg</span></td>
      <td data-col="Type">Photo</td><td data-col="Ajoute le">09/08/2026</td><td data-col="Taille">1,8 Mo</td>
      <td><button class="btn btn--icone btn--fantome btn--sm" aria-label="Telecharger">{{icon:download}}</button></td>
    </tr>
  </tbody>
</table>
@tw w-full text-sm [&_th]:px-3 [&_th]:py-2 [&_th]:text-left [&_td]:px-3 [&_td]:py-2 [&_tbody_tr]:border-t
@end */
.doc-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--r-md); overflow: hidden; }
.doc-table th {
  padding: var(--sp-2) var(--sp-3);
  text-align: left;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--c-text-muted);
  background: var(--c-surface-2);
  border-bottom: 1px solid var(--c-border);
  white-space: nowrap;
}
.doc-table td { padding: var(--sp-2) var(--sp-3); color: var(--c-text); vertical-align: middle; }
.doc-table tbody tr + tr td { border-top: 1px solid var(--c-border); }
.doc-table tbody tr:hover { background: var(--c-surface-2); }
.doc-table tbody tr:has(input:checked) { background: var(--c-primary-soft); }
.doc-table__case { width: 40px; }
.doc-table__nom { display: inline-flex; align-items: center; gap: var(--sp-2); font-weight: var(--fw-medium); }
.doc-table__nom svg { width: 20px; height: 20px; flex: none; }
/* Sous 640 px le tableau devient une pile de cartes : chaque cellule affiche
   son intitule de colonne. Aucun defilement horizontal. */
@media (max-width: 640px) {
  .doc-table thead { display: none; }
  .doc-table, .doc-table tbody, .doc-table tr, .doc-table td { display: block; width: 100%; }
  .doc-table tr { border: 1px solid var(--c-border); border-radius: var(--r-md); margin-bottom: var(--sp-2); padding: var(--sp-2); }
  .doc-table tbody tr + tr td { border-top: none; }
  .doc-table td { display: flex; justify-content: space-between; gap: var(--sp-3); padding: 4px 0; }
  .doc-table td::before { content: attr(data-col); font-size: var(--fs-xs); color: var(--c-text-muted); font-weight: var(--fw-semi); }
  .doc-table td:not([data-col])::before { content: none; }
}
/* @endv */

/* @v DOC-B4
@nom Liste groupee par date
@usage Flux d'ajouts recents, journal d'un dossier. Les intitules restent colles en haut pendant le defilement.
@html
<div class="doc-journal">
  <h4>Aujourd'hui</h4>
  <ul class="doc-liste">
    <li><a href="#">{{icon:f-pdf}}<span class="doc-liste__nom">Facture LTP-2026-118.pdf</span><span class="doc-liste__taille">14:32</span></a></li>
    <li><a href="#">{{icon:f-img}}<span class="doc-liste__nom">Photo apres pose.jpg</span><span class="doc-liste__taille">11:05</span></a></li>
  </ul>
  <h4>Hier</h4>
  <ul class="doc-liste">
    <li><a href="#">{{icon:f-doc}}<span class="doc-liste__nom">Compte rendu visite.docx</span><span class="doc-liste__taille">17:48</span></a></li>
  </ul>
</div>
@tw [&>h4]:sticky [&>h4]:top-0 [&>h4]:bg-white [&>h4]:py-2 [&>h4]:text-xs [&>h4]:uppercase
@end */
.doc-journal { width: 100%; display: flex; flex-direction: column; gap: var(--sp-2); }
.doc-journal h4 {
  position: sticky;
  top: 0;
  z-index: 2;
  margin: var(--sp-3) 0 0;
  padding: var(--sp-2) 0;
  background: var(--c-surface);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--c-text-muted);
}
.doc-journal h4:first-child { margin-top: 0; }
/* @endv */

/* @v DOC-B5
@nom Arborescence
@usage Navigation dans des dossiers imbriques. Les <details> natifs suffisent : pas une ligne de JavaScript, et le clavier fonctionne d'office.
@html
<div class="doc-arbre">
  <details open>
    <summary>{{icon:dossier}} Dossier 2026-103 <span class="doc-section__compte">12</span></summary>
    <details open>
      <summary>{{icon:dossier}} Administratif <span class="doc-section__compte">5</span></summary>
      <a href="#">{{icon:f-pdf}} Devis signe.pdf</a>
      <a href="#">{{icon:f-pdf}} Attestation TVA.pdf</a>
    </details>
    <details>
      <summary>{{icon:dossier}} Photos chantier <span class="doc-section__compte">7</span></summary>
      <a href="#">{{icon:f-img}} Avant travaux.jpg</a>
    </details>
    <a href="#">{{icon:f-xls}} Recensement.xlsx</a>
  </details>
</div>
@tw [&_details]:pl-4 [&_summary]:cursor-pointer [&_a]:flex [&_a]:gap-2 [&_a]:py-1
@end */
.doc-arbre { width: 100%; font-size: var(--fs-sm); }
.doc-arbre details { padding-left: var(--sp-4); }
.doc-arbre > details { padding-left: 0; }
.doc-arbre summary {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 5px var(--sp-2);
  border-radius: var(--r-sm);
  font-weight: var(--fw-semi);
  color: var(--c-text);
  cursor: pointer;
  list-style: none;
}
.doc-arbre summary::-webkit-details-marker { display: none; }
.doc-arbre summary:hover { background: var(--c-surface-2); }
.doc-arbre summary svg { width: 17px; height: 17px; color: var(--c-warn); flex: none; }
.doc-arbre a {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 5px var(--sp-2) 5px var(--sp-6);
  border-radius: var(--r-sm);
  color: var(--c-text-soft);
  text-decoration: none;
}
.doc-arbre a:hover { background: var(--c-surface-2); color: var(--c-text); }
.doc-arbre a svg { width: 17px; height: 17px; flex: none; }
/* @endv */

/* @v DOC-B6
@nom Fil d'Ariane de dossiers
@usage Se situer dans l'arborescence et remonter d'un cran. Le dernier element n'est pas un lien : c'est la position courante.
@html
<nav class="doc-fil" aria-label="Chemin">
  <a href="#">{{icon:dossier}} Documents</a>{{icon:chevron-right}}
  <a href="#">Dossier 2026-103</a>{{icon:chevron-right}}
  <a href="#">Photos chantier</a>{{icon:chevron-right}}
  <span aria-current="page">Avant travaux</span>
</nav>
@tw flex flex-wrap items-center gap-1 text-sm [&_svg]:h-3.5 [&_svg]:text-slate-400
@end */
.doc-fil { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1); font-size: var(--fs-sm); }
.doc-fil a {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px var(--sp-2);
  border-radius: var(--r-sm);
  color: var(--c-text-soft);
  text-decoration: none;
}
.doc-fil a:hover { background: var(--c-surface-2); color: var(--c-text); }
.doc-fil > svg { width: 14px; height: 14px; color: var(--c-text-muted); flex: none; }
.doc-fil a svg { width: 15px; height: 15px; color: var(--c-warn); }
.doc-fil [aria-current] { padding: 3px var(--sp-2); font-weight: var(--fw-semi); color: var(--c-text); }
/* @endv */

/* @v DOC-B7
@nom Bascule grille / liste
@usage Le meme jeu de fichiers, deux presentations. Le choix se retient d'une visite a l'autre, sinon l'utilisateur le refait a chaque fois.
@html
<div class="doc-barre-vue">
  <span class="doc-barre-vue__compte">12 documents</span>
  <div class="btn-segmente">
    <button class="btn is-actif" aria-label="Vue grille">{{icon:grille}}</button>
    <button class="btn" aria-label="Vue liste">{{icon:liste}}</button>
  </div>
</div>
@tw flex items-center justify-between gap-3 border-b pb-3
@end */
.doc-barre-vue {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  width: 100%;
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--c-border);
}
.doc-barre-vue__compte { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--c-text-soft); }
.doc-barre-vue .btn-segmente > .btn { padding: 0 var(--sp-3); }
.doc-barre-vue .btn-segmente svg { width: 17px; height: 17px; }
/* @endv */

/* ===========================================================================
   FAMILLE C  -  DEPOT ET TELEVERSEMENT
   Quatre etats par fichier, sans exception : en attente, en cours, termine,
   en erreur. Un depot qui ne montre que "chargement" fait recharger la page.
   ======================================================================== */

/* @v DOC-C1
@nom Zone de depot
@usage La forme complete : icone, phrase d'action, contraintes, et une porte de sortie cliquable. Tout le monde ne glisse pas des fichiers.
@html
<label class="doc-depot">
  {{icon:upload}}
  <strong>Glissez vos documents ici</strong>
  <span>ou <u>parcourez vos fichiers</u></span>
  <small>PDF, JPG, PNG - 10 Mo par fichier - 20 fichiers maximum</small>
  <input type="file" multiple hidden>
</label>
@tw flex w-full flex-col items-center gap-2 rounded-xl border-2 border-dashed p-10 hover:border-blue-500 hover:bg-blue-50/50
@end */
.doc-depot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: var(--sp-10) var(--sp-6);
  border: 2px dashed var(--c-border-strong);
  border-radius: var(--r-lg);
  background: var(--c-surface-2);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--t-fast), background-color var(--t-fast);
}
.doc-depot svg { width: 34px; height: 34px; color: var(--c-text-muted); margin-bottom: var(--sp-1); }
.doc-depot strong { font-size: var(--fs-lg); font-weight: var(--fw-semi); color: var(--c-text); }
.doc-depot span   { font-size: var(--fs-md); color: var(--c-text-soft); }
.doc-depot u      { color: var(--c-primary-ink); text-underline-offset: 3px; }
.doc-depot small  { font-size: var(--fs-xs); color: var(--c-text-muted); margin-top: var(--sp-2); }
.doc-depot:hover, .doc-depot.is-survol {
  border-color: var(--c-primary);
  background: var(--c-primary-soft);
}
.doc-depot:hover svg, .doc-depot.is-survol svg { color: var(--c-primary); }
.doc-depot:has(input:focus-visible) { outline: 2px solid var(--c-focus); outline-offset: 3px; }
/* @endv */

/* @v DOC-C2
@nom Depot compact
@usage Quand la zone pleine hauteur prendrait trop de place : formulaire long, panneau lateral, ligne de tableau.
@html
<label class="doc-depot doc-depot--compact">
  {{icon:upload}} <strong>Ajouter un fichier</strong> <span>ou glissez-le ici</span>
  <input type="file" hidden>
</label>
@tw flex-row items-center justify-center gap-2 p-4
@end */
.doc-depot--compact {
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: var(--sp-4);
  border-width: 1.5px;
}
.doc-depot--compact svg { width: 20px; height: 20px; margin: 0; }
.doc-depot--compact strong { font-size: var(--fs-md); }
.doc-depot--compact span { font-size: var(--fs-sm); color: var(--c-text-muted); }
/* @endv */

/* @v DOC-C3
@nom File d'envoi
@usage Les quatre etats reunis. Chaque ligne garde son bouton d'annulation ou de reprise : un envoi qui echoue sans recours fait tout recommencer.
@html
<ul class="doc-file">
  <li class="doc-file__ligne is-fait">
    {{icon:f-pdf}}
    <span class="doc-liste__bloc"><strong>Devis signe.pdf</strong><small>248 Ko - envoye</small></span>
    <span class="doc-file__ok">{{icon:check}}</span>
    <button class="btn btn--icone btn--fantome btn--sm" aria-label="Retirer">{{icon:x}}</button>
  </li>
  <li class="doc-file__ligne is-encours" style="--p: 64%">
    {{icon:f-img}}
    <span class="doc-liste__bloc"><strong>Photo toiture.jpg</strong><small>1,8 Mo - 64 %</small><span class="doc-file__barre"></span></span>
    <button class="btn btn--icone btn--fantome btn--sm" aria-label="Annuler l'envoi">{{icon:x}}</button>
  </li>
  <li class="doc-file__ligne is-attente">
    {{icon:f-img}}
    <span class="doc-liste__bloc"><strong>Photo facade.jpg</strong><small>2,1 Mo - en attente</small></span>
    <button class="btn btn--icone btn--fantome btn--sm" aria-label="Retirer">{{icon:x}}</button>
  </li>
  <li class="doc-file__ligne is-erreur">
    {{icon:f-zip}}
    <span class="doc-liste__bloc"><strong>Archive photos.zip</strong><small>Fichier trop volumineux (42 Mo)</small></span>
    <button class="btn btn--secondaire btn--dense">Reessayer</button>
    <button class="btn btn--icone btn--fantome btn--sm" aria-label="Retirer">{{icon:x}}</button>
  </li>
</ul>
@tw [&_li]:flex [&_li]:items-center [&_li]:gap-3 [&_li]:rounded-lg [&_li]:border [&_li]:p-3
@end */
.doc-file { list-style: none; margin: 0; padding: 0; width: 100%; display: flex; flex-direction: column; gap: var(--sp-2); }
.doc-file__ligne {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3);
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  background: var(--c-surface);
}
.doc-file__ligne > svg:first-child { width: 24px; height: 24px; flex: none; }
.doc-file__barre {
  display: block;
  height: 4px;
  margin-top: 6px;
  border-radius: var(--r-full);
  background: var(--c-surface-3);
  overflow: hidden;
}
.doc-file__barre::after {
  content: "";
  display: block;
  height: 100%;
  width: var(--p, 0%);
  border-radius: inherit;
  background: var(--c-primary);
  transition: width var(--t-slow);
}
.doc-file__ok { display: inline-flex; color: var(--c-success); }
.doc-file__ok svg { width: 20px; height: 20px; }
.doc-file__ligne.is-attente { opacity: .62; }
.doc-file__ligne.is-erreur  { border-color: var(--c-danger); background: var(--c-danger-soft); }
.doc-file__ligne.is-erreur small { color: var(--c-danger); font-weight: var(--fw-semi); }
.doc-file__ligne.is-fait    { border-color: var(--c-success); }
/* @endv */

/* @v DOC-C4
@nom Progression globale
@usage Au-dessus de la file : un seul chiffre qui repond a "c'est bientot fini ?". Sans lui, l'utilisateur quitte la page en plein envoi.
@html
<div class="doc-progres">
  <div class="doc-progres__tete"><strong>Envoi de 3 fichiers</strong><span>2 sur 3 - 4,2 Mo sur 6,1 Mo</span></div>
  <div class="doc-progres__barre" style="--p: 68%"></div>
  <button class="btn btn--secondaire btn--dense">Tout annuler</button>
</div>
@tw flex items-center gap-4 rounded-lg border bg-white p-4
@end */
.doc-progres {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  width: 100%;
  padding: var(--sp-4);
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  background: var(--c-surface);
}
.doc-progres__tete { display: flex; flex-direction: column; gap: 2px; min-width: 130px; flex: none; }
.doc-progres__tete strong { font-size: var(--fs-md); font-weight: var(--fw-semi); }
.doc-progres__tete span   { font-size: var(--fs-xs); color: var(--c-text-muted); }
.doc-progres__barre {
  flex: 1 1 90px;
  min-width: 70px;
  height: 8px;
  border-radius: var(--r-full);
  background: var(--c-surface-3);
  overflow: hidden;
}
.doc-progres__barre::after {
  content: "";
  display: block;
  height: 100%;
  width: var(--p, 0%);
  border-radius: inherit;
  background: linear-gradient(90deg, var(--c-primary), var(--c-accent));
  transition: width var(--t-slow);
}
@media (max-width: 560px) { .doc-progres { flex-wrap: wrap; } .doc-progres__barre { order: 3; width: 100%; flex: none; } }
/* @endv */

/* @v DOC-C5
@nom Apercu avant envoi
@usage Confirmer qu'on a pris le bon fichier avant de l'envoyer. La vignette leve l'ambiguite entre IMG_4471 et IMG_4472.
@html
<div class="doc-grille">
  <figure class="doc-carte doc-carte--apercu">
    <div class="doc-vignette doc-photo doc-photo--2">
      <button class="btn btn--icone btn--sm doc-carte__retirer" aria-label="Retirer ce fichier">{{icon:x}}</button>
      <span class="doc-anneau" style="--p: 72"></span>
    </div>
    <span class="doc-carte__nom">IMG_4471.jpg</span>
    <span class="doc-carte__meta">72 % - 1,4 Mo</span>
  </figure>
  <figure class="doc-carte doc-carte--apercu">
    <div class="doc-vignette doc-photo doc-photo--5">
      <button class="btn btn--icone btn--sm doc-carte__retirer" aria-label="Retirer ce fichier">{{icon:x}}</button>
    </div>
    <span class="doc-carte__nom">IMG_4472.jpg</span>
    <span class="doc-carte__meta">Pret a envoyer</span>
  </figure>
</div>
@tw relative + conic-gradient pour l'anneau de progression
@end */
.doc-carte__retirer {
  position: absolute;
  top: 6px; right: 6px;
  width: 24px; height: 24px;
  min-width: 24px;
  padding: 0;
  border-radius: var(--r-full);
  background: rgba(15,18,24,.62);
  color: #fff;
  border: none;
  z-index: 2;
}
.doc-carte__retirer:hover { background: var(--c-danger); }
.doc-carte__retirer svg { width: 13px; height: 13px; }
/* Anneau de progression pose sur la vignette : lisible meme sur photo claire. */
.doc-anneau {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 46px; height: 46px;
  border-radius: 50%;
  background:
    conic-gradient(#fff calc(var(--p) * 1%), rgba(255,255,255,.28) 0),
    rgba(15,18,24,.45);
  -webkit-mask: radial-gradient(circle, transparent 13px, #000 14px);
          mask: radial-gradient(circle, transparent 13px, #000 14px);
}
/* @endv */

/* ===========================================================================
   FAMILLE D  -  PIECES ATTENDUES
   Le dossier a constituer : la liste des pieces est connue d'avance, chacune
   porte un etat. Regle : une piece refusee dit POURQUOI, sinon elle sera
   redeposee a l'identique.
   ======================================================================== */

/* @v DOC-D1
@nom Liste des pieces attendues
@usage Le coeur d'un dossier d'aide ou de financement. Quatre etats : manquante, recue, validee, refusee. L'icone et le mot portent l'etat, jamais la couleur seule.
@html
<ul class="doc-pieces">
  <li class="doc-piece is-validee">
    <span class="doc-piece__puce">{{icon:check}}</span>
    <span class="doc-liste__bloc"><strong>Avis d'imposition 2025</strong><small>Recu le 09/08 - valide par Sophie M.</small></span>
    <button class="btn btn--fantome btn--dense">{{icon:oeil}} Voir</button>
  </li>
  <li class="doc-piece is-recue">
    <span class="doc-piece__puce">{{icon:horloge}}</span>
    <span class="doc-liste__bloc"><strong>Devis signe</strong><small>Recu le 12/08 - en cours de verification</small></span>
    <button class="btn btn--fantome btn--dense">{{icon:oeil}} Voir</button>
  </li>
  <li class="doc-piece is-refusee">
    <span class="doc-piece__puce">{{icon:alerte}}</span>
    <span class="doc-liste__bloc"><strong>Justificatif de domicile</strong><small>Refuse : document de plus de 3 mois</small></span>
    <button class="btn btn--secondaire btn--dense">Redeposer</button>
  </li>
  <li class="doc-piece is-manquante">
    <span class="doc-piece__puce">{{icon:plus}}</span>
    <span class="doc-liste__bloc"><strong>RIB du beneficiaire</strong><small>Obligatoire pour le versement</small></span>
    <button class="btn btn--plein btn--dense">Deposer</button>
  </li>
</ul>
@tw [&_li]:flex [&_li]:items-center [&_li]:gap-3 [&_li]:border-l-4 [&_li]:p-3
@end */
.doc-pieces { list-style: none; margin: 0; padding: 0; width: 100%; display: flex; flex-direction: column; gap: var(--sp-2); }
.doc-piece {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3);
  border: 1px solid var(--c-border);
  border-left-width: 4px;
  border-radius: var(--r-md);
  background: var(--c-surface);
}
.doc-piece__puce {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px; height: 30px;
  flex: none;
  border-radius: var(--r-full);
  background: var(--c-surface-3);
  color: var(--c-text-muted);
}
.doc-piece__puce svg { width: 16px; height: 16px; }
.doc-piece.is-validee   { border-left-color: var(--c-success); }
.doc-piece.is-validee   .doc-piece__puce { background: var(--c-success-soft); color: var(--c-success); }
.doc-piece.is-recue     { border-left-color: var(--c-info); }
.doc-piece.is-recue     .doc-piece__puce { background: var(--c-info-soft); color: var(--c-info); }
.doc-piece.is-refusee   { border-left-color: var(--c-danger); background: var(--c-danger-soft); }
.doc-piece.is-refusee   .doc-piece__puce { background: var(--c-danger); color: #fff; }
.doc-piece.is-refusee   small { color: var(--c-danger); font-weight: var(--fw-semi); }
.doc-piece.is-manquante { border-left-color: var(--c-border-strong); border-style: dashed; }
/* @endv */

/* @v DOC-D2
@nom Cases de pieces en grille
@usage La meme liste en grille, chaque case portant son propre depot. Adapte quand les pieces sont nombreuses et de meme importance.
@html
<div class="doc-cases">
  <label class="doc-case-piece is-remplie">
    <div class="doc-case-piece__apercu"><div class="doc-page doc-page--rouge"><div class="doc-page__lignes"></div></div></div>
    <strong>Devis signe</strong><small>248 Ko - PDF</small>
  </label>
  <label class="doc-case-piece is-remplie">
    <div class="doc-case-piece__apercu doc-photo doc-photo--6"></div>
    <strong>Photo compteur</strong><small>1,1 Mo - JPG</small>
  </label>
  <label class="doc-case-piece">
    <div class="doc-case-piece__apercu">{{icon:plus}}</div>
    <strong>Avis d'imposition</strong><small>Obligatoire</small>
    <input type="file" hidden>
  </label>
  <label class="doc-case-piece">
    <div class="doc-case-piece__apercu">{{icon:plus}}</div>
    <strong>RIB</strong><small>Obligatoire</small>
    <input type="file" hidden>
  </label>
</div>
@tw grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-3 [&_label]:rounded-xl [&_label]:border-2 [&_label]:border-dashed
@end */
.doc-cases {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--sp-3);
  width: 100%;
}
.doc-case-piece {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: var(--sp-3);
  border: 2px dashed var(--c-border-strong);
  border-radius: var(--r-lg);
  background: var(--c-surface-2);
  cursor: pointer;
  transition: border-color var(--t-fast), background-color var(--t-fast);
}
.doc-case-piece__apercu {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
  margin-bottom: var(--sp-1);
  border-radius: var(--r-sm);
  /* background-color et non background : le raccourci effacerait le
     background-image pose par .doc-photo--* sur le meme element. */
  background-color: var(--c-surface-3);
  background-size: cover;
  background-position: center;
  overflow: hidden;
}
.doc-case-piece__apercu svg { width: 26px; height: 26px; color: var(--c-text-muted); }
.doc-case-piece strong { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--c-text); }
.doc-case-piece small  { font-size: var(--fs-xs); color: var(--c-text-muted); }
.doc-case-piece:hover { border-color: var(--c-primary); background: var(--c-primary-soft); }
.doc-case-piece.is-remplie {
  border-style: solid;
  border-color: var(--c-success);
  background: var(--c-surface);
}
/* @endv */

/* @v DOC-D3
@nom Avancement du dossier
@usage En tete de la liste des pieces : combien il en manque, et lesquelles. Un pourcentage seul ne dit pas quoi faire ensuite.
@html
<div class="doc-avancement">
  <div class="doc-avancement__tete">
    <strong>Dossier 2026-103</strong>
    <span class="doc-etiq doc-etiq--attente">2 pieces manquantes</span>
  </div>
  <div class="doc-avancement__jauge"><span style="--p: 66%"></span></div>
  <div class="doc-avancement__pas">
    <span class="is-fait">{{icon:check}} Devis</span>
    <span class="is-fait">{{icon:check}} Avis d'imposition</span>
    <span class="is-fait">{{icon:check}} Photo compteur</span>
    <span>RIB</span>
    <span>Justificatif de domicile</span>
  </div>
</div>
@tw rounded-xl border bg-white p-4 [&_span.is-fait]:bg-green-50 [&_span.is-fait]:text-green-700
@end */
.doc-avancement {
  width: 100%;
  padding: var(--sp-4);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  background: var(--c-surface);
}
.doc-avancement__tete { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); margin-bottom: var(--sp-3); }
.doc-avancement__tete strong { font-size: var(--fs-lg); font-weight: var(--fw-bold); }
.doc-avancement__jauge { height: 8px; border-radius: var(--r-full); background: var(--c-surface-3); overflow: hidden; }
.doc-avancement__jauge span {
  display: block;
  height: 100%;
  width: var(--p, 0%);
  border-radius: inherit;
  background: var(--c-success);
  transition: width var(--t-slow);
}
.doc-avancement__pas { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-3); }
.doc-avancement__pas span {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border-radius: var(--r-full);
  border: 1px dashed var(--c-border-strong);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  color: var(--c-text-muted);
}
.doc-avancement__pas span.is-fait {
  border-style: solid;
  border-color: transparent;
  background: var(--c-success-soft);
  color: var(--c-success);
  font-weight: var(--fw-semi);
}
.doc-avancement__pas svg { width: 13px; height: 13px; }
/* @endv */

/* ===========================================================================
   FAMILLE E  -  CONSULTATION
   ======================================================================== */

/* @v DOC-E1
@nom Visionneuse plein ecran
@usage Ouverture d'une photo depuis la grille. Fermeture par la croix, par Echap et par un clic dans le vide : les trois, toujours.
@html
<div class="doc-visio">
  <div class="doc-visio__barre">
    <span class="doc-visio__titre">Facade avant travaux.jpg <small>3 sur 12</small></span>
    <span class="doc-visio__outils">
      <button class="btn btn--icone btn--verre-sombre btn--sm" aria-label="Pivoter">{{icon:rotation}}</button>
      <button class="btn btn--icone btn--verre-sombre btn--sm" aria-label="Telecharger">{{icon:download}}</button>
      <button class="btn btn--icone btn--verre-sombre btn--sm" aria-label="Fermer">{{icon:x}}</button>
    </span>
  </div>
  <button class="btn btn--icone btn--rond btn--verre-sombre doc-visio__nav doc-visio__nav--g" aria-label="Precedent">{{icon:chevron-left}}</button>
  <div class="doc-visio__image doc-photo doc-photo--1"></div>
  <button class="btn btn--icone btn--rond btn--verre-sombre doc-visio__nav doc-visio__nav--d" aria-label="Suivant">{{icon:chevron-right}}</button>
  <div class="doc-visio__pellicule">
    <span class="doc-photo doc-photo--2"></span><span class="doc-photo doc-photo--3"></span>
    <span class="doc-photo doc-photo--1 is-actif"></span><span class="doc-photo doc-photo--4"></span>
    <span class="doc-photo doc-photo--5"></span><span class="doc-photo doc-photo--6"></span>
  </div>
</div>
@tw fixed inset-0 z-50 flex items-center justify-center bg-black/90
@end */
.doc-visio {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 320px;
  padding: 52px var(--sp-12) 78px;
  border-radius: var(--r-md);
  background: rgba(6,8,12,.94);
  overflow: hidden;
}
.doc-visio__barre {
  position: absolute;
  inset: 0 0 auto 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  background: linear-gradient(rgba(0,0,0,.55), transparent);
}
.doc-visio__titre { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: #fff; }
.doc-visio__titre small { color: rgba(255,255,255,.65); font-weight: var(--fw-normal); margin-left: 6px; }
.doc-visio__outils { display: flex; gap: var(--sp-1); }
.doc-visio__image { width: 100%; max-width: 360px; aspect-ratio: 4 / 3; border-radius: var(--r-sm); box-shadow: 0 12px 40px rgba(0,0,0,.5); }
.doc-visio__nav { position: absolute; top: 50%; transform: translateY(-50%); }
.doc-visio__nav--g { left: var(--sp-3); }
.doc-visio__nav--d { right: var(--sp-3); }
.doc-visio__pellicule {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  gap: var(--sp-2);
  padding: var(--sp-3);
  overflow-x: auto;
  justify-content: center;
}
.doc-visio__pellicule span {
  width: 48px; height: 36px;
  flex: none;
  border-radius: var(--r-xs);
  opacity: .5;
  cursor: pointer;
  transition: opacity var(--t-fast), box-shadow var(--t-fast);
}
.doc-visio__pellicule span:hover { opacity: .8; }
.doc-visio__pellicule span.is-actif { opacity: 1; box-shadow: 0 0 0 2px #fff; }
/* @endv */

/* @v DOC-E2
@nom Panneau de detail
@usage A cote de la grille : l'apercu et les metadonnees du fichier selectionne, sans quitter la liste. Sur mobile, il devient un tiroir du bas.
@html
<aside class="doc-panneau">
  <div class="doc-panneau__apercu doc-photo doc-photo--3"></div>
  <h4>Local technique.jpg</h4>
  <dl class="doc-panneau__infos">
    <dt>Type</dt><dd>Image JPEG</dd>
    <dt>Taille</dt><dd>1,8 Mo - 4032 x 3024</dd>
    <dt>Ajoute le</dt><dd>12 aout 2026 a 14:32</dd>
    <dt>Par</dt><dd>Julien K.</dd>
    <dt>Dossier</dt><dd>2026-103 - Photos chantier</dd>
  </dl>
  <div class="doc-panneau__actions">
    <button class="btn btn--plein btn--bloc">{{icon:download}} Telecharger</button>
    <button class="btn btn--secondaire btn--bloc">{{icon:lien}} Copier le lien</button>
  </div>
</aside>
@tw w-72 shrink-0 rounded-xl border bg-white p-4 [&_dl]:grid [&_dl]:grid-cols-[auto_1fr] [&_dl]:gap-x-3
@end */
.doc-panneau {
  width: 100%;
  max-width: 300px;
  padding: var(--sp-4);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  background: var(--c-surface);
}
.doc-panneau__apercu { aspect-ratio: 4 / 3; border-radius: var(--r-md); margin-bottom: var(--sp-3); }
.doc-panneau h4 { margin: 0 0 var(--sp-3); font-size: var(--fs-md); font-weight: var(--fw-bold); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-panneau__infos {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 7px var(--sp-3);
  margin: 0 0 var(--sp-4);
  font-size: var(--fs-sm);
}
.doc-panneau__infos dt { color: var(--c-text-muted); }
.doc-panneau__infos dd { margin: 0; color: var(--c-text); font-weight: var(--fw-medium); }
.doc-panneau__actions { display: flex; flex-direction: column; gap: var(--sp-2); }
/* @endv */

/* @v DOC-E3
@nom Apercu de document
@usage Lecture d'un PDF sans le telecharger. La barre porte la pagination et le zoom ; le telechargement reste offert, on ne le retire jamais.
@html
<div class="doc-lecteur">
  <div class="doc-lecteur__barre">
    <span>Devis LTP-2026-103.pdf</span>
    <span class="doc-lecteur__pages">
      <button class="btn btn--icone btn--fantome btn--sm" aria-label="Page precedente">{{icon:chevron-left}}</button>
      <em>2 / 4</em>
      <button class="btn btn--icone btn--fantome btn--sm" aria-label="Page suivante">{{icon:chevron-right}}</button>
    </span>
    <button class="btn btn--secondaire btn--dense">{{icon:download}} Telecharger</button>
  </div>
  <div class="doc-lecteur__feuille">
    <div class="doc-page doc-page--rouge"><div class="doc-page__lignes"></div></div>
  </div>
</div>
@tw rounded-xl border bg-slate-100 [&_.feuille]:mx-auto [&_.feuille]:aspect-[1/1.414] [&_.feuille]:bg-white [&_.feuille]:shadow-lg
@end */
.doc-lecteur { width: 100%; border: 1px solid var(--c-border); border-radius: var(--r-lg); overflow: hidden; background: var(--c-surface-3); }
.doc-lecteur__barre {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  background: var(--c-surface);
  border-bottom: 1px solid var(--c-border);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
}
.doc-lecteur__barre > span:first-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.doc-lecteur__pages { display: inline-flex; align-items: center; gap: var(--sp-1); flex: none; }
.doc-lecteur__pages em { font-style: normal; font-size: var(--fs-xs); color: var(--c-text-muted); min-width: 40px; text-align: center; }
.doc-lecteur__feuille { padding: var(--sp-5); display: flex; justify-content: center; }
.doc-lecteur__feuille .doc-page {
  width: 190px;
  aspect-ratio: 1 / 1.414;
  height: auto;
  border-radius: 2px;
  box-shadow: 0 4px 20px rgba(0,0,0,.18);
}
/* @endv */

/* @v DOC-E4
@nom Avant / apres
@usage La preuve de chantier. Le curseur central revele l'une ou l'autre image ; en dessous, deux vignettes cote a cote suffisent souvent.
@html
<div class="doc-avant-apres">
  <div class="doc-avant-apres__cote doc-photo doc-photo--6"><span>Avant</span></div>
  <div class="doc-avant-apres__cote doc-photo doc-photo--3"><span>Apres</span></div>
</div>
@tw grid grid-cols-2 gap-2 [&>div]:relative [&>div]:aspect-[4/3] [&_span]:absolute [&_span]:bottom-2 [&_span]:left-2
@end */
.doc-avant-apres { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); width: 100%; }
.doc-avant-apres__cote { position: relative; aspect-ratio: 4 / 3; border-radius: var(--r-md); overflow: hidden; }
.doc-avant-apres__cote span {
  position: absolute;
  left: var(--sp-2); bottom: var(--sp-2);
  padding: 4px 10px;
  border-radius: var(--r-full);
  background: rgba(10,12,18,.62);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: #fff;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
}
/* @endv */

/* ===========================================================================
   FAMILLE F  -  ETATS ET OUTILS
   Un etat vide sans bouton d'action est un cul-de-sac : il dit ce qui manque
   sans dire quoi faire.
   ======================================================================== */

/* @v DOC-F1
@nom Aucun document
@usage Premiere visite d'un dossier vide. Trois elements obligatoires : ce qui manque, pourquoi c'est utile, et le bouton pour commencer.
@html
<div class="doc-vide">
  {{icon:archive}}
  <strong>Aucun document dans ce dossier</strong>
  <p>Ajoutez le devis, les photos de chantier et les attestations. Le client les retrouvera dans son espace.</p>
  <button class="btn btn--plein">{{icon:upload}} Ajouter des documents</button>
</div>
@tw flex flex-col items-center gap-3 rounded-xl border border-dashed p-10 text-center
@end */
.doc-vide {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  padding: var(--sp-10) var(--sp-6);
  border: 1px dashed var(--c-border-strong);
  border-radius: var(--r-lg);
  background: var(--c-surface);
  text-align: center;
}
.doc-vide > svg { width: 42px; height: 42px; color: var(--c-text-muted); opacity: .7; }
.doc-vide strong { font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--c-text); }
.doc-vide p { margin: 0; max-width: 42ch; font-size: var(--fs-md); color: var(--c-text-soft); line-height: 1.55; }
/* @endv */

/* @v DOC-F2
@nom Aucun resultat
@usage Apres un filtre ou une recherche. Different de F1 : ici il y a des documents, ce sont les criteres qui ne rendent rien. Le bouton efface les filtres.
@html
<div class="doc-vide doc-vide--recherche">
  {{icon:loupe}}
  <strong>Aucun document ne correspond</strong>
  <p>Aucun resultat pour <em>&laquo; attestation 2024 &raquo;</em> avec le filtre <em>Photos</em>.</p>
  <button class="btn btn--secondaire">Effacer les filtres</button>
</div>
@tw idem F1, message centre sur les criteres et non sur le dossier
@end */
.doc-vide--recherche em { font-style: normal; font-weight: var(--fw-semi); color: var(--c-text); }
/* @endv */

/* @v DOC-F3
@nom Chargement
@usage Squelettes calques sur la grille reelle : meme nombre de colonnes, memes proportions. Sinon la page saute a l'arrivee des donnees.
@html
<div class="doc-grille">
  <div class="doc-carte"><div class="doc-vignette doc-squelette"></div><span class="doc-squelette doc-squelette--ligne"></span></div>
  <div class="doc-carte"><div class="doc-vignette doc-squelette"></div><span class="doc-squelette doc-squelette--ligne" style="width:70%"></span></div>
  <div class="doc-carte"><div class="doc-vignette doc-squelette"></div><span class="doc-squelette doc-squelette--ligne" style="width:85%"></span></div>
  <div class="doc-carte"><div class="doc-vignette doc-squelette"></div><span class="doc-squelette doc-squelette--ligne" style="width:60%"></span></div>
</div>
@tw animate-pulse bg-slate-200
@end */
.doc-squelette {
  background: linear-gradient(90deg, var(--c-surface-2) 25%, var(--c-surface-3) 50%, var(--c-surface-2) 75%);
  background-size: 200% 100%;
  animation: doc-scintille 1.4s ease-in-out infinite;
  border-radius: var(--r-md);
}
.doc-squelette--ligne { display: block; height: 12px; width: 100%; border-radius: var(--r-xs); }
@keyframes doc-scintille { to { background-position: -200% 0; } }
/* @endv */

/* @v DOC-F4
@nom Apercu impossible
@usage Format non previsualisable, fichier corrompu, trop volumineux. La ligne reste utilisable : le telechargement, lui, doit rester possible.
@html
<div class="doc-grille">
  <figure class="doc-carte">
    <div class="doc-vignette doc-vignette--erreur">{{icon:alerte}}<span>Apercu indisponible</span></div>
    <span class="doc-carte__nom">Plan technique.dwg</span>
    <span class="doc-carte__meta">4,2 Mo - format non pris en charge</span>
  </figure>
  <figure class="doc-carte">
    <div class="doc-vignette">{{icon:f-zip}}</div>
    <span class="doc-carte__nom">Archive photos.zip</span>
    <span class="doc-carte__meta">42 Mo - 18 fichiers</span>
  </figure>
</div>
@tw flex-col gap-1 bg-slate-100 text-slate-400
@end */
.doc-vignette--erreur {
  flex-direction: column;
  gap: 6px;
  background: var(--c-surface-2);
  color: var(--c-text-muted);
  border: 1px dashed var(--c-border-strong);
}
.doc-vignette--erreur svg { width: 26px; height: 26px; }
.doc-vignette--erreur span { font-size: var(--fs-xs); }
/* @endv */

/* @v DOC-F5
@nom Barre de selection
@usage Apparait des qu'une case est cochee. Elle porte le compte, les actions de masse, et une sortie claire de la selection.
@html
<div class="doc-selection">
  <button class="btn btn--icone btn--fantome btn--sm" aria-label="Annuler la selection">{{icon:x}}</button>
  <strong>4 documents</strong>
  <span class="btn-barre__sep"></span>
  <button class="btn btn--fantome btn--dense">{{icon:download}} Telecharger</button>
  <button class="btn btn--fantome btn--dense">{{icon:dossier}} Deplacer</button>
  <button class="btn btn--fantome btn--dense">{{icon:lien}} Partager</button>
  <span class="btn-barre__sep"></span>
  <button class="btn btn--fantome btn--dense doc-selection__danger">{{icon:trash}} Supprimer</button>
</div>
@tw fixed bottom-6 left-1/2 -translate-x-1/2 flex items-center gap-1 rounded-full border bg-white px-3 py-2 shadow-xl
@end */
.doc-selection {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  padding: 7px var(--sp-3);
  border: 1px solid var(--c-border);
  border-radius: var(--r-full);
  background: var(--c-surface);
  box-shadow: var(--sh-3);
}
.doc-selection strong { font-size: var(--fs-sm); font-weight: var(--fw-bold); padding: 0 var(--sp-2); white-space: nowrap; }
.doc-selection__danger { color: var(--c-danger); }
.doc-selection__danger:hover { background: var(--c-danger-soft); color: var(--c-danger); }
@media (max-width: 560px) { .doc-selection { flex-wrap: wrap; border-radius: var(--r-lg); justify-content: center; } }
/* @endv */

/* @v DOC-F6
@nom Filtres de galerie
@usage Au-dessus de la liste : recherche, type, periode. Les filtres actifs restent affiches en etiquettes retirables, sinon on oublie pourquoi la liste est vide.
@html
<div class="doc-filtres">
  <div class="doc-filtres__ligne">
    <label class="doc-recherche">{{icon:loupe}}<input type="search" placeholder="Rechercher un document"></label>
    <button class="btn btn--secondaire">{{icon:filtre}} Type {{icon:chevron-down}}</button>
    <button class="btn btn--secondaire">{{icon:calendar}} Periode {{icon:chevron-down}}</button>
  </div>
  <div class="doc-filtres__actifs">
    <span class="btn-etiquette btn-etiquette--accent">Photos <button aria-label="Retirer le filtre Photos">{{icon:x}}</button></span>
    <span class="btn-etiquette btn-etiquette--accent">Aout 2026 <button aria-label="Retirer le filtre Aout 2026">{{icon:x}}</button></span>
    <button class="btn btn--texte btn--dense">Tout effacer</button>
  </div>
</div>
@tw flex flex-col gap-3 [&_input]:h-10 [&_input]:w-full [&_input]:rounded-lg [&_input]:border [&_input]:pl-9
@end */
.doc-filtres { display: flex; flex-direction: column; gap: var(--sp-3); width: 100%; }
.doc-filtres__ligne { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.doc-filtres__actifs { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.doc-recherche { position: relative; display: flex; align-items: center; flex: 1; min-width: 190px; }
.doc-recherche svg { position: absolute; left: 11px; width: 17px; height: 17px; color: var(--c-text-muted); pointer-events: none; }
.doc-recherche input {
  width: 100%;
  height: var(--h-md);
  padding: 0 var(--sp-3) 0 36px;
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  background: var(--c-surface);
  color: var(--c-text);
  font-family: var(--font-ui);
  font-size: var(--fs-md);
}
.doc-recherche input::placeholder { color: var(--c-text-muted); }
.doc-recherche input:focus { outline: 2px solid var(--c-focus); outline-offset: -1px; border-color: var(--c-primary); }
/* @endv */

/* ===========================================================================
   FAMILLE G  -  CAS METIER
   Assemblages complets, prets a coller dans un projet.
   ======================================================================== */

/* @v DOC-G1
@nom Documents d'un dossier
@usage L'assemblage type d'une fiche client de CRM : onglets par categorie, compte par onglet, depot toujours accessible.
@html
<div class="doc-bloc">
  <div class="doc-bloc__onglets">
    <button class="btn btn--fantome btn--onglet is-actif">Tous <span class="btn__badge">12</span></button>
    <button class="btn btn--fantome btn--onglet">Devis <span class="btn__badge">3</span></button>
    <button class="btn btn--fantome btn--onglet">Photos <span class="btn__badge">7</span></button>
    <button class="btn btn--fantome btn--onglet">Administratif <span class="btn__badge">2</span></button>
    <span class="cat-head__spacer"></span>
    <button class="btn btn--plein btn--sm">{{icon:plus}} Ajouter</button>
  </div>
  <ul class="doc-liste">
    <li><a href="#">{{icon:f-pdf}}<span class="doc-liste__bloc"><strong>Devis LTP-2026-103.pdf</strong><small>12 aout - 248 Ko</small></span><span class="doc-etiq doc-etiq--ok">Signe</span></a></li>
    <li><a href="#">{{icon:f-img}}<span class="doc-liste__bloc"><strong>Photo toiture.jpg</strong><small>9 aout - 1,8 Mo</small></span><span class="doc-etiq doc-etiq--neutre">Photo</span></a></li>
    <li><a href="#">{{icon:f-doc}}<span class="doc-liste__bloc"><strong>Mandat MaPrimeRenov.docx</strong><small>9 aout - 84 Ko</small></span><span class="doc-etiq doc-etiq--attente">A signer</span></a></li>
  </ul>
</div>
@tw rounded-xl border bg-white [&_nav]:flex [&_nav]:gap-1 [&_nav]:border-b [&_nav]:px-3
@end */
.doc-bloc { width: 100%; border: 1px solid var(--c-border); border-radius: var(--r-lg); background: var(--c-surface); overflow: hidden; }
.doc-bloc__onglets {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  padding: var(--sp-2) var(--sp-3) 0;
  border-bottom: 1px solid var(--c-border);
  overflow-x: auto;
}
.doc-bloc__onglets .btn--sm { margin-bottom: var(--sp-2); flex: none; }
.doc-bloc__onglets .btn--onglet { flex: none; }
.doc-bloc .doc-liste { border: none; border-radius: 0; }
/* @endv */

/* @v DOC-G2
@nom Photos de chantier datees
@usage La galerie d'un artisan : les photos regroupees par visite, avec la date en tete. Sert de preuve en cas de litige.
@html
<div class="doc-chantier">
  <div class="doc-chantier__jour">
    <h5>{{icon:calendar}} 12 aout 2026 <small>Pose de l'unite exterieure</small></h5>
    <div class="doc-grille">
      <figure class="doc-carte"><div class="doc-vignette doc-photo doc-photo--3"><span class="doc-etat doc-etat--info">14:32</span></div></figure>
      <figure class="doc-carte"><div class="doc-vignette doc-photo doc-photo--4"><span class="doc-etat doc-etat--info">15:07</span></div></figure>
      <figure class="doc-carte"><div class="doc-vignette doc-photo doc-photo--6"><span class="doc-etat doc-etat--info">16:45</span></div></figure>
    </div>
  </div>
  <div class="doc-chantier__jour">
    <h5>{{icon:calendar}} 9 aout 2026 <small>Visite technique</small></h5>
    <div class="doc-grille">
      <figure class="doc-carte"><div class="doc-vignette doc-photo doc-photo--1"><span class="doc-etat doc-etat--info">10:12</span></div></figure>
      <figure class="doc-carte"><div class="doc-vignette doc-photo doc-photo--2"><span class="doc-etat doc-etat--info">10:26</span></div></figure>
    </div>
  </div>
</div>
@tw space-y-6 [&_h5]:flex [&_h5]:items-center [&_h5]:gap-2 [&_h5]:text-sm [&_h5]:font-bold
@end */
.doc-chantier { width: 100%; display: flex; flex-direction: column; gap: var(--sp-6); }
.doc-chantier__jour h5 {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  color: var(--c-text);
}
.doc-chantier__jour h5 svg { width: 17px; height: 17px; color: var(--c-primary); }
.doc-chantier__jour h5 small { font-size: var(--fs-sm); font-weight: var(--fw-normal); color: var(--c-text-muted); }
/* @endv */

/* @v DOC-G3
@nom Historique de versions
@usage Un meme document remplace plusieurs fois. La version courante est en tete, les precedentes restent consultables et jamais supprimees en silence.
@html
<ol class="doc-versions">
  <li class="is-actuelle">
    <span class="doc-versions__pastille">v3</span>
    <span class="doc-liste__bloc"><strong>Devis LTP-2026-103.pdf</strong><small>12 aout 2026 - Julien K. - version en vigueur</small></span>
    <span class="doc-etiq doc-etiq--ok">Actuelle</span>
  </li>
  <li>
    <span class="doc-versions__pastille">v2</span>
    <span class="doc-liste__bloc"><strong>Devis LTP-2026-103.pdf</strong><small>9 aout 2026 - Julien K. - ajout de l'option ballon</small></span>
    <button class="btn btn--fantome btn--dense">Restaurer</button>
  </li>
  <li>
    <span class="doc-versions__pastille">v1</span>
    <span class="doc-liste__bloc"><strong>Devis LTP-2026-103.pdf</strong><small>5 aout 2026 - Sophie M. - creation</small></span>
    <button class="btn btn--fantome btn--dense">Restaurer</button>
  </li>
</ol>
@tw relative [&_li]:flex [&_li]:items-center [&_li]:gap-3 [&_li]:py-3 before:absolute before:left-4 before:h-full before:w-px before:bg-slate-200
@end */
.doc-versions { list-style: none; margin: 0; padding: 0; width: 100%; position: relative; }
/* Le trait vertical qui relie les versions, tire entre la premiere et la derniere pastille. */
.doc-versions::before {
  content: "";
  position: absolute;
  left: 15px;
  top: 28px;
  bottom: 28px;
  width: 2px;
  background: var(--c-border);
}
.doc-versions li {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) 0;
}
.doc-versions__pastille {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  flex: none;
  border-radius: var(--r-full);
  background: var(--c-surface-3);
  border: 2px solid var(--c-surface);
  color: var(--c-text-soft);
  font-size: 11px;
  font-weight: var(--fw-bold);
  z-index: 1;
}
.doc-versions li.is-actuelle .doc-versions__pastille { background: var(--c-primary); color: var(--c-primary-text); }
.doc-versions li.is-actuelle strong { color: var(--c-text); }
.doc-versions li:not(.is-actuelle) { opacity: .78; }
/* @endv */

/* @v DOC-G4
@nom Partage par lien
@usage Envoyer un dossier a un client sans lui creer de compte. Trois reglages suffisent : qui peut ouvrir, jusqu'a quand, et avec quel droit.
@html
<div class="doc-partage">
  <h4>{{icon:lien}} Partager 4 documents</h4>
  <div class="btn-copier doc-partage__lien">
    <code>jabsdev.fr/p/a7f3c9</code>
    <button class="btn btn--icone btn--fantome btn--sm" aria-label="Copier le lien">{{icon:copy}}</button>
  </div>
  <label class="bascule-ligne">
    <span class="bascule-ligne__texte"><strong>Autoriser le telechargement</strong><small>Sinon le client peut seulement consulter</small></span>
    <input type="checkbox" checked><span class="bascule__piste"></span>
  </label>
  <label class="bascule-ligne">
    <span class="bascule-ligne__texte"><strong>Expiration dans 30 jours</strong><small>Le lien cessera de fonctionner le 5 octobre</small></span>
    <input type="checkbox" checked><span class="bascule__piste"></span>
  </label>
  <button class="btn btn--plein btn--bloc">Envoyer par courriel</button>
</div>
@tw flex w-full max-w-md flex-col gap-3 rounded-xl border bg-white p-4
@end */
.doc-partage {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  width: 100%;
  max-width: 420px;
  padding: var(--sp-4);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  background: var(--c-surface);
}
.doc-partage h4 { display: flex; align-items: center; gap: var(--sp-2); margin: 0; font-size: var(--fs-lg); font-weight: var(--fw-bold); }
.doc-partage h4 svg { width: 18px; height: 18px; color: var(--c-primary); }
.doc-partage__lien { width: 100%; justify-content: space-between; }
.doc-partage__lien code { overflow: hidden; text-overflow: ellipsis; }
/* @endv */

/* @v DOC-G5
@nom Galerie mobile
@usage Defilement horizontal avec calage : chaque photo s'aligne d'elle-meme. La barre de position remplace des fleches inutilisables au doigt.
@html
<div class="doc-carrousel">
  <span class="doc-photo doc-photo--1"></span>
  <span class="doc-photo doc-photo--2"></span>
  <span class="doc-photo doc-photo--3"></span>
  <span class="doc-photo doc-photo--4"></span>
  <span class="doc-photo doc-photo--5"></span>
</div>
@tw flex snap-x snap-mandatory gap-3 overflow-x-auto [&>*]:snap-start [&>*]:shrink-0
@end */
.doc-carrousel {
  display: flex;
  gap: var(--sp-3);
  width: 100%;
  padding-bottom: var(--sp-2);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
}
.doc-carrousel > * {
  flex: none;
  width: 180px;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-md);
  scroll-snap-align: start;
}
/* @endv */

/* @v DOC-G6
@nom Document a signer
@usage L'ecran de signature d'un devis : l'apercu, la mention legale, puis l'action. Le bouton reste bloque tant que la case n'est pas cochee.
@html
<div class="doc-signature">
  <div class="doc-signature__apercu"><div class="doc-page doc-page--rouge"><div class="doc-page__lignes"></div></div></div>
  <div class="doc-signature__corps">
    <h4>Devis LTP-2026-103</h4>
    <p class="doc-signature__montant">4 280,00 EUR TTC</p>
    <label class="coche"><input type="checkbox"><span class="coche__boite"></span> J'ai lu et j'accepte les conditions generales de vente</label>
    <span class="btn-explique" data-bulle="Cochez d'abord les conditions generales">
      <button class="btn btn--plein btn--lg btn--bloc" disabled>{{icon:signature}} Signer le devis</button>
    </span>
    <small>Signature electronique horodatee, conforme au reglement eIDAS.</small>
  </div>
</div>
@tw flex gap-4 rounded-xl border bg-white p-4 max-sm:flex-col
@end */
.doc-signature {
  display: flex;
  gap: var(--sp-4);
  width: 100%;
  max-width: 520px;
  padding: var(--sp-4);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  background: var(--c-surface);
}
.doc-signature__apercu { width: 120px; flex: none; }
.doc-signature__apercu .doc-page { aspect-ratio: 1 / 1.414; height: auto; border-radius: var(--r-sm); box-shadow: var(--sh-2); }
.doc-signature__corps { display: flex; flex-direction: column; gap: var(--sp-3); flex: 1; min-width: 0; }
.doc-signature__corps h4 { margin: 0; font-size: var(--fs-lg); font-weight: var(--fw-bold); }
.doc-signature__montant { margin: 0; font-size: 24px; font-weight: 800; letter-spacing: -.02em; color: var(--c-text); }
.doc-signature__corps small { font-size: var(--fs-xs); color: var(--c-text-muted); line-height: 1.5; }
.doc-signature .btn-explique { display: block; }
@media (max-width: 560px) {
  .doc-signature { flex-direction: column; }
  .doc-signature__apercu { width: 100px; }
}
/* @endv */
