/* =========================================================================
   TOOLS.CSS — composants maison
   -------------------------------------------------------------------------
   Tableau de données (MCTable), éditeur de texte enrichi (MCEditor), zone de
   texte auto-extensible (MCTextarea), liste déroulante (MCSelect), graphiques
   (MCCharts) et boîtes de dialogue (MCDialog). Le calendrier viendra ici.

   Dépend des jetons déclarés dans backend.css (--dominante-color, --dc-*,
   --fs-*, --btn-h-*, --radius-field, --panel, --line…) : charger après lui.

   Sommaire
     01. Tableau de données    barre d'outils, tri, pagination, mode carte
     02. Éditeur de texte      barre d'outils, zone d'édition, dialogues
     03. Zone de texte         hauteur automatique et compteur
     04. Liste déroulante      champ, panneau, options, recherche
     05. Graphiques            conteneurs à hauteur fixe et vignettes
     06. Dialogues             boîtes modales et notifications
   ========================================================================= */


/* Lato, réinstallée à la demande d'abdAllah (18/08) — UNIQUEMENT pour la
   pagination des datatables (.mc-pagination), pas pour le reste de
   l'interface (qui reste sur Open Sans, auto-hébergée — voir backend.css).
   Auto-hébergée ici aussi (même raison qu'Open Sans dans backend.css : un
   @import distant vers Google Fonts bloque le rendu tant que le serveur
   n'a pas répondu, sur un poste hors ligne ou derrière un DNS lent).
   Seules les graisses employées par .mc-pagination sont embarquées — 400
   et 700, woff2 seul. */

@font-face {
   font-family: 'Lato';
   font-style: normal;
   font-weight: 400;
   font-display: swap;
   src: url('../font/lato-latin-400-normal.woff2') format('woff2');
}

@font-face {
   font-family: 'Lato';
   font-style: normal;
   font-weight: 700;
   font-display: swap;
   src: url('../font/lato-latin-700-normal.woff2') format('woff2');
}


/* ========================================================================
   COMMUN — barres de défilement, jetons partagés
   ======================================================================== */

