:root {
  --color-dashboard: #4338CA;
  --color-dashboard-text: #FFFFFF;
  /* Module Opportunités (pipeline commercial / CRM) — teal « croissance », distinct des autres modules. */
  --color-crm: #6B6B12;
  --color-crm-text: #FFFFFF;
  --color-documents: #1E3A8A;
  --color-documents-text: #FFFFFF;
  --color-e-mails: #DC2626;
  --color-e-mails-text: #FFFFFF;
  --color-taches: #15803D;
  --color-taches-text: #FFFFFF;
  --color-dossiers: #8A6500;      /* encre en thème clair : or foncé (5,3:1 sur blanc) — le jaune de surface y serait illisible */
  --color-dossiers-text: #1D2330;  /* texte SOMBRE sur le jaune « dossier Windows » (07/10/2026) */
  --color-appels: #B5177F; /* magenta (07/10/2026) — la prune se confondait avec les Notes de frais dans le menu */
  --color-appels-text: #FFFFFF;
  --color-agenda: #048297;
  --color-agenda-text: #FFFFFF;
  --color-financier: #2563EB; /* vert foncé = identité du module Financier (texte blanc) */
  --color-financier-text: #ffffff;
  --color-urgent: #DC2626;
  --color-urgent-text: #FFFFFF;
  --color-brouillons: #6B7280;
  --color-brouillons-text: #FFFFFF;
  --color-notes: #DB2777;
  --color-notes-text: #FFFFFF;
  --color-factures: #059669;
  --color-factures-text: #FFFFFF;
  --color-contacts: #7C3AED;
  --color-contacts-text: #FFFFFF;
  --color-temps-passe: #94b9f4;
  --color-temps-passe-text: #000000;
  /* Notes de frais. ⚠️ Un VERT aurait été le choix naturel — c'est de l'argent — mais le vert est
     déjà celui du Financier (#2e7d5b) et des factures (#059669) : la couleur aurait brouillé
     précisément la distinction que l'architecture cherche à tenir. Teinte choisie en mesurant sa
     distance aux treize couleurs de module existantes (la plus éloignée des candidates), et
     vérifiée à 8,02:1 avec le texte blanc du ruban. */
  --color-notesfrais: #881337;
  --color-notesfrais-text: #FFFFFF;
  /* Échéancier RH (migration 152). OCRE DORÉ, et non le fuchsia livré d'abord (#86198F) : mesuré
     sur la teinte de référence, il était loin de tout (ΔE 39,8) — mais le menu ne peint pas la
     teinte. Il la pose en PASTILLE assombrie de 15 % et mélangée à 55 % au fond indigo
     (of-commun.css) : une fois PEINT, le fuchsia n'était plus qu'à ΔE 21,8 des Notes de frais et
     24,9 du fond — deux pastilles violacées côte à côte, confondues (signalé le 2026-09-25).
     Mesuré sur la couleur PEINTE parmi dix-huit candidates : l'ocre est à 37,6 des Notes de frais,
     55,8 du fond, 19,2 du plus proche (les Dossiers, ambre plus clair) ; glyphe blanc 6,01:1 sur la
     pastille, ruban 4,92:1. ⚠️ Toute nouvelle teinte se mesure PEINTE, pas en valeur de référence. */
  --color-echeances: #A16207;
  --color-echeances-text: #FFFFFF;
  /* Interventions (dépannage, SAV — lot B4, 19/10/2026) : brique. Mesurée contre les 17 autres : ΔE 26,8 de la plus proche
     (l'ocre des Échéances), glyphe blanc 7,31:1 ; encre vive #FDBA74 à ΔE 19,8 (Échéances), 6,24:1 sur la barre sombre. */
  --color-interventions: #9A3412;
  --color-interventions-text: #FFFFFF;
  --color-tchat: #A21CAF;
  --color-tchat-text: #FFFFFF;
  --color-documents-original: #3B82F6;
  --color-documents-original-text: #FFFFFF;
  --color-documents-pastel: #dce3ee;
  --color-documents-pastel-text: #000000;
  --color-documents-clair: #a6c2f1;
  --color-documents-clair-text: #000000;
  --color-documents-lumineux: #3280ff;
  --color-documents-lumineux-text: #FFFFFF;
  --color-documents-fonc: #004dcb;
  --color-documents-fonc-text: #FFFFFF;
  --color-documents-sombre: #00307f;
  --color-documents-sombre-text: #FFFFFF;
  --color-documents-tr-s-clair: #eff1f6;
  --color-documents-tr-s-clair-text: #000000;
  --color-documents-d-satur: #8694ab;
  --color-documents-d-satur-text: #000000;
  --color-e-mails-original: #EF4444;
  --color-e-mails-original-text: #FFFFFF;
  --color-e-mails-pastel: #eedddd;
  --color-e-mails-pastel-text: #000000;
  --color-e-mails-clair: #efaaaa;
  --color-e-mails-clair-text: #000000;
  --color-e-mails-lumineux: #ff3434;
  --color-e-mails-lumineux-text: #FFFFFF;
  --color-e-mails-fonc: #c50707;
  --color-e-mails-fonc-text: #FFFFFF;
  --color-e-mails-sombre: #800000;
  --color-e-mails-sombre-text: #FFFFFF;
  --color-e-mails-tr-s-clair: #f5efef;
  --color-e-mails-tr-s-clair-text: #000000;
  --color-e-mails-d-satur: #ab8888;
  --color-e-mails-d-satur-text: #000000;
  --color-taches-original: #10B981;
  --color-taches-original-text: #000000;
  --color-taches-pastel: #99ccbb;
  --color-taches-pastel-text: #000000;
  --color-taches-clair: #54deb0;
  --color-taches-clair-text: #000000;
  --color-taches-lumineux: #00e699;
  --color-taches-lumineux-text: #000000;
  --color-taches-fonc: #045f41;
  --color-taches-fonc-text: #FFFFFF;
  --color-taches-sombre: #001a11;
  --color-taches-sombre-text: #FFFFFF;
  --color-taches-tr-s-clair: #cfe2dc;
  --color-taches-tr-s-clair-text: #000000;
  --color-taches-d-satur: #54756a;
  --color-taches-d-satur-text: #FFFFFF;
  --color-dossiers-original: #F59E0B;
  --color-dossiers-original-text: #000000;
  --color-dossiers-pastel: #dfd1ba;
  --color-dossiers-pastel-text: #000000;
  --color-dossiers-clair: #ebc17b;
  --color-dossiers-clair-text: #000000;
  --color-dossiers-lumineux: #ffa101;
  --color-dossiers-lumineux-text: #000000;
  --color-dossiers-fonc: #9a6100;
  --color-dossiers-fonc-text: #FFFFFF;
  --color-dossiers-sombre: #4e3100;
  --color-dossiers-sombre-text: #FFFFFF;
  --color-dossiers-tr-s-clair: #ede8df;
  --color-dossiers-tr-s-clair-text: #000000;
  --color-dossiers-d-satur: #978669;
  --color-dossiers-d-satur-text: #000000;
  --color-appels-original: #65A30D;
  --color-appels-original-text: #FFFFFF;
  --color-appels-pastel: #ECFCCB;
  --color-appels-pastel-text: #000000;
  --color-appels-clair: #D9F99D;
  --color-appels-clair-text: #000000;
  --color-appels-lumineux: #84CC16;
  --color-appels-lumineux-text: #FFFFFF;
  --color-appels-fonc: #3F6212;
  --color-appels-fonc-text: #FFFFFF;
  --color-appels-sombre: #365314;
  --color-appels-sombre-text: #FFFFFF;
  --color-appels-tr-s-clair: #F7FEE7;
  --color-appels-tr-s-clair-text: #000000;
  --color-appels-d-satur: #8a9a6b;
  --color-appels-d-satur-text: #000000;
  --color-agenda-original: #06B6D4;
  --color-agenda-original-text: #000000;
  --color-agenda-pastel: #9fccd4;
  --color-agenda-pastel-text: #000000;
  --color-agenda-clair: #58d3e8;
  --color-agenda-clair-text: #000000;
  --color-agenda-lumineux: #00c4e6;
  --color-agenda-lumineux-text: #000000;
  --color-agenda-fonc: #006374;
  --color-agenda-fonc-text: #FFFFFF;
  --color-agenda-sombre: #002228;
  --color-agenda-sombre-text: #FFFFFF;
  --color-agenda-tr-s-clair: #cee0e4;
  --color-agenda-tr-s-clair-text: #000000;
  --color-agenda-d-satur: #587c82;
  --color-agenda-d-satur-text: #FFFFFF;
  --color-financier-original: #84CC16;
  --color-financier-original-text: #000000;
  --color-financier-pastel: #c2d3a8;
  --color-financier-pastel-text: #000000;
  --color-financier-clair: #b0df69;
  --color-financier-clair-text: #000000;
  --color-financier-lumineux: #8be600;
  --color-financier-lumineux-text: #000000;
  --color-financier-fonc: #497507;
  --color-financier-fonc-text: #FFFFFF;
  --color-financier-sombre: #1d2f01;
  --color-financier-sombre-text: #FFFFFF;
  --color-financier-tr-s-clair: #dbe2d0;
  --color-financier-tr-s-clair-text: #000000;
  --color-financier-d-satur: #75835f;
  --color-financier-d-satur-text: #FFFFFF;
  --color-urgent-original: #DC2626;
  --color-urgent-original-text: #FFFFFF;
  --color-urgent-pastel: #dcbfbf;
  --color-urgent-pastel-text: #000000;
  --color-urgent-clair: #df8989;
  --color-urgent-clair-text: #000000;
  --color-urgent-lumineux: #f70b0b;
  --color-urgent-lumineux-text: #FFFFFF;
  --color-urgent-fonc: #8c1010;
  --color-urgent-fonc-text: #FFFFFF;
  --color-urgent-sombre: #4a0505;
  --color-urgent-sombre-text: #FFFFFF;
  --color-urgent-tr-s-clair: #ece2e2;
  --color-urgent-tr-s-clair-text: #000000;
  --color-urgent-d-satur: #936f6f;
  --color-urgent-d-satur-text: #FFFFFF;
  --color-brouillons-original: #6B7280;
  --color-brouillons-original-text: #FFFFFF;
  --color-brouillons-pastel: #bcc0c8;
  --color-brouillons-pastel-text: #000000;
  --color-brouillons-clair: #97a3ba;
  --color-brouillons-clair-text: #000000;
  --color-brouillons-lumineux: #2f5ebc;
  --color-brouillons-lumineux-text: #FFFFFF;
  --color-brouillons-fonc: #283a5d;
  --color-brouillons-fonc-text: #FFFFFF;
  --color-brouillons-sombre: #0e182a;
  --color-brouillons-sombre-text: #FFFFFF;
  --color-brouillons-tr-s-clair: #dadbdd;
  --color-brouillons-tr-s-clair-text: #000000;
  --color-brouillons-d-satur: #70747b;
  --color-brouillons-d-satur-text: #FFFFFF;
  --color-notes-original: #EC4899;
  --color-notes-original-text: #000000;
  --color-notes-pastel: #eedde5;
  --color-notes-pastel-text: #000000;
  --color-notes-clair: #edadcd;
  --color-notes-clair-text: #000000;
  --color-notes-lumineux: #ff3599;
  --color-notes-lumineux-text: #FFFFFF;
  --color-notes-fonc: #c10b65;
  --color-notes-fonc-text: #FFFFFF;
  --color-notes-sombre: #7e023f;
  --color-notes-sombre-text: #FFFFFF;
  --color-notes-tr-s-clair: #f5eff2;
  --color-notes-tr-s-clair-text: #000000;
  --color-notes-d-satur: #aa8a9a;
  --color-notes-d-satur-text: #000000;
  --color-factures-original: #059669;
  --color-factures-original-text: #FFFFFF;
  --color-factures-pastel: #96cfbd;
  --color-factures-pastel-text: #000000;
  --color-factures-clair: #4de5b6;
  --color-factures-clair-text: #000000;
  --color-factures-lumineux: #00e69e;
  --color-factures-lumineux-text: #000000;
  --color-factures-fonc: #004d35;
  --color-factures-fonc-text: #FFFFFF;
  --color-factures-sombre: #001a12;
  --color-factures-sombre-text: #FFFFFF;
  --color-factures-tr-s-clair: #cee3dd;
  --color-factures-tr-s-clair-text: #000000;
  --color-factures-d-satur: #3f5c53;
  --color-factures-d-satur-text: #FFFFFF;
  --color-contacts-original: #7C3AED;
  --color-contacts-original-text: #FFFFFF;
  --color-contacts-pastel: #ddd6ea;
  --color-contacts-pastel-text: #000000;
  --color-contacts-clair: #bda1ec;
  --color-contacts-clair-text: #000000;
  --color-contacts-lumineux: #7728ff;
  --color-contacts-lumineux-text: #FFFFFF;
  --color-contacts-fonc: #4908b9;
  --color-contacts-fonc-text: #FFFFFF;
  --color-contacts-sombre: #2b0074;
  --color-contacts-sombre-text: #FFFFFF;
  --color-contacts-tr-s-clair: #f1eff5;
  --color-contacts-tr-s-clair-text: #000000;
  --color-contacts-d-satur: #8f82a5;
  --color-contacts-d-satur-text: #000000;
  --color-temps-passe-original: #94b9f4;
  --color-temps-passe-original-text: #000000;
  --color-temps-passe-pastel: #c8d9f2;
  --color-temps-passe-pastel-text: #000000;
  --color-temps-passe-clair: #b0c8f0;
  --color-temps-passe-clair-text: #000000;
  --color-temps-passe-lumineux: #6a9df2;
  --color-temps-passe-lumineux-text: #000000;
  --color-temps-passe-fonc: #3f6bbd;
  --color-temps-passe-fonc-text: #FFFFFF;
  --color-temps-passe-sombre: #1f3a7f;      
  --color-temps-passe-sombre-text: #FFFFFF;
  --color-temps-passe-tr-s-clair: #e0e6f3;
  --color-temps-passe-tr-s-clair-text: #000000;
  --color-temps-passe-d-satur: #6b7f9c;
  --color-temps-passe-d-satur-text: #FFFFFF;
  --color-tchat-original: #d96a02;
  --color-tchat-original-text: #FFFFFF;
  --color-tchat-pastel: #f2d6c9;
  --color-tchat-pastel-text: #000000;
  --color-tchat-clair: #f2b8a0;
  --color-tchat-clair-text: #000000;
  --color-tchat-lumineux: #ff8f5c;
  --color-tchat-lumineux-text: #000000;
  --color-tchat-fonc: #b34a00;
  --color-tchat-fonc-text: #FFFFFF;
  --color-tchat-sombre: #7f2d00;
  --color-tchat-sombre-text: #FFFFFF;
  --color-tchat-tr-s-clair: #f9e8e0;
  --color-tchat-tr-s-clair-text: #000000;
  --color-tchat-d-satur: #a67b6a;
  --color-tchat-d-satur-text: #000000;

  /* ── Teintes des blocs de la fiche contact qui ne prolongent AUCUN module ──────────────────
     Les autres blocs reprennent la couleur de leur module (Emails, Appels, Notes…) par sa
     variable ci-dessus. Ces deux-là n'ont pas de module derrière eux : leur teinte est CRÉÉE,
     dans la même famille que la palette.

     Elles vivent ICI, avec la palette, parce que DEUX rendus les emploient : la fenêtre de saisie
     (app/contacts/css/custom-styles-contacts.css) et l'onglet Récapitulatif (fiche_contact.php,
     page autonome qui les relit côté PHP via include/utils/palette.php). Recopiées de part et
     d'autre, elles auraient fini par diverger — et le repère de couleur aurait menti d'un écran
     à l'autre, ce qui est pire qu'une absence de couleur. */
  /* ── Encre atténuée : le texte secondaire (sous-titres, horodatages, mentions) ───────────────
     Huit feuilles écrivaient `var(--ct-text-muted, #8a929c)` — ou `#98a6ad` pour les
     notifications. Or `--ct-text-muted` N'EXISTE PAS dans ce thème : c'est la valeur de repli qui
     s'appliquait, toujours, dans les deux thèmes. Rien n'était cassé — juste une couleur figée qui
     ne suivait pas le thème, et un jeton fantôme que chaque copier-coller propageait.

     ⚠️ NE PAS POINTER VERS `--ct-secondary-color` : mesuré, cela AURAIT DÉGRADÉ le contraste
     (3,15 → 3,03 en clair, 3,35 → 3,22 en sombre). Les valeurs ci-dessous sont choisies pour n'être
     jamais moins lisibles qu'avant :
        clair  #767f88 sur blanc   → 4,07:1  (contre 3,15 avec l'ancien repli)
        sombre #a0adb5 sur #37404a → 4,58:1  (contre 3,35)
     Refonte de lisibilité (L1, 13/10/2026) : le clair passe à #5f6a74, l'encre secondaire du
     thème — 5,53:1 sur blanc, 4,97:1 sur le fond de page. Voir le bloc « Encre du thème clair ».
     Au passage, le repli des notifications tombait à 2,50:1 EN THÈME CLAIR — sous le plancher de
     3:1. Personne ne l'avait vu parce que la valeur avait été choisie pour le fond sombre, et
     qu'aucun jeton ne distinguait les deux thèmes. */
  --of-encre-attenuee: #5f6a74;

  --of-teinte-adresses: #0891B2;   /* cyan « carte » — distinct du bleu Documents */
  --of-teinte-liens: #8B5CF6;      /* violet clair : famille Contacts, sans se confondre avec l'Identité */

  /* Ton de l'action « rédiger un email » posée sur une ligne. Dans l'application c'est la classe
     `.text-primary` de Bootstrap (--ct-primary du thème) ; un rendu AUTONOME, lui, n'a pas Bootstrap
     et ne peut pas s'y référer. La valeur est donc redonnée ici — et un test
     (tests/verifier_recap_contact.php) refuse qu'elle s'écarte de --ct-primary : une copie
     surveillée vaut mieux qu'une copie oubliée quand la source ne peut pas être partagée. */
  --of-action-email: #185b8b;   /* = --ct-primary du thème clair (refonte de lisibilité L3) */

  /* ── Repères d'ÉTAT métier, partagés entre le poste et le front mobile ───────────────────────
     Ces teintes disent un état, pas un module : « traité », « urgente ». Elles vivent ici pour la
     même raison que les deux précédentes — DEUX interfaces les emploient désormais, et l'écran du
     téléphone doit dire la même chose que celui du poste. Un utilisateur qui apprend qu'un liseré
     orange signifie « haute » sur son ordinateur ne peut pas découvrir qu'il signifie autre chose
     sur son téléphone : le repère de couleur est une convention, et une convention qui change
     selon l'appareil ne se retient pas.

     ⚠ Ce ne sont PAS les couleurs sémantiques du thème. `--ct-success` vaut #0acf97 (vert menthe)
     et `--ct-danger` #fa5c7c (rose) : s'y référer aurait paru plus propre et aurait donné DEUX
     verts et DEUX rouges différents d'un appareil à l'autre. Les valeurs ci-dessous sont celles
     que le poste affiche déjà, reprises telles quelles depuis app/emails/css/email_inbox.css et
     app/taches/css/taches.css — qui les référencent désormais au lieu de les redonner. */
  --of-etat-traite: #198754;       /* vert « traité » (emails, appels) — Bootstrap success d'origine */
  --of-prio-urgente: #dc3545;
  --of-prio-haute: #fd7e14;
  --of-prio-normale: #4dabf7;
  --of-prio-basse: #adb5bd;
  /* Console SaaS de l’éditeur : dans la palette commune depuis le lot D (05/10/2026) — pastille du menu, ruban, fenêtres. */
  --color-saas: #7E4A86;
  --color-saas-text: #FFFFFF;
  /* Paramètres : dans la palette commune depuis le lot D (05/10/2026) — pastille du menu, ruban, fenêtres. */
  --color-parametres: #55606e;
  --color-parametres-text: #FFFFFF;
}

