/*
 * ARRIVE-FLOW — feuille de style principale.
 * CSS maison (aucun framework, aucune ressource distante : AssetMapper + CSP 'self').
 * Palette sobre BTP : ardoise, orange chantier, fonds clairs.
 */

/* ---------------------------------------------------------------- Variables */
:root {
    --ardoise: #1f2933;
    --ardoise-2: #2b3844;
    --ardoise-3: #3e4c59;
    --orange: #e2711d;
    /* Orange décoratif : bordures, filet des vignettes, anneau de focus, case
       à cocher. Jamais de texte posé dessus (blanc sur #e2711d ne donne que
       3,18:1, sous le minimum AA de 4,5:1). */
    /* #ad5210 : 5,26:1 sur blanc, 5,08:1 sur --surface-2, 4,86:1 sur --fond et
       4,56:1 sur --gris-pale. C'est la couleur des liens ET du fond du bouton
       d'action principal, sur lequel le texte blanc atteint 5,26:1. L'ancienne
       valeur (#c25d12) plafonnait à 4,31:1, sous le seuil AA. */
    --orange-fonce: #ad5210;
    /* Survol du bouton d'action principal : blanc à 7,06:1. */
    --orange-survol: #8f430c;
    --orange-pale: #fdf0e4;

    --fond: #f5f6f7;
    --surface: #ffffff;
    --surface-2: #fafbfc;
    --bordure: #e1e5ea;
    --bordure-forte: #cbd2d9;

    --texte: #1f2933;
    --texte-doux: #616e7c;
    /* #68727f : 4,88:1 sur blanc et 4,71:1 sur --surface-2, soit au-delà du
       minimum de 4,5:1 exigé pour du texte courant. L'ancienne valeur
       (#9aa5b1) ne donnait que 2,5:1 et rendait les références de chantier
       illisibles sur le tableau de bord. */
    --texte-faible: #68727f;
    /* Gris clair réservé aux fonds sombres de la navigation (5,9:1 sur
       --ardoise), où un gris foncé serait au contraire illisible. */
    --texte-sur-sombre: #9aa5b1;

    --vert: #1f7a4d;
    --vert-pale: #e6f4ec;
    --rouge: #b42318;
    --rouge-pale: #fdeceb;
    --bleu: #1d4ed8;
    --bleu-pale: #e8eefc;
    --violet: #6b3fa0;
    --violet-pale: #f0eaf9;
    --gris: #52606d;
    --gris-pale: #eceff2;
    --orange-badge: #9c5406;

    --rayon: 8px;
    --rayon-petit: 5px;
    --ombre: 0 1px 2px rgba(31, 41, 51, .06), 0 1px 3px rgba(31, 41, 51, .08);
    --ombre-forte: 0 8px 24px rgba(31, 41, 51, .12);
    --largeur-nav: 244px;
    --police: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --police-mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
}

/* -------------------------------------------------------------------- Socle */
*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    font-family: var(--police);
    font-size: 14px;
    line-height: 1.5;
    color: var(--texte);
    background: var(--fond);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { margin: 0 0 .4rem; font-weight: 650; line-height: 1.25; }
h1 { font-size: 1.4rem; }
h2 { font-size: 1.1rem; }
h3 { font-size: .98rem; }
p { margin: 0 0 .75rem; }
p:last-child { margin-bottom: 0; }

