/* ===========================================================================
   LDK — Feuille de style
   Éclairage et électricité, suivi des chantiers.

   Principes tenus dans tout ce fichier :
     • Thème clair unique : l'application s'utilise dehors, en plein soleil.
     • Mobile d'abord ; les écrans larges ne font qu'élargir.
     • Aucune ressource externe (police, image, CDN) : la CSP l'interdit.
     • Toutes les mesures passent par des variables. Aucun « 13px » égaré :
       c'est ce qui fait qu'un écran paraît fini plutôt que bricolé.

   Plan du fichier :
      1. Jetons de design (couleurs, espacements, typographie, ombres)
      2. Réinitialisation et bases
      3. Bandeau de messages
      4. Coquille : en-tête, onglets, barre d'état
      5. Blocs de contenu (cartes, titres, états vides)
      6. Boutons
      7. Formulaires
      8. Écran de connexion
      9. Statuts et avancement
     10. Liste des chantiers
     11. Fiche chantier et chronomètre
     12. Matériel
     13. Photos
     14. Documents PDF
     15. Tableaux et tableau de bord
     16. Facturation
     17. Calendrier
     18. Réglages
     19. Enregistrement automatique (indicateurs)
     20. Squelettes de chargement
     21. Vue technicien (tout est plus gros)
     22. Écrans larges
     23. Confort, mouvement réduit, impression
   =========================================================================== */


/* ---------------------------------------------------------------------------
   1. JETONS DE DESIGN
   Un seul endroit à modifier pour ajuster toute l'interface.
   --------------------------------------------------------------------------- */

:root {
  /* --- Identité LDK : bleus historiques, inchangés --- */
  --bleu-nuit: #0f172a;
  --bleu-fonce: #0f172a;          /* alias conservé pour l'existant */
  --bleu: #1d4ed8;
  --bleu-clair: #2563eb;
  --bleu-vif: #3b82f6;
  --cyan: #0ea5e9;
  --cyan-pale: #e0f2fe;

  /* --- Fonds et textes --- */
  --fond: #eef4ff;
  --fond-degrade: linear-gradient(180deg, #eef4ff 0%, #f6f9ff 340px, #f6f9ff 100%);
  --carte: #ffffff;
  --carte-douce: #f8fafc;
  --texte: #0f172a;
  --texte-doux: #475569;
  --texte-tres-doux: #64748b;
  --bordure: #cbd5e1;
  --bordure-douce: #e2e8f0;
  --survol: #eff6ff;

  /* --- États sémantiques --- */
  --rouge: #b91c1c;
  --rouge-fond: #fef2f2;
  --rouge-bord: #fca5a5;
  --rouge-sombre: #7f1d1d;
  --vert: #15803d;
  --vert-fond: #ecfdf5;
  --vert-bord: #86efac;
  --vert-sombre: #14532d;
  --ambre: #b45309;
  --ambre-fond: #fffbeb;
  --ambre-bord: #fcd34d;
  --ardoise-fond: #f1f5f9;

  /* --- Échelle d'espacement (multiples de 4 px) ---
     Utilisée partout : marges, paddings, gouttières de grille.
     Ne jamais écrire une valeur en dur ailleurs. */
  --e0: 0;
  --e1: 4px;
  --e2: 8px;
  --e3: 12px;
  --e4: 16px;
  --e5: 20px;
  --e6: 24px;
  --e7: 32px;
  --e8: 40px;
  --e9: 56px;

  /* --- Échelle typographique --- */
  --t-xs: 0.75rem;      /* 12 px — surtitres, mentions */
  --t-sm: 0.875rem;     /* 14 px — texte secondaire */
  --t-md: 1rem;         /* 16 px — texte courant */
  --t-lg: 1.125rem;     /* 18 px — sous-titres */
  --t-xl: 1.375rem;     /* 22 px — titres de section */
  --t-2xl: 1.75rem;     /* 28 px — titres de page */
  --t-3xl: 2.25rem;     /* 36 px — grands chiffres */

  --gras-normal: 500;
  --gras-moyen: 600;
  --gras-fort: 700;
  --gras-extra: 800;

  /* --- Rayons --- */
  --r-xs: 6px;
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-plein: 999px;
  --rayon: var(--r-md);          /* alias conservé */
  --rayon-petit: var(--r-sm);    /* alias conservé */

  /* --- Ombres : trois niveaux, jamais plus --- */
  --o1: 0 1px 2px rgba(15, 23, 42, 0.05), 0 1px 3px rgba(15, 23, 42, 0.06);
  --o2: 0 2px 4px rgba(15, 23, 42, 0.04), 0 4px 12px rgba(15, 23, 42, 0.08);
  --o3: 0 8px 24px rgba(15, 23, 42, 0.12), 0 2px 6px rgba(15, 23, 42, 0.06);
  --ombre: var(--o1);            /* alias conservé */
  --ombre-forte: var(--o3);      /* alias conservé */

  /* --- Anneau de focus : identique partout, toujours visible --- */
  --anneau: 0 0 0 3px rgba(14, 165, 233, 0.45);

  /* --- Transitions : deux durées, une courbe --- */
  --courbe: cubic-bezier(0.2, 0, 0.2, 1);
  --tr-rapide: 120ms var(--courbe);
  --tr-moyen: 220ms var(--courbe);

  /* --- Cibles tactiles ---
     44 px est le minimum accessible ; 48 px le confort avec des gants ;
     56 px pour les actions principales du terrain. */
  --cible-min: 44px;
  --cible: 48px;
  --cible-grande: 56px;

  /* --- Piles de polices système : aucune ressource externe --- */
  --police: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --police-chiffres: ui-monospace, "SF Mono", "Cascadia Mono", Consolas, "Liberation Mono", monospace;

  /* --- Largeurs --- */
  --largeur-contenu: 1180px;
  --largeur-fiche: 820px;

  color-scheme: light;
}


/* ---------------------------------------------------------------------------
   2. RÉINITIALISATION ET BASES
   --------------------------------------------------------------------------- */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;

  /* Aucun débordement horizontal, jamais : les tableaux larges défilent dans
     leur propre conteneur (.tableau-defilant), et ce filet de sécurité coupe
     ce qui dépasserait malgré tout.

     « clip » et NON « hidden » : `overflow: hidden` fabrique un conteneur de
     défilement, ce qui casse `position: sticky` sur les bandeaux du haut —
     ils défileraient avec la page au lieu de rester visibles. `clip` coupe
     sans créer de conteneur de défilement, donc sticky continue de marcher. */
  overflow-x: clip;
}

body {
  margin: 0;
  padding: 0;
  font-family: var(--police);
  font-size: var(--t-md);
  line-height: 1.55;
  color: var(--texte);
  background: var(--fond);
  background-image: var(--fond-degrade);
  background-attachment: fixed;
  overflow-wrap: break-word;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  margin: 0;
  line-height: 1.25;
  letter-spacing: -0.01em;
}

p { margin: 0; }
img { max-width: 100%; display: block; }

/* Focus toujours visible : indispensable au clavier et sous la lumière du jour.
   Un seul style pour toute l'application, aucune exception. */