/* ══ Encre du thème clair — refonte de lisibilité, lot L1 (13/10/2026) ══════════════════════════════════
   Le thème livrait un texte courant GRIS (#6c757d : 4,69:1 sur blanc, 4,22:1 sur le fond de page) et un
   secondaire plus pâle encore (#8a969c : 3,03:1). Mesuré à l'écran par tools/lisibilite : 37,6 % des
   textes du thème clair passaient sous le seuil de 4,5:1. Décision de Pascal : encre ARDOISE.

     rôle                       avant      après     sur blanc   sur #f1f3f7
     texte courant              #6c757d    #2b3440   12,59:1     11,33:1
     emphase (le plus foncé)    gris 75 %  #1d242d   15,64:1     14,08:1
     secondaire (text-muted)    #8a969c    #5f6a74    5,53:1      4,97:1
     tertiaire                  #6c757d    #5f6a74    (aucun gris plus clair ne tient 4,5:1 sur les fonds gris)

   ⚠️ THÈME CLAIR SEULEMENT, et le sélecteur y veille : of-app.css déclare le clair sur
   `:root,[data-bs-theme=light]` et le sombre sur `[data-bs-theme=dark]`, même spécificité. Cette feuille
   étant chargée APRÈS, un `:root { … }` nu primerait AUSSI sur le sombre et y poserait de l'ardoise sur
   ardoise. `:root:not([data-bs-theme=dark])` laisse le sombre intact.
   ⚠️ `--ct-dark` reste la seule encre qui s'inverse d'un thème à l'autre (cf. theme-variables-ct) : ces
   jetons-ci ne valent que pour le clair, le sombre garde les siens. */
