/* ==========================================================================
   UTILITAIRES — classes remplaçant les styles inline des composants Razor.

   Section 1 : classes sémantiques partagées (motifs récurrents nommés).
   Section 2+ : utilitaires atomiques. Ils sont en !important pour conserver
   exactement la priorité qu'avaient les styles inline qu'ils remplacent
   (un style inline l'emportait déjà sur toute règle de feuille de style).
   Les valeurs numériques des noms sont en pixels (fs-82 = 0.82rem).
   ========================================================================== */

/* ── 1. Classes sémantiques partagées ───────────────────────────────────── */

/* Entête de section : titre à gauche, action(s) à droite */
.entete-section {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 4px;
}

/* Sous-titre discret d'un bloc */
.sous-titre-attenue {
    color: var(--text-subtle);
    font-size: 0.82rem;
    font-weight: 600;
    margin: 0;
}

/* Mention secondaire dans un libellé (ex : « (optionnel) ») */
.texte-attenue {
    color: var(--text-muted);
    font-weight: 400;
}

/* Titre de page/panneau en capitales espacées */
.titre-majuscule {
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 1px;
}

/* Titre principal d'une page. Ces titres étaient des <h2> et sont passés <h1>
   le 2026-08-24 (le <h1> était pris par le nom de l'application dans l'entête) ;
   la taille est figée ici pour que la promotion ne change pas le rendu — un
   <h1> vaut 2em par défaut là où un <h2> vaut 1,5em. */
.page-titre {
    font-size: 1.5rem;
}

/* Libellé cliquable portant une case à cocher */
.libelle-case {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.85rem;
    cursor: pointer;
}

/* Bloc séparé du contenu précédent par un filet */
.bloc-separe {
    border-top: 1px solid var(--border);
    padding-top: 16px;
}

/* Encadré de formulaire secondaire (panneau déplié) */
.bloc-encadre {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 14px;
}

/* Bandeau d'avertissement jaune */
.bandeau-avertissement {
    background: #fff8db;
    border: 1px solid #f0c419;
    border-radius: 6px;
    color: #8a6d00;
}

/* Bloc de code (page de démonstration du style) */
.bloc-code {
    background: var(--background);
    padding: 10px 14px;
    font-size: 0.8rem;
    overflow-x: auto;
    margin: 0 0 12px;
}

