/* Charte reprise de l'ancienne application (main.css + sidebar.css + contrats.css historiques) */
:root {
    --chevron-select: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23666' stroke-width='1.5'/%3E%3C/svg%3E");
    --couleur-principale: #5a879c;
    --couleur-cinq: #2e85cb;
    --couleur-texte: #333333;
    --couleur-bordure: #c3c0c0;
    --couleur-survol: #ececec;
    /* Bridge chart CP (cf. cp-bridge.js) : paire divergente + neutre, validées CVD
       (deutéranopie/protanopie) avec scripts/validate_palette.js du skill dataviz —
       ne pas remplacer par des teintes choisies à l'oeil, cette paire précise passe
       le test (vert/rouge n'y arrive qu'en zone WARN 6-8, légal seulement parce que
       le sens de chaque barre est aussi lisible sur son orientation + l'infobulle). */
    --couleur-bridge-hausse: #388e3c;
    --couleur-bridge-baisse: #e34948;
    --couleur-bridge-neutre: #898781;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
    margin: 0;
    font-family: 'Titillium Web', sans-serif;
    background: #fff;
    color: var(--couleur-texte);
}
button, input, select, textarea { font-family: 'Titillium Web', sans-serif; }
a { color: var(--couleur-principale); }

/* Barre supérieure : blanche, 64px, comme la nav historique */
.topbar {
    display: flex; justify-content: space-between; align-items: center;
    background: #fff; color: var(--couleur-texte);
    height: 64px; padding: 0 1rem 0 76px;
    box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.12);
    position: relative; z-index: 10;
}
.topbar .titre-page { font-size: 20px; }
.topbar .user { display: flex; align-items: center; gap: .5rem; font-size: 15px; }
.topbar .date-jour { color: var(--couleur-texte); }
.topbar .logout-form { display: flex; margin-left: .75rem; }
/* Bouton (pas un lien : la déconnexion détruit la session côté serveur, POST + CSRF
   comme toute écriture de l'app) stylé pour rester visuellement discret comme avant. */
.topbar button.logout {
    background: none; border: 0; box-shadow: none; padding: 0; height: auto;
    text-transform: none; letter-spacing: normal;
    color: var(--couleur-texte); display: flex; cursor: pointer;
}
.topbar button.logout:hover { color: var(--couleur-principale); filter: none; }
.avatar { height: 25px; width: 25px; border-radius: 50%; }

/* Burger d'ouverture du menu-tiroir : n'existe visuellement qu'en mobile
   (le rail d'icônes remplit ce rôle sur desktop). Neutralise le style bouton
   global (fond plein, uppercase…) pour rester une simple icône. */
.btn-menu {
    display: none; background: none; border: 0; box-shadow: none;
    padding: .25rem; height: auto; color: var(--couleur-texte); cursor: pointer;
}
/* Libellé de domaine dans le rail : porté par le HTML (cf. Menu::renderDomaine)
   mais réservé au mode tiroir mobile — le rail desktop reste une colonne d'icônes. */
.libelle-domaine { display: none; }

/* Bandeau d'impersonation (admin « vu comme » une autre personne) */
.chip-impersonation {
    display: inline-flex; align-items: center; gap: .35rem;
    background: #fff3e0; color: #b36b00; border: 1px solid #ffb74d;
    border-radius: 14px; padding: .1rem .3rem .1rem .6rem; font-size: 13px; margin-right: .75rem;
}
.chip-impersonation button {
    background: #b36b00; border: 0; border-radius: 50%; width: 22px; height: 22px;
    padding: 0; display: inline-flex; align-items: center; justify-content: center;
    color: #fff; cursor: pointer; box-shadow: none;
}
.chip-impersonation button .material-icons { font-size: 14px; }

/* Menu latéral fixe : 60px, fond couleur principale (sidenav historique) */
ul.sidenav {
    position: fixed; top: 0; left: 0; bottom: 0; width: 60px;
    margin: 0; padding: 0; list-style: none;
    background: var(--couleur-principale);
    /* Colonne flex : .rail-espace (flex:1) pousse les items placés après elle
       (Mon compte, Paramètres…) en bas du rail, cf. `position: 'bas'` de Menu.php */
    display: flex; flex-direction: column;
    /* z-index au-dessus de .select-icones .si-liste (40, position fixed calée en JS,
       cf. select-icones.js:ouvre()) : le rail établit son PROPRE contexte d'empilement
       (position fixed + z-index), donc c'est CE z-index — pas celui, interne, de
       .flyout — qui détermine si le flyout du niveau 1 passe devant ou derrière une
       liste déroulante de la page (ex. sélecteur de bien/année) quand ils se
       superposent à l'écran. */
    box-shadow: 2px 0 4px rgba(0,0,0,.25); z-index: 45;
}
ul.sidenav > li.rail-espace { flex: 1 1 auto; }
/* Combinateurs directs (> li) : ne doivent viser QUE le rail lui-même, jamais les
   <li> imbriqués du flyout (sinon ul.sidenav li — 2 éléments — l'emporte en
   spécificité sur les règles .flyout ci-dessous et écrase leur mise en page,
   ex. text-align:center hérité à tort par les items du panneau) */
ul.sidenav > li { text-align: center; }
ul.sidenav > li > a {
    display: flex; align-items: center; justify-content: center;
    height: 48px; color: #fff; text-decoration: none;
}
ul.sidenav > li:hover > a { background: rgba(255,255,255,.15); }
ul.sidenav > li.actif > a { background: var(--couleur-cinq); }

/* Icône de domaine : cliquable (pointe sur la 1re feuille construite du sous-arbre)
   via un <a> normal — stylée par ul.sidenav > li > a ci-dessus. Grisée seulement si
   rien n'est encore construit dans tout le sous-arbre (aucun <a>, simple pictogramme).
   Dans tous les cas déclenche le flyout au survol (ciblé sur le <li>, peu importe
   ce qu'il contient). */
ul.sidenav li.menu-domaine { position: relative; }
ul.sidenav li.menu-domaine > span.material-icons.desactive {
    display: flex; align-items: center; justify-content: center;
    height: 48px; color: rgba(255,255,255,.4); cursor: default;
}

/* Flyout niveau 2 : un panneau par domaine, ouvert au survol du niveau 1.
   flyout-titre fait exactement 48px (box-sizing:border-box, cf. règle * en tête de
   fichier) pour que sa bordure basse s'aligne avec le bas du bouton survolé/actif
   du rail (lui aussi 48px) — sans quoi le filet gris grisé « flotte » au-dessus. */
ul.sidenav li.menu-domaine .flyout {
    display: none;
    position: absolute; left: 60px; top: 0;
    min-width: 230px; background: #fff; color: var(--couleur-texte);
    box-shadow: 2px 2px 10px rgba(0,0,0,.3); border-radius: 0 4px 4px 0;
    padding: 0 0 .5rem; z-index: 30; text-align: left;
}
/* Domaines repoussés en bas du rail (ex. Mon compte) : icône proche du bas de
   l'écran, le flyout doit donc s'ouvrir vers le haut (ancré sur le bas de
   l'icône) pour ne pas déborder sous la fenêtre. */
ul.sidenav li.menu-domaine.rail-bas .flyout {
    top: auto; bottom: 0; border-radius: 4px 4px 0 0;
}
/* Ouverture au survol/focus : desktop uniquement (min-width = complément exact du
   media mobile 993px en fin de fichier). Sur tactile il n'y a pas de survol, et
   :focus-within rouvrirait le panneau au tap : en mode tiroir, c'est la classe
   .deplie (posée par app.js, accordéon) qui pilote l'affichage. */
@media screen and (min-width: 993.02px) {
    ul.sidenav li.menu-domaine:hover .flyout,
    ul.sidenav li.menu-domaine:focus-within .flyout { display: block; }
}
.flyout .flyout-titre {
    display: flex; align-items: center;
    height: 48px; padding: 0 1rem; margin-bottom: .25rem;
    font-weight: 600; font-size: 13px; text-transform: uppercase;
    color: var(--couleur-principale); border-bottom: 1px solid var(--couleur-bordure);
}
.flyout ul { list-style: none; margin: 0; padding: 0; }
/* flex + gap : aligne l'icône (niveau 2 et 3, facultative) avec le libellé */
.flyout li > a, .flyout li.desactive {
    display: flex; align-items: center; gap: .5rem;
    padding: .4rem 1rem; font-size: 14px; white-space: nowrap;
}
.flyout li > a { color: var(--couleur-texte); text-decoration: none; }
.flyout li > a:hover { background: var(--couleur-survol); color: var(--couleur-principale); }
/* Chemin de l'écran courant : fond bleu plein (comme l'icône de domaine active
   dans le rail), pas juste une couleur de texte, pour que le repère soit visible
   d'un coup d'œil dans le panneau. */
