/* Styles de base - TERRE ECO+

   Police : celle du systeme (San Francisco sur Mac, Segoe UI sur Windows).
   Le CSS declarait deux @font-face vers des Inter-*.woff2 qui n'ont jamais
   ete deposes dans app/static/fonts/inter/. L'ecran affichait donc deja la
   police systeme par le repli, mais chaque page demandait au passage deux
   fichiers absents (deux 404 par chargement, visibles dans le journal).
   V1.5.1 : les declarations sont retirees. Aucun changement visuel, l'app
   affiche exactement la meme chose qu'avant. Pour embarquer Inter un jour,
   il faudra remettre les @font-face ET deposer les fichiers. */

/* V2.0 lot 4 : police Inter EMBARQUEE (l'application fonctionne hors ligne,
   CLAUDE.md). Police variable, graisses 400 a 800, jeu latin : accents
   francais, oe, euro. Licence : static/fonts/LICENCE-Inter.txt. */
@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url("../fonts/InterVariable-latin.woff2") format("woff2");
}

/* V2.0 lot 4 : palette de la maquette validee (MODIFICATIONS_V2.0.md, D1, D8 ;
   docs/maquette_v2.html). Les NOMS des variables sont ceux de toujours : tous
   les ecrans suivent sans qu'on les touche un par un.
   - accent BLEU pour l'interface (D1) ;
   - vert et rouge reserves aux STATUTS, jamais decoratifs ;
   - "orange" est devenu AMBRE : il ne sert plus qu'aux alertes secondaires et
     aux taches en cours - le statut general orange n'existe plus (D2). */
:root {
    --vert: #1f8a4c;
    --orange: #b26a00;            /* ambre (nom conserve pour la compatibilite) */
    --rouge: #d1383a;
    --texte: #0e1426;             /* encre */
    --texte-2: #3a4459;           /* encre secondaire */
    --gris: #6b7489;
    --fond: #f5f7fc;              /* papier */
    --bordure: #dde3f0;           /* filets */
    --accent: #3358f4;            /* bleu */
    --accent-fonce: #2445d6;
    --accent-lavis: #eef2ff;      /* fond d'un element actif */
    --nuit: #0a1330;
    --pervenche: #a9bbff;
    --vert-lavis: #e6f4ec;
    --rouge-lavis: #fdecec;
    --ambre-lavis: #fff4e0;
    --rayon: 14px;                /* petits blocs, champs larges */
    --rayon-carte: 20px;          /* cartes et tuiles */
    --ombre: 0 1px 0 rgba(10, 19, 48, 0.04), 0 24px 48px -32px rgba(10, 19, 48, 0.35);
    --ombre-survol: 0 1px 0 rgba(10, 19, 48, 0.04), 0 28px 52px -30px rgba(10, 19, 48, 0.45);
    --focus: 0 0 0 3px rgba(51, 88, 244, 0.18);

    /* Largeurs de mise en page (V1.4 item 1).
       Sur le poste d'Ophelie (fenetre 1440 px) c'est --marge-laterale qui fixe
       la largeur utile : 1440 - 48 = 1392 px, soit +32 % par rapport aux
       1052 px de la V1.3. --largeur-max ne sert que sur un ecran externe, pour
       eviter que le contenu s'etire indefiniment. */
    --largeur-max: 1760px;
    --marge-laterale: 24px;
    /* Blocs de texte continu : borne de lecture d'environ 75-90 caracteres.
       Un paragraphe etale sur 1392 px devient illisible. */
    --largeur-texte: 80ch;
    /* Formulaires : on repartit les champs en colonnes, on ne les allonge pas. */
    --largeur-formulaire: 1040px;

    /* Hauteur des cartes Google (V1.4 item 4). Un seul endroit a modifier pour
       ajuster apres essai. Deux valeurs : sur une fiche la carte n'est qu'un
       complement (une adresse a situer), tandis que celle du tableau de bord
       sert a lire une repartition geographique et merite plus de place.
       Redefinies par palier d'ecran en bas de fichier. */
    --hauteur-carte: 380px;
    --hauteur-carte-tdb: 500px;
}

* { box-sizing: border-box; }

/* V1.4 item 3 : plus aucun soulignement permanent dans l'interface.
   Il n'existait aucune regle globale sur <a> : tout lien sans classe retombait
   sur le rendu par defaut du navigateur (bleu souligne). On neutralise ce
   defaut ; chaque famille de liens declare ensuite son propre affordance
   (fond, couleur d'accent, curseur). Le soulignement reste possible au survol
   d'un vrai lien de texte, jamais en permanence. */
a {
    color: inherit;
    text-decoration: none;
}

body {
    margin: 0;
    font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    font-size: 15px;
    color: var(--texte);
    background: var(--fond);
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

/* Barre superieure : claire, translucide, collante.
   Le fond et la bordure restent pleine largeur (esprit macOS), mais le contenu
   de la barre est borne comme .content : sur un grand ecran externe, le logo
   reste aligne avec le titre de la page, sans decalage visuel (V1.4 item 1). */
.topbar {
    position: sticky;
    top: 0;
    z-index: 50;
    padding: 0.55rem var(--marge-laterale);
    background: rgba(255, 255, 255, 0.82);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    backdrop-filter: saturate(180%) blur(20px);
    border-bottom: 1px solid var(--bordure);
    color: var(--texte);
}
.topbar-inner {
    width: 100%;
    max-width: var(--largeur-max);
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}
.brand {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    text-decoration: none;
    color: var(--texte);
}
.brand-logo { height: 40px; width: auto; display: block; }
.brand-texte { font-weight: 600; font-size: 0.95rem; color: var(--gris); }
.mainnav { display: flex; align-items: center; gap: 0.25rem; flex-wrap: wrap; }
.mainnav a {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    color: var(--texte);
    text-decoration: none;
    font-size: 0.9rem;
    font-weight: 500;
    padding: 0.45rem 0.85rem;
    border-radius: 10px;
    color: var(--texte-2);
    transition: background 0.15s ease, color 0.15s ease;
}
.mainnav a:hover { background: var(--fond); color: var(--texte); }
/* V2.0 : l'actif est un lavis bleu, plus un aplat plein - plus calme. */
.mainnav a.actif { background: var(--accent-lavis); color: var(--accent-fonce); font-weight: 600; }
.nav-icone { width: 19px; height: 19px; flex-shrink: 0; }
.nav-deconnexion { color: var(--gris); }

/* Contenu : largeur fluide bornee (V1.4 item 1). */
.content {
    width: 100%;
    max-width: var(--largeur-max);
    margin: 0 auto;
    padding: 1.5rem var(--marge-laterale);
}
/* Ecrans de saisie : la page entiere est resserree et centree, titre compris.
   Un formulaire n'a pas besoin de 1392 px, mais le borner en le laissant colle
   a gauche laissait une bande vide a droite. On centre plutot (V1.4 item 1). */
.content.contenu-etroit { max-width: var(--largeur-formulaire); }

/* Blocs de texte continu : a poser sur un paragraphe long pour qu'il garde une
   largeur de lecture confortable meme dans un conteneur tres large. */
.texte-long { max-width: var(--largeur-texte); }
h1 { font-weight: 800; font-size: clamp(1.75rem, 2.6vw, 2.35rem); line-height: 1.05; letter-spacing: -0.035em; text-wrap: balance; }
h2 { font-weight: 700; letter-spacing: -0.015em; }
.intro, .note { color: var(--gris); }

/* Cartes d'indicateurs */
.cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 1rem;
    margin: 1.5rem 0;
}
.card {
    background: #fff;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon-carte);
    box-shadow: var(--ombre);
    padding: 1.2rem;
    text-align: center;
}
.card-nombre { font-size: 2rem; font-weight: 800; letter-spacing: -0.04em; color: var(--accent); font-variant-numeric: tabular-nums; }
.card-libelle { color: var(--gris); margin-top: 0.3rem; }

/* Pied de page : meme largeur que le contenu (V1.4 item 1). */
.footer {
    width: 100%;
    max-width: var(--largeur-max);
    margin: 0 auto;
    text-align: center;
    color: var(--gris);
    font-size: 0.85rem;
    padding: 1.5rem var(--marge-laterale);
}

/* Navigation : infos utilisateur */
.user-info { margin-left: 0.8rem; color: var(--gris); font-size: 0.88rem; text-decoration: none; }
.user-info:hover { color: var(--texte, inherit); text-decoration: underline; }