a { color: var(--orange-fonce); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible {
    outline: 2px solid var(--orange);
    outline-offset: 2px;
    border-radius: 3px;
}

/* ------------------------------------------------------------ Mise en page */
.application {
    display: flex;
    min-height: 100vh;
    align-items: stretch;
}

.zone-principale {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.contenu {
    flex: 1 1 auto;
    padding: 1.5rem 1.75rem 3rem;
    max-width: 1560px;
    width: 100%;
}

body.sans-navigation .contenu {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 2rem 1rem;
}

/* ------------------------------------------------------ Barre de navigation */
.nav-laterale {
    flex: 0 0 var(--largeur-nav);
    width: var(--largeur-nav);
    background: var(--ardoise);
    color: #cbd2d9;
    display: flex;
    flex-direction: column;
    padding: 1.1rem .75rem 1rem;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
}

.marque {
    display: block;
    padding: .1rem .5rem 1.2rem;
    font-size: 1.25rem;
    font-weight: 800;
    letter-spacing: .06em;
    color: #fff;
    text-decoration: none;
}
.marque:hover { text-decoration: none; }
.marque__nom { color: #fff; }
.marque__suffixe { color: var(--orange); margin-left: .28rem; }

.nav-liste {
    list-style: none;
    margin: 0 0 .5rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.nav-lien {
    display: flex;
    align-items: center;
    gap: .65rem;
    padding: .5rem .6rem;
    border-radius: var(--rayon-petit);
    color: #cbd2d9;
    font-size: .875rem;
    font-weight: 500;
    text-decoration: none;
    border-left: 3px solid transparent;
    transition: background-color .12s ease, color .12s ease;
}
.nav-lien:hover {
    background: var(--ardoise-2);
    color: #fff;
    text-decoration: none;
}
.nav-lien.est-actif {
    background: var(--ardoise-2);
    color: #fff;
    border-left-color: var(--orange);
}
.nav-lien.est-actif .nav-icone { color: var(--orange); }

.nav-icone {
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    color: var(--texte-sur-sombre);
}

.nav-section {
    margin: 1rem .6rem .4rem;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--texte-sur-sombre);
}

.nav-pied {
    margin-top: auto;
    padding: .9rem .6rem 0;
    font-size: .72rem;
    /* #7b8794 ne donnait que 4,03:1 sur l'ardoise de la navigation ; le gris
       déjà retenu pour les fonds sombres monte à 5,90:1. */
    color: var(--texte-sur-sombre);
    border-top: 1px solid var(--ardoise-3);
}

/* -------------------------------------------------- Navigation sur téléphone */
/*
 * Sous 901 px, la barre latérale est remplacée par un bandeau fixe portant la
 * marque et un bouton « Menu » : il déplie la liste complète des entrées. Le
 * mécanisme est celui de <details>/<summary>, donc utilisable sans JavaScript.
 */
.barre-mobile {
    display: none;
    position: sticky;
    top: 0;
    z-index: 30;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: .5rem .75rem;
    background: var(--ardoise);
    color: #cbd2d9;
}
.marque--compacte { padding: 0; font-size: 1.05rem; white-space: nowrap; }

.menu-mobile { position: static; }
.menu-mobile__declencheur {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    min-height: 44px;
    min-width: 44px;
    padding: .5rem .9rem;
    border: 1px solid var(--ardoise-3);
    border-radius: var(--rayon-petit);
    background: var(--ardoise-2);
    color: #fff;
    font-size: .88rem;
    font-weight: 650;
    cursor: pointer;
    list-style: none;
}
.menu-mobile__declencheur::-webkit-details-marker { display: none; }
.menu-mobile__declencheur::marker { content: ""; }
.menu-mobile__declencheur:hover { background: var(--ardoise-3); }
.menu-mobile[open] .menu-mobile__declencheur { background: var(--orange-fonce); border-color: var(--orange-fonce); }
.menu-mobile__icone { flex: 0 0 20px; width: 20px; height: 20px; }

.menu-mobile__panneau {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 30;
    max-height: calc(100vh - 64px);
    overflow-y: auto;
    padding: .6rem .75rem .9rem;
    background: var(--ardoise);
    border-top: 1px solid var(--ardoise-3);
    box-shadow: var(--ombre-forte);
}
.menu-mobile__panneau .nav-liste { margin-bottom: 0; }
.menu-mobile__panneau .nav-lien {
    min-height: 44px;
    padding: .55rem .7rem;
    font-size: .95rem;
}

/* ------------------------------------------------------------------ En-tête */
.entete {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    align-items: center;
    justify-content: space-between;
    padding: .9rem 1.75rem;
    background: var(--surface);
    border-bottom: 1px solid var(--bordure);
    position: sticky;
    top: 0;
    z-index: 20;
}

.entete__titres { min-width: 0; }
.entete__titre { margin: 0; font-size: 1.28rem; }
.entete__sous-titre { margin: .15rem 0 0; color: var(--texte-doux); font-size: .85rem; }

.entete__droite {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    flex-wrap: wrap;
}
.entete__actions { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }

.utilisateur {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding-left: 1.25rem;
    border-left: 1px solid var(--bordure);
}
.utilisateur__avatar {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--ardoise);
    color: #fff;
    font-weight: 700;
    font-size: .9rem;
}
.utilisateur__identite { display: flex; flex-direction: column; line-height: 1.2; }
.utilisateur__nom { font-weight: 600; font-size: .85rem; }
.utilisateur__metier { font-size: .72rem; color: var(--texte-doux); }

/* ------------------------------------------------------------------- Cartes */
.carte {
    background: var(--surface);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    box-shadow: var(--ombre);
    margin-bottom: 1.25rem;
    overflow: hidden;
}
.carte__entete {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    align-items: center;
    justify-content: space-between;
    padding: .85rem 1.1rem;
    border-bottom: 1px solid var(--bordure);
    background: var(--surface-2);
}
.carte__titre { margin: 0; font-size: .98rem; font-weight: 650; }
.carte__corps { padding: 1.1rem; }
.carte__corps--serre { padding: 0; }
.carte__pied {
    padding: .75rem 1.1rem;
    border-top: 1px solid var(--bordure);
    background: var(--surface-2);
}

/* ----------------------------------------------------------------- Tableaux */
/*
 * Un tableau de chantier est presque toujours plus large que sa carte : il
 * défile donc horizontalement dans « .tableau-scroll ». Trois dispositifs
 * rendent ce défilement perceptible et supportable :
 *   — un ascenseur horizontal toujours visible (les ascenseurs superposés des
 *     systèmes récents n'apparaissent qu'au survol, donc jamais au doigt) ;
 *   — une ombre portée révélée sur le bord vers lequel il reste du contenu
 *     (astuce des dégradés « background-attachment: local, scroll ») ;
 *   — les colonnes de repère figées : les actions à droite, la colonne des
 *     rubriques à gauche pour les tableaux en lignes (relevé camions).
 */
.tableau-scroll {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    background:
        linear-gradient(to right, var(--surface), rgba(255, 255, 255, 0)) 0 0 / 24px 100% no-repeat local,
        linear-gradient(to left, var(--surface), rgba(255, 255, 255, 0)) 100% 0 / 24px 100% no-repeat local,
        linear-gradient(to right, rgba(31, 41, 51, .32), rgba(31, 41, 51, 0)) 0 0 / 16px 100% no-repeat scroll,
        linear-gradient(to left, rgba(31, 41, 51, .32), rgba(31, 41, 51, 0)) 100% 0 / 16px 100% no-repeat scroll;
}
.tableau-scroll::-webkit-scrollbar { height: 10px; }
.tableau-scroll::-webkit-scrollbar-track { background: var(--surface-2); }
.tableau-scroll::-webkit-scrollbar-thumb { background: var(--bordure-forte); border-radius: 999px; }
.tableau-scroll::-webkit-scrollbar-thumb:hover { background: var(--texte-faible); }

.tableau {
    width: 100%;
    border-collapse: collapse;
    font-size: .84rem;
}
.tableau th,
.tableau td {
    padding: .5rem .75rem;
    text-align: left;
    border-bottom: 1px solid var(--bordure);
    vertical-align: middle;
}
/* Le retour à la ligne est la règle : seules les valeurs courtes — chiffres,
   heures, dates, références et boutons — restent insécables, faute de quoi la
   largeur mini du tableau dépasse toujours celle de la carte. */
.tableau tbody .num,
.tableau tfoot .num,
.tableau .mono,
.tableau .nowrap,
.tableau .actions { white-space: nowrap; }
.tableau td.enveloppe,
.tableau th.enveloppe { white-space: normal; min-width: 150px; }
.tableau thead th {
    background: var(--surface-2);
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--texte-doux);
    border-bottom: 1px solid var(--bordure-forte);
    position: sticky;
    top: 0;
    z-index: 1;
}
.tableau tbody tr:hover { background: var(--surface-2); }
.tableau tbody tr:last-child td { border-bottom: none; }
.tableau tfoot td {
    font-weight: 700;
    background: var(--surface-2);
    border-top: 2px solid var(--bordure-forte);
}
.tableau .num,
.tableau .texte-droite { text-align: right; font-variant-numeric: tabular-nums; }
.tableau--zebre tbody tr:nth-child(even) { background: var(--surface-2); }

/* Colonne d'actions : boutons côte à côte et colonne figée au bord droit, pour
   que « Consulter » ou « PDF » restent entiers et atteignables. */
.tableau .actions {
    text-align: right;
    width: 1%;
    position: sticky;
    right: 0;
    z-index: 2;
    background: var(--surface);
    box-shadow: -9px 0 9px -9px rgba(31, 41, 51, .4);
}
.tableau thead th.actions { z-index: 3; background: var(--surface-2); }
.tableau tfoot td.actions { background: var(--surface-2); }
.tableau--zebre tbody tr:nth-child(even) td.actions { background: var(--surface-2); }
.tableau tbody tr:hover td.actions { background: var(--surface-2); }
.tableau .actions .groupe-boutons { flex-wrap: nowrap; justify-content: flex-end; }
.tableau .actions .bouton { white-space: nowrap; }

/* Tableaux « rubriques en lignes » : la colonne de gauche porte le nom de la
   rubrique, elle est figée pour rester lisible pendant le défilement. */
.tableau tbody th[scope="row"],
.tableau:has(tbody th[scope="row"]) thead th:first-child,
.tableau:has(tbody th[scope="row"]) tfoot td:first-child {
    position: sticky;
    left: 0;
    background: var(--surface);
    box-shadow: 9px 0 9px -9px rgba(31, 41, 51, .4);
}
.tableau:has(tbody th[scope="row"]) thead th:first-child { z-index: 3; background: var(--surface-2); }
.tableau:has(tbody th[scope="row"]) tfoot td:first-child { background: var(--surface-2); }
.tableau--zebre tbody tr:nth-child(even) th[scope="row"] { background: var(--surface-2); }
.tableau tbody tr:hover th[scope="row"] { background: var(--surface-2); }

/* ------------------------------------------------------------------- Badges */
.badge {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .13rem .5rem;
    border-radius: 999px;
    font-size: .72rem;
    font-weight: 650;
    line-height: 1.5;
    white-space: nowrap;
    background: var(--gris-pale);
    color: var(--gris);
    border: 1px solid transparent;
}
.badge--gris   { background: var(--gris-pale);   color: var(--gris); }
.badge--vert   { background: var(--vert-pale);   color: var(--vert); }
.badge--orange { background: var(--orange-pale); color: var(--orange-badge); }
.badge--rouge  { background: var(--rouge-pale);  color: var(--rouge); }
.badge--bleu   { background: var(--bleu-pale);   color: var(--bleu); }
.badge--violet { background: var(--violet-pale); color: var(--violet); }

/* ------------------------------------------------------------------ Boutons */
.bouton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    padding: .45rem .85rem;
    border: 1px solid var(--bordure-forte);
    border-radius: var(--rayon-petit);
    background: var(--surface);
    color: var(--texte);
    font-family: inherit;
    font-size: .84rem;
    font-weight: 600;
    line-height: 1.4;
    text-decoration: none;
    cursor: pointer;
    transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
.bouton:hover { background: var(--surface-2); border-color: var(--texte-faible); text-decoration: none; }
.bouton:disabled,
.bouton.est-desactive {
    background: var(--gris-pale);
    border-color: var(--bordure-forte);
    color: var(--texte-doux);
    cursor: not-allowed;
}

.bouton--primaire {
    background: var(--orange-fonce);
    border-color: var(--orange-fonce);
    color: #fff;
}
.bouton--primaire:hover { background: var(--orange-survol); border-color: var(--orange-survol); }

.bouton--sombre {
    background: var(--ardoise);
    border-color: var(--ardoise);
    color: #fff;
}
.bouton--sombre:hover { background: var(--ardoise-2); border-color: var(--ardoise-2); }

.bouton--danger {
    background: var(--rouge);
    border-color: var(--rouge);
    color: #fff;
}
.bouton--danger:hover { background: #8f1c14; border-color: #8f1c14; }

.bouton--fantome {
    background: transparent;
    border-color: transparent;
    color: var(--texte-doux);
}
.bouton--fantome:hover { background: var(--gris-pale); border-color: transparent; color: var(--texte); }

.bouton--petit { padding: .28rem .6rem; font-size: .78rem; }
.bouton--bloc { width: 100%; }

.groupe-boutons { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.groupe-boutons--fin { justify-content: flex-end; }

/* ---------------------------------------------------------------------- KPI */
.grille-kpi {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.kpi {
    background: var(--surface);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    box-shadow: var(--ombre);
    padding: .95rem 1.05rem;
    border-top: 3px solid var(--orange);
}
.kpi__libelle {
    margin: 0;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--texte-doux);
}
.kpi__valeur {
    margin: .3rem 0 0;
    font-size: 1.7rem;
    font-weight: 700;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}
.kpi__detail { margin: .2rem 0 0; font-size: .78rem; color: var(--texte-doux); }
.kpi--vert  { border-top-color: var(--vert); }
.kpi--rouge { border-top-color: var(--rouge); }
.kpi--bleu  { border-top-color: var(--bleu); }
.kpi--gris  { border-top-color: var(--bordure-forte); }

/* --------------------------------------------------------------- Grilles */
.grille { display: grid; gap: 1.25rem; }
.grille--2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.grille--3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.grille--formulaire { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 0 1rem; }

/* ------------------------------------------------------------ Formulaires */
form { margin: 0; }

.champ { margin-bottom: 1rem; }
.champ > label {
    display: block;
    margin-bottom: .28rem;
    font-size: .78rem;
    font-weight: 650;
    color: var(--texte-doux);
}
.champ > label.required::after {
    content: " *";
    color: var(--rouge);
}

input[type="text"],
input[type="search"],
input[type="email"],
input[type="password"],
input[type="number"],
input[type="tel"],
input[type="url"],
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="week"],
input[type="month"],
input[type="file"],
select,
textarea {
    width: 100%;
    padding: .45rem .6rem;
    font-family: inherit;
    font-size: .86rem;
    color: var(--texte);
    background: var(--surface);
    border: 1px solid var(--bordure-forte);
    border-radius: var(--rayon-petit);
    transition: border-color .12s ease, box-shadow .12s ease;
}
textarea { min-height: 84px; resize: vertical; }
select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--texte-doux) 50%), linear-gradient(135deg, var(--texte-doux) 50%, transparent 50%); background-position: calc(100% - 15px) 51%, calc(100% - 10px) 51%; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 1.75rem; }
select[multiple] { background-image: none; padding-right: .6rem; }