.flyout li.actif > a { background: var(--couleur-cinq); color: #fff; font-weight: 600; }
.flyout li.desactive { color: #bbb; cursor: default; }
.flyout .material-icons.petit { font-size: 16px; }

/* Niveau 3 : sous-panneau imbriqué, masqué par défaut, ouvert au survol/focus du
   groupe niveau 2 (cascade classique, comme le flyout niveau 1 mais à droite du
   groupe plutôt que du rail) */
.flyout li.groupe { position: relative; }
.flyout li.groupe > .groupe-titre {
    display: flex; align-items: center; gap: .5rem;
    /* Même padding vertical que .flyout li > a (.4rem, symétrique) : un padding
       asymétrique décale visuellement l'icône/le texte par rapport au fond de
       survol/sélection (mesuré : 3,2px d'écart), et un padding symétrique mais
       différent (.5rem) rend la ligne plus haute que ses voisines de niveau 2
       (mesuré : 40px contre 33,78px) — .4rem donne la même hauteur de ligne
       partout, groupe ou non. */
    padding: .4rem 1rem; font-size: 12px;
    text-transform: uppercase; letter-spacing: .3px; text-decoration: none;
    /* Même padding que .flyout li > a, mais une police plus petite (12px vs 14px)
       lui donne malgré tout un line-height "normal" plus court, donc une ligne
       plus basse (mesuré : 31,78px contre 33,78px) — min-height comble l'écart
       sans toucher au style (taille/majuscules) qui distingue un en-tête de groupe. */
    min-height: 34px;
}
/* Groupe cliquable (au moins un niveau 3 construit) : texte normal, comme un item
   simple — hérité de .flyout li > a (couleur-texte), pas de gris ici ; le grisé
   « Bientôt disponible » ne s'applique qu'au span.desactive (aucun niveau 3 construit). */
.flyout li.groupe > a.groupe-titre:hover { color: var(--couleur-principale); background: var(--couleur-survol); }
.flyout li.groupe.actif > a.groupe-titre { background: var(--couleur-cinq); color: #fff; }
.flyout li.groupe > .groupe-titre::after {
    /* line-height:1 (comme .material-icons) : sans ça, le line-height "normal" du
       chevron (~19px) dépasse celui de l'icône (16px, réglée à 1) et rend toute
       la ligne plus haute que ses voisines de niveau 2 (mesuré : 36,78px contre
       33,78px). */
    content: '›'; margin-left: auto; padding-left: .5rem; color: #bbb;
    font-size: 16px; line-height: 1;
}
.flyout li.groupe.actif > .groupe-titre::after { color: rgba(255,255,255,.8); }
.flyout li.groupe > ul {
    display: none;
    position: absolute; left: 100%; top: -.5rem;
    min-width: 200px; background: #fff; color: var(--couleur-texte);
    box-shadow: 2px 2px 10px rgba(0,0,0,.3); border-radius: 4px;
    padding: .5rem 0; z-index: 31;
}
/* Comme le flyout de niveau 1 : cascade au survol réservée au desktop. En mode
   tiroir mobile, les sous-listes sont toujours dépliées (cf. media 993px). */
@media screen and (min-width: 993.02px) {
    .flyout li.groupe:hover > ul,
    .flyout li.groupe:focus-within > ul { display: block; }
}
.flyout li.groupe > span.groupe-titre.desactive { color: #bbb; cursor: default; }

main { padding: 0 1.5rem 2rem 76px; width: 100%; }
h1 { font-size: 1.25rem; color: var(--couleur-principale); font-weight: 600; }

.card { background: #fff; border: 1px solid var(--couleur-bordure); border-radius: 4px;
        padding: 1rem 1.25rem; margin-bottom: 1.25rem; }
.card h2 { margin-top: 0; font-size: 1.05rem; }

/* Boutons (btn-small Materialize) */
button {
    background: var(--couleur-principale); color: #fff; border: 0; border-radius: 2px;
    height: 32.4px; padding: 0 16px; cursor: pointer; text-transform: uppercase;
    font-size: 13px; letter-spacing: .5px;
    box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.12);
}
button:hover { filter: brightness(1.08); }
button.secondaire { background: #9e9e9e; }
button.lien { background: none; border: 0; box-shadow: none; padding: 0 .15rem; height: auto;
              cursor: pointer; color: var(--couleur-principale); vertical-align: middle; }
button.lien:hover { color: var(--couleur-cinq); filter: none; }

/* Bouton d'export du plugin DataTables Buttons (Rapprochements bancaires, Journaux) :
   sa feuille de style (div.dt-buttons>.dt-button, spécificité 0,2,1) l'emporterait sur
   une simple règle .dt-button (0,1,0) malgré l'ordre de chargement — !important pour
   reprendre sans ambiguïté le style des autres boutons de l'app. */
div.dt-buttons > .dt-button {
    background: var(--couleur-principale) !important; color: #fff !important;
    border: 0 !important; border-radius: 2px !important;
    height: 32.4px !important; padding: 0 16px !important; cursor: pointer;
    text-transform: uppercase; font-size: 13px !important; letter-spacing: .5px;
    box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.12) !important;
}
div.dt-buttons > .dt-button:hover:not(.disabled) {
    filter: brightness(1.08); background: var(--couleur-principale) !important;
}
.dt-buttons { margin-bottom: .75rem; }
code { background: #eef; padding: .2rem .4rem; border-radius: 3px; }

/* Onglets (tabs Materialize, texte couleur principale comme l'ancienne app) */
.tabs { display: flex; align-items: stretch; background: #f0f0f0; border-radius: 4px 4px 0 0; margin: 20px 0; }
.tabs-principaux { display: flex; flex: 1; min-width: 0; }
.tabs-principaux button, .tabs-principaux a {
    flex: 1; display: flex; align-items: center; justify-content: center; gap: .5rem;
    background: transparent; color: var(--couleur-principale); box-shadow: none;
    border-radius: 0; height: 48px; font-weight: 500; text-decoration: none;
    border-bottom: 2px solid transparent; text-transform: uppercase; font-size: 14px;
}
.tabs-principaux button .material-icons { font-size: 18px; }
.tabs-principaux button:hover, .tabs-principaux a:hover { background: #eee; filter: none; }
.tabs-principaux button.actif, .tabs-principaux a.actif {
    color: var(--couleur-principale); background: #fff;
    border-bottom-color: var(--couleur-principale); font-weight: 600;
}

/* Sous-onglets (vue tableau/analyse de CP) : logés dans la même barre que les
   onglets principaux (typologie), à droite, en style compact pour bien les
   distinguer comme un groupe secondaire — une seule ligne d'onglets au total. */
.tabs-secondaires { display: flex; align-items: center; gap: .25rem; flex-shrink: 0; padding: 0 .75rem; border-left: 1px solid #ddd; }
.tabs-secondaires button {
    display: flex; align-items: center; gap: .35rem; height: 30px; padding: 0 .75rem;
    background: transparent; color: var(--couleur-texte); box-shadow: none;
    border-radius: 4px; font-weight: 500; font-size: 13px;
}
.tabs-secondaires button .material-icons { font-size: 16px; }
.tabs-secondaires button:hover { background: #e4e4e4; filter: none; }
.tabs-secondaires button.actif { background: #fff; color: var(--couleur-principale); font-weight: 600; }
[data-theme="dark"] .tabs-secondaires { border-left-color: #444; }

/* Graphique d'évolution (onglets Analyses/Bridge de CP) : pleine largeur ; hauteur
   calée sur le viewport (le graphique laissait ~300px de vide sous 450px fixes sur
   un écran normal) avec un plancher pour rester lisible sur les petits écrans.
   position: relative obligatoire (documentation Chart.js) : sans elle, le canevas en
   maintainAspectRatio:false ne mesure pas correctement la hauteur du conteneur lors
   du redimensionnement responsive. */
.zone-graphique { position: relative; margin: 20px 0; height: calc(100vh - 280px); min-height: 450px; }

/* Bouton de réinitialisation du zoom (onglet Évolution, chartjs-plugin-zoom) : affiché
   uniquement une fois qu'un zoom/déplacement a été effectué (cf. consommation.js). */
.bouton-reset-zoom { position: absolute; top: 0; right: 0; z-index: 1; }

/* Page de connexion (login natif, hors layout applicatif — pas de sidenav/topbar) :
   reprend exactement la mise en page de l'ancien login.php (Materialize) — logo,
   titre grand et léger, lignes label-à-gauche/champ-souligné-à-droite centrées,
   bouton, lien mot de passe oublié — avec en plus la gestion du mode sombre. */
.page-connexion { text-align: center; padding: 2rem 1rem; }
.page-connexion .logo { height: 50px; display: block; margin: 0 auto; }
/* Tailles en px explicites (mesurées via getComputedStyle sur l'ancienne page) : Materialize
   y fixe html{font-size:14px} (pas 16px), donc ses rem ne se transposent pas tels quels ici. */
.page-connexion h1 { font-size: 32px; font-weight: 400; color: var(--couleur-texte); margin: .25rem 0 2rem; }
[data-theme="dark"] .page-connexion .logo { filter: invert(1) brightness(1.9); }
/* Pas de conteneur centré : comme l'ancienne table pleine largeur (col label 45% +
   champ à largeur FIXE, non extensible), pour que le champ retombe au même endroit
   que sur l'ancienne page — sinon un champ qui s'étire jusqu'au bord d'un conteneur
   centré ne tombe pas sous le bouton, lui-même centré indépendamment sur toute la page. */
.ligne-connexion { display: flex; align-items: baseline; margin: 0 0 2rem; }
.ligne-connexion label { flex: 0 0 45%; text-align: right; color: #9e9e9e; font-size: 11px; padding-right: 8px; }
.ligne-connexion input {
    flex: 0 0 200px; border: 0; border-bottom: 1px solid var(--couleur-bordure);
    background: transparent; font-size: 16px; color: var(--couleur-texte); padding: .2rem 0; outline: none;
}
.ligne-connexion input:focus {
    border-bottom: 1px solid var(--couleur-principale); box-shadow: 0 1px 0 0 var(--couleur-principale);
}
.boutons-connexion { margin: 0 0 1rem; }
.page-connexion .lien-secondaire { font-size: 10.5px; margin: 0 0 .5rem; }
.page-connexion .lien-secondaire a { text-decoration: none; }
/* Messages de résultat (identifiants/reCAPTCHA/token/envoi) : simples <p>, pas de
   <small> — taille de base (14px, mesurée) et couleurs littérales comme l'ancienne app. */
.page-connexion .erreur { color: red; font-size: 14px; }
.page-connexion .succes { color: green; font-size: 14px; }
.page-connexion .info { color: #e65100; font-size: 14px; }
.page-connexion h1.titre-secondaire { font-size: 23px; line-height: 1.3; }

/* Barre d'outils des tableaux (déplacée par JS sur la ligne de recherche DataTables) */
.table-toolbar { display: flex; align-items: center; margin: 0 0 0 auto; }
.toggle-caduc-label { font-size: 13px; color: #666; display: flex; align-items: center; gap: .3rem; cursor: pointer; }
p.sous-tableau { text-align: center; margin: 14px 0; }

/* Champ de recherche DataTables (à gauche, libellé non souligné) */
div.dt-container div.dt-search { text-align: left; font-size: 14px; margin: 8px 0 5px; }
div.dt-container div.dt-search label { text-decoration: none; color: var(--couleur-texte); }
div.dt-container div.dt-search input.dt-input {
    border: 0; border-bottom: 1px solid var(--couleur-bordure); background: transparent;
    height: 25px; font-size: 13px; outline: none; margin-left: .4rem; border-radius: 0;
}
div.dt-container div.dt-search input.dt-input:focus {
    border-bottom: 1px solid var(--couleur-cinq); box-shadow: 0 1px 0 0 var(--couleur-cinq);
}

/* Tableaux de données (dataTable_sogefi historique : 13px, compact, lignes fines,
   en-têtes centrés avec séparateurs verticaux façon cell-border).
   Sélecteurs volontairement précis pour l'emporter sur le CSS DataTables. */
table.dataTable.liste-contrats { border-collapse: collapse; font-size: 13px; line-height: 15px; margin: 0; width: 100% !important; }
table.dataTable.liste-contrats > thead > tr > th,
table.dataTable.table-details > thead > tr > th {
    padding: 5px !important; text-align: center; font-weight: 600; background: #fff;
    /* En-tête collant au défilement ; les traits noirs passent en box-shadow car
       les bordures d'un th sticky ne suivent pas avec border-collapse. Collant à
       l'intérieur de .echeances-scroll pour les tableaux imbriqués (table-details
       une fois passés en DataTables — demande utilisateur 25/07/2026). */
    position: sticky; top: 0; z-index: 5;
    border-top: none; border-bottom: none;
    box-shadow: inset 0 1px 0 black, inset 0 -1px 0 black;
}
/* Pas d'encadré gris au survol des en-têtes (outline DataTables 2) */
table.dataTable.liste-contrats > thead > tr > th:hover,
table.dataTable.liste-contrats > thead > tr > th:active,
table.dataTable.table-details > thead > tr > th:hover,
table.dataTable.table-details > thead > tr > th:active { outline: none; }
/* Icônes de tri DataTables : toujours à droite du libellé — DataTables 2 inverse
   le flex (row-reverse) sur les colonnes numériques, on rétablit le sens normal */
table.dataTable.liste-contrats th.dt-type-numeric div.dt-column-header,
table.dataTable.liste-contrats th.dt-type-date div.dt-column-header,
table.dataTable.table-details th.dt-type-numeric div.dt-column-header,
table.dataTable.table-details th.dt-type-date div.dt-column-header {
    flex-direction: row;
}
/* … et en bleu comme l'ancien site */
table.dataTable.liste-contrats > thead > tr > th span.dt-column-order::before,
table.dataTable.liste-contrats > thead > tr > th span.dt-column-order::after,
table.dataTable.table-details > thead > tr > th span.dt-column-order::before,
table.dataTable.table-details > thead > tr > th span.dt-column-order::after {
    color: var(--couleur-cinq);
}
table.dataTable.liste-contrats > tbody > tr > td {
    padding: 5px; border-bottom: 1px solid #e0e0e0; box-shadow: none;
}
/* Lignes compactées à 15px comme l'ancienne interface (mesuré : contenu 15,5px).
   PIÈGE mesuré au headless : les icônes/boutons alignés `middle` débordent sous la
   ligne de base et gonflent la boîte de ligne à ~16,75px malgré line-height:15px ;
   `vertical-align: top` les fait tenir exactement dans la ligne de 15px. */
table.dataTable.liste-contrats > thead > tr > th,
table.dataTable.liste-contrats > tbody > tr > td,
table.table-details th,
table.table-details td { line-height: 15px !important; }
table.dataTable.liste-contrats .material-icons.petit,
table.table-details .material-icons.petit { font-size: 15px; line-height: 15px; }
button.lien svg { display: block; }
table.dataTable.liste-contrats td .icone,
table.dataTable.liste-contrats td button.lien,
table.dataTable.liste-contrats td .material-icons.petit,
table.table-details td .icone,
table.table-details td button.lien,
table.table-details td .material-icons.petit { vertical-align: top; }
tr.ligne-contrat { cursor: pointer; }
tr.ligne-contrat:hover td { background: var(--couleur-survol); }
tr.ligne-contrat.shown td { background: lightgrey; font-weight: bold; }

/* Curseur forcé comme sur l'ancienne interface : lignes non cliquables (travaux/
   équipements) en curseur normal, lignes cliquables (charges/produits, contrats)
   en curseur pointeur, y compris sur les cellules d'action. Les lignes dépliées
   (.detail-contrat) restent exclues : elles gardent le curseur normal ci-dessus. */
#table-te tbody tr, #table-te tbody td { cursor: default; }
table[id^="table-cp-"] tbody tr:not(.detail-contrat),
table[id^="table-cp-"] tbody tr:not(.detail-contrat) > td { cursor: pointer; }
#table-contrats tbody tr:not(.detail-contrat),
#table-contrats tbody tr:not(.detail-contrat) > td { cursor: pointer; }

/* Contrats fermés : double barré gris (classe caduc historique) ;
   masqués par défaut via le filtre DataTables (voir contrats.js) */
tr.caduc td { text-decoration: line-through; text-decoration-style: double; color: grey; }

/* Échéances théoriques restantes déjà passées (page /emprunts) : simple barré, pas
   double comme .caduc (une échéance passée n'est pas forcément un vrai impayé, juste
   pas encore repointée — demande utilisateur 25/07/2026). */
tr.echeance-passee td { text-decoration: line-through; color: grey; }

/* Échéance la plus proche de la date du jour : léger repère visuel, en plus du
   recentrage automatique du scroll fait par emprunts.js à l'ouverture de l'onglet. */
tr.echeance-proche td { background: var(--couleur-survol); }

tr.detail-contrat td { background: #f7f7f7; font-size: 13px; cursor: default; }
tr.detail-contrat p { margin: .25rem 0; }

/* En-tête d'un tableau table-details imbriqué DANS une ligne dépliée (ex. les 3
   onglets de /emprunts) : fond gris comme le reste de la ligne, pas le blanc par
   défaut (réservé au cas modale/dialog, fond blanc là) — demande utilisateur.
   Sélecteur volontairement large (pas de ">", pas de ".dataTable" requis) pour
   s'appliquer quelle que soit la structure DOM insérée par DataTables autour du
   th ; !important pour trancher net plutôt que rejouer une bataille de spécificité. */
tr.detail-contrat table.table-details th { background: #f7f7f7 !important; }

/* Emprunt sans caractéristiques renseignées (cf. /emprunts) : atténué, pas de
   barré (contrairement à .caduc — ce n'est pas fermé, juste incomplet) */
tr.incomplet td { color: grey; font-style: italic; }

/* En-têtes de #table-emprunts réellement centrés (demande utilisateur 15/07/2026) :
   DataTables 2 place le libellé dans un conteneur flex (div.dt-column-header,
   justify-content:space-between par défaut) qui ignore le text-align:center du
   th — même défaut sur .liste-contrats en général (contrats/te/cp), mais corrigé
   ICI SEULEMENT (scope #table-emprunts) à la demande explicite de l'utilisateur,
   qui ne veut pas changer le rendu déjà validé des autres pages. */
#table-emprunts.dataTable > thead > tr > th div.dt-column-header { justify-content: center; }
/* Barre de progression à droite du % dans la colonne "Progression" (/emprunts) :
   simple repère visuel, pas un code couleur bon/mauvais, donc une seule teinte
   (--couleur-principale). Le pourcentage réel peut être hors bornes (ex. avant
   liaison des déblocages d'un prêt à tranches, cf. mémoire
   patrimoine-emprunt-conception) : la valeur affichée n'est pas tronquée, seule
   la largeur de la barre est clampée 0-100% côté template. */
#table-emprunts td.barre-progression .ligne-progression {
    display: inline-flex; align-items: center; gap: .5rem;
}
#table-emprunts td.barre-progression .barre {
    position: relative; width: 50px; height: 8px; border-radius: 4px;
    background: var(--couleur-bordure); overflow: hidden;
}
#table-emprunts td.barre-progression .barre .fond {
    position: absolute; inset: 0; background: var(--couleur-principale);
}
/* Idem pour l'en-tête "Type"/"CP" de #table-biens (demande utilisateur 17/08/2026) :
   même contournement, limité aux th.centre pour ne pas changer Nom/Adresse/Ville. */
#table-biens.dataTable > thead > tr > th.centre div.dt-column-header { justify-content: center; }
tr.incomplet td:first-child, tr.incomplet td:nth-child(2), tr.incomplet td:nth-child(3), tr.incomplet td:nth-child(4) { font-style: normal; }
.echeances-scroll { max-height: 320px; overflow-y: auto; }

/* Détail d'un emprunt (page /emprunts) : fiche de champs courts (légende + valeur)
   plutôt que des paragraphes à tirets, moins fouillis à lire (demande utilisateur
   25/07/2026). 6 colonnes fixes (pas auto-fit) pour tenir sur 2 lignes de façon
   prévisible quelle que soit la largeur (densification demandée le même jour) ;
   repli à 2 colonnes en dessous de 993px, cf. media query plus bas. */
.detail-emprunt { display: grid; grid-template-columns: repeat(6, 1fr); gap: .5rem 1.5rem; margin: .25rem 0 .75rem; }
.detail-emprunt div { font-size: 13px; }
.detail-emprunt span { display: block; font-size: .72rem; color: #9e9e9e; }
[data-theme="dark"] .detail-emprunt span { color: #999; }

/* Onglets Échéances/Déblocages/Assurances du détail d'un emprunt (demande
   utilisateur 25/07/2026) : barre compacte propre au bloc détail, pas de
   couleur fixe (contrairement à .tabs-secondaires) pour rester lisible en
   thème sombre. */
.onglets-detail { display: flex; gap: .25rem; margin: .5rem 0 0; border-bottom: 1px solid var(--couleur-bordure); }
/* Espacement du contenu de l'onglet géré ici (pas par la marge de table.table-details,
   qui vaudrait pour la barre d'onglets ET pour le tableau, doublant l'écart par
   collapse de marges — demande utilisateur). */
.panneau-detail { margin-top: .5rem; }
.panneau-detail table.table-details { margin-top: 0; }
.onglets-detail button {
    background: transparent; color: var(--couleur-texte); box-shadow: none;
    border-radius: 4px 4px 0 0; height: 30px; padding: 0 .75rem; font-weight: 500; font-size: 13px;
    text-transform: none; letter-spacing: normal;
}
.onglets-detail button:hover { background: var(--couleur-survol); filter: none; }
.onglets-detail button.actif { background: var(--couleur-survol); color: var(--couleur-principale); font-weight: 600; }
.panneau-detail[hidden] { display: none; }

/* Icônes (imgPersonne historique : 15px, coins arrondis) */
.icone { height: 15px; border-radius: 3px; vertical-align: middle; }
th.num, td.num { text-align: right; }
th.action, td.action { text-align: center; white-space: nowrap; }
/* Doit l'emporter sur l'alignement auto de DataTables (dt-type-date/numeric → right) */
table.dataTable.liste-contrats td.centre,
table.dataTable.liste-contrats th.centre,
td.centre { text-align: center; }
.material-icons.petit { font-size: 16px; vertical-align: middle; }
.pointe { color: green; font-size: .8em; opacity: .7; }
.pdf { color: red; }
.verrou { color: #9e9e9e; }
table.liste-contrats tbody tr:hover td { background: var(--couleur-survol); }

/* Ligne d'en-tête de groupe (une par commune : région > département > groupement de
   communes > commune sur la même ligne) du tableau des biens — insérée par
   biens.js/insereLignesGroupes, pas une extension DataTables. */
tr.ligne-groupe td {
    background: rgba(90, 135, 156, .12); font-weight: 600; padding: 5px 8px; cursor: default;
}
/* Logo de chaque segment (région/département/groupement/commune, cf. biens.js) : masqué
   via onerror si absent plutôt que d'afficher l'icône d'image cassée du navigateur. */
tr.ligne-groupe img.logo-groupe { height: 18px; width: 18px; object-fit: contain; vertical-align: middle; margin-right: 6px; }

/* Page /biens (reprend la mise en page de l'ancienne app index.php) : tableau des
   biens + ligne dépliable à gauche, carte/onglets à droite, 2 colonnes égales
   au-dessus du point de rupture mobile. */
.biens-layout { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; align-items: start; }
.carte-biens { height: 500px; border: 1px solid var(--couleur-bordure); border-radius: 4px; }
.cases-carte { display: flex; gap: 1.5rem; margin: .75rem 0 0; }
.objet-plan { width: 100%; height: 500px; border: 1px solid var(--couleur-bordure); border-radius: 4px; }
.iframe-vues360 { width: 100%; height: 500px; border: 1px solid var(--couleur-bordure); border-radius: 4px; }
/* Détail d'un bien (ligne dépliée) : deux colonnes (dates/propriétaires/lots/PDL à
   gauche, streetview/parcelles/estimation/SIRET à droite), comme l'ancienne app. */
.detail-bien { display: grid; grid-template-columns: 1fr 1fr; gap: 0 2rem; margin: .25rem 0 .75rem; font-size: 13px; }
.detail-bien p { margin: .5rem 0; }
.detail-bien ul { margin: .25rem 0 .5rem; padding: 0; list-style: none; }
.detail-bien li { margin: .15rem 0; }
/* Popup MapLibre au survol d'un bien : compacte (juste le nom) */
.maplibregl-popup.popup-bien .maplibregl-popup-content { padding: 4px 8px; font-size: 12px; }
@media (max-width: 992px) {
    .biens-layout { grid-template-columns: 1fr; }
}

/* Sélecteurs bien / année : deux moitiés pleine largeur, comme l'ancienne interface.
   min-height = hauteur du composant construit en JS, pour éviter le saut de mise en page */
.selecteurs { display: flex; gap: 2rem; margin: 20px 0; }
.selecteurs > * { flex: 1; min-width: 0; min-height: 2.2rem; }
/* Sélecteur seul (ex. société, page /societes) : pas de second contrôle à côté pour
   se partager la largeur — .si-bouton fait 100% de son conteneur, donc borné ici
   plutôt que de s'étirer sur toute la largeur de la page comme .selecteurs. */
.selecteur-societe { max-width: 320px; margin: 20px 0; min-height: 2.2rem; }
select.natif {
    height: 2.2rem; font-size: 14px; color: var(--couleur-texte);
    background: #fff; border: 1px solid var(--couleur-bordure); border-radius: 2px;
    font-family: 'Titillium Web', sans-serif;
}

/* Chevron unique pour tous les sélecteurs (selects natifs et composant select-icones) */
select.natif, .grille select {
    appearance: none;
    background-image: var(--chevron-select);
    background-repeat: no-repeat;
    background-position: right 8px center;
    background-size: 10px 6px;
    padding-right: 26px;
}
.select-icones .si-fleche {
    margin-left: auto; width: 10px; height: 6px; flex-shrink: 0;
    background: var(--chevron-select) center / 10px 6px no-repeat;
}
.selecteurs .si-bouton { font-size: 14px; }
.si-pastille { width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0;
               border: 1px solid rgba(0,0,0,.2); }
.select-icones .si-liste li.si-estompe { color: #9e9e9e; }

/* Modale : radios de type et case à cocher */
fieldset.type-choix { border: 0; padding: 0; margin: 0; display: flex; gap: 2rem;
                      flex-direction: row !important; }
.grille .centre-modal { justify-content: center; align-self: center; }
fieldset.type-choix label { flex-direction: row; align-items: center; gap: .4rem;
                            font-size: 14px; color: var(--couleur-texte); }
.grille label.case, label.case { flex-direction: row; align-items: center; gap: .5rem;
                     font-size: 14px; color: var(--couleur-texte); display: inline-flex; }

/* Diagnostics (page d'accueil du socle) */
.ok { color: #1b5e20; }
.ko { color: #b71c1c; font-weight: bold; }
section.card table { border-collapse: collapse; width: 100%; }
section.card th, section.card td { text-align: left; padding: .35rem .5rem; border-bottom: 1px solid #eee; }

/* Modale (esprit modale Materialize : blanche, 55%, inputs à souligné, selects natifs) */
dialog {
    border: 0; border-radius: 2px; box-shadow: 0 24px 38px 3px rgba(0,0,0,.14);
    padding: 24px; width: min(720px, 92vw); max-height: 88vh; overflow-y: auto;
}
dialog::backdrop { background: rgba(0,0,0,.5); }
dialog h2 { font-size: 1.25rem; font-weight: 400; margin: 0 0 1rem; color: var(--couleur-texte); }
.grille { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem 1.5rem; }
.grille label { display: flex; flex-direction: column; font-size: .8rem; color: #9e9e9e;
                gap: .2rem; min-width: 0; }
.grille .pleine-largeur { grid-column: 1 / -1; }
.grille input {
    width: 100%; padding: .3rem 0; border: 0; border-bottom: 1px solid var(--couleur-bordure);
    background: transparent; font-size: 14px; color: var(--couleur-texte); outline: none;
}
/* Cases à cocher et radios : taille naturelle, collées à leur libellé */
.grille input[type="checkbox"], .grille input[type="radio"] {
    width: auto; padding: 0; border: 0; box-shadow: none;
}
/* Champs fichier : pas de trait de soulignement (réservé aux champs texte) */
.grille input[type="file"],
.grille input[type="file"]:focus { border: 0; box-shadow: none; }
.grille input:focus {
    border-bottom: 1px solid var(--couleur-principale); box-shadow: 0 1px 0 0 var(--couleur-principale);
}
.grille select {
    width: 100%; max-width: 100%; height: 2.2rem; font-size: 13px;
    color: var(--couleur-texte); border: 1px solid var(--couleur-bordure);
    border-radius: 2px;
    /* background-color et non background : le raccourci écraserait le chevron (background-image) */
    background-color: #fff;
}
.boutons { display: flex; gap: .75rem; justify-content: flex-end; margin: 1.25rem 0 0; }

/* Voile de chargement pendant les navigations (équivalent du sogefi_loader historique) */
#chargement {
    position: fixed; inset: 0; z-index: 200;
    /* Opaque : un voile translucide laisse deviner la mise en place de la page
       (bascule de police, composants JS) pendant un chargement complet */
    background: #fff;
    display: flex; align-items: center; justify-content: center;
}
/* Navigation par fragments : pas de FOUC à masquer, le voile reste lisible
   (et il n'apparaît que si la requête traîne, cf. chargeFragment) */
#chargement.leger { background: rgba(255,255,255,.5); }
#chargement[hidden] { display: none; }
#chargement .spinner {
    width: 48px; height: 48px; border-radius: 50%;
    border: 4px solid var(--couleur-principale); border-top-color: transparent;
    animation: rotation-chargement .8s linear infinite;
}
@keyframes rotation-chargement { to { transform: rotate(360deg); } }

/* Composant select à icônes (select-icones.js) */
.select-icones { position: relative; min-width: 0; }
.select-icones .si-bouton {
    width: 100%; height: 2.2rem; display: flex; align-items: center; gap: .4rem;
    background: #fff; color: var(--couleur-texte); border: 1px solid var(--couleur-bordure);
    border-radius: 2px; box-shadow: none; text-transform: none; letter-spacing: 0;
    font-size: 13px; padding: 0 .5rem; justify-content: flex-start;
}
.select-icones .si-bouton:hover { filter: none; border-color: var(--couleur-principale); }
.select-icones .si-choix { display: flex; align-items: center; gap: .4rem; overflow: hidden;
                           white-space: nowrap; text-overflow: ellipsis; }
.select-icones .si-choix.si-vide { color: #9e9e9e; }
.select-icones .si-liste {
    position: absolute; z-index: 40; left: 0; right: 0; top: 100%;
    margin: 0; padding: 0; list-style: none;
    background: #fff; border: 1px solid var(--couleur-bordure);
    max-height: 240px; overflow: auto; box-shadow: 0 4px 12px rgba(0,0,0,.25);
}
.select-icones .si-liste li {
    display: flex; align-items: center; gap: .4rem; padding: .35rem .5rem;
    cursor: pointer; font-size: 13px;
}
.select-icones .si-liste li:hover { background: var(--couleur-survol); }
.select-icones .si-liste li.si-entete {
    cursor: default; font-weight: 600; font-size: 11px; text-transform: uppercase;
    letter-spacing: .03em; color: #888; background: #f5f5f5;
}
.select-icones .si-liste li.si-entete:hover { background: #f5f5f5; }
/* Sélection multiple (multiSelectable, Ctrl/Cmd+clic — cf. select-icones.js) */
.select-icones .si-liste li.si-selectionne,
.select-icones .si-liste li.si-selectionne:hover { background: var(--couleur-principale); color: #fff; }
.select-icones .si-liste li.si-selectionne .si-sous { color: #e0e0e0; }
/* Libellés longs : retour à la ligne dans la liste + sous-libellé grisé (IBAN…) */
.select-icones .si-texte { display: flex; flex-direction: column; min-width: 0; }
.select-icones .si-libelle { white-space: normal; }
.select-icones .si-sous { font-size: 11px; color: #888; white-space: normal; }
/* Sous-libellé court (immatriculation…) : reste sur la même ligne que le libellé */
.select-icones .si-texte.si-texte-ligne { flex-direction: row; align-items: baseline; gap: 6px; }
.select-icones .si-texte-ligne .si-sous { white-space: nowrap; }
.select-icones img { height: 15px; border-radius: 3px; flex-shrink: 0; }
.select-icones .si-icone-police { font-size: 13px; width: 16px; text-align: center;
                                  color: var(--couleur-principale); flex-shrink: 0; }

/* Vue agrégée (comparaison multi-biens, lecture seule — cf. cp.js / templates/cp) :
   sélection au clavier/souris via le sélecteur de bien lui-même (Ctrl/Cmd+clic,
   cf. .si-selectionne ci-dessus) — pas de composant dédié. */
.selecteurs-agrege { align-items: center; }
.annee-figee { font-size: 14px; color: var(--couleur-texte); margin: 0; }

/* Charges & produits (cp.js / templates/cp) */
.volet-cp { margin: 0 0 2.5rem; }
/* Titres et totaux centrés, boutons à droite : comme l'ancienne interface */
.titre-tableau { font-size: 14px; margin: 1.5rem 0 .5rem; text-align: center; }
.pied-tableau { font-size: 14px; margin: .6rem 0 0; text-align: center; }
.pied-tableau small { color: #777; }
p.sous-tableau.droite { text-align: right; }
p.sous-tableau.droite > * + * { margin-left: 10px; }
/* Lien habillé en bouton (téléchargement des factures) */
a.bouton {
    display: inline-flex; align-items: center; gap: .3rem;
    background: var(--couleur-principale); color: #fff; border-radius: 2px;
    height: 32.4px; padding: 0 16px; text-transform: uppercase;
    font-size: 13px; letter-spacing: .5px; text-decoration: none;
    box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.12);
    vertical-align: middle;
}
a.bouton:hover { filter: brightness(1.08); }
/* Statut des postes : vert = montant annuel confirmé, orange = année passée non confirmée */
button.lien.statut-ok { color: darkgreen; }
button.lien.statut-attention { color: orange; }
.detail-cp { display: flex; gap: 3rem; }
.detail-cp p { margin: .25rem 0; }
.detail-cp ul { margin: .25rem 0; padding-left: 1.25rem; }
/* Modale de poste : ligne commentaire / montant estimé / case confirmé */
dialog.dialog-large { min-width: min(900px, 92vw); }
.grille.grille-annuel { grid-template-columns: 2fr 1fr auto; align-items: end; }
/* Les champs masqués d'une variante doivent vraiment disparaître
   (.grille label { display:flex } écraserait le [hidden] natif) */
.grille label[hidden] { display: none; }
/* Modale de ligne : grille 12 colonnes reproduisant les proportions Materialize
   de l'ancienne interface (s2/s3/s4/s6/s8/s12), variables selon la variante */
.grille.grille-detail { grid-template-columns: repeat(12, 1fr); }
.grille-detail label { grid-column: span 12; }
/* Aperçu du PDF déposé (cf. cp.js affichePdfApercu) : pleine largeur de la modale, quitte
   à dépasser sa hauteur (le "dialog" a déjà overflow-y:auto) — une facture A4 lisible
   prime sur la compacité. */
.apercu-pdf { margin-top: .4rem; }
.apercu-pdf canvas {
    width: 100%; height: auto; display: block; border: 1px solid var(--couleur-bordure);
    border-radius: 4px; box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
}
/* Débours (charges, toutes typologies) : Date(2) Date facture(2) Montant(2) Commentaire(4)
   / mode(4) compte(8) / contrat(12) / PDF(12) */
.variante-debours .ch-date,
.variante-debours .ch-date_facture,
.variante-debours .ch-montant { grid-column: span 2; }
.variante-debours .ch-commentaire { grid-column: span 4; }
.variante-debours .ch-mode { grid-column: span 4; }
.variante-debours .ch-compte { grid-column: span 8; }
/* Revenu immobilier : Date(2) Mois quittance(2) Montant(4) Commentaire(4)
   / Réservation(12) / mode(4) compte(8) */
.variante-revenu-resa .ch-date,
.variante-revenu-resa .ch-quittance { grid-column: span 2; }
.variante-revenu-resa .ch-montant,
.variante-revenu-resa .ch-commentaire { grid-column: span 4; }
.variante-revenu-resa .ch-mode { grid-column: span 4; }
.variante-revenu-resa .ch-compte { grid-column: span 8; }
/* Revenu personne : Date(3) Montant(3) Commentaire(6) / mode(4) compte(8) / PDF(12) */
.variante-revenu-pdf .ch-date,
.variante-revenu-pdf .ch-montant { grid-column: span 3; }
.variante-revenu-pdf .ch-commentaire { grid-column: span 6; }
.variante-revenu-pdf .ch-mode { grid-column: span 4; }
.variante-revenu-pdf .ch-compte { grid-column: span 8; }
/* Tableau des lignes détaillées dans la modale (hors DataTables) */
table.table-details { border-collapse: collapse; font-size: 13px; line-height: 15px;
                      width: 100%; margin: 1rem 0 0; }
/* !important sur text-align/font-weight : ce tableau est imbriqué dans une ligne
   dépliée (row.child) d'un DataTable (table.dataTable thead th), dont la règle CSS
   propre (text-align:left) l'emporte sinon par spécificité (thead en plus dans son
   sélecteur) — même piège déjà contourné plus haut pour line-height. */
/* Fond blanc + double filet (haut+bas) : même cadre que les en-têtes de
   table.dataTable.liste-contrats plus haut, pour que ces tableaux imbriqués
   (échéances/déblocages/assurances d'un emprunt, etc.) ne détonnent pas visuellement
   à côté des autres tableaux de l'appli (demande utilisateur 25/07/2026). */
table.table-details th { padding: 5px; text-align: center !important; font-weight: 600 !important;
                         background: #fff; box-shadow: inset 0 1px 0 #000, inset 0 -1px 0 #000; }
table.table-details td { padding: 5px; border-bottom: 1px solid #ddd; }
table.table-details td.centre { text-align: center; }
table.table-details td.num { text-align: right; white-space: nowrap; }
table.table-details td.action { text-align: center; white-space: nowrap; }

/* ============================================================
   Mobile (≤ 993px, complément exact des min-width: 993.02px plus haut) :
   le rail d'icônes + flyouts au survol devient un tiroir off-canvas ouvert
   par le burger de la topbar, avec un accordéon par domaine (classe .deplie
   posée par app.js) — le survol n'existe pas au doigt.
   ============================================================ */
@media screen and (max-width: 993px) {
    main { padding-left: 1.5rem; }
    /* Le rail est hors écran : la topbar reprend un padding normal, le burger
       prend la place. Titre borné (ellipse) et date masquée pour tenir en largeur. */
    .topbar { padding-left: .5rem; gap: .5rem; }
    .topbar .titre-page { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
    .topbar .date-jour { display: none; }
    .btn-menu { display: flex; }
    .grille { grid-template-columns: 1fr; }
    .detail-emprunt { grid-template-columns: 1fr 1fr; }

    /* Rail → tiroir : même fond, glissé hors écran au repos */
    ul.sidenav {
        width: 280px; max-width: 85vw;
        transform: translateX(-100%);
        transition: transform .25s ease;
        overflow-y: auto;
        box-shadow: none;
    }
    body.menu-ouvert ul.sidenav {
        transform: none;
        box-shadow: 2px 0 12px rgba(0,0,0,.35);
    }
    /* Pas de défilement de la page derrière le tiroir ouvert */
    body.menu-ouvert { overflow: hidden; }
    #voile-menu { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.4); z-index: 44; }
    body.menu-ouvert #voile-menu { display: block; }

    /* Ligne de domaine : icône + libellé alignés à gauche, chevron indicateur
       d'accordéon poussé à droite (tourné de 90° quand le panneau est déplié) */
    ul.sidenav > li { text-align: left; }
    ul.sidenav > li > a { justify-content: flex-start; gap: .75rem; padding: 0 1rem; }
    .libelle-domaine { display: inline; font-size: 15px; }
    ul.sidenav li.menu-domaine > a::after {
        content: '›'; margin-left: auto; color: rgba(255,255,255,.7);
        font-size: 18px; line-height: 1; transition: transform .2s ease;
    }
    ul.sidenav li.menu-domaine.deplie > a::after { transform: rotate(90deg); }

    /* Flyout → panneau d'accordéon logé dans le flux du tiroir. Le titre du
       panneau disparaît (redondant : la ligne de domaine porte déjà le libellé). */
    ul.sidenav li.menu-domaine .flyout {
        position: static; min-width: 0; box-shadow: none; border-radius: 0;
        padding: .25rem 0;
    }
    ul.sidenav li.menu-domaine.deplie .flyout { display: block; }
    .flyout .flyout-titre { display: none; }
    /* Cibles de tap plus hautes, libellés longs autorisés à passer à la ligne */
    .flyout li > a, .flyout li.desactive { white-space: normal; padding: .5rem 1rem .5rem 1.25rem; }
    /* Niveau 3 : toujours déplié et simplement indenté (pas de cascade au survol) */
    .flyout li.groupe > ul {
        display: block; position: static; min-width: 0;
        box-shadow: none; border-radius: 0; padding: 0 0 .25rem 1rem;
    }
    /* Chevron « sous-panneau à droite » sans objet quand tout est déplié */
    .flyout li.groupe > .groupe-titre::after { content: none; }
}

/* ============================================================
   Mode sombre — préférence locale (localStorage), cf. mon-compte/index.php
   et app.js:appliqueTheme(). L'attribut data-theme est posé sur <html> par
   layout.php avant le premier rendu, donc ces règles surchargent simplement
   les couleurs codées en dur ailleurs dans ce fichier (les couleurs déjà
   posées via les variables --couleur-* héritent automatiquement du bloc
   :root[data-theme="dark"] ci-dessous, sans règle supplémentaire).
   ============================================================ */
:root[data-theme="dark"] {
    --couleur-texte: #d8d8d8;
    --couleur-bordure: #4a4a4a;
    --couleur-survol: #333;
    --couleur-bridge-hausse: #81c784;
    --couleur-bridge-baisse: #e66767;
    --couleur-bridge-neutre: #c3c2b7;
}
[data-theme="dark"] body { background: #1e1e1e; }
/* .flyout doit ici égaler ou dépasser la spécificité de "ul.sidenav li.menu-domaine
   .flyout" (règle d'origine, ligne ~97) — un simple "[data-theme] .flyout" perd la
   bataille de spécificité et reste blanc malgré cette surcharge. */
[data-theme="dark"] ul.sidenav li.menu-domaine .flyout,
[data-theme="dark"] .topbar,
[data-theme="dark"] .flyout li.groupe > ul,
[data-theme="dark"] .card,
[data-theme="dark"] dialog,
[data-theme="dark"] select.natif,
[data-theme="dark"] .grille select,
[data-theme="dark"] .select-icones .si-bouton,
[data-theme="dark"] .select-icones .si-liste,
[data-theme="dark"] table.dataTable.liste-contrats > thead > tr > th,
[data-theme="dark"] table.table-details th {
    background: #2a2a2a; color: var(--couleur-texte);
}
[data-theme="dark"] table.dataTable.liste-contrats > thead > tr > th {
    box-shadow: inset 0 1px 0 #666, inset 0 -1px 0 #666;
}
[data-theme="dark"] table.table-details th { box-shadow: inset 0 1px 0 #666, inset 0 -1px 0 #666; }
[data-theme="dark"] .select-icones .si-liste li.si-entete { background: #333; }
[data-theme="dark"] tr.ligne-contrat.shown td { background: #444; }
[data-theme="dark"] tr.detail-contrat td { background: #262626; }
[data-theme="dark"] tr.detail-contrat table.table-details th { background: #262626 !important; }
[data-theme="dark"] .grille input { color: var(--couleur-texte); }
[data-theme="dark"] code { background: #333; color: #dde; }
[data-theme="dark"] dialog::backdrop { background: rgba(0,0,0,.7); }
[data-theme="dark"] #chargement { background: #1e1e1e; }
[data-theme="dark"] #chargement.leger { background: rgba(30,30,30,.5); }
[data-theme="dark"] .tabs { background: #2a2a2a; }
[data-theme="dark"] .tabs button:hover, [data-theme="dark"] .tabs a:hover { background: #333; }
[data-theme="dark"] .tabs button.actif, [data-theme="dark"] .tabs a.actif { background: #1e1e1e; }

.grecaptcha-badge {
    display: none !important;
}
/* ---------- Pointage des relevés bancaires (/pointage) ---------- */
.barre-pointage { display: flex; align-items: center; gap: 1.5rem; margin: 0 0 12px; }
.barre-pointage .ressort { flex: 1; }
.barre-pointage label { cursor: pointer; font-size: 14px; }
/* Couleurs identiques à l'ancienne page. Badges : classes Materialize (green #4caf50,
   grey #9e9e9e, cyan #00bcd4, orange #ff9800 via releve.css). Chip : surcharges de
   releve.css (#43a047 / #ff9800 / #e74c3c). Boutons : PAS de couleur spécifique — la
   charte de l'ancienne app écrasait green/cyan en #5a879c, le défaut du socle ici. */
#stats-pointage { padding: .15rem .7rem; border-radius: 1rem; color: #fff; font-size: .85rem;
                  font-weight: bold; }
#stats-pointage.vert { background: #43a047; }
#stats-pointage.orange { background: #ff9800; }
#stats-pointage.rouge { background: #e74c3c; }
/* Badges d'état compacts (taille des .badge Materialize de l'ancienne page) ;
   on neutralise le gabarit des boutons du socle (hauteur, uppercase, ombre) */
button.badge-etat { border: 0; border-radius: 2px; height: 20px; line-height: 20px;
                    padding: 0 8px; font-size: .75rem; letter-spacing: 0; text-transform: none;
                    color: #fff; cursor: pointer; box-shadow: none; }
button.badge-etat:hover { filter: brightness(1.08); box-shadow: 0 1px 4px rgba(0,0,0,.25); }
button.badge-etat.non { background: #9e9e9e; }
button.badge-etat.partiel { background: #ff9800; }
button.badge-etat.ok { background: #4caf50; }
button.badge-etat.perso { background: #00bcd4; }
/* Materialize (ancienne page) rendait les <small> à 75 % — le défaut navigateur (~83 %)
   ne donne pas la même hiérarchie visuelle dans les libellés */
#table-pointage tbody small, #dialog-recherche small { font-size: 75%; }
td.col-pointage small { display: block; line-height: 1.25; }
td.col-pointage .restant { color: #ff9800; white-space: nowrap; }
td.col-pointage .restant button.lien { color: #f44336; font-size: .8rem; }
/* Fonds de lignes selon l'état, repris tels quels de l'ancienne page ; !important
   comme dans releve.css pour que le survol DataTables ne les efface pas */
#table-pointage tbody tr.ligne-pointee td { background: #e8f5e8 !important; }
#table-pointage tbody tr.ligne-partielle td { background: #fff3e0 !important; }
#table-pointage tbody tr.ligne-perso td { background: #e0f7fa !important; }
/* Mode sombre : mêmes fonds pastel, texte foncé pour rester lisible */
[data-theme="dark"] #table-pointage tbody tr.ligne-pointee td,
[data-theme="dark"] #table-pointage tbody tr.ligne-partielle td,
[data-theme="dark"] #table-pointage tbody tr.ligne-perso td { color: #333; }
/* Surbrillance temporaire des lignes rapprochées par le pointage auto (pointage.js,
   surligneLignes()) : sur outline (pas background, qui est !important ci-dessus et
   masquerait toute animation dessus), tenue puis effacée en fin d'anim. */
#table-pointage tbody tr.ligne-recemment-pointee { animation: pointage-surbrillance 3s ease-out; }
@keyframes pointage-surbrillance {
    0%, 70% { outline: 3px solid #4caf50; outline-offset: -2px; }
    100%    { outline: 3px solid transparent; outline-offset: -2px; }
}
/* Modale de recherche : présentation reprise de l'ancienne interface (releve.php) —
   trois colonnes montant / date / bouton, puis liste « collection » à liseré vert */
#dialog-recherche .ligne-recherche { display: flex; gap: 1.5rem; align-items: flex-end; }
#dialog-recherche .ligne-recherche label { flex: 1; display: flex; flex-direction: column; gap: .35rem; }
#dialog-recherche .ligne-recherche .col-bouton { flex: 1; text-align: center; }
#resultats-recherche { max-height: 45vh; overflow-y: auto; margin-top: 1rem; }
#resultats-recherche .candidat { display: flex; justify-content: space-between; align-items: center;
                                 gap: 1rem; padding: .5rem .75rem; border-bottom: 1px solid var(--couleur-bordure);
                                 border-left: 4px solid #4caf50; }
#resultats-recherche .candidat button { height: 26px; padding: 0 12px; font-size: 12px; }

/* Candidats de liaison "Déblocage" (page Emprunts) : même présentation en liste */
#liste-deblocage-candidats .candidat { display: flex; justify-content: space-between; align-items: center;
                                        gap: 1rem; padding: .5rem .75rem; border-bottom: 1px solid var(--couleur-bordure);
                                        border-left: 4px solid #4caf50; }
#liste-deblocage-candidats .candidat button { height: 26px; padding: 0 12px; font-size: 12px; }
.estompe { color: #888; }
[data-theme="dark"] .estompe { color: #999; }

/* Pagination DataTables (page Pointage) : reprise du style plat de l'app à la place
   des pavés bordés/dégradés de la feuille DataTables (spécificité alignée dessus) */
div.dt-container div.dt-paging button.dt-paging-button {
    background: transparent; border: 0; box-shadow: none; border-radius: 2px;
    color: var(--couleur-texte); height: 28px; min-width: 28px; padding: 0 9px; margin: 0 1px;
    font-size: 13px; text-transform: none; letter-spacing: 0; cursor: pointer;
}
div.dt-container div.dt-paging button.dt-paging-button:hover:not(.disabled):not(.current) {
    background: var(--couleur-survol); color: var(--couleur-principale); border: 0; filter: none;
}
div.dt-container div.dt-paging button.dt-paging-button.current,
div.dt-container div.dt-paging button.dt-paging-button.current:hover {
    background: var(--couleur-principale); color: #fff !important; border: 0; font-weight: 600;
}
div.dt-container div.dt-paging button.dt-paging-button.disabled,
div.dt-container div.dt-paging button.dt-paging-button.disabled:hover {
    background: transparent; color: #bbb !important; border: 0; cursor: default;
}
[data-theme="dark"] div.dt-container div.dt-paging button.dt-paging-button.disabled { color: #555 !important; }

/* ---------- Locations (/locations) ---------- */
/* Onglets pas encore construits (occupation, quittances, annonces) : grisés,
   comme les entrées « Bientôt disponible » du menu */
.tabs-principaux button:disabled,
.tabs-principaux button:disabled:hover { color: #bbb; background: transparent; cursor: default; }
[data-theme="dark"] .tabs-principaux button:disabled,
[data-theme="dark"] .tabs-principaux button:disabled:hover { color: #555; }
/* Ligne de statistiques annuelles au-dessus du tableau (titretabreservations historique) */
.stats-locations { text-align: center; cursor: help; font-size: 14px; margin: 1.5rem 0 .5rem; }
/* Liens des colonnes Source (plateforme) et Nom (fiche Pappers) du tableau des
   réservations : pas de soulignement (comme les autres liens habillés en icône+texte
   de l'app), couleur au survol seulement */
.lien-discret { text-decoration: none; color: inherit; }
.lien-discret:hover { color: var(--couleur-cinq); }
/* Drapeau de nationalité devant le nom (reprend .flag de l'ancienne loc.css) */
.flag { border: 1px solid #ddd; border-radius: 2px; height: 12px; width: 16px; vertical-align: baseline; }
[data-theme="dark"] .flag { border-color: #555; }
/* Ligne dépliée (occupation des parties du bien) : ligne mère mise en évidence,
   saisies compactes centrées (équivalent .shown/.nostyle de l'ancienne page) */
#table-reservations tbody tr.ouverte td { background: var(--couleur-survol); font-weight: 600; }
.occupation-parties { text-align: center; }
.occupation-parties p { margin: .3rem 0 0; }
.occupation-parties table { width: auto; margin: 0 auto; }
.occupation-parties td { text-align: center; padding: .3rem 1rem; }
.occupation-parties input { max-width: 60px; text-align: center; margin-top: .2rem; }
/* Le curseur main ne vaut que sur les lignes dépliables (celles du tableau mère) */
#table-reservations tbody tr[data-id] td { cursor: pointer; }
#table-reservations tbody tr[data-id] td.action { cursor: default; }
/* Onglet Quittances : sections par bien (locations.js, templates/locations/index.php) —
   deux colonnes pour densifier (une section peut être une seule ligne), repli sur une
   colonne au même seuil que le rail latéral (993px, cf. plus haut). */
.grille-quittances { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem 2rem; align-items: start; }
@media screen and (max-width: 993px) {
    .grille-quittances { grid-template-columns: 1fr; }
}
.section-quittances { min-width: 0; }
.titre-bien-quittances { margin: 0 0 .4rem; font-size: .95rem; font-weight: 600; }
.table-quittances tbody tr[data-id] { cursor: pointer; }
.table-quittances tbody tr.ouverte td { background: var(--couleur-survol); font-weight: 600; }
.table-quittances tbody tr.ligne-ciblee td { background: var(--couleur-cinq); color: #fff; transition: background 1.5s, color 1.5s; }
/* Ligne de détail dépliée (quittances de la réservation) : tableau imbriqué compact,
   même esprit que l'ancienne modale qu'elle remplace */
.detail-quittances td { background: none; cursor: default; padding: .5rem 0; }
.quittances-detail { min-width: 320px; margin: 0 auto; }

/* Onglet Occupation : frise vis-timeline (chargée à la demande, cf. locations.js) */
#timeline-occupation { margin: 0 0 1.5rem; min-height: 60px; }
/* Styles de barres repris à l'identique de l'ancienne page (assets/css/loc.css) */
#timeline-occupation .vis-item.resume { background-color: #5a879c82; border-color: #2e85cb; }
#timeline-occupation .vis-item.vis-selected.resume { border-color: rgba(255,0,0,1); }
#timeline-occupation .vis-item.detail { background: rgba(90,135,156,.13); border-color: rgb(171,192,208); }
#timeline-occupation .vis-item.vis-selected.detail { border-color: rgba(255,0,0,1); }
#timeline-occupation .vis-timeline { border: none !important; }
#timeline-occupation .vis-label.vis-nested-group { border: inherit; background-color: inherit !important; }
[data-theme="dark"] #timeline-occupation .vis-labelset,
[data-theme="dark"] #timeline-occupation .vis-panel,
[data-theme="dark"] #timeline-occupation .vis-label,
[data-theme="dark"] #timeline-occupation .vis-time-axis .vis-text { background: #1e1e1e; color: var(--couleur-texte); border-color: #4a4a4a; }
/* Largeur fixe de la colonne des libellés (bien ET partie du bien, même largeur) :
   sans ça, déplier un bien fait apparaître les parties indentées et vis-timeline
   recalcule (agrandit) la largeur du panneau gauche, faisant "sauter" toute la frise.
   !important nécessaire : vis-timeline réécrit la largeur du panneau en style inline
   à chaque rendu, une règle normale perdrait systématiquement face à l'inline. */
#timeline-occupation .vis-panel.vis-left { width: 210px !important; }
/* vis-timeline ne parvient pas à déterminer le niveau d'imbrication réel de nos
   groupes "partie du bien" (classe de repli "vis-group-level-unknown-but-gte1") et
   applique alors, par prudence, l'indentation la plus profonde qu'il connaisse
   (150px de chaque côté) — largement plus que nécessaire pour une hiérarchie à 2
   niveaux, ce qui masquait une bonne partie du libellé dans les 210px du panneau.
   Ramené à l'indentation d'un niveau 1 normal (15px), comme s'il avait été détecté. */
#timeline-occupation .vis-label.vis-group-level-unknown-but-gte1 .vis-inner {
    padding-left: 15px !important; padding-right: 15px !important;
}
.etiquette-groupe { display: inline-block; max-width: 165px; overflow: hidden;
                     white-space: nowrap; text-overflow: ellipsis; vertical-align: middle; }
.icone-groupe { font-size: 13px; }
/* Marqueur de fin de travaux : positionné sur la frise (à sa date, ligne du bien
   concerné) plutôt qu'en badge dans le libellé — le point par défaut de vis-timeline
   (.vis-dot) est masqué, l'icône suffit à se repérer. */
#timeline-occupation .vis-item.marqueur-travaux .vis-dot { display: none; }
#timeline-occupation .vis-item.marqueur-travaux { z-index: 2; }
.fin-travaux { font-size: 18px !important; color: #e65100; cursor: help; background: #fff;
               border-radius: 50%; box-shadow: 0 0 0 2px #fff; }
[data-theme="dark"] .fin-travaux { background: #1e1e1e; box-shadow: 0 0 0 2px #1e1e1e; }
/* Grisé avant l'acquisition / après l'aliénation d'un bien (ligne du bien uniquement) */
#timeline-occupation .vis-item.hors-periode { background: repeating-linear-gradient(
    135deg, rgba(0,0,0,.05), rgba(0,0,0,.05) 6px, rgba(0,0,0,.09) 6px, rgba(0,0,0,.09) 12px); border: none; }
[data-theme="dark"] #timeline-occupation .vis-item.hors-periode { background: repeating-linear-gradient(
    135deg, rgba(255,255,255,.04), rgba(255,255,255,.04) 6px, rgba(255,255,255,.08) 6px, rgba(255,255,255,.08) 12px); }
/* Trait vertical à chaque changement d'année (item très fin, cf. locations.js) */
#timeline-occupation .vis-item.trait-annee { background: #888; border: none; min-width: 1px; z-index: 1; }
[data-theme="dark"] #timeline-occupation .vis-item.trait-annee { background: #999; }

/* ---------- Toasts (app.js:afficheToast) ---------- */
#toasts { position: fixed; bottom: 1.5rem; right: 1.5rem; display: flex; flex-direction: column;
          gap: .5rem; z-index: 1000; max-width: min(420px, calc(100vw - 3rem)); }
#toasts .toast { background: #333; color: #fff; padding: .6rem 1rem; border-radius: 4px;
                 font-size: 14px; box-shadow: 0 2px 8px rgba(0,0,0,.3); cursor: pointer;
                 white-space: pre-line; border-left: 4px solid var(--couleur-principale);
                 opacity: 0; transform: translateY(8px); transition: opacity .25s, transform .25s; }
#toasts .toast.visible { opacity: 1; transform: none; }
#toasts .toast.succes { border-left-color: #2e7d32; }
#toasts .toast.erreur { border-left-color: #c62828; }
[data-theme="dark"] #toasts .toast { background: #2a2a2a; }

/* ---------- Bilan (/bilan) : tableau de répartition, pas de DataTables (mise en
   page à rowspan/couleurs par section, fidèle à l'ancienne page) ---------- */
.bilan-scroll { overflow-x: auto; }
/* Largeur reprise de l'ancienne page (colonnes Materialize s10/l10, centrées) :
   un tableau moins étiré est plus lisible, surtout avec peu de personnes. */
.bilan-table { border-collapse: collapse; width: 83%; min-width: 600px; margin: 0 auto; font-size: 13px; }
.bilan-table td { padding: 6px 10px; border-bottom: 1px solid var(--couleur-bordure); }
.bilan-table h5 { margin: 0; font-size: 15px; font-weight: 600; }
.bilan-table .droite { text-align: right; white-space: nowrap; }
.bilan-table .bold { font-weight: bold; }
.bilan-table .bilan-aide { cursor: help; }
.bilan-table tr.bilan-haut td { border-top: 2px solid var(--couleur-texte); }
.bilan-table tr.bilan-bas td { border-bottom: 2px solid var(--couleur-texte); }
/* Cellule à rowspan de la dernière section (BALANCE TRÉSORERIE) : déclarée dans la
   première ligne du groupe (tr.bilan-haut), elle ne récupère donc pas le bas épais
   de tr.bilan-bas (dernière ligne du tableau) par la seule sélection de ligne. */
.bilan-table td.bilan-fin { border-bottom: 2px solid var(--couleur-texte); }
.bilan-table .bilan-note { font-size: 11px; color: #757575; }
.bilan-table .icone-personne { height: 25px; border-radius: 4px; }
.bilan-entete td { border-bottom: 2px solid var(--couleur-texte); vertical-align: bottom; }
/* Une couleur pastel par section, comme les classes Materialize (light-green/yellow/
   indigo/cyan lighten-4) de l'ancienne page */
.bilan-groupe-investissement { background: #eef7ee; }
.bilan-groupe-exploitation { background: #fdf8e3; }
.bilan-groupe-repartition { background: #ececf7; }
.bilan-groupe-tresorerie { background: #e3f6f8; }
[data-theme="dark"] .bilan-groupe-investissement { background: #1e2a1e; }
[data-theme="dark"] .bilan-groupe-exploitation { background: #2c2814; }
[data-theme="dark"] .bilan-groupe-repartition { background: #23233a; }
[data-theme="dark"] .bilan-groupe-tresorerie { background: #163338; }
[data-theme="dark"] .bilan-table td { border-bottom-color: #4a4a4a; }
[data-theme="dark"] .bilan-table tr.bilan-haut td,
[data-theme="dark"] .bilan-table tr.bilan-bas td,
[data-theme="dark"] .bilan-table td.bilan-fin,
[data-theme="dark"] .bilan-entete td { border-color: var(--couleur-texte); }
[data-theme="dark"] .bilan-table .bilan-note { color: #aaa; }