:focus-visible {
  outline: 3px solid var(--cyan);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

/* Les éléments qui reçoivent le focus à la souris ne clignotent pas. */
:focus:not(:focus-visible) { outline: none; }

/* Lien d'évitement : premier élément atteint au clavier. */
.saut-contenu {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: var(--e3) var(--e4);
  background: var(--bleu);
  color: #fff;
  font-weight: var(--gras-fort);
  border-radius: 0 0 var(--r-sm) 0;
}

.saut-contenu:focus {
  left: 0;
}

.chargement {
  padding: var(--e8) var(--e5);
  text-align: center;
  color: var(--texte-doux);
  font-size: var(--t-lg);
}

/* Texte réservé aux lecteurs d'écran. */
.lecteur-ecran-seul {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}


/* ---------------------------------------------------------------------------
   3. BANDEAU DE MESSAGES (erreurs, confirmations)
   --------------------------------------------------------------------------- */

/* Bandeau de message et bandeau réseau restent visibles en haut de l'écran :
   un technicien doit voir « Hors ligne » même après avoir fait défiler la page.
   Les deux sont empilés dans un seul conteneur collant, ce qui évite qu'ils se
   recouvrent quand ils s'affichent en même temps. */
.barres-hautes {
  position: sticky;
  top: 0;
  z-index: 60;
}

.bandeau {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e4);
  padding: var(--e3) var(--e4);
  padding-top: max(var(--e3), env(safe-area-inset-top));
  font-size: var(--t-md);
  font-weight: var(--gras-moyen);
  border-bottom: 3px solid transparent;
  box-shadow: var(--o1);
  animation: bandeau-entree 220ms var(--courbe);
}

@keyframes bandeau-entree {
  from { transform: translateY(-100%); opacity: 0; }
  to   { transform: translateY(0);     opacity: 1; }
}

.bandeau[hidden] { display: none; }

.bandeau-erreur { background: var(--rouge-fond); border-bottom-color: var(--rouge); color: var(--rouge-sombre); }
.bandeau-succes { background: var(--vert-fond);  border-bottom-color: var(--vert);  color: var(--vert-sombre); }
.bandeau-info   { background: var(--survol);     border-bottom-color: var(--bleu);  color: #1e3a8a; }

.bandeau-texte { flex: 1; min-width: 0; }

.bandeau-fermer {
  flex-shrink: 0;
  min-height: var(--cible-min);
  padding: var(--e2) var(--e4);
  border: 1px solid currentColor;
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, 0.75);
  color: inherit;
  font: inherit;
  font-weight: var(--gras-fort);
  cursor: pointer;
  transition: background-color var(--tr-rapide);
}

.bandeau-fermer:hover { background: #fff; }


/* ---------------------------------------------------------------------------
   4. COQUILLE : EN-TÊTE, ONGLETS, BARRE D'ÉTAT
   --------------------------------------------------------------------------- */

.app { min-height: 100vh; min-height: 100dvh; }

.entete {
  background: linear-gradient(155deg, var(--bleu-nuit) 0%, #16337c 45%, var(--bleu) 100%);
  color: #f8fafc;
  padding: var(--e3) var(--e4) 0;
  padding-top: max(var(--e3), env(safe-area-inset-top));
  box-shadow: var(--o2);
}

.entete-haut {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e3);
  flex-wrap: wrap;
}

.marque {
  display: flex;
  align-items: center;
  gap: var(--e3);
  min-width: 0;
}

.marque-logo {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  flex-shrink: 0;
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, 0.16);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.28);
  font-weight: var(--gras-extra);
  font-size: var(--t-sm);
  letter-spacing: 0.08em;
}

.marque-logo-grand {
  width: 88px;
  height: 88px;
  border-radius: var(--r-lg);
  font-size: var(--t-xl);
  background: linear-gradient(155deg, var(--bleu-clair), var(--bleu));
  color: #fff;
  box-shadow: var(--o3);
}

.marque-texte { display: flex; flex-direction: column; min-width: 0; }
.marque-texte strong { font-size: var(--t-md); letter-spacing: -0.01em; }
.marque-texte small { opacity: 0.82; font-size: var(--t-xs); text-transform: uppercase; letter-spacing: 0.08em; }

.entete-compte { display: flex; align-items: center; gap: var(--e2); }

.avatar {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.22);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3);
  font-weight: var(--gras-fort);
  font-size: var(--t-sm);
}

.entete-nom {
  display: none;
  font-weight: var(--gras-moyen);
  font-size: var(--t-sm);
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Bouton de déconnexion dans l'en-tête sombre : contour clair, pas de fond blanc. */
.bouton-entete {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.35);
  color: #f8fafc;
  min-height: var(--cible-min);
  padding: var(--e2) var(--e3);
  font-size: var(--t-sm);
}

.bouton-entete:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.22);
  border-color: rgba(255, 255, 255, 0.6);
}

/* --- Onglets --- */

.onglets {
  display: flex;
  gap: var(--e1);
  margin-top: var(--e3);
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.onglets::-webkit-scrollbar { display: none; }

.onglet {
  position: relative;
  flex: 0 0 auto;
  min-height: var(--cible-min);
  padding: var(--e3) var(--e4);
  border: 0;
  border-radius: var(--r-sm) var(--r-sm) 0 0;
  background: rgba(255, 255, 255, 0.1);
  color: #e0ecff;
  font: inherit;
  font-weight: var(--gras-moyen);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--tr-rapide), color var(--tr-rapide);
}

.onglet:hover:not(.onglet-actif) { background: rgba(255, 255, 255, 0.2); color: #fff; }
.onglet:focus-visible { outline-offset: -3px; }

.onglet-actif {
  background: #f6f9ff;
  color: var(--bleu);
  font-weight: var(--gras-fort);
}

.contenu {
  padding: var(--e4) var(--e3) var(--e8);
  padding-bottom: max(var(--e8), env(safe-area-inset-bottom));
  max-width: var(--largeur-contenu);
  margin: 0 auto;
}


/* ---------------------------------------------------------------------------
   5. BLOCS DE CONTENU
   --------------------------------------------------------------------------- */

.pile { display: flex; flex-direction: column; gap: var(--e4); }

.carte {
  background: var(--carte);
  border: 1px solid var(--bordure-douce);
  border-radius: var(--r-md);
  box-shadow: var(--o1);
  padding: var(--e5) var(--e4);
}

/* Liseré de couleur en tête de carte : repère visuel du type de contenu. */
.carte-jour   { border-top: 4px solid var(--bleu); }
.carte-chrono { border-top: 4px solid var(--vert); }
.carte-fin    { border-top: 4px solid var(--ambre); }
.carte-photos { border-top: 4px solid var(--cyan); }
.carte-documents { border-top: 4px solid var(--bleu-clair); }

.entete-section {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--e3);
  flex-wrap: wrap;
  margin-bottom: var(--e4);
}

.surtitre {
  color: var(--bleu);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: var(--t-xs);
  font-weight: var(--gras-extra);
  margin-bottom: var(--e1);
}

.titre-section { font-size: var(--t-xl); }
.titre-bloc { font-size: var(--t-lg); margin-bottom: var(--e2); }

.entete-bloc {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e2);
  flex-wrap: wrap;
  margin-bottom: var(--e2);
}

.bloc-formulaire {
  margin-top: var(--e5);
  padding-top: var(--e4);
  border-top: 1px solid var(--bordure-douce);
}

/* --- État vide soigné : ce n'est pas une ligne perdue, c'est une mise en page. --- */

.vide {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e2);
  padding: var(--e7) var(--e4);
  border: 1px dashed var(--bordure);
  border-radius: var(--r-md);
  background: var(--carte-douce);
  text-align: center;
  color: var(--texte-doux);
}

.vide-icone {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--survol);
  color: var(--bleu-vif);
  margin-bottom: var(--e1);
}

.vide-titre {
  font-size: var(--t-md);
  font-weight: var(--gras-fort);
  color: var(--texte);
}

.vide-detail {
  font-size: var(--t-sm);
  max-width: 44ch;
}

.aide {
  color: var(--texte-doux);
  font-size: var(--t-sm);
  margin-top: var(--e2);
}

.mention {
  display: inline-flex;
  align-items: center;
  gap: var(--e2);
  padding: var(--e2) var(--e3);
  border-radius: var(--r-sm);
  background: var(--ardoise-fond);
  color: var(--texte-doux);
  font-size: var(--t-sm);
  font-weight: var(--gras-moyen);
}

