:root{
  --anthracite:#1F2A33;
  --anthracite-clair:#2C3A45;
  --orange:#E8710A;
  --orange-clair:#FFF1E3;
  --vert:#1B7A5A;
  --rouge:#C0392B;
  --bleu:#1F6FB2;
  --fond:#F2F4F6;
  --carte:#FFFFFF;
  --trait:#DFE4E9;
  --texte:#1F2A33;
  --texte-doux:#65727C;
  --rayon:14px;
  --ombre:0 1px 2px rgba(31,42,51,.06), 0 8px 24px rgba(31,42,51,.06);
}
*{box-sizing:border-box}
body{
  margin:0; background:var(--fond); color:var(--texte);
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  font-size:15px; line-height:1.45;
}
h1,h2,h3{margin:0 0 .6rem}
h1{font-size:1.45rem}
h2{font-size:1.1rem}
h3{font-size:.95rem}

/* ---------- Barre du haut ---------- */
.topbar{
  background:var(--anthracite); color:#fff; padding:.7rem 1.2rem .1rem;
  position:sticky; top:0; z-index:20;
}
.marque{display:flex; align-items:center; gap:.75rem; margin-bottom:.6rem}
.marque-carre{
  width:40px;height:40px;border-radius:11px;background:var(--orange);
  display:grid;place-items:center;font-weight:700;letter-spacing:.5px
}
.marque-nom{font-weight:700; font-size:1.05rem}
.marque-sous{font-size:.78rem; color:#A9B6C0}
.onglets{display:flex; gap:.25rem; overflow-x:auto}
.onglet{
  background:none;border:0;color:#A9B6C0;padding:.55rem .9rem;cursor:pointer;
  border-radius:10px 10px 0 0; font-size:.9rem; white-space:nowrap; font-family:inherit
}
.onglet:hover{color:#fff}
.onglet.actif{background:var(--fond); color:var(--anthracite); font-weight:600}

/* ---------- Structure ---------- */
main{padding:1.2rem; max-width:1180px; margin:0 auto}
.carte{
  background:var(--carte); border:1px solid var(--trait); border-radius:var(--rayon);
  padding:1rem 1.1rem; box-shadow:var(--ombre); margin-bottom:1rem
}
.entete-vue{display:flex; align-items:center; justify-content:space-between; gap:1rem; margin-bottom:1rem; flex-wrap:wrap}
.grille{display:grid; gap:1rem}
.g2{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
.g4{grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
.doux{color:var(--texte-doux); font-size:.85rem}
.vide{padding:2rem; text-align:center; color:var(--texte-doux)}

/* ---------- Boutons ---------- */
button, .btn{font-family:inherit; font-size:.9rem}
.btn{
  border:1px solid var(--trait); background:#fff; color:var(--texte);
  padding:.5rem .9rem; border-radius:999px; cursor:pointer; white-space:nowrap
}
.btn:hover{background:#F7F9FA}
.btn-plein{background:var(--orange); border-color:var(--orange); color:#fff; font-weight:600}
.btn-plein:hover{background:#CE6208}
.btn-sombre{background:var(--anthracite); border-color:var(--anthracite); color:#fff}
.btn-danger{color:var(--rouge); border-color:#E9C4BF}
.btn-danger:hover{background:#FDF3F2}
.btn-min{padding:.28rem .6rem; font-size:.8rem}

/* ---------- Champs ---------- */
label{display:block; font-size:.78rem; color:var(--texte-doux); margin-bottom:.25rem}
input,select,textarea{
  width:100%; padding:.5rem .65rem; border:1px solid var(--trait); border-radius:10px;
  font-family:inherit; font-size:.9rem; background:#fff; color:var(--texte)
}
input:focus,select:focus,textarea:focus{outline:2px solid var(--orange-clair); border-color:var(--orange)}
.champ{margin-bottom:.8rem}
.ligne-champs{display:grid; gap:.8rem; grid-template-columns:repeat(auto-fit,minmax(160px,1fr))}
input[type=number]{text-align:right}

/* ---------- Tableaux ---------- */
table{width:100%; border-collapse:collapse; font-size:.88rem}
th{text-align:left; font-size:.74rem; text-transform:uppercase; letter-spacing:.4px; color:var(--texte-doux); font-weight:600; padding:.45rem .5rem; border-bottom:1px solid var(--trait)}
td{padding:.5rem; border-bottom:1px solid #EDF0F2; vertical-align:middle}
tr:last-child td{border-bottom:0}
.num{text-align:right; font-variant-numeric:tabular-nums}
.tbl-scroll{overflow-x:auto; -webkit-overflow-scrolling:touch}

/* ---------- Pastilles ---------- */
.pastille{
  display:inline-block; padding:.16rem .6rem; border-radius:999px; font-size:.74rem; font-weight:600;
  background:#EEF1F4; color:var(--texte-doux)
}
/* Dans un tableau, une pastille ne se coupe jamais en deux lignes */
td .pastille, th .pastille{white-space:nowrap}
/* Un message d'erreur, lui, se lit sur plusieurs lignes */
.message-erreur{display:block; padding:.5rem .8rem; border-radius:12px; font-size:.85rem;
  font-weight:600; background:#FBEAE8; color:var(--rouge);
  white-space:normal; overflow-wrap:break-word; margin-bottom:.8rem}
.p-orange{background:var(--orange-clair); color:#A24E05}
.p-vert{background:#E3F3EE; color:var(--vert)}
.p-bleu{background:#E6F0F9; color:var(--bleu)}
.p-rouge{background:#FBEAE8; color:var(--rouge)}

/* ---------- Indicateurs ---------- */
.kpi{background:var(--carte); border:1px solid var(--trait); border-radius:var(--rayon); padding:.9rem 1rem; box-shadow:var(--ombre)}
.kpi-val{font-size:1.55rem; font-weight:700; font-variant-numeric:tabular-nums}
.kpi-lib{font-size:.78rem; color:var(--texte-doux)}

/* ---------- Récapitulatif devis ---------- */
.recap div{display:flex; justify-content:space-between; gap:1rem; padding:.32rem 0; font-size:.9rem}
.recap .val{flex:0 0 auto; white-space:nowrap}
.recap .sep{border-top:1px solid var(--trait); margin:.4rem 0; padding:0}
.recap .fort{font-weight:700; font-size:1.05rem}
.recap .val{font-variant-numeric:tabular-nums}

/* ---------- Checklist ---------- */
.check{display:flex; align-items:flex-start; gap:.6rem; padding:.45rem 0; border-bottom:1px solid #EDF0F2}
.check:last-child{border-bottom:0}
.check input{width:18px; height:18px; margin-top:.15rem; flex:0 0 auto; accent-color:var(--orange)}
.check-txt{font-size:.88rem; display:block}
.check-note{font-size:.76rem; color:var(--texte-doux); display:block; margin-top:.1rem}

/* ---------- Modale ---------- */
.modale-fond{position:fixed; inset:0; background:rgba(31,42,51,.45); display:grid; place-items:center; padding:1rem; z-index:40}
.modale-fond[hidden]{display:none}
.modale{background:#fff; border-radius:18px; padding:1.2rem; width:min(640px,100%); max-height:88vh; overflow:auto; box-shadow:0 24px 60px rgba(0,0,0,.25)}
.modale-pied{display:flex; gap:.5rem; justify-content:flex-end; margin-top:1rem}

/* ---------- Impression ---------- */
@media print{
  .topbar,.onglets,.no-print{display:none !important}
  body{background:#fff}
  main{padding:0; max-width:none}
  .carte{box-shadow:none; border:0; page-break-inside:avoid}
  .modale-fond{position:static; background:none; padding:0}
  .modale{box-shadow:none; max-height:none; width:100%}
}

/* Référence réglementaire sous une étape */
.ref{font-size:.74rem; color:var(--bleu); text-decoration:none; border-bottom:1px dotted var(--bleu)}
.ref:hover{color:var(--orange); border-color:var(--orange)}

/* ---------- Audit ---------- */
.q{padding:.8rem 0; border-bottom:1px solid #EDF0F2}
.q:last-child{border-bottom:0}
.q-lib{font-weight:600; margin-bottom:.15rem}
.q-aide{font-size:.8rem; color:var(--texte-doux); margin-bottom:.45rem}
.q-rep{max-width:560px}
.choix{display:flex; flex-wrap:wrap; gap:.4rem}
.choix label{display:inline-flex; align-items:center; gap:.35rem; border:1px solid var(--trait);
  border-radius:999px; padding:.32rem .75rem; cursor:pointer; font-size:.86rem;
  color:var(--texte); margin:0; background:#fff}
.choix label:hover{background:#F7F9FA}
.choix input{width:auto; margin:0; accent-color:var(--orange)}
.choix label.sel{border-color:var(--orange); background:var(--orange-clair); font-weight:600}
.jauge{height:9px; background:#EEF1F4; border-radius:99px; overflow:hidden}
.jauge div{height:9px; border-radius:99px}
.jauge-barre{background:var(--orange); transition:width .2s}
.note{font-size:1.9rem; font-weight:700; line-height:1; font-variant-numeric:tabular-nums}
.alerte{display:flex; gap:.6rem; padding:.5rem 0; border-bottom:1px solid #EDF0F2}
.alerte:last-child{border-bottom:0}
.puce{width:9px;height:9px;border-radius:99px;margin-top:.42rem;flex:0 0 auto}

/* ===========================================================
   Écrans étroits : téléphone et tablette en portrait
   =========================================================== */
@media (max-width: 820px){
  main{padding:.8rem}
  .carte{padding:.85rem .9rem; border-radius:12px}
  h1{font-size:1.25rem}
  .entete-vue{gap:.6rem}
  .kpi-val{font-size:1.3rem}
  .note{font-size:1.5rem}

  /* Tous les onglets restent visibles : ils passent à la ligne plutôt que de sortir de l'écran */
  .onglets{flex-wrap:wrap; overflow:visible; gap:.3rem; padding-bottom:.35rem}
  .onglet{padding:.45rem .75rem; font-size:.85rem; border-radius:10px}
  .onglet.actif{box-shadow:0 2px 0 var(--orange) inset}

  /* Le bandeau d'état passe sous le nom, en petit */
  #etatSync{margin-left:0 !important; font-size:.7rem !important; padding:.12rem .5rem !important}
  .marque{flex-wrap:wrap}

  /* Confort tactile : cibles plus hautes, texte assez grand pour ne pas déclencher le zoom */
  input, select, textarea{font-size:16px; padding:.6rem .7rem}
  .btn{padding:.55rem 1rem}
  .btn-min{padding:.4rem .8rem; font-size:.85rem}
  .choix label{padding:.45rem .9rem}
  .check input{width:22px; height:22px}
}

/* Le tableau du devis devient une pile de fiches sur téléphone */
@media (max-width: 620px){
  /* Nos tableaux n'ont pas de thead : la ligne d'en-têtes est la première ligne */
  .tbl-cartes thead{display:none}
  .tbl-cartes th{display:none}
  .tbl-cartes tr:first-child{border:0; padding:0; margin:0}
  .tbl-cartes, .tbl-cartes tbody, .tbl-cartes tr, .tbl-cartes td{display:block; width:100%}
  .tbl-cartes tr{border:1px solid var(--trait); border-radius:12px; padding:.6rem; margin-bottom:.6rem}
  .tbl-cartes td{border:0; padding:.22rem 0; display:flex; justify-content:space-between; gap:1rem; align-items:center}
  .tbl-cartes td::before{content:attr(data-libelle); color:var(--texte-doux); font-size:.78rem; flex:0 0 auto}
  .tbl-cartes td:first-child{display:block}
  .tbl-cartes td:first-child::before{display:none}
  .tbl-cartes td.num{text-align:right}
  .tbl-cartes input{max-width:150px}
}

/* Impression : toujours en tableau, jamais en fiches */
@media print{
  .tbl-cartes thead{display:table-header-group}
  .tbl-cartes th{display:table-cell}
  .tbl-cartes{display:table} .tbl-cartes tbody{display:table-row-group}
  .tbl-cartes tr{display:table-row; border:0; padding:0}
  .tbl-cartes td{display:table-cell; padding:.5rem}
  .tbl-cartes td::before{display:none}
}

/* ===========================================================
   iPhone : encoche, bords arrondis, et rien qui dépasse
   =========================================================== */
html, body{max-width:100%; overflow-x:hidden}
body{
  padding-left:env(safe-area-inset-left);
  padding-right:env(safe-area-inset-right);
}
.topbar{
  padding-top:calc(.7rem + env(safe-area-inset-top));
  padding-left:calc(1.2rem + env(safe-area-inset-left));
  padding-right:calc(1.2rem + env(safe-area-inset-right));
}
main{padding-bottom:calc(1.2rem + env(safe-area-inset-bottom))}

/* Une image, un tableau ou une fenêtre ne débordent jamais de l'écran */
img, canvas, video{max-width:100%; height:auto}
.carte, .kpi, .modale{max-width:100%}
input, select, textarea{max-width:100%}
pre, textarea{white-space:pre-wrap; word-break:break-word}
.doux, .check-note{overflow-wrap:anywhere}
td, th{overflow-wrap:break-word}

@media (max-width: 700px){
  /* Les largeurs minimales prévues pour un écran large sont levées */
  [style*="min-width"]{min-width:0 !important}
  .recap{min-width:0 !important}
  .entete-vue{flex-direction:column; align-items:stretch}
  .entete-vue > div{width:100%}
  .entete-vue [style*="text-align:right"]{text-align:left !important}
  .grille.g2, .grille.g4{grid-template-columns:1fr}
  .modale{padding:.9rem; border-radius:14px}
  .modale-pied{flex-wrap:wrap}
  .modale-pied .btn{flex:1}
  /* Les deux blocs de signature des documents passent l'un sous l'autre */
  .doc-signatures{flex-direction:column}
}

@media (max-width: 380px){
  /* Trop étroit pour tenir le libellé et trois pastilles sur la même ligne */
  .tbl-cartes td[data-libelle="Contexte"]{display:block}
  .tbl-cartes td[data-libelle="Contexte"]::before{display:block; margin-bottom:.25rem}
  main{padding:.6rem}
  .carte{padding:.7rem}
  h1{font-size:1.15rem}
  .btn{padding:.5rem .8rem; font-size:.86rem}
  .choix label{font-size:.82rem; padding:.4rem .7rem}
}

/* Un bouton qui porte une phrase peut aller à la ligne : sinon il pousse la page.

   « anywhere » est proscrit ici, et ce n'est pas un détail de style : cette
   valeur autorise le navigateur à couper N'IMPORTE OÙ, donc la largeur
   minimale du bouton devient celle d'UNE LETTRE. Dans une rangée serrée, les
   boutons se compriment jusque-là et le texte tombe en colonne, une lettre par
   ligne. C'est ce qui s'est produit sur la barre du dossier photos.
   « break-word » coupe aussi les mots trop longs, mais réserve au bouton la
   largeur de son mot le plus long. Même remède que pour les tableaux. */
.btn-texte{white-space:normal; line-height:1.35; text-align:left; height:auto; overflow-wrap:break-word}

/* Une rangée de boutons doit pouvoir passer à la ligne.
   Beaucoup de rangées sont écrites en style direct « display:flex » sans
   préciser le retour à la ligne : sur un téléphone, le quatrième bouton
   n'entre pas et toute la rangée s'écrase. On le corrige ici une fois pour
   toutes, plutôt qu'à cinquante-six endroits. */
[style*="display:flex"]{flex-wrap:wrap}
.barre-actions{display:flex; flex-wrap:wrap; gap:.5rem}
.barre-actions > .btn{flex:0 1 auto}
.choix label{max-width:100%; white-space:normal; text-align:left}

/* Champs modifiables : on doit voir au premier coup d'oeil qu'ils se saisissent */
.tbl-cartes input[type=number]{background:#FFF; border-color:#C9D2D9}
.tbl-cartes input[readonly]{border-style:dashed}
@media (max-width: 620px){
  .tbl-cartes td[data-libelle="Total de la ligne"]{
    border-top:1px solid var(--trait); margin-top:.35rem; padding-top:.45rem; font-size:1.02rem}
  .tbl-cartes td:first-child{font-weight:600; margin-bottom:.35rem}
}

/* En mode fiches, la cellule Quantité empile son champ et son bouton :
   sinon le champ se retrouve écrasé et le nombre tronqué. */
@media (max-width: 620px){
  .tbl-cartes td[data-libelle="Quantité"]{flex-wrap:wrap; align-items:center}
  .tbl-cartes td[data-libelle="Quantité"] > div{flex:1 1 auto; justify-content:flex-end}
  .tbl-cartes td[data-libelle="Quantité"] input{min-width:96px; max-width:none !important; flex:1 1 auto}
  .tbl-cartes td[data-libelle="Quantité"] > .btn{flex:1 1 100%; margin-top:.4rem}
}

/* ===========================================================
   Tableaux sur téléphone — plus jamais de colonnes écrasées
   Deux comportements, selon le tableau :
   - ceux marqués « tbl-cartes » deviennent une pile de fiches ;
   - tous les autres gardent leur forme de tableau et défilent
     horizontalement dans leur cadre, sans jamais couper les mots.
   =========================================================== */
/* Quelle que soit la taille de l'écran : un tableau garde sa largeur
   naturelle et c'est son cadre qui défile. Jamais de colonne écrasée. */
.tbl-scroll{overflow-x:auto; -webkit-overflow-scrolling:touch}
.tbl-scroll > table{width:auto; min-width:100%}
table td, table th{overflow-wrap:normal; word-break:normal; hyphens:none}
table th{min-width:4.5rem}
table td{min-width:4.5rem}
table td.num, table th.num{min-width:5.5rem; white-space:nowrap}

@media (max-width: 620px){
  /* Les tableaux des documents imprimables ne sont pas dans un cadre :
     ils deviennent eux-mêmes le cadre qui défile. */
  .doc table, #zoneImpression table{display:block; overflow-x:auto; -webkit-overflow-scrolling:touch}

  /* En fiches, la fiche occupe toute la largeur : plus de largeur minimale */
  .tbl-scroll > table.tbl-cartes{width:100%; min-width:0}
  .tbl-cartes td, .tbl-cartes th{min-width:0}
  .tbl-cartes td{overflow-wrap:break-word}

  /* En fiches : la ligne de titre porte le libellé de l'ouvrage ou du chantier */
  .tbl-cartes td.td-titre{display:block; font-weight:600; margin-bottom:.35rem}
  .tbl-cartes td.td-titre::before{display:none}
  .tbl-cartes td.td-titre input{max-width:none; width:100%}
  /* Les boutons d'action passent en bas de la fiche, sur toute la largeur */
  .tbl-cartes td.td-actions{display:flex; flex-wrap:wrap; gap:.4rem; justify-content:flex-start;
    margin-top:.5rem; padding-top:.5rem; border-top:1px solid var(--trait)}
  .tbl-cartes td.td-actions::before{display:none}
  .tbl-cartes td.td-actions .btn{flex:1 1 auto}
  /* Le détail des coûts n'a pas sa place sur un petit écran : il reste
     accessible par le bouton Composition. */
  .masq-mob{display:none !important}

  /* Les pastilles de contexte restent d'un seul tenant et se serrent au besoin */
  .tbl-cartes td[data-libelle="Contexte"]{flex-wrap:wrap; justify-content:flex-end; row-gap:.35rem}
  .tbl-cartes td[data-libelle="Contexte"] .pastille{white-space:nowrap; padding:.2rem .55rem; font-size:.74rem}
}

/* À l'impression, tout redevient un vrai tableau, tenu dans la largeur de la page */
@media print{
  .masq-mob{display:table-cell !important}
  .tbl-cartes td.td-titre, .tbl-cartes td.td-actions{display:table-cell}
  .doc table, #zoneImpression table{display:table}
  .tbl-scroll{overflow:visible}
  .tbl-scroll > table, table{width:100%; min-width:0}
  table td, table th{min-width:0; overflow-wrap:break-word}
  table td.num, table th.num{min-width:0}
}

/* ===========================================================
   D'où vient ce chiffre
   Un chiffre expliqué se signale discrètement et s'ouvre au clic.
   =========================================================== */
.chiffre{cursor:pointer; border-bottom:1px dotted var(--bleu); padding-bottom:1px}
.chiffre:hover{color:var(--orange); border-color:var(--orange)}

.expl{border:1px solid var(--trait); border-radius:12px; padding:.5rem .8rem; margin-bottom:.8rem}
.expl-fam{font-size:.74rem; text-transform:uppercase; letter-spacing:.4px; color:var(--texte-doux);
  font-weight:600; margin:.6rem 0 .2rem}
.expl-fam:first-child{margin-top:0}
.expl-ligne{display:flex; justify-content:space-between; gap:1rem; align-items:baseline;
  padding:.28rem 0; border-bottom:1px solid #F2F5F7}
.expl-ligne:last-child{border-bottom:0}
.expl-lib{flex:1 1 auto}
.expl-calc{display:block; font-size:.78rem; color:var(--texte-doux); font-variant-numeric:tabular-nums}
.expl-note{display:block; font-size:.76rem; color:var(--texte-doux); font-style:italic}
.expl-val{flex:0 0 auto; font-variant-numeric:tabular-nums; white-space:nowrap; text-align:right}
.expl-total{font-weight:600; border-top:1px solid var(--trait); border-bottom:0; margin-top:.2rem}
.expl-doux, .expl-doux .expl-val{color:var(--texte-doux)}
.expl-resultat{display:flex; justify-content:space-between; gap:1rem; align-items:baseline;
  background:var(--orange-clair, #FDF0E4); border-radius:12px; padding:.6rem .8rem;
  font-weight:700; font-size:1.05rem; margin-bottom:.9rem}
.expl-regle{background:#F7F9FA; border-radius:12px; padding:.7rem .8rem; font-size:.85rem; line-height:1.55}
.expl-regle-titre{font-weight:600; margin-bottom:.25rem}
.expl-source{margin-top:.4rem; font-size:.8rem; color:var(--texte-doux)}

@media (max-width: 620px){
  .expl-ligne{flex-wrap:wrap; row-gap:.15rem}
  .expl-val{width:100%; text-align:right}
}
@media print{
  .chiffre{border-bottom:0}
  .expl, .expl-regle, .expl-resultat{break-inside:avoid}
}

/* ===========================================================
   Espace du chef d'équipe
   =========================================================== */
.etapes{display:flex; gap:.4rem; flex-wrap:wrap; margin-bottom:1rem}
.etape{
  border:1px solid var(--trait); background:#FFF; color:var(--texte);
  border-radius:12px; padding:.5rem .9rem; font-size:.9rem; font-weight:600;
  cursor:pointer; display:inline-flex; align-items:center; gap:.4rem
}
.etape:hover{border-color:var(--orange)}
.etape.actif{background:var(--orange); color:#FFF; border-color:var(--orange)}
.etape-nb{
  font-size:.74rem; font-weight:600; background:#EEF1F4; color:var(--texte-doux);
  border-radius:99px; padding:.05rem .45rem
}
.etape.actif .etape-nb{background:rgba(255,255,255,.25); color:#FFF}

.tache-faite{opacity:.62}
.tache-faite .pastille{opacity:.7}

/* ---------- Photos ---------- */
.galerie{display:grid; grid-template-columns:repeat(auto-fill, minmax(190px, 1fr)); gap:.8rem}
.vignette{margin:0; border:1px solid var(--trait); border-radius:12px; overflow:hidden; background:#FFF}
/* La zone qui ouvre la photo : une hauteur minimale même vide, sinon il n'y
   a rien à toucher tant que l'image n'a pas chargé. */
.vignette-image{cursor:pointer; min-height:96px; background:#EDF1F4; display:block}
.vignette-image:focus-visible{outline:3px solid var(--orange); outline-offset:-3px}
.vignette img{
  width:100%; aspect-ratio:4/3; object-fit:cover; display:block; background:#EEF1F4; cursor:zoom-in
}
.vignette figcaption{padding:.5rem .6rem; font-size:.82rem; display:flex; flex-direction:column; gap:.15rem}
.photo-grande{border-radius:12px; overflow:hidden; background:#EEF1F4}
.photo-grande img{width:100%; display:block; max-height:60vh; object-fit:contain}

.dossiers{display:grid; grid-template-columns:repeat(auto-fill, minmax(200px, 1fr)); gap:.8rem}
.dossier{
  border:1px solid var(--trait); border-radius:14px; background:#FFF; padding:0 0 .6rem;
  text-align:left; cursor:pointer; overflow:hidden; font:inherit; color:inherit
}
.dossier:hover{border-color:var(--orange)}
.dossier-vue{background:#EEF1F4; aspect-ratio:4/3}
.dossier-vue img{width:100%; height:100%; object-fit:cover; display:block}
.dossier-nom{font-weight:600; padding:.5rem .7rem 0}
.dossier .doux{padding:0 .7rem; font-size:.78rem}

/* ---------- Commentaires ---------- */
.commentaire{
  border-left:3px solid var(--trait); padding:.4rem .7rem; margin-bottom:.5rem;
  background:#F7F9FA; border-radius:0 10px 10px 0
}
.commentaire.du-bureau{border-left-color:var(--orange); background:var(--orange-clair)}
.commentaire-tete{font-size:.8rem; font-weight:600; margin-bottom:.15rem}

@media (max-width: 620px){
  .etapes{gap:.3rem}
  .etape{padding:.45rem .7rem; font-size:.84rem}
  .galerie{grid-template-columns:repeat(auto-fill, minmax(140px, 1fr)); gap:.5rem}
  .dossiers{grid-template-columns:repeat(auto-fill, minmax(150px, 1fr)); gap:.5rem}
}
@media print{
  .etapes{display:none}
  .galerie{grid-template-columns:repeat(2, 1fr)}
  .vignette{break-inside:avoid}
}

/* Les photos sous une tâche sont plus petites : elles accompagnent, elles ne dominent pas */
.galerie-tache{grid-template-columns:repeat(auto-fill, minmax(130px, 1fr)); gap:.5rem}
.galerie-tache .vignette figcaption{padding:.35rem .5rem; font-size:.76rem}

/* Une pastille rouge sur l'onglet du fil : elle dit qu'on a manqué quelque
   chose, ce qu'un simple compteur gris ne dit pas. */
.etape-nb.nouveau{background:var(--rouge); color:#FFF; font-weight:700}

/* ---------- Photos des chantiers de référence, dans le mémoire ----------
   Petites et alignées : elles appuient le texte, elles ne le remplacent pas.
   Un acheteur qui feuillette doit voir l'ouvrage fini sans que la page se
   transforme en album. */
.refs-photos{display:flex; flex-direction:column; gap:.9rem; margin-top:.8rem}
.ref-chantier{break-inside:avoid}
.ref-titre{font-weight:700; font-size:.92rem; margin-bottom:.35rem}
.ref-photos{display:grid; grid-template-columns:repeat(auto-fill, minmax(150px, 1fr)); gap:.6rem}
.ref-photo{margin:0; border:1px solid var(--trait); border-radius:8px; overflow:hidden; background:#FFF}
.ref-photo img{width:100%; height:110px; object-fit:cover; display:block}
.ref-photo figcaption{padding:.3rem .45rem; font-size:.74rem; color:var(--texte-doux)}
@media print{
  .ref-photos{grid-template-columns:repeat(3, 1fr)}
  .ref-photo img{height:80px}
}

/* ---------- Groupes de photos repliables ----------
   L'en-tête occupe toute la largeur et se touche facilement avec un gant :
   c'est la cible la plus utilisée de cet écran. */
.groupe-photos{padding:0}
.groupe-photos > summary{
  list-style:none; cursor:pointer; display:flex; align-items:center;
  gap:.6rem; padding:.85rem 1rem; user-select:none}
.groupe-photos > summary::-webkit-details-marker{display:none}
.groupe-photos > summary::before{
  content:''; flex:none; width:0; height:0;
  border-left:7px solid var(--texte-doux);
  border-top:5px solid transparent; border-bottom:5px solid transparent;
  transition:transform .15s ease}
.groupe-photos[open] > summary::before{transform:rotate(90deg)}
.groupe-photos > summary:hover{background:#F7F9FA}
.groupe-titre{font-weight:700; font-size:1.02rem; flex:1}
.groupe-nb{background:#EDF1F4; color:var(--texte-doux); border-radius:99px;
  padding:.1rem .55rem; font-size:.82rem; font-weight:600; flex:none}
.groupe-photos[open] > summary{border-bottom:1px solid var(--trait)}
.groupe-photos > .galerie{padding:.9rem 1rem 1rem}
@media print{
  /* À l'impression, tout est déplié : un dossier remis au client ne se plie pas. */
  .groupe-photos > .galerie{display:grid !important}
  .groupe-photos > summary::before{display:none}
}

/* ---------- Le fil du chantier ----------
   Les messages du bureau se distinguent de ceux du chantier par leur fond,
   et un message réservé au bureau porte en plus un liseré bleu et sa
   mention : sur un écran partagé, on doit savoir d'un coup d'oeil que ce
   qu'on lit n'est pas destiné à tout le monde. */
.fil{display:flex; flex-direction:column; gap:.6rem; max-height:56vh; overflow-y:auto;
     padding-right:.2rem}
.fil-msg{background:#F7F9FA; border:1px solid var(--trait); border-radius:12px;
         padding:.6rem .75rem}
.fil-msg.du-bureau{background:#F2F7FB}
.fil-msg.reserve{border-left:4px solid #1F6FB2}
.fil-tete{display:flex; flex-wrap:wrap; align-items:center; gap:.4rem;
          font-size:.82rem; margin-bottom:.2rem}
.fil-texte{white-space:pre-wrap; overflow-wrap:break-word}
.fil audio{max-width:100%}

/* ---------- Observation dite ----------

   Sur un chantier, tout le monde ne lit pas et n'écrit pas. Le bouton qui
   déclenche la parole doit donc se reconnaître SANS lire son libellé : une
   grosse pastille rouge au repos — la convention de l'enregistrement, comprise
   partout — et un carré blanc pendant qu'il enregistre, l'autre convention.
   Le libellé reste écrit à côté pour ceux qui lisent : on n'enlève rien.
   Aucun pictogramme : des formes, de la couleur, et de la taille. */
.btn-dire{background:var(--rouge); border-color:var(--rouge); color:#FFF;
  font-weight:600; display:inline-flex; align-items:center; gap:.45rem}
.btn-dire::before{content:''; display:inline-block; width:12px; height:12px;
  border-radius:99px; background:#FFF; flex:none}
.btn-dire:hover{background:#A8291B; border-color:#A8291B}
.btn-dire-grand{font-size:1.05rem; padding:.75rem 1.3rem; border-radius:99px}
.btn-dire-grand::before{width:16px; height:16px}

/* Pendant l'enregistrement : la pastille devient un carré, et elle bat.
   Deux signes au lieu d'un, pour qui ne distingue pas bien les couleurs. */
.btn-dire.enregistre::before{border-radius:2px; animation:pulseVocal 1s infinite}

/* Une photo qui porte une observation dite doit se repérer d'un coup d'oeil
   dans une galerie de deux cents images : un bouton vert, la couleur de ce
   qu'on peut écouter, et un triangle de lecture — forme, pas pictogramme. */
.btn-ecouter{background:var(--vert); border-color:var(--vert); color:#FFF;
  font-weight:600; display:inline-flex; align-items:center; gap:.4rem}
.btn-ecouter::before{content:''; display:inline-block; width:0; height:0; flex:none;
  border-left:9px solid #FFF; border-top:6px solid transparent;
  border-bottom:6px solid transparent}
.btn-ecouter:hover{background:#12604C; border-color:#12604C}
.marque-dite{color:var(--vert); font-weight:600}

/* La rangée sous une vignette : parler passe avant écrire */
.barre-vignette{display:flex; flex-wrap:wrap; align-items:center;
  gap:.35rem; margin-top:.4rem}
.vocal-grand{margin-top:.9rem}
.vocal-etat{font-size:.76rem}

.vocal{display:flex; align-items:center; gap:.7rem; flex-wrap:wrap; margin-top:.5rem}
/* Ces règles précèdent l'arrivée du bouton « Dire » : on les écarte de lui,
   sinon leur spécificité plus forte le repeindrait en orange sur fond blanc
   et lui rendrait sa pastille ronde pendant l'enregistrement. */
.vocal .btn:not(.btn-dire){border-color:var(--orange); color:var(--orange)}
.vocal .btn:not(.btn-dire).enregistre{background:var(--rouge); border-color:var(--rouge); color:#FFF}
.vocal .btn:not(.btn-dire).enregistre::before{
  content:''; display:inline-block; width:10px; height:10px; border-radius:99px;
  background:#FFF; margin-right:.5rem; animation:pulseVocal 1s infinite
}
@keyframes pulseVocal{0%,100%{opacity:1} 50%{opacity:.25}}
.commentaire audio{max-width:100%}

/* ---------- Les images des panneaux ----------
   Elles viennent du cours de signalisation temporaire de FORMENERGIE : le chef
   d'équipe reconnaît sur son téléphone ce qu'on lui a montré en salle. */
.panneau{display:inline-flex; align-items:center; justify-content:center; position:relative}
.panneau img{display:block; width:100%; height:auto}
.panneau-moyen{width:62px}
.panneau-petit{width:40px}
.panneau-grand{width:96px}

/* Un panneau dont l'image manque garde son code écrit : sur un sujet
   réglementaire, mieux vaut un repère nu qu'un dessin approximatif. */
.panneau-absent{display:inline-flex; align-items:center; justify-content:center;
  min-width:56px; padding:.3rem .5rem; border:2px solid var(--anthracite);
  border-radius:6px; background:#FFF; font-weight:700; font-size:.85rem; color:var(--anthracite)}
.panneau-valeur{position:absolute; right:-4px; bottom:-4px; background:var(--anthracite);
  color:#FFF; border-radius:99px; font-size:.68rem; font-weight:700; padding:.05rem .32rem}
.panneau-absent .panneau-valeur{position:static; margin-left:.25rem}
.td-panneau{text-align:center}

/* ---------- Schéma de balisage ---------- */
.schema-balisage{border:1px solid var(--trait); border-radius:12px; padding:.5rem;
  background:#FFF; margin-bottom:.9rem; overflow-x:auto}
.schema-balisage svg{min-width:520px; display:block}

/* Le plan garde le rapport d'un A4 couché : ce qu'on voit à l'écran est ce
   qui sortira de l'imprimante. */
.plan-a4 svg{min-width:680px}

@media print{
  /* Le plan de balisage s'imprime seul, en paysage, sur une page entière. */
  @page{size:A4 landscape; margin:8mm}
  .plan-a4{border:0; padding:0; margin:0; overflow:visible; break-inside:avoid}
  .plan-a4 svg{min-width:0; width:100%; height:auto}
}

/* ===========================================================
   Mémoire technique
   Ce qui reste à compléter doit sauter aux yeux, à l'écran comme
   à l'impression : un mémoire remis avec un trou se voit.
   =========================================================== */
.memoire h2{margin-top:1.6rem; padding-bottom:.3rem; border-bottom:2px solid var(--orange)}
.memoire h3{margin-top:1rem; margin-bottom:.3rem}
.memoire p{margin:.4rem 0}
.memoire ul, .memoire ol{margin:.3rem 0 .3rem 1.2rem; padding:0}
.memoire li{margin-bottom:.25rem}
.mem-sommaire{columns:2; column-gap:2rem}
.mem-rubrique{break-inside:auto; page-break-inside:auto}
.mem-tache{margin-bottom:.9rem; break-inside:avoid; page-break-inside:avoid}
.mem-sous{margin:.3rem 0 .3rem .3rem}
.mem-sous ol{margin-top:.15rem}
.mem-criteres{
  background:var(--orange-clair); border-radius:12px; padding:.8rem 1rem; margin:1rem 0;
  line-height:1.6
}
.a-completer{
  background:#FFF3CD; color:#8A6100; padding:.05rem .4rem; border-radius:6px;
  font-weight:600; border-bottom:2px dotted #C89A00
}
.doc-tete{display:flex; align-items:flex-start; gap:1rem; margin-bottom:1.2rem}
.doc-logo{max-height:70px; max-width:180px; object-fit:contain}
@media (max-width: 620px){
  .mem-sommaire{columns:1}
}
@media print{
  .memoire h2{page-break-after:avoid}
  .a-completer{background:#FFF3CD !important; -webkit-print-color-adjust:exact; print-color-adjust:exact}
}

/* ---------- Galeries dans les documents ---------- */
.galerie-doc{grid-template-columns:repeat(auto-fill, minmax(210px, 1fr)); gap:.7rem; margin:.6rem 0 1rem}
.galerie-doc.grande{grid-template-columns:repeat(auto-fill, minmax(300px, 1fr))}
.galerie-doc .vignette img{cursor:default; aspect-ratio:4/3}
.galerie-doc .vignette figcaption{padding:.4rem .55rem; font-size:.78rem}
.fiche-reference .chapeau{font-size:1.05rem; line-height:1.6; margin:.8rem 0 1.2rem}
.fiche-reference h2{margin-top:1.4rem; padding-bottom:.25rem; border-bottom:2px solid var(--orange)}

@media print{
  /* Une photographie ne doit jamais se couper entre deux pages */
  .galerie-doc .vignette{break-inside:avoid; page-break-inside:avoid}
  .galerie-doc{grid-template-columns:repeat(3, 1fr)}
  .galerie-doc.grande{grid-template-columns:repeat(2, 1fr)}
}

/* Une observation dite déjà entendue : le repère s'éteint, il ne réclame plus */
.marque-lue{color:var(--texte-doux); font-weight:400}

/* ===========================================================
   OUTILS DE CALCUL DU TECHNICIEN (calculs.js)
   Un téléphone au bord de l'unité extérieure : gros champs,
   16 px au moins pour que l'iPhone ne zoome pas, une carte par outil.
   =========================================================== */
.calc-carte{padding:0; overflow:hidden}
.calc-titre{list-style:none; cursor:pointer; display:flex; justify-content:space-between; align-items:center;
  gap:.8rem; padding:1rem 1.1rem; font-weight:700; font-size:1.02rem; min-height:56px}
.calc-titre::-webkit-details-marker{display:none}
.calc-titre::after{content:"+"; flex:0 0 auto; font-size:1.3rem; font-weight:400; color:var(--texte-doux); margin-left:.2rem}
.calc-carte[open] > .calc-titre::after{content:"−"}
.calc-titre-txt{flex:1 1 auto}
.calc-apercu{flex:0 0 auto; color:var(--vert); font-variant-numeric:tabular-nums; white-space:nowrap}
.calc-corps{padding:0 1.1rem 1.1rem}
.calc-champs{display:grid; grid-template-columns:repeat(auto-fill, minmax(230px, 1fr)); gap:.7rem 1rem}
.calc-champ{display:flex; flex-direction:column; gap:.25rem; min-width:0}
.calc-lib{font-weight:600; font-size:.88rem}
.calc-saisie{display:flex; align-items:center; gap:.4rem}
.calc-saisie input{flex:1 1 auto; min-width:0; font-size:18px; min-height:48px; text-align:right;
  font-variant-numeric:tabular-nums}
.calc-champ select{font-size:16px; min-height:48px; width:100%}
.calc-unite{flex:0 0 auto; color:var(--texte-doux); font-size:.9rem; min-width:2.2rem}
.calc-signe{flex:0 0 auto; min-width:48px; min-height:48px; font-size:1.1rem; padding:0}
.calc-aide{font-size:.78rem; color:var(--texte-doux); line-height:1.35}
.calc-res{margin-top:1rem; border-radius:var(--rayon); background:#EEF6F3; padding:.9rem 1rem}
.calc-res-vide{background:#F7F9FA; color:var(--texte-doux)}
.calc-res-lib{font-size:.85rem; color:var(--texte-doux); font-weight:600}
.calc-res-val{font-size:2rem; font-weight:800; color:var(--vert); line-height:1.15; margin:.15rem 0 .5rem;
  font-variant-numeric:tabular-nums; overflow-wrap:break-word}
.calc-res-unite{font-size:1.05rem; font-weight:600}
.calc-alerte{margin-top:.5rem; padding:.5rem .7rem; border-radius:10px; font-size:.88rem; border-left:4px solid}
.calc-alerte-ok{background:#E3F3EE; border-color:var(--vert)}
.calc-alerte-attention{background:#FDEDEB; border-color:var(--rouge)}
.calc-alerte-info{background:#EAF2FA; border-color:var(--bleu)}
.calc-detail{margin-top:.7rem; font-size:.82rem; line-height:1.5}
.calc-detail-titre{font-weight:700; margin-bottom:.2rem}
.calc-detail-ligne{font-variant-numeric:tabular-nums; overflow-wrap:break-word; padding:.1rem 0}
.calc-source{margin-top:.5rem; font-size:.78rem; color:var(--texte-doux); overflow-wrap:break-word}
.calc-source a{color:var(--bleu)}
.calc-notice{margin-top:.4rem; font-size:.82rem; font-weight:700}
#calcImpression{display:none}
.calc-doc h2{margin-top:1.2rem; padding-bottom:.2rem; border-bottom:2px solid var(--vert)}
.calc-doc table{width:100%; border-collapse:collapse; font-size:.85rem; margin-bottom:.4rem}
.calc-doc td, .calc-doc th{border-bottom:1px solid var(--trait); padding:.3rem .4rem; text-align:left}
@media print{
  body.impr-calc #ecran > *:not(#calcImpression){display:none !important}
  body.impr-calc #calcImpression{display:block}
  .calc-doc-outil{break-inside:avoid; page-break-inside:avoid}
  .calc-res{-webkit-print-color-adjust:exact; print-color-adjust:exact}
}
@media (max-width: 620px){
  .calc-champs{grid-template-columns:1fr}
  .calc-corps{padding:0 .85rem .9rem}
  .calc-titre{padding:.9rem .85rem}
}