/* Messages flash */
.flash-zone { margin-bottom: 1rem; }
.flash {
    padding: 0.7rem 1rem;
    border-radius: 10px;
    margin-bottom: 0.5rem;
    border: 1px solid transparent;
    box-shadow: var(--ombre);
}
.flash-succes { background: var(--vert-lavis); border-color: #bfe3cc; color: #16663a; }
.flash-erreur { background: var(--rouge-lavis); border-color: #f5c6c6; color: #9e2426; }
.flash-info   { background: var(--accent-lavis); border-color: #cdd8ff; color: var(--accent-fonce); }

/* Boutons */
.btn {
    cursor: pointer;
    border: 1px solid var(--bordure);
    background: #fff;
    color: var(--texte);
    border-radius: 10px;
    padding: 0.55rem 1rem;
    font-size: 0.9rem;
    font-weight: 600;
    font-family: inherit;
    text-decoration: none;
    transition: background 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
}
.btn:hover { border-color: #c3cce2; background: #fff; }
.btn:active { transform: scale(0.98); }
.btn-principal { background: var(--accent); color: #fff; border-color: var(--accent); }
.btn-principal:hover { background: var(--accent-fonce); border-color: var(--accent-fonce); }
.btn-petit { padding: 0.35rem 0.65rem; font-size: 0.82rem; }
.btn-danger { color: var(--rouge); border-color: #f2c9c9; }
.btn-danger:hover { background: var(--rouge-lavis); border-color: #eab0b0; }

/* Champs de saisie : anneau de focus doux sur toute l'app */
input, select, textarea {
    accent-color: var(--accent);
}
input:focus-visible, select:focus-visible, textarea:focus-visible {
    outline: none;
    border-color: var(--accent) !important;
    box-shadow: var(--focus);
}

/* Selects : apparence moderne homogene (chevron personnalise, plus de rendu
   navigateur brut), partout dans l'app */
select {
    appearance: none;
    -webkit-appearance: none;
    padding: 0.45rem 2rem 0.45rem 0.6rem;
    border: 1px solid var(--bordure);
    border-radius: 10px;
    background-color: #fff;
    background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="8" viewBox="0 0 12 8"><path d="M1 1.5l5 5 5-5" fill="none" stroke="%236b7489" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>');
    background-repeat: no-repeat;
    background-position: right 0.6rem center;
    background-size: 12px 8px;
    font-family: inherit;
    font-size: 0.9rem;
    color: var(--texte);
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* Champs date : meme habillage que les autres champs, icone calendrier douce */
input[type="date"] {
    padding: 0.42rem 0.6rem;
    border: 1px solid var(--bordure);
    border-radius: 10px;
    background: #fff;
    font-family: inherit;
    font-size: 0.9rem;
    color: var(--texte);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
input[type="date"]::-webkit-calendar-picker-indicator { cursor: pointer; opacity: 0.5; }
input[type="date"]::-webkit-calendar-picker-indicator:hover { opacity: 1; }

/* Ecran de connexion */
.login-box {
    max-width: 360px;
    margin: 3rem auto;
    background: #fff;
    border: none;
    border-radius: 16px;
    box-shadow: var(--ombre-survol);
    padding: 2rem;
}
.login-box label { display: block; margin: 1rem 0 0.3rem; font-weight: 600; }
.login-box input {
    width: 100%;
    padding: 0.6rem;
    border: 1px solid var(--bordure);
    border-radius: 7px;
    font-family: inherit;
    font-size: 1rem;
}
.login-box .btn { width: 100%; margin-top: 1.5rem; }

/* Sections de parametres */
.param-section {
    background: #fff;
    border: none;
    border-radius: var(--rayon);
    box-shadow: var(--ombre);
    padding: 1.3rem 1.5rem;
    margin-bottom: 1.5rem;
}
.param-section h2 { margin-top: 0; font-weight: 600; font-size: 1.15rem; }
.aide { color: var(--gris); font-size: 0.88rem; margin-top: 0; }

.param-table { width: 100%; border-collapse: collapse; margin-bottom: 1rem; }
.param-table th, .param-table td {
    text-align: left;
    padding: 0.6rem 0.6rem;
    border-bottom: 1px solid #f0f0f3;
    vertical-align: middle;
}
.param-table th {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--gris);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.param-table tbody tr { transition: background 0.12s ease; }
.param-table tbody tr:hover { background: #fafafa; }
.param-table tr.inactif { opacity: 0.5; }
.param-table .actions { white-space: nowrap; }

/* Formulaires en ligne (dans les tableaux et zones d'ajout) */
/* V1.4 item 2 : ces rangees de saisie ne se coupaient qu'en dessous de 800 px.
   Entre 800 et 1366 px, la ligne d'edition d'un contact (5 champs + 3 boutons)
   restait insecable et faisait defiler toute la fiche horizontalement. Le
   passage a la ligne devient valable a toute largeur : il ne se declenche que
   s'il manque reellement de la place, les formulaires courts ne bougent pas. */
.ligne-form, .ajout-form, .actions form {
    display: inline-flex;
    flex-wrap: wrap;
    max-width: 100%;
    gap: 0.4rem;
    align-items: center;
    margin: 0 0.3rem 0.3rem 0;
}
.ligne-form input, .ligne-form select,
.ajout-form input, .ajout-form select { min-width: 0; }
.ajout-form { margin-top: 0.5rem; }
.ligne-form input[type="text"],
.ajout-form input[type="text"],
.ajout-form input[type="password"],
.ligne-form input[type="password"],
.ligne-form input[type="number"] {
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--bordure);
    border-radius: 10px;
    font-family: inherit;
    font-size: 0.9rem;
    background-color: #fff;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.champ-nombre { width: 90px; }

/* Reglages generaux : voir la refonte V2.0.1 (fin de fichier). */

/* ===================== Chantiers ===================== */

/* Pastilles de statut couleur */
.pastille {
    display: inline-block;
    width: 14px; height: 14px;
    border-radius: 50%;
}
.pastille-vert   { background: var(--vert); }
.pastille-orange { background: var(--orange); }
.pastille-rouge  { background: var(--rouge); }
/* V1.2 : hors phase de preparation, le statut couleur ne s'applique plus. */
.pastille-neutre { background: #c7c7cc; }

/* Badges de statut (fiche) */
.badge {
    display: inline-block;
    padding: 0.3rem 0.7rem;
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 600;
    color: #fff;
}
.badge-vert   { background: var(--vert); }
.badge-orange { background: var(--orange); }
.badge-rouge  { background: var(--rouge); }

/* Badges de phase du cycle de vie (V1.2 item 0). Volontairement sobres :
   ils informent d'une etape, ils n'alertent pas comme le statut couleur. */
.badge-phase-2 { background: #8a6d3b; }        /* remblai a faire : terre/ocre */
.badge-phase-3 { background: var(--gris); }    /* termine : neutre */
.badge-phase {
    display: inline-block;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    color: #fff;
    vertical-align: middle;
    margin-left: 0.35rem;
}

/* Liste des chantiers */
.entete-liste, .entete-fiche {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}
/* V1.2 item 11 : sans retour a la ligne, les boutons d'action poussaient la
   page hors de l'ecran sur telephone. */
.entete-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }
/* Les tableaux restants (decharges, archives) deviennent des cartes arrondies */
.table-scroll {
    overflow-x: auto;
    background: #fff;
    border-radius: var(--rayon);
    box-shadow: var(--ombre);
}
/* V1.2 item 11 : meme defilement, mais sans habillage, pour les tableaux deja
   contenus dans une carte (.fiche-bloc, .param-section) : inutile d'empiler un
   second fond blanc et une seconde ombre. */
.tableau-defilant { overflow-x: auto; }
.liste-table {
    width: 100%;
    border-collapse: collapse;
    background: #fff;
    font-size: 0.9rem;
}
.liste-table th, .liste-table td {
    padding: 0.65rem 0.8rem;
    border-bottom: 1px solid #f0f0f3;
    text-align: left;
    white-space: nowrap;
}
.liste-table tbody tr:last-child td { border-bottom: none; }
.liste-table th {
    color: var(--gris);
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.ligne-cliquable { cursor: pointer; transition: background 0.12s ease; }
.ligne-cliquable:hover { background: #f0f4f1; }
.nom-client { font-weight: 600; }
.liste-table .non { color: var(--rouge); }
.vide { color: var(--gris); }

/* Listes en blocs deux lignes (V1.1 item 2, generalise en V1.4 item 2).

   Un tableau classique impose sa largeur naturelle et defile des que la fenetre
   se resserre. Reparties sur deux lignes, les colonnes tiennent a toute largeur.
   La structure ci-dessous est commune a toutes les listes ; seule la
   repartition des colonnes change, declaree plus bas, une fois par liste.
   Gabarit associe : partials/liste_deux_lignes.html. */
.liste-blocs {
    background: #fff;
    border: none;
    border-radius: var(--rayon);
    box-shadow: var(--ombre);
    overflow: hidden;
}
.bloc-liste {
    padding: 0.55rem 0.9rem;
    border-bottom: 1px solid var(--bordure);
}
.bloc-liste:last-child { border-bottom: none; }
/* Fond alterne par enregistrement (bloc entier), pas par ligne */
.bloc-liste:nth-child(even) { background: #f8fafe; }
.bloc-liste:hover { background: #eef2fb; }

.bloc-l1, .bloc-l2 {
    display: grid;
    align-items: center;
    gap: 0.4rem 1rem;
}
.bloc-l1 { font-size: 0.9rem; }
.bloc-l2 {
    margin-top: 0.3rem;
    font-size: 0.85rem;          /* 13.6px : jamais sous 13px */
    color: var(--texte);
}

/* --- Repartition des colonnes, une declaration par liste ---
   Les valeurs sont en minmax(...) : les colonnes se compriment jusqu'a leur
   minimum puis le texte s'ellipse.
   ATTENTION : une colonne en `max-content` echappe a cette regle, elle ne se
   comprime jamais et son contenu finit coupe si la fenetre est trop etroite.
   C'est ce qui est arrive a .col-statuts entre 800 et 957 px jusqu'a la V1.5.1
   (voir le palier 1024 px plus bas). Toute nouvelle colonne en `max-content`
   demande donc de verifier ce qu'elle devient en tablette portrait. */

/* Chantiers : pastille, identite, conducteur, centre, planning */
.liste-chantiers .bloc-l1 {
    grid-template-columns: 20px minmax(160px, 1.4fr) minmax(90px, 1fr) minmax(90px, 1fr) max-content;
}
.liste-chantiers .bloc-l2 {
    grid-template-columns: 20px max-content minmax(120px, 1fr) minmax(90px, 1fr) max-content;
}

/* Decharges. Les deux lignes partagent la meme repartition : c'est ce qui les
   aligne verticalement. L1 statut, nom, ville, contact, telephone.
   L2 (vide), adresse, alerte de geolocalisation. */
/* Largeurs figees et non "max-content" : chaque bloc est sa propre grille, une
   colonne dimensionnee par son contenu se calerait differemment d'une ligne a
   l'autre selon que le telephone est rempli ou non, et les colonnes ne
   s'aligneraient plus verticalement d'un enregistrement au suivant. */
.liste-decharges .bloc-l1,
.liste-decharges .bloc-l2 {
    grid-template-columns: 62px minmax(170px, 2fr) minmax(100px, 1fr) minmax(120px, 1.2fr) 130px;
}
.liste-decharges .bloc-l2 .col-geoloc { grid-column: 3 / -1; }

/* Remblais. L1 chantier, constructeur, anciennete, saisie de la date de fin.
   L2 date de terrassement, conducteur, centre, commentaire. Largeurs figees
   (meme raison que pour les decharges). */
.liste-remblais .bloc-l1,
.liste-remblais .bloc-l2 {
    grid-template-columns: minmax(170px, 2fr) minmax(110px, 1fr) minmax(110px, 1fr) 250px;
}

/* Proximite. L1 rang, decharge, distance, temps, bouton Selectionner.
   L2 (vide), adresse + conditions, tarif, cout estime, lien Itineraire. */
.liste-proximite .bloc-l1,
.liste-proximite .bloc-l2 {
    grid-template-columns: 30px minmax(150px, 2fr) minmax(100px, 1fr) minmax(100px, 1fr) 110px;
}
.col-rang { color: var(--gris); font-variant-numeric: tabular-nums; }
/* La decharge retenue teinte tout le bloc, pas seulement sa premiere ligne.
   Si :has() n'est pas reconnu, le bloc reste simplement non teinte : aucune
   information n'est perdue, le bouton affiche deja "Retenue". */
.liste-proximite .bloc-liste:has(.ligne-retenue) { background: #e6f4ea; }
.liste-proximite .bloc-liste:has(.ligne-retenue):hover { background: #d8eede; }
/* Mise en evidence pilotee par la carte (carte.js pose .ligne-active sur
   l'element portant data-carte-marqueur, desormais le bloc entier). */
.bloc-liste.ligne-active { box-shadow: inset 3px 0 0 var(--orange); }

/* V1.6 : lien etire.
   Le bloc etait un <article onclick> : cliquable a la souris, invisible au
   clavier. Le nom porte desormais un vrai <a href> - donc tabulation, Entree,
   clic milieu et "ouvrir dans un nouvel onglet" fonctionnent - et ce
   pseudo-element etend sa zone de clic a tout le bloc, ce qui preserve
   exactement le confort d'avant a la souris.
   Le lien ne couvre que le NOM et non le bloc entier : un <a> enveloppant les
   six colonnes ferait un libelle de lien illisible pour un lecteur d'ecran. */
.bloc-liste.ligne-cliquable { position: relative; }
.lien-bloc { color: inherit; text-decoration: none; }
/* L'etirement ne vaut que pour les blocs. Dans un tableau (archives), le lien
   reste un lien ordinaire sur le nom : `position: relative` sur un <tr> est un
   terrain trop incertain pour y accrocher une zone de clic. */
.bloc-liste.ligne-cliquable .lien-bloc::after {
    content: "";
    position: absolute;
    inset: 0;
}
/* Le focus clavier doit se voir sur le BLOC, pas seulement sur le nom : c'est
   le bloc entier qui sera ouvert. */
.bloc-liste.ligne-cliquable:focus-within {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}
.lien-bloc:focus-visible { outline: none; }
.col-pastille { display: flex; align-items: center; }
.nom-chantier { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nom-chantier .dept { font-weight: 400; color: var(--gris); margin-left: 0.2rem; }
/* V1.4 item 3 : dans la liste des remblais, le bloc n'est pas cliquable dans
   son ensemble (il porte un formulaire de saisie rapide) et le nom du chantier
   est le seul lien. Le soulignement par defaut ayant disparu, il lui faut sa
   propre affordance : couleur d'accent au survol.
   V2.0.1 : plus de soulignement (juge disgracieux par Geoffrey) ; la regle
   touchait aussi les listes des chantiers et des decharges, ou toute la ligne
   est deja le lien et se colore au survol. */
.nom-chantier a:hover { color: var(--accent); }
.col-affectation { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--texte); }
.col-terrassement { white-space: nowrap; text-align: right; }
.col-dates { white-space: nowrap; }
.col-dates .non { color: var(--rouge); font-weight: 600; }
.col-statuts { white-space: nowrap; display: flex; gap: 0.3rem; justify-content: flex-end; }
.col-decharge { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Cellules ajoutees par les listes converties en V1.4 item 2. */
.col-adresse { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--gris); }
.col-geoloc, .col-actions { white-space: nowrap; text-align: right; }
.col-conditions { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--gris); font-style: italic; }
.col-mesure { white-space: nowrap; text-align: right; font-variant-numeric: tabular-nums; }
/* Une decharge inactive reste lisible mais ne tire plus l'oeil. */
.bloc-l1.inactif { opacity: 0.55; }
.badge-statut {
    justify-self: start;
    font-size: 0.72rem;
    font-weight: 600;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    white-space: nowrap;
}
.badge-statut.ok { background: #e6f4ea; color: #1e6b2c; }
.badge-statut.ko { background: #f1f1f3; color: var(--gris); }
.col-commentaire {
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    color: var(--gris); font-style: italic;
}
.texte-attenue { color: var(--gris); }

/* Pilules des statuts administratifs (nom complet + couleur oui/non) */
.mini-statut {
    display: inline-flex;
    align-items: center;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-size: 0.8125rem;        /* 13px */
    font-weight: 600;
    color: #fff;
}
.mini-statut.ok { background: var(--vert); }
.mini-statut.ko { background: var(--rouge); }

/* Fiche chantier */
.fiche-colonnes {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.2rem;
    margin: 1rem 0;
}
.fiche-bloc {
    background: #fff;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon-carte);
    box-shadow: var(--ombre);
    padding: 1.35rem 1.5rem;
    margin-bottom: 1.2rem;
}
.fiche-bloc h2 { margin-top: 0; font-size: 1.05rem; font-weight: 700; }
.fiche-bloc h2.espace { margin-top: 1.5rem; }
.infos-table { width: 100%; border-collapse: collapse; }
.infos-table th {
    text-align: left;
    color: var(--gris);
    font-weight: 500;
    width: 45%;
    padding: 0.35rem 0.5rem 0.35rem 0;
    vertical-align: top;
}
.infos-table td { padding: 0.35rem 0; }
.case { display: block; margin-bottom: 0.5rem; }
/* V1.2 item 3 : le statut plan / CRI se saisit par sa date, pas par une case. */
.case-date {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
}
.case-date-libelle { flex: 1; }
.case-date input[type="date"] {
    padding: 0.3rem 0.5rem;
    border: 1px solid var(--bordure);
    border-radius: 10px;
    font-family: inherit;
    font-size: 0.9rem;
    background: #fff;
    color: var(--texte);
}
/* V1.2 item 4.2 : choix unique d'acces au chantier. */
.choix-acces {
    border: none;
    border-top: 1px solid var(--bordure);
    margin: 0.9rem 0 0.6rem;
    padding: 0.7rem 0 0;
}
.choix-acces legend {
    padding: 0;
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--gris);
}
.statuts-lecture { list-style: none; padding: 0; }
.statuts-lecture li { padding: 0.3rem 0; }
/* Texte libre : borne de lecture, le conteneur est desormais bien plus large
   que ce qu'un paragraphe supporte (V1.4 item 1). */
.commentaire-principal { white-space: pre-wrap; max-width: var(--largeur-texte); }
.ajout-commentaire { display: flex; gap: 0.5rem; margin-bottom: 1rem; }
.ajout-commentaire input { flex: 1; padding: 0.5rem; border: 1px solid var(--bordure); border-radius: 6px; font-family: inherit; }
.historique { list-style: none; padding: 0; max-width: var(--largeur-texte); }
.historique li { padding: 0.4rem 0; border-bottom: 1px solid var(--bordure); }
.historique .date { color: var(--gris); font-size: 0.85rem; }
.historique .auteur { color: var(--gris); font-size: 0.85rem; }

/* Bloc adresse + coordonnees, partage chantier / decharge (V1.2 item 2) */
.coordonnees {
    margin-top: 1rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--bordure);
}
.coordonnees-entete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.8rem;
    flex-wrap: wrap;
}
.coordonnees-titre { font-weight: 600; }
.message-geocodage {
    margin: 0.6rem 0 0;
    padding: 0.5rem 0.75rem;
    border-radius: 10px;
    font-size: 0.9rem;
}
.message-succes { background: #e8f3ea; color: #1f5c2a; }
.message-erreur { background: #fdecea; color: #8c1d18; }
.mention-coord {
    margin: 0.5rem 0 0;
    font-size: 0.85rem;
    color: var(--gris);
}

/* Formulaires chantier / decharge : chaque section devient une carte */
.chantier-form fieldset {
    border: none;
    background: #fff;
    border-radius: var(--rayon);
    box-shadow: var(--ombre);
    margin: 0 0 1.2rem;
    padding: 1.1rem 1.4rem 1.3rem;
}
/* Le conteneur s'elargit, pas les formulaires : au-dela de cette largeur on
   n'ajoute plus de colonnes, la saisie resterait illisible (V1.4 item 1). */
.chantier-form, .form-champs { max-width: var(--largeur-formulaire); }
.chantier-form legend {
    font-weight: 600;
    font-size: 1.05rem;
    padding: 0;
    margin-bottom: 0.4rem;
}
/* auto-FILL et non auto-fit (V1.4 item 1) : les colonnes vides sont conservees,
   donc un fieldset de deux champs garde deux champs de largeur normale au lieu
   de les etirer sur toute la grille. Un champ de date large de 500 px n'a aucun
   sens. En dessous de 220 px de place, la grille repasse seule sur une colonne. */
.grille {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 1rem;
}
/* Ces regles habillent les champs de saisie : libelle au-dessus, champ dessous.
   Elles etaient reservees a .chantier-form, c'est-a-dire aux deux ecrans de
   creation/modification. Un formulaire pose directement sur une fiche (les
   horaires d'une decharge) n'en heritait pas et retombait sur le rendu brut du
   navigateur : textarea monospace de 182 px, bordure grise, sans arrondi.
   .form-champs permet de reutiliser cet habillage partout. */
.chantier-form label, .form-champs label {
    display: flex; flex-direction: column; gap: 0.3rem; font-weight: 500;
}
.chantier-form label.large { grid-column: 1 / -1; }
/* Un champ .large occupe toute la grille. C'est utile pour une zone de texte,
   absurde pour une rue : on borne la saisie sur une ligne (V1.4 item 1). */
.chantier-form label.large input,
.chantier-form label.large select { max-width: var(--largeur-texte); }
/* L'asterisque se pose sur le libelle, pas sur le label : le label est une
   colonne flex, un ::after pose dessus devenait un element flex a lui seul et
   tombait sur une ligne separee sous le champ. */
.chantier-form label.obligatoire > .libelle::after,
.form-champs label.obligatoire > .libelle::after { content: " *"; color: var(--rouge); }
/* Cote .form-champs on ne vise que les champs places DANS un libelle : les
   cases a cocher et les champs heure de la grille des horaires gardent ainsi
   leur propre style compact. */
.chantier-form input, .chantier-form select, .chantier-form textarea,
.form-champs label input, .form-champs label select, .form-champs label textarea {
    padding: 0.55rem 0.65rem;
    border: 1px solid var(--bordure);
    border-radius: 9px;
    font-family: inherit;
    font-size: 0.95rem;
    background-color: #fff;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.chantier-form select, .form-champs label select { padding-right: 2rem; }
.chantier-form textarea, .form-champs label textarea { resize: vertical; }
/* Un libelle detache du groupe de champs qui le precede. */
label.espace { margin-top: 1.1rem; }
.form-actions { display: flex; gap: 0.6rem; margin-top: 0.5rem; }

/* Tonnage calcule automatiquement : badge "estime" dans le champ (V1.1 item 6) */
.champ-avec-badge { position: relative; display: flex; }
.champ-avec-badge input { flex: 1; }
.badge-estime {
    position: absolute;
    right: 0.55rem;
    top: 50%;
    transform: translateY(-50%);
    background: #fff4e2;
    color: #b25e00;
    font-size: 0.72rem;
    font-weight: 600;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    pointer-events: none;
}
/* Variante en ligne (fiche chantier) */
.badge-estime-fiche { position: static; transform: none; pointer-events: auto; margin-left: 0.3rem; }

/* ===================== Pieces jointes (V1.1 item 7) ===================== */
/* Badge compteur dans la liste des chantiers (trombone + nombre) */
.badge-pj {
    display: inline-flex;
    align-items: center;
    gap: 0.15rem;
    margin-left: 0.4rem;
    padding: 0.05rem 0.45rem;
    border-radius: 999px;
    background: #eef0f3;
    color: var(--gris);
    font-size: 0.78rem;
    font-weight: 500;
    vertical-align: 1px;
}
.badge-pj svg { width: 12px; height: 12px; }

/* Compteur dans le titre de section (fiche) */
.badge-compteur {
    display: inline-block;
    background: var(--accent);
    color: #fff;
    font-size: 0.78rem;
    font-weight: 600;
    padding: 0.05rem 0.55rem;
    border-radius: 999px;
    vertical-align: 3px;
    margin-left: 0.2rem;
}

/* Formulaire d'ajout */
.ajout-piece-jointe {
    display: flex;
    gap: 0.6rem;
    align-items: center;
    margin-bottom: 1rem;
    flex-wrap: wrap;
}
.ajout-piece-jointe input[type="file"] { font-size: 0.88rem; color: var(--gris); }
.ajout-piece-jointe input[type="file"]::file-selector-button {
    cursor: pointer;
    border: 1px solid var(--bordure);
    background: #fff;
    color: var(--texte);
    border-radius: 9px;
    padding: 0.45rem 0.9rem;
    font-size: 0.88rem;
    font-weight: 500;
    font-family: inherit;
    margin-right: 0.7rem;
    transition: background 0.15s ease;
}
.ajout-piece-jointe input[type="file"]::file-selector-button:hover { background: #f0f2f5; }
.nom-fichier { font-weight: 500; max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ===================== Tableau de bord ===================== */
/* Refonte du 27/07/2026 : les 11 tuiles de meme poids sont remplacees par
   trois blocs hierarchises - repartition, actions a mener, remblais. */

/* --- 1. Repartition du portefeuille --- */
.tdb-sante {
    background: #fff;
    border-radius: var(--rayon);
    box-shadow: var(--ombre);
    padding: 1.4rem 1.5rem 1.2rem;
    margin: 1.5rem 0 1rem;
}
.tdb-total {
    display: flex;
    align-items: baseline;
    gap: 0.55rem;
    text-decoration: none;
    color: var(--texte);
    width: max-content;
}
.tdb-total-nombre { font-size: 2.6rem; font-weight: 600; line-height: 1; }
.tdb-total-libelle { color: var(--gris); font-size: 1rem; }
.tdb-total:hover .tdb-total-libelle { color: var(--texte); }

/* Barre segmentee : chaque segment grandit proportionnellement a son compte
   (flex-grow pose en style inline par le gabarit). */
.tdb-barre {
    display: flex;
    gap: 3px;
    height: 12px;
    margin: 1.1rem 0 0.9rem;
}
.tdb-segment {
    display: block;
    min-width: 8px;
    border-radius: 999px;
    background: var(--gris);
    transition: opacity 0.15s ease, transform 0.15s ease;
}
.tdb-barre:hover .tdb-segment { opacity: 0.45; }
.tdb-barre .tdb-segment:hover { opacity: 1; transform: scaleY(1.35); }
.tdb-segment-vert   { background: var(--vert); }
.tdb-segment-orange { background: var(--orange); }
.tdb-segment-rouge  { background: var(--rouge); }
.tdb-segment-terre  { background: #8a6d3b; }
.tdb-segment-gris   { background: #c7c7cc; }

.tdb-legende {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1.4rem;
    list-style: none;
    padding: 0;
    margin: 0;
    font-size: 0.9rem;
}
.tdb-legende a {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    text-decoration: none;
    color: var(--gris);
}
.tdb-legende a:hover { color: var(--texte); }
.tdb-legende strong { color: var(--texte); font-weight: 600; }
/* Une categorie vide reste visible mais ne tire plus l'oeil. */
.tdb-legende .a-zero { opacity: 0.45; }
.pastille-terre { background: #8a6d3b; }
.pastille-gris  { background: #c7c7cc; }

/* --- 2. Actions a mener  /  3. Remblais --- */
/* Le conteneur elargi (V1.4 item 1) donnait une liste "A traiter" de 1170 px :
   le libelle a gauche, la pastille a l'autre bout de l'ecran. On redistribue en
   proportions plutot qu'en colonne fixe : la liste gagne ~90 px seulement, le
   reste va a la carte des remblais. Aucune zone vide, aucun etirement. */
/* V1.5 item 2 : depuis l'elargissement de la V1.4, tout l'espace gagne partait
   dans la seule tuile "A traiter", etiree sur 2,5 fois la largeur de sa
   voisine. Repartition d'environ 55 / 45, en fractions de grille (jamais en
   pixels) pour qu'elle tienne a toutes les tailles d'ecran. */
.tdb-colonnes {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    gap: 1rem;
    margin-bottom: 1.5rem;
    align-items: start;
}
.tdb-actions {
    background: #fff;
    border-radius: var(--rayon);
    box-shadow: var(--ombre);
    padding: 1.2rem 1.4rem 0.9rem;
}
.tdb-actions h2 {
    margin: 0 0 0.6rem;
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--gris);
}
.tdb-rien { color: var(--vert); font-weight: 500; margin: 0.2rem 0 0.6rem; }
.liste-actions { list-style: none; padding: 0; margin: 0; }
.liste-actions a {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.6rem 0.2rem;
    border-bottom: 1px solid #f0f0f3;
    text-decoration: none;
    color: var(--texte);
    transition: padding-left 0.15s ease;
}
.liste-actions li:last-child a { border-bottom: none; }
.liste-actions a:hover { padding-left: 0.55rem; }
.action-libelle { flex: 1; }
/* Le compteur porte la couleur de gravite, pas la ligne entiere : le rouge
   reste lisible parce qu'il est rare. */
.action-nombre {
    min-width: 2.1rem;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    text-align: center;
    font-weight: 600;
    font-size: 0.9rem;
    background: #f0f0f3;
    color: var(--gris);
}
.action-rouge  .action-nombre { background: #fdecea; color: var(--rouge); }
.action-orange .action-nombre { background: #fff4e2; color: #b25e00; }
.liste-actions .a-zero .action-libelle { color: var(--gris); }
.liste-actions .a-zero .action-nombre { background: #f6f6f8; color: #b8b8be; }

.tdb-remblais {
    display: flex;
    flex-direction: column;
    align-self: start;          /* la carte se dimensionne a son contenu plutot
                                   que de s'etirer sur la hauteur de la liste */
    background: #fff;
    border-radius: var(--rayon);
    box-shadow: var(--ombre);
    padding: 1.2rem 1.3rem;
    text-decoration: none;
    color: var(--texte);
    border-top: 4px solid #8a6d3b;
    transition: box-shadow 0.18s ease;
}
/* V1.5 item 2 : la tuile porte maintenant plusieurs liens (l'entete, chaque
   remblai, le lien vers la liste complete). Le survol se joue donc ligne par
   ligne, la tuile entiere ne se souleve plus. */
.tdb-remblais-entete { display: block; }
.tdb-remblais-liste {
    list-style: none;
    margin: 0.9rem 0 0;
    padding: 0.9rem 0 0;
    border-top: 1px solid #f0f0f3;
}
.tdb-remblais-liste a {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.45rem 0.2rem;
    color: var(--texte);
    border-radius: 10px;
    transition: background 0.15s ease;
}
.tdb-remblais-liste a:hover { background: #f7f7f9; }
.tdb-remblais-nom {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.92rem;
}
.tdb-remblais-jours {
    font-weight: 600;
    font-size: 0.85rem;
    color: var(--gris);
    white-space: nowrap;
}
.tdb-remblais-jours.jours-orange { color: #b25e00; }
.tdb-remblais-jours.jours-rouge  { color: var(--rouge); }
.tdb-remblais-tous {
    margin-top: 0.7rem;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--accent);
}
.tdb-remblais-tous:hover { text-decoration: underline; }
.tdb-remblais-vide {
    margin: 0.7rem 0 0;
    color: var(--gris);
    font-size: 0.9rem;
}
.tdb-remblais-entete:hover .tdb-remblais-libelle { color: var(--texte); }
.tdb-remblais-nombre {
    display: block;
    font-size: 2.2rem;
    font-weight: 600;
    line-height: 1;
    color: #8a6d3b;
}
.tdb-remblais-libelle { display: block; color: var(--gris); margin-top: 0.25rem; }
/* Au-dela du seuil rouge parametrable, le bloc bascule en alerte. */
.tdb-remblais.urgent { border-top-color: var(--rouge); }
.tdb-remblais.urgent .tdb-remblais-nombre { color: var(--rouge); }

/* Fiche decharge : contacts multiples et horaires (V1.2 items 10.2 et 10.4) */
.badge-principal {
    display: inline-block;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    background: var(--accent);
    color: #fff;
    font-size: 0.75rem;
    font-weight: 600;
}
tr.contact-principal { background: #f3f6fd; }
.ajout-contact { margin-top: 0.8rem; flex-wrap: wrap; }
.table-horaires tr.jour-courant,
.infos-table tr.jour-courant { background: #f3f6fd; font-weight: 600; }
.table-horaires .cellule-plage { white-space: nowrap; }
.table-horaires input[type="time"] {
    padding: 0.2rem 0.35rem;
    border: 1px solid var(--bordure);
    border-radius: 10px;
    font-family: inherit;
    font-size: 0.85rem;
}
.horaire-ferme  { color: var(--gris); }
.horaire-ouvert { color: var(--vert); }

/* Travaux divers et renommage des pieces jointes (V1.2 items 8 et 9) */
.table-travaux tr.travail-fait td { color: var(--gris); }
.ajout-travail { margin-top: 0.8rem; flex-wrap: wrap; }
.form-renommer { display: flex; gap: 0.35rem; align-items: center; }
.form-renommer input[type="text"] {
    min-width: 12rem;
    padding: 0.25rem 0.45rem;
    border: 1px solid var(--bordure);
    border-radius: 10px;
    font-family: inherit;
    font-size: 0.9rem;
}

/* Liste des remblais a faire (V1.2 item 6) */
.table-remblais .col-commentaire {
    max-width: 240px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.table-remblais tr.ligne-orange { background: #fff6e9; }
.table-remblais tr.ligne-rouge  { background: #fdecea; }
.cellule-anciennete { white-space: nowrap; font-weight: 600; }
.pastille-anciennete {
    display: inline-block;
    width: 9px; height: 9px;
    border-radius: 50%;
    background: #c7c7cc;
    margin-right: 0.35rem;
}
.pastille-anciennete.pastille-orange { background: var(--orange); }
.pastille-anciennete.pastille-rouge  { background: var(--rouge); }
.form-fin-remblai { display: flex; gap: 0.35rem; align-items: center; }
.form-fin-remblai input[type="date"] {
    padding: 0.25rem 0.4rem;
    border: 1px solid var(--bordure);
    border-radius: 10px;
    font-family: inherit;
    font-size: 0.85rem;
    background: #fff;
    color: var(--texte);
}

/* ===================== Calendrier hebdomadaire ===================== */
.calendrier { margin-top: 2rem; }
.calendrier-entete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}
.calendrier-entete h2 { font-size: 1.2rem; font-weight: 600; margin: 0.5rem 0; }
.calendrier-nav { display: flex; gap: 0.4rem; }

.calendrier-grille {
    display: grid;
    gap: 0.8rem;
    margin-top: 0.8rem;
}
.calendrier-grille.jours-5 { grid-template-columns: repeat(5, 1fr); }
.calendrier-grille.jours-6 { grid-template-columns: repeat(6, 1fr); }

.calendrier-jour {
    background: #fff;
    border-radius: var(--rayon);
    box-shadow: var(--ombre);
    padding: 0.7rem 0.75rem;
    min-height: 170px;
}
.calendrier-jour.aujourdhui {
    box-shadow: inset 0 0 0 2px var(--accent), var(--ombre);
}
.calendrier-jour.aujourdhui .jour-titre { color: var(--accent); }
.jour-titre {
    font-size: 0.82rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--gris);
    margin-bottom: 0.55rem;
}
.jour-date { font-weight: 400; margin-left: 0.15rem; }

.jour-chantier {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.45rem;
    margin-bottom: 0.35rem;
    border-radius: 10px;
    background: #f5f5f7;
    text-decoration: none;
    color: var(--texte);
    font-size: 0.82rem;
    font-weight: 500;
    transition: background 0.15s ease;
}
.jour-chantier:hover { background: #e9e9ee; }
.jour-chantier .pastille { width: 10px; height: 10px; flex-shrink: 0; }
.jour-chantier-nom { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Chantier planifie mais pas encore pret : alerte implicite */
.jour-chantier.pas-pret { box-shadow: inset 0 0 0 1.5px var(--rouge); background: #fdf3f2; }
.jour-chantier.pas-pret:hover { background: #fbe9e7; }
.picto-attention { margin-left: auto; color: var(--rouge); font-size: 0.9rem; }

.calendrier-vide { color: var(--gris); font-size: 0.9rem; margin-top: 0.8rem; }

@media (max-width: 800px) {
    .calendrier-grille.jours-5, .calendrier-grille.jours-6 { grid-template-columns: 1fr; }
    .calendrier-jour { min-height: 0; }
}

/* ===================== Recherche & filtres ===================== */
.barre-recherche { display: flex; gap: 0.5rem; margin: 1rem 0; }
.barre-recherche input[type="search"] {
    flex: 1;
    max-width: 480px;
    padding: 0.55rem 0.9rem;
    border: 1px solid var(--bordure);
    border-radius: 999px;
    font-family: inherit;
    font-size: 0.95rem;
    background: #fff;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
/* --- V1.5 item 1 : vues enregistrees, panneau avance, filtres actifs ---
   Les quinze puces de meme poids sont remplacees par une hierarchie : les vues
   d'abord (controle segmente, une seule active), la recherche ensuite, les
   criteres rares dans un panneau replie. */
.vues-liste {
    display: flex;
    flex-wrap: wrap;
    gap: 0.2rem;
    padding: 0.25rem;
    margin: 1rem 0 0;
    background: rgba(0, 0, 0, 0.04);
    border-radius: 999px;
    width: fit-content;
    max-width: 100%;
}
.onglet-vue {
    padding: 0.4rem 0.95rem;
    border-radius: 999px;
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--gris);
    white-space: nowrap;
    transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
.onglet-vue:hover { color: var(--texte); }
.onglet-vue.actif {
    background: #fff;
    color: var(--texte);
    font-weight: 600;
    box-shadow: var(--ombre);
}

.barre-liste { margin-bottom: 1rem; }
.barre-liste .barre-recherche { align-items: center; }
.btn-filtres.actif { background: var(--accent); color: #fff; border-color: var(--accent); }
.compteur-resultats {
    margin-left: auto;
    color: var(--gris);
    font-size: 0.9rem;
    white-space: nowrap;
}

.filtres-avances {
    background: #fff;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    padding: 1rem 1.1rem;
    box-shadow: var(--ombre);
}
.grille-filtres {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 0.9rem 1.2rem;
}
.grille-filtres label,
.filtres-avances legend {
    display: block;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--gris);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
/* Les selects gardent l'apparence commune a l'app (chevron personnalise) :
   on ne redefinit ici que la largeur et l'espacement. */
.grille-filtres select,
.grille-filtres input[type="date"] {
    display: block;
    width: 100%;
    margin-top: 0.3rem;
}
.grille-filtres input[type="date"] {
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--bordure);
    border-radius: 10px;
    background-color: #fff;
    font-family: inherit;
    font-size: 0.9rem;
    color: var(--texte);
}
.filtre-periode { grid-column: span 2; }
.periode-champs { display: flex; gap: 0.5rem; }
.periode-champs > * { flex: 1; }

.filtres-documents {
    margin: 1rem 0 0;
    padding: 0.9rem 0 0;
    border: 0;
    border-top: 1px solid var(--bordure);
}
.filtres-documents legend { padding: 0; }
.case-document {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0.55rem 1.2rem 0 0;
    font-size: 0.9rem;
    font-weight: 400;
    color: var(--texte);
    text-transform: none;
    letter-spacing: 0;
}
.case-document input { accent-color: var(--accent); }

.actions-filtres {
    display: flex;
    gap: 0.5rem;
    margin-top: 1rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--bordure);
}

.filtres-actifs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 1rem;
}
.pastille-filtre {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.28rem 0.5rem 0.28rem 0.75rem;
    border-radius: 999px;
    background: rgba(51, 88, 244, 0.10);
    color: var(--accent);
    font-size: 0.85rem;
    font-weight: 500;
    transition: background 0.15s ease;
}
.pastille-filtre:hover { background: rgba(51, 88, 244, 0.18); }
.pastille-filtre .croix { font-size: 1.05rem; line-height: 1; opacity: 0.6; }
.lien-reinitialiser {
    color: var(--gris);
    font-size: 0.85rem;
    padding: 0.28rem 0.4rem;
}
.lien-reinitialiser:hover { color: var(--texte); text-decoration: underline; }

/* Sous 1024 px, les six vues ne tiennent plus sur une ligne : plutot qu'un
   controle segmente casse en deux, on defile horizontalement. */
@media (max-width: 1024px) {
    .vues-liste {
        width: 100%;
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: none;
    }
    .vues-liste::-webkit-scrollbar { display: none; }

    /* V1.6 : le ruban defilait sans le dire. La barre etant masquee, rien
       n'indiquait qu'il y avait d'autres vues hors champ - et une vue qu'on ne
       voit pas est une vue qui n'existe pas pour l'utilisateur.
       Fondu du bord concerne, uniquement quand il reste vraiment quelque
       chose de ce cote (classes posees par filtres.js d'apres le
       defilement reel). Un fondu permanent aurait attenue l'onglet actif
       lorsqu'il se trouve en derniere position. */
    .vues-liste.deborde-droite {
        -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
        mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
    }
    .vues-liste.deborde-gauche {
        -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 28px), transparent);
        mask-image: linear-gradient(to left, #000 calc(100% - 28px), transparent);
    }
    .vues-liste.deborde-gauche.deborde-droite {
        -webkit-mask-image: linear-gradient(to right, transparent, #000 28px,
                                            #000 calc(100% - 28px), transparent);
        mask-image: linear-gradient(to right, transparent, #000 28px,
                                    #000 calc(100% - 28px), transparent);
    }
}

@media (max-width: 800px) {
    .barre-liste .barre-recherche { flex-wrap: wrap; }
    .barre-liste .barre-recherche input[type="search"] { max-width: none; flex-basis: 100%; }
    .filtre-periode { grid-column: span 1; }
    .periode-champs { flex-wrap: wrap; }
    .compteur-resultats { margin-left: 0; }
}

.filtres-rapides { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 1rem; }
.puce-filtre {
    padding: 0.35rem 0.85rem;
    border: 1px solid var(--bordure);
    border-radius: 999px;
    text-decoration: none;
    color: var(--texte);
    font-size: 0.85rem;
    font-weight: 500;
    background: #fff;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.puce-filtre:hover { background: #f0f2f5; }
.puce-filtre.actif { background: var(--accent); color: #fff; border-color: var(--accent); }

/* ===================== Alertes ===================== */
.point {
    display: inline-block;
    width: 10px; height: 10px;
    border-radius: 50%;
    margin-right: 2px;
}
.point-rouge  { background: var(--rouge); }
.point-orange { background: var(--orange); }
.cellule-alertes { white-space: nowrap; }

.badge-actualiser {
    display: inline-block;
    background: var(--orange);
    color: #fff;
    font-size: 0.72rem;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    margin-left: 0.3rem;
}

.ligne-retenue { background: #e6f4ea; }
.ligne-retenue:hover { background: #d8eede; }

/* V1.3 item 4 : ligne liee au marqueur actif de la carte de proximite. */
.liste-table [data-carte-marqueur] { cursor: pointer; }
.liste-table tr.ligne-active { box-shadow: inset 3px 0 0 var(--orange); }
/* V1.4 item 3 : les liens "Trier par" sont des boutons textuels, pas des liens
   de texte courant. Ils deviennent de petites pastilles facon controle
   segmente : le soulignement disparait, l'affordance passe par le fond au
   survol et la couleur d'accent sur le critere actif. Pas de chevron ici, le
   sens du tri est porte par le libelle lui-meme ("plus ancien d abord"). */
.lien-tri {
    display: inline-block;
    padding: 0.1rem 0.6rem;
    margin-right: 0.15rem;
    border-radius: 999px;
    color: var(--gris);
    transition: background 0.15s ease, color 0.15s ease;
}
.lien-tri:hover { background: rgba(0, 0, 0, 0.06); color: var(--texte); }
.tri-actif {
    background: rgba(51, 88, 244, 0.10);
    color: var(--accent);
    font-weight: 600;
}
.conditions { max-width: 220px; white-space: normal; font-size: 0.85rem; }

/* V2.0 lot 4c : plus de bordure gauche, les alertes sont des pastilles (plus bas). */
.liste-alertes { list-style: none; padding: 0; margin: 0; }
.alerte { padding: 0.35rem 0; }
.alerte-rouge { color: var(--rouge); font-weight: 600; }
.alerte-orange { color: var(--orange); }

/* Palier tablette (V1.2 item 11). Jusqu'ici le CSS ne connaissait que deux
   paliers : desktop et telephone, avec une bascule unique a 800 px. Une tablette
   en portrait (768 px) sautait donc d'un coup en mise en page telephone, et une
   tablette en paysage (834 px) recevait la mise en page desktop sans adaptation.
   Ce palier intermediaire garde la navigation complete mais repasse les fiches
   sur une seule colonne : a cette largeur, deux colonnes serrent trop. */
@media (max-width: 1024px) {
    .content { padding: 1.2rem 1rem; }
    .fiche-colonnes { grid-template-columns: 1fr; }
    /* Tableau de bord : les actions et les remblais s'empilent. */
    .tdb-colonnes { grid-template-columns: 1fr; }

    /* V1.5.1 : la liste des chantiers etait le trou de ce palier.
       Sa deuxieme ligne (dates, decharge, commentaire, statuts) reclame 957 px
       pour tenir, parce que .col-statuts est en max-content : cette colonne ne
       se comprime jamais. En dessous, le trop-plein n'etait ni defilable ni
       ellipse, il etait COUPE. Mesure du 09/09/2026 sur iPad portrait
       (834 px) : 138 px manquants, "BDC ABS" tronque et "Travaux prepa"
       purement absent. Un suivi administratif ampute sans que rien ne signale
       qu'il manque quelque chose - le pire des defauts d'affichage.
       Correction : la colonne des statuts peut se comprimer et les pastilles
       passent a la ligne. La grille et l'alignement vertical des colonnes
       obtenus en V1.4 sont conserves ; seule la hauteur du bloc augmente. */
    .liste-chantiers .bloc-l2 {
        grid-template-columns: 20px max-content minmax(120px, 1fr)
                               minmax(90px, 1fr) minmax(0, max-content);
    }
    .liste-chantiers .col-statuts { flex-wrap: wrap; }

    /* Tableaux de liste en cartes empilees (remblais, decharges) : plutot que
       de defiler horizontalement, chaque ligne devient une carte et chaque
       cellule passe a la ligne, precedee du libelle de sa colonne. Meme esprit
       que la liste des chantiers. Le tableau desktop, lui, ne change pas. */
    .table-cartes thead { display: none; }
    .table-cartes, .table-cartes tbody,
    .liste-table.table-cartes td { display: block; width: auto; }
    /* colonne flex plutot que bloc : permet de remonter le nom en titre de carte
       sans changer l'ordre des colonnes du tableau desktop */
    .table-cartes tr {
        display: flex;
        flex-direction: column;
        padding: 0.7rem 0.9rem;
        border-bottom: 1px solid var(--bordure);
    }
    .table-cartes tr:last-child { border-bottom: none; }
    .table-cartes tr:nth-child(even) { background: #f8fafe; }
    .liste-table.table-cartes td {
        display: flex;
        gap: 0.6rem;
        align-items: baseline;
        padding: 0.15rem 0;
        border-bottom: none;
        white-space: normal;
        overflow: visible;
    }
    /* Libelle de colonne repris devant la valeur (data-libelle sur chaque td) */
    .liste-table.table-cartes td::before {
        content: attr(data-libelle);
        flex: 0 0 8rem;
        color: var(--gris);
        font-size: 0.72rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.05em;
    }
    /* La premiere cellule sert de titre de carte : pas de libelle, pleine largeur */
    .liste-table.table-cartes td.nom-client {
        display: block;
        order: -1;                   /* toujours en tete, meme si ce n'est pas
                                        la premiere colonne du tableau */
        font-size: 0.98rem;
        margin-bottom: 0.35rem;
    }
    .liste-table.table-cartes td.nom-client::before { display: none; }
    /* Une cellule sans valeur n'occupe pas de place */
    .liste-table.table-cartes td:empty { display: none; }
    /* Une cellule sans data-libelle occupe toute la largeur, sans intitule :
       cas des lignes modifiables ou le formulaire remplace toutes les colonnes
       (travaux divers), et de la cellule d'actions. */
    .liste-table.table-cartes td:not([data-libelle]) { display: block; }
    .liste-table.table-cartes td:not([data-libelle])::before { display: none; }
    /* Le commentaire est du texte long : libelle au-dessus et pleine largeur,
       sinon il s'ecrase sur la colonne etroite laissee par le libelle. */
    .liste-table.table-cartes td.col-commentaire {
        display: block;
        white-space: normal;
        overflow: visible;
        font-style: italic;
        margin-top: 0.2rem;
    }
    .liste-table.table-cartes td.col-commentaire::before {
        display: block;
        margin-bottom: 0.1rem;
        font-style: normal;
    }
}

/* Responsive : une colonne sur petit ecran */
@media (max-width: 800px) {
    /* .fiche-colonnes est deja sur une colonne depuis le palier 1024 px. */

    /* Tableaux cle/valeur : empiles plutot que defilants, un libelle et sa
       valeur restent lisibles cote a cote sur 390 px. */
    .infos-table, .infos-table tbody, .infos-table tr,
    .infos-table th, .infos-table td { display: block; width: auto; }
    .infos-table tr {
        padding: 0.4rem 0;
        border-bottom: 1px solid #f0f0f3;
    }
    .infos-table tr:last-child { border-bottom: none; }
    .infos-table th { padding: 0 0 0.15rem 0; font-size: 0.82rem; }
    .infos-table td { padding: 0; }

    /* Formulaires en ligne (ajout de tarif, de categorie, d'utilisateur...) :
       une rangee flex non secable faisait 638 px et poussait toute la page.
       Sur telephone ils passent a la ligne et occupent la largeur disponible. */
    .ligne-form, .ajout-form {
        display: flex;
        flex-wrap: wrap;
        width: 100%;
        margin-right: 0;
    }
    .ligne-form input, .ligne-form select,
    .ajout-form input, .ajout-form select {
        flex: 1 1 8rem;
        min-width: 0;
        max-width: 100%;
    }
    .ligne-form button, .ajout-form button { flex: 0 0 auto; }

    /* Barre de navigation : libelles masques, icones seules */
    .topbar { padding: 0.5rem 0.8rem; }
    .brand-texte { display: none; }
    .brand-logo { height: 34px; }
    .mainnav a span:not(.compteur-nav) { display: none; }
    .mainnav a { padding: 0.5rem 0.6rem; }
    .user-info { display: none; }

    /* V1.6 : tableaux en cartes, palier TELEPHONE.
       Report decide en V1.5 ("six tableaux defilent encore sous 600 px"),
       jamais fait. Mesure du 09/09/2026 : ils sont huit et non six (la
       proximite, citee a l'epoque, a ete convertie depuis en V1.4), et le pire
       reclame 730 px dans une fenetre de 310 -- deux ecrans et demi de
       defilement horizontal a l'interieur d'une page qui defile deja
       verticalement, ou l'on perd des colonnes sans le savoir.
       Pourquoi une variante et non `.table-cartes` : mesure faite, ces
       tableaux tiennent parfaitement en tablette (834 px) et ne cassent qu'en
       dessous de 600. Les basculer des 1024 px comme `.table-cartes` leur
       ferait perdre leur densite sans rien resoudre. Meme motif visuel, palier
       different parce que le besoin est different.
       Les declarations sont volontairement repetees plutot que factorisees :
       sans preprocesseur, la seule facon de partager serait de melanger les
       deux paliers dans un meme selecteur, et on ne saurait plus ce qui
       s'applique ou. */
    .table-cartes-tel thead { display: none; }
    .table-cartes-tel, .table-cartes-tel tbody,
    .table-cartes-tel td { display: block; width: auto; }
    .table-cartes-tel tr {
        display: flex;
        flex-direction: column;
        padding: 0.7rem 0.9rem;
        border-bottom: 1px solid var(--bordure);
    }
    .table-cartes-tel tr:last-child { border-bottom: none; }
    .table-cartes-tel td {
        display: flex;
        gap: 0.6rem;
        align-items: baseline;
        padding: 0.15rem 0;
        border-bottom: none;
        white-space: normal;
        overflow: visible;
        /* Noms de fichiers de sauvegarde et adresses e-mail : des chaines sans
           aucune espace. `white-space: normal` ne les coupe pas, elles sortaient
           donc du cadre par la droite. */
        overflow-wrap: anywhere;
        min-width: 0;
    }
    .table-cartes-tel td::before {
        content: attr(data-libelle);
        flex: 0 0 7rem;
        color: var(--gris);
        font-size: 0.72rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.05em;
    }
    /* Titre de carte : pleine largeur, en tete, sans intitule. */
    .table-cartes-tel td.nom-client {
        display: block;
        order: -1;
        font-weight: 600;
        font-size: 0.98rem;
        margin-bottom: 0.35rem;
    }
    .table-cartes-tel td.nom-client::before { display: none; }
    /* Une cellule vide ne prend pas de place ; une cellule sans intitule
       (formulaire occupant toutes les colonnes, cellule d'actions) occupe
       toute la largeur. */
    .table-cartes-tel td:empty { display: none; }
    .table-cartes-tel td:not([data-libelle]) { display: block; }
    .table-cartes-tel td:not([data-libelle])::before { display: none; }
    /* L'enrobage ne sert plus a rien une fois le tableau empile : sans cela il
       garde un defilement horizontal fantome de quelques pixels. */
    .tableau-defilant:has(> .table-cartes-tel),
    .table-scroll:has(> .table-cartes-tel) { overflow-x: visible; }

    /* Listes deux lignes : chaque bloc devient une carte empilee */
    .bloc-l1, .bloc-l2 {
        display: flex;
        flex-wrap: wrap;
        gap: 0.3rem 0.8rem;
    }
    .liste-chantiers .bloc-l2 { padding-left: 30px; }  /* aligne sous le nom, apres la pastille */
    .bloc-l2 .col-pastille { display: none; }
    .nom-chantier { flex: 1 1 calc(100% - 34px); white-space: normal; }
    .col-terrassement { text-align: left; }
    .col-statuts { flex-wrap: wrap; justify-content: flex-start; }
    .col-commentaire { flex: 1 1 100%; white-space: normal; }
    .bloc-liste { padding: 0.8rem 0.9rem; }
    /* Les cellules qui s'ellipsaient en grille reprennent leur largeur libre. */
    .bloc-l1 > *, .bloc-l2 > * { white-space: normal; overflow: visible; }
    .col-adresse, .col-conditions { flex: 1 1 100%; }
}

/* =========================================================================
   Cartes Google (V1.3) - fiche chantier, fiche decharge, proximite, tableau
   de bord. Sobre : la carte est un complement, jamais le sujet de la page.
   ========================================================================= */

.carte-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    margin-bottom: 0.6rem;
}

.carte-bloc {
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    overflow: hidden;
    background: var(--fond);
}

.carte-barre {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    padding: 0.5rem 0.6rem;
    border-bottom: 1px solid var(--bordure);
    background: #fff;
}
.carte-barre:empty { display: none; }

.carte-toile {
    width: 100%;
    height: var(--hauteur-carte);
    background: var(--fond);
}
/* Variante haute : carte d'ensemble du tableau de bord (V1.4 item 4). */
.carte-grande .carte-toile { height: var(--hauteur-carte-tdb); }

/* Encarts de repli : cartographie non configuree, hors ligne, sans coordonnees.
   Meme apparence que les autres messages neutres de l'application. */
.carte-encart,
.carte-repli {
    margin: 0;
    padding: 1.4rem 1rem;
    text-align: center;
    color: var(--gris);
    font-size: 0.9rem;
    background: var(--fond);
    border: 1px dashed var(--bordure);
    border-radius: var(--rayon);
}
.carte-repli { border: 0; }

/* Filtres de la carte d'ensemble (item 5). */
.carte-filtres {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

/* Pastille de regroupement : plusieurs chantiers au meme endroit (item 5). */
.carte-groupe {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    font-size: 0.82rem;
    font-weight: 600;
    border: 2px solid #fff;
    box-shadow: var(--ombre-survol);
    cursor: pointer;
}

/* Infobulle Google : on neutralise la police du SDK pour rester sur celle
   de l'application (V1.5.1 : ce n'est plus Inter, c'est celle du systeme,
   mais `inherit` reste la bonne reponse quelle que soit la police). */
.carte-info {
    font-family: inherit;
    font-size: 0.86rem;
    line-height: 1.45;
    color: var(--texte);
}

/* V1.4 item 4 : la carte du tableau de bord suit le palier tablette de
   l'application (1024 px, V1.2 item 11), la ou le tableau de bord repasse sur
   une colonne. L'ancien palier des cartes, a 820 px, ne correspondait a aucun
   autre palier du fichier : une tablette de 834 px gardait une carte de 500 px.
   Les cartes de fiche gardent leur propre palier ci-dessous : elles ne sont pas
   dans le perimetre de l'item 4, leur reglage V1.3 reste inchange. */
@media (max-width: 1024px) {
    :root { --hauteur-carte-tdb: 380px; }
}

@media (max-width: 820px) {
    :root { --hauteur-carte: 300px; }
}

@media (max-width: 560px) {
    /* Hauteur raisonnable sur telephone (item 9). Le defilement de la page
       reste prioritaire : le SDK est en mode "cooperative". */
    :root {
        --hauteur-carte: 240px;
        --hauteur-carte-tdb: 260px;
    }
    .carte-actions { flex-wrap: wrap; }
}

/* ============ Page "A propos" (V1.5 item 4.5) ============
   Deux colonnes libelle / valeur : on lit un etat, on ne remplit pas un
   formulaire. Les chemins de fichiers passent en police a chasse fixe, sinon
   ils sont illisibles et impossibles a recopier sans erreur. */
.ligne-apropos {
    display: flex;
    gap: 1rem;
    padding: 0.55rem 0;
    border-bottom: 1px solid #f0f0f3;
    font-size: 0.92rem;
}
.ligne-apropos:last-child { border-bottom: none; }
.apropos-libelle { flex: 0 0 40%; color: var(--gris); }
.apropos-valeur { flex: 1; min-width: 0; word-break: break-word; }
.apropos-complement { color: var(--vert); font-size: 0.85rem; margin-left: 0.4rem; }
.alerte-schema .apropos-valeur { color: var(--rouge); }

@media (max-width: 560px) {
    .ligne-apropos { flex-direction: column; gap: 0.15rem; }
    .apropos-libelle { flex: none; }
}

/* ====== Bandeau d'environnement d'essai (V1.5 item 4.6) ======
   Volontairement voyant et en haut de TOUTES les pages : son seul role est
   d'empecher de confondre deux fenetres identiques, l'une sur les vraies
   donnees, l'autre sur une copie. Rayures pour qu'il ne ressemble a aucun
   message metier de l'application. */
.bandeau-essai {
    position: sticky;
    top: 0;
    z-index: 100;
    padding: 0.5rem 1rem;
    text-align: center;
    font-size: 0.85rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: #4a3000;
    background: repeating-linear-gradient(
        45deg, #ffd77a, #ffd77a 12px, #ffcf5c 12px, #ffcf5c 24px);
    border-bottom: 2px solid #d9a200;
}

/* V1.7 (B3) : part du quota Google gratuit consommee ce mois-ci. */
.quota-ok { font-variant-numeric: tabular-nums; }
.quota-orange { color: var(--orange); font-weight: 600; font-variant-numeric: tabular-nums; }
.quota-rouge { color: var(--rouge); font-weight: 600; font-variant-numeric: tabular-nums; }


/* ===================== V2.0 lot 3 : onglet Taches =====================
   Habillage minimal et fonctionnel ; le design d'ensemble est le lot 4. */
.visuellement-cache {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap;
}
.compteur-nav {
    display: inline-grid; place-items: center; min-width: 1.35rem; height: 1.35rem;
    padding: 0 0.35rem; margin-left: 0.35rem; border-radius: 999px;
    background: var(--rouge); color: #fff; font-size: 0.72rem; font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.barre-taches { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 1.2rem; margin: 1rem 0; }
.barre-taches .vues-liste { margin: 0; }
.filtre-conducteur label { display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.9rem; }
.table-taches .col-urgence { width: 1.5rem; }
.table-taches tr.tache-urgente td { background: #fdf3f2; }
.table-taches tr.ligne-reglee td { opacity: 0.55; }
.table-taches tr.ligne-reglee td:nth-child(4) { text-decoration: line-through; }
.table-taches .ligne-groupe th { text-align: left; padding-top: 1rem; background: transparent; }
.badge-type { font-size: 0.75rem; font-weight: 600; padding: 0.15rem 0.5rem; border-radius: 6px; background: #eef0f5; }
.badge-type-acces { background: #fdecec; color: #9e2426; }
.tdb-taches-liste { list-style: none; margin: 0; padding: 0; }
.tdb-taches-liste li a {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0.1rem 1rem;
    padding: 0.55rem 0; border-top: 1px solid var(--bordure);
}
.tdb-taches-liste li:first-child a { border-top: 0; }
.tdb-taches-nom { font-weight: 600; }
.tdb-taches-liste .texte-attenue { grid-column: 1; }
.tdb-taches-quand { grid-row: 1 / span 2; grid-column: 2; align-self: center; font-variant-numeric: tabular-nums; }
.tdb-taches-liste li.tache-urgente .tdb-taches-quand { color: var(--rouge); font-weight: 700; }

/* ===================== V2.0 lot 4 : harmonisation des blocs =====================
   Tous les grands conteneurs prennent le traitement "carte" de la maquette :
   grand rayon, filet fin, ombre douce et profonde. Regroupe ici plutot que
   disperse dans chaque section, pour qu'on voie d'un coup d'oeil ce qui
   partage le meme habillage. Les petits blocs (jours du calendrier, repli de
   carte) gardent le rayon moyen. */
.param-section, .table-scroll, .liste-blocs, .chantier-form fieldset,
.tdb-sante, .tdb-actions, .tdb-remblais, .filtres-avances, .carte-bloc {
    border-radius: var(--rayon-carte);
    border: 1px solid var(--bordure);
    box-shadow: var(--ombre);
}
/* Un tableau pose DANS une carte n'en redessine pas une seconde. */
.fiche-bloc .table-scroll, .param-section .table-scroll {
    border: 0; box-shadow: none; border-radius: 0;
}
.calendrier-jour, .carte-repli { border-radius: var(--rayon); }

/* Chiffres alignes partout ou ils se comparent. */
.tdb-total-nombre, .badge-compteur, .compteur-resultats, .col-dates,
.col-terrassement, .liste-table td { font-variant-numeric: tabular-nums; }


/* ===================== V2.0 : en-tetes de tuile et temoin d'enregistrement =====================
   Manquaient depuis le lot 1 (constate a la premiere capture du lot 4) : le
   temoin "Enregistre" restait affiche en permanence, et les liens d'en-tete
   tombaient sous le titre. */
.titre-bloc {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
    gap: 0.4rem 1rem; margin-bottom: 0.9rem;
}
.titre-bloc h2 { margin: 0; }
.lien-tous { color: var(--accent); font-weight: 600; font-size: 0.88rem; }
.lien-tous:hover { color: var(--accent-fonce); }
/* Temoin : invisible au repos, "Enregistre" s'affiche puis s'efface (JS),
   une erreur reste affichee jusqu'a la prochaine modification. */
.temoin {
    font-size: 0.82rem; font-weight: 600; color: var(--vert);
    opacity: 0; transition: opacity 0.25s ease; min-height: 1em;
}
.temoin.visible { opacity: 1; }
.temoin:not(.temoin-erreur)::before { content: "✓ "; }
.temoin.temoin-erreur { color: var(--rouge); }
[aria-busy="true"] { opacity: 0.6; }

/* Grand chiffre du tableau de bord : en bleu, comme la maquette. */
.tdb-total-nombre { color: var(--accent); font-weight: 800; letter-spacing: -0.045em; }

/* ===================== V2.0 lot 4c : fiche chantier (maquette) ===================== */
.surtitre { margin: 0; font-size: 0.85rem; font-weight: 500; color: var(--gris); min-height: 1.2em; }
.h1-dept { font-size: 0.55em; font-weight: 500; color: var(--gris); letter-spacing: -0.01em; }
.entete-chantier h1 { margin: 0.25rem 0 0.7rem; }

/* Statut general : controle a deux positions. Le bouton choisi prend la
   couleur de son statut ; l'autre reste neutre. */
.statut-general { display: inline-flex; align-items: center; gap: 0.8rem; flex-wrap: wrap; }
.statut-choix {
    display: inline-flex; gap: 4px; padding: 4px;
    background: var(--fond); border: 1px solid var(--bordure); border-radius: 12px;
}
.statut-option { position: relative; cursor: pointer; }
.statut-option input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.statut-option span {
    display: inline-flex; align-items: center; gap: 0.5rem;
    padding: 0.45rem 0.9rem; border-radius: 9px;
    font-weight: 600; font-size: 0.88rem; color: var(--gris);
    transition: background 0.15s ease, color 0.15s ease;
}
.statut-option span::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--bordure); }
.statut-option input:checked + span { background: #fff; box-shadow: 0 1px 2px rgba(10, 19, 48, 0.08); }
.statut-vert input:checked + span { color: var(--vert); }
.statut-vert input:checked + span::before { background: var(--vert); }
.statut-rouge input:checked + span { color: var(--rouge); }
.statut-rouge input:checked + span::before { background: var(--rouge); }
.statut-option input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Alertes : pastilles sur une ligne (item 2.1). */
.bloc-alertes { margin: 0 0 1.2rem; }
.bloc-alertes .liste-alertes { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.bloc-alertes .alerte {
    display: inline-flex; align-items: center; gap: 0.5rem;
    padding: 0.45rem 0.8rem; border-radius: 10px; border: 0;
    font-size: 0.87rem; font-weight: 500;
}
.bloc-alertes .alerte::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.bloc-alertes .alerte-rouge { background: var(--rouge-lavis); color: #9e2426; }
.bloc-alertes .alerte-orange { background: var(--ambre-lavis); color: #7a4a00; }

/* Suivi administratif : libelle a gauche, commande a droite, une ligne par
   element, separees par un filet (maquette). */
.champs-suivi { display: grid; }
.champs-suivi .case {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    padding: 0.6rem 0; margin: 0; border-top: 1px solid var(--bordure); font-weight: 500;
}
.champs-suivi .case:first-child { border-top: 0; }
.champs-suivi .case select, .champs-suivi .case input[type="date"] { width: min(18.5rem, 62%); }

/* Interrupteurs (D8) : les cases a cocher du suivi prennent la forme d'un
   interrupteur. C'est TOUJOURS une case a cocher (clavier, lecteur d'ecran,
   enregistrement automatique inchanges) : seul l'habillage change. */
.champs-suivi input[type="checkbox"] {
    order: 2; appearance: none; -webkit-appearance: none; flex-shrink: 0;
    position: relative; width: 44px; height: 26px; margin: 0; cursor: pointer;
    border-radius: 999px; background: #d5dceb; transition: background 0.2s ease;
}
.champs-suivi input[type="checkbox"]::after {
    content: ""; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px;
    border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(10, 19, 48, 0.25);
    transition: transform 0.2s ease;
}
.champs-suivi input[type="checkbox"]:checked { background: var(--vert); }
.champs-suivi input[type="checkbox"]:checked::after { transform: translateX(18px); }
.champs-suivi input[type="checkbox"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
    .champs-suivi input[type="checkbox"], .champs-suivi input[type="checkbox"]::after,
    .statut-option span, .temoin { transition: none; }
}

/* Etats des taches : rouge a faire, AMBRE en cours, vert fait (D8). */
.select-etat { font-weight: 600; }
tr.tache-a_faire .select-etat { color: var(--rouge); }
tr.tache-en_cours .select-etat { color: var(--orange); }
tr.tache-fait .select-etat { color: var(--vert); }
tr.tache-fait td.nom-client input { text-decoration: line-through; color: var(--gris); }
.badge-compteur.tout-fait { background: var(--vert-lavis); color: var(--vert); }


/* V2.0 : onglet Taches sur telephone. Le menu d'acces ("Devis en attente
   d'acceptation") faisait deborder TOUTE la page de 38 px a 390 px de large
   (mesure du 25/09/2026). Il prend la largeur disponible, jamais plus. */
.table-taches select { max-width: 100%; min-width: 0; }
@media (max-width: 800px) {
    .table-taches td[data-libelle] select { width: 100%; }
    .table-taches td[data-libelle] { min-width: 0; }
}

/* ===================== V2.0.1 : refonte de la page Parametres =====================
   Retour de Geoffrey sur la V2.0 : trop d'espace perdu, et les champs des
   conducteurs / centres etaient restes nus (rendu carre du navigateur).
   Listes courtes deux par deux, lignes serrees, champs "sur place". */
.param-grille {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.25rem;
    align-items: start;
    margin-bottom: 1.25rem;
}
.param-grille .param-section { margin-bottom: 0; }
@media (max-width: 1024px) {
    .param-grille { grid-template-columns: minmax(0, 1fr); }
}

.param-section { padding: 1.1rem 1.25rem 1rem; }
.param-section .titre-bloc { margin-bottom: 0.5rem; }
.param-section h2 { font-size: 1.05rem; display: flex; align-items: center; gap: 0.5rem; }
.param-compte {
    display: inline-grid; place-items: center; min-width: 1.5rem; height: 1.5rem;
    padding: 0 0.45rem; border-radius: 999px;
    background: var(--accent-lavis); color: var(--accent);
    font-size: 0.75rem; font-weight: 700; font-variant-numeric: tabular-nums;
}

.param-table { margin-bottom: 0; }
.param-table th, .param-table td { padding: 0.3rem 0.4rem; border-bottom: 1px solid #eef1f7; }
.param-table tbody tr:last-child td { border-bottom: none; }
.param-table tbody tr:hover { background: #f8f9fd; }
.param-table tr.inactif { opacity: 1; }
.param-table tr.inactif .champ-sur-place { color: var(--gris); }
.param-table .col-nom { width: 100%; }
.param-table .col-statut, .param-table .col-densite, .param-table .col-role { white-space: nowrap; }
.param-table .col-role { color: var(--texte-2); font-size: 0.9rem; padding-right: 1rem; }
.param-table .actions { text-align: right; }
.param-table .actions form { margin: 0 0 0 0.3rem; }

/* Champ modifiable sur place : aspect de texte au repos, cadre au survol,
   anneau d'accent a la saisie (regle commune :focus-visible). */
.champ-sur-place {
    width: 100%;
    min-width: 0;
    padding: 0.4rem 0.6rem;
    border: 1px solid transparent;
    border-radius: 10px;
    background: transparent;
    font: inherit;
    font-size: 0.92rem;
    color: var(--texte);
    transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}
.champ-sur-place:hover { border-color: var(--bordure); background: #fff; }
.champ-sur-place:focus { background: #fff; }
.champ-sur-place.champ-nombre { width: 5.5rem; text-align: right; }

.champ-unite { display: inline-flex; align-items: center; gap: 0.35rem; }
.unite { color: var(--gris); font-size: 0.85rem; }

/* Statut : pastille plutot que texte brut. */
.pastille-etat {
    display: inline-block; padding: 0.15rem 0.6rem; border-radius: 999px;
    font-size: 0.75rem; font-weight: 600;
}
.pastille-etat-oui { background: var(--vert-lavis); color: var(--vert); }
.pastille-etat-non { background: #eef0f4; color: var(--gris); }

/* Zone d'ajout : pied de carte, separe par un filet. */
.param-ajout {
    display: flex;
    width: 100%;
    margin: 0.6rem 0 0;
    padding-top: 0.75rem;
    border-top: 1px dashed var(--bordure);
}
.param-ajout input[type="text"], .param-ajout input[type="password"] { flex: 1 1 10rem; }
.param-ajout input[type="number"], .param-ajout select,
.param-ajout input.champ-nombre {
    padding: 0.45rem 0.6rem; border: 1px solid var(--bordure); border-radius: 10px;
    font: inherit; font-size: 0.9rem; background-color: #fff;
}
.param-ajout select { padding-right: 2rem; }

/* Reglages : une ligne par reglage, libelle a gauche, valeur a droite. */
.reglages-form { display: flex; flex-direction: column; }
.reglage {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    padding: 0.35rem 0.4rem; border-bottom: 1px solid #eef1f7;
}
.reglage:last-child { border-bottom: none; }
.reglage-libelle { font-size: 0.92rem; color: var(--texte-2); }
.reglage .unite { min-width: 4.6rem; }   /* valeurs alignees d'une ligne a l'autre */

/* Telephone : les tableaux passent en cartes (table-cartes-tel, palier 800 px). */
@media (max-width: 800px) {
    .param-section { padding: 1rem; }
    /* Une ligne = le nom sur toute la largeur, puis statut et boutons cote a
       cote : la carte empilee generique (un intitule par valeur) triplait la
       hauteur de ces listes pour rien. */
    .param-table.table-cartes-tel tr {
        flex-direction: row; flex-wrap: wrap; align-items: center;
        gap: 0.35rem 0.5rem; padding: 0.55rem 0;
    }
    .param-table.table-cartes-tel td { padding: 0; border-bottom: none; align-items: center; }
    .param-table.table-cartes-tel td.col-nom,
    .param-table.table-cartes-tel td.nom-client { flex: 1 0 100%; margin-bottom: 0; }
    .param-table.table-cartes-tel td.col-statut::before,
    .param-table.table-cartes-tel td.col-densite::before,
    .param-table.table-cartes-tel td.col-role::before { display: none; }
    .param-table .actions { text-align: left; margin-left: auto; }
    .param-table .actions form { margin: 0 0 0 0.3rem; }
    .reglage { flex-direction: column; align-items: flex-start; gap: 0.25rem; }
}

/* ===================== V2.0.4 : retours sur la V2.0.3 =====================
   1. Graisses de la maquette validee (docs/maquette_v2.html) : titres de
      ligne en demi-gras, chiffres en gras, grands nombres en extra-gras.
   2. En-tete de la fiche chantier et tuile "Informations principales".
   3. Barre de navigation : elle passait sur deux lignes entre 800 et 1300 px
      (fenetre du navigateur non maximisee). */

/* --- 1. Graisses ---------------------------------------------------------- */
.tdb-total-nombre { font-size: 3.4rem; font-weight: 800; letter-spacing: -0.045em; line-height: 0.9; color: var(--accent); }
.tdb-total-libelle { color: var(--texte-2); font-weight: 500; }
.tdb-legende strong { font-weight: 700; }
.tdb-actions h2 {
    margin: 0 0 0.4rem; font-size: 1rem; font-weight: 700; letter-spacing: -0.015em;
    text-transform: none; color: var(--texte);
}
.action-libelle { font-weight: 600; letter-spacing: -0.01em; }
.liste-actions .a-zero .action-libelle { font-weight: 500; }
.action-nombre { font-weight: 700; }
.tdb-remblais-nombre { font-weight: 800; letter-spacing: -0.04em; }
.tdb-remblais-libelle { color: var(--texte-2); font-weight: 500; }
.tdb-remblais-nom { font-weight: 600; letter-spacing: -0.01em; }
.tdb-remblais-jours { font-weight: 700; }
.tdb-remblais-tous, .lien-tous { font-weight: 600; }
.jour-chantier { font-weight: 500; }
.jour-titre { font-weight: 700; }
.tdb-taches-quand { font-weight: 600; }
.fiche-bloc h2, .param-section h2 { letter-spacing: -0.015em; }

/* --- 2. Fiche chantier ---------------------------------------------------- */
.entete-chantier { align-items: flex-end; margin-bottom: 1rem; }
.entete-chantier h1 { margin: 0.3rem 0 0; }
.entete-titre { min-width: 0; }
.surtitre { display: flex; flex-wrap: wrap; gap: 0.2rem 0.45rem; align-items: center; }
.lien-retour { color: var(--accent); font-weight: 600; }
.lien-retour:hover { color: var(--accent-fonce); }
.entete-chantier .entete-actions { align-items: center; gap: 0.6rem; }
.entete-chantier .entete-actions form { margin: 0; }
/* Le temoin passe a gauche du controle : a droite, il decalait les boutons. */
.entete-chantier .statut-general { gap: 0.6rem; }

/* Informations principales : grille de couples libelle / valeur, deux par
   ligne, l'adresse sur toute la largeur. */
.infos-grille {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0; margin: 0;
}
.info { padding: 0.55rem 0; border-top: 1px solid var(--bordure); min-width: 0; }
.info:nth-child(-n+1) { border-top: 0; }
.info-large { grid-column: 1 / -1; }
.info dt { font-size: 0.78rem; color: var(--gris); font-weight: 500; margin-bottom: 0.1rem; }
.info dd { margin: 0; font-weight: 600; letter-spacing: -0.01em; overflow-wrap: anywhere; }
.info:not(.info-large):nth-child(even) { padding-right: 1rem; }
.info dd.a-renseigner { color: var(--gris); font-weight: 500; }
.info .mention-coord { display: block; font-weight: 400; }
@media (max-width: 560px) {
    .infos-grille { grid-template-columns: minmax(0, 1fr); }
}

/* Page Modifier : gestes rares, en pied de page, sobres. */
.zone-rare {
    margin-top: 2.5rem; padding: 1.1rem 1.3rem;
    border: 1px dashed var(--bordure); border-radius: var(--rayon-carte);
}
.zone-rare h2 { margin: 0 0 0.5rem; font-size: 0.95rem; color: var(--texte-2); }
.zone-rare-ligne {
    display: flex; align-items: center; justify-content: space-between; gap: 0.6rem 1.5rem;
    flex-wrap: wrap; padding: 0.6rem 0; border-top: 1px solid var(--bordure);
}
.zone-rare-ligne:first-of-type { border-top: 0; }
.zone-rare-ligne p { margin: 0; flex: 1 1 22rem; color: var(--gris); font-size: 0.88rem; }
.zone-rare-ligne form { margin: 0; }

/* --- 3. Navigation ------------------------------------------------------- */
.topbar-inner { flex-wrap: nowrap; }
.mainnav { flex-wrap: nowrap; }
.mainnav a { white-space: nowrap; }
@media (max-width: 1320px) {
    .brand-texte { display: none; }
}
@media (max-width: 1180px) {
    .mainnav a { padding: 0.45rem 0.6rem; }
    .user-info { display: none; }
}
/* Entre le palier telephone et 1060 px : icones seules, le libelle reste
   annonce par l'attribut title (et lu par les lecteurs d'ecran). */
@media (max-width: 1060px) {
    .mainnav a span:not(.compteur-nav) { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}
/* La tuile d'informations, plus courte que le suivi, ne s'etire plus : un
   grand blanc dans une carte se lit comme une information manquante. */
.fiche-colonnes { align-items: start; }
/* Palier telephone : la barre reprend le droit de passer a la ligne (icones
   seules, mais sept liens plus le compteur des taches depassent 390 px). */
@media (max-width: 800px) {
    .topbar-inner, .mainnav { flex-wrap: wrap; }
    .mainnav { justify-content: flex-end; }
}

/* ===================== V2.1 lot 1 : fiche chantier =====================
   Colonne de gauche (informations + avancement), frise d'avancement,
   carte unique et ses commandes. */
.fiche-colonne { display: grid; gap: 1.2rem; align-content: start; min-width: 0; }
.fiche-colonne > .fiche-bloc { margin-bottom: 0; }

/* Frise : quatre etapes, la courante en bleu, les faites en vert. */
.frise {
    list-style: none; margin: 0 0 0.9rem; padding: 0;
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
}
.etape { position: relative; padding-top: 1.35rem; min-width: 0; }
.etape::before {                      /* le trait qui relie les etapes */
    content: ""; position: absolute; top: 0.45rem; left: 0; right: 0;
    height: 3px; background: var(--bordure);
}
.etape:first-child::before { left: 0.5rem; }
.etape:last-child::before { right: auto; width: 0.5rem; }
.etape::after {                       /* le point de l'etape */
    content: ""; position: absolute; top: 0; left: 0;
    width: 12px; height: 12px; border-radius: 50%;
    background: #fff; border: 3px solid var(--bordure);
}
.etape.fait::before, .etape.fait::after { background: var(--vert); border-color: var(--vert); }
.etape.en-cours::after { border-color: var(--accent); box-shadow: var(--focus); }
.etape-nom { display: block; font-weight: 600; font-size: 0.9rem; letter-spacing: -0.01em; }
.etape-date { display: block; font-size: 0.78rem; color: var(--gris); font-variant-numeric: tabular-nums; }
.etape.en-cours .etape-nom { color: var(--accent); }
.etape:not(.fait):not(.en-cours) .etape-nom { color: var(--gris); font-weight: 500; }
.avancement-dates { border-top: 1px solid var(--bordure); padding-top: 0.7rem; }
.avancement-dates input:disabled { opacity: 0.5; cursor: not-allowed; }

/* Carte unique : commandes dans l'en-tete de la tuile. */
.carte-commandes { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.8rem; }
.segments {
    display: inline-flex; gap: 3px; padding: 3px;
    background: var(--fond); border: 1px solid var(--bordure); border-radius: 11px;
}
.segment {
    border: 0; background: transparent; cursor: pointer; font: inherit;
    font-size: 0.82rem; font-weight: 600; color: var(--gris);
    padding: 0.35rem 0.75rem; border-radius: 8px;
}
.segment[aria-pressed="true"] { background: #fff; color: var(--accent-fonce); box-shadow: 0 1px 2px rgba(10, 19, 48, 0.08); }
.segment:disabled, .interrupteur-carte input:disabled { cursor: default; opacity: 0.55; }
.interrupteur-carte { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.85rem; font-weight: 600; cursor: pointer; }
.carte-legende { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem 0.5rem; margin: -0.3rem 0 0.7rem; font-size: 0.8rem; }
.point-legende { width: 10px; height: 10px; border-radius: 50%; display: inline-block; margin-left: 0.4rem; }
.point-legende:first-child { margin-left: 0; }
.point-chantier { background: #2e5d3b; }
.point-depot { background: var(--accent); }
.point-decharge { background: #ed6c02; }

@media (max-width: 800px) {
    .frise { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 0.8rem; }
    .etape:nth-child(2)::before { right: auto; width: 0.5rem; }
    .etape:nth-child(3)::before { left: 0.5rem; }
}

/* ===================== V2.1 lot 2 : fil d'actualite =====================
   Une carte par auteur et par chantier : pastille d'initiales, nom, chantier,
   moment, puis les actions. */
.fil-outils { display: flex; align-items: center; gap: 0.8rem; flex-wrap: wrap; }
.fil-filtre { margin: 0; }
.fil-filtre select { font-size: 0.82rem; padding-top: 0.3rem; padding-bottom: 0.3rem; }
.fil-suite { text-align: center; margin: 1rem 0 0; }

/* ===================== V2.1 lot 3 : photos, carrousel, types =====================
   Grille de vignettes carrees, carrousel plein ecran (element <dialog>). */
.btn-icone { padding: 0.45rem 0.6rem; display: inline-flex; align-items: center; }
.photos-grille {
    list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 0.5rem;
}
.photo-vignette {
    position: relative; display: block; width: 100%; aspect-ratio: 1; padding: 0;
    border: 0; border-radius: 12px; overflow: hidden; cursor: zoom-in; background: var(--fond);
}
.photo-vignette img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.2s ease; }
.photo-vignette:hover img { transform: scale(1.04); }
.photo-gps {
    position: absolute; left: 6px; bottom: 6px; padding: 0.05rem 0.35rem; border-radius: 6px;
    background: rgba(10, 19, 48, 0.65); color: #fff; font-size: 0.65rem; font-weight: 700; letter-spacing: 0.04em;
}
.photos-etat { margin: 0 0 0.7rem; font-size: 0.88rem; font-weight: 600; color: var(--accent); }
.photos-etat.photos-etat-erreur { color: var(--rouge); }

.carrousel {
    width: 100vw; height: 100vh; max-width: none; max-height: none; margin: 0; padding: 0;
    border: 0; background: rgba(8, 12, 28, 0.94); color: #fff;
}
.carrousel[open] { display: flex; flex-direction: column; }
.carrousel::backdrop { background: rgba(8, 12, 28, 0.6); }
.carrousel-barre {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.8rem;
    padding: 0.7rem 1rem; font-size: 0.88rem;
}
.carrousel-compteur { font-weight: 700; font-variant-numeric: tabular-nums; }
.carrousel-infos { flex: 1; color: #c9d1e6; min-width: 12rem; }
.carrousel-barre form { margin: 0; }
.carrousel-scene { flex: 1; min-height: 0; display: grid; grid-template-columns: auto 1fr auto; align-items: center; }
.carrousel-scene img { max-width: 100%; max-height: calc(100vh - 5rem); margin: auto; object-fit: contain; }
.carrousel-fleche {
    background: transparent; border: 0; color: #fff; font-size: 3rem; line-height: 1;
    padding: 1rem 1.2rem; cursor: pointer; opacity: 0.75;
}
.carrousel-fleche:hover { opacity: 1; }
@media (max-width: 800px) {
    .carrousel-fleche { font-size: 2.2rem; padding: 0.5rem; }
    .photos-grille { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.col-type-document { white-space: nowrap; }
.select-type-document { font-size: 0.82rem; padding-top: 0.25rem; padding-bottom: 0.25rem; }
.badge-type-document {
    font-size: 0.75rem; font-weight: 600; padding: 0.15rem 0.5rem; border-radius: 6px;
    background: var(--accent-lavis); color: var(--accent-fonce);
}
.ajout-piece-jointe select { max-width: 13rem; }

/* ===================== V2.1 lot 4 : onglet Planning =====================
   Grille des jours a gauche, colonne "A planifier / Remblais" a droite.
   V2.1.1 : semaine et mois du lundi au samedi (6 colonnes), puces sur deux
   niveaux, textes qui passent a la ligne au lieu de deborder. */
.entete-planning { align-items: flex-end; }
.entete-planning .surtitre { margin-top: 0.2rem; }
.planning-outils { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 1rem; }
.planning-nav { display: inline-flex; gap: 0.35rem; }
.segments a.segment { text-decoration: none; display: inline-block; }
.planning-message { margin: 0.8rem 0 0; font-weight: 600; color: var(--accent); }
.planning-message.planning-message-erreur { color: var(--rouge); }

.planning {
    display: grid; grid-template-columns: minmax(0, 1fr) 17rem; gap: 1.2rem;
    align-items: start; margin-top: 1rem;
}
.planning-grille { display: grid; gap: 0.6rem; grid-template-columns: repeat(6, minmax(0, 1fr)); }
.planning-grille.vue-mois { gap: 0.4rem; }
.planning-entete-col { font-size: 0.75rem; font-weight: 700; color: var(--gris); text-transform: uppercase; letter-spacing: 0.05em; padding: 0 0.3rem; }

.planning-jour {
    background: #fff; border: 1px solid var(--bordure); border-radius: var(--rayon);
    padding: 0.55rem; min-height: 18rem; min-width: 0; display: flex; flex-direction: column; gap: 0.45rem;
    transition: box-shadow 0.15s ease, border-color 0.15s ease;
}
.vue-mois .planning-jour { min-height: 7.5rem; padding: 0.4rem; gap: 0.3rem; }
.planning-jour.aujourdhui { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.planning-jour.hors-mois { opacity: 0.45; }
.planning-jour.week-end { background: #fafbfe; }
.planning-jour.survol-depot, .planning-a-planifier.survol-depot { border-color: var(--accent); box-shadow: var(--focus); }
.planning-jour-tete { display: flex; align-items: center; justify-content: space-between; gap: 0.3rem; font-size: 0.8rem; color: var(--gris); min-height: 1.6rem; }
.planning-jour-tete > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.planning-jour-tete strong { color: var(--texte); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; font-size: 0.75rem; }
.aujourdhui .planning-jour-tete strong, .aujourdhui .planning-numero { color: var(--accent); }
.planning-numero { font-weight: 700; color: var(--texte); }
.planning-plus {
    flex-shrink: 0; width: 1.6rem; height: 1.6rem; border-radius: 8px; border: 1px solid var(--bordure);
    background: #fff; color: var(--gris); cursor: pointer; font-size: 1rem; line-height: 1;
    opacity: 0; transition: opacity 0.15s ease;
}
.planning-jour:hover .planning-plus, .planning-plus:focus-visible { opacity: 1; }
@media (hover: none) { .planning-plus { opacity: 1; } }
.planning-plus:hover { color: var(--accent); border-color: var(--accent); }
.planning-contenu { display: flex; flex-direction: column; gap: 0.35rem; min-height: 1.5rem; min-width: 0; }

/* Puce : petite ligne de type, puis le nom (trois lignes au plus). */
.puce-planning {
    display: flex; flex-direction: column; gap: 0.1rem; padding: 0.4rem 0.5rem;
    border-radius: 9px; font-size: 0.8rem; font-weight: 600; color: var(--texte);
    background: var(--fond); border: 1px solid transparent; min-width: 0;
    border-left: 3px solid var(--bordure);
}
.puce-planning[draggable="true"] { cursor: grab; }
.puce-planning:hover { border-color: var(--bordure); background: #fff; }
.puce-planning.en-deplacement { opacity: 0.4; }
.puce-terrassement.pret { background: var(--vert-lavis); border-left-color: var(--vert); }
.puce-terrassement.pas-pret { background: var(--rouge-lavis); border-left-color: var(--rouge); }
.puce-tache { background: var(--accent-lavis); border-left-color: var(--accent); }
.puce-tache.etat-en_cours { background: var(--ambre-lavis); border-left-color: var(--orange); }
.puce-type {
    display: flex; align-items: center; gap: 0.3rem; min-width: 0;
    font-size: 0.66rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--gris);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.puce-type .pastille { width: 7px; height: 7px; flex-shrink: 0; }
.puce-texte {
    min-width: 0; line-height: 1.3; overflow-wrap: anywhere; hyphens: auto;
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.puce-tache .puce-texte { font-weight: 500; }
.puce-tache.etat-fait { opacity: 0.55; }
.puce-tache.etat-fait .puce-texte { text-decoration: line-through; }
/* Mois : une ligne par element, le type devient la seule pastille. */
.vue-mois .puce-planning { flex-direction: row; align-items: center; gap: 0.3rem; padding: 0.2rem 0.35rem; font-size: 0.72rem; border-left-width: 3px; }
.vue-mois .puce-type { display: none; }
.vue-mois .puce-texte { display: block; white-space: nowrap; text-overflow: ellipsis; }
.planning-plus-de { font-size: 0.72rem; font-weight: 600; color: var(--accent); padding-left: 0.3rem; }

.planning-cote { display: grid; gap: 1rem; min-width: 0; }
.planning-cote .fiche-bloc { margin-bottom: 0; padding: 1rem 1.1rem; min-width: 0; }
.planning-cote h2 { font-size: 0.98rem; display: flex; align-items: center; gap: 0.4rem; }
.planning-cote .aide { font-size: 0.8rem; margin: 0.2rem 0 0.6rem; }
.planning-remblais { list-style: none; margin: 0; padding: 0; }
.planning-remblais a { display: flex; align-items: center; gap: 0.5rem; padding: 0.35rem 0.2rem; font-size: 0.85rem; font-weight: 600; min-width: 0; }
.planning-remblais a:hover { color: var(--accent); }
.planning-remblais .puce-texte { flex: 1; display: block; white-space: nowrap; text-overflow: ellipsis; }
.planning-remblais .tdb-remblais-jours { flex-shrink: 0; }

.dialogue-planning {
    border: 0; border-radius: var(--rayon-carte); padding: 1.3rem 1.4rem; width: min(26rem, calc(100vw - 2rem));
    box-shadow: var(--ombre-survol);
}
.dialogue-planning::backdrop { background: rgba(10, 19, 48, 0.35); }
.dialogue-planning h2 { margin: 0 0 0.9rem; font-size: 1.05rem; }
.dialogue-planning .segments { margin-bottom: 0.8rem; }
.dialogue-planning label.segment { cursor: pointer; }
.dialogue-planning label.segment input { position: absolute; opacity: 0; pointer-events: none; }
.dialogue-planning label.segment:has(input:checked) { background: #fff; color: var(--accent-fonce); box-shadow: 0 1px 2px rgba(10, 19, 48, 0.08); }
.champ-dialogue { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.85rem; font-weight: 600; margin-bottom: 0.7rem; }
.champ-dialogue select, .champ-dialogue input { width: 100%; font-weight: 400; }
.champ-dialogue input { padding: 0.45rem 0.6rem; border: 1px solid var(--bordure); border-radius: 10px; font: inherit; }

/* Moins de 1180 px : la colonne passe sous la grille, en deux tuiles cote a cote. */
@media (max-width: 1180px) {
    .planning { grid-template-columns: minmax(0, 1fr); }
    .planning-cote { grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); align-items: start; }
}
/* Moins de 900 px : la semaine devient une liste de jours. */
@media (max-width: 900px) {
    .planning-grille.vue-semaine { grid-template-columns: minmax(0, 1fr); }
    .vue-semaine .planning-jour { min-height: 0; }
    .vue-semaine .planning-contenu { display: grid; grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr)); }
}
@media (max-width: 800px) {
    .planning-grille.vue-mois { gap: 2px; }
    .vue-mois .planning-jour { min-height: 3.2rem; padding: 0.2rem; border-radius: 6px; }
    .vue-mois .puce-planning .puce-texte { display: none; }
    .vue-mois .puce-planning { padding: 0; width: 8px; height: 8px; border-radius: 50%; border: 0; }
    .vue-mois .puce-terrassement.pret { background: var(--vert); }
    .vue-mois .puce-terrassement.pas-pret { background: var(--rouge); }
    .vue-mois .puce-tache { background: var(--accent); }
    .vue-mois .planning-contenu { flex-direction: row; flex-wrap: wrap; gap: 2px; }
    .vue-mois .planning-plus-de { display: none; }
    /* Mois sur telephone : pas de "+" dans des cases de 50 px ; toucher le
       numero ouvre la semaine, ou le "+" est a sa place. */
    .vue-mois .planning-plus { display: none; }
    /* Huit liens depuis l'onglet Planning : icones resserrees pour tenir sur
       une ligne sous le logo. */
    .mainnav { gap: 0; }
    .mainnav a { padding: 0.45rem 0.42rem; }
}

/* ===================== V2.1.1 : tableau de bord, fil, carte =====================
   Le tableau de bord ne garde que le fil (a gauche) et la carte (a droite,
   collante). Le fil devient une suite de cartes facon reseau social, photos
   en grand (retour de Geoffrey, capture Alobees a l'appui). */
.tdb-grille {
    display: grid; grid-template-columns: minmax(0, 40rem) minmax(0, 1fr);
    gap: 1.5rem; align-items: start;
}
.tdb-fil-titre { margin-bottom: 0.8rem; }
.tdb-fil-titre h2 { font-size: 1.35rem; }
.tdb-carte { position: sticky; top: 5.2rem; }
.point-pret { background: #2e7d32; }
.point-pas-pret { background: #c62828; }
.fil-vide { background: #fff; border: 1px dashed var(--bordure); border-radius: var(--rayon-carte); padding: 2rem 1.5rem; text-align: center; }
@media (max-width: 1180px) {
    .tdb-grille { grid-template-columns: minmax(0, 1fr); }
    .tdb-fil { max-width: 42rem; width: 100%; margin: 0 auto; }
    .tdb-carte { position: static; }
}

/* Cartes du fil */
.fil { list-style: none; margin: 0; padding: 0; display: grid; gap: 1rem; }
.fil-carte {
    background: #fff; border: 1px solid var(--bordure); border-radius: var(--rayon-carte);
    box-shadow: var(--ombre); padding: 1rem 1.15rem 1.1rem;
}
.fil-entete { display: flex; align-items: center; gap: 0.75rem; }
.fil-avatar {
    flex-shrink: 0; width: 2.6rem; height: 2.6rem; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--teinte, var(--accent)); color: #fff;
    font-size: 0.85rem; font-weight: 700; letter-spacing: 0.02em;
}
.fil-qui { min-width: 0; display: flex; flex-direction: column; gap: 0.05rem; }
.fil-tete { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.1rem 0.5rem; }
.fil-tete strong { font-weight: 700; }
.fil-quand { font-size: 0.8rem; color: var(--gris); white-space: nowrap; }
.fil-chantier { font-weight: 600; color: var(--accent); font-size: 0.92rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fil-chantier:hover { color: var(--accent-fonce); }
.fil-chantier-supprime { color: var(--gris); text-decoration: line-through; }
.fil-actions { list-style: none; margin: 0.65rem 0 0; padding: 0; font-size: 0.92rem; color: var(--texte-2); }
.fil-actions li { padding: 0.1rem 0; }
.fil-actions li::first-letter { text-transform: uppercase; }

/* Mosaique : une grande photo, puis jusqu'a trois vignettes. */
.fil-mosaique {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px;
    margin-top: 0.8rem; border-radius: 14px; overflow: hidden;
}
.fil-photo { position: relative; display: block; aspect-ratio: 1 / 1; background: var(--fond); overflow: hidden; }
.fil-photo img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.25s ease; }
.fil-photo:hover img { transform: scale(1.03); }
.fil-photo-grande { grid-column: 1 / -1; aspect-ratio: 4 / 3; }
.fil-mosaique.n1 .fil-photo-grande { aspect-ratio: 4 / 3; }
.fil-mosaique.n2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.fil-mosaique.n3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.fil-photo-plus {
    position: absolute; inset: 0; display: grid; place-items: center;
    background: rgba(10, 19, 48, 0.45); color: #fff; font-size: 1.9rem; font-weight: 700;
}
.fil-suite { text-align: center; margin: 1.2rem 0 0; }

/* Fil d'une fiche : plus serre, sans ombre (il est deja dans une tuile). */
.fil-fiche { gap: 0; }
.fil-fiche .fil-carte { border: 0; border-top: 1px solid var(--bordure); border-radius: 0; box-shadow: none; padding: 0.9rem 0; }
.fil-fiche .fil-carte:first-child { border-top: 0; padding-top: 0.2rem; }
.fil-fiche .fil-mosaique { display: flex; flex-wrap: wrap; gap: 6px; border-radius: 0; overflow: visible; }
.fil-fiche .fil-photo { width: 6.5rem; border-radius: 10px; }
.fil-fiche .fil-photo-plus { font-size: 1.3rem; }
.fil-fiche .fil-actions { margin-top: 0.4rem; }

/* Carte : barre a deux cotes, et mode "Agrandir" (taille de la fenetre). */
.carte-barre { justify-content: space-between; align-items: center; flex-wrap: wrap; }
.carte-barre-gauche { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; min-width: 0; }
.carte-barre-droite { display: flex; gap: 0.5rem; align-items: center; margin-left: auto; }
.carte-astuce { font-size: 0.75rem; white-space: nowrap; }
.btn-agrandir { display: inline-flex; align-items: center; gap: 0.35rem; }
.carte-filtres select { font-size: 0.82rem; padding-top: 0.3rem; padding-bottom: 0.3rem; max-width: 15rem; }

html.carte-agrandie-ouverte, html.carte-agrandie-ouverte body { overflow: hidden; }
@media (hover: none) { .carte-astuce { display: none; } }
@media (max-width: 600px) { .carte-astuce { display: none; } }

/* Menu : compteurs neutres (chantiers en preparation) et ambres (remblais). */
.compteur-nav.compteur-neutre { background: #e3e8f5; color: var(--texte-2); }
.compteur-nav.compteur-ambre { background: var(--orange); }
.mainnav a.actif .compteur-nav.compteur-neutre { background: #fff; color: var(--accent-fonce); }

/* Onglet Chantiers : la repartition du tableau de bord, en une ligne. */
.repartition-chantiers { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.35rem 0 0; padding: 0; list-style: none; }
.repartition-chantiers a {
    display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.22rem 0.65rem;
    border-radius: 999px; background: #fff; border: 1px solid var(--bordure);
    font-size: 0.82rem; color: var(--texte-2); white-space: nowrap;
}
.repartition-chantiers a:hover { border-color: var(--accent); color: var(--accent-fonce); }
.repartition-chantiers strong { font-weight: 700; color: var(--texte); font-variant-numeric: tabular-nums; }
.repartition-chantiers .pastille { width: 8px; height: 8px; }
.fil-page { max-width: 42rem; margin: 1rem auto 0; }
/* Icones seules (moins de 1060 px) : les compteurs deviennent de petites
   pastilles posees sur l'icone, pour que le menu tienne sur une ligne. */
@media (max-width: 1060px) {
    .mainnav a { position: relative; }
    .mainnav a .compteur-nav {
        position: absolute; top: 0; right: -0.1rem; margin: 0;
        min-width: 1rem; height: 1rem; padding: 0 0.22rem; font-size: 0.6rem;
        box-shadow: 0 0 0 2px #fff;
    }
}

/* ===================== V2.1.1 : fiche chantier en onglets =====================
   Onglets souligne (facon maquette) sous l'en-tete ; ils restent visibles en
   haut de l'ecran quand on fait defiler un long onglet. */
.onglets-fiche {
    position: sticky; top: 3.9rem; z-index: 20;
    display: flex; gap: 0.3rem; overflow-x: auto; scrollbar-width: none;
    margin: 0.4rem 0 1.2rem; padding: 0.35rem;
    background: rgba(245, 247, 252, 0.9);
    -webkit-backdrop-filter: saturate(180%) blur(16px); backdrop-filter: saturate(180%) blur(16px);
    border: 1px solid var(--bordure); border-radius: 14px;
}
.onglets-fiche::-webkit-scrollbar { display: none; }
.onglet-fiche {
    display: inline-flex; align-items: center; gap: 0.45rem; white-space: nowrap;
    padding: 0.5rem 1rem; border-radius: 10px;
    font-weight: 600; font-size: 0.92rem; color: var(--texte-2);
}
.onglet-fiche:hover { color: var(--texte); background: rgba(255, 255, 255, 0.7); }
.onglet-fiche[aria-selected="true"] { background: #fff; color: var(--accent-fonce); box-shadow: 0 1px 2px rgba(10, 19, 48, 0.08), 0 0 0 1px var(--bordure); }
.onglet-compteur {
    display: inline-grid; place-items: center; min-width: 1.3rem; height: 1.3rem; padding: 0 0.35rem;
    border-radius: 999px; background: #e3e8f5; color: var(--texte-2); font-size: 0.72rem; font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.onglet-fiche[aria-selected="true"] .onglet-compteur { background: var(--accent-lavis); color: var(--accent-fonce); }
.onglet-coche { color: var(--vert); font-weight: 800; }
/* Sans JavaScript, les panneaux s'enchainent : un filet les separe. */
.onglets-fiche:not(.onglets-actifs) ~ .onglet-panneau + .onglet-panneau { border-top: 1px dashed var(--bordure); padding-top: 1.2rem; }

/* Photos : grille plus genereuse maintenant qu'elle a son onglet. */
#photos .photos-grille { grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); }

/* Decharges et carte cote a cote a partir de 1320 px ; la carte reste en vue. */
@media (min-width: 1320px) {
    .decharges-et-carte { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 1.2rem; align-items: start; }
    .decharges-et-carte .fiche-bloc { margin-bottom: 0; }
    .bloc-carte-fiche { position: sticky; top: 8.2rem; }
    .bloc-carte-fiche .carte-toile { height: min(34rem, calc(100vh - 17rem)); }
}
@media (max-width: 800px) {
    .onglets-fiche { top: 0; margin-left: -0.2rem; margin-right: -0.2rem; }
    .onglet-fiche { padding: 0.45rem 0.7rem; font-size: 0.86rem; }
}
/* V2.3 (K4) : au telephone, les quatre onglets en deux lignes, tous visibles
   (une barre qui defile cachait "Decharges et carte"). */
@media (max-width: 560px) {
    .onglets-fiche { display: grid; grid-template-columns: 1fr 1fr; overflow: visible; }
    .onglet-fiche { justify-content: center; }
}
/* Une ancre interieure (#taches-prepa, #carte) ne doit pas finir sous le menu
   et la barre d'onglets, tous deux collants. */
.onglet-panneau [id] { scroll-margin-top: 8.5rem; }
.carte-barre .segments { font-size: 0.82rem; }

/* ===================== V2.1.2 : remblais dans le planning ===================== */
.puce-remblai { background: #f6efe6; border-left-color: #8a6a3f; }
.vue-mois .puce-remblai { background: #f6efe6; }
@media (max-width: 800px) { .vue-mois .puce-remblai { background: #8a6a3f; } }
.planning-remblais-a-faire.survol-depot { border-color: var(--accent); box-shadow: var(--focus); }
.puce-remblai .jours-orange { color: #b25e00; }
.puce-remblai .jours-rouge { color: var(--rouge); }

/* ===================== V2.1.2 : recherche rapide du tableau de bord ===================== */
.recherche-rapide { position: relative; margin: 0 0 1.4rem; z-index: 30; }
.recherche-rapide input[type=search] {
    width: 100%; padding: 0.9rem 3rem 0.9rem 3rem; font: inherit; font-size: 1.02rem;
    border: 1px solid var(--bordure); border-radius: 16px; background: #fff;
    box-shadow: var(--ombre); outline: none; transition: box-shadow 0.15s ease, border-color 0.15s ease;
}
.recherche-rapide input[type=search]:focus { border-color: var(--accent); box-shadow: var(--focus), var(--ombre); }
.recherche-loupe { position: absolute; left: 1.05rem; top: 50%; transform: translateY(-50%); color: var(--gris); pointer-events: none; }
.recherche-raccourci {
    position: absolute; right: 1rem; top: 50%; transform: translateY(-50%);
    font: 600 0.75rem/1 inherit; color: var(--gris); padding: 0.25rem 0.45rem;
    border: 1px solid var(--bordure); border-radius: 6px; background: var(--fond);
}
.recherche-rapide input:focus ~ .recherche-raccourci { display: none; }
.recherche-suggestions {
    position: absolute; left: 0; right: 0; top: calc(100% + 0.4rem); margin: 0; padding: 0.35rem;
    list-style: none; background: #fff; border: 1px solid var(--bordure); border-radius: 16px;
    box-shadow: var(--ombre-survol); max-height: 70vh; overflow-y: auto;
}
.recherche-suggestions a {
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto; column-gap: 0.7rem; row-gap: 0.05rem;
    align-items: center; padding: 0.55rem 0.75rem; border-radius: 10px; color: var(--texte);
}
.recherche-suggestions [aria-selected="true"] a, .recherche-suggestions a:hover { background: var(--accent-lavis); }
.recherche-nom { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.recherche-etat { font-size: 0.78rem; color: var(--gris); white-space: nowrap; }
.recherche-detail { grid-column: 2 / -1; font-size: 0.8rem; color: var(--gris); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.recherche-detail:empty { display: none; }
.recherche-vide { padding: 0.7rem 0.75rem; color: var(--gris); font-size: 0.9rem; }
.recherche-tout { border-top: 1px solid var(--bordure); margin-top: 0.3rem; padding-top: 0.3rem; }
.recherche-tout a { display: block; font-size: 0.85rem; font-weight: 600; color: var(--accent); }
@media (hover: none) { .recherche-raccourci { display: none; } }

/* ===================== V2.1.2 : la carte est sa propre tuile =====================
   Plus de "tuile dans la tuile" : le cadre porte l'habillage de carte, un
   en-tete compact, puis la carte bord a bord avec sa legende posee dessus. */
.carte-cadre {
    background: #fff; border: 1px solid var(--bordure); border-radius: var(--rayon-carte);
    box-shadow: var(--ombre); overflow: hidden; margin-bottom: 1.2rem;
}
.carte-tete {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.8rem;
    padding: 0.65rem 0.8rem 0.65rem 1.1rem; border-bottom: 1px solid var(--bordure);
}
.carte-titre { margin: 0; font-size: 1.02rem; white-space: nowrap; }
.carte-outils { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; min-width: 0; }
.carte-tete-droite { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin-left: auto; }
.carte-cadre .carte-bloc { position: relative; border: 0; border-radius: 0; box-shadow: none; }
.carte-cadre .carte-encart { margin: 0.9rem; }
.carte-cadre:has(.carte-bloc[hidden]) .carte-tete { border-bottom: 0; }
.carte-cadre:has(.carte-bloc[hidden]) [data-carte-agrandir],
.carte-cadre:has(.carte-bloc[hidden]) .carte-astuce { display: none; }
.btn-discret { background: transparent; border-color: transparent; color: var(--gris); }
.btn-discret:hover { color: var(--texte); background: var(--fond); }
.carte-commandes .segment { padding-left: 0.7rem; padding-right: 0.7rem; }
.carte-legende-flottante {
    position: absolute; left: 0.6rem; top: 0.6rem; margin: 0; z-index: 2;
    display: flex; flex-wrap: wrap; gap: 0.2rem 0.7rem; padding: 0.3rem 0.65rem;
    font-size: 0.75rem; font-weight: 600; color: var(--texte-2);
    background: rgba(255, 255, 255, 0.92); border-radius: 999px; box-shadow: 0 1px 4px rgba(10, 19, 48, 0.18);
    pointer-events: none;
}
.carte-legende-flottante > span { display: inline-flex; align-items: center; gap: 0.3rem; white-space: nowrap; }
.carte-legende-flottante .point-legende { margin: 0; }
.carte-bloc[hidden] ~ .carte-legende-flottante { display: none; }
/* Agrandie : le cadre entier (en-tete compris) occupe la fenetre. */
.carte-cadre.carte-agrandie {
    position: fixed; inset: 0; z-index: 1000; margin: 0; border: 0; border-radius: 0;
    display: flex; flex-direction: column;
}
.carte-cadre.carte-agrandie .carte-bloc { flex: 1; display: flex; flex-direction: column; }
.carte-cadre.carte-agrandie .carte-toile { flex: 1; height: auto; }
.tdb-carte .carte-toile { height: min(var(--hauteur-carte-tdb), calc(100vh - 11rem)); }
@media (max-width: 1180px) { .tdb-carte .carte-toile { height: var(--hauteur-carte-tdb); } }

/* ===================== V2.1.2 : tuile "Decharges a proximite" ===================== */
.bloc-decharges { padding: 1.1rem 1.2rem 0.9rem; }
.decharges-tete { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 0.6rem 1rem; margin-bottom: 0.6rem; }
.decharges-titre h2 { margin: 0; }
.decharges-titre p { margin: 0.15rem 0 0; font-size: 0.82rem; }
.decharges-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.decharges-tri { display: inline-flex; align-items: center; gap: 0.4rem; margin: 0; font-size: 0.82rem; }
.decharges-tri select { font-size: 0.82rem; padding-top: 0.3rem; padding-bottom: 0.3rem; }
.decharges-liste { list-style: none; margin: 0 -0.5rem; padding: 0; }
.decharge-ligne {
    display: grid; grid-template-columns: 1.6rem minmax(0, 1fr) 5.2rem 6.4rem auto;
    align-items: center; gap: 0.2rem 0.8rem; padding: 0.6rem 0.5rem;
    border-top: 1px solid var(--bordure); border-radius: 10px; transition: background 0.12s ease;
}
.decharge-ligne:first-child { border-top-color: transparent; }
.decharge-ligne:hover, .decharge-ligne.ligne-active { background: var(--fond); }
.decharge-ligne.decharge-retenue { background: var(--vert-lavis); border-top-color: transparent; }
.decharge-ligne.decharge-retenue + .decharge-ligne { border-top-color: transparent; }
.decharge-rang {
    display: grid; place-items: center; width: 1.6rem; height: 1.6rem; border-radius: 50%;
    background: #fdebd9; color: #b25400; font-size: 0.78rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.decharge-retenue .decharge-rang { background: var(--vert); color: #fff; }
.decharge-ident { min-width: 0; display: flex; flex-direction: column; gap: 0.05rem; }
.decharge-nom { font-weight: 700; color: var(--texte); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.decharge-nom:hover { color: var(--accent); }
.decharge-adresse { font-size: 0.8rem; color: var(--gris); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.decharge-chiffres { display: flex; flex-direction: column; align-items: flex-end; gap: 0.05rem; font-variant-numeric: tabular-nums; }
.decharge-chiffres strong { font-weight: 700; font-size: 0.92rem; white-space: nowrap; }
.decharge-chiffres span { font-size: 0.78rem; color: var(--gris); white-space: nowrap; }
.decharge-actions { display: flex; align-items: center; justify-content: flex-end; gap: 0.35rem; min-width: 7.2rem; }
.decharge-actions form { margin: 0; }
.btn-icone-seule { display: inline-grid; place-items: center; padding: 0.3rem 0.45rem; }
.badge-retenue { font-size: 0.78rem; font-weight: 700; color: var(--vert); white-space: nowrap; padding: 0 0.3rem; }
.decharges-note { margin: 0.5rem 0 0; font-size: 0.76rem; }
@media (max-width: 600px) {
    .decharge-ligne { grid-template-columns: 1.6rem minmax(0, 1fr) auto; }
    .decharge-ident { grid-column: 2 / -1; }
    .decharge-chiffres { grid-column: 2; flex-direction: row; justify-content: flex-start; gap: 0.5rem; align-items: baseline; }
    .decharge-chiffres + .decharge-chiffres { grid-column: 2; }
    .decharge-actions { grid-column: 3; grid-row: 2 / span 2; }
}

/* ===================== V2.1.2 : onglet Documents ===================== */
.depot-documents { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0.6rem 1rem; align-items: end; margin-bottom: 1.1rem; }
.depot-zone {
    grid-column: 1 / -1; display: flex; flex-direction: column; align-items: center; gap: 0.3rem;
    padding: 1.4rem 1rem; border: 2px dashed var(--bordure); border-radius: var(--rayon);
    background: var(--fond); color: var(--gris); text-align: center; cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
}
.depot-zone:hover, .depot-zone:focus-within { border-color: var(--pervenche); }
.depot-zone.depot-survol { border-color: var(--accent); background: var(--accent-lavis); color: var(--accent-fonce); }
.depot-zone.depot-en-cours { opacity: 0.6; pointer-events: none; }
.depot-texte { color: var(--texte-2); }
.depot-texte strong { color: var(--texte); }
.depot-lien { color: var(--accent); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
.depot-aide { font-size: 0.78rem; }
.depot-type { display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; font-weight: 600; color: var(--texte-2); }
.depot-etat { grid-column: 1 / -1; margin: 0; font-weight: 600; color: var(--accent); }
.depot-etat.depot-etat-erreur { color: var(--rouge); }

.documents-grille { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: 0.9rem; }
.document-carte {
    display: flex; flex-direction: column; border: 1px solid var(--bordure); border-radius: var(--rayon);
    background: #fff; overflow: hidden; transition: box-shadow 0.15s ease;
}
.document-carte:hover { box-shadow: var(--ombre-survol); }
.document-apercu {
    position: relative; display: block; aspect-ratio: 4 / 3; background: var(--fond);
    border-bottom: 1px solid var(--bordure); overflow: hidden;
}
.document-apercu img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top center; background: #fff; }
.document-icone {
    position: absolute; inset: 0; display: grid; place-items: center;
    font-size: 1.1rem; font-weight: 800; letter-spacing: 0.06em; color: var(--gris);
}
.document-infos { display: flex; flex-direction: column; gap: 0.35rem; padding: 0.7rem 0.75rem 0.3rem; min-width: 0; }
.document-infos select, .document-infos input { width: 100%; font-size: 0.85rem; }
.document-infos .champ-renommer { font-weight: 600; }
.document-nom { font-weight: 600; overflow-wrap: anywhere; }
.document-meta { font-size: 0.76rem; color: var(--gris); }
.document-actions { display: flex; flex-wrap: wrap; gap: 0.35rem; padding: 0.4rem 0.75rem 0.75rem; margin-top: auto; }
.document-actions form { margin: 0; }
@media (max-width: 600px) {
    .depot-documents { grid-template-columns: minmax(0, 1fr); }
    .documents-grille { grid-template-columns: minmax(0, 1fr); }
}
.carte-repli:not([hidden]) ~ .carte-legende-flottante { display: none; }
/* En-tete de carte : titre et boutons sur la premiere ligne, filtres ou
   commandes sur la seconde, pleine largeur. */
.carte-tete .carte-outils { order: 3; flex-basis: 100%; }
.carte-tete .carte-tete-droite { order: 2; }

/* ===================== V2.2 : videos ===================== */
.photo-vignette, .fil-photo { position: relative; }
.photo-vignette:not(:has(img)), .fil-photo:not(:has(img)) { background: #1c2438; }
.photo-lecture {
    position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
    display: grid; place-items: center; width: 2.6rem; height: 2.6rem; border-radius: 50%;
    background: rgba(10, 19, 48, 0.55); color: #fff; pointer-events: none;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
}
.photo-lecture svg { margin-left: 3px; }
.fil-photo-grande .photo-lecture { width: 3.6rem; height: 3.6rem; }
.photo-duree {
    position: absolute; right: 0.35rem; bottom: 0.35rem; padding: 0.05rem 0.35rem; border-radius: 5px;
    background: rgba(10, 19, 48, 0.7); color: #fff; font-size: 0.72rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.carrousel-scene video { max-width: 100%; max-height: calc(100vh - 5rem); margin: auto; background: #000; border-radius: 6px; }
.carrousel-scene [hidden] { display: none; }
/* V2.2 : historique complet d'un chantier, dans une tuile comme sur la fiche. */
.fil-page .fil-fiche { background: #fff; border: 1px solid var(--bordure); border-radius: var(--rayon-carte); box-shadow: var(--ombre); padding: 0.6rem 1.2rem; }

/* V2.2 : note libre dans l'activite d'une fiche. */
.message-activite { display: flex; gap: 0.6rem; align-items: flex-end; margin: 0 0 1rem; }
.message-activite textarea {
    flex: 1; min-width: 0; resize: vertical; min-height: 2.9rem; padding: 0.65rem 0.8rem;
    font: inherit; font-size: 0.92rem; border: 1px solid var(--bordure); border-radius: 12px; background: var(--fond);
}
.message-activite textarea:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus); background: #fff; }
/* Un message sur plusieurs lignes garde ses retours a la ligne. */
.fil-actions li { white-space: pre-line; }
@media (max-width: 600px) { .message-activite { flex-direction: column; align-items: stretch; } }

/* ===================== V2.3 (K4) : telephones =====================
   Safari (iPhone) zoome toute la page quand on touche un champ ecrit en
   moins de 16 px, et ne dezoome pas seul. Sur ecran tactile, tous les
   champs passent a 16 px (!important : des regles plus precises les
   reduisent, comme la note de l'activite).  */
@media (pointer: coarse) {
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), textarea, select { font-size: 16px !important; }
}