.mention-info { background: var(--survol); color: #1e3a8a; }
.mention-attention { background: var(--ambre-fond); color: var(--ambre); }


/* ---------------------------------------------------------------------------
   6. BOUTONS
   Chaque variante possède ses cinq états : repos, survol, focus, actif,
   désactivé — plus un état « occupé » quand une requête est en cours.
   --------------------------------------------------------------------------- */

.bouton {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e2);
  min-height: var(--cible);
  padding: var(--e3) var(--e5);
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  font: inherit;
  font-weight: var(--gras-fort);
  line-height: 1.2;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition:
    background-color var(--tr-rapide),
    border-color var(--tr-rapide),
    color var(--tr-rapide),
    box-shadow var(--tr-rapide),
    transform var(--tr-rapide);
}

.bouton:active:not(:disabled) { transform: translateY(1px); }

.bouton:disabled,
.bouton[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
}

.bouton-principal {
  background: var(--bleu);
  color: #fff;
  box-shadow: var(--o1);
}
.bouton-principal:hover:not(:disabled) { background: var(--bleu-clair); box-shadow: var(--o2); }
.bouton-principal:active:not(:disabled) { background: #1e40af; }

.bouton-discret {
  background: #fff;
  border-color: var(--bordure);
  color: var(--bleu-nuit);
}
.bouton-discret:hover:not(:disabled) { background: var(--survol); border-color: var(--bleu-vif); color: var(--bleu); }
.bouton-discret:active:not(:disabled) { background: #dbeafe; }

.bouton-valider {
  background: var(--vert);
  color: #fff;
  box-shadow: var(--o1);
}
.bouton-valider:hover:not(:disabled) { background: #166534; box-shadow: var(--o2); }

.bouton-danger {
  background: var(--rouge-fond);
  border-color: var(--rouge-bord);
  color: var(--rouge);
}
.bouton-danger:hover:not(:disabled) { background: #fee2e2; border-color: var(--rouge); }


.bouton-pleine-largeur { width: 100%; }
.bouton-grand { min-height: var(--cible-grande); font-size: var(--t-lg); padding: var(--e3) var(--e6); }

.bouton-retour {
  align-self: flex-start;
  background: transparent;
  border-color: transparent;
  color: var(--bleu);
  padding-left: var(--e2);
  padding-right: var(--e3);
  font-weight: var(--gras-moyen);
}
.bouton-retour:hover:not(:disabled) { background: var(--survol); }

.ligne-boutons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2);
  align-items: center;
}

.bouton-rond {
  display: grid;
  place-items: center;
  width: var(--cible);
  height: var(--cible);
  flex-shrink: 0;
  border: 1px solid var(--bordure);
  border-radius: 50%;
  background: #fff;
  color: var(--bleu);
  cursor: pointer;
  transition: background-color var(--tr-rapide), border-color var(--tr-rapide), transform var(--tr-rapide);
}
.bouton-rond:hover { background: var(--survol); border-color: var(--bleu); }
.bouton-rond:active { transform: scale(0.94); }
.bouton-rond-danger { color: var(--rouge); border-color: var(--rouge-bord); }
.bouton-rond-danger:hover { background: var(--rouge-fond); border-color: var(--rouge); }

/* --- État « occupé » : le bouton montre qu'il travaille --- */

.bouton-occupe {
  color: transparent !important;
  pointer-events: none;
}

.bouton-occupe > * { visibility: hidden; }

.bouton-occupe::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 20px;
  height: 20px;
  margin: -10px 0 0 -10px;
  border: 2.5px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  color: inherit;
  animation: rotation 640ms linear infinite;
  /* La couleur du trait doit rester visible : on la reprend explicitement. */
}

.bouton-principal.bouton-occupe::after,
.bouton-valider.bouton-occupe::after { border-color: #fff; border-top-color: transparent; }

.bouton-discret.bouton-occupe::after,
.bouton-danger.bouton-occupe::after,
.bouton-retour.bouton-occupe::after { border-color: var(--bleu); border-top-color: transparent; }

@keyframes rotation {
  to { transform: rotate(360deg); }
}


/* ---------------------------------------------------------------------------
   7. FORMULAIRES
   --------------------------------------------------------------------------- */

.champ {
  display: flex;
  flex-direction: column;
  gap: var(--e2);
  margin-bottom: var(--e4);
}

.champ-libelle {
  font-weight: var(--gras-fort);
  font-size: var(--t-sm);
  color: var(--bleu-nuit);
}

.champ-indication {
  font-size: var(--t-xs);
  color: var(--texte-tres-doux);
  font-weight: var(--gras-normal);
  margin-top: calc(var(--e1) * -1);
}

.champ-saisie {
  width: 100%;
  min-height: var(--cible);
  padding: var(--e3) var(--e4);
  border: 2px solid var(--bordure);
  border-radius: var(--r-sm);
  background: #fff;
  color: var(--texte);
  font: inherit;
  font-size: var(--t-md); /* 16 px : empêche le zoom automatique sur iOS */
  transition: border-color var(--tr-rapide), box-shadow var(--tr-rapide), background-color var(--tr-rapide);
}

.champ-saisie:hover:not(:disabled):not(:focus) { border-color: #94a3b8; }
.champ-saisie:focus { border-color: var(--bleu); box-shadow: var(--anneau); outline: none; }
.champ-saisie:disabled { background: var(--ardoise-fond); color: var(--texte-tres-doux); cursor: not-allowed; }
.champ-saisie[aria-invalid="true"] { border-color: var(--rouge); }

/* Les listes déroulantes sont dessinées par le système : on garde la
   même boîte que les champs texte pour l'alignement. */
select.champ-saisie {
  appearance: none;
  -webkit-appearance: none;
  padding-right: var(--e8);
  /* Chevron dessiné en CSS pur : aucune image externe. */
  background-image:
    linear-gradient(45deg, transparent 50%, var(--texte-doux) 50%),
    linear-gradient(135deg, var(--texte-doux) 50%, transparent 50%);
  background-position:
    calc(100% - 22px) calc(50% + 2px),
    calc(100% - 16px) calc(50% + 2px);
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  cursor: pointer;
}

.champ-zone { min-height: 130px; resize: vertical; line-height: 1.6; }

.champ-motdepasse { display: flex; gap: var(--e2); align-items: stretch; }
.champ-motdepasse .champ-saisie { flex: 1; min-width: 0; }
.bouton-oeil { flex-shrink: 0; white-space: nowrap; }

/* Champ fichier masqué : c'est le <label> associé qui sert de bouton. */
.champ-fichier {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Le label-bouton doit montrer le focus du champ fichier qu'il pilote. */
.champ-fichier:focus-visible + .bouton,
.bouton:has(+ .champ-fichier:focus-visible) {
  outline: 3px solid var(--cyan);
  outline-offset: 2px;
}

.grille-champs { display: grid; grid-template-columns: 1fr; gap: 0 var(--e5); }
.grille-cases { display: grid; grid-template-columns: 1fr; gap: var(--e1); }

.case-a-cocher {
  display: flex;
  align-items: center;
  gap: var(--e3);
  min-height: var(--cible);
  padding: var(--e2) var(--e2);
  border-radius: var(--r-sm);
  cursor: pointer;
  font-weight: var(--gras-moyen);
  transition: background-color var(--tr-rapide);
}

.case-a-cocher:hover { background: var(--survol); }

.case-a-cocher input {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  accent-color: var(--bleu);
  cursor: pointer;
}

.case-a-cocher input:focus-visible { outline: 3px solid var(--cyan); outline-offset: 2px; }

/* --- Interrupteur (activation / désactivation d'une option) --- */

.interrupteur {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e4);
  min-height: var(--cible-grande);
  padding: var(--e3) var(--e4);
  border: 1px solid var(--bordure-douce);
  border-radius: var(--r-md);
  background: var(--carte-douce);
  cursor: pointer;
  transition: border-color var(--tr-rapide), background-color var(--tr-rapide);
}

.interrupteur:hover { border-color: var(--bleu-vif); background: var(--survol); }

.interrupteur-texte { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.interrupteur-titre { font-weight: var(--gras-fort); font-size: var(--t-md); }
.interrupteur-detail { font-size: var(--t-sm); color: var(--texte-doux); }

.interrupteur-boite {
  position: relative;
  flex-shrink: 0;
  width: 56px;
  height: 32px;
  border-radius: var(--r-plein);
  background: #94a3b8;
  transition: background-color var(--tr-moyen);
}

.interrupteur-boite::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: #fff;
  box-shadow: var(--o1);
  transition: transform var(--tr-moyen);
}

.interrupteur input { position: absolute; opacity: 0; width: 0; height: 0; }
.interrupteur input:checked + .interrupteur-boite { background: var(--vert); }
.interrupteur input:checked + .interrupteur-boite::after { transform: translateX(24px); }
.interrupteur input:focus-visible + .interrupteur-boite { box-shadow: var(--anneau); }
.interrupteur input:disabled + .interrupteur-boite { opacity: 0.5; }

.message-formulaire {
  margin: var(--e3) 0;
  font-size: var(--t-sm);
  color: var(--texte-doux);
  min-height: 1.4em;
}

.message-erreur {
  color: var(--rouge);
  font-weight: var(--gras-fort);
  padding: var(--e3) var(--e3);
  border-radius: var(--r-sm);
  background: var(--rouge-fond);
  border: 1px solid var(--rouge-bord);
}

.message-succes {
  color: var(--vert);
  font-weight: var(--gras-fort);
  padding: var(--e3) var(--e3);
  border-radius: var(--r-sm);
  background: var(--vert-fond);
  border: 1px solid var(--vert-bord);
}

/* --- Champ de durée : deux grandes cases heures / minutes --- */

.champ-duree { margin-bottom: var(--e4); }

.duree-cases { display: flex; align-items: center; gap: var(--e2); }

.duree-case {
  width: 88px;
  min-height: var(--cible-grande);
  padding: var(--e2);
  border: 2px solid var(--bordure);
  border-radius: var(--r-sm);
  background: #fff;
  font-family: var(--police-chiffres);
  font-size: var(--t-2xl);
  font-weight: var(--gras-fort);
  text-align: center;
  color: var(--texte);
  font-variant-numeric: tabular-nums;
  transition: border-color var(--tr-rapide), box-shadow var(--tr-rapide);
}

.duree-case:hover:not(:focus) { border-color: #94a3b8; }
.duree-case:focus { border-color: var(--bleu); box-shadow: var(--anneau); outline: none; }

.duree-separateur {
  font-size: var(--t-2xl);
  font-weight: var(--gras-extra);
  color: var(--texte-tres-doux);
}


.grille-durees { display: grid; grid-template-columns: 1fr; gap: 0; }


/* ---------------------------------------------------------------------------
   8. ÉCRAN DE CONNEXION
   --------------------------------------------------------------------------- */

.app-connexion {
  display: grid;
  place-items: center;
  padding: var(--e7) var(--e4);
  min-height: 100vh;
  min-height: 100dvh;
}

.ecran-connexion {
  width: 100%;
  max-width: 440px;
  display: flex;
  flex-direction: column;
  gap: var(--e6);
}

.connexion-marque {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e3);
  text-align: center;
}

.connexion-baseline {
  color: var(--texte-doux);
  font-weight: var(--gras-moyen);
}

.carte-connexion { padding: var(--e6) var(--e5); box-shadow: var(--o2); }
.titre-connexion { font-size: var(--t-2xl); margin-bottom: var(--e1); }
.sous-titre-connexion { color: var(--texte-doux); margin-bottom: var(--e5); font-size: var(--t-sm); }



/* ---------------------------------------------------------------------------
   9. STATUTS ET AVANCEMENT
   --------------------------------------------------------------------------- */

.statut {
  display: inline-flex;
  align-items: center;
  gap: var(--e1);
  padding: var(--e1) var(--e3);
  border-radius: var(--r-plein);
  border: 1px solid;
  font-size: var(--t-xs);
  font-weight: var(--gras-extra);
  letter-spacing: 0.01em;
  white-space: nowrap;
}

.statut::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

.statut-gris  { background: var(--ardoise-fond); border-color: var(--bordure); color: #334155; }
.statut-cyan  { background: #ecfeff; border-color: #67e8f9; color: #0e7490; }
.statut-bleu  { background: var(--survol); border-color: #93c5fd; color: var(--bleu); }
.statut-ambre { background: var(--ambre-fond); border-color: var(--ambre-bord); color: var(--ambre); }
.statut-vert  { background: var(--vert-fond); border-color: var(--vert-bord); color: var(--vert); }

.avancement {
  position: relative;
  height: 26px;
  min-width: 110px;
  border-radius: var(--r-plein);
  background: var(--bordure-douce);
  overflow: hidden;
  box-shadow: inset 0 1px 2px rgba(15, 23, 42, 0.08);
}

.avancement-barre {
  width: var(--avancement, 0%);
  height: 100%;
  background: linear-gradient(90deg, var(--bleu-clair), var(--cyan));
  transition: width var(--tr-moyen);
}

.avancement-alerte .avancement-barre {
  background: linear-gradient(90deg, #d97706, #f59e0b);
}

.avancement-depasse .avancement-barre {
  background: linear-gradient(90deg, #dc2626, #f97316);
}

.avancement-texte {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: var(--t-xs);
  font-weight: var(--gras-extra);
  color: var(--bleu-nuit);
  font-variant-numeric: tabular-nums;
}


/* ---------------------------------------------------------------------------
   10. LISTE DES CHANTIERS
   --------------------------------------------------------------------------- */

.liste-chantiers { display: flex; flex-direction: column; gap: var(--e3); }

.chantier-carte {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--e1);
  width: 100%;
  min-height: 92px;
  padding: var(--e4) var(--e8) var(--e4) var(--e4);
  border: 2px solid #bfdbfe;
  border-radius: var(--r-md);
  background: var(--survol);
  color: var(--texte);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition:
    border-color var(--tr-rapide),
    box-shadow var(--tr-rapide),
    transform var(--tr-rapide),
    background-color var(--tr-rapide);
}

.chantier-carte:hover {
  border-color: var(--bleu);
  box-shadow: var(--o2);
  transform: translateY(-1px);
}

.chantier-carte:active { transform: translateY(0); box-shadow: var(--o1); }

.chantier-carte-active {
  border-color: var(--vert);
  background: var(--vert-fond);
  box-shadow: 0 0 0 3px rgba(21, 128, 61, 0.15);
}

.chantier-carte-active:hover { border-color: var(--vert); }

.chantier-carte-haut {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e2);
  margin-bottom: 2px;
}

.chantier-heure {
  font-size: var(--t-lg);
  font-weight: var(--gras-extra);
  color: var(--bleu);
  font-variant-numeric: tabular-nums;
}

.chantier-societe { font-size: var(--t-lg); font-weight: var(--gras-fort); }
.chantier-adresse { color: var(--texte-doux); font-size: var(--t-sm); }

.chantier-chrono-actif {
  display: inline-flex;
  align-items: center;
  gap: var(--e2);
  margin-top: var(--e2);
  font-weight: var(--gras-extra);
  color: var(--vert);
  font-size: var(--t-sm);
}

.chantier-chrono-actif::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--vert);
  animation: pulsation 1.6s ease-in-out infinite;
}

@keyframes pulsation {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.35; transform: scale(0.8); }
}

.chantier-fleche {
  position: absolute;
  right: var(--e3);
  top: 50%;
  transform: translateY(-50%);
  color: var(--bleu);
  transition: transform var(--tr-rapide);
}

.chantier-carte:hover .chantier-fleche { transform: translateY(-50%) translateX(3px); }


/* ---------------------------------------------------------------------------
   11. FICHE CHANTIER ET CHRONOMÈTRE
   --------------------------------------------------------------------------- */

.pile-fiche { gap: var(--e4); }

.fiche-entete {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--e3);
  flex-wrap: wrap;
  margin-bottom: var(--e4);
}

.fiche-titre { font-size: var(--t-2xl); }

.fiche-liens {
  display: flex;
  flex-direction: column;
  gap: var(--e2);
  margin-bottom: var(--e4);
}

.lien-action {
  display: flex;
  align-items: center;
  gap: var(--e3);
  min-height: var(--cible);
  padding: var(--e3) var(--e4);
  border: 2px solid #bfdbfe;
  border-radius: var(--r-sm);
  background: var(--survol);
  color: var(--bleu);
  font-weight: var(--gras-fort);
  text-decoration: none;
  transition: border-color var(--tr-rapide), background-color var(--tr-rapide);
}

.lien-action:hover { border-color: var(--bleu); background: #dbeafe; }

.fiche-details {
  display: grid;
  grid-template-columns: minmax(130px, auto) 1fr;
  gap: var(--e2) var(--e4);
  margin: 0 0 var(--e4);
  font-size: var(--t-sm);
}

.fiche-details dt { color: var(--texte-doux); font-weight: var(--gras-moyen); }
.fiche-details dd { margin: 0; font-weight: var(--gras-fort); min-width: 0; }

.fiche-cumul {
  margin-top: var(--e3);
  font-weight: var(--gras-fort);
  color: var(--bleu-nuit);
  font-variant-numeric: tabular-nums;
}

/* --- Chronomètre : l'élément central de la vue terrain --- */

.chrono-bloc {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e1);
  padding: var(--e4) 0 var(--e5);
}

.chrono-valeur {
  font-family: var(--police-chiffres);
  font-size: clamp(3rem, 16vw, 4.25rem);
  font-weight: var(--gras-extra);
  letter-spacing: 0.02em;
  color: var(--bleu-nuit);
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
}

.chrono-etat {
  display: inline-flex;
  align-items: center;
  gap: var(--e2);
  font-weight: var(--gras-fort);
  color: var(--texte-doux);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: var(--t-xs);
}

.chrono-etat-actif { color: var(--vert); }

.chrono-etat-actif::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--vert);
  animation: pulsation 1.6s ease-in-out infinite;
}