/* Texte coupé par une ellipse */
.texte-tronque {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── 2. Disposition (flex / grid) ───────────────────────────────────────── */

.flex          { display: flex !important; }
.flex-colonne  { flex-direction: column !important; }
.flex-wrap     { flex-wrap: wrap !important; }
.flex-centre   { align-items: center !important; }
.items-fin     { align-items: end !important; }
.justif-fin    { justify-content: flex-end !important; }
.flex-1        { flex: 1 !important; }
.flex-fixe     { flex-shrink: 0 !important; }

.gap-6    { gap: 6px !important; }
.gap-8    { gap: 8px !important; }
.gap-10   { gap: 10px !important; }
.gap-12   { gap: 12px !important; }
.gap-8-18 { gap: 8px 18px !important; }

.colonne-pleine { grid-column: 1 / -1 !important; }
.colonne-2      { grid-column: span 2 !important; }
.colonne-3      { grid-column: span 3 !important; }

/* Quand les grilles retombent sur une colonne (cf. form.css), un « span 2 »
   créerait une deuxième colonne implicite et ferait déborder la ligne. On rend
   la main à la grille. Ces règles vivent ici, et non dans form.css, parce que
   utilitaires.css est chargé en dernier : à !important égal, c'est la dernière
   feuille qui l'emporte. */
/* .colonne-3 est neutralisé dès 1024px : c'est le seuil auquel .info-grid-3
   passe à deux colonnes (form.css). Le laisser à 768 faisait qu'entre 769 et
   1024 un « span 3 » créait une troisième colonne implicite dans une grille
   qui n'en avait plus que deux — le champ débordait de sa rangée. */
@media (max-width: 1024px) {
    .colonne-3 {
        grid-column: auto !important;
    }
}

/* .colonne-2 suit .info-grid-2, qui ne retombe sur une colonne qu'à 768px. */
@media (max-width: 768px) {
    .colonne-2 {
        grid-column: auto !important;
    }
}

/* ── 3. Marges / paddings ───────────────────────────────────────────────── */
/* .m-0 est déclaré en premier : combiné à un mt-*/mb-*, c'est la marge
   directionnelle (déclarée plus bas) qui gagne. */

.m-0   { margin: 0 !important; }
.my-12 { margin-top: 12px !important; margin-bottom: 12px !important; }
.mx-16 { margin-left: 16px !important; margin-right: 16px !important; }

.mt-4  { margin-top: 4px !important; }
.mt-10 { margin-top: 10px !important; }
.mt-12 { margin-top: 12px !important; }
.mt-16 { margin-top: 16px !important; }

.mb-0  { margin-bottom: 0 !important; }
.mb-8  { margin-bottom: 8px !important; }
.mb-10 { margin-bottom: 10px !important; }
.mb-12 { margin-bottom: 12px !important; }
.mb-14 { margin-bottom: 14px !important; }
.mb-16 { margin-bottom: 16px !important; }
.mb-20 { margin-bottom: 20px !important; }

.ml-4  { margin-left: 4px !important; }
.ml-6  { margin-left: 6px !important; }

.p-0     { padding: 0 !important; }
.p-24    { padding: 24px !important; }
.p-8-12  { padding: 8px 12px !important; }
.p-10-16 { padding: 10px 16px !important; }

/* ── 4. Dimensions ──────────────────────────────────────────────────────── */

.w-auto { width: auto !important; }
.w-100  { width: 100% !important; }

.max-l-130  { max-width: 130px !important; }
.max-l-140  { max-width: 140px !important; }
.max-l-420  { max-width: 420px !important; }
.max-l-640  { max-width: 640px !important; }
.max-l-700  { max-width: 700px !important; }
.max-l-800  { max-width: 800px !important; }
.max-l-805  { max-width: 805px !important; }
.max-l-828  { max-width: 828px !important; }
.max-l-1035 { max-width: 1035px !important; }
.max-l-1150 { max-width: 1150px !important; }

.max-h-70vh { max-height: 70vh !important; }
.max-h-80vh { max-height: 80vh !important; }
.max-h-96vh { max-height: 96vh !important; }

/* ── 5. Texte ───────────────────────────────────────────────────────────── */

.texte-centre { text-align: center !important; }
.texte-droite { text-align: right !important; }
.texte-gauche { text-align: left !important; }

.nowrap     { white-space: nowrap !important; }
.monospace  { font-family: monospace !important; }
.italique   { font-style: italic !important; }
.majuscules { text-transform: uppercase !important; }

.fw-600 { font-weight: 600 !important; }
.fw-700 { font-weight: 700 !important; }

.fs-80  { font-size: 0.8rem !important; }
.fs-82  { font-size: 0.82rem !important; }
.fs-85  { font-size: 0.85rem !important; }
.fs-90  { font-size: 0.9rem !important; }
.fs-105 { font-size: 1.05rem !important; }
.fs-125 { font-size: 1.25rem !important; }

/* ── 6. Couleurs / opacité ──────────────────────────────────────────────── */

.texte-base       { color: var(--text) !important; }
.texte-primaire   { color: var(--primary) !important; }
.texte-secondaire { color: var(--secondary) !important; }
.texte-accent     { color: var(--accent) !important; }

.fond-primaire-pastel   { background-color: var(--primary-pastel) !important; }
.fond-secondaire-pastel { background-color: var(--secondary-pastel) !important; }

/* Les utilitaires .opacite-* ont été retirés le 2026-08-24 : appliquer une
   opacité à du texte produisait un contraste insuffisant en dessous de 0,65
   (0,60 rend #777776, soit 4,48:1 sur blanc). Le texte atténué passe désormais
   par une couleur ; l'opacité reste réservée au décoratif, déclarée directement
   dans la feuille du composant concerné. */
.texte-discret { color: var(--text-muted) !important; }
.texte-efface  { color: var(--text-subtle) !important; }

/* ── 7. Divers ──────────────────────────────────────────────────────────── */

.pointeur         { cursor: pointer !important; }
.masque           { display: none !important; }
.sans-debordement { overflow: hidden !important; }
.defilement-y     { overflow-y: auto !important; }

/* ==========================================================================
   8. Complément — valeurs présentes dans le code postérieur au 09/07/2026.
   Même rôle et mêmes conventions que les sections ci-dessus : ces classes
   couvrent les styles inline apparus dans les composants ajoutés depuis la
   factorisation initiale.
   ========================================================================== */

/* Marges */
.mt-2      { margin-top: 2px !important; }
.mt-6      { margin-top: 6px !important; }
.mt-8      { margin-top: 8px !important; }
.mt-14     { margin-top: 14px !important; }
.mt-20     { margin-top: 20px !important; }
.mt-0      { margin-top: 0 !important; }
.mt-neg-4  { margin-top: -4px !important; }
.mt-neg-8  { margin-top: -8px !important; }
.mt-neg-16 { margin-top: -16px !important; }
.mb-4      { margin-bottom: 4px !important; }
.mb-6      { margin-bottom: 6px !important; }

/* Paddings */
.p-16  { padding: 16px !important; }
.p-32  { padding: 32px !important; }
.p-40  { padding: 40px !important; }
.pt-26 { padding-top: 26px !important; }
.pl-18 { padding-left: 18px !important; }

/* Dimensions */
.col-64  { width: 64px; }
.col-190 { width: 190px; }
.col-220 { width: 220px; }
.col-340 { width: 340px; }

.max-l-180 { max-width: 180px !important; }
.max-l-200 { max-width: 200px !important; }
.max-l-220 { max-width: 220px !important; }
.max-l-240 { max-width: 240px !important; }
.max-l-320 { max-width: 320px !important; }
.max-l-360 { max-width: 360px !important; }
.max-l-440 { max-width: 440px !important; }
.max-l-480 { max-width: 480px !important; }
.max-l-680 { max-width: 680px !important; }
.max-l-720 { max-width: 720px !important; }
.max-l-900 { max-width: 900px !important; }

.max-h-72vh { max-height: 72vh !important; }
.max-h-92vh { max-height: 92vh !important; }

/* Disposition */
.bloc          { display: block !important; }
.justif-espace { justify-content: space-between !important; }
.gap-4         { gap: 4px !important; }
.gap-16        { gap: 16px !important; }
.auto-etire    { align-self: stretch !important; }

/* Texte */
.fs-72            { font-size: 0.72rem !important; }
.fs-76            { font-size: 0.76rem !important; }
.fs-78            { font-size: 0.78rem !important; }
.fs-88            { font-size: 0.88rem !important; }
.fw-400           { font-weight: 400 !important; }
.pre-wrap         { white-space: pre-wrap !important; }
.sans-soulignement { text-decoration: none !important; }

/* Couleurs / opacité */
/* Rouge d'erreur : valeur historique conservée telle quelle par la
   factorisation. Centralisée ici pour pouvoir être corrigée en un seul point
   (contraste 3,82:1 sur blanc, sous le seuil AA de 4,5:1). */
/* Les deux nuances de rouge (#e74c3c et #c0392b) sont réunies dans --danger :
   la plus claire échouait au contraste (3,82:1), la plus foncée est devenue
   la valeur du token. */
.texte-danger { color: var(--danger) !important; }
.fond-danger         { background: var(--danger) !important; }
.texte-blanc         { color: #ffffff !important; }