input:focus,
select:focus,
textarea:focus {
    outline: none;
    border-color: var(--orange);
    box-shadow: 0 0 0 3px rgba(226, 113, 29, .16);
}
input:disabled,
select:disabled,
textarea:disabled { background: var(--gris-pale); color: var(--texte-doux); cursor: not-allowed; }
input[aria-invalid="true"],
select[aria-invalid="true"],
textarea[aria-invalid="true"] { border-color: var(--rouge); }

input[type="checkbox"],
input[type="radio"] {
    width: 1.15rem;
    height: 1.15rem;
    margin-right: .4rem;
    accent-color: var(--orange);
    vertical-align: middle;
}
/*
 * Le thème de formulaire rend l'étiquette AVANT la case : « Panier repas » se
 * lisait donc comme un champ resté vide. On ramène la case à gauche de son
 * étiquette, sur une seule ligne, avec une cible cliquable confortable.
 */
.champ:has(> input[type="checkbox"]),
.champ:has(> input[type="radio"]) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    min-height: 34px;
}
.champ:has(> input[type="checkbox"]) > input,
.champ:has(> input[type="radio"]) > input { order: 1; margin: 0; }
.champ:has(> input[type="checkbox"]) > label,
.champ:has(> input[type="radio"]) > label {
    order: 2;
    margin-bottom: 0;
    font-size: .86rem;
    color: var(--texte);
    cursor: pointer;
}
.champ:has(> input[type="checkbox"]) > .form-erreur,
.champ:has(> input[type="checkbox"]) > .aide,
.champ:has(> input[type="checkbox"]) > .help-text,
.champ:has(> input[type="radio"]) > .aide,
.champ:has(> input[type="radio"]) > .help-text { order: 3; flex: 1 0 100%; margin-top: 0; }