.bouton-chrono {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--e3);
  width: 100%;
  min-height: 82px;
  border: 0;
  border-radius: var(--r-md);
  background: var(--vert);
  color: #fff;
  font: inherit;
  font-size: var(--t-lg);
  font-weight: var(--gras-extra);
  cursor: pointer;
  box-shadow: 0 4px 0 var(--vert-sombre), var(--o2);
  transition: transform var(--tr-rapide), box-shadow var(--tr-rapide), background-color var(--tr-rapide);
}

.bouton-chrono:hover:not(:disabled) { background: #166534; }
.bouton-chrono:active:not(:disabled) { transform: translateY(3px); box-shadow: 0 1px 0 var(--vert-sombre); }
.bouton-chrono:disabled { opacity: 0.6; cursor: progress; }

.bouton-chrono-arret {
  background: var(--rouge);
  box-shadow: 0 4px 0 var(--rouge-sombre), var(--o2);
}

.bouton-chrono-arret:hover:not(:disabled) { background: #991b1b; }
.bouton-chrono-arret:active:not(:disabled) { box-shadow: 0 1px 0 var(--rouge-sombre); }

/* --- Historique replié --- */

.repli {
  margin-top: var(--e4);
  border: 1px solid var(--bordure-douce);
  border-radius: var(--r-sm);
  background: var(--carte-douce);
}

.repli summary {
  min-height: var(--cible);
  display: flex;
  align-items: center;
  gap: var(--e2);
  padding: 0 var(--e3);
  font-weight: var(--gras-fort);
  color: var(--bleu);
  cursor: pointer;
  border-radius: var(--r-sm);
}

.repli summary:hover { background: var(--survol); }
.repli[open] summary { border-bottom: 1px solid var(--bordure-douce); border-radius: var(--r-sm) var(--r-sm) 0 0; }

.liste-historique {
  list-style: none;
  margin: 0;
  padding: var(--e3);
  display: flex;
  flex-direction: column;
  gap: var(--e2);
}

.liste-historique li {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--e3);
  border: 1px solid var(--bordure-douce);
  border-radius: var(--r-sm);
  background: #fff;
  font-size: var(--t-sm);
}

.liste-historique span { color: var(--texte-doux); }
.liste-historique strong { font-variant-numeric: tabular-nums; }

/* --- Fin de chantier --- */

.fin-message {
  display: flex;
  align-items: center;
  gap: var(--e3);
  font-weight: var(--gras-fort);
  color: var(--vert);
}

.confirmation-question {
  margin: var(--e3) 0;
  font-weight: var(--gras-extra);
  font-size: var(--t-md);
}

.confirmation-en-ligne {
  display: inline-flex;
  align-items: center;
  gap: var(--e2);
  flex-wrap: wrap;
  font-weight: var(--gras-fort);
  color: var(--rouge);
}


/* ---------------------------------------------------------------------------
   12. MATÉRIEL
   --------------------------------------------------------------------------- */

.liste-materiaux { display: flex; flex-direction: column; gap: var(--e2); }

.materiau-ligne {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e3);
  flex-wrap: wrap;
  padding: var(--e3);
  border: 1px solid var(--bordure-douce);
  border-radius: var(--r-sm);
  background: var(--carte-douce);
  transition: border-color var(--tr-rapide), background-color var(--tr-rapide);
}