.mc-menu,
.mc-editor-toolbar-scroll,
.mc-editor-content,
.mc-table-scroll {
   scrollbar-width: thin;
   scrollbar-color: var(--dc-40-w, #9bbed0) transparent;
}

.mc-menu::-webkit-scrollbar,
.mc-editor-toolbar-scroll::-webkit-scrollbar,
.mc-editor-content::-webkit-scrollbar,
.mc-table-scroll::-webkit-scrollbar {
   width: 8px;
   height: 8px;
}

.mc-menu::-webkit-scrollbar-thumb,
.mc-editor-toolbar-scroll::-webkit-scrollbar-thumb,
.mc-editor-content::-webkit-scrollbar-thumb,
.mc-table-scroll::-webkit-scrollbar-thumb {
   border-radius: 4px;
   background: var(--dc-40-w, #9bbed0);
}

.mc-toolbar {
   display: flex;
   flex-wrap: wrap;
   align-items: center;
   gap: .4rem;
   padding: .5rem;
   border-bottom: 1px solid var(--mc-border);
}

.mc-toolbar-group {
   display: flex;
   align-items: center;
   gap: .35rem;
   flex-wrap: wrap;
}

.mc-toolbar-group.mc-grow {
   /* flex-grow à 0 (et non 1) : cette ligne n'a plus vocation à s'étirer pour
      occuper tout l'espace restant de la barre d'outils — 320px de base,
      qui peut rétrécir (flex-shrink:1) si la largeur manque. */
   flex: 0 1 320px;
   min-width: 0;
}

.mc-pagination {
   display: flex;
   flex-wrap: wrap;
   align-items: center;
   gap: .25rem;
   font-family: 'Lato', sans-serif;
}

.mc-footer,
.mc-editor-status,
.mc-textarea-counter {
   font-size: var(--fs-2xs);
}

.mc-toolbar,
.mc-footer {
   padding: .4rem .5rem;
   border-color: var(--line);
}

/* Fond clair de la charte sur la BARRE D'OUTILS et le PIED de tableau : ils
   encadrent les lignes, et s'y confondaient sans lui (abdAllah, 23/08, étendu
   à `.mc-toolbar` le 09/09).

   `--dc-7-w` : la teinte des onglets `.nav-tabs`, générée par mc-theme.js à
   partir de la dominante — elle suit donc la couleur choisie par
   l'établissement. Le repli reprend celui des onglets. */
.mc-toolbar,
.mc-footer,
.mc-info {
   /* `!important` : `.mc-info` est posée par mc-table.js dans un conteneur qui
      lui donne déjà un fond, qu'une règle simple ne surcharge pas. */
   background: var(--dc-7-w, #eef4f7) !important;
}

[data-theme="dark"] .mc-table-wrapper,
[data-theme="dark"] .mc-editor-shell {
   --mc-surface: var(--panel);
   --mc-surface-alt: var(--panel-soft);
   --mc-border: var(--line);
   --mc-text: #f3f4f7;
   --mc-muted: var(--slate);
}

.mc-table-wrapper,
.mc-editor-shell {
   --mc-border: var(--line);
   --mc-muted: var(--slate);
}

.mc-toolbar .mc-btn {
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   border-color: var(--line);
   color: var(--dominante-color);
   font-weight: var(--fw-bold);
}

.mc-toolbar .mc-btn:hover,
.mc-toolbar .mc-btn:focus-visible,
.mc-toolbar .mc-btn[aria-expanded="true"] {
   background: var(--dc-20-t, rgba(6, 93, 137, .2));
   border-color: var(--dominante-color);
   color: var(--dominante-color);
}

[data-theme="dark"] .mc-toolbar .mc-btn {
   background: var(--dc-20-t, rgba(6, 93, 137, .2));
   color: var(--dc-60-w, #6b9fba);
}

[data-theme="dark"] .mc-toolbar .mc-btn:hover,
[data-theme="dark"] .mc-toolbar .mc-btn:focus-visible,
[data-theme="dark"] .mc-toolbar .mc-btn[aria-expanded="true"] {
   background: var(--dc-30-t, rgba(6, 93, 137, .3));
}

@media (max-width:767.98px) {
   .mc-search input,
   .mc-select,
   .mc-tool-select,
   .mc-dialog-body input,
   .mc-dialog-body select,
   .mce-dialog-body input,
   .mce-dialog-body select {
      font-size: 16px;
   }

   .mc-toolbar-group.mc-grow {
      flex: 1 1 100%;
      order: -1;
   }

   .mc-footer {
      justify-content: center;
      text-align: center;
   }

   .mc-table-wrapper.mc-cards table.mc-table thead {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip: rect(0 0 0 0);
      white-space: nowrap;
   }

   .mc-table-wrapper.mc-cards table.mc-table,
   .mc-table-wrapper.mc-cards table.mc-table tbody,
   .mc-table-wrapper.mc-cards table.mc-table tr,
   .mc-table-wrapper.mc-cards table.mc-table td {
      display: block;
      width: 100%;
   }

   .mc-table-wrapper.mc-cards table.mc-table tr {
      margin: .5rem;
      border: 1px solid var(--mc-border);
      border-left: 4px solid var(--mc-accent);
      border-radius: var(--mc-radius);
      background: var(--mc-surface);
      overflow: hidden;
   }

   .mc-table-wrapper.mc-cards table.mc-table tbody tr:nth-child(even) {
      background: var(--mc-surface-alt);
   }

   .mc-table-wrapper.mc-cards table.mc-table td:last-child {
      border-bottom: none;
   }

   .mc-table-wrapper.mc-cards table.mc-table td::before {
      content: attr(data-label);
      flex: 0 0 40%;
      color: var(--mc-muted);
      font-size: .75rem;
      font-weight: 700;
      text-align: left;
      text-transform: uppercase;
      letter-spacing: .02em;
   }

   .mc-table-wrapper.mc-cards table.mc-table td {
      display: flex;
      align-items: baseline;
      justify-content: space-between;
      gap: .75rem;
      padding: .4rem .7rem;
      border: none;
      border-bottom: 1px dashed var(--mc-border);
      text-align: right;
   }

   .mc-btn,
   .mc-select,
   .mc-page-btn,
   .mc-search input,
   .btn {
      min-height: var(--btn-h-lg);
   }

   .mc-tool,
   .mc-tool-select,
   .mc-tool-color {
      height: var(--btn-h-lg);
   }

   .mc-tool {
      min-width: var(--btn-h-lg);
   }

   .mc-tool-color {
      width: var(--btn-h-lg);
   }

}

@media print {
   .mc-toolbar,
   .mc-footer,
   .mc-loading {
      display: none;
   }

   .mc-table-wrapper {
      --mc-border: #999;
   }

   table.mc-table thead th {
      position: static;
      color: #000;
      background: #eee;
      -webkit-print-color-adjust: exact;
      print-color-adjust: exact;
   }

}

@media (min-width:768px) {
   .mc-textarea-wrap textarea {
      font-size: .95rem;
   }

}

@-webkit-keyframes mc-spin {
   to {
      -webkit-transform: rotate(360deg);
   }
}

@keyframes mc-spin {
   to {
      transform: rotate(360deg);
   }
}

/* ========================================================================
   01. TABLEAU DE DONNÉES (MCTable) — barre d'outils, tri, pagination, cartes
   ======================================================================== */

.mc-table-wrapper {
   --mc-accent: var(--dominante-color, #065d89);
   --mc-border: rgba(0, 0, 0, .12);
   --mc-surface: #fff;
   --mc-surface-alt: rgba(0, 0, 0, .03);
   --mc-text: #111;
   --mc-muted: #6c757d;
   --mc-radius: .5rem;
   position: relative;
   display: block;
   width: 100%;
   color: var(--mc-text);
   font-family: inherit;
}

[data-theme="dark"] .mc-table-wrapper {
   --mc-border: rgba(255, 255, 255, .18);
   --mc-surface: #2c2c2c;
   --mc-surface-alt: rgba(255, 255, 255, .05);
   --mc-text: #f1f1f1;
   --mc-muted: #adb5bd;
}

.mc-btn {
   -webkit-appearance: none;
   appearance: none;
   display: inline-flex;
   /* `center` centre les BOÎTES, pas les lignes de texte (abdAllah, 07/09) :
      l'icône Phosphor porte sa propre hauteur de ligne, plus haute que celle du
      libellé, et le texte remontait de deux ou trois pixels.

      `line-height: 1` sur les deux enfants les ramène à la même assise. */
   align-items: center;
   justify-content: center;
   gap: .35rem;
   min-height: 38px;
   padding: .35rem .7rem;
   border: 1px solid var(--mc-border);
   border-radius: var(--mc-radius);
   background: var(--mc-surface);
   color: var(--mc-text);
   font-size: .85rem;
   line-height: 1.2;
   cursor: pointer;
   white-space: nowrap;
   transition: background .15s ease, border-color .15s ease, color .15s ease;
}

/* UN BOUTON RÉDUIT, pour les listes étroites : la taille `sm` de Bootstrap
   reste haute quand la ligne ne porte qu'un nom de fichier. */
/* LA ZONE DE DÉPÔT reprend le fond des icônes de champs : elle appartient au
   formulaire, pas au fond de la modale. */
/* LA PASTILLE DANS UN `input-group` : elle en prend la hauteur et le coin
   arrondi de droite, `mc-couleur-swatch` étant taillée pour une grille. */
.input-group > .mc-couleur-swatch {
   flex: 0 0 40%;
   min-height: 38px;
   /* SANS GRAS : `mc-couleur-swatch` en porte pour les pastilles serrées des
      configurations. Ici le rendu doit être FIDÈLE à la cellule du tableau, qui
      n'en a pas. */
   font-weight: var(--fw-normal, 400);
   border-radius: 0 var(--mc-radius, .375rem) var(--mc-radius, .375rem) 0;
   border-left: 0;
   font-size: .84rem;
   overflow: hidden;
   white-space: nowrap;
   text-overflow: ellipsis;
}

/* LES SECTEURS en tuiles, quatre par ligne (abdAllah, 07/09).

   Le motif est celui des filières, avec deux différences : la grille est fixée
   à quatre colonnes plutôt que laissée au flux, et les cartes sont PLATES —
   `mc-filiere-carte` porte une ombre portée dont on ne veut pas ici. */
/* LES JUSTIFICATIFS côte à côte : le nombre de colonnes est posé par le script,
   selon le nombre de pièces. */
.mc-pieces-grille {
   display: grid;
   gap: .6rem;
}

.mc-piece-media {
   display: block;
   width: 100%;
   height: 30vh;
   max-height: 30vh;
   object-fit: contain;
}

@media (max-width: 767.98px) {
   .mc-pieces-grille {
      grid-template-columns: 1fr !important;
   }

   .mc-piece-media {
      height: 24vh;
   }
}

.mc-secteur-grille {
   display: grid;
   grid-template-columns: repeat(4, 1fr);
   gap: .4rem;
}

@media (max-width: 767.98px) {
   .mc-secteur-grille {
      grid-template-columns: repeat(2, 1fr);
   }
}

/* LES TUILES APPARAISSENT une à une (abdAllah, 09/09) : à l'ouverture de la
   modale, dix pastilles surgissant d'un coup donnaient une impression de saut.

   `prefers-reduced-motion` la coupe pour qui l'a demandé. */
@keyframes mcTuileEntree {
   from { opacity: 0; transform: translateY(.25rem); }
   to   { opacity: 1; transform: none; }
}

.mc-secteur-carte {
   animation: mcTuileEntree .25s ease both;
}

@media (prefers-reduced-motion: reduce) {
   .mc-secteur-carte {
      animation: none;
   }
}

.mc-secteur-carte {
   position: relative;
   display: flex;
   flex-direction: column;
   justify-content: space-between;
   gap: .4rem;
   min-height: 4.2rem;
   padding: .5rem .6rem;
   border-radius: var(--radius-field, .375rem);
   font-size: .84rem;
}

.mc-secteur-libelle {
   overflow-wrap: anywhere;
   line-height: 1.25;
}

.mc-secteur-actions {
   display: flex;
   justify-content: flex-end;
   gap: .15rem;
}

.mc-secteur-action-form {
   display: inline;
   margin: 0;
}

/* Le BOUTON est nu : il ne porte que son icône, sur le fond de la carte. */
.mc-secteur-action {
   padding: 0 .15rem;
   border: 0;
   background: none;
   font-size: 1.05rem;
   line-height: 1;
   cursor: pointer;
   opacity: .75;
   transition: opacity .15s ease;
}

.mc-secteur-action:hover,
.mc-secteur-action:focus-visible {
   opacity: 1;
}

.mc-depot-zone {
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   border: 2px dashed var(--mc-border, #ced4da);
   border-radius: .5rem;
   cursor: pointer;
   transition: background .15s ease, border-color .15s ease;
}

.mc-depot-zone:hover {
   background: var(--dc-20-t, rgba(6, 93, 137, .2));
}

/* LES FICHIERS EN ATTENTE, à l'allure d'un bouton secondaire : ils réagissent au
   survol — l'aperçu s'y ouvre — et doivent le montrer. */
/* DANS UN `input-group`, le cadre prend la place restante et perd ses coins de
   droite : le bouton s'y soude. */
/* LA RANGÉE ne se replie PAS : `input-group` porte `flex-wrap: wrap`, et un nom
   de fichier long poussait le bouton à la ligne suivante. */
/* UN GROUPE DÉSACTIVÉ grise en entier (abdAllah, 08/09) : Bootstrap ne touche
   que le champ, l'icône restait claire et la bordure paraissait incomplète.

   `:has()` cible le groupe depuis l'état de son champ — sans lui, il faudrait
   une classe posée à la main sur chaque groupe désactivé. */
/* UN SELECT DÉSACTIVÉ GARDE SON RETRAIT (abdAllah, 09/09) : `mc-select.js` ne
   l'habille pas — il n'y a rien à ouvrir — et c'est donc le champ natif qu'on
   voit. Une règle du projet le mettait à `padding: 0`, et son texte collait au
   bord.

   `.75rem` : la valeur que Bootstrap donne à ses champs. */
.form-select:disabled,
.mc-combo-disabled .form-select {
   padding-left: .75rem;
}

.input-group:has(> .form-select:disabled) > .input-group-text,
.input-group:has(> .form-control:disabled) > .input-group-text,
.input-group:has(> .form-control[readonly]) > .input-group-text {
   background: var(--bs-secondary-bg, #e9ecef);
   opacity: 1;
}

/* UN CHAMP EN LECTURE SEULE SE GRISE AUSSI (abdAllah, 09/09) : Bootstrap le
   laisse blanc, indistinct d'un champ ouvert à la saisie.

   La banque et le numéro de chèque passent en `readonly` hors chèque — le champ
   part alors avec le formulaire, là où `disabled` l'aurait effacé. Mais rien ne
   disait qu'il était fermé. */
.form-control[readonly] {
   background: var(--bs-secondary-bg, #e9ecef);
}

/* LE GROUPE DE TYPES à la HAUTEUR d'un champ : `btn-sm` le laissait plus court,
   et la ligne Date / Type paraissait bancale.

   `--btn-h-md` est la mesure des `form-control` du projet. */
/* LE TYPE DE VERSEMENT (abdAllah, 08/09) : chaque bouton porte EN PERMANENCE le
   pastel de son badge, on reconnaît ce qu'on va choisir avant de cliquer.

   LE CHOIX SE MARQUE PAR LE GRIS — l'inverse de l'habitude, mais le seul moyen
   de le distinguer sur un groupe déjà coloré.

   La HAUTEUR ne demande rien : `btn-sm` retiré du balisage, le bouton reprend
   celle des champs. */
.mc-type-choix {
   background: var(--mc-type-fond) !important;
   color: var(--mc-type-texte) !important;

   /* SANS GRAS, en plus petit : trois mots côte à côte, l'appui du gras les
      rendait lourds.
      
      `!important` : `btn` pose sa taille par `--bs-btn-font-size`, qu'une règle
      ordinaire ne bat pas. */
   font-size: .75rem !important;
   font-weight: var(--fw-normal, 400);
   /* LE PADDING RÉDUIT : trois libellés dans une colonne de sept, ils étaient à
      l'étroit sur un écran moyen. */
   padding-left: .4rem;
   padding-right: .4rem;

   /* LES NON CHOISIS S'EFFACENT par l'opacité, plutôt que de virer au gris :
      la couleur reste lisible, seul le contraste dit lequel est retenu. */
   opacity: .45;
   transition: opacity .15s ease;
}

.mc-type-choix:hover {
   opacity: .75;
}

.btn-check:checked + .mc-type-choix {
   opacity: 1;
}

/* UN GROUPE FIGÉ (abdAllah, 09/09) : la fiche d'un foyer ne saisit que des
   cotisations, mais doit pouvoir AFFICHER une donation issue d'un trop-perçu.

   D'où `data-mc-fige` plutôt que `disabled` : un bouton désactivé ne peut pas
   être coché, et le type reçu se perdait.

   LE BOUTON COCHÉ garde sa couleur — c'est le type réel. Les autres s'effacent,
   et le script les rend inertes au clic. */
/* L'ENTRÉE « AJOUTER » d'un combo à saisie libre (abdAllah, 09/09) : elle
   propose ce que le staff vient de taper, quand aucune option ne correspond.

   EN TÊTE et DISTINCTE : un liseré la sépare des valeurs existantes, sans quoi
   on la prendrait pour l'une d'elles. */
.mc-combo-option-libre {
   border-bottom: 1px solid var(--line, #dee2e6);
   font-style: italic;
}

.mc-combo-option-libre > i {
   margin-right: .3rem;
   opacity: .7;
}

/* mc-suggestion.js — la liste qui paraît au focus d'un champ libre
   (abdAllah, 09/09).

   MÊME HABILLAGE que le panneau de `mc-select.js` : le staff y retrouve ses
   repères, et rien ne dit que ce sont deux composants distincts. */
.mc-suggestion-panneau {
   position: absolute;
   z-index: 1056;
   top: 100%;
   left: 0;
   right: 0;

   /* `1056` : au-dessus d'une modale Bootstrap, qui monte à 1055. Sans cela le
      panneau se glissait DERRIÈRE le formulaire. */
   max-height: 14rem;
   overflow-y: auto;
   margin-top: .15rem;
   padding: .25rem;
   border: 1px solid var(--line, #dee2e6);
   border-radius: var(--radius-md, .375rem);
   background: var(--mc-surface, #fff);
   box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .1);
}

.mc-suggestion-entree {
   padding: .35rem .6rem;
   border-radius: var(--radius-sm, .25rem);
   cursor: pointer;
   font-size: var(--fs-sm);
}

.mc-suggestion-entree:hover,
.mc-suggestion-active {
   background: var(--dc-7-w, #eef4f7);
}

.mc-suggestion-vide {
   padding: .35rem .6rem;
   color: var(--slate-dim, #6c757d);
   font-size: var(--fs-sm);
   font-style: italic;
}

[data-mc-fige] .btn-check:not(:checked) + .mc-type-choix {
   opacity: .25;
   cursor: not-allowed;
}

/* UN TYPE INDISPONIBLE perd sa couleur (abdAllah, 08/09) : `disabled` sur le
   radio ne touche pas au `label` qui le suit, et le bouton gardait son pastel
   comme s'il restait choisissable.

   Sur la fiche d'un foyer, seule la cotisation se saisit. */
.btn-check:disabled + .mc-type-choix {
   background: var(--bs-secondary-bg, #e9ecef) !important;
   border-color: var(--bs-border-color, #dee2e6) !important;
   color: var(--bs-secondary, #6c757d) !important;
   opacity: .55;
   cursor: not-allowed;
   pointer-events: none;
}

.mc-piece-rangee {
   flex-wrap: nowrap;
}

.input-group > .mc-piece-attente {
   flex: 1 1 auto;
   /* `min-width: 0` autorise le rétrécissement : sans lui, un enfant flex ne
      descend pas sous la largeur de son contenu. */
   min-width: 0;
   overflow: hidden;
   /* LA MARGE est portée ICI et non par `p-1` : cette classe utilitaire de
      Bootstrap porte `!important`, qu'aucune règle ordinaire ne bat. */
   padding: .25rem .25rem .25rem .5rem;
   border-radius: var(--mc-radius, .375rem) 0 0 var(--mc-radius, .375rem);
   border-right: 0;
}

.mc-piece-attente {
   font-size: .84rem;
   background: var(--bs-secondary-bg, #e9ecef);
   border: 1px solid var(--bs-border-color, #dee2e6);
   color: var(--bs-body-color, #212529);
   transition: background .15s ease, border-color .15s ease;
}

/* LES NOUVELLES PIÈCES, pas encore enregistrées : une bordure à gauche les
   distingue de celles qui le sont. */
.mc-piece-neuve {
   border-left: 4px solid var(--bs-secondary, #6c757d) !important;
}

.mc-piece-attente:hover {
   background: var(--bs-secondary-border-subtle, #ced4da);
   border-color: var(--bs-secondary, #6c757d);
}


/* LE BOUTON DES PIÈCES porte une icône ET un compteur : `btn-actions` fixe sa
   largeur, où les deux se serraient. On lui rend sa largeur naturelle, sans
   écart entre les deux signes. */
.btn-actions.mc-pieces-voir {
   width: auto;
   min-width: 2.25rem;
   padding-left: .35rem;
   padding-right: .35rem;
   gap: .1rem;
}

.mc-btn-mini {
   --bs-btn-padding-y: .05rem;
   --bs-btn-padding-x: .2rem;
   --bs-btn-font-size: .65rem;
   line-height: 1;
}

.mc-btn-mini > i {
   line-height: 1;
}

/* `btn-actions` pose une largeur FIXE (abdAllah, 07/09) : les variables Bootstrap
   ne peuvent rien contre elle. On la redéclare, avec la spécificité de deux
   classes pour l'emporter. */
.btn-actions.mc-btn-mini {
   width: 1.5rem;
   height: 1.4rem;
   min-height: 0;
}

/* DANS UN `input-group`, le bouton s'aligne sur le cadre : Bootstrap ne pose
   aucune hauteur sur les enfants d'un groupe, `align-items: stretch` du
   conteneur s'en charge.

   Encore faut-il ne rien figer : `mc-btn-mini` posait une hauteur, et l'icône
   Phosphor en imposait une autre par sa taille. */
.input-group > .btn-actions.mc-btn-mini {
   height: auto !important;
   min-height: 0;
   /* `margin-bottom: 3px` (abdAllah, 08/09) : `backend.css` la pose sur `.btn`,
      et c'est elle qui laissait le bouton court de trois pixels sous le cadre.
      
      Cherchée longtemps du côté de la hauteur et de l'icône, elle était dans la
      marge. */
   margin-bottom: 0;
   flex-shrink: 0;
   /* L'ICÔNE respire : `btn-actions` pose `padding-left: 0` et
      `padding-right: 0`, taillés pour un bouton carré de colonne. */
   padding-left: .4rem;
   padding-right: .4rem;
   width: auto;
   border-radius: 0 var(--mc-radius, .375rem) var(--mc-radius, .375rem) 0;
}

.mc-btn > i,
.mc-btn > span {
   line-height: 1;
}

.mc-btn:hover,
.mc-btn:focus-visible {
   border-color: var(--mc-accent);
   color: var(--mc-accent);
}

.mc-btn:focus-visible {
   outline: 2px solid var(--mc-accent);
   outline-offset: 1px;
}

.mc-btn[aria-pressed="true"] {
   background: var(--mc-accent);
   border-color: var(--mc-accent);
   color: #fff;
}

/* Le champ est un <input type="search"> : WebKit y dessine SA PROPRE croix
   d'effacement, qui venait doubler celle du composant. On l'efface plutôt que
   de renoncer à la nôtre — la native ne se met pas à la charte, ne prévient
   pas le composant et disparaît hors de WebKit, où la croix manquerait alors.

   appearance: none est nécessaire en plus sur certaines versions, le
   pseudo-élément n'étant pas atteignable seul. */
.mc-recherche[type="search"] {
   -webkit-appearance: none;
   appearance: none;
}

.mc-recherche[type="search"]::-webkit-search-cancel-button,
.mc-recherche[type="search"]::-webkit-search-decoration {
   -webkit-appearance: none;
   appearance: none;
   display: none;
}

/* Bootstrap carre les DEUX côtés du champ (`.input-group > :not(:first-
   child)`, `:not(:last-child)`) parce que .mc-search-clear le SUIT dans le
   DOM — bien qu'en position:absolute, donc hors du flux visuel, il compte
   quand même comme un frère suivant pour ces sélecteurs purement
   structurels. Le champ perdait ainsi son arrondi À DROITE aussi, alors que
   rien ne le touche visuellement de ce côté. Ne force que le côté droit :
   le côté gauche doit rester carré, pour rejoindre la loupe. */
.mc-recherche {
   border-top-right-radius: var(--radius-field) !important;
   border-bottom-right-radius: var(--radius-field) !important;
}

.mc-search-clear {
   position: absolute;
   right: .25rem;
   border: none;
   background: none;
   color: var(--mc-muted);
   font-size: 1.1rem;
   line-height: 1;
   width: 1.6rem;
   height: 1.6rem;
   cursor: pointer;
   border-radius: 50%;
}

.mc-menu[hidden] {
   display: none;
}

.mc-table-scroll {
   width: 100%;
   overflow-x: auto;
   -webkit-overflow-scrolling: touch;
   padding: 2px;
}

table.mc-table th,
table.mc-table td {
   padding: .55rem .6rem;
   border-bottom: 1px solid var(--mc-border);
   text-align: left;
   vertical-align: middle;
}

table.mc-table thead th.mc-sortable {
   cursor: pointer;
}

table.mc-table thead th .mc-th-inner {
   display: flex;
   align-items: center;
   gap: .35rem;
}

/* Colonne avatar/genre du tableau Abonnés (newsletter.php) — icône seule
   sans texte ni tri : le display:flex générique ci-dessus n'a aucun effet
   utile ici, juste retiré pour cette colonne précise. Classe dédiée (pas
   data-key, jamais reposé par mc-table.js sur le <th> reconstruit — voir
   le motif déjà établi pour className/style dans _readSchema()/render()). */
.mc-th-avatar-abonne .mc-th-inner {
   display: contents;
}

.mc-sort-icon {
   font-size: .7rem;
   opacity: .45;
}

th[aria-sort="ascending"] .mc-sort-icon,
th[aria-sort="descending"] .mc-sort-icon {
   opacity: 1;
}

table.mc-table tbody tr:nth-child(even) {
   background: var(--mc-surface-alt);
}

table.mc-table tbody tr:hover {
   background: var(--dc-8-t, rgba(6, 93, 137, .08));
}

table.mc-table tbody tr.mc-selected {
   background: var(--dc-16-t, rgba(6, 93, 137, .16));
}

.mc-empty {
   padding: 2rem 1rem;
   text-align: center;
   color: var(--mc-muted);
}

.mc-footer {
   display: flex;
   flex-wrap: wrap;
   align-items: center;
   justify-content: space-between;
   gap: .5rem;
   padding: .5rem;
   border-top: 1px solid var(--mc-border);
   font-size: .85rem;
   color: var(--mc-muted);
}

.mc-page-btn[aria-current="page"] {
   background: var(--mc-accent);
   border-color: var(--mc-accent);
   color: #fff;
   font-weight: 700;
}

/* Survol de la pagination, sur le modèle des autres boutons d'outils : le
   trait et le texte prennent la dominante.

   :not(:disabled) est indispensable — aux extrémités, « premier » et
   « précédent » sont désactivés, et les voir réagir au passage de la souris
   promettrait une action qui n'aura pas lieu.

   :not([aria-current]) épargne la page courante, déjà sur aplat plein : lui
   donner la dominante en texte la rendrait illisible sur son propre fond. */
.mc-page-btn:not(:disabled):not([aria-current="page"]):hover,
.mc-page-btn:not(:disabled):not([aria-current="page"]):focus-visible {
   border-color: var(--mc-accent);
   color: var(--mc-accent);
   background: var(--dc-8-t, rgba(6, 93, 137, .08));
}

.mc-page-btn:disabled {
   opacity: .45;
   cursor: not-allowed;
}

.mc-loading {
   position: absolute;
   inset: 0;
   display: flex;
   align-items: center;
   justify-content: center;
   background: rgba(255, 255, 255, .6);
   z-index: 3;
}

[data-theme="dark"] .mc-loading {
   background: rgba(0, 0, 0, .45);
}

.mc-loading[hidden] {
   display: none;
}

table.mc-table {
   width: 100%;
   border-collapse: collapse;
   font-size: var(--fs-sm);
   /* Cadre gauche/droit/bas autour de TOUTE la table (pas par ligne, voir
      .mc-table-bordures-lignes pour ce motif-là) — sur <table> elle-même,
      pas sur <tr>, donc pas concernée par le piège border-collapse:collapse
      déjà documenté pour les bordures posées sur une ligne. */
   border-left: 1px solid var(--line);
   border-right: 1px solid var(--line);
   border-bottom: 1px solid var(--line);
}

.btn,
.mc-btn {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   gap: .4em;
   min-height: var(--btn-h-md);
   padding: 0 var(--btn-px-md);
   font-size: var(--btn-fs-md);
   line-height: 1.2;
   border-radius: var(--radius-field);
}

.btn-sm {
   min-height: var(--btn-h-sm);
   padding: 0 var(--btn-px-sm);
   font-size: var(--btn-fs-sm);
}

table.mc-table thead th {
   position: sticky;
   top: 0;
   z-index: 2;
   background: var(--mc-accent);
   color: #fff;
   font-weight: var(--fw-bold);
   white-space: nowrap;
   -webkit-user-select: none;
   user-select: none;
   letter-spacing: .06em;
   padding: .4rem .6rem;
   font-size: .6875rem;
   text-transform: uppercase;
}

/* La MÊME référence, pour un tableau STANDARD — sans tri, pagination ni
   export, donc sans MCTable pour l'habiller. La liste des sessions en est le
   premier exemple : quelques lignes, rien à trier.

   `.table-mc-entete` se pose sur le <table>, comme table-striped/table-sm ;
   pas sticky ici, un tel tableau n'est jamais assez long pour le justifier.

   var(--dominante-color), PAS var(--mc-accent) : cette dernière n'est
   déclarée que dans la portée de .mc-table-wrapper (le composant MCTable) —
   un tableau standard qui n'en descend jamais ne la voit pas, et sans repli
   dans le var(), la propriété retombait sur transparent. --dominante-color,
   elle, est posée sur :root, visible de partout.

   !important : Bootstrap peint un box-shadow inset de 9999px sur CHAQUE
   cellule d'un .table (.table > :not(caption) > * > *, y compris les <th> de
   thead), au-dessus du fond — transparent en temps normal, mais rien ne
   garantit qu'une classe ajoutée plus tard (table-active, table-hover…) ne
   vienne un jour l'opacifier sur cette même ligne. Le fond de l'en-tête ne
   doit jamais dépendre de ce qui se passe ailleurs dans le tableau. */
.table-mc-entete thead th {
   background: var(--dominante-color, #065d89) !important;
   color: #fff !important;
   font-weight: var(--fw-bold);
   white-space: nowrap;
   letter-spacing: .06em;
   padding: .4rem .6rem;
   font-size: .6875rem;
   text-transform: uppercase;
}

/* Ligne de TOTAL en pied de tableau (ex. profils-stats.php) — même fond
   clair que .card-header (var(--dc-12-t)), donc "suit la charte" au sens
   propre : pas une couleur inventée pour l'occasion. Même !important que
   thead ci-dessus et pour la même raison documentée plus haut (le
   box-shadow inset de Bootstrap, transparent par défaut, mais jamais
   garanti de le rester si une classe ajoutée plus tard l'opacifie). */
.table-mc-entete tfoot td {
   background: var(--dc-12-t, rgba(6, 93, 137, .12)) !important;
}

/* Bordure gauche/droite sur chaque LIGNE du tableau (thead ET tbody),
   plutôt qu'un seul cadre autour de tout le bloc — border-left/right posée
   directement sur <tr> ne s'affiche pas de façon fiable avec
   border-collapse:collapse (comportement par défaut de `table`, voir
   bootstrap.css), donc ciblée ici sur la 1re/dernière cellule de chaque
   ligne à la place. `tr > *` couvre th et td en une seule règle. */
.mc-table-bordures-lignes tr > *:first-child {
   border-left: 1px solid var(--line);
}

.mc-table-bordures-lignes tr > *:last-child {
   border-right: 1px solid var(--line);
}

table.mc-table tbody td {
   /* `.2rem` en haut et en bas : la cellule qui porte des boutons d'action
      n'a plus besoin de la marge d'avant, ceux-ci ayant été réduits. */
   padding: .2rem .6rem;
   line-height: 1.35;
   border-bottom: 1px solid var(--line);
}

table.mc-table tbody tr:last-child td {
   border-bottom: 0;
}

.mc-select,
.mc-search input,
.mc-page-btn {
   min-height: var(--btn-h-md);
   border-radius: var(--radius-field);
   border-color: var(--line);
}

.mc-menu {
   position: absolute;
   z-index: 1050;
   top: calc(100% + 4px);
   left: 0;

   /* Le menu prend la largeur de son entrée la plus longue. Un plancher de
      190px l'étirait bien au-delà — « Copier », « CSV », « Excel » tiennent
      dans la moitié —, et les libellés flottaient dans le vide.

      Le plancher devient un plafond : max-content colle au contenu, et
      max-width l'empêche de déborder de la fenêtre si une entrée était longue,
      ce que max-content ne borne pas de lui-même. */
   width: max-content;
   max-width: min(90vw, 22rem);
   max-height: 60vh;
   overflow-y: auto;
   -webkit-overflow-scrolling: touch;
   padding: .3rem;
   border: 1px solid var(--mc-border);
   border-radius: var(--radius-field);
   background: var(--mc-surface);
   box-shadow: 0 6px 20px rgba(0, 0, 0, .18);
   border-color: var(--line);
}

.mc-page-btn {
   min-width: var(--btn-h-md);
   min-height: var(--btn-h-md);
   padding: .25rem .5rem;
   border: 1px solid var(--mc-border);
   border-radius: var(--radius-field);
   background: var(--mc-surface);
   color: var(--mc-text);
   font-size: .85rem;
   cursor: pointer;
}

/* Les quatre boutons de NAVIGATION — « ‹ › » — portent des chevrons, et non
   des chiffres : à la taille des numéros de page ils passaient inaperçus.
   Plus gros et plus gras, ils se distinguent de la suite des pages.

   La classe vient du JS, qui la pose sur ces quatre-là seulement : la donner à
   .mc-page-btn grossirait aussi les chiffres.

   line-height serré pour que la hauteur du bouton ne suive pas la police. */
.mc-page-nav {
   font-size: 1.35rem;
   font-weight: var(--fw-bold);
   line-height: 1;
}

/* ========================================================================
   02. ÉDITEUR DE TEXTE (MCEditor) — barre d'outils, édition, dialogues
   ======================================================================== */

.mc-editor-shell {
   --mc-accent: var(--dominante-color, #065d89);
   --mc-border: rgba(0, 0, 0, .15);
   --mc-surface: #fff;
   --mc-surface-alt: #f7f7f7;
   --mc-text: #111;
   --mc-muted: #6c757d;
   --mc-radius: .5rem;
   display: flex;
   flex-direction: column;
   border: 1px solid var(--mc-border);
   border-radius: var(--mc-radius);
   background: var(--mc-surface);
   color: var(--mc-text);
}

/* Coins arrondis posés sur le premier/dernier enfant visible (barre d'outils
   en haut, zone de texte OU barre de statut en dernier selon si elle existe)
   plutôt que overflow:hidden sur le conteneur — piège CONNU et documenté de
   longue date (TinyMCE : « floatpanels become unmoored » quand l'éditeur vit
   dans un ancêtre qui coupe l'overflow) : un menu déroulant du type
   Police/Taille qui doit s'échapper de la modale pour rester visible ne
   PEUT PAS le faire correctement si CE conteneur-ci coupe déjà tout, avant
   même la modale. Même rendu visuel, sans ce piège. */
.mc-editor-shell > :first-child {
   border-top-left-radius: var(--mc-radius);
   border-top-right-radius: var(--mc-radius);
}

.mc-editor-shell > :last-child {
   border-bottom-left-radius: var(--mc-radius);
   border-bottom-right-radius: var(--mc-radius);
   overflow: hidden;
}

[data-theme="dark"] .mc-editor-shell {
   --mc-border: rgba(255, 255, 255, .2);
   --mc-surface: #2c2c2c;
   --mc-surface-alt: #383838;
   --mc-text: #f1f1f1;
   --mc-muted: #adb5bd;
}

.mc-editor-shell:focus-within {
   border-color: var(--mc-accent);
   box-shadow: 0 0 0 .15rem var(--dc-18-t, rgba(6, 93, 137, .18));
}

.mc-editor-toolbar {
   position: sticky;
   top: 0;
   z-index: 2;
   padding: .3rem;
   background: var(--mc-surface-alt);
   border-bottom: 1px solid var(--mc-border);
}

/* Défilement horizontal isolé ICI, pas sur .mc-editor-toolbar : overflow-x
   pose AUSSI overflow-y (les deux axes ne peuvent pas rester "visible"
   indépendamment en CSS dès qu'un seul change) — posé sur le PARENT direct
   des boutons/selects, ça coupait tout menu déroulant voulant s'ouvrir
   au-delà de sa hauteur (Police, Taille…). Ici, seul CE sous-conteneur
   coupe — les selects, remontant leurs ancêtres, ne rencontrent plus que la
   modale elle-même comme overflow à contourner (déjà géré par mc-select.js). */
.mc-editor-toolbar-scroll {
   display: flex;
   flex-wrap: nowrap;
   align-items: center;
   gap: .15rem;
   overflow-x: auto;
   -webkit-overflow-scrolling: touch;
   scrollbar-width: thin;
}

/* Placée APRÈS la règle ci-dessus, à dessein : une version antérieure de
   cette variante grand écran existait AVANT la règle principale dans ce
   fichier — donc TOUJOURS écrasée par elle en cascade (même sélecteur, la
   dernière déclaration l'emporte), peu importe la largeur d'écran réelle.
   Ce n'était pas un bug de logique, juste d'ORDRE. */
@media (min-width: 768px) {
   .mc-editor-toolbar-scroll {
      flex-wrap: wrap;
      overflow-x: visible;
   }
}

.mc-editor-sep {
   flex: 0 0 auto;
   width: 1px;
   height: 22px;
   margin: 0 .2rem;
   background: var(--mc-border);
}

.mc-tool:hover {
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   color: var(--mc-accent);
}

.mc-tool:focus-visible {
   outline: 2px solid var(--mc-accent);
   outline-offset: -2px;
}

.mc-tool[aria-pressed="true"] {
   background: var(--mc-accent);
   color: #fff;
}

.mc-tool-select {
   flex: 0 0 auto;
   height: 38px;
   max-width: 150px;
   padding: 0 .4rem;
   border: 1px solid var(--mc-border);
   border-radius: calc(var(--mc-radius) - 2px);
   background: var(--mc-surface);
   color: var(--mc-text);
   font-size: .85rem;
}

.mc-editor-content:empty::before {
   content: attr(data-placeholder);
   color: var(--mc-muted);
   pointer-events: none;
}

.mc-editor-content img {
   max-width: 100%;
   height: auto;
}

.mc-editor-content table {
   width: 100%;
   border-collapse: collapse;
   margin: .5rem 0;
}

.mc-editor-content table td,
.mc-editor-content table th {
   border: 1px solid var(--mc-border);
   padding: .35rem .5rem;
}

.mc-editor-content blockquote {
   margin: .5rem 0;
   padding: .25rem .9rem;
   border-left: 4px solid var(--mc-accent);
   color: var(--mc-muted);
}

.mc-editor-content table thead th {
   background: var(--mc-surface-alt, rgba(0, 0, 0, .05));
}

.mce-cellule-numero {
   text-align: center;
   width: 3rem;
}

/* Condensé : posé sur la balise <table> elle-même (mce-table-condense), pas
   seulement dans l'éditeur — reste visible partout où ce contenu s'affiche
   ensuite. Sélecteur assez spécifique pour l'emporter sur le padding normal
   ci-dessus (même dans .mc-editor-content), sans avoir recours à !important. */
.mc-editor-content table.mce-table-condense td,
.mc-editor-content table.mce-table-condense th,
table.mce-table-condense td,
table.mce-table-condense th {
   padding: .15rem .35rem;
}

.mc-editor-content pre {
   padding: .6rem .8rem;
   border-radius: var(--mc-radius);
   background: var(--mc-surface-alt);
   overflow-x: auto;
}

.mc-editor-content a {
   color: var(--mc-accent);
}

/* Menu contextuel de tableau (clic droit dans une cellule) — voir
   _menuTableau() dans mc-editor.js. Nommé mce- (pas mc-dialog*) pour la
   même raison que le reste des dialogues de l'éditeur : éviter toute
   collision avec le système MCDialog de confirmations/alertes, qui
   utilise déjà ces préfixes ailleurs dans le projet. */
.mce-tablemenu {
   position: fixed;
   z-index: 1080;
   min-width: 220px;
   padding: .3rem;
   border: 1px solid var(--mc-border, rgba(0, 0, 0, .15));
   border-radius: .5rem;
   background: var(--mc-surface, #fff);
   box-shadow: 0 8px 28px rgba(0, 0, 0, .22);
}

[data-theme="dark"] .mce-tablemenu {
   background: #2c2c2c;
}

.mce-tablemenu-item {
   display: flex;
   align-items: center;
   gap: .5rem;
   width: 100%;
   padding: .45rem .6rem;
   border: 0;
   border-radius: .35rem;
   background: transparent;
   color: inherit;
   text-align: left;
   font-size: .9rem;
   cursor: pointer;
}

.mce-tablemenu-item .ph-duotone {
   font-size: 1.05rem;
   color: var(--dominante-color, #065d89);
   flex-shrink: 0;
}

.mce-tablemenu-danger .ph-duotone {
   color: inherit;
}

.mce-tablemenu-item:hover,
.mce-tablemenu-item:focus-visible {
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   outline: none;
}

.mce-tablemenu-danger {
   color: #b3261e;
}

[data-theme="dark"] .mce-tablemenu-danger {
   color: #ff8a8a;
}

.mce-tablemenu-sep {
   height: 1px;
   margin: .3rem .2rem;
   background: var(--mc-border, rgba(0, 0, 0, .15));
}

/* Sous-menu au survol (insérer plusieurs lignes/colonnes d'un coup) — voir
   _menuTableau() dans mc-editor.js. Positionné à droite de l'item par
   défaut ; sur un très petit écran, il resterait dans les limites du menu
   parent (déjà repositionné dans la fenêtre), sans logique séparée. */
.mce-tablemenu-avec-sous {
   position: relative;
}

.mce-tablemenu-chevron {
   position: absolute;
   right: .5rem;
   top: 50%;
   transform: translateY(-50%);
   font-size: .8rem;
}

.mce-tablemenu-sous {
   position: absolute;
   left: 100%;
   top: 0;
   z-index: 1;
   display: none;
   align-items: center;
   gap: .4rem;
   padding: .4rem .5rem;
   border: 1px solid var(--mc-border, rgba(0, 0, 0, .15));
   border-radius: .4rem;
   background: var(--mc-surface, #fff);
   box-shadow: 0 8px 28px rgba(0, 0, 0, .22);
}

[data-theme="dark"] .mce-tablemenu-sous {
   background: #2c2c2c;
}

.mce-tablemenu-sous-visible {
   display: flex;
}

.mce-tablemenu-sous-input {
   width: 4rem;
   min-height: 32px;
   padding: .25rem .4rem;
   border: 1px solid var(--mc-border, rgba(0, 0, 0, .15));
   border-radius: .35rem;
   background: transparent;
   color: inherit;
   text-align: center;
}

/* Poignée de redimensionnement de colonne — un fin repère sur le bord droit
   de chaque cellule d'en-tête, voir _preparerTableau()/
   _colonneRedimensionnerDebut() dans mc-editor.js. Invisible au repos,
   visible seulement au survol pour ne jamais gêner la lecture normale
   d'un tableau. */
/* Sélecteur de couleur de cellule — visible, posé SOUS la cellule (pas
   dessus), voir _celluleCouleur() dans mc-editor.js. */
.mce-cellule-couleur-flottante {
   position: fixed;
   z-index: 1080;
   width: 44px;
   height: 34px;
   padding: 2px;
   border: 1px solid var(--mc-border, rgba(0, 0, 0, .15));
   border-radius: .35rem;
   box-shadow: 0 4px 16px rgba(0, 0, 0, .25);
   cursor: pointer;
}

/* Sélection multi-cellules (glissement), voir _selectionnerPlage() dans
   mc-editor.js — un fond semi-transparent posé PAR-DESSUS la cellule
   (outline, pas background : ne masque jamais une couleur de fond déjà
   choisie pour cette cellule). */
.mce-cellule-selectionnee {
   outline: 2px solid var(--dominante-color, #065d89);
   outline-offset: -2px;
   position: relative;
}

.mce-cellule-selectionnee::after {
   content: '';
   position: absolute;
   inset: 0;
   background: var(--dc-20-t, rgba(6, 93, 137, .2));
   pointer-events: none;
}

/* Image sélectionnée — contour, barre flottante (Supprimer) au-dessus,
   poignée de redimensionnement au coin bas-droit. Voir _imageSelectionner()
   dans mc-editor.js. */
.mce-image-selectionnee {
   outline: 2px solid var(--dominante-color, #065d89);
   outline-offset: 2px;
}

.mce-image-barre {
   position: fixed;
   z-index: 1080;
}

.mce-image-poignee {
   position: fixed;
   z-index: 1080;
   width: 16px;
   height: 16px;
   border: 2px solid #fff;
   border-radius: 50%;
   background: var(--dominante-color, #065d89);
   box-shadow: 0 1px 4px rgba(0, 0, 0, .4);
}

.mce-image-poignee-largeur {
   cursor: ew-resize;
}

.mce-image-poignee-hauteur {
   cursor: ns-resize;
}

.mce-image-poignee-diagonale {
   cursor: nwse-resize;
}


.mce-col-resize {
   position: absolute;
   top: 0;
   right: -3px;
   bottom: 0;
   width: 6px;
   cursor: col-resize;
   user-select: none;
   z-index: 2;
}

.mce-col-resize:hover,
.mce-col-resize:active {
   background: var(--dominante-color, #065d89);
   opacity: .4;
}

.mc-editor-shell.mc-fullscreen {
   position: fixed;
   inset: 0;
   z-index: 1060;
   border-radius: 0;
   max-height: none;
}

.mc-editor-shell.mc-fullscreen .mc-editor-content {
   max-height: none;
   flex: 1 1 auto;
}

.mc-editor-status {
   display: flex;
   flex-wrap: wrap;
   align-items: center;
   justify-content: space-between;
   gap: .5rem;
   padding: .3rem .6rem;
   border-top: 1px solid var(--mc-border);
   background: var(--mc-surface-alt);
   color: var(--mc-muted);
   font-size: .75rem;
}

.mc-editor-path {
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
}

.mce-dialog-backdrop {
   position: fixed;
   inset: 0;
   z-index: 1070;
   display: flex;
   align-items: center;
   justify-content: center;
   padding: 1rem;
   background: rgba(0, 0, 0, .45);
}

.mce-dialog {
   width: 100%;
   max-width: 420px;
   max-height: 90vh;
   overflow-y: auto;
   border-radius: .6rem;
   background: var(--mc-surface, #fff);
   color: var(--mc-text, #111);
   box-shadow: 0 12px 40px rgba(0, 0, 0, .3);
}

[data-theme="dark"] .mce-dialog {
   background: #2c2c2c;
   color: #f1f1f1;
}

.mce-dialog-body {
   padding: 1rem;
}

.mce-dialog-field {
   flex: 1 1 0;
   margin-bottom: .8rem;
}

.mce-dialog-field-half {
   margin-bottom: 0;
}

.mce-dialog-body label {
   display: block;
   margin-bottom: .25rem;
   font-size: .85rem;
   font-weight: 700;
}

.mce-dialog-footer {
   display: flex;
   justify-content: flex-end;
   gap: .5rem;
   padding: .7rem 1rem;
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   border-top: 1px solid var(--mc-border, rgba(0, 0, 0, .15));
   border-radius: 0 0 .6rem .6rem;
}

/* Aperçu — une fenêtre bien plus large qu'une boîte de dialogue de
   formulaire ordinaire (celle-ci affiche un document entier, pas deux ou
   trois champs), voir MCEditor.showPreview(). */
/* Quatre boutons carrés (icône + libellé sur deux lignes), voir la fenêtre
   « Où placer le contenu importé ? » dans reglement.php. Générique,
   réutilisable si un autre choix multiple similaire se présente ailleurs. */
.mce-choix-import-grille {
   display: flex;
   gap: .6rem;
}

.mce-choix-import-btn {
   flex: 1 1 0;
   display: flex;
   flex-direction: column;
   align-items: center;
   gap: .4rem;
   padding: .9rem .4rem;
   border: 1px solid var(--mc-border, rgba(0, 0, 0, .15));
   border-radius: .5rem;
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   color: var(--dominante-color, #065d89);
   font-size: .8rem;
   line-height: 1.3;
   text-align: center;
   cursor: pointer;
}

.mce-choix-import-btn .ph-duotone {
   font-size: 1.6rem;
}

.mce-choix-import-btn:hover,
.mce-choix-import-btn:focus-visible {
   background: var(--dc-20-t, rgba(6, 93, 137, .2));
   outline: none;
}

.mce-choix-import-btn-danger {
   color: #b3261e;
   border-color: rgba(179, 38, 30, .3);
   background: rgba(179, 38, 30, .08);
}

.mce-choix-import-btn-danger:hover,
.mce-choix-import-btn-danger:focus-visible {
   background: rgba(179, 38, 30, .16);
}

[data-theme="dark"] .mce-choix-import-btn-danger {
   color: #ff8a8a;
   border-color: rgba(255, 138, 138, .3);
}

.mce-preview {
   max-width: 900px;
}

.mce-preview-body {
   max-height: 70vh;
   overflow-y: auto;
   overflow-x: hidden;
   line-height: 1.6;
   /* Même motif que .mc-editor-content (plus bas dans ce fichier) — sans
      lui, un mot long sans espace (URL, identifiant) ou une image encore
      non contrainte (voir .mce-preview-body img juste après) forçait un
      débordement horizontal, malgré .mce-preview { max-width: 900px; }
      ci-dessus qui ne borne que le DIALOGUE, pas son CONTENU. */
   word-wrap: break-word;
   overflow-wrap: break-word;
}

/* La MÊME contrainte que .mc-editor-content img — sans elle, une image
   s'affichait à sa taille naturelle ici mais contenue dans l'éditeur,
   donnant l'impression que les deux vues montrent des contenus différents
   alors que le HTML sous-jacent est rigoureusement identique. */
.mce-preview-body img {
   max-width: 100%;
   height: auto;
}

.mce-preview-body table {
   width: 100%;
   border-collapse: collapse;
   margin: .5rem 0;
}

.mce-preview-body table td,
.mce-preview-body table th {
   border: 1px solid var(--mc-border, rgba(0, 0, 0, .15));
   padding: .35rem .5rem;
}

.mce-preview-body table thead th {
   background: var(--mc-surface-alt, rgba(0, 0, 0, .05));
}

.mce-preview-body table.mce-table-condense td,
.mce-preview-body table.mce-table-condense th {
   padding: .15rem .35rem;
}

.mc-editor-content {
   min-height: 220px;
   max-height: 50vh;
   padding: .9rem 1rem;
   overflow-y: auto;
   -webkit-overflow-scrolling: touch;
   background: var(--mc-surface);
   color: var(--mc-text);
   font-size: var(--fs-base);
   line-height: var(--lh-loose);
   outline: none;
   word-wrap: break-word;
   overflow-wrap: break-word;
}

/* .card-body p { max-width: 72ch } (backend.css) borne la largeur d'un
   texte descriptif ORDINAIRE pour sa lisibilité — l'éditeur, lui, vit
   aussi dans une .card-body mais édite un DOCUMENT ENTIER, qui doit
   occuper toute la largeur disponible (comme le fait déjà un tableau
   inséré) plutôt que se retrouver comprimé à ~700px sans rapport avec la
   largeur réelle de la zone d'édition. */
.mc-editor-content p {
   max-width: none;
   /* Repris explicitement ici plutôt que de compter sur la règle globale
      `p { margin-bottom: .75rem; line-height: var(--lh-normal) }`
      (backend.css) : celle-ci cible directement l'élément <p>, donc
      l'EMPORTE sur le line-height plus généreux (--lh-loose) hérité de
      .mc-editor-content — un paragraphe de l'éditeur affichait un
      interlignage plus serré que prévu. */
   margin-bottom: .75rem;
   line-height: var(--lh-loose);
}

/* Filet de sécurité : defaultParagraphSeparator (posé côté JS, voir
   mc-editor.js) fait que Chrome insère des <p> plutôt que des <div> à
   chaque Entrée. Si un navigateur ignore ce réglage malgré tout, ce <div>
   garde au moins un espacement — sans cette règle, les lignes s'empilaient
   sans le moindre espace entre elles. */
.mc-editor-content > div {
   margin-bottom: .75rem;
   line-height: var(--lh-loose);
}

.mc-editor-content h1 {
   font-size: var(--fs-xl);
}

.mc-editor-content h2 {
   font-size: var(--fs-lg);
}

.mc-editor-content h3 {
   font-size: var(--fs-md);
}

.mce-dialog h3 {
   margin: 0;
   padding: .8rem 1rem;
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   border-bottom: 1px solid var(--mc-border, rgba(0, 0, 0, .15));
   border-radius: .6rem .6rem 0 0;
   font-size: var(--fs-md);
   color: var(--dominante-color, #065d89);
   font-weight: var(--fw-bold);
}

.mc-editor,
.mc-editor-toolbar,
.mc-editor-status {
   border-color: var(--line);
}

.mc-editor-toolbar .ph-duotone {
   font-size: 1rem;
}

.mc-tool {
   -webkit-appearance: none;
   appearance: none;
   flex: 0 0 auto;
   display: inline-flex;
   align-items: center;
   justify-content: center;
   min-width: var(--btn-h-md);
   height: var(--btn-h-md);
   padding: 0 .45rem;
   border: 1px solid transparent;
   border-radius: calc(var(--mc-radius) - 2px);
   background: none;
   color: var(--mc-text);
   font-size: .9rem;
   line-height: 1;
   cursor: pointer;
   transition: background .15s ease, color .15s ease;
}

/* .mc-tool-select/.mc-tool-color { height:var(--btn-h-md) } retirée :
   toujours écrasée plus loin par height:38px littéral sur chacun des 2
   sélecteurs séparément — jamais effective. */
.mc-tool-color {
   flex: 0 0 auto;
   width: var(--btn-h-md);
   height: 38px;
   padding: 2px;
   border: 1px solid var(--mc-border);
   border-radius: calc(var(--mc-radius) - 2px);
   background: var(--mc-surface);
   cursor: pointer;
}

@supports not (gap:1px) {
   .mc-editor-status>* {
      margin: 0 .25rem;
   }

}

@media (prefers-reduced-motion:reduce) {
   .mc-tool {
      transition: none;
   }

}

/* ========================================================================
   03. ZONE DE TEXTE (MCTextarea) — hauteur automatique et compteur
   ======================================================================== */

.mc-textarea-wrap {
   position: relative;
   display: block;
}

.mc-textarea-wrap textarea {
   display: block;
   width: 100%;
   min-height: 90px;
   overflow: hidden;
   resize: none;
   font-size: 16px;
   line-height: 1.5;
}

.mc-textarea-counter {
   display: block;
   margin-top: .15rem;
   text-align: right;
   font-size: .75rem;
   color: var(--mc-muted, #6c757d);
}

.mc-textarea-counter.mc-over {
   color: var(--state-error);
   font-weight: 700;
}

.mc-textarea-wrap>.input-group {
   width: 100%;
}

/* UN GROUPE DANS UNE COLONNE OCCUPE SA LARGEUR (abdAllah, 09/09) : Bootstrap le
   laisse à `width: auto`, et il se contentait de son contenu — un champ de
   montant faisait 113 px là où sa colonne en offrait 233.

   `.mc-combo` porte déjà `width: 100%`, d'où l'inégalité entre un combo et un
   champ ordinaire posés côte à côte. */
[class*="col-"] > .input-group {
   width: 100%;
}

.mc-textarea-wrap .input-group-text {
   align-items: flex-start;
   padding-top: .45rem;
}

.input-group>.mc-textarea-wrap {
   flex: 1 1 auto;
   width: 1%;
   min-width: 0;
}

/* ========================================================================
   04. LISTE DÉROULANTE (MCSelect) — remplace l'affichage natif du <select>
   ========================================================================
   La liste d'un <select> est dessinée par le système : ni le fond bleu de
   l'option survolée, ni la police ne sont accessibles au CSS. Le composant
   remplace cet affichage par du HTML ; le <select> reste dans le formulaire,
   masqué mais fonctionnel.
   ======================================================================== */

/* Le conteneur porte l'apparence du champ : bordure, fond, rayon, hauteur.
   Le bouton intérieur n'est qu'une ligne transparente. Ainsi une classe
   maison posée sur le <select> (ex. .sessionSelect) habille le composant
   sans que conteneur et champ se contredisent sur les dimensions. */
.mc-combo {
   position: relative;
   display: inline-flex;
   align-items: center;
   width: 100%;
   min-height: var(--btn-h-md);
   padding: .3rem .6rem;
   border: 1px solid var(--line);
   border-radius: var(--radius-field);
   background: var(--panel);
   color: inherit;
   font-size: var(--fs-sm);
   vertical-align: middle;
   cursor: pointer;
}

/* PAS AU SURVOL D'UN COMBO DÉSACTIVÉ (abdAllah, 08/09) : la bordure changeait
   de couleur sur le combo seul, sans l'icône à sa gauche — d'où un contour qui
   paraissait incomplet.
   
   `mc-combo-disabled` ne portait que l'opacité et le curseur. */
.mc-combo:not(.mc-combo-disabled):hover {
   border-color: var(--dominante-color);
}

.mc-combo:not(.mc-combo-disabled):focus-within,
.mc-combo-open {
   border-color: var(--dominante-color);
   box-shadow: 0 0 0 .15rem var(--dc-20-t, rgba(6, 93, 137, .2));
}

.mc-combo-disabled {
   opacity: .6;
   cursor: not-allowed;
}

/* Le <select> d'origine : invisible mais toujours en place et focalisable.
   Ni `display: none` ni `visibility: hidden` : la validation HTML5 doit
   pouvoir lui donner le focus pour afficher son message sur un champ requis. */
.mc-combo-native {
   position: absolute;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
   margin: 0;
   padding: 0;
   border: 0;
   opacity: 0;
   pointer-events: none;
}

/* Dans un groupe de champs, le composant se comporte comme un .form-select :
   il occupe la place restante au lieu de passer à la ligne sous l'affixe. */
.input-group > .mc-combo {
   flex: 1 1 auto;
   width: 1%;
   min-width: 0;
}

.input-group > .mc-combo:not(:first-child) {
   border-top-left-radius: 0;
   border-bottom-left-radius: 0;
}

/* Le message de validation est un frère du composant : sans la clause
   `has-validation`, le conteneur n'était plus le dernier enfant et perdait
   ses coins droits. Bootstrap applique exactement ce raisonnement à ses
   propres champs. */
.input-group:not(.has-validation) > .mc-combo:not(:last-child),
.input-group.has-validation > .mc-combo:nth-last-child(n+3) {
   border-top-right-radius: 0;
   border-bottom-right-radius: 0;
}

/* Champ en erreur : le message de Bootstrap est un frère du <select>, or
   celui-ci est désormais imbriqué. La classe posée par MCSelect rétablit
   le lien sans recourir à :has(), encore trop récent. */
.mc-combo-invalid {
   border-color: var(--state-error);
}

.mc-combo-invalid ~ .invalid-feedback {
   display: block;
}

/* Sélecteur de format de l'éditeur : MCSelect le remplace comme les autres,
   mais il reste un contrôle de barre d'outils — largeur au contenu, hauteur
   des autres boutons, pas d'étirement. */
.mc-combo.mc-tool-select {
   flex: 0 0 auto;
   width: auto;
   min-width: 7.5rem;
   max-width: 150px;
   min-height: var(--btn-h-md);
   padding: 0 .5rem;
   font-size: .85rem;
}

.mc-combo-field {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: .5rem;
   width: 100%;
   padding: 0;
   border: 0;
   background: none;
   color: inherit;
   font: inherit;
   text-align: left;
   line-height: 1.4;
   cursor: inherit;
}

.mc-combo-field:focus,
.mc-combo-field:focus-visible {
   outline: none;
}

.mc-combo-value {
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
}

.mc-combo-placeholder .mc-combo-value {
   color: var(--slate-dim);
}

.mc-combo-arrow {
   flex: 0 0 auto;
   display: inline-flex;
   color: var(--dominante-color);
   transition: transform .18s ease;
}

.mc-combo-open .mc-combo-arrow {
   transform: rotate(180deg);
}

.mc-combo-arrow .ph-duotone {
   font-size: 1rem;
}

/* ---------- Panneau déroulant ---------- */
.mc-combo-panel {
   position: absolute;
   z-index: 1060;
   top: calc(100% + 4px);
   left: 0;
   right: 0;
   border: 1px solid var(--line);
   border-radius: var(--radius-field);
   background: var(--panel);
   box-shadow: 0 8px 24px rgba(0, 0, 0, .18);
   overflow: hidden;
}

.mc-combo-up .mc-combo-panel {
   top: auto;
   bottom: calc(100% + 4px);
}

.mc-combo-panel[hidden] {
   display: none;
}

.mc-combo-search {
   padding: .35rem;
   border-bottom: 1px solid var(--line);
   background: var(--panel-soft);
}

.mc-combo-search input {
   width: 100%;
   min-height: var(--btn-h-sm);
   padding: .25rem .5rem;
   border: 1px solid var(--line);
   border-radius: var(--radius-field);
   background: var(--panel);
   color: inherit;
   font-size: var(--fs-sm);
}

.mc-combo-search input:focus {
   outline: none;
   border-color: var(--dominante-color);
}

.mc-combo-list {
   overflow-y: auto;
   -webkit-overflow-scrolling: touch;
   padding: .25rem;
}

.mc-combo-group {
   padding: .4rem .6rem .2rem;
   color: var(--slate-dim);
   font-size: var(--fs-2xs);
   font-weight: var(--fw-bold);
   text-transform: uppercase;
   letter-spacing: .05em;
}

.mc-combo-option {
   padding: .4rem .6rem;
   margin-bottom: 2px;
   border-radius: 3px;
   font-size: var(--fs-sm);
   line-height: 1.35;
   cursor: pointer;
   /* C'est ici que se joue la raison d'être du composant : le fond de
      l'option survolée suit la couleur d'interface, pas le bleu système. */
}

.mc-combo-option[hidden] {
   display: none;
}

/* Pastille texte d'une option (data-badge-droite) — pendant textuel de
   l'icône de droite. Volontairement discrète : elle qualifie l'option,
   elle ne doit pas concurrencer son libellé. */
.mc-combo-badge {
   flex: 0 0 auto;
   min-width: 1.35rem;
   text-align: center;
   background: var(--dominante-color);
   color: #fff;
   font-weight: var(--fw-bold);
   font-size: .7rem;
   line-height: 1.35rem;
   border-radius: .25rem;
   padding: 0 .25rem;
}

.mc-combo-option-icone-droite {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: .5rem;
}

.mc-combo-option-icone-droite .mc-combo-option-texte {
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
   min-width: 0;
}

/* Rendu riche (data-photo, mc-select.js) : photo/avatar à gauche, libellé
   au centre, sous-texte (ex. un âge) aligné à droite — même conteneur
   flex repris pour le champ visible fermé (.mc-combo-value-photo). */
.mc-combo-option-photo-ligne,
.mc-combo-value-photo {
   display: flex;
   align-items: center;
   gap: .5rem;
}

.mc-combo-option-photo {
   flex: 0 0 auto;
   width: 1.8rem;
   height: 1.8rem;
   border-radius: 50%;
   object-fit: cover;
}

.mc-combo-option-photo-ligne .mc-combo-option-texte,
.mc-combo-value-photo .mc-combo-option-texte {
   flex: 1 1 auto;
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
   min-width: 0;
}

/* PASTILLE sur fond dominante (abdAllah, 23/08) : en simple texte gris, le
   nombre disparaissait — trop pâle sur fond clair, et effacé par la couleur de
   filière sur les options colorées. Un fond plein le rend lisible quel que
   soit celui de l'option. */
.mc-combo-option-sous-texte {
   flex: 0 0 auto;
   margin-left: auto;
   background: var(--dominante-color, #065d89);
   color: var(--dominante-contrast, #fff);
   font-size: var(--fs-2xs);
   padding: .05rem .4rem;
   border-radius: 1rem;
   line-height: 1.4;
}

/* Sur l'option SÉLECTIONNÉE, le fond de la ligne est déjà la dominante : la
   pastille s'inverse pour rester détachée. */
.mc-combo-option[aria-selected="true"] .mc-combo-option-sous-texte {
   background: var(--dominante-contrast, #fff);
   color: var(--dominante-color, #065d89);
}

.mc-combo-active {
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   color: var(--dominante-color);
}

/* Les options à fond coloré (priorité…) posent leur couleur en style
   inline (mc-select.js) — ce fond l'emporterait sur .mc-combo-active,
   rendant le survol invisible. filter() se superpose sans écraser la
   couleur de fond elle-même, contrairement à background. */
.mc-combo-option-couleur.mc-combo-active {
   filter: brightness(0.92);
}

.mc-combo-option.mc-combo-active .ph-duotone {
   font-size: 1.1rem;
}

.mc-combo-option[aria-selected="true"] {
   background: var(--dominante-color);
   color: #ffffff;
   font-weight: var(--fw-bold);
}

/* Option COLORÉE et sélectionnée (abdAllah, 25/08) : la règle ci-dessus pose
   un texte blanc sur la couleur dominante, mais le fond de l'option vient d'un
   style INLINE que la feuille ne peut pas écraser. Le blanc restait donc sur un
   fond pâle — « Femme » sur rose devenait illisible.

   La couleur du texte revient à celle de l'option ; le choix reste marqué par
   la graisse et le liseré. */
.mc-combo-option-couleur[aria-selected="true"] {
   color: inherit;
   box-shadow: inset 3px 0 0 var(--dominante-color);
}

.mc-combo-option-disabled {
   opacity: .45;
   cursor: not-allowed;
}

.mc-combo-empty {
   padding: .7rem .6rem;
   color: var(--slate-dim);
   font-size: var(--fs-sm);
   text-align: center;
}

/* Cible tactile et absence de zoom iOS */
@media (max-width: 767.98px) {
   .mc-combo {
      min-height: var(--btn-h-lg);
      font-size: 16px;
   }

   .mc-combo-option {
      padding: .55rem .6rem;
      font-size: 16px;
   }

   .mc-combo-search input {
      font-size: 16px;
   }

   /* 50vh (défaut, grand écran) occupe une bonne partie de l'écran visible
      en mobile — un doigt qui glisse À L'INTÉRIEUR de cette zone (son propre
      overflow-y:auto) fait défiler ELLE, pas la modale qui la contient,
      donnant l'impression que la modale entière est figée. Moins de
      hauteur ici laisse plus de marge pour toucher la modale ailleurs. */
   .mc-editor-content {
      max-height: 40vh;
   }
}

/* ========================================================================
   05. GRAPHIQUES (MCCharts / Chart.js)
   ========================================================================
   Chart.js dessine dans un <canvas> qu'il redimensionne lui-même : sans
   conteneur de hauteur fixe, il s'agrandit à chaque rendu jusqu'à remplir
   la page. D'où `.chart-box`, en position absolue.
   ======================================================================== */

.chart-box {
   position: relative;
   width: 100%;
   height: 140px;
}

.chart-box canvas {
   position: absolute;
   top: 0;
   left: 0;
   width: 100% !important;
   height: 100% !important;
}

/* Vignette de la bibliothèque de modèles */
.chart-tile {
   height: 100%;
   padding: .7rem .8rem;
   border: 1px solid var(--line);
   border-radius: var(--radius-field);
   background: var(--panel-soft);
}

.chart-tile-label {
   margin-bottom: .4rem;
   color: var(--slate);
   font-size: var(--fs-2xs);
   font-weight: var(--fw-bold);
   text-transform: uppercase;
   letter-spacing: .05em;
}

@media (max-width: 575.98px) {
   .chart-box {
      height: 120px;
   }
}

/* ========================================================================
   06. BOÎTES DE DIALOGUE ET NOTIFICATIONS (MCDialog)
   ========================================================================
   Remplace SweetAlert2. Les couleurs sémantiques sont déclarées ici : elles
   ne servent qu'aux dialogues et aux notifications.
   ======================================================================== */

.mc-dialog-backdrop {
   position: fixed;
   inset: 0;
   top: 0;
   right: 0;
   bottom: 0;
   left: 0;
   z-index: 1090;
   display: flex;
   align-items: center;
   justify-content: center;
   padding: 1rem;
   background: rgba(0, 0, 0, .45);
   opacity: 0;
   transition: opacity .18s ease;
}

.mc-dialog-shown {
   opacity: 1;
}

body.mc-dialog-open {
   overflow: hidden;
}

.mc-dialog {
   width: 100%;
   max-width: 26rem;
   padding: 1.5rem 1.5rem 1.25rem;
   border: 1px solid var(--line);
   border-radius: var(--radius-field);
   background: var(--panel);
   color: inherit;
   text-align: center;
   box-shadow: 0 18px 48px rgba(0, 0, 0, .28);
   transform: translateY(-8px) scale(.97);
   transition: transform .18s ease;
   outline: none;
}

.mc-dialog-shown .mc-dialog {
   transform: none;
}

.mc-dialog-icon {
   margin-bottom: .5rem;
   line-height: 1;
}

.mc-dialog-icon .ph-duotone {
   font-size: 3.25rem;
}

.mc-dialog-icon-success {
   color: var(--state-success);
}

.mc-dialog-icon-error {
   color: var(--state-error);
}

.mc-dialog-icon-warning {
   color: var(--state-warning);
}

.mc-dialog-icon-info,
.mc-dialog-icon-question {
   color: var(--dominante-color);
}

.mc-dialog-title {
   margin: 0 0 .35rem;
   font-size: var(--fs-lg);
   font-weight: var(--fw-bold);
   line-height: var(--lh-snug);
}

.mc-dialog-body {
   margin-bottom: 1.1rem;
   color: var(--slate);
   font-size: var(--fs-sm);

   /* pre-line honore les retours à la ligne du message sans rien exiger de
      plus : un texte peut ainsi se donner sur deux lignes sans passer par du
      balisage, ce qu'on évite quand la chaîne contient des noms de fichiers
      fournis par l'utilisateur. Les espaces, eux, restent repliés. */
   white-space: pre-line;
   line-height: var(--lh-normal);
}

.mc-dialog-actions {
   display: flex;
   justify-content: center;
   gap: .5rem;
   flex-wrap: wrap;
}

.mc-dialog-actions .btn {
   min-width: 6rem;
}

/* Compte à rebours : la largeur est animée par une transition, pas par une
   image-clé, pour que la durée vienne du JavaScript. */
.mc-dialog-timer {
   height: 3px;
   margin: 1rem -1.5rem -1.25rem;
   background: var(--panel-soft);
}

.mc-dialog-timer span {
   display: block;
   width: 100%;
   height: 100%;
   background: var(--dominante-color);
   transition-property: width;
   transition-timing-function: linear;
}

/* ---------- Notifications ---------- */
/* SOUS LA NAVBAR, pas par-dessus. Le z-index la fait passer devant, mais un
   message posé sur la barre en masque les commandes — et la barre est ce qu'on
   regarde en premier quand on cherche à réagir au message. */
.mc-toast-host {
   position: fixed;
   z-index: 1095;
   top: calc(var(--navbar-h, 60px) + .75rem);
   right: 1rem;
   display: flex;
   flex-direction: column;
   gap: .5rem;
   max-width: 22rem;
   pointer-events: none;
}

.mc-toast {
   position: relative;      /* ancre la jauge, posée en absolu sur le bord bas */
   display: flex;
   align-items: flex-start;
   gap: .6rem;
   padding: .8rem .9rem 1rem;
   border: 1px solid var(--line);
   border-left: 4px solid var(--dominante-color);
   border-radius: var(--radius-field);
   background: var(--panel);
   box-shadow: 0 10px 30px rgba(0, 0, 0, .28);
   opacity: 0;
   transform: translateX(1rem);
   transition: opacity .2s ease, transform .2s ease;
   pointer-events: auto;
}

.mc-toast-shown {
   opacity: 1;
   transform: none;
}

.mc-toast .ph-duotone {
   flex: 0 0 auto;
   font-size: 1.3rem;
   line-height: 1.2;
}

/* LE FOND PORTE LE TYPE, pas seulement le liseré. Un filet de trois pixels sur
   un panneau neutre se remarque quand on le cherche ; le message, lui, doit se
   voir sans qu'on le cherche.

   Les fonds et les bordures viennent des jetons d'état de backend.css — ceux
   des alertes — plutôt que de teintes inventées ici : une erreur a la même
   couleur qu'elle paraisse en bandeau ou en notification. */
.mc-toast-success {
   border-color: var(--state-success-line);
   border-left-color: var(--state-success);
   background: var(--state-success-bg);
}

.mc-toast-success > .ph-duotone {
   color: var(--state-success);
}

.mc-toast-error {
   border-color: var(--state-error-line);
   border-left-color: var(--state-error);
   background: var(--state-error-bg);
}

.mc-toast-error > .ph-duotone {
   color: var(--state-error);
}

.mc-toast-warning {
   border-color: var(--state-warning-line);
   border-left-color: var(--state-warning);
   background: var(--state-warning-bg);
}

.mc-toast-warning > .ph-duotone {
   color: var(--state-warning);
}

.mc-toast-info,
.mc-toast-question {
   border-color: var(--dc-30-t, rgba(6, 93, 137, .3));
   background: var(--dc-10-w, #e6eff3);
}

.mc-toast-info > .ph-duotone,
.mc-toast-question > .ph-duotone {
   color: var(--dominante-color);
}

/* En thème sombre, les fonds clairs des jetons d'état écraseraient le texte.
   On revient au panneau, et c'est le liseré épaissi qui porte le type — les
   couleurs vives restent lisibles sur fond foncé, pas les pastels. */
[data-theme="dark"] .mc-toast-success,
[data-theme="dark"] .mc-toast-error,
[data-theme="dark"] .mc-toast-warning,
[data-theme="dark"] .mc-toast-info,
[data-theme="dark"] .mc-toast-question {
   border-color: var(--line);
   background: var(--panel);
}

.mc-toast-text {
   flex: 1 1 auto;
   min-width: 0;
   font-size: var(--fs-sm);
   line-height: var(--lh-snug);
}

.mc-toast-text strong {
   display: block;
   font-weight: var(--fw-bold);
}

.mc-toast-text span {
   color: var(--slate);
}

/* LA JAUGE. Sa largeur dit le temps qui reste avant la disparition — et le
   survol la met en pause, avec la disparition qu'elle commande : on peut lire
   un message sans courir après.

   Posée en bas, sur toute la largeur, elle prolonge le liseré de gauche plutôt
   que d'ajouter un élément de plus à regarder. */
.mc-toast-jauge {
   position: absolute;
   left: 0;
   right: 0;
   bottom: 0;
   height: 3px;
   overflow: hidden;
   border-radius: 0 0 var(--radius-field) var(--radius-field);
}

.mc-toast-jauge > span {
   display: block;
   width: 100%;
   height: 100%;
   transform-origin: left center;
   background: var(--dominante-color);
   animation-name: mc-toast-jauge;
   animation-timing-function: linear;
   animation-fill-mode: forwards;
}

.mc-toast:hover .mc-toast-jauge > span,
.mc-toast:focus-within .mc-toast-jauge > span {
   animation-play-state: paused;
}

@keyframes mc-toast-jauge {
   from { transform: scaleX(1); }
   to   { transform: scaleX(0); }
}

/* La jauge reprend la teinte du type, comme l'icône. */
.mc-toast-success .mc-toast-jauge > span { background: var(--bs-success, #198754); }
.mc-toast-error   .mc-toast-jauge > span { background: var(--bs-danger,  #dc3545); }
.mc-toast-warning .mc-toast-jauge > span { background: var(--bs-warning, #ffc107); }

/* Sans mouvement, l'animation se joue quand même — c'est elle qui déclenche la
   disparition. On la rend seulement instantanée à l'œil : la barre saute à zéro
   au lieu de glisser, et le message part à l'heure dite. */
@media (prefers-reduced-motion: reduce) {
   .mc-toast-jauge > span {
      transition: none;
   }
}

.mc-toast-close {
   flex: 0 0 auto;
   padding: 0;
   border: 0;
   background: none;
   color: var(--slate-dim);
   cursor: pointer;
   line-height: 1;
}

.mc-toast-close .ph-duotone {
   font-size: 1rem;
}

.mc-toast-close:hover {
   color: inherit;
}

@media (max-width: 575.98px) {
   .mc-toast-host {
      top: auto;
      right: .75rem;
      bottom: .75rem;
      left: .75rem;
      max-width: none;
   }

   .mc-dialog {
      padding: 1.25rem 1.1rem 1rem;
   }

   .mc-dialog-timer {
      margin: 1rem -1.1rem -1rem;
   }
}


/* ========================================================================
   07. ARBRE RÉORDONNABLE — MCArbre
   ------------------------------------------------------------------------
   Gestion des menus. Les listes sont imbriquées sans limite de profondeur :
   toute la mise en forme s'appuie sur l'imbrication, aucune classe ne dit
   « niveau 2 ».
   ======================================================================== */

.mc-arbre {
   margin: 0;
   padding: 0;
   list-style: none;
}

/* Sans cet interligne, une colonne de modules repliés forme un bloc compact
   où l'œil ne distingue plus les entrées les unes des autres. */
.mc-noeud + .mc-noeud {
   margin-top: .3rem;
}

.mc-noeud > .mc-arbre {
   margin-top: .3rem;
}

.mc-arbre .mc-arbre {
   margin-left: 1.15rem;
   padding-left: .6rem;
   border-left: 1px solid var(--line);
}

.mc-noeud-tete {
   display: flex;
   align-items: center;
   gap: .45rem;
   padding: .3rem .4rem;
   border-radius: var(--radius-field);
   font-size: var(--fs-sm);
}

.mc-noeud-tete:hover {
   background: var(--panel-soft);
}

/* Le premier niveau de l'arbre d'agencement porte un fond : ce sont les entrées
   qui paraîtront dans la barre latérale, modules et liens directs mêlés. Les
   pages qu'ils contiennent restent sur fond neutre, en retrait.

   Posé sur .mc-noeud-tete et non sur le <li> : le <li> englobe les enfants
   dépliés, le fond déborderait sur eux. */
.mc-noeud-1 > .mc-noeud-tete {
   background: var(--dc-10-w, #e6eff3);
   font-weight: var(--fw-bold);
}

.mc-noeud-1 > .mc-noeud-tete:hover {
   background: var(--dc-15-w, #dae7ed);
}

[data-theme="dark"] .mc-noeud-1 > .mc-noeud-tete {
   background: var(--dc-20-t, rgba(6, 93, 137, .2));
}

/* Un dossier se distingue d'une page au premier coup d'œil : même fond que
   .input-group-text, l'aplat de la charte pour les zones d'accroche. Les deux
   valeurs sont celles de backend.css, section « Composants Bootstrap ». */
.mc-noeud-dossier > .mc-noeud-tete {
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   color: var(--dominante-color);
   font-weight: var(--fw-bold);
}

.mc-noeud-dossier > .mc-noeud-tete:hover {
   background: var(--dc-20-t, rgba(6, 93, 137, .2));
}

[data-theme="dark"] .mc-noeud-dossier > .mc-noeud-tete {
   background: var(--dc-20-t, rgba(6, 93, 137, .2));
   color: var(--dc-60-w, #6b9fba);
}

/* La poignée est le SEUL point de saisie : on ne déplace pas une entrée en
   attrapant son libellé, sinon toute sélection de texte devient un glissement. */
.mc-poignee {
   flex: 0 0 auto;
   padding: 0 .15rem;
   border: 0;
   background: none;
   color: var(--slate-dim);
   cursor: grab;
   touch-action: none;
}

/* :focus et non :focus-visible seul. Après un clic souris, les navigateurs
   n'appliquent pas :focus-visible — la poignée serait alors armée pour les
   flèches du clavier sans que rien ne le montre. Ici le repère EST
   l'information : il désigne l'entrée que les flèches vont déplacer.

   Un fond plein plutôt qu'un anneau : l'anneau se dessinait AUTOUR du bouton,
   au-dessus du fond de la ligne, et donnait deux cadres emboîtés là où une
   seule chose est désignée. */
.mc-poignee:focus {
   outline: none;
   border-radius: var(--radius-field);
   background: var(--dominante-color);
   color: var(--dominante-contrast, #fff);
}

.mc-plier {
   flex: 0 0 auto;
   width: 1.1rem;
   padding: 0;
   border: 0;
   background: none;
   color: var(--slate-dim);
}

.mc-noeud-libelle {
   flex: 1 1 auto;
   min-width: 0;
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
}

.mc-noeud-plie > .mc-arbre {
   display: none;
}

/* Enfant direct, pas descendance : en sélecteur large, un dossier plié faisait
   pivoter AUSSI les flèches de ses sous-dossiers, y compris celles restées
   dépliées. Invisible tant que le parent est fermé, faux dès qu'on l'ouvre. */
.mc-noeud-plie > .mc-noeud-tete .mc-plier i {
   transform: rotate(-90deg);
}

/* Entrée en cours de déplacement */
/* LA LIGNE COURANTE. Le focus vit sur la poignée — c'est lui qui décide quel
   nœud les flèches du clavier déplaceront. Sans marque visible, on presse une
   flèche sans savoir ce qui va bouger.

   :focus-within plutôt qu'une classe posée en JavaScript : l'état est déjà
   porté par le document, le dupliquer dans une classe ouvrirait la porte aux
   deux qui se désynchronisent. Partir du focus garantit que ce qu'on voit
   surligné est exactement ce que le clavier va saisir.

   Le fond est plus soutenu que celui du premier niveau, sinon une entrée de
   tête sélectionnée ne changerait pas d'aspect. Le liseré tranche pour ceux qui
   distinguent mal les aplats proches — il est posé à DROITE, le bord gauche
   étant déjà occupé par la poignée et par l'indentation des niveaux. */
.mc-noeud-tete:focus-within {
   background: var(--dc-20-t, rgba(6, 93, 137, .2));
   box-shadow: inset -3px 0 0 var(--dominante-color, #065d89);
}

.mc-noeud-1 > .mc-noeud-tete:focus-within {
   background: var(--dc-30-t, rgba(6, 93, 137, .3));
}

[data-theme="dark"] .mc-noeud-tete:focus-within {
   background: var(--dc-40-t, rgba(6, 93, 137, .4));
}

/* La poignée garde son propre anneau de focus pour la navigation au clavier :
   le fond de ligne dit « c'est cette ligne », l'anneau dit « c'est ce bouton ».
   Les deux se complètent, on n'en supprime aucun. */

.mc-noeud-saisi > .mc-noeud-tete {
   background: var(--dc-10-w, #e6eff3);
   box-shadow: 0 1px 6px rgba(0, 0, 0, .12);
}

/* LA LIGNE COURANTE, marquée par une classe posée en JavaScript.
   
   Deux sélecteurs de classe sur le nœud — .mc-noeud.mc-noeud-courant — pour
   passer devant .mc-noeud-dossier > .mc-noeud-tete:hover, qui en compte autant
   et gagnerait sinon par sa position. Un survol ne doit pas effacer la marque
   de ce qu'on vient de déplacer, et le pointeur est justement posé dessus au
   sortir d'une dépose.

   Placé en fin de section pour que l'ordre appuie la spécificité plutôt que de
   la contredire. */
.mc-noeud.mc-noeud-courant > .mc-noeud-tete {
   background: var(--dc-20-t, rgba(6, 93, 137, .2));
   box-shadow: inset -3px 0 0 var(--dominante-color, #065d89);
}

.mc-noeud-1.mc-noeud-courant > .mc-noeud-tete {
   background: var(--dc-30-t, rgba(6, 93, 137, .3));
}

.mc-noeud.mc-noeud-courant > .mc-noeud-tete .mc-poignee {
   border-radius: var(--radius-field);
   background: var(--dominante-color);
   color: var(--dominante-contrast, #fff);
}

[data-theme="dark"] .mc-noeud.mc-noeud-courant > .mc-noeud-tete {
   background: var(--dc-40-t, rgba(6, 93, 137, .4));
}

[data-theme="dark"] .mc-noeud.mc-noeud-courant > .mc-noeud-tete .mc-poignee {
   background: var(--dc-60-w, #6b9fba);
   color: var(--dc-20-k, #01131b);
}

/* Pendant le glissement : ni curseur texte, ni sélection accidentelle. */
.mc-arbre-glisse {
   cursor: grabbing;
   user-select: none;
}

/* Barre d'actions d'un formulaire de réglages.
   .acces-actions ne convient pas ici : elle vient de la page de connexion et
   impose flex: 1 1 0 à ses boutons, qui s'étirent alors sur toute la largeur.
   Ici l'action est ponctuelle — bouton à droite, état à sa gauche. */
.mc-actions {
   display: flex;
   align-items: center;
   justify-content: flex-end;
   gap: .75rem;
}

/* Colonne d'espace */
/* Bandeau d'espace. Même teinte que l'en-tête des tableaux maison, mais par
   la variable GLOBALE : --mc-accent est déclarée sur .mc-table-wrapper, donc
   locale au composant MCTable. Hors de ce conteneur elle ne résout rien, et
   `background: var(--mc-accent)` devient invalide — le fond disparaît au lieu
   de foncer. --dominante-color est déclarée sur :root, elle vaut partout. */
/* UN CADRE PAR PUBLIC, posés sous celui du titre. Ce sont trois menus
   séparés, chacun avec son ordre propre : les réunir sous un même toit
   laissait croire à une seule liste en trois morceaux.

   Le cadre est une carte Bootstrap — bordure, fond, arrondi, ombre et thème
   sombre viennent avec. Il ne reste ici qu'à teinter le bandeau de titre. */
.mc-colonne-titre {
   display: flex;
   align-items: center;
   gap: .4rem;
   padding: .5rem .7rem;
   background: var(--dominante-color, #065d89);
   color: #fff;
   font-weight: var(--fw-bold);
}

/* La carte a son propre rembourrage d'en-tête ; le bandeau vient à sa place,
   il faut donc rendre au corps l'espace du haut. */
.mc-colonne > .card-body {
   padding-top: .8rem;
}

/* Plier / déplier toute la colonne. Poussé à droite par la marge automatique :
   le titre garde sa place quelle que soit sa longueur. */
.mc-colonne-actions {
   display: flex;
   gap: .3rem;
   margin-left: auto;
}

/* Même habillage que les champs et les boutons de la charte : hauteur des
   petits boutons, rayon des champs, trait de bordure commun. Sans fond ni
   bordure, deux icônes posées sur le fond de carte ne se lisaient pas comme
   des commandes cliquables. */
.mc-colonne-action {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   width: var(--btn-h-sm);
   height: var(--btn-h-sm);
   padding: 0;
   border: 1px solid var(--line);
   border-radius: var(--radius-field);
   background: var(--panel-soft);
   color: var(--slate-dim);
   font-size: 1rem;
   line-height: 1;
}

.mc-colonne-action:hover {
   border-color: var(--dominante-color);
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   color: var(--dominante-color);
}

.mc-colonne-action:focus-visible {
   outline: 2px solid var(--dominante-color);
   outline-offset: 1px;
}

/* Sur le fond foncé du bandeau, les boutons reprennent le blanc, atténué. */
.mc-colonne-titre .mc-colonne-action {
   border-color: rgba(255, 255, 255, .35);
   background: rgba(255, 255, 255, .12);
   color: #fff;
}

.mc-colonne-titre .mc-colonne-action:hover {
   border-color: #fff;
   background: rgba(255, 255, 255, .25);
   color: #fff;
}

.mc-colonne-titre .mc-colonne-action:focus-visible {
   outline-color: #fff;
}

/* Le corps prend la place restante : c'est lui qui étire le panneau, de sorte
   que la bordure descende jusqu'en bas même quand la liste est courte. */
.mc-colonne-vide {
   margin: 0;
   color: var(--slate-dim);
   font-size: var(--fs-sm);
   font-style: italic;
}


/* ========================================================================
   08. GRILLE DES PERMISSIONS
   ------------------------------------------------------------------------
   Soixante-quatorze lignes : l'en-tête doit rester visible pendant le
   défilement, sinon on ne sait plus quelle colonne on coche.
   ======================================================================== */

/* La position collante se calcule par rapport au premier ancêtre qui défile.
   Il faut donc que ce conteneur défile VERTICALEMENT — .table-responsive de
   Bootstrap ne gère que l'horizontale. D'où cette hauteur maximale : sans
   elle, l'en-tête ne collerait à rien. */
.table-permissions-scroll {
   max-height: 70vh;
   overflow: auto;
   scrollbar-width: thin;
   scrollbar-color: var(--dc-40-w, #9bbed0) transparent;
}

/* box-shadow: none est indispensable, pas décoratif. Bootstrap 5 peint le fond
   de CHAQUE cellule par une ombre interne de 9999px (règle
   « .table > :not(caption) > * > * »), qui recouvre le background posé ici.
   Sans l'éteindre, l'en-tête garde le fond du tableau et le réglage ci-dessous
   n'a aucun effet visible. */
/* Bootstrap étire .table à 100 %. Sur un écran large, les trois colonnes de
   cases s'éloignaient du nom de la page de plusieurs centaines de pixels :
   l'œil devait traverser un vide pour relier une case à sa ligne, et se
   trompait de rang. Le tableau est donc borné, et il reste calé à gauche
   plutôt que centré — la lecture commence par le nom. */
/* La largeur suit le nombre de colonnes, que le PHP annonce dans
   --mc-colonnes. Le plafond fixe de 46 rem convenait aux trois colonnes
   d'origine ; à six, il n'aurait plus laissé que quatre rem au nom de la page.
   Ainsi le nom garde ses 25 rem quoi qu'il arrive. */
.table-permissions {
   max-width: calc(25rem + var(--mc-colonnes, 3) * 7rem);
}

/* Les colonnes de statut n'ont qu'une case à montrer : largeur fixe, et tout
   l'espace restant revient au nom de la page. :not(:first-child) épargne les
   lignes de dossier, dont la cellule unique porte un colspan. */
.table-permissions th:not(:first-child),
.table-permissions td:not(:first-child) {
   width: 7rem;
}

.table-permissions thead th {
   position: sticky;
   top: 0;
   z-index: 2;
   background: var(--dominante-color, #065d89);
   box-shadow: none;
   color: #fff;
   font-weight: var(--fw-bold);
   white-space: nowrap;
   /* Même graisse et même taille que l'en-tête des tableaux maison. Ce n'est
      pas qu'une question d'harmonie : en nowrap et à la taille du corps de
      texte, « Administrateur » dépasse les 7 rem de la colonne et l'élargit,
      width n'étant qu'une indication en table-layout automatique. */
   font-size: .6875rem;
   letter-spacing: .06em;
}

/* Les lignes de dossier gardent leur aplat malgré le zébrage.
   Bootstrap 5 peint le zébrage par un box-shadow interne, pas par le fond :
   un simple background ne suffirait pas à repasser dessus. */
.table-permissions .mc-ligne-dossier > th {
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   box-shadow: none;
   color: var(--dominante-color);
}

/* L'icône du dossier porte sa PROPRE couleur, déclarée dans backend.css : elle
   n'hérite pas de celle du <th> et serait restée bleu foncé sur l'anthracite. */
[data-theme="dark"] .table-permissions tbody th .ph-duotone {
   color: var(--dc-60-w, #6b9fba);
}

[data-theme="dark"] .table-permissions .mc-ligne-dossier > th {
   background: var(--dc-20-t, rgba(6, 93, 137, .2));
   color: var(--dc-60-w, #6b9fba);
}


/* ========================================================================
   09. RACCOURCIS — page shorts.php
   ======================================================================== */

.mc-short .mc-noeud-tete {
   gap: .5rem;
}

.mc-short-libelle {
   flex: 0 0 11rem;
   max-width: 11rem;
}

/* margin-left: auto pousse la case tout à droite, quelle que soit la largeur
   de ce qui précède. C'est le seul repère commun aux deux sortes de lignes :
   un lien porte un libellé et un chemin, un séparateur ne porte rien — alignées
   sur le contenu, les cases se retrouveraient à des abscisses différentes.
   La disposition interne, elle, est celle de .form-check : on n'y touche pas. */
.mc-short-retrait {
   flex: 0 0 auto;
   margin: 0 0 0 auto;   /* annule aussi le margin-bottom de .form-check */
   white-space: nowrap;
}

/* Ce Bootstrap ne pose cursor: pointer nulle part — il ne déclare que le
   cursor: default des cases désactivées. Sans ces deux lignes, survoler une
   case à cocher garde la flèche, et rien n'indique qu'elle se clique. */
.mc-short-retrait .form-check-input,
.mc-short-retrait .form-check-label {
   cursor: pointer;
}

.mc-short-retrait .form-check-label {
   color: var(--state-error);
   font-size: var(--fs-xs);
   font-style: italic;
}

.mc-short-ajout {
   max-width: 34rem;
}

/* ========================================================================
   10. SÉLECTEUR D'ICÔNES — MCIcones
   ======================================================================== */

.mc-icone-champ {
   display: inline-flex;
   align-items: center;
   gap: .5rem;
}

/* Même gabarit qu'un champ de la charte : c'est bien une valeur qu'on saisit,
   même si on la saisit en cliquant. */
.mc-icone-bouton {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   width: var(--btn-h-md);
   height: var(--btn-h-md);
   padding: 0;
   border: 1px solid var(--line);
   border-radius: var(--radius-field);
   background: var(--panel-soft);
   color: var(--dominante-color);
   font-size: 1.25rem;
   line-height: 1;
}

.mc-icone-bouton:hover {
   border-color: var(--dominante-color);
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
}

.mc-icone-bouton:focus-visible {
   outline: 2px solid var(--dominante-color);
   outline-offset: 1px;
}

/* Le panneau vit dans <body>, positionné en coordonnées de page : posé dans le
   champ, le moindre parent en overflow le couperait. */
.mc-icones {
   position: absolute;
   z-index: 1080;
   display: none;
   width: min(24rem, calc(100vw - 1rem));
   padding: .6rem;
   border: 1px solid var(--line);
   border-radius: var(--radius-field);
   background: var(--panel);
   box-shadow: 0 8px 24px rgba(0, 0, 0, .18);
}

.mc-icones-ouvert {
   display: block;
}

.mc-icones-recherche {
   margin-bottom: .5rem;
}

.mc-icones-onglets {
   display: flex;
   flex-wrap: wrap;
   gap: .2rem;
   margin-bottom: .5rem;
}

.mc-icones-onglet {
   padding: .15rem .45rem;
   border: 1px solid var(--line);
   border-radius: var(--radius-field);
   background: none;
   color: var(--slate-dim);
   font-size: var(--fs-2xs);
}

.mc-icones-onglet:hover {
   border-color: var(--dominante-color);
   color: var(--dominante-color);
}

.mc-icones-onglet-actif {
   border-color: var(--dominante-color);
   background: var(--dominante-color);
   color: #fff;
}

.mc-icones-grille {
   display: grid;
   grid-template-columns: repeat(auto-fill, minmax(2.4rem, 1fr));
   gap: .2rem;
   max-height: 15rem;
   overflow-y: auto;
   scrollbar-width: thin;
   scrollbar-color: var(--dc-40-w, #9bbed0) transparent;
}

.mc-icones-choix {
   display: flex;
   align-items: center;
   justify-content: center;
   aspect-ratio: 1;
   border: 1px solid transparent;
   border-radius: var(--radius-field);
   background: none;
   /* La dominante plutôt que la couleur du texte : ce sont des icônes à
      choisir, pas de la lecture. La charte les tient, elles suivent donc le
      thème retenu par l'établissement. */
   color: var(--dominante-color);
   font-size: 1.5rem;
}

.mc-icones-choix:hover {
   border-color: var(--dominante-color);
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   color: var(--dominante-color);
}

.mc-icones-vide {
   margin: .6rem 0 0;
   color: var(--slate-dim);
   font-size: var(--fs-sm);
   text-align: center;
}

/* Séparateur dans la page de réglage : la ligne reste déplaçable, mais elle
   ne porte aucun champ — d'où l'aspect volontairement plus discret. */
.mc-short-sep .mc-noeud-tete {
   color: var(--slate-dim);
   font-style: italic;
}

/* Page et Libellé sur une seule ligne. La page prend la place restante, le
   libellé court n'a jamais besoin de plus de treize caractères. */
.mc-short-ligne {
   display: flex;
   flex-wrap: wrap;
   gap: 1rem;
   align-items: flex-end;
}

.mc-short-page {
   flex: 1 1 18rem;
   min-width: 0;
}

.mc-short-court {
   flex: 0 0 11rem;
}

/* Sélecteur posé : il n'est plus un panneau flottant, il fait partie du
   formulaire. Ni position absolue, ni ombre portée, ni masquage. */
.mc-icone-pose {
   display: block;
   width: 100%;
}

.mc-icones-pose {
   position: static;
   display: block;
   width: 100%;
   box-shadow: none;
}

/* Le libellé à gauche, l'aperçu à droite, sur la même ligne. align-items:
   flex-end les cale par le bas : sans lui, le libellé se centrerait sur les
   34 px de la vignette et flotterait au-dessus de sa ligne de base. */
.mc-icone-entete {
   display: flex;
   align-items: flex-end;
   justify-content: space-between;
   gap: .5rem;
   margin-bottom: .4rem;
}

.mc-icone-apercu {
   display: flex;
   align-items: center;
   justify-content: center;
   flex: 0 0 auto;
   width: var(--btn-h-md);
   height: var(--btn-h-md);
   margin: 0;
   border: 1px solid var(--dominante-color);
   border-radius: var(--radius-field);
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   color: var(--dominante-color);
   font-size: 1.25rem;
}

/* ========================================================================
   11. RACCOURCIS — écrans étroits
   ------------------------------------------------------------------------
   Une ligne de raccourci mesure environ 588 px au minimum : poignée, icône,
   libellé de 11 rem, chemin complet et case à cocher, tous en flex: 0 0. Rien
   ne se comprimait, et sur un écran de 360 px la carte débordait de plus de
   250 px. Point de rupture md, celui déjà employé par le projet.
   ======================================================================== */

@media (max-width: 767.98px) {

   /* La ligne passe sur deux rangs plutôt que de déborder. */
   .mc-short .mc-noeud-tete {
      flex-wrap: wrap;
   }

   /* Le libellé cesse d'être figé à 11 rem : c'est lui qui absorbe la place
      restante une fois la poignée, l'icône et la case posées. */
   .mc-short-libelle {
      flex: 1 1 6rem;
      max-width: none;
   }

   /* Page et Libellé cessent de partager une ligne : 18 rem + 11 rem ne
      tiennent pas côte à côte, ils s'empilent. */
   .mc-short-page,
   .mc-short-court {
      flex: 1 1 100%;
   }

   /* Dix familles d'icônes qui passent à la ligne occupaient quatre rangs et
      repoussaient la grille hors de l'écran : une seule ligne qui défile. */
   .mc-icones-onglets {
      flex-wrap: nowrap;
      overflow-x: auto;
      scrollbar-width: thin;
      scrollbar-color: var(--dc-40-w, #9bbed0) transparent;
   }

   .mc-icones-onglet {
      flex: 0 0 auto;
   }

   /* La grille laisse de la place au reste du formulaire. */
   .mc-icones-grille {
      max-height: 11rem;
   }

   /* Deux boutons côte à côte peuvent ne plus tenir sous 360 px. */
   .mc-actions {
      flex-wrap: wrap;
   }

   /* Le plafond de 46 rem n'a plus de sens quand l'écran est plus étroit que
      lui : le tableau reprend toute la place, et les colonnes de cases se
      resserrent pour laisser lisible le nom de la page. */
   .table-permissions {
      max-width: none;
   }

   .table-permissions th:not(:first-child),
   .table-permissions td:not(:first-child) {
      width: 3.5rem;
   }
}

/* ========================================================================
   12. THÈME SOMBRE — composants des raccourcis, des menus et des permissions
   ------------------------------------------------------------------------
   Deux jetons NE BASCULENT PAS entre les thèmes, et c'est là que tout se
   joue :

     --text-color        vaut #111 dans les deux. Employé comme couleur de
                         texte sur un panneau sombre, il devient invisible.

     --dominante-color   reste la teinte choisie par la personne, sombre par
                         défaut (#065d89). Elle convient en FOND avec du blanc
                         par-dessus — bandeaux, en-têtes de tableau, bouton
                         Raccourcis — mais pas en AVANT-PLAN sur une surface
                         sombre : bleu foncé sur gris anthracite ne se lit pas.

   La convention du projet, déjà suivie par .mc-toolbar .mc-btn, est de passer
   à la variante éclaircie var(--dc-60-w) en avant-plan, et d'épaissir les
   aplats translucides de --dc-12-t vers --dc-20-t, la transparence rendant
   moins sur fond sombre.
   ======================================================================== */

/* ---- Formulaires ------------------------------------------------------- */

/* La coche de validité sur un champ REMPLI AUTOMATIQUEMENT.

   Bootstrap dessine cette coche en background-image sur le champ. Chrome impose
   son propre fond aux champs qu'il remplit — couleur ET image — et sa feuille de
   style l'écrit en !important : aucune déclaration d'auteur ne peut la
   reprendre. La coche disparaissait donc dès qu'on employait la saisie
   automatique, alors qu'une frappe manuelle la faisait bien paraître.

   La classe est posée par validator.js, et NON par un sélecteur :has(...
   :autofill). Cette écriture-là ne fonctionne pas : Chrome ne réévalue pas
   :has() quand l'état de remplissage change, si bien que la règle est écrite
   mais jamais déclenchée. En JavaScript, matches(':-webkit-autofill') répond
   pourtant juste — c'est ce constat qui a tranché.

   Le groupe porte la coche parce qu'un <input> n'a pas de pseudo-élément.
   Bootstrap réserve déjà la place à droite par un padding-right sur :valid, une
   propriété que Chrome, lui, laisse tranquille. */
.mc-coche-auto {
   position: relative;
}

/* Trois champs du projet (mot de passe de connexion, mot de passe et
   confirmation de l'inscription) portent un bouton « voir » APRÈS le champ,
   dans le même groupe. Cette coche de secours vise le bord droit du GROUPE
   — juste au-dessus, exactement pour la même raison qu'elle existe — donc
   ce bord tombe sur le bouton, pas sur le champ, dès que le remplissage
   automatique du navigateur la déclenche.

   --mc-decalage-coche, posée par validator.js au moment même où la coche
   s'affiche, vaut la largeur RÉELLE de ce qui suit le champ dans son
   groupe — mesurée, pas devinée : aucune valeur fixe n'aurait tenu d'un
   rendu à l'autre (police, thème, futurs boutons). 0px par défaut, pour
   les groupes sans bouton après le champ — la coche garde alors sa
   position d'origine, contre le bord du groupe. */
.mc-coche-auto::after {
   content: "";
   position: absolute;

   /* AU-DESSUS DU CHAMP. Bootstrap empile les champs d'un groupe : 3 pour un
      champ valide, 4 pour un invalide, 5 pour celui qui a le focus. Laissé en
      z-index automatique, ce pseudo-élément se dessinait SOUS le champ, dont
      le fond imposé par le remplissage automatique est opaque — tout était en
      place, la coche était simplement cachée derrière. 6 la garde visible même
      quand le champ a le focus. */
   z-index: 6;

   top: 0;
   bottom: 0;
   right: calc(var(--mc-decalage-coche, 0px) + .375em + .1875rem);
   width: calc(.75em + .375rem);
   height: calc(.75em + .375rem);
   margin: auto 0;
   background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
   background-repeat: no-repeat;
   background-size: contain;
   pointer-events: none;
}

/* ---- Dépôt de fichiers (MCFichier) -------------------------------------- */

/* Le champ natif reste dans le formulaire ET dans la tabulation : on l'ôte de
   la VUE, pas des lecteurs d'écran. Sans display:none, qui l'exclurait de la
   mise au point et empêcherait input.click() sur certains navigateurs. */
.mc-depot-natif {
   position: absolute;
   width: 1px;
   height: 1px;
   padding: 0;
   overflow: hidden;
   clip-path: inset(50%);
   white-space: nowrap;
   border: 0;
}

.mc-depot {
   flex: 1 1 auto;
   width: 100%;
   min-height: 6.5rem;
   padding: 1rem;
   border: 2px dashed var(--dc-30-t, rgba(6, 93, 137, .3));
   border-radius: var(--radius-field);
   background: var(--dc-3-w, #f7fafb);
   cursor: pointer;
   transition: border-color .2s ease, background-color .2s ease;
}

/* Le focus est sur le CHAMP, qui est invisible : c'est la zone, sa
   représentation, qui doit le montrer. Sans cela l'utilisateur au clavier
   perdrait toute trace de l'endroit où il se trouve.

   :focus et non :focus-visible — le validateur met le champ au point par
   programme lors d'une soumission fautive, et la zone doit le dire aussi. */
.mc-depot:hover,
.mc-depot-natif:focus ~ .mc-depot {
   border-color: var(--dominante-color);
   background: var(--dc-7-w, #eef4f7);
}

.mc-depot-natif:focus ~ .mc-depot {
   outline: 2px solid var(--dominante-color);
   outline-offset: 2px;
}

/* Pendant le survol d'un fichier tracté : trait plein, pour dire que le dépôt
   est admis ici et nulle part ailleurs. */
.mc-depot-survol {
   border-style: solid;
   border-color: var(--dominante-color);
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
}

/* L'état fautif se lit du champ, qui est le FRÈRE de la zone : aucun code n'a
   donc à le recopier ici. */
.is-invalid ~ .mc-depot {
   border-color: var(--state-error);
}

/* L'icône coiffe l'invite : elle dit d'un coup d'œil, avant même la lecture,
   que cette zone attend un dépôt. */
.mc-depot-icone {
   display: block;
   margin-bottom: .4rem;
   color: var(--dc-50-777777, #3f6a80);
   font-size: 2rem;
   line-height: 1;
   text-align: center;
}

.mc-depot-survol .mc-depot-icone,
.mc-depot:hover .mc-depot-icone {
   color: var(--dominante-color);
}

.mc-depot-invite {
   margin: 0;
   color: var(--slate-dim);
   font-size: var(--fs-sm);
   text-align: center;
   line-height: 1.5;
}

.mc-depot-liste {
   margin: 0;
   padding: 0;
   list-style: none;

   /* Les vignettes sont en ligne : c'est l'alignement du texte qui les centre
      dans la zone. */
   text-align: center;
}

/* Les lignes de fichiers, elles, restent à gauche : un nom centré se lirait
   mal, et son ellipse partirait du mauvais côté. */
.mc-depot-item:not(.mc-depot-item-image) {
   text-align: left;
}

.mc-depot-item {
   display: flex;
   align-items: center;
   gap: .5rem;
   padding: .3rem .35rem .3rem .6rem;
   border-radius: var(--radius-field);
   background: var(--dc-8-t, rgba(6, 93, 137, .08));
   font-size: var(--fs-sm);
}

.mc-depot-item + .mc-depot-item {
   margin-top: .35rem;
}

/* Une image se montre : la ligne devient une vignette, la croix se posant
   par-dessus plutôt qu'à côté — elle occuperait sinon une largeur entière pour
   un seul bouton. */
.mc-depot-item-image {
   position: relative;
   display: inline-flex;
   width: auto;
   padding: .25rem;
   vertical-align: top;
}

.mc-depot-item-image + .mc-depot-item-image {
   margin-top: 0;
   margin-left: .35rem;
}

.mc-depot-vignette {
   display: block;
   max-width: 100%;
   max-height: 7rem;
   border-radius: var(--radius-field);

   /* contain et non cover : une pièce justificative se lit, et rogner pourrait
      en couper un cachet ou une signature. */
   object-fit: contain;
}

.mc-depot-item-image .mc-depot-retirer {
   position: absolute;
   top: .4rem;
   right: .4rem;
   background: var(--panel);
   box-shadow: 0 1px 4px rgba(0, 0, 0, .25);
}

/* Un nom long ne doit pas pousser le poids ni la croix hors de la zone. */
.mc-depot-nom {
   flex: 1 1 auto;
   min-width: 0;
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
}

.mc-depot-poids {
   flex: 0 0 auto;
   color: var(--slate-dim);
   font-size: var(--fs-xs, .78rem);
   font-variant-numeric: tabular-nums;
}

.mc-depot-retirer {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   flex: 0 0 auto;
   width: 1.35rem;
   height: 1.35rem;
   padding: 0;
   border: 0;
   border-radius: var(--radius-field);
   background: transparent;
   color: var(--dc-70-k, #14415a);
   line-height: 1;
   cursor: pointer;
}

.mc-depot-retirer:hover {
   background: var(--dominante-color);
   color: #fff;
}

.mc-depot-retirer:focus-visible {
   outline: 2px solid var(--dominante-color);
   outline-offset: 1px;
}

/* ---- Choix multiple par jetons (MCMulti) ------------------------------- */

/* Le bandeau des choix retenus, sous le champ. Il occupe sa place même vide :
   sans cela, prendre un premier choix ferait sauter tout ce qui suit. */
.mc-multi {
   display: flex;
   flex-wrap: wrap;
   align-items: center;
   gap: .4rem;
   min-height: var(--btn-h-sm);
   margin-top: .5rem;
}

.mc-multi-vide {
   margin: 0;
   color: var(--slate-dim);
   font-size: var(--fs-sm);
   font-style: italic;
}

/* Le jeton porte la dominante en fond atténué : assez pour se détacher du
   panneau, assez peu pour que le libellé reste lisible en noir. */
.mc-multi-jeton {
   display: inline-flex;
   align-items: center;
   gap: .3rem;
   max-width: 100%;
   padding: .15rem .2rem .15rem .55rem;
   border: 1px solid var(--dc-30-t, rgba(6, 93, 137, .3));
   border-radius: var(--radius-field);
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   color: var(--dc-80-k, #0a2a3c);
   font-size: var(--fs-sm);
   line-height: 1.4;

   /* Saisissable : le curseur l'annonce, et touch-action coupe le défilement
      de la page pendant le glissement — sans lui, le doigt ferait défiler au
      lieu de déplacer. */
   cursor: grab;
   touch-action: none;
   user-select: none;
}

/* :focus-within et NON :focus-visible. Ce dernier ne s'active qu'au clavier :
   cliquer un jeton le désignait sans rien montrer, et la bordure n'apparaissait
   qu'à la première flèche. C'est aussi la convention de l'arbre, où la ligne
   courante se surligne par :focus-within — un clic n'importe où suffit à la
   désigner.

   Le :within couvre en outre le cas où c'est la croix qui a le focus : le
   jeton reste alors clairement celui dont il est question. */
.mc-multi-jeton:focus-within {
   outline: 2px solid var(--dominante-color);
   outline-offset: 1px;
}

/* Le jeton saisi s'allège pour laisser voir la place qu'il va prendre.

   pointer-events: none le rend transparent au pointeur : elementFromPoint rend
   alors le voisin qui se trouve dessous, celui qu'il faut franchir. Sans cela,
   le jeton se retrouvant sous le curseur après chaque échange, il n'avançait
   plus d'un seul cran. */
.mc-multi-jeton-saisi {
   cursor: grabbing;
   opacity: .55;
   pointer-events: none;
}

/* Pendant le glissement, plus rien ne se sélectionne au passage du curseur. */
.mc-multi-glisse {
   cursor: grabbing;
   user-select: none;
}

/* Un libellé long ne doit pas pousser le bandeau hors du panneau. */
.mc-multi-libelle {
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
}

.mc-multi-retirer {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   flex: 0 0 auto;
   width: 1.35rem;
   height: 1.35rem;
   padding: 0;
   border: 0;
   border-radius: var(--radius-field);
   background: transparent;
   color: var(--dc-70-k, #14415a);
   font-size: .85rem;
   line-height: 1;
   cursor: pointer;
}

.mc-multi-retirer:hover {
   background: var(--dominante-color);
   color: #fff;
}

.mc-multi-retirer:focus-visible {
   outline: 2px solid var(--dominante-color);
   outline-offset: 1px;
}


/* L'astérisque des champs obligatoires. aria-hidden dans le balisage : les
   lecteurs d'écran annoncent déjà « obligatoire » d'après l'attribut required,
   et l'entendre deux fois alourdit sans rien apprendre.

   --state-error plutôt qu'un rouge écrit en dur : la charte le décline avec le
   reste, et il tient sur les deux thèmes. */
.mc-requis {
   margin-left: .2rem;
   color: var(--state-error);
   font-weight: var(--fw-bold);
}

/* Le pendant pour un champ FACULTATIF — même principe, même emplacement
   dans le balisage (aria-hidden : rien à annoncer deux fois, l'absence de
   `required` le dit déjà), --state-success pour rester sur la charte. */
.mc-optionnel {
   margin-left: .2rem;
   color: var(--state-success);
   font-weight: var(--fw-bold);
}

/* La légende qui explique les deux marqueurs ci-dessus, en tête de
   formulaire. Petit et grisé comme un .form-text : ce n'est pas une
   instruction qu'on lit à chaque champ, seulement un rappel disponible une
   fois pour toutes. */
.mc-legende-champs {
   font-size: var(--fs-xs);
   color: var(--slate-dim);
   margin-bottom: .75rem;
}

.mc-legende-champs .mc-requis,
.mc-legende-champs .mc-optionnel {
   margin-left: 0;
   margin-right: .2rem;
}

/* ---- Sélecteur d'icônes ------------------------------------------------ */

[data-theme="dark"] .mc-icones-choix:hover,
[data-theme="dark"] .mc-icones-onglet:hover {
   background: var(--dc-20-t, rgba(6, 93, 137, .2));
   color: var(--dc-60-w, #6b9fba);
}

/* En sombre, la dominante s'assombrit avec le fond : on prend sa déclinaison
   claire, celle qu'emploient déjà les autres éléments actifs du thème. */
[data-theme="dark"] .mc-icones-choix {
   color: var(--dc-60-w, #6b9fba);
}

[data-theme="dark"] .mc-icones-onglet {
   color: var(--slate, #8a91a6);
}

[data-theme="dark"] .mc-icones-vide {
   color: var(--slate, #8a91a6);
}

/* L'onglet actif garde le fond dominante et le blanc : sur un aplat plein,
   le contraste tient dans les deux thèmes. */

[data-theme="dark"] .mc-icone-bouton,
[data-theme="dark"] .mc-icone-apercu {
   border-color: var(--dc-60-w, #6b9fba);
   background: var(--dc-20-t, rgba(6, 93, 137, .2));
   color: var(--dc-60-w, #6b9fba);
}

[data-theme="dark"] .mc-icone-bouton:hover {
   border-color: var(--dc-60-w, #6b9fba);
   background: var(--dc-30-t, rgba(6, 93, 137, .3));
}

/* Une ombre portée noire ne se voit pas sur un fond sombre : c'est la bordure
   qui doit détacher le panneau du reste. */
[data-theme="dark"] .mc-icones {
   border-color: var(--dc-40-t, rgba(6, 93, 137, .4));
   box-shadow: 0 8px 24px rgba(0, 0, 0, .5);
}

/* ---- Agencement des menus --------------------------------------------- */

[data-theme="dark"] .mc-colonne-action {
   color: var(--slate, #8a91a6);
}

[data-theme="dark"] .mc-colonne-action:hover {
   border-color: var(--dc-60-w, #6b9fba);
   background: var(--dc-20-t, rgba(6, 93, 137, .2));
   color: var(--dc-60-w, #6b9fba);
}

[data-theme="dark"] .mc-poignee:focus {
   background: var(--dc-60-w, #6b9fba);
   color: var(--dc-20-k, #01131b);
}

/* ---- Arbre : chevrons, chemins, colonnes vides ------------------------- */

/* --slate-dim tombe à #5b6174 en sombre, presque la teinte du panneau : ces
   trois éléments s'effaçaient. --slate est le gris atténué prévu pour ce
   thème, c'est celui que le projet emploie déjà comme --mc-muted. */
[data-theme="dark"] .mc-plier,
[data-theme="dark"] .mc-colonne-vide {
   color: var(--slate, #8a91a6);
}

/* ---- Raccourcis -------------------------------------------------------- */

[data-theme="dark"] .mc-short-sep .mc-noeud-tete {
   color: var(--slate, #8a91a6);
}

/* Le rouge d'erreur ne bascule pas non plus. #d64545 tient sur un fond clair,
   il s'assombrit visuellement sur l'anthracite : on l'éclaircit. */
[data-theme="dark"] .mc-short-retrait .form-check-label {
   color: #ff8a8a;
}

/* ---- Composants du projet restés en avant-plan foncé ------------------- */

/* Ces règles posent une couleur EXPLICITE : elles n'héritent pas de body,
   la bascule de --text-color ne les touche donc pas. Même convention que
   plus haut : la dominante passe à sa variante éclaircie, --slate-dim au
   --slate prévu pour ce thème, et le rouge d'erreur s'éclaircit. */

[data-theme="dark"] .mc-combo-arrow,
[data-theme="dark"] .mc-combo-active,
[data-theme="dark"] .mce-dialog h3,
[data-theme="dark"] .mc-dialog-icon-question,
[data-theme="dark"] .mc-toast-question > .ph-duotone {
   color: var(--dc-60-w, #6b9fba);
}

[data-theme="dark"] .mc-combo-group,
[data-theme="dark"] .mc-combo-empty,
[data-theme="dark"] .mc-combo-placeholder .mc-combo-value,
[data-theme="dark"] .mc-toast-close {
   color: var(--slate, #8a91a6);
}

[data-theme="dark"] .mc-dialog-icon-error,
[data-theme="dark"] .mc-toast-error > .ph-duotone,
[data-theme="dark"] .mc-textarea-counter.mc-over {
   color: #ff8a8a;
}

/* ==========================================================================
   Cartes de filières — Fonctionnement / Sessions & Filières
   ========================================================================== */

/* La grille des cartes : elles se rangent en flux, chacune une largeur
   minimale confortable, plutôt qu'une colonne rigide qui laisserait du vide
   sur une rangée incomplète. */
.mc-filiere-grille {
   display: flex;
   flex-wrap: wrap;
   gap: .9rem;
}

.mc-filiere-carte {
   position: relative;
   flex: 1 1 220px;
   max-width: 280px;
   padding: .9rem 1rem;
   border-radius: var(--radius-field);
   box-shadow: rgb(0 0 0) 2px 2px 5px;
}

/* L'APERÇU reprend .mc-filiere-carte (même carte que la galerie), mais hors
   de .mc-filiere-grille il n'est plus un élément flexible — flex:1 1 220px
   n'a alors aucun effet. .mc-filiere-carte porte aussi son propre
   max-width: 280px, pensé pour garder les tuiles de la galerie à une taille
   raisonnable — ici, on ne le veut PAS : l'aperçu doit suivre .w-100 en
   entier. Un sélecteur d'ID l'emporte sans !important : max-width: none
   neutralise le plafond de la classe, PAS juste l'absence de déclaration —
   sans quoi la règle de la classe reprenait la main par défaut. */
#filiere-apercu {
   max-width: none;
   margin-inline: auto;
}

/* abdAllah (19/08) : même problème, même correctif que #filiere-apercu
   ci-dessus — .mc-filiere-carte plafonne à 280px pour les tuiles de la
   galerie, ce qui écrase w-100 sur l'aperçu du formulaire des salles. */
#salle-apercu {
   max-width: none;
   margin-inline: auto;
}

/* Une filière désactivée reste lisible mais se distingue au premier regard —
   sans quoi rien ne la différencierait d'une filière active. Le ruban
   reprend le même opacity : 45% que le reste de la carte, cohérent avec son
   allure « effacée » plutôt que de rester net au-dessus d'un fond éteint.

   .mc-filiere-ruban est un PETIT conteneur dédié, dans le coin — pas le
   ::after de la carte entière coupé par l'overflow:hidden de celle-ci
   (premier essai, mal calibré : le ruban débordait ou coupait mal selon la
   taille réelle de la carte). Un coin de taille fixe, avec son PROPRE
   overflow:hidden, est la technique éprouvée : le ruban s'y découpe
   proprement quelle que soit la carte qui le porte. */
.mc-filiere-inactive {
   opacity: .45;
}

.mc-filiere-ruban {
   position: absolute;
   top: 0;
   right: 0;
   width: 90px;
   height: 90px;
   overflow: hidden;
   pointer-events: none;
}

.mc-filiere-ruban span {
   position: absolute;
   top: 20px;
   right: -35px;
   width: 130px;
   transform: rotate(45deg);
   background: #111;
   color: #fff;
   text-align: center;
   font-size: .65rem;
   font-weight: var(--fw-bold);
   letter-spacing: .04em;
   text-transform: uppercase;
   padding: .25rem 0;
}

.mc-filiere-entete {
   display: flex;
   align-items: baseline;
   gap: .4rem;
   margin-bottom: .35rem;
}

.mc-filiere-id {
   font-size: .78rem;
   opacity: .75;
}

.mc-filiere-libelle {
   font-weight: var(--fw-bold);
   font-size: 1.05rem;
   line-height: var(--lh-tight);
}

.mc-filiere-court {
   font-size: .9rem;
   opacity: .9;
   margin-bottom: .6rem;
}

.mc-filiere-actions {
   display: flex;
   justify-content: flex-end;
   gap: .25rem;
}

/* Les actions reprennent la couleur du texte de la carte, transmise en ligne
   depuis texteFiliere — jamais une couleur fixe, qui pourrait devenir
   illisible sur certaines combinaisons de fond choisies par l'utilisateur. */
.mc-filiere-action {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   width: 1.9rem;
   height: 1.9rem;
   border: 1px solid color-mix(in srgb, currentColor 45%, transparent);
   border-radius: var(--radius-field);
   background: rgba(255, 255, 255, .15);
   font-size: 1rem;
   opacity: .85;
   transition: opacity .15s ease, background-color .15s ease;
}

.mc-filiere-action:hover,
.mc-filiere-action:focus-visible {
   opacity: 1;
   background: rgba(255, 255, 255, .3);
}

.mc-filiere-action-form {
   margin: 0;
   display: contents;
}

/* Réutilise le motif visuel des cartes filière (couleur/texte transmis en
   ligne) pour un usage plus compact — plusieurs entrées d'une même filière
   empilées dans une seule cellule "Classe" (backend/inscriptions/
   desistements.php, inscriptions.php, pre-inscriptions.php,
   liste-attente.php — les 4 pages du module Listings). */
.mc-listing-filiere {
   padding: .3rem .5rem;
   border-radius: var(--radius-field);
   margin-bottom: .3rem;
}

.mc-listing-filiere:last-child {
   margin-bottom: 0;
}

/* Colonne d'icônes infos, HORS du bloc coloré (23/08) : dedans, elles
   héritaient du fond de filière et devenaient illisibles sur les teintes
   sombres. */
.mc-listing-ligne {
   display: flex;
   align-items: flex-start;
   gap: .35rem;
   margin-bottom: .3rem;
}

.mc-listing-ligne:last-child {
   margin-bottom: 0;
}

/* La marge du bloc voisin est portée par la ligne : la garder ici
   décalerait les icônes d'un cran vers le bas. */
.mc-listing-ligne > .mc-listing-filiere {
   margin-bottom: 0;
   min-width: 0;
}

/* Une icône par classe, empilées pour rester en face de leur libellé.
   `padding` identique à celui du bloc coloré, sans quoi la première icône
   serait plus haute que la première ligne de texte. */
.mc-listing-infos {
   display: flex;
   flex-direction: column;
   flex-shrink: 0;
   padding: .3rem 0;
   line-height: 1.5;
}

/* Une classe sans identifiant n'a pas d'icône : on réserve sa hauteur pour
   que les suivantes restent alignées sur leur libellé. */
.mc-listing-infos-vide {
   display: block;
   height: 1.5em;
}

/* ==========================================================================
   État vide — tableau ou liste sans aucune ligne
   -------------------------------------------------------------------------
   Icône seule sur sa ligne, puis le message en dessous — jamais côte à côte.
   Convention commune à TOUT tableau ou liste vide du projet : voir
   LE-SOCLE.md, « L'état vide ».
   ========================================================================== */

/* Un formulaire d'ajout détaché du tableau qu'il alimente a besoin d'un
   encadré léger pour s'en distinguer — sans quoi il se confond avec le
   reste du modal-body. `bg-light`/`border`/`rounded` de Bootstrap auraient
   fait l'affaire en clair, mais `bg-light` est une couleur fixe : blanche
   sur fond déjà blanc en clair, blanche sur fond sombre en sombre, donc
   invisible ou à contre-sens selon le thème. --panel-soft et --line suivent
   tous deux le thème, --radius-field reprend le même rayon que les champs
   qu'il contient — pas d'angles vifs ici, cet encadré n'est pas une carte. */
.mc-boite-ajout {
   background: var(--panel-soft);
   border: 1px solid var(--line);
   border-radius: var(--radius-field);
   padding: .75rem;
}

/* Une icône seule dans un en-tête de .table-mc-entete hérite du même
   font-size que le texte des libellés (.6875rem, minuscule) — parfait pour
   des majuscules espacées, illisible pour un pictogramme. */
/* Une icône seule dans un en-tête de .table-mc-entete hérite du même
   font-size que le texte des libellés (.6875rem, minuscule) — parfait pour
   des majuscules espacées, illisible pour un pictogramme.

   PAS .mc-icone-entete : ce nom était déjà pris par un tout autre composant
   (libellé + aperçu de filière, plus haut) — display: flex s'appliquait
   alors aussi à cette icône, cassant le chevauchement ::before/::after
   (margin-left: -1em) que le duotone exige en flux normal. Résultat : la
   couche de fond (::before, 20% d'opacité) se plaçait à côté du trait
   plutôt que dessous, prenant l'allure d'un carré. */
.mc-icone-th {
   font-size: 1rem;
}

/* Page établissement — un intitulé de sous-section À L'INTÉRIEUR d'un
   card-body (« Responsable »), pas un card-header à part entière : cette
   page en a déjà quatre, un cinquième pour un seul champ serait disproportionné. */
.mc-sous-titre {
   font-size: var(--fs-sm);
   font-weight: var(--fw-bold);
   text-transform: uppercase;
   letter-spacing: .04em;
   color: var(--slate-dim);
   border-bottom: 1px solid var(--line);
   padding-bottom: .35rem;
}

.mc-fichier-consigne {
   font-size: var(--fs-2xs);
   text-align: center;
   color: var(--slate-dim);
   margin: .15rem 0 .5rem;
}

/* Logo/signature déjà enregistrés — un carré contenu, pas la pleine largeur
   de la carte : la recommandation (200×200) reste carrée quel que soit le
   format réellement déposé, object-fit l'y ramène sans déformation. */
.mc-fichier-actuel {
   display: block;
   width: 100%;
   max-width: 140px;
   aspect-ratio: 1 / 1;
   object-fit: contain;
   border: 1px solid var(--line);
   border-radius: var(--radius-field);
   background: var(--panel-soft);
   padding: .5rem;
}

/* MC-PHOTO — photo de profil unique, avatar par défaut (mc-photo.js).
   Même famille visuelle que .mc-depot (bordure pointillée, survol coloré),
   mais circulaire et centrée sur l'image elle-même, sans texte d'invite. */
.mc-photo {
   position: relative;
   width: 8.5rem;
   height: 10rem;
   border: 2px solid var(--dc-30-t, rgba(6, 93, 137, .3));
   background: var(--dc-3-w, #f7fafb);
   cursor: pointer;
   overflow: hidden;
   transition: border-color .2s ease, background-color .2s ease;
}

.mc-photo:hover,
.mc-photo-survol {
   border-color: var(--dominante-color);
   background: var(--dc-7-w, #eef4f7);
}

.mc-photo-image {
   display: block;
   width: 100%;
   height: 100%;
   object-fit: cover;
}

.mc-photo-supprimer {
   position: absolute;
   bottom: .1rem;
   right: .1rem;
   width: 1.8rem;
   height: 1.8rem;
   display: flex;
   align-items: center;
   justify-content: center;
   border-radius: 3px;
   border: none;
   background: var(--bs-danger, #dc3545);
   color: #fff;
   cursor: pointer;
   padding: 0;
}

.mc-photo-supprimer:hover {
   filter: brightness(0.9);
}

/* Sélecteur de navigation entre les listes de profils (selecteur-profils.php)
   — largeur fixe demandée, aligné à droite avec le bouton Ajouter. Même fond
   que .card-header : la charte doit se retrouver ici aussi. */
.mc-select-listing {
   width: 130px;
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
}

/* Sélecteur de navigation entre les 4 listings du module Inscriptions
   (selecteur-listings.php) — classe DÉDIÉE plutôt qu'une surcharge de
   .mc-select-listing ci-dessus (partagée avec les pages Profils, jamais
   touchée par cette demande) : plus large pour accueillir sans troncature
   ses libellés les plus longs ("Pré-Inscrits", "Désistement"). Même fond
   que la charte, même principe que .mc-select-listing. */
.mc-select-listing-inscriptions {
   width: 200px;
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
}

/* ========================================================================
   COMPOSITION DES CLASSES (backend/inscriptions/composition-des-classes.php)
   — grille de cartes par classe (1 filière/onglet). Table simple plutôt
   que mc-datatable : listes courtes (1 classe), pas de tri/filtre/export
   nécessaire par carte — l'impression se fait sur la page entière via
   window.print(), pas via l'export intégré à mc-table.js.
   ======================================================================== */

.mc-composition-carte {
   transition: box-shadow .2s ease, transform .2s ease;
}

.mc-composition-carte:hover {
   box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .15);
   transform: translateY(-2px);
}

.mc-composition-carte .card-header {
   display: flex;
   align-items: center;
   justify-content: space-between;
   font-size: var(--fs-sm);
}

/* Annule border/border-radius/padding de la règle GLOBALE .tab-content
   (backend.css), PARTAGÉE avec 5 autres pages à onglets (effectifs-des-
   classes.php, informations-classes.php, classes-de-la-session.php...) :
   la modifier directement les aurait toutes affectées. Limité à cette
   page via son id dédié (#compositionTabContent), pas de changement sur
   .tab-content elle-même. !important : au cas où la spécificité ID seule
   ne suffise pas à emporter sur .tab-content dans tous les contextes. */
#compositionTabContent {
   border: none !important;
   border-radius: 0 !important;
   padding: 0 !important;
}

.mc-composition-infos,
.mc-composition-membres {
   width: 100%;
   border-collapse: collapse;
   font-size: var(--fs-sm);
}

/* Dégradé clair — utilitaire générique (pas préfixé mc-composition-),
   réutilisable ailleurs si besoin. */
.grady-light {
   background: -webkit-linear-gradient(#fff, #ddd);
   background: -moz-linear-gradient(#fff, #ddd);
   background: -o-linear-gradient(#fff, #ddd);
   background: linear-gradient(#fff, #ddd);
}

/* Couleur de bordure alignée sur le bas du dégradé .grady-light du thead
   (#ddd) — cohérence visuelle avec l'en-tête clair, plutôt que le gris
   générique de Bootstrap. Posée sur .mc-composition-infos ELLE-MÊME (le
   <table>, pas th/td) : c'est de là que .table-bordered propage la
   couleur sur ses 4 côtés — Bootstrap pose `border-color: inherit`
   globalement sur thead/tbody/tr/td/th, hérité du <table> parent. La
   poser sur th/td au lieu du <table> aurait laissé la couleur héritée
   du <table> (grise, faute de classe `.table`) sur 3 côtés, seul
   border-bottom (règle explicite ci-dessous) aurait été #ddd — bordures
   incohérentes, effet "sombre" sinon. */
.mc-composition-infos {
   --bs-table-border-color: #ddd;
}

.mc-composition-infos th,
.mc-composition-infos td {
   padding: .35rem .5rem;
   border-bottom: 1px solid var(--bs-table-border-color);
}

/* mc-composition-membres n'a pas table-bordered — pas concernée par le
   diagnostic ci-dessus, garde sa bordure grise générique inchangée
   (--mc-border, pas --bs-table-border-color qu'elle hérite maintenant
   malgré elle de sa nouvelle classe `.table`, ajoutée pour que
   table-striped fonctionne — sans cette séparation, sa bordure aurait
   changé sans que ce soit demandé). */
.mc-composition-membres th,
.mc-composition-membres td {
   padding: .35rem .5rem;
   border-bottom: 1px solid var(--mc-border, #e5e5e5);
}

/* mc-composition-infos : toujours centré (mode/public/section/reste/
   attente, une seule ligne de données). mc-composition-membres : PAS de
   centrage générique — id/nom-prénom/âge portent chacun sa propre classe
   Bootstrap (text-center/text-end) directement dans le gabarit, un
   <td> reste aligné à gauche par défaut sans qu'il soit besoin de le
   forcer ici (ID centré, Nom/Prénom à gauche, Âge à droite). */
.mc-composition-infos th,
.mc-composition-infos td {
   text-align: center;
}

/* En-tête de mc-composition-infos — dégradé .grady-light (classe posée
   directement sur le <thead> dans le gabarit), pas de fond/texte forcés
   ici : un fond clair appelle un texte de couleur normale, pas blanc. */
.mc-composition-infos thead th {
   font-weight: var(--fw-bold);
}

/* La couleur de texte dynamique par filière (même logique que le
   card-header) est portée en style INLINE directement dans
   renduTableMembresComposition() — pas ici en CSS statique, puisqu'elle
   dépend de $fil['texte'] au moment du rendu. Les cellules de données
   (id via renduColonneId(), fond coloré par genre) ne suivent PAS cette
   couleur : renduColonneId() ne produit AUCUN <a> (juste un <td onclick>,
   voir son commentaire dans shared/membres.php), sa couleur bleue vient
   déjà de .linkUrl-cellule — classe GLOBALE (backend.css), déjà appliquée
   partout où cette même fonction partagée est utilisée. */
.mc-composition-membres thead th {
   font-weight: var(--fw-bold);
}

.mc-composition-attente-titre {
   text-align: center;
   font-weight: var(--fw-bold);
   font-size: var(--fs-sm);
   padding: .35rem;
}

/* En-tête d'impression (établissement à gauche, filière à droite) —
   justify-content posé ici (pas par d-print-flex, qui ne fait que
   display:flex) ; le fond .grady-light est appliqué en HTML aux côtés
   de cette classe. */
.mc-composition-entete-impression {
   display: flex;
   justify-content: space-between;
   align-items: center;
   border: 1px solid #ddd;
   padding: .35rem .5rem;
   font-weight: var(--fw-bold);
   font-size: var(--fs-base);
   color: var(--dominante-color);
}

.mc-composition-logo-impression {
   max-width: 80px;
   max-height: 80px;
}

/* ========================================================================
   IMPRESSION — structure ENTIÈREMENT SÉPARÉE de la grille écran (voir le
   docblock de composition-des-classes.php pour le contexte complet de ce
   choix). `.mc-composition-page-impression` est un <div> SIMPLE, sans
   classe de grille Bootstrap, directement enfant de `.d-none.d-print-block`
   — aucun override de largeur/marge/bordure n'est nécessaire ici, un bloc
   normal se comporte déjà correctement nativement. Seul le saut de page
   a besoin d'être posé explicitement.
   ======================================================================== */
@media print {
   /* Carte EXTÉRIEURE qui englobe TOUT le contenu de la page (titre +
      onglets + tab-content + les pages imprimées elles-mêmes) — son
      cadre Bootstrap par défaut (bordure + padding), puisqu'il entoure
      littéralement tout ce qui s'imprime, encercle l'ENSEMBLE des pages
      d'un seul grand cadre commun si non retiré. */
   .mc-composition-page {
      border: none !important;
      margin: 0 !important;
      width: 100% !important;
   }

   .mc-composition-page > .card-body {
      padding: 0 !important;
   }

   .mc-composition-page-impression {
      page-break-after: always;
      break-after: page;
      page-break-inside: avoid;
      break-inside: avoid;
   }

   .mc-composition-page-impression:last-child {
      page-break-after: auto;
      break-after: auto;
   }
}

.mc-composition-print-colonnes {
   display: flex;
   gap: 1rem;
}

.mc-composition-print-colonnes > div {
   flex: 1 1 50%;
   min-width: 0;
}


/* abdAllah (20/08) : boutons "Jours" du formulaire d'ajout de cours
   (organisation/emploi-du-temps.php) — couleur du thème utilisateur
   (--dominante-color) plutôt que le bleu Bootstrap générique quand
   coché, cohérent avec les badges de périodes déjà colorés ainsi. */
.mc-jour-label {
   background-color: var(--dc-12-t, rgba(6, 93, 137, .12));
   /* Bordure visible au repos (abdAllah, 20/08) : elle était transparente,
      les 7 boutons se lisaient comme un seul aplat continu. */
   border: 1px solid var(--dc-25-t, rgba(6, 93, 137, .25));
   color: inherit;
   padding-top: .6rem;
   padding-bottom: .6rem;
   transition: background-color var(--transition-speed, .15s),
               border-color var(--transition-speed, .15s),
               box-shadow var(--transition-speed, .15s),
               transform var(--transition-speed, .15s);
}
/* Survol — le halo et le zoom sont posés ICI, donc communs aux deux
   états. C'est le point corrigé le 20/08 : un jour NON sélectionné
   changeait de fond, de bordure ET de couleur de texte, tandis qu'un jour
   sélectionné ne pouvait varier que d'une nuance de bleu sur bleu (1,78:1
   entre les deux fonds) — l'effet semblait absent sur le jour choisi. Le
   halo, lui, se voit exactement pareil dans les deux cas. */
.mc-jour-label:hover {
   background-color: var(--dc-25-t, rgba(6, 93, 137, .25));
   border-color: var(--dominante-color);
   color: var(--dominante-color);
   /* Zoom très léger. position/z-index sont nécessaires : dans un
      .btn-group les labels se chevauchent (marges négatives Bootstrap),
      sans remontée le bouton agrandi passerait sous ses voisins. */
   transform: scale(1.04);
   position: relative;
   z-index: 1;
   box-shadow: 0 0 0 .15rem var(--dc-30-t, rgba(6, 93, 137, .3));
}
/* Un jour coché reste lisible au survol : sans cette règle, le :hover
   ci-dessus reprenait le dessus et repassait le bouton en fond clair. */
.mc-jour-check:checked + .mc-jour-label:hover {
   background-color: var(--dominante-color-hover, var(--dominante-color));
   border-color: var(--dominante-color-hover, var(--dominante-color));
   color: #fff;
   transform: scale(1.04);
}
.mc-jour-check:checked + .mc-jour-label {
   background-color: var(--dominante-color);
   border-color: var(--dominante-color);
   color: #fff;
}

/* abdAllah (20/08) : refonte complète de l'emploi du temps en timeline
   salle × heure (un tableau par jour), sur le modèle fourni en capture
   d'écran — remplace la grille "une colonne par jour" précédente. */
.mc-planning-jour {
   margin-bottom: 1.5rem;
   border: 1px solid var(--bs-border-color, #dee2e6);
   border-radius: .5rem;
   /* La carte s'arrête à la largeur de son contenu (colonne des salles +
      1440px de timeline) au lieu de s'étirer sur toute la page : sinon un
      grand écran laisse une bande vide à droite de la grille. max-width
      garde le défilement horizontal de .mc-planning-corps sur petit écran. */
   width: max-content;
   max-width: 100%;
}
.mc-planning-entete-jour {
   background: var(--dominante-color);
   color: #fff;
   font-weight: var(--fw-bold);
   padding: .5rem 1rem;
   border-radius: .5rem .5rem 0 0;
}
.mc-planning-corps {
   display: flex;
   overflow-x: auto;
}
.mc-planning-col-salles {
   flex: 0 0 auto;
   display: flex;
   flex-direction: column;
   position: sticky;
   left: 0;
   z-index: 3;
}
/* Chaque salle garde SA couleur, posée en ligne par PHP. Seule la case
   d'angle (:first-child, celle qui fait face à la bande des heures) reprend
   l'aplat de .mc-planning-heure-label — voir la règle plus bas. */
.mc-planning-salle-nom {
   display: flex;
   align-items: center;
   padding: 0 .6rem;
   font-size: .82rem;
   font-weight: var(--fw-bold);
   color: #fff;
   height: 46px;
   white-space: nowrap;
   border-top: 1px solid rgba(255, 255, 255, .2);
}
/* Case d'angle : même aplat que .mc-planning-heure-label (abdAllah, 20/08),
   pour que la colonne des salles et la bande des heures se rejoignent sans
   rupture. Elle n'a plus de style en ligne côté PHP, la règle peut donc
   s'appliquer — les autres cases, elles, gardent le leur. */
.mc-planning-col-salles .mc-planning-salle-nom:first-child {
   height: 44px;
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   color: var(--dominante-color);
   border-top: 0;
}
/* La dernière salle porte un aplat de couleur pleine qui carrait le coin
   bas-gauche de la carte (abdAllah, 20/08). Le rayon est repris ici plutôt
   que par un overflow:hidden sur .mc-planning-jour, qui rognerait les
   menus déroulants des cours. */
.mc-planning-col-salles .mc-planning-salle-nom:last-child {
   border-bottom-left-radius: .5rem;
}
.mc-planning-timeline {
   /* 0 0 auto, PAS 1 1 auto : la largeur est posée en ligne par PHP
      ($largeurTimeline = nb d'heures x 60 x MC_PX_PAR_MIN, soit 1440px pour
      8h-20h). Avec flex-grow, dès que l'écran est plus large que ça, la
      timeline s'étirait alors que les blocs d'heures (flex:0 0 auto) et les
      cellules (position:absolute) gardaient leur taille : l'en-tête
      s'arrêtait à 19h50 et les lignes de salles continuaient dans le vide
      jusqu'au bord droit. */
   flex: 0 0 auto;
   position: relative;
}
.mc-planning-timeline-entete {
   display: flex;
   border-bottom: 1px solid var(--bs-border-color, #dee2e6);
}
.mc-planning-heure-bloc {
   flex: 0 0 auto;
   border-left: 1px solid var(--bs-border-color, #dee2e6);
}
.mc-planning-heure-label {
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   color: var(--dominante-color);
   font-weight: var(--fw-bold);
   font-size: .78rem;
   padding: .2rem 0;
   text-align: center;
   border-bottom: 1px solid var(--bs-border-color, #dee2e6);
}
.mc-planning-heure-minutes {
   display: flex;
}
.mc-planning-minute-label {
   flex: 1 1 0;
   font-size: .58rem;
   color: var(--slate, #6c757d);
   text-align: center;
}
.mc-planning-ligne-salle {
   position: relative;
   height: 46px;
   border-top: 1px solid var(--bs-border-color, #dee2e6);
}
.mc-planning-cellule {
   display: block;
   position: absolute;
   top: 0;
   bottom: 0;
   cursor: pointer;
   border-left: 1px dotted rgba(0, 0, 0, .07);
}
.mc-planning-cellule:hover {
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
}
.mc-planning-cours {
   position: absolute;
   top: 3px;
   bottom: 3px;
   border-radius: .25rem;
   padding: .1rem .4rem;
   font-size: .72rem;
   line-height: 1.2;
   z-index: 2;
   box-shadow: 0 1px 2px rgba(0, 0, 0, .15);
}
/* Un menu ouvert doit passer AU-DESSUS des cours des lignes suivantes.
   Les lignes de salles sont des frères en z-index auto : la ligne peinte
   après recouvrait le menu de la ligne précédente. On remonte donc la
   ligne ET le cours concernés tant que le menu est ouvert. */
.mc-planning-ligne-salle:has(.dropdown-menu.show) {
   z-index: 5;
}
.mc-planning-cours:has(.dropdown-menu.show) {
   z-index: 1055;
}
.mc-planning-cours-entete {
   display: flex;
   justify-content: space-between;
   align-items: center;
   gap: .3rem;
   font-weight: var(--fw-bold);
   white-space: nowrap;
}
.mc-planning-cours-menu-btn {
   background: none;
   border: none;
   padding: 0;
   line-height: 1;
   color: inherit;
   opacity: .8;
}
.mc-planning-cours-menu-btn:hover {
   opacity: 1;
}
.mc-planning-cours-classe {
   white-space: nowrap;
   text-overflow: ellipsis;
   overflow: hidden;
}
.mc-planning-cours-enseignant {
   font-style: italic;
   white-space: nowrap;
   text-overflow: ellipsis;
   overflow: hidden;
}

/* abdAllah (20/08) : largeur fixe du sélecteur "1er jour". mc-select.js
   CACHE le <select> natif et affiche son propre bouton .mc-combo à la
   place — une largeur posée sur le select seul ne changerait rien à
   l'écran. Le combo généré porte data-select="<id du select>", c'est lui
   qu'il faut cibler. flex-basis en plus de width : le combo est dans un
   .input-group, donc dans un contexte flex. */
#premierJourSemaine,
.mc-combo[data-select="premierJourSemaine"] {
   width: 120px;
   flex: 0 0 120px;
}

/* abdAllah (20/08) : champs Heures/Minutes du formulaire de cours —
   séparateur ":" moins large, valeur affichée centrée dans le combo
   mc-select (cible .mc-combo-value, le span de texte réel — le
   <select> natif est caché par mc-select.js). */
.mc-horaire-separateur {
   width: auto;
   padding-left: .15rem;
   padding-right: .15rem;
}
.mc-horaire-champ .mc-combo-value {
   flex: 1 1 auto;
   text-align: center;
}
/* Le ":" entre heures et minutes : même aplat clair que les
   .input-group-text de la charte, pour qu'il se lise comme une accroche
   du groupe et non comme du texte flottant (abdAllah, 20/08). */
.mc-horaire-deuxpoints {
   display: flex;
   align-items: center;
   background-color: var(--dc-12-t, rgba(6, 93, 137, .12));
   color: var(--dominante-color);
   font-weight: var(--fw-bold);
   border-radius: var(--bs-border-radius, .375rem);
   padding: 0 .4rem;
}

/* abdAllah (20/08) : cours de moins d'1 heure — le bloc est trop
   étroit pour tout afficher, on masque le détail (classe/enseignant)
   et on l'affiche au survol, en élargissant temporairement le bloc. */
.mc-planning-cours-court .mc-planning-cours-details {
   display: none;
}
/* Le bloc est plus étroit que son en-tête (« 10:00 ⋮ 10:30 » en nowrap) :
   sans ceci le texte débordait sur les cellules voisines. */
.mc-planning-cours-court {
   overflow: hidden;
}
/* Au survol ET tant qu'un menu est ouvert : le bloc s'élargit et laisse
   de nouveau tout sortir — sans la 2e condition, cliquer sur le menu puis
   éloigner la souris le ferait disparaître, coupé par overflow:hidden. */
.mc-planning-cours-court:hover,
.mc-planning-cours-court:has(.dropdown-menu.show) {
   width: auto !important;
   min-width: 160px;
   z-index: 10;
   overflow: visible;
}
.mc-planning-cours-court:hover .mc-planning-cours-details,
.mc-planning-cours-court:has(.dropdown-menu.show) .mc-planning-cours-details {
   display: flex;
}

/* abdAllah (20/08) : finalement pas de badge — retour au sous-texte
   simple par défaut de mc-select.js pour Classe/Salle présentielle. */

/* ========================================================================
   IMPRESSION DES PLANNINGS (organisation/emploi-du-temps.php) — abdAllah
   (20/08). 5 gabarits x 2 rendus. Le réceptacle #zoneImpression est REJETÉ
   HORS ÉCRAN plutôt que masqué en display:none : la technique
   .section-a-imprimer de backend.css repose sur `visibility`, qui n'a
   aucun effet sur un élément non rendu.
   ======================================================================== */
#zoneImpression {
   position: absolute;
   left: -99999px;
   top: 0;
   width: 1600px;
}
.mc-impr-entete {
   margin-bottom: .8rem;
   border-bottom: 2px solid var(--dominante-color);
   padding-bottom: .4rem;
}
.mc-impr-entete h2 {
   margin: 0;
   font-size: 1.15rem;
   color: var(--dominante-color);
}
.mc-impr-entete p {
   margin: 0;
   font-size: .8rem;
   color: var(--slate, #6c757d);
}
.mc-impr-table {
   width: 100%;
   border-collapse: collapse;
   font-size: .78rem;
}
.mc-impr-table th,
.mc-impr-table td {
   border: 1px solid #999;
   padding: .25rem .4rem;
   text-align: left;
}
/* En-tête en dominante pleine (abdAllah, 20/08), plus l'aplat clair. */
.mc-impr-table thead th {
   background: var(--dominante-color);
   color: #fff;
   border-color: var(--dominante-color);
}
/* Zébrage (abdAllah, 20/08). Règle propre plutôt que la classe
   .table-striped de Bootstrap : celle-ci peint par `box-shadow: inset`
   d'une teinte à 5% d'opacité — quasi invisible sur papier, et les ombres
   sont les premières victimes du rendu d'impression. On reprend le rang
   IMPAIR comme Bootstrap, pour que le zébrage tombe au même endroit que
   dans les tableaux du reste du projet.
   Les cellules Classe et Salle portent un fond en ligne : il gagne, et
   c'est voulu — leur couleur reste prioritaire sur la rayure. */
.mc-impr-table tbody tr:nth-of-type(odd) td {
   background: var(--dc-8-t, rgba(6, 93, 137, .08));
}
/* Filière, 2e ligne de la cellule Classe : hérite de la couleur de texte
   posée sur le <td>, atténuée — pas une couleur fixe, qui deviendrait
   illisible sur les filières à texte noir. */
.mc-impr-table .mc-impr-sous {
   font-size: .68rem;
   font-weight: var(--fw-regular, 400);
   opacity: .85;
}

@media print {
   /* PAGES BLANCHES (abdAllah, 20/08) — la technique .section-a-imprimer de
      backend.css repose sur `visibility: hidden`, qui MASQUE sans supprimer :
      toute la hauteur de la page reste occupée, d'où plusieurs feuilles vides
      après le contenu utile. On complète donc, POUR CETTE PAGE UNIQUEMENT,
      par un vrai `display: none` sur les frères du réceptacle — la règle
      partagée de backend.css reste intacte pour les autres pages.

      Et `position: static` : `.section-a-imprimer` place l'élément en absolu,
      or un bloc positionné en absolu qui dépasse une page est tronqué par le
      navigateur au lieu de se poursuivre. Un tableau de 40 cours doit pouvoir
      couler sur plusieurs feuilles. */
   body.mc-impression-section .container-fluid > *:not(#zoneImpression) {
      display: none !important;
   }
   body.mc-impression-section #zoneImpression.section-a-imprimer {
      position: static;
      left: auto;
      width: 100%;
   }
   #zoneImpression {
      left: 0;
      width: 100%;
   }
   /* Aplats de couleur des cours et des salles : sans ceci, Chrome les
      supprime à l'impression et la grille devient illisible. */
   #zoneImpression .mc-planning-cours,
   #zoneImpression .mc-planning-salle-nom,
   #zoneImpression .mc-planning-entete-jour,
   #zoneImpression .mc-impr-table td,
   #zoneImpression .mc-impr-table thead th,
   #zoneImpression .mc-composition-entete-impression {
      -webkit-print-color-adjust: exact;
      print-color-adjust: exact;
   }
   /* Une carte de jour ne doit pas être coupée en deux par un saut de page. */
   #zoneImpression .mc-planning-jour {
      break-inside: avoid;
      page-break-inside: avoid;
      margin-bottom: .6rem;
   }
   /* Colonne des salles FIGÉE : le JS soustrait cette largeur de la feuille
      avant de recalculer la timeline. Les deux valeurs doivent rester
      identiques (LARGEUR_SALLES dans emploi-du-temps.php). Un nom trop long
      est tronqué plutôt que d'élargir la colonne et de tout décaler. */
   #zoneImpression .mc-planning-col-salles,
   #zoneImpression .mc-planning-salle-nom {
      width: 110px;
      min-width: 110px;
      max-width: 110px;
      overflow: hidden;
   }
   #zoneImpression .mc-planning-salle-nom {
      text-overflow: ellipsis;
      display: block;
      line-height: 46px;
      padding: 0 .4rem;
      white-space: nowrap;
   }
   #zoneImpression .mc-planning-col-salles .mc-planning-salle-nom:first-child {
      line-height: 44px;
   }
   /* La carte cesse de s'auto-dimensionner : sa largeur est celle de la
      feuille, et son contenu a été recalculé pour y tenir exactement. */
   #zoneImpression .mc-planning-jour {
      width: 100%;
      max-width: 100%;
   }
   #zoneImpression .mc-planning-corps {
      overflow: hidden;
   }
   /* « Toutes les classes » : une section par classe, chacune sur sa page.
      Le saut n'est posé que sur les sections SAUF la dernière (côté JS),
      sinon l'impression se termine par une feuille blanche. */
   /* Saut porté par le SUIVANT (break-before) plutôt que par le précédent :
      c'est la forme la mieux respectée par Chrome, et elle ne peut pas
      produire de feuille blanche finale puisque la dernière section n'a
      aucun suivant. `.mc-impr-saut`, posée en JS, est conservée en second
      filet mais n'est plus indispensable. */
   #zoneImpression .mc-impr-page + .mc-impr-page {
      break-before: page;
      page-break-before: always;
   }
   #zoneImpression .mc-impr-saut {
      break-after: page;
      page-break-after: always;
   }
   /* Un conteneur positionné en absolu n'est PAS fragmenté : le navigateur
      ignore alors tout saut de page à l'intérieur. La règle partagée
      .section-a-imprimer (backend.css) posant justement `position:absolute`,
      on la neutralise ici — c'est la cause la plus probable des sauts
      ignorés signalés par abdAllah le 20/08. `display:block` et
      `float:none` écartent les deux autres contextes qui bloquent aussi
      la fragmentation. */
   #zoneImpression .mc-impr-page {
      break-inside: auto;
      display: block;
      float: none;
      position: static;
      overflow: visible;
   }
   #zoneImpression .mc-impr-table tr {
      break-inside: avoid;
      page-break-inside: avoid;
   }
   #zoneImpression .mc-impr-table thead {
      display: table-header-group;   /* en-têtes répétés à chaque page */
   }
}

/* ========================================================================
   INFORMATIONS-CLASSES — onglets Cours et Calendrier (abdAllah, 20/08)
   ======================================================================== */
/* Le fond vient du genre (genre_couleur(), posé en ligne) : la couleur
   n'est donc PAS déclarée ici, sans quoi elle l'emporterait au chargement
   sur les pastilles sans genre renseigné. La couleur de texte reste celle
   du corps, ces aplats de genre étant très clairs. */
.mc-classe-enseignant {
   display: inline-flex;
   align-items: center;
   gap: .35rem;
   font-weight: var(--fw-bold);
   border: 1px solid var(--bs-border-color, #dee2e6);
   border-radius: 1rem;
   padding: .15rem .6rem .15rem .15rem;
   font-size: .85rem;
}
/* Barre des déplacements en attente : fixée en bas d'écran. On travaille
   DANS la grille, souvent défilée vers la droite — un bouton posé en haut de
   page obligerait à remonter pour enregistrer. */
.mc-barre-deplacements {
   position: fixed;
   left: 50%;
   /* 2.5rem : assez haut pour ne pas frôler le bas de fenêtre, assez bas
      pour ne pas mordre sur la grille (abdAllah, 22/08). */
   bottom: 2.5rem;
   transform: translateX(-50%);
   z-index: 1040;   /* au-dessus du contenu, sous les modales (1055) */
   display: flex;
   align-items: center;
   gap: .5rem;
   padding: .5rem .75rem;
   border-radius: .5rem;
   background: var(--bs-body-bg, #fff);
   box-shadow: rgba(60, 64, 67, .3) 0 1px 2px 0, rgba(60, 64, 67, .15) 0 2px 6px 2px;
}

/* Voile sous la barre : elle flotte au-dessus de la grille, dense et colorée —
   sans ce fondu, ses boutons se confondraient avec les blocs de cours.
   Porté par le PARENT et non par la barre : celle-ci a un `transform`
   (translateX pour se centrer), et un ancêtre transformé devient le référent
   des positions `fixed` — le voile était donc borné à la largeur de la barre
   au lieu de couvrir l'écran (abdAllah, 22/08).
   `pointer-events: none` est INDISPENSABLE : on glisse encore des cours à cet
   endroit, un voile capturant le pointeur bloquerait le dépôt. */
.mc-voile-deplacements {
   position: fixed;
   left: 0;
   right: 0;
   bottom: 0;
   height: 9rem;
   z-index: 1039;   /* juste sous la barre (1040) */
   pointer-events: none;
   /* Voile NOIR (abdAllah, 22/08) : la barre porte une action à confirmer,
      elle doit se détacher franchement de la grille. Fondu vers le haut
      plutôt qu'un bord net, qui trancherait en travers du planning. */
   background: linear-gradient(to top,
      rgba(0, 0, 0, .78) 0%,
      rgba(0, 0, 0, .58) 45%,
      rgba(0, 0, 0, 0) 100%);
}

/* En thème sombre, un voile noir sur fond noir ne détache RIEN : c'est le
   contraste qui compte, pas la couleur. On éclaircit donc au lieu d'assombrir
   (abdAllah, 22/08). */
[data-theme="dark"] .mc-voile-deplacements {
   background: linear-gradient(to top,
      rgba(255, 255, 255, .55) 0%,
      rgba(255, 255, 255, .34) 45%,
      rgba(255, 255, 255, 0) 100%);
}

/* Cours déplacé mais PAS encore enregistré : liseré pointillé. Il se
   distingue d'un cours en place sans imiter les états de surcapacité. */
.mc-planning-cours.est-en-attente {
   outline: 2px dashed rgba(var(--bs-primary-rgb), .9);
   outline-offset: -2px;
}

/* ── Glisser-déposer dans la grille (chantier 6, 22/08) ────────────────
   Le bloc saisi s'efface pour qu'on voie la grille dessous, et la ligne
   survolée annonce le résultat AVANT le dépôt : vert si la place est libre,
   rouge si elle est prise, orange si la salle est trop petite (on peut alors
   forcer, comme dans le formulaire). */
.mc-planning-cours[draggable="true"] {
   cursor: grab;
}

.mc-planning-cours.est-deplace {
   opacity: .35;
   cursor: grabbing;
}

.mc-planning-ligne-salle.est-cible-ok,
.mc-planning-ligne-salle.est-cible-refus,
.mc-planning-ligne-salle.est-cible-avertit {
   /* `inset` : un contour classique élargirait la ligne et ferait sauter la
      grille pendant le glissement. */
   box-shadow: inset 0 0 0 1px currentColor;
   position: relative;
}

.mc-planning-ligne-salle.est-cible-ok      { color: #198754; }
.mc-planning-ligne-salle.est-cible-avertit { color: #fd7e14; }
.mc-planning-ligne-salle.est-cible-refus   { color: #dc3545; }

/* Empreinte de dépose : rectangle à la position et à la largeur qu'aura le
   cours, bord gauche compris. Le bloc glissé suit le curseur sans se recaler
   sur le pas de 10 minutes — c'est CE repère qui dit où il atterrira. */
.mc-planning-ligne-salle.est-cible-ok::before,
.mc-planning-ligne-salle.est-cible-avertit::before,
.mc-planning-ligne-salle.est-cible-refus::before {
   content: '';
   position: absolute;
   top: 2px;
   bottom: 2px;
   left: var(--mc-cible-x, 0);
   width: var(--mc-cible-largeur, 0);
   z-index: 2;
   border: 1px solid currentColor;
   /* Bord gauche un peu plus marqué : c'est LUI le repère de dépose — mais
      2px suffisent à le distinguer sans alourdir le tracé. */
   border-left-width: 2px;
   border-radius: .2rem;
   background: rgba(255, 255, 255, .18);
   pointer-events: none;
}

/* L'heure visée, et le motif du refus le cas échéant : sans elle on dépose à
   l'aveugle, puisque le bloc suit le curseur sans se recaler. */
.mc-planning-ligne-salle[data-cible-heure]::after {
   content: attr(data-cible-heure);
   position: absolute;
   top: 2px;
   /* Ancrée au BORD GAUCHE de l'empreinte, pas au bord de la ligne
      (abdAllah, 22/08) : l'heure doit se lire à l'endroit qu'elle désigne,
      pas à l'autre bout de la journée. */
   left: calc(var(--mc-cible-x, 0px) + 2px);
   z-index: 3;
   padding: 0 .35rem;
   border-radius: .2rem;
   font-size: .72rem;
   font-weight: 600;
   white-space: nowrap;
   /* `background: currentColor` avec `color: #fff` donnait du BLANC sur
      BLANC : l'étiquette existait mais restait illisible (abdAllah, 22/08).
      Le fond sombre et fixe garantit le contraste quel que soit l'état —
      vert, orange ou rouge — et la bordure reprend, elle, la couleur de
      l'état pour rester cohérente avec l'empreinte. */
   color: #fff;
   background: rgba(33, 37, 41, .92);
   border: 1px solid currentColor;
   pointer-events: none;
}

.mc-planning-ligne-salle.est-cible-ok::after,
.mc-planning-ligne-salle.est-cible-avertit::after,
.mc-planning-ligne-salle.est-cible-refus::after {
   /* Le texte reprend la couleur de l'état ; on force le blanc par-dessus. */
   color: #fff;
}

/* Motif du refus : porté par le BLOC GLISSÉ, dont le ::after est libre.
   Séparé de l'heure car réunis ils débordaient de l'empreinte sur un cours
   court (30 min = 60 px de large). Il suit le curseur, donc reste visible. */
.mc-planning-cours.est-deplace[data-motif]::after {
   content: attr(data-motif);
   position: absolute;
   top: -1.4rem;
   left: 0;
   z-index: 4;
   padding: 0 .35rem;
   border-radius: .2rem;
   font-size: .72rem;
   font-weight: 600;
   white-space: nowrap;
   color: #fff;
   background: #dc3545;
   pointer-events: none;
}

/* Sans état actif, l'étiquette ne doit pas rester à l'écran. */
.mc-planning-ligne-salle:not(.est-cible-ok):not(.est-cible-avertit):not(.est-cible-refus)::after {
   content: none;
}

/* Zone défilante bornée à la place restante. La hauteur exacte est POSÉE PAR
   mc-defilant.js, qui MESURE la position réelle de l'élément : ce qui le
   précède varie d'une page à l'autre et selon les données, un calc() figé
   serait faux. La valeur ci-dessous n'est qu'un repli, appliqué si le script
   ne tourne pas — la zone reste alors bornée au lieu de s'étirer sans fin. */
.mc-defilant {
   max-height: 60vh;
   overflow-y: auto;
   /* overflow-y non-visible force l'autre axe à sortir de "visible" (même
      piège que .nav-tabs dans backend.css, dans l'autre sens) : le zoom au
      survol dépasse alors d'un demi-pourcent et fait apparaître une barre
      horizontale. D'où overflow-x:hidden EXPLICITE. */
   overflow-x: hidden;
}

/* Ligne d'une zone défilante : plus compacte que l'item Bootstrap par défaut
   (.75rem 1.25rem), pour en montrer davantage sans faire défiler. */
/* Liste simple, en remplacement du list-group de Bootstrap : on n'en
   utilisait que le filet de séparation et le fond. */
.mc-liste {
   display: flex;
   flex-direction: column;
}

/* Filet de séparation UNIQUEMENT entre lignes inertes : les lignes cliquables
   portent leur propre bordure ci-dessous, un filet en plus ferait double
   trait. */
.mc-liste .mc-defilant-item:not(.mc-defilant-action) + .mc-defilant-item:not(.mc-defilant-action) {
   border-top: 1px solid var(--bs-border-color, #dee2e6);
}

.mc-defilant-item {
   /* <button> et <label> n'héritent NI de la police NI de la couleur : sans
      ces trois lignes, les lignes cliquables se distingueraient des autres. */
   font-family: inherit;
   color: inherit;
   background: none;
   /* `border: 0` ici, la bordure des lignes cliquables est posée plus bas :
      le socle sert surtout à neutraliser celle, native, des <button>. */
   border: 0;
   text-align: left;
   padding: .35rem .6rem;
   font-size: .9rem;
   /* Le survol agrandit de 1 % : sans cette réserve, les bords de la ligne
      seraient rognés par overflow-x:hidden. */
   width: calc(100% - 6px);
   margin-inline: 3px;
}

/* Survol net : la ligne est cliquable, elle doit le dire. Bootstrap éclaircit
   à peine le fond sur un list-group-flush ; on force un fond de surbrillance
   et un liseré gauche qui donne le sens de lecture. */
.mc-defilant-action {
   /* Cartouche à part entière (abdAllah, 22/08) : bordure, coins arrondis et
      espacement. Une ligne cliquable se détache ainsi de ses voisines au lieu
      de se fondre dans une liste continue. */
   border: 1px solid var(--bs-border-color, #dee2e6);
   border-radius: .35rem;
   margin-bottom: .35rem;
   /* La transition porte sur la ligne, pas sur le survol : sans elle, le
      retour à l'état normal serait sec. */
   transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease;
}

/* La dernière ne pousse pas le bas de la liste. */
.mc-liste .mc-defilant-action:last-child {
   margin-bottom: 0;
}

/* Survol d'une ligne à dégradé : `.grady-light` est déclarée `!important`
   dans backend.css, un simple background-color ne passerait pas. On teinte
   donc le DÉGRADÉ lui-même, sinon la ligne ne réagirait plus au survol. */
.mc-defilant-action.grady-light:hover,
.mc-defilant-action.grady-light:focus-visible {
   background: linear-gradient(
      rgba(var(--bs-primary-rgb), .10),
      rgba(var(--bs-primary-rgb), .22)) !important;
}

.mc-defilant-action:hover,
.mc-defilant-action:focus-visible {
   /* Variables BOOTSTRAP, présentes partout dans le projet — pas de noms
      maison qui n'existeraient nulle part et retomberaient sur le repli. */
   background-color: rgba(var(--bs-primary-rgb), .08);
   transform: scale(1.01);
   box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 2px 6px 2px;
   /* Sans z-index, l'ombre passerait SOUS les lignes voisines : elles sont
      posées après dans le flux et la recouvriraient. */
   position: relative;
   z-index: 1;
}

/* Zone défilante à hauteur FIXE : même défilement que .mc-defilant, mais la
   hauteur vient d'un style en ligne et non du calcul JS. Sert quand on veut
   une taille constante quelle que soit la place disponible. */
.mc-defilant-fixe {
   overflow-y: auto;
   /* Même piège que .mc-defilant : un axe non-visible force l'autre à sortir
      de « visible », et le zoom au survol ferait apparaître une barre
      horizontale. */
   overflow-x: hidden;
}

/* Ligne cochable : tout le rectangle est cliquable, le curseur doit le dire.
   `user-select` évite qu'un clic un peu traînant sélectionne le texte au lieu
   de cocher. `margin-bottom: 0` annule celui que Bootstrap pose sur <label>. */
.mc-defilant-cochable {
   cursor: pointer;
   /* Plus de `margin-bottom: 0` ici : il servait à neutraliser celui que
      Bootstrap pose sur <label>, mais il ANNULAIT aussi l'espacement voulu de
      .mc-defilant-action, déclaré plus haut donc moins prioritaire. */
   user-select: none;
}

/* Lignes rayées : réservées aux listes SANS ligne cliquable. Là où le survol
   distingue déjà les lignes, le rayage ferait doublon ; là où il n'y a rien à
   survoler, il redonne le repère visuel qui manque. */
.mc-defilant-raye .mc-defilant-item:nth-child(odd) {
   background-color: rgba(var(--bs-emphasis-color-rgb), .04);
}

/* Créneau sous le libellé : secondaire, donc plus petit et estompé. */
.mc-defilant-detail {
   font-size: .78rem;
   opacity: .75;
   line-height: 1.2;
}

/* Avatar : même gabarit que renduColonneAvatar() (shared/membres.php),
   en plus petit — rond, jamais déformé quel que soit le format de la photo. */
.mc-classe-avatar {
   width: 26px;
   height: 26px;
   border-radius: 50%;
   object-fit: cover;
   flex: 0 0 auto;
}

/* Carte de cours À L'HORIZONTALE (abdAllah, 20/08) : heure de début,
   enseignant et matières, salle, heure de fin — tout sur une ligne.
   Le fond vient de la classe .bg-light posée en HTML, pas d'ici. */
/* Les JOURS à l'horizontale : une colonne par jour, qui se replient sur
   les lignes suivantes quand la largeur manque. */
.mc-classe-jours {
   display: flex;
   flex-wrap: wrap;
   align-items: flex-start;
   gap: .8rem;
   margin-bottom: .5rem;
}
.mc-classe-jour-col {
   display: flex;
   flex-direction: column;
   gap: .4rem;
   min-width: 13rem;
}
.mc-classe-jour-titre {
   font-weight: var(--fw-bold);
   color: var(--dominante-color);
}

/* Carte de cours : mise en page VERTICALE d'origine (heure de début en
   haut, corps, salle, heure de fin en bas) — c'est l'empilement de la
   capture. Seuls les jours sont disposés horizontalement. */
.mc-classe-cours {
   display: block;
   border: 1px solid var(--bs-border-color, #dee2e6);
   border-radius: .4rem;
   padding: .35rem .6rem;
   box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 2px 6px 2px;
   /* La carte est un <a> vers l'emploi du temps : on annule le style de
      lien pour que seul le survol signale la cible. `color: inherit` est
      nécessaire, sans quoi tout le contenu passerait en bleu de lien et
      les couleurs propres (salle en dominante, heures en gris) seraient
      écrasées. */
   text-decoration: none;
   color: inherit;
   transition: box-shadow var(--transition-speed, .15s),
               border-color var(--transition-speed, .15s),
               transform var(--transition-speed, .15s);
}
.mc-classe-cours:hover,
.mc-classe-cours:focus-visible {
   border-color: var(--dominante-color);
   transform: translateY(-2px);
   box-shadow: rgba(60, 64, 67, 0.3) 0px 2px 4px 0px, rgba(60, 64, 67, 0.2) 0px 4px 10px 3px;
   color: inherit;
}
.mc-classe-cours:hover .mc-classe-cours-corps {
   color: var(--dominante-color);
}
.mc-classe-cours-heure {
   font-size: .78rem;
   font-weight: var(--fw-bold);
   color: var(--slate, #6c757d);
}
.mc-classe-cours-corps {
   display: flex;
   align-items: center;
   gap: .3rem;
   font-size: .95rem;
}
.mc-classe-cours-salle {
   text-align: right;
   font-size: .78rem;
   font-weight: var(--fw-bold);
   color: var(--dominante-color);
   text-transform: uppercase;
}
.mc-classe-cours-matieres {
   font-size: .78rem;
   color: var(--slate, #6c757d);
}

/* Calendrier : 3 colonnes comme la capture, 1 seule sur mobile. */
/* Bandeau : jours ouvrés à gauche, jours fériés à droite. */
.mc-classe-calendrier-total {
   display: flex;
   justify-content: space-between;
   gap: .6rem;
   flex-wrap: wrap;
   background: var(--dc-8-t, rgba(6, 93, 137, .08));
   border: 1px solid var(--bs-border-color, #dee2e6);
   border-radius: .3rem;
   padding: .3rem .6rem;
   margin-bottom: .6rem;
   font-size: .85rem;
   color: var(--dominante-color);
}
.mc-classe-calendrier {
   display: grid;
   grid-template-columns: repeat(4, 1fr);
   gap: .4rem;
   /* Une session à 5 jours de cours dépasse les 200 cases : la liste
      défile dans une hauteur fixe plutôt que d'allonger la page.
      Le .pe-1 en HTML réserve la place de l'ascenseur, sinon il chevauche
      la bordure droite des cases de la dernière colonne. */
   height: 600px;
   overflow-y: auto;
}
/* Chaque date est un <button> : on annule le style natif et on garde
   exactement l'apparence de case qu'elle avait avant de devenir cliquable. */
.mc-classe-jour {
   width: 100%;
   background: transparent;
   border: 1px solid var(--bs-border-color, #dee2e6);
   border-radius: .3rem;
   padding: .3rem .5rem;
   text-align: center;
   font-size: .85rem;
   color: var(--dominante-color);
   cursor: pointer;
   transition: background-color var(--transition-speed, .15s),
               border-color var(--transition-speed, .15s);
}
.mc-classe-jour:hover,
.mc-classe-jour:focus-visible {
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   border-color: var(--dominante-color);
}
/* Un jour férié est rendu en <div>, pas en <button> : aucun cours n'a lieu,
   il n'y a donc rien à annuler ni à déplacer. Le curseur doit le dire. */
div.mc-classe-jour {
   cursor: default;
}

/* Séance ANNULÉE : barrée et estompée, mais toujours là — la faire
   disparaître laisserait croire qu'elle n'a jamais existé. */
.mc-classe-jour.est-annulee {
   text-decoration: line-through;
   opacity: .55;
}
/* Déplacée ou ajoutée : vert, l'action est positive (la séance a lieu). */
.mc-classe-jour.est-deplacee,
.mc-classe-jour.est-ajoutee {
   color: var(--bs-success, #198754);
   background: rgba(25, 135, 84, .07);
   border-color: rgba(25, 135, 84, .35);
}
/* Hachure sur les séances DÉPLACÉES : même effet que les cours en
   surcapacité de la grille (abdAllah, 21/08), en vert plutôt qu'en rouge —
   la séance a bien lieu, elle a seulement changé de date. `position` et
   `overflow` sont nécessaires : la case est un <button>, dont le contenu
   déborderait sinon du pseudo-élément. */
.mc-classe-jour.est-deplacee {
   position: relative;
   overflow: hidden;
}
.mc-classe-jour.est-deplacee::after {
   content: "";
   position: absolute;
   inset: 0;
   pointer-events: none;
   background: repeating-linear-gradient(
      45deg,
      rgba(25, 135, 84, .18) 0 6px,
      transparent 6px 12px
   );
}
/* Jour férié : rouge sur fond rosé, comme la capture. Les couleurs sont
   celles de Bootstrap (--bs-danger) pour rester cohérentes avec le reste
   des états d'alerte du projet. */
/* Horaire de désambiguïsation, quand plusieurs séances tombent le même
   jour. Discret : la date reste l'information principale. */
.mc-classe-jour-heure {
   display: block;
   font-size: .72rem;
   opacity: .75;
}
.mc-classe-jour.est-ferie {
   color: var(--bs-danger, #dc3545);
   background: rgba(220, 53, 69, .07);
   border-color: rgba(220, 53, 69, .35);
}
/* 4 colonnes ne tiennent pas sous 1200px : on dégrade par paliers plutôt
   que de laisser les dates se replier au milieu d'un libellé. */
@media (max-width: 1199.98px) {
   .mc-classe-calendrier {
      grid-template-columns: repeat(3, 1fr);
   }
}
@media (max-width: 991.98px) {
   .mc-classe-calendrier {
      grid-template-columns: repeat(2, 1fr);
   }
}
@media (max-width: 575.98px) {
   .mc-classe-calendrier {
      grid-template-columns: 1fr;
   }
}

/* Compteur des cours affichés (organisation/emploi-du-temps.php) —
   abdAllah, 20/08. Posé à côté du bouton « Réinitialiser » de la barre
   de filtres. */
.mc-compteur-cours {
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   color: var(--dominante-color);
   border-color: var(--dc-25-t, rgba(6, 93, 137, .25));
}
/* Filtre actif mais aucun cours retenu : la grille vide pourrait passer
   pour une panne, le compteur vire au rouge pour lever le doute. */
.mc-compteur-cours.est-vide {
   background: rgba(220, 53, 69, .1);
   color: var(--bs-danger, #dc3545);
}

/* Message d'erreur sur plusieurs lignes (organisation/emploi-du-temps.php) :
   le conflit de salle liste les salles libres sur une 2e ligne. Le texte
   étant échappé par e(), le saut est un vrai "\n" dans la chaîne et c'est
   `pre-line` qui le rend — sans figer les espaces comme le ferait `pre`. */
.mc-erreur-multiligne {
   white-space: pre-line;
}

/* ========================================================================
   DÉRIVE DE CAPACITÉ (organisation/emploi-du-temps.php) — abdAllah, 20/08
   ======================================================================== */
/* Les deux indicateurs sur une ligne à eux. */
.mc-ligne-indicateurs {
   display: flex;
   flex-wrap: wrap;
   align-items: stretch;
   gap: .5rem;
}

/* Socle COMMUN aux deux : toutes les dimensions sont ici et nulle part
   ailleurs, c'est ce qui garantit qu'ils restent identiques quoi qu'il
   arrive. Les classes spécifiques ne posent QUE des couleurs. */
.mc-indicateur {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   gap: .4rem;
   min-width: 12rem;
   min-height: 2.1rem;
   padding: .25rem .8rem;
   border: 1px solid transparent;
   border-radius: .3rem;
   font-weight: var(--fw-bold);
   font-size: .85rem;
   text-decoration: none;
   white-space: nowrap;
}
.mc-indicateur .ph-duotone {
   font-size: 1.25rem;
   line-height: 1;
}

.mc-alerte-surcapacite {
   background: rgba(220, 53, 69, .12);
   color: var(--bs-danger, #dc3545);
   border-color: rgba(220, 53, 69, .35);
}
.mc-alerte-surcapacite:hover,
.mc-alerte-surcapacite.est-actif {
   background: var(--bs-danger, #dc3545);
   color: #fff;
   border-color: var(--bs-danger, #dc3545);
}

/* Le bloc de cours garde la COULEUR DE SA FILIÈRE (posée en ligne) : on ne
   la remplace pas, on ajoute un liseré et une hachure. Un fond plein ferait
   perdre l'information de filière, et le style en ligne l'emporterait de
   toute façon sur une règle d'ici.
   Deux niveaux : ROUGE = salle déjà dépassée (constat), ORANGE = risque
   structurel (classe sans plafond, ou plafond au-dessus de la salle). */
.mc-planning-cours.est-surcapacite {
   outline: 2px solid var(--bs-warning, #ffc107);
   outline-offset: -2px;
}
.mc-planning-cours.est-depassee {
   outline-color: var(--bs-danger, #dc3545);
}
.mc-planning-cours.est-surcapacite::after {
   content: "";
   position: absolute;
   inset: 0;
   pointer-events: none;
   background: repeating-linear-gradient(
      45deg,
      rgba(255, 193, 7, .30) 0 6px,
      transparent 6px 12px
   );
}
.mc-planning-cours.est-depassee::after {
   background: repeating-linear-gradient(
      45deg,
      rgba(220, 53, 69, .28) 0 6px,
      transparent 6px 12px
   );
}
@media print {
   #zoneImpression .mc-planning-cours.est-surcapacite {
      -webkit-print-color-adjust: exact;
      print-color-adjust: exact;
   }
}

/* ========================================================================
   MC-SELECT — mode MULTIPLE à cases à cocher (23/08)
   ========================================================================
   Le composant refusait les selects multiples ; il les habille désormais.
   Même apparence qu'en simple, avec une case à gauche de chaque option et
   les choix affichés en pastilles colorées dans le champ.
   ======================================================================== */

/* Case à cocher — MÊME DESSIN que `.form-check-input` du projet (abdAllah,
   23/08) : 22px, bordure 2px dominante, rayon 4px, et la coche en V d'un
   `::after`. J'avais dessiné la mienne, elle ne ressemblait pas aux autres.

   Un <span> et non un <input> : la ligne entière est déjà cliquable, un vrai
   champ y ajouterait une seconde cible et un ordre de tabulation parasite.
   D'où la reprise du dessin plutôt que de la classe. */
.mc-combo-case {
   /* `inline-block` : `.mc-combo-option` n'est PAS un conteneur flex, une
      propriété `flex` y serait ignorée et la case se réduirait à un trait. */
   display: inline-block;
   vertical-align: middle;
   width: 22px;
   height: 22px;
   margin-right: .5rem;
   border: 2px solid var(--dominante-color, #065d89);
   border-radius: 4px;
   background-color: transparent;
   position: relative;
   transition: all .25s ease;
}

[data-theme="dark"] .mc-combo-case {
   border: 2px solid var(--dc-70-w, #518eac);
}

/* `aria-selected` porte l'état : le CSS et les lecteurs d'écran lisent la
   même source, elles ne peuvent pas diverger. */
.mc-combo-option[aria-selected="true"] .mc-combo-case {
   background-color: var(--dc-40-w, #9bbed0);
   border-color: var(--dominante-color, #065d89);
}

.mc-combo-case::after {
   content: "";
   position: absolute;
   /* Dimensions du TRAIT, pas de la case — comme .form-check-input. */
   top: 2px;
   left: 6px;
   width: 6px;
   height: 12px;
   border: solid var(--dc-50-777777, #3f6a80);
   border-width: 0 3px 3px 0;
   transform: rotate(40deg);
   opacity: 0;
   pointer-events: none;
   transition: opacity .2s ease-in-out;
}

[data-theme="dark"] .mc-combo-case::after {
   border: solid var(--dc-1-w, #fdfdfe);
   border-width: 0 3px 3px 0;
}

.mc-combo-option[aria-selected="true"] .mc-combo-case::after {
   opacity: 1;
}

/* Le champ fermé : une pastille par choix, qui passent à la ligne plutôt que
   de déborder. */
.mc-combo-value-multiple {
   display: flex;
   flex-wrap: wrap;
   gap: .25rem;
   align-items: center;
}

.mc-combo-pastille {
   display: inline-block;
   padding: .05rem .45rem;
   border-radius: 1rem;
   font-size: var(--fs-2xs);
   background: var(--dc-12-t, rgba(6, 93, 137, .12));
   line-height: 1.4;
}

/* Option neutralisée par une option EXCLUSIVE cochée (23/08) : « Toutes mes
   classes » ou « Tout l'établissement » englobent déjà les autres. Grisées
   plutôt que masquées — on voit ce qui existe, et pourquoi c'est indisponible. */
.mc-combo-option-inerte {
   opacity: .45;
   cursor: not-allowed;
}

/* Ni fond au survol ni case cliquable : la ligne ne réagit plus. */
.mc-combo-option-inerte:hover,
.mc-combo-option-inerte.mc-combo-active {
   background: transparent;
}