.form-erreur {
    margin: .3rem 0 0;
    font-size: .78rem;
    font-weight: 600;
    color: var(--rouge);
}

.aide,
.help-text {
    margin: .25rem 0 0;
    font-size: .75rem;
    color: var(--texte-doux);
}

.form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    align-items: center;
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--bordure);
}

.barre-filtres {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: .75rem;
    padding: .9rem 1.1rem;
    background: var(--surface);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    box-shadow: var(--ombre);
    margin-bottom: 1.25rem;
}
.barre-filtres .champ { margin-bottom: 0; min-width: 165px; flex: 1 1 165px; }
.barre-filtres .groupe-boutons { flex: 0 0 auto; }

/* --------------------------------------------------------------- Collections */
.collection { display: flex; flex-direction: column; gap: .75rem; }
.collection-item {
    position: relative;
    padding: .9rem 1rem;
    background: var(--surface-2);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon-petit);
}
.collection-item .champ { margin-bottom: .6rem; }
.collection-item__actions { display: flex; justify-content: flex-end; }

/* ------------------------------------------------------------------ Alertes */
.alerte {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem .6rem;
    align-items: baseline;
    padding: .65rem .9rem;
    margin-bottom: 1rem;
    border: 1px solid;
    border-left-width: 4px;
    border-radius: var(--rayon-petit);
    font-size: .86rem;
}
.alerte__titre { font-weight: 700; }
.alerte--succes        { background: var(--vert-pale);   border-color: var(--vert);   color: #14532d; }
.alerte--avertissement { background: var(--orange-pale); border-color: var(--orange); color: #7c3f05; }
.alerte--danger        { background: var(--rouge-pale);  border-color: var(--rouge);  color: #7f1d1d; }
.alerte--info          { background: var(--bleu-pale);   border-color: var(--bleu);   color: #1e3a8a; }

/* --------------------------------------------------------------- Pagination */
.pagination {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    align-items: center;
    justify-content: space-between;
    margin-top: 1rem;
}
.pagination__resume { margin: 0; font-size: .8rem; color: var(--texte-doux); }
.pagination__liste {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: .25rem;
    margin: 0;
    padding: 0;
}
.pagination__lien {
    display: inline-flex;
    align-items: center;
    padding: .3rem .62rem;
    border: 1px solid var(--bordure-forte);
    border-radius: var(--rayon-petit);
    background: var(--surface);
    color: var(--texte);
    font-size: .8rem;
    font-weight: 600;
    text-decoration: none;
}
.pagination__lien:hover { background: var(--surface-2); text-decoration: none; }
.pagination__lien.est-actif {
    background: var(--ardoise);
    border-color: var(--ardoise);
    color: #fff;
}
.pagination__lien.est-desactive { opacity: .45; pointer-events: none; }
.pagination__ellipse { display: inline-flex; padding: .3rem .35rem; color: var(--texte-faible); }

/* ---------------------------------------------------------------- État vide */
.vide {
    padding: 2.25rem 1.25rem;
    text-align: center;
    color: var(--texte-doux);
}
.vide__titre { margin: 0 0 .35rem; font-size: .95rem; font-weight: 650; color: var(--texte); }
.vide__texte { margin: 0 auto .9rem; max-width: 460px; font-size: .85rem; }

/* ----------------------------------------------------------------- Modales */
/*
 * Fenêtres modales natives (<dialog>), déclarées une fois dans
 * _partials/modale.html.twig et pilotées par les contrôleurs Stimulus
 * « modale » et « confirmation ».
 *
 * Le dialogue n'a ni marge intérieure ni bordure : sa boîte se confond avec
 * « .modale__cadre ». Un clic dont la cible est le <dialog> lui-même ne peut
 * donc venir que de l'arrière-plan, ce dont le contrôleur se sert pour fermer.
 *
 * Le cadre est une colonne flexible : en-tête et pied restent visibles, seul
 * « .modale__corps » défile. C'est indispensable ici — le formulaire de fiche
 * de journée approche 1 900 px de haut et celui du relevé camions davantage.
 */
.modale {
    padding: 0;
    border: 0;
    /* La feuille de style du navigateur limite un <dialog> à
       « calc(100% - 6px - 2em) » : sans cette remise à zéro, la largeur
       demandée plus bas ne serait pas tenue sur les écrans étroits. */
    max-width: none;
    max-height: none;
    width: min(1100px, 94vw);
    border-radius: var(--rayon);
    background: var(--surface);
    color: var(--texte);
    box-shadow: var(--ombre-forte);
    overflow: hidden;
}
.modale--etroite { width: min(520px, 94vw); }

.modale::backdrop { background: rgba(31, 41, 51, .58); }

.modale__cadre {
    display: flex;
    flex-direction: column;
    max-height: 90vh;
}

.modale__entete {
    flex: 0 0 auto;
    display: flex;
    gap: .75rem;
    align-items: center;
    justify-content: space-between;
    padding: .85rem 1.1rem;
    border-bottom: 1px solid var(--bordure);
    background: var(--surface-2);
}
.modale__titre { margin: 0; font-size: .98rem; font-weight: 650; }

.modale__fermer {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--rayon-petit);
    background: transparent;
    color: var(--texte-doux);
    cursor: pointer;
}
.modale__fermer:hover { background: var(--gris-pale); color: var(--texte); }
.modale__fermer svg { width: 17px; height: 17px; }

.modale__corps {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 1.1rem;
}

.modale__pied {
    flex: 0 0 auto;
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    justify-content: flex-end;
    padding: .75rem 1.1rem;
    border-top: 1px solid var(--bordure);
    background: var(--surface-2);
}

/* Le formulaire distant arrive avec ses propres cartes : dans le dialogue,
   elles sont déjà posées sur une surface, on retire donc l'ombre portée et on
   supprime la marge de la dernière pour ne pas creuser le bas du cadre. */
.modale__corps .carte { box-shadow: none; }
.modale__corps > form > .carte:last-child,
.modale__corps > form > .form-actions:last-child { margin-bottom: 0; }
.modale__corps .form-actions { margin-bottom: 0; }

.modale__chargement {
    margin: 0;
    padding: 2rem 0;
    text-align: center;
    color: var(--texte-doux);
    font-size: .88rem;
    animation: modale-pulsation 1.4s ease-in-out infinite;
}
@keyframes modale-pulsation {
    0%, 100% { opacity: 1; }
    50%      { opacity: .45; }
}
@media (prefers-reduced-motion: reduce) {
    .modale__chargement { animation: none; }
}

/* Le fond de page ne défile plus derrière une fenêtre ouverte. */
body:has(dialog[open]) { overflow: hidden; }

/* ---------------------------------------------------------------- Connexion */
.carte-connexion {
    width: 100%;
    max-width: 380px;
    background: var(--surface);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    box-shadow: var(--ombre-forte);
    padding: 1.75rem;
}
.carte-connexion .marque {
    padding: 0 0 1.25rem;
    color: var(--ardoise);
    text-align: center;
}
.carte-connexion .marque__nom { color: var(--ardoise); }

/* -------------------------------------------------------------- Utilitaires */
.texte-doux { color: var(--texte-doux); }
.texte-faible { color: var(--texte-faible); }
.texte-droite { text-align: right; }
.texte-centre { text-align: center; }
.texte-petit { font-size: .78rem; }
.mono { font-family: var(--police-mono); font-size: .8rem; }
.num { font-variant-numeric: tabular-nums; }
.nowrap { white-space: nowrap; }
.pile { display: flex; flex-direction: column; gap: .35rem; }
.rangee { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.rangee--espacee { justify-content: space-between; }
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}
.marge-haut { margin-top: 1.25rem; }
.sans-marge { margin: 0; }

.liste-definitions {
    display: grid;
    grid-template-columns: minmax(140px, max-content) 1fr;
    gap: .35rem 1rem;
    margin: 0;
    font-size: .86rem;
}
.liste-definitions dt { color: var(--texte-doux); font-weight: 600; }
.liste-definitions dd { margin: 0; }

/* -------------------------------------------------------------- Responsive */
@media (max-width: 900px) {
    .application { flex-direction: column; }

    /* La barre latérale s'efface au profit du bandeau et de son menu dépliant :
       sur 390 px, une bande d'onglets glissante ne laissait voir que deux
       entrées sur douze, sans rien qui signale les autres. */
    .nav-laterale { display: none; }
    .barre-mobile { display: flex; }

    .entete { position: static; padding: .85rem 1rem; }
    .contenu { padding: 1rem 1rem 2.5rem; }
    .utilisateur { padding-left: 0; border-left: none; }
    .utilisateur__identite { display: none; }
    .grille-kpi { gap: .75rem; }

    /* Cibles tactiles : 44 px au minimum, gants de chantier compris. */
    .bouton { min-height: 44px; padding: .55rem 1rem; }
    .bouton--petit { min-height: 44px; padding: .45rem .8rem; font-size: .8rem; }
    .groupe-boutons { gap: .6rem; }
    /* Les actions opposées (ajouter / retirer) ne doivent plus se toucher. */
    .rangee--espacee { gap: .75rem 1.5rem; }
    .rangee--espacee > .bouton--danger { margin-left: auto; }

    input[type="text"],
    input[type="search"],
    input[type="email"],
    input[type="password"],
    input[type="number"],
    input[type="tel"],
    input[type="url"],
    input[type="date"],
    input[type="time"],
    input[type="datetime-local"],
    input[type="week"],
    input[type="month"],
    input[type="file"],
    select { min-height: 44px; }
    input[type="radio"] { width: 1.35rem; height: 1.35rem; }
    /*
     * Cases à cocher : la case native se limite à sa boîte, qui plafonnait à
     * 22 px de côté — trop peu pour un doigt ganté, et sous les 44 px attendus.
     * On dessine donc la case nous-mêmes : la zone tactile fait 44 × 44 px,
     * la case reste visuellement de la même taille qu'auparavant.
     */
    input[type="checkbox"] {
        appearance: none;
        -webkit-appearance: none;
        width: 44px;
        height: 44px;
        margin: 0;
        padding: 0;
        border: 0;
        background: transparent;
        display: inline-grid;
        place-items: center;
        cursor: pointer;
    }
    input[type="checkbox"]::before {
        grid-area: 1 / 1;
        content: "";
        width: 24px;
        height: 24px;
        border: 2px solid var(--bordure-forte);
        border-radius: var(--rayon-petit);
        background: var(--surface);
    }
    input[type="checkbox"]::after {
        grid-area: 1 / 1;
        content: "";
        width: 6px;
        height: 11px;
        border: solid #fff;
        border-width: 0 2.5px 2.5px 0;
        transform: translateY(-2px) rotate(45deg);
        opacity: 0;
    }
    input[type="checkbox"]:checked::before {
        background: var(--orange-fonce);
        border-color: var(--orange-fonce);
    }
    input[type="checkbox"]:checked::after { opacity: 1; }
    input[type="checkbox"]:disabled { cursor: not-allowed; }
    input[type="checkbox"]:disabled::before {
        background: var(--gris-pale);
        border-color: var(--bordure);
    }
    .champ:has(> input[type="checkbox"]),
    .champ:has(> input[type="radio"]) { min-height: 44px; }
    /* La case dessinée porte déjà ses 44 px : on rattrape la marge visuelle. */
    .champ:has(> input[type="checkbox"]) { gap: .15rem; }

    .tableau td.enveloppe,
    .tableau th.enveloppe { min-width: 130px; }

    /* Sous 900 px, la fenêtre modale occupe tout l'écran : un formulaire de
       fiche de journée n'a rien à gagner à être encadré sur 390 px de large. */
    .modale,
    .modale--etroite {
        width: 100%;
        max-width: 100%;
        height: 100dvh;
        max-height: 100dvh;
        margin: 0;
        border-radius: 0;
    }
    .modale__cadre { height: 100%; max-height: none; }
    .modale__fermer { width: 44px; height: 44px; }
}

@media (max-width: 560px) {
    .entete__droite { width: 100%; justify-content: space-between; }
    .grille--2, .grille--3 { grid-template-columns: 1fr; }
    .liste-definitions { grid-template-columns: 1fr; gap: 0 0; }
    .liste-definitions dd { margin-bottom: .5rem; }

    /* Sept indicateurs pleine largeur remplissaient tout le premier écran du
       tableau de bord : on les resserre à deux par ligne. */
    .grille-kpi { grid-template-columns: repeat(2, 1fr); gap: .6rem; }
    .kpi { padding: .7rem .8rem; }
    .kpi__libelle { font-size: .64rem; letter-spacing: .05em; }
    .kpi__valeur { font-size: 1.35rem; margin-top: .2rem; }
    .kpi__detail { font-size: .72rem; }

    .tableau { font-size: .82rem; }
    .tableau th,
    .tableau td { padding: .45rem .55rem; }
    .tableau td.enveloppe,
    .tableau th.enveloppe { min-width: 115px; }
    /* Figée, la colonne d'actions mangerait la moitié d'un écran de 390 px :
       elle défile donc avec le tableau, la colonne des rubriques restant
       seule ancrée à gauche. « relative » plutôt que « static » : la cellule
       reste le bloc conteneur de son intitulé en « sr-only », qui déborderait
       sinon la page entière. */
    .tableau .actions { position: relative; right: auto; box-shadow: none; }

    /* 38 px de large sur les numéros à un chiffre : il manquait 6 px pour
       atteindre la cible tactile de 44 px. */
    .pagination__lien { min-height: 44px; min-width: 44px; justify-content: center; padding: .5rem .9rem; }
    .pagination__lien.est-desactive {
        opacity: 1;
        background: var(--gris-pale);
        border-color: var(--bordure);
        color: var(--texte-faible);
    }
}

/* ---------------------------------------------------------------- Impression */
@media print {
    :root { --ombre: none; --ombre-forte: none; }

    body { background: #fff; font-size: 11px; }

    .nav-laterale,
    .barre-mobile,
    .entete,
    .pagination,
    .barre-filtres,
    .alerte,
    .bouton,
    .groupe-boutons,
    .form-actions,
    .sf-toolbar,
    .modale,
    .ne-pas-imprimer { display: none !important; }

    .application, .zone-principale { display: block; }
    .contenu { padding: 0; max-width: none; }

    .carte {
        border: 1px solid #999;
        border-radius: 0;
        box-shadow: none;
        break-inside: avoid;
        margin-bottom: .6rem;
    }
    .carte__entete { background: #fff; }

    .tableau { font-size: 10px; }
    .tableau th, .tableau td { border-bottom: 1px solid #bbb; padding: .25rem .35rem; }
    .tableau thead th { background: #eee; color: #000; position: static; }
    .tableau-scroll { overflow: visible; background: none; }
    /* À l'impression, plus rien ne défile : ni colonnes figées ni ombres. */
    .tableau .actions,
    .tableau tbody th[scope="row"],
    .tableau thead th:first-child,
    .tableau tfoot td:first-child { position: static; box-shadow: none; background: transparent; }

    .badge { border: 1px solid #999; background: #fff !important; color: #000 !important; }

    a { color: #000; text-decoration: none; }
}