.materiau-ligne:hover { border-color: var(--bordure); background: #fff; }

.materiau-nom { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.materiau-nom strong { font-size: var(--t-md); }
.materiau-nom small { color: var(--texte-doux); font-size: var(--t-xs); }

.materiau-controles { display: flex; align-items: center; gap: var(--e2); }

.materiau-quantite {
  width: 78px;
  min-height: var(--cible);
  padding: var(--e2);
  border: 2px solid var(--bordure);
  border-radius: var(--r-sm);
  background: #fff;
  font-family: var(--police-chiffres);
  font-size: var(--t-lg);
  font-weight: var(--gras-fort);
  text-align: center;
  color: var(--texte);
  font-variant-numeric: tabular-nums;
  transition: border-color var(--tr-rapide), box-shadow var(--tr-rapide);
}

.materiau-quantite:focus { border-color: var(--bleu); box-shadow: var(--anneau); outline: none; }

.liste-materiaux-edition { display: flex; flex-direction: column; gap: var(--e2); }

.materiau-edition {
  display: grid;
  grid-template-columns: 1fr 84px 92px var(--cible);
  gap: var(--e2);
  align-items: center;
}

.materiau-edition .champ-saisie { min-height: var(--cible-min); }


/* ---------------------------------------------------------------------------
   13. PHOTOS
   --------------------------------------------------------------------------- */

.photo-bloc { margin-bottom: var(--e6); }
.photo-bloc:last-child { margin-bottom: 0; }

.photo-entete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e3);
  flex-wrap: wrap;
  margin-bottom: var(--e3);
}

.bouton-photo { min-height: var(--cible-grande); }

.photo-grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: var(--e2);
}

.photo-vignette {
  position: relative;
  margin: 0;
  border: 1px solid var(--bordure);
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--ardoise-fond);
  transition: border-color var(--tr-rapide), box-shadow var(--tr-rapide);
}

.photo-vignette:hover { border-color: var(--bleu); box-shadow: var(--o2); }

.photo-vignette img {
  width: 100%;
  height: 124px;
  object-fit: cover;
}

.photo-supprimer {
  position: absolute;
  top: var(--e1);
  right: var(--e1);
  width: var(--cible-min);
  height: var(--cible-min);
  border: 0;
  border-radius: 50%;
  background: rgba(15, 23, 42, 0.78);
  color: #fff;
  font-size: var(--t-xl);
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--tr-rapide), transform var(--tr-rapide);
}

.photo-supprimer:hover { background: var(--rouge); transform: scale(1.06); }