:root:not([data-bs-theme="dark"]) {
  --ct-body-color: #2b3440;
  --ct-body-color-rgb: 43, 52, 64;
  --ct-emphasis-color: #1d242d;
  --ct-emphasis-color-rgb: 29, 36, 45;
  --ct-secondary-color: #5f6a74;
  --ct-secondary-color-rgb: 95, 106, 116;
  --ct-tertiary-color: #5f6a74;
  --ct-tertiary-color-rgb: 95, 106, 116;
  --ct-code-color: #0e7490;   /* <code> (comptes du Journal) : #39afd1 faisait 2,55:1 sur blanc */
}

/* ══ Surfaces du thème clair — refonte de lisibilité, lot L2 (13/10/2026) ════════════════════════════════
   Le fond de page (#fafbfe) et les cartes (blanches, SANS bordure, ombre diffuse à 15 %) étaient presque de la
   même valeur : les blocs se fondaient dans la page. Le fond passe à un gris-bleu visible et la carte prend un
   filet de 1 px, une ombre courte et des coins de 8 px — le dessin des cartes du tableau de bord, déjà là.
   ⚠️ Mêmes bornes que l'encre : le sombre n'est pas touché.
   ⚠️ `:where()` pour la carte : sa spécificité reste celle d'un `.card` nu (0,1,0). Le thème ANNULE l'ombre dans
   certains contextes (`… .card { box-shadow: none }`, plus spécifiques) ; une règle plus forte les écraserait. */
:root:not([data-bs-theme="dark"]) {
  --ct-body-bg: #f1f3f7;
  --ct-body-bg-rgb: 241, 243, 247;
}
:where(:root:not([data-bs-theme="dark"])) .card {
  --ct-card-border-width: 1px;
  --ct-card-border-color: #dfe4eb;
  --ct-card-border-radius: .5rem;
  --ct-card-inner-border-radius: calc(.5rem - 1px);
  box-shadow: 0 1px 2px rgba(16, 24, 40, .05);
}

/* ══ Couleurs d'action du thème clair — refonte de lisibilité, lot L3 (13/10/2026) ═══════════════════════════
   Les couleurs sémantiques du thème étaient trop pâles pour porter du texte : texte blanc sur le bouton
   principal lavande #727cf5 à 3,55:1, sur le rouge #fa5c7c à 3,05:1, sur le vert #0acf97 à 2,0:1. Décision de
   Pascal : le bleu acier A, #185b8b (7,22:1 ; ΔE2000 ≥ 12,1 avec chacune des 17 couleurs de modules).

     rôle        avant      après     blanc dessus   en encre sur #f1f3f7
     principal   #727cf5    #185b8b   7,22:1         6,50:1   (liens compris)
     secondaire  #6c757d    #5f6a74   5,53:1         4,97:1
     succès      #0acf97    #157347   5,87:1         5,29:1   (= sens « entrant » des appels, déjà mesuré)
     info        #39afd1    #0e7490   5,36:1         4,82:1
     danger      #fa5c7c    #c62828   5,62:1         5,06:1   (= sens « sortant » des appels)
   L'orange d'avertissement ne change pas : il porte un texte FONCÉ (cf. verifier_contraste_couleurs).

   ⚠️ Bootstrap COMPILE les couleurs des boutons et de plusieurs composants en valeurs littérales : redéfinir
   --ct-primary ne repeint ni `.btn-primary`, ni la case cochée, ni la pagination. D'où les redéfinitions
   composant par composant ci-dessous, toutes sous `:where()` (spécificité du composant nu).
   ⚠️ Thème clair seulement ; le sombre aura son propre lot (contraste du sombre, validé le 13/10). */
