        /* 🎨 Identité visuelle CABIVA (indépendante du site public) */
        :root { --color-primary: #00A99D; --color-secondary: #132F55; --sc-navy: #132F55; --sc-navy-dark: #0D1B2A; --sc-teal: #00A99D; --sc-mint: #E6F7F4; --sc-gray: #F2F4F7; }
        * { box-sizing: border-box; }
        html, body { font-family: 'Poppins', 'Outfit', sans-serif; max-width: 100vw; overflow-x: hidden !important; width: 100%; margin: 0; padding: 0; background-color: #F2F4F7; color: #132F55; }
        .font-serif { font-family: 'Poppins', sans-serif !important; font-weight: 700; letter-spacing: -0.02em; }
        /* Onglet actif : forcer la couleur de marque (contourne un conflit d'animation Tailwind CDN) */
        .tab-button.text-primary, .tab-button.text-primary .sidebar-text, .mobile-tab-btn.text-primary { color: var(--color-primary) !important; }

        /* 🌑 Menu latéral en mode sombre (identité CABIVA) */
        #sidebar { background: linear-gradient(180deg, #132F55 0%, #0D1B2A 100%) !important; border-color: rgba(255,255,255,0.08) !important; }
        #sidebar .border-slate-100, #sidebar .border-slate-200 { border-color: rgba(255,255,255,0.08) !important; }
        #sidebar .bg-slate-50\/50 { background-color: rgba(255,255,255,0.03) !important; }
        #sidebar h1.text-slate-800, #sidebar .text-slate-800 { color: #f1f5f9 !important; }
        #sidebar .text-slate-600 { color: #cbd5e1 !important; }
        #sidebar .text-slate-500 { color: #94a3b8 !important; }
        #sidebar .menu-header, #sidebar .text-slate-400 { color: #6b7f9e !important; }
        #sidebar .hover\:bg-slate-50:hover { background-color: rgba(255,255,255,0.07) !important; }
        #sidebar #now-widget { background-color: rgba(0,0,0,0.22) !important; }
        #sidebar #global-search { background-color: rgba(255,255,255,0.06) !important; border-color: rgba(255,255,255,0.1) !important; color: #e2e8f0 !important; }
        #sidebar #global-search::placeholder { color: #64748b !important; }
        #sidebar #global-search:focus { background-color: rgba(255,255,255,0.12) !important; }
        #sidebar #global-search-results { background-color: #0D1B2A !important; border-color: rgba(255,255,255,0.12) !important; }
        #sidebar #global-search-results .border-slate-50 { border-color: rgba(255,255,255,0.06) !important; }
        #sidebar #global-search-results .hover\:bg-primary\/5:hover { background-color: rgba(255,255,255,0.06) !important; }
        /* Logo sidebar (fond sombre) : sans fond, ajusté au conteneur */
        #sidebar #header-logo-img:not(.hidden) { height:3.9rem !important; max-width:230px !important; }
        /* Sidebar réduite (desktop) : logo carré centré, pas de débordement */
        #sidebar.w-20 > div:first-child { padding-left:0 !important; padding-right:0 !important; justify-content:center !important; }
        /* object-contain : le logo est fourni détouré avec ses propres coins
           arrondis — le recadrer (cover) en couperait les bords. */
        #sidebar.w-20 #header-logo-img:not(.hidden) { height:3.25rem !important; width:3.25rem !important; max-width:3.25rem !important; object-fit:contain; }
        /* Menu : texte aligné à gauche (pas centré), plus petit pour ne pas être tronqué */
        #sidebar nav button, #sidebar nav a { font-size:0.8125rem !important; }
        #sidebar nav button > .sidebar-text.truncate, #sidebar nav a > .sidebar-text.truncate { min-width:0; flex:1 1 auto; text-align:left; }
        /* Badges du menu : masqués en mode réduit */
        #sidebar.w-20 .side-badge { display:none !important; }
        .table-container { width: 100%; max-width: 100%; overflow-x: auto; -ms-overflow-style: none; scrollbar-width: none; }
        .table-container::-webkit-scrollbar { display: none; }
        .loader { border-top-color: var(--color-primary); animation: spinner 1.5s linear infinite; }
        @keyframes spinner { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
        ::-webkit-scrollbar { height: 6px; width: 8px; } 
        ::-webkit-scrollbar-track { background: transparent; border-radius: 4px; } 
        ::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 4px; } 
        ::-webkit-scrollbar-thumb:hover { background: #94a3b8; }
        .toast-enter { transform: translateY(100%); opacity: 0; } 
        .toast-enter-active { transform: translateY(0); opacity: 1; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); } 
        .toast-exit { transform: translateY(0); opacity: 1; } 
        .toast-exit-active { transform: translateY(100%); opacity: 0; transition: all 0.3s ease-in; }
        .hide-scroll::-webkit-scrollbar { display: none; } 
        .hide-scroll { -ms-overflow-style: none; scrollbar-width: none; }
        .modal-overlay { transition: opacity 0.3s ease; opacity: 0; pointer-events: none; }
        .modal-overlay.active { opacity: 1; pointer-events: auto; }
        .modal-content { transition: transform 0.3s ease; transform: scale(0.95); }
        .modal-overlay.active .modal-content { transform: scale(1); }
        /* ✖️ Pas de croix de fermeture sur les écrans affichés COMME DES PAGES.
           Un « Nouveau RDV » ou un dossier patient occupe tout l'espace et se
           quitte par le fil d'Ariane : une croix en plus laissait croire à une
           fenêtre superposée et donnait deux façons de faire la même chose.
           Les VRAIES fenêtres (.modal-overlay sans .modal-page — confirmation,
           éditeur, aperçu, import…) gardent la leur : elles n'ont pas de fil
           d'Ariane et la croix y est le seul moyen de sortir. */
        .modal-page button[onclick*="closeModal"] { display: none !important; }

        /* 📄 Fenêtres affichées DANS le flux de la page (comme un onglet agenda/accueil) */
        .modal-page.mp-inline { position:static !important; inset:auto !important; display:block !important; opacity:1 !important; pointer-events:auto !important; background:transparent !important; padding:0 !important; z-index:auto !important; transform:none !important; animation:fadeUp 0.3s cubic-bezier(0.16,1,0.3,1); }
        .modal-page.mp-inline .modal-content { width:100% !important; max-width:100% !important; height:auto !important; max-height:none !important; transform:none !important; margin:0 auto !important; }
        .modal-page.mp-inline:not(#modal-patient-profile) .modal-content { max-width:920px !important; }
        /* Neutraliser les zones à hauteur fixe internes pour que TOUTE la page scrolle */
        .modal-page.mp-inline .overflow-y-auto, .modal-page.mp-inline .overflow-y-scroll { overflow:visible !important; max-height:none !important; }
        @keyframes ping-large { 75%, 100% { transform: scale(2); opacity: 0; } } 
        .animate-ping-large { animation: ping-large 1.5s cubic-bezier(0, 0, 0.2, 1) infinite; }
        input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
        
        /* Kanban Styles */
        /* 🩺 Fil des étapes de consultation.
           Il défilait horizontalement avec une barre masquée : la 4ᵉ étape
           « Finalisation » était coupée et inatteignable à la souris. On laisse
           les étapes passer à la ligne — elles restent toutes visibles. */
        #consult-stepper { flex-wrap: wrap !important; overflow: visible !important; row-gap: .375rem; }
        #consult-stepper > * { flex: 0 1 auto; }

        /* 📅 Agenda Global — vues Mois et Semaine.
           FullCalendar tronque le titre d'un événement sur une seule ligne : on
           lisait « 10 h Fatima Zahra… » sans jamais voir le motif ni le numéro.
           On autorise le retour à la ligne et on laisse la case grandir. */
        #global-calendar .fc-daygrid-event,
        #global-calendar .fc-timegrid-event { white-space: normal !important; }
        #global-calendar .fc-event-title,
        #global-calendar .fc-event-title-container { white-space: normal !important; overflow: visible !important; text-overflow: clip !important; line-height: 1.25; }
        #global-calendar .fc-daygrid-event-harness { margin-bottom: 2px; }
        #global-calendar .fc-daygrid-day-frame { min-height: 5.5rem; }
        #global-calendar .fc-daygrid-day-events { font-size: .72rem; }

        .kanban-container { min-height: 150px; padding-bottom: 20px; transition: background-color 0.2s; }
        /* 🖱️ Kanban : la classe hide-scroll masquait la barre de défilement.
           Sur mobile c'est bien (on fait glisser au doigt), mais à la souris il
           ne restait AUCUN moyen d'atteindre les dernières colonnes. On rétablit
           une barre fine sur ordinateur ; la molette est traitée en JS. */
        @media (min-width: 1024px) {
            #agenda-kanban-view { scrollbar-width: thin !important; scrollbar-color: #cbd5e1 transparent; -ms-overflow-style: auto !important; }
            #agenda-kanban-view::-webkit-scrollbar { display: block !important; height: 9px; }
            #agenda-kanban-view::-webkit-scrollbar-track { background: transparent; }
            #agenda-kanban-view::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 999px; }
            #agenda-kanban-view::-webkit-scrollbar-thumb:hover { background: #94a3b8; }
        }
        .kb-card { transition: transform 0.2s, box-shadow 0.2s; cursor: grab; }
        .kb-card:active { cursor: grabbing; }
        .sortable-ghost { opacity: 0.4; background-color: #f1f5f9; border: 2px dashed #cbd5e1; }
        .sortable-drag { transform: scale(1.05); box-shadow: 0 10px 25px rgba(0,0,0,0.1); }
        
        /* FullCalendar Customizations */
        .fc { font-family: 'Outfit', sans-serif; }
        .fc-theme-standard td, .fc-theme-standard th { border-color: #f1f5f9; }
        .fc-col-header-cell { padding: 0.5rem 0; color: #64748b; background-color: #f8fafc; font-size: 0.875rem; }
        .fc-v-event { border-radius: 6px; box-shadow: 0 1px 2px rgba(0,0,0,0.05); border: none !important; border-left: 4px solid rgba(0,0,0,0.2) !important;}
        .fc-v-event:hover { opacity: 0.9; cursor: pointer; }
        .fc-event-main { padding: 2px 4px; }
        .fc-timegrid-slot-label { font-size: 0.75rem; color: #94a3b8; font-weight: 500; }
        .fc .fc-toolbar-title { font-size: 1.1rem; font-weight: bold; color: #1e293b; }
        .fc .fc-button-primary { background-color: var(--color-primary); border-color: var(--color-primary); text-transform: capitalize; font-weight: bold; }
        .fc .fc-button-primary:hover { opacity: 0.9; background-color: var(--color-primary); border-color: var(--color-primary); }
        .fc .fc-scroller { -webkit-overflow-scrolling: touch; }
        .fc-event-title { font-weight: 700 !important; font-size: 0.8rem !important; line-height: 1.25 !important; }
        .fc-event-time { font-weight: 600 !important; font-size: 0.72rem !important; }
        .fc .fc-timegrid-slot { height: 2.2em; }

        /* FullCalendar Mobile (Agenda Global) */
        @media (max-width: 767px) {
            .fc .fc-toolbar.fc-header-toolbar { flex-direction: column; align-items: stretch; gap: 0.5rem; margin-bottom: 0.75rem; }
            .fc .fc-toolbar-chunk { display: flex; justify-content: center; flex-wrap: wrap; gap: 0.25rem; }
            .fc .fc-toolbar-title { font-size: 1rem; text-align: center; }
            .fc .fc-button { padding: 0.35rem 0.6rem; font-size: 0.75rem; }
            .fc .fc-col-header-cell { font-size: 0.7rem; padding: 0.25rem 0; }
            .fc-timegrid-slot-label { font-size: 0.65rem; }
            .fc .fc-event-main { font-size: 0.7rem; padding: 1px 2px; }
            .fc .fc-daygrid-day-number, .fc .fc-daygrid-event { font-size: 0.7rem; }
            #global-calendar, #daily-calendar { min-height: 450px; }
            #tab-calendrier .bg-white { padding: 0.75rem; }
        }

        /* ✨ Skeleton loaders (shimmer) */
        @keyframes shimmer { 0% { background-position: -800px 0; } 100% { background-position: 800px 0; } }
        .skeleton { background: linear-gradient(90deg, #eef2f7 25%, #f8fafc 50%, #eef2f7 75%); background-size: 800px 100%; animation: shimmer 1.4s infinite linear; border-radius: 10px; }

        /* ✨ Transitions & micro-animations */
        .tab-content:not(.hidden) { animation: fadeUp 0.35s cubic-bezier(0.16,1,0.3,1); }
        @keyframes fadeUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
        .kb-card { animation: fadeUp 0.3s ease both; }
        .stat-card { transition: transform 0.2s ease, box-shadow 0.2s ease; }
        .stat-card:hover { transform: translateY(-3px); box-shadow: 0 12px 24px -8px rgba(15,23,42,0.15); }
        #fab-btn { transition: transform 0.2s ease, box-shadow 0.2s ease; }


        /* ═══════════════════════════════════════════════════════════════
           ✨ AFFINAGE VISUEL — « surfaces plates »
           Refonte de la FORME uniquement : mêmes couleurs d'identité
           (#00A99D / #132F55 / #0D1B2A / #F2F4F7), même contenu, mêmes
           fonctions. Le menu latéral sombre est CONSERVÉ (choix du cabinet).
           Principe : remplacer les ombres portées par des filets fins.
           Les ombres empilées créaient un bruit visuel sur un écran
           consulté toute la journée ; un filet de 1px sépare aussi bien
           et laisse le regard se poser sur les chiffres.
           ═══════════════════════════════════════════════════════════════ */

        /* 1. Cartes plates : filet au lieu d'ombre */
        #main-scroll .shadow-sm,
        #main-scroll .shadow-md,
        #main-scroll .shadow-lg,
        #main-scroll .shadow-xl,
        #main-scroll .shadow-2xl { box-shadow: none !important; }
        #main-scroll .bg-white.border,
        #main-scroll .bg-white.rounded-2xl,
        #main-scroll .bg-white.rounded-xl { border: 1px solid #e6eaf0 !important; }

        /* 2. Rayons unifiés : plus calmes, moins « bulle » */
        #main-scroll .rounded-3xl { border-radius: 1rem !important; }
        #main-scroll .rounded-2xl { border-radius: 0.875rem !important; }

        /* 3. En-tête : filet net plutôt qu'une ombre diffuse */
        header.bg-white, #breadcrumb-bar { box-shadow: none !important; border-bottom: 1px solid #e6eaf0 !important; }

        /* 4. Cartes de statistiques : le chiffre devient le héros */
        #main-scroll .stat-card { transition: border-color .15s ease, transform .15s ease; }
        #main-scroll .stat-card:hover { border-color: var(--sc-teal) !important; transform: translateY(-1px); }
        #main-scroll .stat-card p.uppercase { letter-spacing: .06em; font-weight: 600; color: #94a3b8 !important; }
        #main-scroll .stat-card h3 { font-weight: 700; letter-spacing: -.02em; }

        /* 5. Tableaux : en-tête discret, lignes plus aérées */
        #main-scroll thead tr { background: #fafbfc !important; }
        #main-scroll thead th { font-weight: 600 !important; letter-spacing: .05em; color: #8494a8 !important; border-bottom: 1px solid #e6eaf0 !important; }
        #main-scroll tbody tr { transition: background-color .12s ease; }
        #main-scroll tbody tr:hover { background-color: #f7f9fb !important; }

        /* 6. Champs de saisie : bordure plus douce, focus net à la marque */
        #main-scroll input:not([type=color]):not([type=checkbox]),
        #main-scroll select, #main-scroll textarea {
            border-color: #dfe5ec !important; transition: border-color .15s ease, box-shadow .15s ease;
        }
        #main-scroll input:not([type=color]):not([type=checkbox]):focus,
        #main-scroll select:focus, #main-scroll textarea:focus {
            border-color: var(--sc-teal) !important; box-shadow: 0 0 0 3px rgba(0,169,157,.12) !important; outline: none;
        }

        /* 7. Boutons : appui tactile plus lisible, sans ombre colorée */
        #main-scroll button { transition: filter .15s ease, transform .12s ease, background-color .15s ease; }
        #main-scroll button:active { transform: scale(.985); }

        /* 8. Menu latéral CONSERVÉ sombre — état actif plus lisible
              (barre d'accent à gauche au lieu d'un simple changement de teinte) */
        #sidebar .tab-button, #sidebar .side-action { position: relative; border-radius: .625rem !important; }
        #sidebar .tab-button.text-primary { background-color: rgba(0,169,157,.14) !important; }
        #sidebar .tab-button.text-primary::before {
            content: ''; position: absolute; left: 0; top: 18%; bottom: 18%; width: 3px;
            border-radius: 0 3px 3px 0; background: var(--sc-teal);
        }
        #sidebar nav { gap: .125rem; }
        #sidebar .menu-header { font-size: .625rem !important; letter-spacing: .12em; margin-top: .25rem; }

        /* 9. Onglets du dossier patient : soulignement au lieu d'une pastille pleine */
        .pt-tab-btn { border-radius: .5rem !important; }

        /* 10. Bouton flottant : plus discret au repos */
        #fab-btn { box-shadow: 0 4px 14px rgba(0,169,157,.35) !important; }

        /* ═══════════════════════════════════════════════════════════════
           📱 BARRES DE FILTRES — anti-chevauchement (mobile / tablette / PC)
           Les barres empilaient des champs à largeur fixe : sur petit écran
           ils se chevauchaient, sur tablette ils débordaient de la carte.
           Règle unique : tout élément de filtre peut rétrécir (min-width:0)
           et passe à la ligne proprement.
           ═══════════════════════════════════════════════════════════════ */
        .filter-bar { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; width: 100%; min-width: 0; }
        .filter-bar > * { min-width: 0; }
        .filter-bar input[type="text"],
        .filter-bar input[type="search"] { flex: 1 1 12rem; min-width: 0; }
        .filter-bar input[type="date"] { flex: 0 1 9.5rem; min-width: 0; }
        .filter-bar select { flex: 0 1 11rem; min-width: 0; }
        .filter-bar button { flex: 0 0 auto; }

        /* Les conteneurs de filtres existants héritent du même comportement */
        #tab-rdv .flex.flex-wrap, #tab-crm .flex.flex-wrap,
        #tab-facturation .flex.flex-wrap, #tab-stock .flex.flex-wrap { min-width: 0; }
        #tab-rdv input, #tab-rdv select,
        #tab-crm input, #tab-crm select,
        #tab-facturation input, #tab-facturation select,
        #tab-stock input, #tab-stock select { min-width: 0; max-width: 100%; }

        @media (max-width: 640px) {
            /* Mobile : les champs occupent toute la largeur, les boutons se partagent la ligne */
            #tab-rdv input[type="text"], #tab-crm input[type="text"],
            #tab-facturation input[type="text"], #tab-stock input[type="text"] { flex: 1 1 100%; }
            #tab-rdv input[type="date"], #tab-facturation input[type="date"] { flex: 1 1 calc(50% - .25rem); }
            #tab-rdv select, #tab-crm select, #tab-facturation select, #tab-stock select { flex: 1 1 100%; }
            /* Les groupes de boutons d'action ne débordent plus */
            #tab-facturation .flex.gap-2, #tab-rdv .flex.gap-2 { flex-wrap: wrap; }
            #tab-facturation .flex.gap-2 > button, #tab-rdv .flex.gap-2 > button { flex: 1 1 auto; }
        }
        @media (min-width: 641px) and (max-width: 1024px) {
            /* Tablette : deux colonnes de filtres, jamais de débordement */
            #tab-rdv input[type="text"], #tab-crm input[type="text"],
            #tab-facturation input[type="text"] { flex: 1 1 16rem; }
        }

        /* ═══════════════════════════════════════════════════════════════
           👤 DOSSIER PATIENT — barre d'actions en icônes sur mobile
           Les libellés faisaient déborder la barre ; l'icône suffit,
           le libellé reste accessible via l'attribut title.
           ═══════════════════════════════════════════════════════════════ */
        @media (max-width: 640px) {
            #prof-actions .act-label { display: none; }
            #prof-actions button, #prof-actions a {
                width: 2.75rem; height: 2.75rem; padding: 0 !important;
                display: inline-flex; align-items: center; justify-content: center;
                gap: 0 !important; border-radius: .75rem;
            }
            #prof-actions { gap: .5rem; flex-wrap: wrap; }
            #prof-actions i { margin: 0 !important; font-size: 1.05rem; }
        }

        /* ── Correctif ciblé : chevauchement filtres ↔ boutons ──────────────
           Les barres sont construites en « groupe de filtres (flex-1) + groupe
           de boutons (shrink-0) ». Les encadrés de dates n'avaient pas de
           min-width:0 : leur largeur intrinsèque débordait du groupe filtres et
           venait se superposer aux boutons. On autorise le rétrécissement, et
           sous 640 px chaque groupe occupe sa propre ligne. */
        #tab-facturation .flex.flex-wrap > div,
        #tab-rdv .flex.flex-wrap > div,
        #tab-stock .flex.flex-wrap > div,
        #tab-crm .flex.flex-wrap > div { min-width: 0; }

        #tab-facturation input[type="date"],
        #tab-rdv input[type="date"] { min-width: 0; width: 100%; }

        @media (max-width: 767px) {
            /* Groupe de boutons : passe sous les filtres au lieu de les chevaucher */
            #tab-facturation .flex.gap-2.shrink-0,
            #tab-rdv .flex.gap-2.shrink-0,
            #tab-crm .flex.gap-2.shrink-0,
            #tab-stock .flex.gap-2.shrink-0 {
                flex: 1 0 100% !important; flex-wrap: wrap; margin-top: .25rem;
            }
            #tab-facturation .flex.gap-2.shrink-0 > *,
            #tab-rdv .flex.gap-2.shrink-0 > * { flex: 1 1 auto; justify-content: center; }
            /* Les deux encadrés de dates se partagent la ligne */
            #tab-facturation .flex.flex-wrap.gap-2 > div:has(input[type="date"]) { flex: 1 1 calc(50% - .5rem); }
        }

        /* ═══════════════════════════════════════════════════════════════
           📱 COHÉRENCE MOBILE DES BARRES D'ACTIONS
           Sur téléphone, trois zones se comportaient différemment :
             • la barre d'actions du dossier laissait WhatsApp (ml-auto) tomber
               seul sur une 2ᵉ ligne, avec un grand vide à gauche ;
             • le bouton « réinitialiser » restait un carré de 42 px orphelin
               sur sa propre ligne, sous des champs pleine largeur ;
             • l'export apparaissait tantôt seul, tantôt avec un autre bouton.
           Règle unique : en dessous de 768 px, un contrôle occupe toute la
           largeur OU partage sa ligne à parts égales. Jamais d'orphelin.
           ═══════════════════════════════════════════════════════════════ */
        @media (max-width: 767px) {
            /* Barre d'actions du dossier : 6 icônes, une seule ligne, à parts égales */
            #prof-actions {
                display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
                gap: .375rem; overflow: visible;
            }
            #prof-actions > * {
                margin-left: 0 !important; width: auto; min-width: 0;
                display: inline-flex; align-items: center; justify-content: center;
                padding-left: 0; padding-right: 0;
            }
            /* Zones de filtres : chaque champ pleine largeur, actions à parts égales.
               ⚠️ Sélecteurs volontairement doublés : Tailwind est injecté APRÈS
               cette feuille, donc à spécificité égale (.flex) c'est lui qui
               gagnerait et `display: grid` serait ignoré. */
            .zone-filtres > div { width: 100%; }
            /* Sans flex-wrap, les champs ne peuvent pas descendre : ils se font
               écraser (le select du stock tombait à 26 px, réduit à sa flèche). */
            .zone-filtres .zone-filtres-champs { flex-wrap: wrap !important; }
            .zone-filtres .zone-filtres-champs > * { width: 100% !important; max-width: none; flex: 0 0 100%; }
            .zone-filtres .zone-filtres-reset { display: flex !important; align-items: center; justify-content: center; }
            /* Classe réutilisable : toute barre de boutons qui laisserait un
               orphelin sur une 2ᵉ ligne. Sert aussi à la barre d'outils de la
               synthèse (Focus / Renouveler / Actualiser / Imprimer). */
            .zone-filtres-actions {
                /* auto-fit plutôt qu'un nombre fixe de colonnes : le plancher de
                   8rem empêche d'écraser un libellé comme « Renouveler », et
                   auto-fit fait disparaître les colonnes vides — un bouton seul
                   occupe donc toute la largeur au lieu de rester à un quart. */
                display: grid !important;
                grid-template-columns: repeat(auto-fit, minmax(min(100%, 8rem), 1fr));
                gap: .5rem;
                /* Sinon la barre partage sa ligne avec le titre voisin et se
                   retrouve écrasée à ~112 px (cas de la synthèse du dossier). */
                width: 100%; flex-basis: 100%;
            }
            /* :not([style*="none"]) — sans cette exclusion, le !important
               réaffichait les boutons que les permissions viennent de masquer
               (la secrétaire revoyait « Importer » alors qu'elle n'y a pas droit). */
            .zone-filtres-actions > *:not([style*="none"]) {
                display: inline-flex !important; align-items: center; justify-content: center;
                min-width: 0; padding-left: .5rem; padding-right: .5rem;
            }
            /* Libellés toujours affichés : deux boutons partageant une ligne
               laissent assez de place, et une icône seule est ambiguë. */
            .zone-filtres-actions > * > span { white-space: nowrap; }

            /* Pagination : « Total » et les trois boutons se disputaient une
               seule ligne — « Suivant » finissait sous le bouton flottant « + ».
               On empile, puis on réserve la hauteur du bouton flottant. */
            .zone-pagination {
                flex-direction: column; align-items: stretch; gap: .5rem;
                padding-bottom: 5rem;
            }
            .zone-pagination > span { text-align: center; }
            .zone-pagination > div {
                display: grid !important; grid-auto-flow: column;
                grid-auto-columns: 1fr; gap: .5rem;
            }
            .zone-pagination > div > * { text-align: center; white-space: nowrap; }
        }

        /* Sur ordinateur, les champs sans classe de largeur (date, select)
           s'étiraient sur toute la ligne et repoussaient les suivants : les
           filtres s'empilaient sur trois lignes au lieu d'une. On les ramène à
           leur largeur naturelle. */
        @media (min-width: 768px) {
            /* !important : Tailwind est injecté après cette feuille et marque
               ses utilitaires en !important — sans cela la largeur est ignorée. */
            .zone-filtres-champs > input,
            .zone-filtres-champs > select { width: auto !important; min-width: 9rem; }
        }

        /* ═══════════════════════════════════════════════════════════════
           👤 DOSSIER PATIENT — 2 colonnes (ordinateur) · accordéon (mobile)
           ═══════════════════════════════════════════════════════════════ */
        #pt-layout { display: block; }
        #pt-side { display: none; }
        .pt-acc-head { display: none; }

        /* ── Ordinateur : colonne de contexte fixe à droite ── */
        @media (min-width: 1024px) {
            #pt-layout { display: grid; grid-template-columns: minmax(0, 1fr) 19rem; gap: 1rem; align-items: start; }
            #pt-main { min-width: 0; }
            #pt-side { display: block; }
            #pt-side > div { position: sticky; top: .5rem; }

            /* La barre d'onglets n'existe QUE sur ordinateur (le mobile utilise
               l'accordéon) : un défilement horizontal n'y a donc aucun sens —
               à la souris il oblige à un glissé maladroit et les derniers
               onglets restaient invisibles. On passe en lignes : les 8 sections
               sont toutes atteignables d'un seul clic, sans rien faire défiler. */
            #pt-tabbar { flex-wrap: wrap; overflow: visible; gap: .25rem; }
            /* Base à 25 % => 4 par ligne, donc 4+4 pour les 8 sections du Docteur.
               flex-grow à 0 : quand le rôle en masque (Secrétaire n'en garde que
               deux), les restants gardent leur largeur au lieu de s'étirer sur
               toute la barre. */
            #pt-tabbar .pt-tab-btn {
                /* 25 % sur un grand écran (=> 4 par ligne), mais jamais moins de
                   9rem : sur un 1024 px la colonne ne fait que ~330 px et un
                   quart tronquerait « Historique ». En dessous, on passe
                   naturellement à 2 par ligne. */
                flex: 0 1 max(9rem, calc(25% - .25rem)); min-width: 0;
                display: inline-flex; align-items: center; justify-content: center; gap: .35rem;
            }
        }

        /* ── Mobile & tablette : accordéon vertical, plus de défilement latéral ── */
        @media (max-width: 1023px) {
            #pt-tabbar { display: none; }
            .pt-acc-head {
                display: flex; align-items: center; justify-content: space-between;
                width: 100%; margin-top: .5rem; padding: .75rem 1rem;
                background: #fff; border: 1px solid #e6eaf0; border-radius: .75rem;
                font-size: .8125rem; font-weight: 700; color: #475569;
                transition: background-color .15s ease, color .15s ease;
            }
            .pt-acc-head .pt-acc-chev { font-size: .7rem; transition: transform .2s ease; color: #94a3b8; }
            .pt-acc-head.is-open {
                background: var(--sc-teal); color: #fff; border-color: var(--sc-teal);
                border-bottom-left-radius: 0; border-bottom-right-radius: 0; margin-bottom: 0;
            }
            .pt-acc-head.is-open .pt-acc-chev { transform: rotate(180deg); color: #fff; }
            /* La section ouverte se raccorde visuellement à son en-tête */
            .pt-tab-content:not(.hidden) {
                border: 1px solid var(--sc-teal); border-top: 0;
                border-radius: 0 0 .75rem .75rem; padding: .875rem; background: #fff;
            }
        }

        /* ═══════════════════════════════════════════════════════════════
           👥 PAGE PATIENTS — mise en page mobile
           L'en-tête « Campagne Promotionnelle » empilait deux boutons pleine
           largeur au-dessus des filtres : le tableau était repoussé sous la
           ligne de flottaison. Sur mobile on compacte l'en-tête et on met les
           deux actions côte à côte.
           ═══════════════════════════════════════════════════════════════ */
        @media (max-width: 767px) {
            #tab-crm .bg-slate-50.p-4,
            #tab-crm .bg-slate-50.p-5 { padding: .75rem !important; }
            /* Titre + sous-titre de la campagne : plus compacts */
            #tab-crm h4 { font-size: .8125rem !important; }
            #tab-crm h4 + p { font-size: .6875rem !important; margin-top: .125rem !important; }
            /* Les deux boutons partagent la ligne au lieu de s'empiler */
            #tab-crm .flex.flex-wrap.gap-2.justify-center { flex-wrap: nowrap !important; gap: .5rem; width: 100%; }
            #tab-crm .flex.flex-wrap.gap-2.justify-center > button {
                flex: 1 1 0; min-width: 0; padding-left: .5rem !important; padding-right: .5rem !important;
                font-size: .6875rem !important; white-space: normal; line-height: 1.15;
            }
            #tab-crm .flex.flex-wrap.gap-2.justify-center > button i { margin-right: .25rem !important; }
            /* Filtres : recherche et ville sur une ligne, actions à droite */
            #tab-crm input[type="text"] { flex: 1 1 100% !important; }
            #tab-crm .px-4.py-4 { padding: .625rem .75rem !important; }
            /* Le tableau des patients devient lisible sans zoom */
            #tab-crm table { font-size: .8125rem; }
            #tab-crm #all-crm-body td { padding-top: .625rem !important; padding-bottom: .625rem !important; }
        }

        /* Mobile : supprimer le défilement imbriqué des tableaux.
           Le conteneur était limité en hauteur (184 px pour 917 px de contenu) :
           l'utilisateur devait faire défiler DANS le tableau, à l'intérieur de la
           page qui défile déjà. Sur petit écran, la page défile d'un seul bloc. */
        @media (max-width: 767px) {
            #tab-crm .table-container,
            #tab-rdv .table-container,
            #tab-facturation .table-container { overflow-y: visible !important; flex: none !important; height: auto !important; }
            #tab-crm .tab-content, #tab-crm > div { height: auto !important; min-height: 0 !important; }
            #tab-crm, #tab-rdv, #tab-facturation { height: auto !important; }
            /* Les deux boutons d'outils des filtres se placent côte à côte */
            #tab-crm .px-4.py-4 > .flex.gap-2,
            #tab-crm .px-4.py-4 > button { display: inline-flex; }
            #tab-crm .px-4.py-4 { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
            #tab-crm .px-4.py-4 > button { flex: 0 0 auto; }
        }