.photo-confirmation {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--e2);
  padding: var(--e2);
  background: rgba(255, 255, 255, 0.96);
}

.photo-confirmation .bouton { min-height: var(--cible-min); padding: var(--e2) var(--e3); font-size: var(--t-sm); }


/* ---------------------------------------------------------------------------
   14. DOCUMENTS PDF ATTACHÉS
   --------------------------------------------------------------------------- */

.depot-fichier {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e3);
  padding: var(--e6) var(--e4);
  border: 2px dashed var(--bordure);
  border-radius: var(--r-md);
  background: var(--carte-douce);
  text-align: center;
  transition: border-color var(--tr-rapide), background-color var(--tr-rapide);
}

.depot-fichier-survol {
  border-color: var(--bleu);
  border-style: solid;
  background: var(--survol);
}

.depot-titre { font-weight: var(--gras-fort); color: var(--texte); }
.depot-detail { font-size: var(--t-sm); color: var(--texte-doux); }
.depot-icone { color: var(--bleu-vif); }

.liste-documents {
  list-style: none;
  margin: var(--e4) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--e2);
}

.document-ligne {
  display: flex;
  align-items: center;
  gap: var(--e3);
  flex-wrap: wrap;
  padding: var(--e3);
  border: 1px solid var(--bordure-douce);
  border-radius: var(--r-sm);
  background: #fff;
  transition: border-color var(--tr-rapide), box-shadow var(--tr-rapide);
}

.document-ligne:hover { border-color: var(--bleu-vif); box-shadow: var(--o1); }

.document-icone {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  flex-shrink: 0;
  border-radius: var(--r-sm);
  background: var(--rouge-fond);
  color: var(--rouge);
}

.document-infos { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.document-nom { font-weight: var(--gras-fort); overflow-wrap: anywhere; }
.document-meta { font-size: var(--t-xs); color: var(--texte-doux); font-variant-numeric: tabular-nums; }

.document-actions { display: flex; gap: var(--e2); align-items: center; flex-wrap: wrap; }
.document-actions .bouton { min-height: var(--cible-min); padding: var(--e2) var(--e3); font-size: var(--t-sm); }

/* Barre d'envoi « indéterminée ».
   fetch() ne sait pas dire où en est un téléversement : afficher un
   pourcentage serait inventé. On montre donc un mouvement qui dit
   « ça travaille », sans prétendre à une progression chiffrée. */
.document-progression {
  width: 100%;
  height: 6px;
  margin-top: var(--e1);
  border-radius: var(--r-plein);
  background: var(--bordure-douce);
  overflow: hidden;
}

.document-progression-barre {
  width: 40%;
  height: 100%;
  border-radius: var(--r-plein);
  background: linear-gradient(90deg, var(--bleu-clair), var(--cyan));
  animation: va-et-vient 1.2s ease-in-out infinite;
}

@keyframes va-et-vient {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}


/* ---------------------------------------------------------------------------
   15. TABLEAUX ET TABLEAU DE BORD
   --------------------------------------------------------------------------- */

.grille-statistiques {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--e2);
}

.statistique {
  display: flex;
  flex-direction: column;
  gap: var(--e2);
  min-height: 92px;
  padding: var(--e4);
  border: 2px solid var(--bordure-douce);
  border-radius: var(--r-md);
  background: var(--carte-douce);
  color: var(--texte);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition:
    border-color var(--tr-rapide),
    background-color var(--tr-rapide),
    box-shadow var(--tr-rapide),
    transform var(--tr-rapide);
}

.statistique:hover { border-color: #93c5fd; background: var(--survol); transform: translateY(-1px); }
.statistique:active { transform: translateY(0); }

.statistique-active {
  border-color: var(--bleu);
  background: var(--survol);
  box-shadow: 0 0 0 3px rgba(29, 78, 216, 0.12);
}

.statistique-libelle { color: var(--texte-doux); font-weight: var(--gras-moyen); font-size: var(--t-sm); }
.statistique-valeur {
  font-size: var(--t-3xl);
  font-weight: var(--gras-extra);
  color: var(--bleu-nuit);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.tableau-defilant {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  /* Le tableau ne pousse jamais la page : il défile chez lui. */
  max-width: 100%;
  border-radius: var(--r-sm);
}

.tableau {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-sm);
}

.tableau th {
  padding: var(--e3);
  border-bottom: 2px solid var(--bordure);
  text-align: left;
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--texte-doux);
  white-space: nowrap;
  background: var(--carte-douce);
}

.tableau td {
  padding: var(--e3);
  border-bottom: 1px solid var(--bordure-douce);
  vertical-align: middle;
}

.tableau tbody tr { transition: background-color var(--tr-rapide); }
.tableau tbody tr:hover { background: var(--carte-douce); }
.tableau tbody tr:last-child td { border-bottom: 0; }

.cellule-secondaire { display: block; color: var(--texte-doux); font-size: var(--t-xs); }

.cellule-actions { white-space: nowrap; }
.cellule-actions .bouton {
  min-height: var(--cible-min);
  padding: var(--e2) var(--e3);
  margin: 2px var(--e1) 2px 0;
  font-size: var(--t-sm);
}

/* Sur téléphone, le tableau devient une pile de fiches lisibles.
   Aucun défilement horizontal ne subsiste. */
@media (max-width: 719px) {
  .tableau thead { display: none; }
  .tableau, .tableau tbody, .tableau tr, .tableau td { display: block; width: 100%; }

  .tableau tr {
    margin-bottom: var(--e3);
    border: 1px solid var(--bordure);
    border-radius: var(--r-sm);
    background: #fff;
    overflow: hidden;
    box-shadow: var(--o1);
  }

  .tableau td {
    display: grid;
    grid-template-columns: 40% 1fr;
    gap: var(--e2);
    align-items: center;
    border-bottom: 1px solid var(--bordure-douce);
  }

  .tableau td::before {
    content: attr(data-libelle);
    font-size: var(--t-xs);
    font-weight: var(--gras-fort);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--texte-doux);
  }

  .cellule-actions { display: flex !important; flex-wrap: wrap; gap: var(--e1); }
  .cellule-actions::before { display: none; }
}


/* ---------------------------------------------------------------------------
   16. FACTURATION
   --------------------------------------------------------------------------- */

.liste-factures { display: flex; flex-direction: column; gap: var(--e4); }

.facture-ligne {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--e4);
  padding: var(--e4);
  border: 1px solid var(--ambre-bord);
  border-left: 5px solid var(--ambre);
  border-radius: var(--r-sm);
  background: var(--ambre-fond);
}

.facture-infos { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.facture-infos strong { font-size: var(--t-lg); }
.facture-infos small { color: var(--texte-doux); font-size: var(--t-xs); }

.facture-chiffres {
  display: flex;
  flex-direction: column;
  gap: var(--e2);
  font-size: var(--t-sm);
  font-weight: var(--gras-moyen);
  font-variant-numeric: tabular-nums;
}

.facture-actions { display: flex; flex-wrap: wrap; gap: var(--e2); }
.facture-actions .bouton { background-color: #fff; }
.facture-actions .bouton-valider { background-color: var(--vert); }


/* ---------------------------------------------------------------------------
   17. CALENDRIER
   --------------------------------------------------------------------------- */

.navigation-mois {
  display: flex;
  align-items: center;
  gap: var(--e2);
  flex-wrap: wrap;
}

.navigation-mois .bouton {
  min-height: var(--cible-min);
  padding: var(--e2) var(--e3);
  font-size: var(--t-sm);
}

.mois-libelle {
  font-size: var(--t-md);
  min-width: 160px;
  text-align: center;
  font-weight: var(--gras-fort);
}

.calendrier { margin-bottom: var(--e5); }

.calendrier-entete,
.calendrier-grille {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--e1);
}

.calendrier-entete {
  margin-bottom: var(--e2);
  text-align: center;
  font-size: var(--t-xs);
  font-weight: var(--gras-extra);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--texte-doux);
}