:root:not([data-bs-theme="dark"]) {
  --ct-primary: #185b8b;      --ct-primary-rgb: 24, 91, 139;
  --ct-secondary: #5f6a74;    --ct-secondary-rgb: 95, 106, 116;
  --ct-success: #157347;      --ct-success-rgb: 21, 115, 71;
  --ct-info: #0e7490;         --ct-info-rgb: 14, 116, 144;
  --ct-danger: #c62828;       --ct-danger-rgb: 198, 40, 40;
  --ct-link-color: #185b8b;   --ct-link-color-rgb: 24, 91, 139;
  --ct-link-hover-color: #134a70; --ct-link-hover-color-rgb: 19, 74, 112;
  --ct-primary-text-emphasis: #0f3a59;
  --ct-primary-bg-subtle: #e8f0f6;
  --ct-primary-border-subtle: #b6cde0;
  --ct-indigo: #185b8b;
}
:where(:root:not([data-bs-theme="dark"])) .btn-primary {
  --ct-btn-bg: #185b8b; --ct-btn-border-color: #185b8b;
  --ct-btn-hover-bg: #134a70; --ct-btn-hover-border-color: #134a70;
  --ct-btn-active-bg: #134a70; --ct-btn-active-border-color: #134a70;
  --ct-btn-focus-shadow-rgb: 24, 91, 139;
}
:where(:root:not([data-bs-theme="dark"])) .btn-outline-primary {
  --ct-btn-color: #185b8b; --ct-btn-border-color: #185b8b;
  --ct-btn-hover-bg: #185b8b; --ct-btn-hover-border-color: #185b8b;
  --ct-btn-active-bg: #185b8b; --ct-btn-active-border-color: #185b8b;
  --ct-btn-disabled-color: #185b8b; --ct-btn-disabled-border-color: #185b8b;
  --ct-btn-focus-shadow-rgb: 24, 91, 139;
}
:where(:root:not([data-bs-theme="dark"])) .btn-secondary {
  --ct-btn-bg: #5f6a74; --ct-btn-border-color: #5f6a74;
  --ct-btn-hover-bg: #4f5962; --ct-btn-hover-border-color: #4f5962;
  --ct-btn-active-bg: #4f5962; --ct-btn-active-border-color: #4f5962;
  --ct-btn-focus-shadow-rgb: 95, 106, 116;
}
:where(:root:not([data-bs-theme="dark"])) .btn-outline-secondary {
  --ct-btn-color: #5f6a74; --ct-btn-border-color: #5f6a74;
  --ct-btn-hover-bg: #5f6a74; --ct-btn-hover-border-color: #5f6a74;
  --ct-btn-active-bg: #5f6a74; --ct-btn-active-border-color: #5f6a74;
  --ct-btn-disabled-color: #5f6a74; --ct-btn-disabled-border-color: #5f6a74;
  --ct-btn-focus-shadow-rgb: 95, 106, 116;
}
:where(:root:not([data-bs-theme="dark"])) .btn-success {
  --ct-btn-bg: #157347; --ct-btn-border-color: #157347;
  --ct-btn-hover-bg: #115d39; --ct-btn-hover-border-color: #115d39;
  --ct-btn-active-bg: #115d39; --ct-btn-active-border-color: #115d39;
  --ct-btn-focus-shadow-rgb: 21, 115, 71;
}
:where(:root:not([data-bs-theme="dark"])) .btn-outline-success {
  --ct-btn-color: #157347; --ct-btn-border-color: #157347;
  --ct-btn-hover-bg: #157347; --ct-btn-hover-border-color: #157347;
  --ct-btn-active-bg: #157347; --ct-btn-active-border-color: #157347;
  --ct-btn-disabled-color: #157347; --ct-btn-disabled-border-color: #157347;
  --ct-btn-focus-shadow-rgb: 21, 115, 71;
}
:where(:root:not([data-bs-theme="dark"])) .btn-info {
  --ct-btn-bg: #0e7490; --ct-btn-border-color: #0e7490;
  --ct-btn-hover-bg: #0b5d73; --ct-btn-hover-border-color: #0b5d73;
  --ct-btn-active-bg: #0b5d73; --ct-btn-active-border-color: #0b5d73;
  --ct-btn-focus-shadow-rgb: 14, 116, 144;
}
:where(:root:not([data-bs-theme="dark"])) .btn-outline-info {
  --ct-btn-color: #0e7490; --ct-btn-border-color: #0e7490;
  --ct-btn-hover-bg: #0e7490; --ct-btn-hover-border-color: #0e7490;
  --ct-btn-active-bg: #0e7490; --ct-btn-active-border-color: #0e7490;
  --ct-btn-disabled-color: #0e7490; --ct-btn-disabled-border-color: #0e7490;
  --ct-btn-focus-shadow-rgb: 14, 116, 144;
}
:where(:root:not([data-bs-theme="dark"])) .btn-danger {
  --ct-btn-bg: #c62828; --ct-btn-border-color: #c62828;
  --ct-btn-hover-bg: #a82020; --ct-btn-hover-border-color: #a82020;
  --ct-btn-active-bg: #a82020; --ct-btn-active-border-color: #a82020;
  --ct-btn-focus-shadow-rgb: 198, 40, 40;
}
:where(:root:not([data-bs-theme="dark"])) .btn-outline-danger {
  --ct-btn-color: #c62828; --ct-btn-border-color: #c62828;
  --ct-btn-hover-bg: #c62828; --ct-btn-hover-border-color: #c62828;
  --ct-btn-active-bg: #c62828; --ct-btn-active-border-color: #c62828;
  --ct-btn-disabled-color: #c62828; --ct-btn-disabled-border-color: #c62828;
  --ct-btn-focus-shadow-rgb: 198, 40, 40;
}
:where(:root:not([data-bs-theme="dark"])) .form-check-input:checked,
:where(:root:not([data-bs-theme="dark"])) .form-check-input[type=checkbox]:indeterminate { background-color: #185b8b; border-color: #185b8b; }
:where(:root:not([data-bs-theme="dark"])) .form-range::-webkit-slider-thumb { background-color: #185b8b; }
:where(:root:not([data-bs-theme="dark"])) .form-range::-moz-range-thumb { background-color: #185b8b; }
:where(:root:not([data-bs-theme="dark"])) .nav-pills { --ct-nav-pills-link-active-bg: #185b8b; }
:where(:root:not([data-bs-theme="dark"])) .pagination { --ct-pagination-active-bg: #185b8b; --ct-pagination-active-border-color: #185b8b; }
:where(:root:not([data-bs-theme="dark"])) :is(.progress, .progress-stacked) { --ct-progress-bar-bg: #185b8b; }
:where(:root:not([data-bs-theme="dark"])) .list-group { --ct-list-group-active-bg: #185b8b; --ct-list-group-active-border-color: #185b8b; }
:where(:root:not([data-bs-theme="dark"])) input[data-switch=primary]:checked + label { background-color: #185b8b; }
/* Agenda : le thème force l'encre des événements « bg-primary-subtle » en #727cf5 avec !important. */
:root:not([data-bs-theme="dark"]) :is(.fc-daygrid-event.bg-primary-subtle .fc-event-main, .fc-daygrid-event.bg-primary-subtle .fc-event-title,
  .fc-timegrid-event.bg-primary-subtle .fc-event-title, .fc-list-event.bg-primary-subtle, .fc-list-event.bg-primary-subtle .fc-list-event-title > a) { color: #185b8b !important; }
:root:not([data-bs-theme="dark"]) .fc-list-event.bg-primary-subtle .fc-list-event-dot { border-color: #185b8b; }

/* ── AVERTISSEMENT (jaune) — oublié en L3, signalé par Pascal le 14/10/2026 sur les fenêtres de pièce et de facture reçue
   (« Avoir », « Annuler », « Reçue » illisibles). L'aplat jaune #ffc35a porte un texte FONCÉ (9,7:1) — mais le thème y
   mettait du BLANC (1,59:1) sur `.btn-warning`, et l'employait comme ENCRE sur blanc (1,59:1) pour le contour et
   `.text-warning`. En clair, l'encre devient un ambre foncé #975a00 (5,6:1 sur blanc, 5,0:1 sur le fond de page) ;
   l'aplat garde son jaune, avec une encre foncée, dans les DEUX thèmes. En sombre, le jaune en encre se lit (fond sombre). */
.btn-warning {
  --ct-btn-color: #212529; --ct-btn-hover-color: #212529; --ct-btn-active-color: #212529; --ct-btn-disabled-color: #212529;
}
.btn-outline-warning { --ct-btn-hover-color: #212529; --ct-btn-active-color: #212529; }
:where(:root:not([data-bs-theme="dark"])) .btn-outline-warning {
  --ct-btn-color: #975a00; --ct-btn-border-color: #975a00;
  --ct-btn-disabled-color: #975a00; --ct-btn-disabled-border-color: #975a00;
}
:root:not([data-bs-theme="dark"]) .text-warning { color: #975a00 !important; }
/* Badge « allégé » jaune (compteur d'un dossier d'emails) : même encre, il faisait 1,52:1 sur son fond pâle. */
:root:not([data-bs-theme="dark"]) .badge-warning-lighten { color: #975a00 !important; }
/* Même famille : `.btn-outline-light` (jours de la récurrence d'un événement, non cochés) écrit en quasi-blanc — invisible
   sur une fenêtre blanche. En clair : encre du texte, contour gris ; le sombre garde sa valeur (elle y est faite pour). */
:where(:root:not([data-bs-theme="dark"])) .btn-outline-light {
  --ct-btn-color: var(--ct-body-color); --ct-btn-border-color: #cfd6df;
  --ct-btn-hover-color: var(--ct-body-color); --ct-btn-hover-bg: #eef1f5; --ct-btn-hover-border-color: #b9c2cd;
}

/* Badges succès / info : of-commun.css leur FORCE une encre foncée (#212529 !important), juste tant que leurs
   fonds étaient pâles (menthe, cyan). Sur les fonds de L3, foncés, cette encre tomberait à ~2,6:1 : en clair,
   l'encre redevient blanche (5,87:1 sur #157347, 5,36:1 sur #0e7490). Le sombre garde ses fonds pâles et
   l'encre foncée. L'avertissement (ambre, inchangé) garde son encre foncée dans les deux thèmes. */
:root:not([data-bs-theme="dark"]) :is(.badge.bg-success, .bg-success.text-dark, .bg-success.text-white, .text-bg-success,
                                      .badge.bg-info, .bg-info.text-dark, .bg-info.text-white, .text-bg-info) { color: #fff !important; }

/* Un bouton DÉSACTIVÉ se lit comme tel : gris franc. Le thème le rendait en sa couleur à 65 % d'opacité — un
   bouton principal inactif ressemblait à un bouton principal clair (« Enregistrer », « Générer les relances »).
   La WCAG exempte un contrôle inactif du seuil de contraste ; le gris choisi reste lisible (4,0:1). */
:where(:root:not([data-bs-theme="dark"])) .btn:is(:disabled, .disabled):not(.btn-link) {
  background-color: #eceff3; border-color: #dde2e8; color: #66707a; opacity: 1; box-shadow: none;
}

/* Aplats à TEXTE BLANC des modules (onglet actif, pastille de compte, bouton rond…) : ils lisent --of-aplat-*, qui vaut
   la couleur d'action dans le clair et un aplat FONCÉ dans le sombre (où --ct-* devient une ENCRE claire, voir plus bas). */
:root {
  --of-aplat-primary: #185b8b; --of-aplat-secondary: #5f6a74; --of-aplat-success: #157347;
  --of-aplat-info: #0e7490; --of-aplat-danger: #c62828;
}

/* ══ Contraste du thème SOMBRE — refonte de lisibilité (14/10/2026, lot validé par Pascal le 13/10) ══════════════════
   Mesuré à l'écran (tools/lisibilite) : 25 % des textes du sombre sous 4,5:1. Trois causes :
     1. l'encre secondaire #8391a2 (3,3:1 sur les cartes) — petits textes, dates, onglets, icônes de la barre ;
     2. les couleurs d'action : texte blanc sur le lavande (3,55:1) et sur le rouge (3,05:1) ;
     3. quelques gris en dur dans les modules (traités dans leurs feuilles).

   ⚠️ LE PIÈGE DU SOMBRE : une même couleur ne peut pas être À LA FOIS un FOND sous un texte blanc (il la faut foncée)
   et une ENCRE sur un fond sombre (il la faut claire). Le thème le faisait avec une seule valeur, moyenne, qui ratait
   les deux. On SÉPARE : --ct-primary / -danger / -success / -info / -secondary deviennent des ENCRES (liens, text-*, les
   ~60 couleurs de texte des modules) ; les aplats (boutons, badges, bg-*, cases, pagination…) lisent des valeurs
   foncées, ici et dans --of-aplat-*.

     rôle          encre (sur #37404a)   aplat (texte blanc)
     texte         #dde3ea  8,2:1        —
     secondaire    #b8c3ce  5,9:1        #5f6a74  5,5:1
     principal     #9ccbec  6,1:1        #1f6aa5  5,7:1   (bleu A éclairci pour rester visible sur le fond sombre)
     succès        #6fd8a0  6,0:1        #157347  5,9:1
     info          #7dd3e6  6,2:1        #0e7490  5,4:1
     danger        #ffa59d  5,6:1        #c62828  5,6:1
   Pire fond retenu : #464f5b (en-têtes de tableau) — chaque encre y tient 4,4:1 ou mieux. */
:root[data-bs-theme="dark"] {
  --ct-body-color: #dde3ea;       --ct-body-color-rgb: 221, 227, 234;
  --ct-emphasis-color: #eef2f6;   --ct-emphasis-color-rgb: 238, 242, 246;
  --ct-secondary-color: #b8c3ce;  --ct-secondary-color-rgb: 184, 195, 206;
  --ct-tertiary-color: #b8c3ce;   --ct-tertiary-color-rgb: 184, 195, 206;
  --ct-heading-color: #eef2f6;
  --ct-primary: #9ccbec;   --ct-primary-rgb: 156, 203, 236;
  --ct-secondary: #b8c3ce; --ct-secondary-rgb: 184, 195, 206;
  --ct-success: #6fd8a0;   --ct-success-rgb: 111, 216, 160;
  --ct-info: #7dd3e6;      --ct-info-rgb: 125, 211, 230;
  --ct-danger: #ffa59d;    --ct-danger-rgb: 255, 165, 157;
  --ct-link-color: #9ccbec; --ct-link-color-rgb: 156, 203, 236;
  --ct-link-hover-color: #c0def2; --ct-link-hover-color-rgb: 192, 222, 242;
  --ct-indigo: #9ccbec;
  --ct-primary-text-emphasis: #c0def2;   /* bandeaux de groupes (Documents) : était le lavande #aab0f9 */
  --ct-code-color: #7dd3e6;
  --of-aplat-primary: #1f6aa5; --of-aplat-secondary: #5f6a74; --of-aplat-success: #157347;
  --of-aplat-info: #0e7490; --of-aplat-danger: #c62828;
}
/* FullCalendar peint ses boutons avec --ct-primary SOUS un texte blanc : dans l'agenda, le primaire redevient l'APLAT
   (1,73:1 sinon — vu à l'écran sur les boutons Année / Mois / Semaine). */
:root[data-bs-theme="dark"] .fc { --ct-primary: #1f6aa5; --ct-primary-rgb: 31, 106, 165; }
/* Même cas, relevé par tests/verifier_lisibilite_sombre.php dans la feuille du thème : des composants qui peignent un
   APLAT à texte blanc avec les couleurs sémantiques — avatars à initiales, étiquettes et options de Select2, sélecteur
   de dates, info-bulle de DataTables. Dans ces conteneurs, le sombre leur rend leurs valeurs d'aplat. */
:root[data-bs-theme="dark"] :is(.avatar-title, .select2-container, .daterangepicker, div.dt-button-info) {
  --ct-primary: #1f6aa5;   --ct-primary-rgb: 31, 106, 165;
  --ct-secondary: #5f6a74; --ct-secondary-rgb: 95, 106, 116;
  --ct-success: #157347;   --ct-success-rgb: 21, 115, 71;
  --ct-info: #0e7490;      --ct-info-rgb: 14, 116, 144;
  --ct-danger: #c62828;    --ct-danger-rgb: 198, 40, 40;
}
/* Effectif d'un groupe de Documents (« Hier · 6 ») : la pastille mêle 25 % de l'encre CLAIRE du primaire au fond, assez
   pour que #c0def2 n'y fasse plus que 3,6:1 — en blanc, 5,1:1. */
:root[data-bs-theme="dark"] .of-liste-groupe-nb { color: #fff; }
/* Barre du haut sombre : icônes et fil d'Ariane (#8391a2 : 2,9:1 sur #3a444e). */
html[data-bs-theme="dark"][data-topbar-color="dark"] { --ct-topbar-item-color: #b8c3ce; --ct-topbar-item-hover-color: #ffffff; }
:root[data-bs-theme="dark"] { --of-barre-fil: #b8c3ce; }
:where(:root[data-bs-theme="dark"]) .btn-primary {
  --ct-btn-bg: #1f6aa5; --ct-btn-border-color: #1f6aa5; --ct-btn-color: #fff;
  --ct-btn-hover-bg: #2471ad; --ct-btn-hover-border-color: #2471ad; --ct-btn-hover-color: #fff;
  --ct-btn-active-bg: #2471ad; --ct-btn-active-border-color: #2471ad; --ct-btn-focus-shadow-rgb: 31, 106, 165;
}
:where(:root[data-bs-theme="dark"]) .btn-outline-primary {
  --ct-btn-color: #9ccbec; --ct-btn-border-color: #9ccbec;
  --ct-btn-hover-bg: #1f6aa5; --ct-btn-hover-border-color: #1f6aa5; --ct-btn-hover-color: #fff;
  --ct-btn-active-bg: #1f6aa5; --ct-btn-active-border-color: #1f6aa5; --ct-btn-active-color: #fff;
  --ct-btn-disabled-color: #9ccbec; --ct-btn-disabled-border-color: #9ccbec; --ct-btn-focus-shadow-rgb: 31, 106, 165;
}
:where(:root[data-bs-theme="dark"]) .btn-secondary {
  --ct-btn-bg: #5f6a74; --ct-btn-border-color: #5f6a74; --ct-btn-color: #fff;
  --ct-btn-hover-bg: #68737e; --ct-btn-hover-border-color: #68737e; --ct-btn-hover-color: #fff;
  --ct-btn-active-bg: #68737e; --ct-btn-active-border-color: #68737e; --ct-btn-focus-shadow-rgb: 95, 106, 116;
}
:where(:root[data-bs-theme="dark"]) .btn-outline-secondary {
  --ct-btn-color: #b8c3ce; --ct-btn-border-color: #b8c3ce;
  --ct-btn-hover-bg: #5f6a74; --ct-btn-hover-border-color: #5f6a74; --ct-btn-hover-color: #fff;
  --ct-btn-active-bg: #5f6a74; --ct-btn-active-border-color: #5f6a74; --ct-btn-active-color: #fff;
  --ct-btn-disabled-color: #b8c3ce; --ct-btn-disabled-border-color: #b8c3ce; --ct-btn-focus-shadow-rgb: 95, 106, 116;
}
:where(:root[data-bs-theme="dark"]) .btn-success {
  --ct-btn-bg: #157347; --ct-btn-border-color: #157347; --ct-btn-color: #fff;
  --ct-btn-hover-bg: #188050; --ct-btn-hover-border-color: #188050; --ct-btn-hover-color: #fff;
  --ct-btn-active-bg: #188050; --ct-btn-active-border-color: #188050; --ct-btn-focus-shadow-rgb: 21, 115, 71;
}
:where(:root[data-bs-theme="dark"]) .btn-outline-success {
  --ct-btn-color: #6fd8a0; --ct-btn-border-color: #6fd8a0;
  --ct-btn-hover-bg: #157347; --ct-btn-hover-border-color: #157347; --ct-btn-hover-color: #fff;
  --ct-btn-active-bg: #157347; --ct-btn-active-border-color: #157347; --ct-btn-active-color: #fff;
  --ct-btn-disabled-color: #6fd8a0; --ct-btn-disabled-border-color: #6fd8a0; --ct-btn-focus-shadow-rgb: 21, 115, 71;
}
:where(:root[data-bs-theme="dark"]) .btn-info {
  --ct-btn-bg: #0e7490; --ct-btn-border-color: #0e7490; --ct-btn-color: #fff;
  --ct-btn-hover-bg: #107f9c; --ct-btn-hover-border-color: #107f9c; --ct-btn-hover-color: #fff;
  --ct-btn-active-bg: #107f9c; --ct-btn-active-border-color: #107f9c; --ct-btn-focus-shadow-rgb: 14, 116, 144;
}
:where(:root[data-bs-theme="dark"]) .btn-outline-info {
  --ct-btn-color: #7dd3e6; --ct-btn-border-color: #7dd3e6;
  --ct-btn-hover-bg: #0e7490; --ct-btn-hover-border-color: #0e7490; --ct-btn-hover-color: #fff;
  --ct-btn-active-bg: #0e7490; --ct-btn-active-border-color: #0e7490; --ct-btn-active-color: #fff;
  --ct-btn-disabled-color: #7dd3e6; --ct-btn-disabled-border-color: #7dd3e6; --ct-btn-focus-shadow-rgb: 14, 116, 144;
}
:where(:root[data-bs-theme="dark"]) .btn-danger {
  --ct-btn-bg: #c62828; --ct-btn-border-color: #c62828; --ct-btn-color: #fff;
  --ct-btn-hover-bg: #cf3030; --ct-btn-hover-border-color: #cf3030; --ct-btn-hover-color: #fff;
  --ct-btn-active-bg: #cf3030; --ct-btn-active-border-color: #cf3030; --ct-btn-focus-shadow-rgb: 198, 40, 40;
}
:where(:root[data-bs-theme="dark"]) .btn-outline-danger {
  --ct-btn-color: #ffa59d; --ct-btn-border-color: #ffa59d;
  --ct-btn-hover-bg: #c62828; --ct-btn-hover-border-color: #c62828; --ct-btn-hover-color: #fff;
  --ct-btn-active-bg: #c62828; --ct-btn-active-border-color: #c62828; --ct-btn-active-color: #fff;
  --ct-btn-disabled-color: #ffa59d; --ct-btn-disabled-border-color: #ffa59d; --ct-btn-focus-shadow-rgb: 198, 40, 40;
}
:where(:root[data-bs-theme="dark"]) :is(.bg-primary, .text-bg-primary) { background-color: #1f6aa5 !important; }
:where(:root[data-bs-theme="dark"]) :is(.bg-secondary, .text-bg-secondary) { background-color: #5f6a74 !important; }
:where(:root[data-bs-theme="dark"]) :is(.bg-success, .text-bg-success) { background-color: #157347 !important; }
:where(:root[data-bs-theme="dark"]) :is(.bg-info, .text-bg-info) { background-color: #0e7490 !important; }
:where(:root[data-bs-theme="dark"]) :is(.bg-danger, .text-bg-danger) { background-color: #c62828 !important; }
/* Badges succès / info : of-commun.css leur force une encre FONCÉE (fonds pâles d'origine) ; leurs aplats sombres sont
   désormais foncés → encre blanche, comme en clair. */
:root[data-bs-theme="dark"] :is(.badge.bg-success, .bg-success.text-dark, .bg-success.text-white, .text-bg-success,
                                .badge.bg-info, .bg-info.text-dark, .bg-info.text-white, .text-bg-info) { color: #fff !important; }
:where(:root[data-bs-theme="dark"]) .form-check-input:checked,
:where(:root[data-bs-theme="dark"]) .form-check-input[type=checkbox]:indeterminate { background-color: #1f6aa5; border-color: #1f6aa5; }
:where(:root[data-bs-theme="dark"]) .form-range::-webkit-slider-thumb { background-color: #9ccbec; }
:where(:root[data-bs-theme="dark"]) .form-range::-moz-range-thumb { background-color: #9ccbec; }
:where(:root[data-bs-theme="dark"]) .nav-pills { --ct-nav-pills-link-active-bg: #1f6aa5; }
:where(:root[data-bs-theme="dark"]) .pagination { --ct-pagination-active-bg: #1f6aa5; --ct-pagination-active-border-color: #1f6aa5; }
:where(:root[data-bs-theme="dark"]) :is(.progress, .progress-stacked) { --ct-progress-bar-bg: #1f6aa5; }
:where(:root[data-bs-theme="dark"]) .list-group { --ct-list-group-active-bg: #1f6aa5; --ct-list-group-active-border-color: #1f6aa5; }
:where(:root[data-bs-theme="dark"]) input[data-switch=primary]:checked + label { background-color: #1f6aa5; }
:root[data-bs-theme="dark"] :is(.fc-daygrid-event.bg-primary-subtle .fc-event-main, .fc-daygrid-event.bg-primary-subtle .fc-event-title,
  .fc-timegrid-event.bg-primary-subtle .fc-event-title, .fc-list-event.bg-primary-subtle, .fc-list-event.bg-primary-subtle .fc-list-event-title > a) { color: #9ccbec !important; }
/* Bouton désactivé du sombre : gris franc, opaque, sans halo (comme en clair). */
:where(:root[data-bs-theme="dark"]) .btn:is(:disabled, .disabled):not(.btn-link) {
  background-color: #464f5b; border-color: #525c69; color: #aab4bf; opacity: 1; box-shadow: none;
}

/* ══ Titre dans la barre du haut — refonte de lisibilité, lot L6 (13/10/2026) ═══════════════════════════════════
   Décision de Pascal : le titre du module (icône, nom, fil d'Ariane) monte dans la barre du haut, à la même place
   dans les DEUX thèmes ; l'étiquette colorée sous la barre disparaît, la barre d'outils de la page reste.
   Mécanique : include/utils/ruban.php (le script qui remplit #of-titre-page et pose html.of-titre-monte).
   En thème CLAIR la barre devient BLANCHE (filet en bas) ; en sombre elle reste sombre.

   ⚠️ Les encres « vives » des modules (--color-<m>-vif) ont été choisies parce que « la barre du haut est toujours
   sombre ». Sur la barre blanche elles seraient des pastels illisibles : les icônes de la barre lisent désormais
   --of-barre-<m>, vive en sombre, teinte de surface en clair (Financier 5,17:1, Documents 10,4:1, Notes 4,6:1).

     encre                      clair                  sombre (sur #3a444e)
     titre                      #1d242d  15,6:1        #f1f4f8  9,0:1
     fil d'Ariane, icônes       #5f6a74   5,5:1        #aab8c5  4,9:1  (les icônes gardent #8391a2 : lot du sombre) */
:root {
  --of-barre-titre: #f1f4f8;
  --of-barre-fil: #aab8c5;
  --of-barre-financier: var(--color-financier-vif);
  --of-barre-documents: var(--color-documents-vif);
  --of-barre-notes: var(--color-notes-vif);
}
html:not([data-bs-theme="dark"])[data-topbar-color="dark"] {
  --ct-topbar-bg: #ffffff;
  --ct-topbar-item-color: #5f6a74;
  --ct-topbar-item-hover-color: #185b8b;
  --ct-topbar-search-bg: #f1f3f7;
  --ct-topbar-user-bg: #ffffff;
  --ct-topbar-user-border: #e3e7ed;
  --of-barre-titre: #1d242d;
  --of-barre-fil: #5f6a74;
  --of-barre-financier: var(--color-financier-fond);
  --of-barre-documents: var(--color-documents-fond);
  --of-barre-notes: var(--color-notes-fond);
}
html:not([data-bs-theme="dark"])[data-topbar-color="dark"] .navbar-custom { border-bottom: 1px solid #e3e7ed; }

.of-titre-page { display: flex; align-items: center; gap: .7rem; min-width: 0; margin-left: .25rem; }
.of-titre-page[hidden], .of-titre-fil[hidden] { display: none; }
.of-titre-ico {
  flex: none; width: 34px; height: 34px; border-radius: 8px; display: grid; place-items: center;
  background: var(--of-titre-fond); color: var(--of-titre-encre); font-size: 1.15rem; line-height: 1;
}
.of-titre-textes { display: flex; flex-direction: column; min-width: 0; line-height: 1.15; }
.of-titre-nom {
  font-size: 1.25rem; font-weight: 800; letter-spacing: -.01em; color: var(--of-barre-titre);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.of-titre-fil { font-size: .78rem; font-weight: 600; color: var(--of-barre-fil); white-space: nowrap; }
/* Un titre LONG (nom d'un Dossier, d'un contact) se tronque en « … » : c'est lui qui cède la place, pas les icônes
   ni l'utilisateur à droite (mesuré à 1024 px : « Julie Lefev » rogné par le bord de l'écran). */
.navbar-custom .topbar > div:has(> #of-titre-page) { min-width: 0; flex: 1 1 auto; }
.navbar-custom .topbar > .topbar-menu { flex: none; }
/* Le titre est monté : la date et l'heure lui cèdent la place, l'étiquette sous la barre disparaît, et son filet de
   couleur aussi (posé EN LIGNE sur chaque page, d'où !important). Un cadre qui ne portait QUE l'étiquette (pas de
   barre d'outils) ne laisse pas une bande vide. */
html.of-titre-monte #datetime { display: none !important; }
html.of-titre-monte .module-ribbon { display: none; }
html.of-titre-monte .module-ribbon-box { border-bottom-color: transparent !important; }
html.of-titre-monte .module-ribbon-box:not(:has(> :not(.module-ribbon, script))) { display: none; }
/* Page d'un objet (Dossier, contact) : le nom est monté dans la barre, le bandeau ne le répète pas (of_titre_objet). */
html.of-titre-monte .of-titre-double { display: none !important; }

/* ── Palette des modules (audit d'uniformité, lot D — décisions de Pascal, 05/10/2026) ───────────────────────────────
   Chaque module porte un texte BLANC lisible sur sa couleur (≥ 4,5:1 ; Temps passé : texte NOIR sur bleu clair, 10:1),
   et chaque couleur se distingue de toutes les autres (ΔE2000 ≥ 9,4 — le maximum atteignable pour 17 teintes soutenues ;
   paires les plus proches : Tableau de bord / Contacts, Dossiers / Emails). Proposition « B » retenue, Documents en bleu
   marine (« les couleurs de Word ») et Financier en bleu vif ; un seul vert (Tâches) ; Opportunités en kaki, Appels en
   prune, Tchat en fuchsia. Comparatif : https://claude.ai/artifact/8fsAU7u3rXX3iX1MrJ9516
   Deux jetons par module :
     · `--color-<m>-fond` — une SURFACE qui porte du texte (ruban, en-tête de fenêtre, pastille du menu, bouton plein,
       onglet actif) : toujours la teinte soutenue, dans les deux thèmes ;
     · `--color-<m>` — l'ENCRE (icône, lien, bordure, point, teinte légère par color-mix) : la même teinte en thème
       clair, ÉCLAIRCIE en thème sombre (≥ 4,5:1 sur le fond) — soutenue, elle s'y perdait (1,6 à 2,3:1).
   ⚠️ Un nouveau fond plein à texte blanc lit `-fond` ; une nouvelle teinte se mesure contre les VOISINES (ΔE), pas
   seulement contre le blanc (tests/verifier_uniformite_lot_d.php). */
:root {
  --color-dashboard-fond: #4338CA;
  --color-contacts-fond: #7C3AED;
  --color-documents-fond: #1E3A8A;
  --color-temps-passe-fond: #94b9f4;
  --color-agenda-fond: #048297;
  --color-crm-fond: #6B6B12;
  --color-taches-fond: #15803D;
  --color-financier-fond: #2563EB;
  --color-appels-fond: #B5177F;
  --color-echeances-fond: #A16207;
  --color-interventions-fond: #9A3412;
  --color-dossiers-fond: #F2C84B;
  --color-tchat-fond: #A21CAF;
  --color-saas-fond: #7E4A86;
  --color-e-mails-fond: #DC2626;
  --color-notesfrais-fond: #881337;
  --color-notes-fond: #DB2777;
  --color-parametres-fond: #55606e;
  /* ENCRE VIVE : lisible (≥ 4,5:1) sur un fond SOMBRE, quel que soit le thème — la barre du haut est toujours sombre.
     Les 17 encres se distinguent aussi deux à deux (ΔE2000 ≥ 10,3) : éclaircies sans soin, Documents et Financier, ou
     Notes et Notes de frais, devenaient le même pastel (constaté le 05/10/2026 : icônes Factures et Parapheur). */
  --color-contacts-vif: #BB9EFF;
  --color-agenda-vif: #50BCD3;
  --color-crm-vif: #C0AF59;
  --color-taches-vif: #60C371;
  --color-appels-vif: #F08FD0;
  --color-echeances-vif: #E2A236;
  --color-interventions-vif: #FDBA74;
  --color-dossiers-vif: #F2C84B;
  --color-tchat-vif: #F880FF;
  --color-saas-vif: #C9A6D8;
  --color-e-mails-vif: #FF9080;
  --color-notesfrais-vif: #DCA3A7;
  --color-notes-vif: #FF8AAE;
  --color-parametres-vif: #A2ABB7;
  --color-dashboard-vif: #E0D8FA;
  --color-documents-vif: #AAB2DF;
  --color-financier-vif: #7DB2FF;
  --color-temps-passe-vif: #A8DDF5;
}
html[data-bs-theme="dark"] {
  --color-contacts: var(--color-contacts-vif);
  --color-agenda: var(--color-agenda-vif);
  --color-crm: var(--color-crm-vif);
  --color-taches: var(--color-taches-vif);
  --color-appels: var(--color-appels-vif);
  --color-echeances: var(--color-echeances-vif);
  --color-interventions: var(--color-interventions-vif);
  --color-dossiers: var(--color-dossiers-vif);
  --color-tchat: var(--color-tchat-vif);
  --color-saas: var(--color-saas-vif);
  --color-e-mails: var(--color-e-mails-vif);
  --color-notesfrais: var(--color-notesfrais-vif);
  --color-notes: var(--color-notes-vif);
  --color-parametres: var(--color-parametres-vif);
  --color-dashboard: var(--color-dashboard-vif);
  --color-documents: var(--color-documents-vif);
  --color-financier: var(--color-financier-vif);
}


/* Custom styles for the document and contact lists */
.table tr.selected .view-document i {
    color: white !important;
}

.table tr.selected i.mdi-dots-vertical {
    color: white !important;
}

table.dataTable.fixedHeader-floating, table.dataTable.fixedHeader-locked {
    background-color: var(--ct-primary);
}

table.dataTable.fixedHeader-floating>:not(caption)>*>*, table.dataTable.fixedHeader-locked>:not(caption)>*>* {
    color: white !important;
}

.table td {
    padding: 0.75rem !important;
    vertical-align: middle !important;
}

#liste_documents thead tr, #liste_contacts thead tr {
    vertical-align: middle !important; 
}

.dropdown-item {
    padding: 0.25rem 1.5rem !important;
    cursor: pointer;
}
.dropdown-item:hover {
    background-color: #f8f9fa !important;
}
.dropdown-item:focus {
    background-color: #f8f9fa !important;
}
.dropdown-item:active {
    background-color: #f8f9fa !important;
}
.dropdown-item:focus, .dropdown-item:active {
    outline: none !important;
}

/* La conversation sélectionnée du tchat se stylait ICI, en bleu vif et texte blanc imposés par
   `!important`. Refonte du 2026-09-19 : tout le style du tchat vit dans
   app/tchat/css/tchat-window.css — une seule feuille, sans surenchère de spécificité. */

#tchat-messages-scroll {
  height: calc(100vh - 320px); /* Ajuste 320px selon la hauteur de ton header + footer + paddings */
  max-height: none;
  min-height: 0;
}

.no-resize {
  resize: none;
}

/* Dark mode styles for the compose modal */
.dark-mode .CodeMirror,
[data-bs-theme='dark'] .CodeMirror {
    background: #23272f !important;
    color: #f1f1f1 !important;
}
.dark-mode .CodeMirror-cursor,
[data-bs-theme='dark'] .CodeMirror-cursor {
    border-left: 1px solid #f1f1f1 !important;
}
.dark-mode .editor-toolbar,
[data-bs-theme='dark'] .editor-toolbar {
    background: #23272f !important;
    border-color: #444 !important;
}
.dark-mode .editor-toolbar button,
[data-bs-theme='dark'] .editor-toolbar button {
    color: #f1f1f1 !important;
}

/* ── Bandeau d'identité de module (remplace l'ancien .floating-chip flottant) ─────────────────
   L'ancienne version était en position:absolute dans une .page-title-box réservée à 74-84px de
   hauteur, dont l'essentiel restait vide. Le ruban garde la même forme (coin coupé, couleur du
   module) mais reste dans le flux normal, sur la même ligne que les actions de la page — la
   hauteur suit le contenu réel au lieu d'être figée. On garde la classe .page-title-box sur les
   pages (plusieurs la masquent en mode encapsulé/dossier via `.page-title-box{display:none}`) et
   on AJOUTE .module-ribbon-box comme modificateur, pour ne pas toucher son usage par défaut
   ailleurs. (dashboard.php était cité ici comme la page « sans ruban » : il en a un depuis sa
   réécriture — l'exemple ne vaut plus, la règle si.) */
.page-title-box.module-ribbon-box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  min-height: 52px;
  padding: 0.4rem 0;
  margin-bottom: 0.5rem;
}
/* Pages où un DataTable suit immédiatement le ruban (Documents, Contacts, Modèles) : le thème
   tire chaque wrapper DataTables de -.625rem (margin-top négatif global, cf. mémoire
   "temps-passe-module-plan" — piège déjà rencontré) pour le rapprocher de l'élément précédent.
   L'ancien bloc de 74-84px avait assez de vide résiduel sous le chip pour l'absorber sans y
   paraître ; le ruban compact, ajusté au plus près, a besoin d'un peu plus de marge pour ne pas
   se faire mordre par ce -10px. */
.page-title-box.module-ribbon-box.module-ribbon-box--dt {
  margin-bottom: 1rem;
}
.module-ribbon-box .page-title-right {
  float: none;
  margin: 0 0 0 auto;
  order: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}
/* Barre d'outils du module DANS le ruban (recherche, filtres, Actualiser — unification du 05/10/2026, sur le
   modèle de l'Agenda) : elle prend toute la place laissée par l'étiquette et se cale à droite. Sous la largeur
   d'une ligne, elle passe d'elle-même sous l'étiquette (flex-wrap du ruban). Les libellés de champ au-dessus
   des contrôles n'ont pas leur place sur une ligne de 52 px : `.of-ruban-label` les garde pour les lecteurs
   d'écran seulement — le texte d'exemple (placeholder) ou la première option dit déjà ce qu'on choisit. */
.module-ribbon-box .page-title-right.of-ruban-outils {
  flex: 1 1 auto;
  min-width: 0;
  justify-content: flex-end;
}
/* Tout est CENTRÉ VERTICALEMENT dans le ruban — l'étiquette, la recherche, les boutons (décision de Pascal,
   05/10/2026). L'étiquette se calait sur la première ligne (align-self: flex-start) : sur une seule ligne, elle
   mesure 4 px de plus que les contrôles, et la recherche paraissait remontée. Sur deux lignes, l'étiquette se
   centre entre les deux : c'est le prix assumé de la règle « jamais sous l'étiquette ». Les lignes de contrôles,
   elles, sont centrées chacune (align-items de .page-title-right). */
/* 🔴 JAMAIS sous l'étiquette (décision de Pascal, 05/10/2026, captures Tâches et Temps passé à 1720 px) : quand
   les contrôles ne tiennent pas sur une ligne, ce n'est pas le BLOC qui passe sous l'étiquette, ce sont les
   contrôles qui passent à la ligne, à DROITE de l'étiquette — deux lignes plutôt qu'une barre déportée.
   `flex-wrap: nowrap` sur le ruban + `flex-basis: 0` sur la barre : elle prend la place restante, quelle que
   soit la largeur de son contenu. Sous 768 px (le front mobile prend le relais, mais une fenêtre étroite
   reste possible), l'étiquette garde sa ligne. */
@media (min-width: 768px) {
  .page-title-box.module-ribbon-box:has(> .of-ruban-outils) { flex-wrap: nowrap; align-items: center; }
  .module-ribbon-box .page-title-right.of-ruban-outils { flex: 1 1 0; }
}
.of-ruban-label {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
/* L'icône de l'étiquette : une taille, ici (elle était imposée en ligne, `font-size: 1.3em !important`, sur 36 pages). */
.module-ribbon > .mdi { font-size: 1.3em; line-height: 1; }
.module-ribbon {
  order: 1;
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.3em 1em;
  border-radius: 0 20px 20px 0;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.14);
  font-size: 1.05rem;
  font-weight: 700;
  white-space: nowrap;
}

/* En-têtes de modales à la couleur du module (uniformisation UI — passées en
   titleClass à showModal). On garde bg-danger (erreurs/suppressions) et bg-success
   (succès) pour leur valeur sémantique ; les modales neutres/informatives prennent
   la couleur du module. */
.modal-header.bg-documents { background-color: var(--color-documents-fond) !important; color: var(--color-documents-text) !important; }
.modal-header.bg-contacts { background-color: var(--color-contacts-fond) !important; color: var(--color-contacts-text) !important; }
/* Paramètres : la couleur du module vit dans parametres.css (--color-parametres) ; titleClass 'bg-parametres' n'avait
   aucune règle — en-tête sans fond, titre BLANC posé par showModal : invisible en thème clair (audit du 05/10/2026). */
.modal-header.bg-parametres { background-color: var(--color-parametres-fond, #55606e) !important; color: #fff !important; }
/* En-tête de fenêtre à la couleur de CHAQUE module (audit d'uniformité, lot C, 05/10/2026) : `titleClass: 'bg-<module>'`
   pour showModal, ou la classe sur un .modal-header statique. Le texte prend `--color-<module>-text` ; showModal pose
   lui-même le titre et la croix en blanc dès qu'il voit une classe bg-*. Une SUPPRESSION reste en bg-danger. */
.modal-header.bg-dashboard { background-color: var(--color-dashboard-fond) !important; color: var(--color-dashboard-text) !important; }
.modal-header.bg-agenda { background-color: var(--color-agenda-fond) !important; color: var(--color-agenda-text) !important; }
.modal-header.bg-e-mails { background-color: var(--color-e-mails-fond) !important; color: var(--color-e-mails-text) !important; }
.modal-header.bg-dossiers { background-color: var(--color-dossiers-fond) !important; color: var(--color-dossiers-text) !important; }
.modal-header.bg-taches { background-color: var(--color-taches-fond) !important; color: var(--color-taches-text) !important; }
.modal-header.bg-financier { background-color: var(--color-financier-fond) !important; color: var(--color-financier-text) !important; }
.modal-header.bg-notesfrais { background-color: var(--color-notesfrais-fond) !important; color: var(--color-notesfrais-text) !important; }
.modal-header.bg-echeances { background-color: var(--color-echeances-fond) !important; color: var(--color-echeances-text) !important; }
.modal-header.bg-appels { background-color: var(--color-appels-fond) !important; color: var(--color-appels-text) !important; }
.modal-header.bg-interventions { background-color: var(--color-interventions-fond) !important; color: var(--color-interventions-text) !important; }
.modal-header.bg-crm { background-color: var(--color-crm-fond) !important; color: var(--color-crm-text) !important; }
.modal-header.bg-temps-passe { background-color: var(--color-temps-passe-fond) !important; color: var(--color-temps-passe-text) !important; }
.modal-header.bg-notes { background-color: var(--color-notes-fond) !important; color: var(--color-notes-text) !important; }
.modal-header.bg-tchat { background-color: var(--color-tchat-fond) !important; color: var(--color-tchat-text) !important; }
.modal-header.bg-saas { background-color: var(--color-saas-fond) !important; color: var(--color-saas-text) !important; }

/* Menu d'actions « … » des listes Contacts/Documents : en thème sombre les libellés
   en .text-secondary étaient trop sombres sur le fond foncé du menu. On les éclaircit
   (le rouge de « Supprimer » est conservé pour sa valeur sémantique). */
html[data-bs-theme="dark"] .dropdown-actions-contacts .dropdown-item:not(.text-danger),
html[data-bs-theme="dark"] .dropdown-actions-docs .dropdown-item:not(.text-danger),
html[data-bs-theme="dark"] .dropdown-actions-contacts .dropdown-item:not(.text-danger) i,
html[data-bs-theme="dark"] .dropdown-actions-docs .dropdown-item:not(.text-danger) i {
  color: #c8cfe7 !important;
}
/* Menu d'actions par ligne (« … » vertical) des listes Contacts/Documents : mêmes
   libellés .text-secondary trop sombres en thème sombre. On ne cible QUE .text-secondary
   pour préserver les items à couleur de module (Créer une tâche, Générer un document)
   et le rouge de Supprimer. */
html[data-bs-theme="dark"] .dropdown-menu-contacts .dropdown-item.text-secondary,
html[data-bs-theme="dark"] .dropdown-menu-docs .dropdown-item.text-secondary,
html[data-bs-theme="dark"] .dropdown-menu-contacts .dropdown-item.text-secondary i,
html[data-bs-theme="dark"] .dropdown-menu-docs .dropdown-item.text-secondary i {
  color: #c8cfe7 !important;
}

/* Survol en thème sombre : forcer un fond SOMBRE (par défaut Bootstrap met un fond clair
   → texte clair illisible). Vaut pour les deux menus (« … Actions » et menu de ligne). */
html[data-bs-theme="dark"] .dropdown-actions-contacts .dropdown-item:hover,
html[data-bs-theme="dark"] .dropdown-actions-docs .dropdown-item:hover,
html[data-bs-theme="dark"] .dropdown-menu-contacts .dropdown-item:hover,
html[data-bs-theme="dark"] .dropdown-menu-docs .dropdown-item:hover {
  background-color: rgba(255, 255, 255, 0.12) !important;
}
/* Au survol : libellés neutres en blanc (les items à couleur de module et « Supprimer »
   gardent leur teinte, lisible sur fond sombre). */
html[data-bs-theme="dark"] .dropdown-actions-contacts .dropdown-item:not(.text-danger):hover,
html[data-bs-theme="dark"] .dropdown-actions-docs .dropdown-item:not(.text-danger):hover,
html[data-bs-theme="dark"] .dropdown-actions-contacts .dropdown-item:not(.text-danger):hover i,
html[data-bs-theme="dark"] .dropdown-actions-docs .dropdown-item:not(.text-danger):hover i,
html[data-bs-theme="dark"] .dropdown-menu-contacts .dropdown-item.text-secondary:hover,
html[data-bs-theme="dark"] .dropdown-menu-docs .dropdown-item.text-secondary:hover,
html[data-bs-theme="dark"] .dropdown-menu-contacts .dropdown-item.text-secondary:hover i,
html[data-bs-theme="dark"] .dropdown-menu-docs .dropdown-item.text-secondary:hover i {
  color: #ffffff !important;
}

/* ── Généralisation app-wide des menus « … » en thème sombre ─────────────────
   Les règles ci-dessus ne couvraient que Contacts/Documents. On généralise à TOUS
   les menus déroulants (couvre le menu « … » des colonnes du Kanban / Tâches et tout
   futur menu) : au repos, on éclaircit les libellés .text-secondary (trop sombres sur
   fond foncé) ; au survol, on rétablit un fond SOMBRE — car le survol global plus haut
   force un fond clair (#f8f9fa !important) qui, en thème sombre, rend le libellé clair
   illisible. .text-danger (Supprimer/Archiver) garde sa sémantique rouge. */
html[data-bs-theme="dark"] .dropdown-item.text-secondary,
html[data-bs-theme="dark"] .dropdown-item.text-secondary i {
  color: #c8cfe7 !important;
}
html[data-bs-theme="dark"] .dropdown-item:hover,
html[data-bs-theme="dark"] .dropdown-item:focus,
html[data-bs-theme="dark"] .dropdown-item:active {
  background-color: rgba(255, 255, 255, 0.12) !important;
}
html[data-bs-theme="dark"] .dropdown-item:not(.text-danger):hover,
html[data-bs-theme="dark"] .dropdown-item:not(.text-danger):hover i {
  color: #ffffff !important;
}

/* ── Un menu ouvert SE DÉTACHE de la page (signalé par Pascal le 14/10/2026) ──────────────────────────────────────
   Mesuré dans Chrome (Contacts, Documents, Factures) : le menu avait EXACTEMENT le fond de la liste sous lui
   (#fff sur #fff ; #37404a sur #37404a en sombre), un filet à 1,2:1 et une ombre diffuse à 15 % — en sombre, une
   ombre plus claire que le fond, donc invisible. Le menu se lisait comme une suite de lignes de la liste.
   Remède, dans les deux thèmes : un filet net, une ombre portée franche (proche + lointaine), des coins arrondis ;
   en sombre, en plus, le menu monte d'un cran de luminosité (une surface au-dessus, comme une carte posée).
   On ne touche qu'aux VARIABLES du thème : un menu qui fixe lui-même son fond le garde. */
.dropdown-menu {
  --ct-dropdown-border-color: #b3bcc7;
  --ct-dropdown-border-radius: .5rem;
  --ct-dropdown-inner-border-radius: calc(.5rem - 1px);
  --ct-dropdown-box-shadow: 0 16px 40px rgba(16, 24, 40, .22), 0 3px 8px rgba(16, 24, 40, .14);
  box-shadow: var(--ct-dropdown-box-shadow);
}
html[data-bs-theme="dark"] .dropdown-menu {
  --ct-dropdown-bg: #283038;
  --ct-dropdown-border-color: #75818f;
  --ct-dropdown-box-shadow: 0 14px 34px rgba(0, 0, 0, .6), 0 2px 8px rgba(0, 0, 0, .45);
}

/* ── Centrage des fenêtres modales (vertical + horizontal), app-wide ──────────
   Toutes les modales Bootstrap sont centrées H+V. On centre via le CONTENEUR .modal
   en flex + marges auto sur le dialogue, SANS min-height plein écran (l'ancien
   « min-height: calc(100% - margin*2) » provoquait un scroll parasite quand la marge
   réelle du dialogue ne correspondait pas au fallback). Si le contenu dépasse la
   hauteur de l'écran, la modale défile depuis le haut (pas de rognage). Le mode plein
   écran (.modal-fullscreen*) est exclu. ------------------------------------- */
.modal.show {
  display: flex !important;
}
.modal.show > .modal-dialog:not([class*="modal-fullscreen"]) {
  margin: auto;
  min-height: 0;
  width: 100%;
}

/* ── Correctif menu "Condensé" — grand vide en bas des pages courtes ──────────
   Le thème vendor (app.css) fixe .content-page à min-height: 2000px (variable
   --ct-leftbar-condensed-height) dès que data-sidenav-size=condensed, quelle que soit la
   hauteur réelle du contenu — valeur figée, sans rapport avec le nombre d'items du menu
   OrgaFlex. Le menu condensé est déjà position:fixed (top:0/bottom:0 sur .leftside-menu),
   il n'a donc pas besoin que .content-page atteigne 2000px. Symptôme : sur une page au
   contenu volontairement calé sur la fenêtre (ex. Agenda), un vide apparaît entre le bas
   du contenu et le footer (footer en position:absolute; bottom:0 de .content-page, donc
   plaqué au bas de ce min-height artificiel). On réaligne sur le min-height par défaut
   (identique aux autres tailles de menu). Même sélecteur que le thème pour l'emporter à
   spécificité égale (règle chargée après app.min.css). */
html[data-sidenav-size=condensed]:not([data-layout=topnav]) .wrapper .content-page {
  min-height: calc(100vh - var(--ct-topbar-height) - 2px);
}

/* ── Case à cocher « tout sélectionner » mal centrée en en-tête DataTables (Documents, Contacts)
   DataTables 2.x enveloppe le contenu de chaque en-tête dans .dt-column-header (flex,
   justify-content:space-between) > .dt-column-title, en réservant systématiquement 30px de
   padding-right sur les DEUX (header ET title) pour la flèche de tri — même sur une colonne non
   triable comme celle-ci (orderable:false). Résultat : la case, en display:block dans .dt-column-title,
   reste collée à gauche de cet espace réduit au lieu d'être centrée comme dans les <td> du corps du
   tableau (qui n'ont pas cette enveloppe). On neutralise ce padding et le rendu space-between
   uniquement pour l'en-tête contenant #select-all (même id sur Documents et Contacts). */
th:has(#select-all) .dt-column-header {
  justify-content: center !important;
  padding-right: 0 !important;
}
th:has(#select-all) .dt-column-title {
  padding-right: 0 !important;
}
th:has(#select-all) .dt-column-order {
  display: none !important;
}

/* En-têtes personnalisés (datatable-utils.js setupSearchInputs) : le titre est désormais dans un
   <span class="dt-column-title"> — obligatoire pour que DataTables 2.x lise column().title(), sans
   quoi l'export Excel plante. Mais le padding-right:30px de .dt-column-title (réservé à la flèche de
   tri) créerait ici un vide entre le titre et le champ de recherche voisin : notre en-tête gère sa
   propre mise en page (flex + gap-2), on retire donc ce padding. Apparence inchangée. */
.custom-header-cell > .dt-column-title {
  padding-right: 0;
}

/* ── Encre atténuée, thème sombre ─────────────────────────────────────────────────────────────
   Un PAS PROPRE, pas un éclaircissement automatique : la valeur est choisie contre le fond des
   cartes du thème sombre (#37404a) et mesurée à 4,58:1. */
html[data-bs-theme="dark"] {
  --of-encre-attenuee: #b8c3ce;   /* contraste du sombre (14/10/2026) : #a0adb5 tombait à 4,06:1 sur le fond tertiaire */
}