.calendrier-jour {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-height: 54px;
  padding: var(--e1);
  border: 1px solid var(--bordure-douce);
  border-radius: var(--r-xs);
  background: #fff;
  color: var(--texte);
  font: inherit;
  cursor: pointer;
  transition: border-color var(--tr-rapide), background-color var(--tr-rapide), transform var(--tr-rapide);
}

.calendrier-jour:hover { border-color: var(--bleu); background: var(--survol); }
.calendrier-jour:active { transform: scale(0.96); }

.calendrier-jour-hors { opacity: 0.38; }
.calendrier-jour-weekend { background: var(--carte-douce); }

.calendrier-jour-aujourdhui {
  border-color: var(--bleu);
  border-width: 2px;
  font-weight: var(--gras-extra);
}

.calendrier-jour-choisi {
  background: var(--bleu);
  border-color: var(--bleu);
  color: #fff;
}

.calendrier-jour-choisi:hover { background: var(--bleu-clair); }
.calendrier-jour-choisi .calendrier-pastille { background: #fff; color: var(--bleu); }

.calendrier-numero { font-size: var(--t-sm); font-weight: var(--gras-moyen); font-variant-numeric: tabular-nums; }

.calendrier-pastille {
  display: grid;
  place-items: center;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border-radius: var(--r-plein);
  background: var(--bleu);
  color: #fff;
  font-size: var(--t-xs);
  font-weight: var(--gras-extra);
}

.calendrier-details {
  padding-top: var(--e4);
  border-top: 1px solid var(--bordure-douce);
}

.calendrier-details .titre-bloc { margin-bottom: var(--e3); text-transform: capitalize; }


/* ---------------------------------------------------------------------------
   18. RÉGLAGES (administrateur)
   --------------------------------------------------------------------------- */

.reglages-groupe { display: flex; flex-direction: column; gap: var(--e3); }

.reglages-apercu {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--e2);
  padding: var(--e4);
  border: 1px solid var(--bordure-douce);
  border-radius: var(--r-sm);
  background: var(--carte-douce);
  font-size: var(--t-sm);
}

.reglages-apercu-ligne {
  display: flex;
  justify-content: space-between;
  gap: var(--e3);
  align-items: baseline;
}

.reglages-apercu-libelle { color: var(--texte-doux); }
.reglages-apercu-valeur { font-weight: var(--gras-fort); font-variant-numeric: tabular-nums; }


/* ---------------------------------------------------------------------------
   19. ENREGISTREMENT AUTOMATIQUE
   L'indicateur est visible et honnête : il ne dit « enregistré » que lorsque
   le serveur a confirmé.
   --------------------------------------------------------------------------- */

/* Bandeau fin sous l'en-tête : réseau et file d'attente. */
.barre-reseau {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--e2);
  padding: var(--e2) var(--e4);
  font-size: var(--t-sm);
  font-weight: var(--gras-fort);
  background: var(--ambre-fond);
  color: var(--ambre);
  border-bottom: 1px solid var(--ambre-bord);
}

.barre-reseau[hidden] { display: none; }

.barre-reseau-icone {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
  animation: pulsation 1.8s ease-in-out infinite;
}

/* Conteneur de l'indicateur et de son explication, en tête de bloc. */
.zone-auto { margin-bottom: var(--e4); }

.zone-etat {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--e2);
}

/* Étiquette d'état placée en tête de chaque bloc auto-enregistré. */
.etat-sauvegarde {
  display: inline-flex;
  align-items: center;
  gap: var(--e2);
  min-height: 30px;
  padding: var(--e1) var(--e3);
  border: 1px solid var(--bordure-douce);
  border-radius: var(--r-plein);
  background: var(--ardoise-fond);
  color: var(--texte-doux);
  font-size: var(--t-xs);
  font-weight: var(--gras-fort);
  white-space: nowrap;
  transition: background-color var(--tr-moyen), color var(--tr-moyen), border-color var(--tr-moyen);
}

.etat-sauvegarde::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

/* Au repos, rien n'a changé : discret. */
.etat-repos { background: var(--ardoise-fond); border-color: var(--bordure-douce); color: var(--texte-tres-doux); }

/* Modifications non enregistrées : ambre, on doit le remarquer. */
.etat-modifie { background: var(--ambre-fond); border-color: var(--ambre-bord); color: var(--ambre); }

/* Envoi en cours : bleu, avec un anneau qui tourne. */
.etat-envoi { background: var(--survol); border-color: #93c5fd; color: var(--bleu); }

.etat-envoi::before {
  width: 11px;
  height: 11px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  background: none;
  animation: rotation 640ms linear infinite;
}

/* Enregistré : vert, avec l'heure exacte. */
.etat-enregistre { background: var(--vert-fond); border-color: var(--vert-bord); color: var(--vert); }

/* En attente de réseau : gris-ambre, la donnée est conservée. */
.etat-attente { background: var(--ambre-fond); border-color: var(--ambre-bord); color: var(--ambre); }

/* Refus du serveur (chantier facturé, date hors fenêtre) : rouge, explicite. */
.etat-refus { background: var(--rouge-fond); border-color: var(--rouge-bord); color: var(--rouge); }

/* Conflit : quelqu'un d'autre a modifié entre-temps. */
.etat-conflit { background: #f5f3ff; border-color: #c4b5fd; color: #6d28d9; }

/* Explication longue, affichée sous l'étiquette quand le serveur refuse. */
.explication-sauvegarde {
  margin-top: var(--e2);
  padding: var(--e3);
  border-radius: var(--r-sm);
  font-size: var(--t-sm);
  font-weight: var(--gras-moyen);
  line-height: 1.5;
}

.explication-refus { background: var(--rouge-fond); border: 1px solid var(--rouge-bord); color: var(--rouge-sombre); }
.explication-attente { background: var(--ambre-fond); border: 1px solid var(--ambre-bord); color: #78350f; }
.explication-conflit { background: #f5f3ff; border: 1px solid #c4b5fd; color: #5b21b6; }

/* Rappel de brouillon retrouvé au retour sur la page. */
.rappel-brouillon {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e3);
  flex-wrap: wrap;
  margin-bottom: var(--e4);
  padding: var(--e3) var(--e4);
  border: 1px solid var(--ambre-bord);
  border-left: 4px solid var(--ambre);
  border-radius: var(--r-sm);
  background: var(--ambre-fond);
  color: #78350f;
  font-size: var(--t-sm);
  font-weight: var(--gras-moyen);
}

.rappel-brouillon .bouton { min-height: var(--cible-min); padding: var(--e2) var(--e3); font-size: var(--t-sm); }


/* ---------------------------------------------------------------------------
   20. SQUELETTES DE CHARGEMENT
   Plutôt qu'un écran blanc : on montre la forme de ce qui arrive.
   --------------------------------------------------------------------------- */

.squelette {
  border-radius: var(--r-xs);
  background:
    linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 37%, #e2e8f0 63%);
  background-size: 400% 100%;
  animation: squelette-defilement 1.4s ease-in-out infinite;
}

@keyframes squelette-defilement {
  from { background-position: 100% 50%; }
  to   { background-position: 0 50%; }
}

.squelette-ligne { height: 14px; margin-bottom: var(--e2); }
.squelette-ligne:last-child { margin-bottom: 0; }
.squelette-titre { height: 22px; width: 45%; margin-bottom: var(--e4); }
.squelette-court { width: 60%; }
.squelette-moyen { width: 80%; }

.squelette-carte {
  height: 92px;
  border-radius: var(--r-md);
  margin-bottom: var(--e3);
}

.squelette-statistique { height: 92px; border-radius: var(--r-md); }


/* ---------------------------------------------------------------------------
   21. VUE TECHNICIEN : tout est plus gros
   Utilisée dehors, sur un téléphone, avec des gants.
   --------------------------------------------------------------------------- */

.app-user { font-size: 17px; }
.app-user .titre-section { font-size: 1.45rem; }
.app-user .chantier-societe { font-size: 1.25rem; }
.app-user .chantier-heure { font-size: 1.4rem; }
.app-user .bouton { min-height: var(--cible-grande); font-size: 1.05rem; }
.app-user .bouton-entete { min-height: var(--cible); font-size: var(--t-sm); }
.app-user .champ-saisie { min-height: var(--cible-grande); font-size: 1.05rem; }
.app-user .champ-libelle { font-size: 1rem; }
.app-user .onglet { min-height: var(--cible-grande); font-size: 1.02rem; }
.app-user .statut { font-size: 0.85rem; padding: var(--e2) var(--e3); }
.app-user .duree-case { width: 100px; min-height: 72px; font-size: 2rem; }
.app-user .fiche-details { font-size: 1rem; }
.app-user .materiau-quantite { width: 92px; min-height: var(--cible-grande); font-size: 1.5rem; }
.app-user .bouton-rond { width: var(--cible-grande); height: var(--cible-grande); }
.app-user .etat-sauvegarde { font-size: 0.82rem; min-height: 34px; }
.app-user .repli summary { min-height: var(--cible-grande); }


/* ---------------------------------------------------------------------------
   21bis. TRÈS PETITS ÉCRANS (iPhone SE et assimilés, 320 à 379 px)
   Rien ne doit déborder, même à 320 px de large. Les grilles serrées
   redeviennent des colonnes.
   --------------------------------------------------------------------------- */

@media (max-width: 379px) {
  .contenu { padding-left: var(--e2); padding-right: var(--e2); }
  .carte { padding: var(--e4) var(--e3); }

  /* Désignation / quantité / unité / suppression : une ligne chacun. */
  .materiau-edition {
    grid-template-columns: 1fr var(--cible);
    grid-template-areas:
      "nom      retirer"
      "quantite retirer"
      "unite    retirer";
    row-gap: var(--e1);
  }
  .materiau-edition > *:nth-child(1) { grid-area: nom; }
  .materiau-edition > *:nth-child(2) { grid-area: quantite; }
  .materiau-edition > *:nth-child(3) { grid-area: unite; }
  .materiau-edition > *:nth-child(4) { grid-area: retirer; align-self: center; }

  /* Libellé au-dessus de la valeur : deux colonnes ne tiennent plus. */
  .fiche-details { grid-template-columns: 1fr; gap: var(--e1) 0; }
  .fiche-details dd { margin-bottom: var(--e2); }

  /* Vignettes photo : deux par ligne plutôt qu'une seule très large. */
  .photo-grille { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
  .photo-vignette img { height: 100px; }

  /* Les tuiles de statut restent lisibles sur une colonne. */
  .grille-statistiques { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
  .statistique-valeur { font-size: var(--t-2xl); }

  /* La navigation de mois passe à la ligne proprement. */
  .mois-libelle { min-width: 100%; order: -1; }

  /* Les durées gardent de grandes cases mais ne poussent pas la page. */
  .duree-case { width: 76px; }
  .app-user .duree-case { width: 84px; font-size: 1.7rem; }

  /* Les actions d'un document passent sous son nom. */
  .document-actions { width: 100%; }
  .document-actions .bouton { flex: 1 1 auto; }
}


/* ---------------------------------------------------------------------------
   22. ÉCRANS LARGES
   --------------------------------------------------------------------------- */

@media (min-width: 720px) {
  .contenu { padding: var(--e6) var(--e6) var(--e8); }
  .carte { padding: var(--e6); }
  .entete { padding: var(--e5) var(--e6) 0; }
  .entete-nom { display: inline; }

  .grille-champs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .champ-large { grid-column: 1 / -1; }
  .grille-cases { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grille-durees { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--e5); }

  .fiche-liens { flex-direction: row; flex-wrap: wrap; }
  .fiche-liens .lien-action { flex: 1 1 260px; }

  .calendrier-jour { min-height: 78px; }
  .facture-ligne { grid-template-columns: 1.4fr 1fr; }
  .facture-actions { grid-column: 1 / -1; }
  .photo-vignette img { height: 152px; }

  .reglages-apercu { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--e2) var(--e5); }
}

@media (min-width: 1024px) {
  .grille-cases { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* La fiche chantier ne s'étire pas bêtement : une colonne de lecture. */
  .pile-fiche { max-width: var(--largeur-fiche); }
  .bouton-chrono { min-height: 92px; font-size: var(--t-xl); }
  .ecran-connexion { max-width: 460px; }
}

@media (min-width: 1400px) {
  /* Très grand écran : on limite la largeur du texte plutôt que de l'étirer. */
  .contenu { padding-left: var(--e7); padding-right: var(--e7); }
}


/* ---------------------------------------------------------------------------
   23. CONFORT, MOUVEMENT RÉDUIT, IMPRESSION
   --------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 1ms !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

/* Contraste renforcé : les bordures douces deviennent franches. */
@media (prefers-contrast: more) {
  :root {
    --bordure-douce: #94a3b8;
    --texte-doux: #334155;
    --texte-tres-doux: #475569;
  }
}

@media print {
  .entete, .onglets, .bandeau, .bouton, .bouton-chrono,
  .barre-reseau, .etat-sauvegarde, .depot-fichier { display: none !important; }
  body { background: #fff; }
  .carte { box-shadow: none; border: 1px solid #999; break-inside: avoid; }
  .tableau-defilant { overflow: visible; }
}


/* ---------------------------------------------------------------------------
   24. AJUSTEMENTS PAR FORMULAIRE
   --------------------------------------------------------------------------- */

.formulaire-connexion .champ { margin-bottom: var(--e5); }
.formulaire-connexion .case-a-cocher { margin-bottom: var(--e3); }

.formulaire-temps { margin-top: var(--e1); }
.formulaire-temps .aide { margin-bottom: var(--e3); }

.formulaire-chantier .grille-champs { margin-bottom: var(--e1); }
.formulaire-chantier .ligne-boutons { margin-top: var(--e5); }

.formulaire-compte .grille-champs { margin-bottom: var(--e1); }
.formulaire-compte .bouton { margin-top: var(--e2); }

/* Matrice des droits (lecture seule, vue Comptes) */
.tableau-matrice .matrice-entete-role { text-align: center; }
.tableau-matrice .matrice-cellule { text-align: center; font-weight: 600; }
.tableau-matrice .matrice-oui { color: var(--vert); }
.tableau-matrice .matrice-non { color: var(--texte-tres-doux); }
.matrice-notes { margin-top: var(--e2); padding-left: 1.1rem; }
.matrice-notes li { margin: 0.15rem 0; }

/* La première colonne est un <th scope="row"> : sans cette règle elle hérite
   de l'en-tête de tableau (petites majuscules grises, white-space: nowrap) et
   des libellés comme « Réinitialiser le mot de passe d'un autre » refusent de
   se couper — table trop large sur ordinateur, illisible sur téléphone. */
.tableau-matrice th[scope="row"] {
  text-transform: none;
  letter-spacing: normal;
  white-space: normal;
  font-size: var(--t-sm);
  font-weight: var(--gras-moyen);
  color: var(--texte);
  background: transparent;
  border-bottom: 1px solid var(--bordure-douce);
}

@media (max-width: 719px) {
  /* La bascule « tableau en pile de fiches » ne traite que les <td> : on y
     ajoute le <th> de ligne, qui sert ici de titre à chaque fiche. */
  .tableau-matrice th[scope="row"] {
    display: block;
    width: 100%;
    padding: var(--e3);
    background: var(--carte-douce);
    border-bottom: 1px solid var(--bordure);
  }
}

/* Sélecteurs d'action en ligne dans les tableaux (statut, assignation) */
.select-en-ligne { min-width: 9.5rem; max-width: 100%; padding-top: 0.35rem; padding-bottom: 0.35rem; }

