/* Feuille de style unique pour toute l'appli (pas de framework CSS).
   Convention : toutes les classes sont préfixées "gs-" (Gestion Spectacles) pour éviter
   toute collision avec d'autres styles qui pourraient être chargés sur la page. */

/* ============================================
   Application ADMIN / RESPONSABLE (app.js)
   ============================================ */

/* Largeur standard, commune à TOUTES les pages de l'appli (Tableau de bord, Gestion, Infos
   spectacle, Mon profil...) : ne change jamais en changeant de page, seul le contenu à l'intérieur
   varie. C'est ICI (pas sur #gs-main, voir plus bas) que la limite + le centrage sont appliqués :
   #gs-app est un simple bloc dans le flux normal de #gs-main, le centrage par marges automatiques
   y est donc fiable (toujours exactement 1200px si la place le permet). #gs-main, lui, est un item
   flexible côté admin/responsable (enfant de .gs-colonne-app) — centrer un item flexible avec des
   marges automatiques ne vise pas une largeur fixe, il se contente de rétrécir à la taille de son
   contenu, ce qui donnait une largeur différente sur chaque page. */
#gs-app { max-width: 1200px; margin: 0 auto; }

/* ============================================
   Coquille de page admin/responsable, sous le bandeau principal (gs-header, pleine largeur,
   commun aux 3 profils) : sidebar + colonne de contenu l'une à côté de l'autre, en dehors de tout
   conteneur centré/à largeur limitée. C'est ce qui permet à la sidebar de toucher réellement le
   bord gauche de l'écran plutôt que d'être une colonne posée au milieu d'une page comme un bloc
   de contenu, connectée au bandeau au-dessus d'elle (même couleur, aucun espace entre les deux).
   align-items:stretch (par défaut) fait que la sidebar s'étire toujours à la même hauteur que le
   contenu à côté ; min-height:100vh en plus, pour que les deux atteignent quand même le bas de
   l'écran même quand le contenu est court (sinon la sidebar s'arrêtait net avant le bas de la page).
   ============================================ */
.gs-app-shell { display: flex; min-height: 100vh; }

/* Barre latérale : arborescence à 3 niveaux de navigation, remplace l'ancienne nav horizontale +
   les sous-onglets qui occupaient chacun leur propre bandeau au-dessus du contenu. Colle au bord
   gauche, et reste "collée" à l'écran pendant le défilement d'une page longue grâce à
   position:sticky (juste sous le bandeau principal, non sticky lui, qui défile normalement). */
.gs-sidebar {
    flex: 0 0 240px;
    background: #1b2340;
    padding: 1.1rem 0.9rem;
    display: flex;
    flex-direction: column;
    gap: 2px;
    position: sticky;
    top: 0;
    box-sizing: border-box;
}

/* Colonne de contenu à droite de la sidebar : le contenu applicatif habituel (#gs-main, inchangé),
   la gestion de compte étant revenue dans le bandeau principal pleine largeur au-dessus. */
.gs-colonne-app { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* Niveau 0 : Tableau de bord / Gestion — la nav principale, en gras/grand, surbrillance blanche
   sur le fond marine de la sidebar pour l'état actif (le marine du fond ne permet pas d'y reposer
   une 2e couleur "marine" pour l'actif, contrairement à l'ancienne nav sur fond clair). */
.gs-nav-btn {
    width: 100%;
    text-align: left;
    background: transparent;
    border: none;
    color: rgba(255,255,255,0.92);
    padding: 0.55rem 0.65rem;
    border-radius: 8px;
    cursor: pointer;
    font-weight: 700;
    font-size: 0.86rem;
    letter-spacing: 0.01em;
    margin-top: 16px;
}
.gs-nav-btn:first-child { margin-top: 0; }
.gs-nav-btn.active { background: rgba(255,255,255,0.16); color: white; }

/* Replie la sidebar en tiroir sur petit écran (voir #btn-toggle-sidebar dans app.js) : masqué par
   défaut au-delà du seuil, seul le bouton ☰ du bandeau de compte permet de l'ouvrir. Poussé au
   bord gauche du bandeau via margin-right:auto (au lieu d'un 2e conteneur juste pour ça), pendant
   que gs-header-right reste ancré à droite grâce à justify-content:flex-end sur le parent. */
.gs-hamburger {
    display: none;
    background: rgba(255,255,255,0.12);
    border: none;
    color: white;
    width: 34px;
    height: 34px;
    border-radius: 8px;
    font-size: 1.1rem;
    cursor: pointer;
}
@media (max-width: 860px) {
    .gs-hamburger { display: inline-flex; align-items: center; justify-content: center; margin-right: auto; }
    .gs-sidebar {
        position: fixed;
        top: 0; left: 0; bottom: 0;
        z-index: 100;
        width: 260px;
        min-height: 100vh;
        transform: translateX(-100%);
        transition: transform 0.2s ease;
        overflow-y: auto;
    }
    .gs-sidebar.gs-sidebar-ouverte { transform: translateX(0); }
    /* Voile derrière le tiroir ouvert : cliquer dessus le referme (voir app.js). Posé/retiré du
       DOM par JS en même temps que la classe ci-dessus, pas besoin de le garder si le tiroir est fermé. */
    .gs-sidebar-voile { position: fixed; inset: 0; background: rgba(20,22,30,0.4); z-index: 99; }
}

/* Conteneur de défilement horizontal propre à un tableau large (voir index.php, .gs-table-scroll
   enveloppe chaque table) : sur petit écran, un tableau à 5-7 colonnes ne peut pas physiquement
   tenir sans devenir illisible — plutôt que de forcer TOUTE LA PAGE à défiler horizontalement (ce
   qui cassait aussi la sidebar/le bandeau, restés fixes), seul ce cadre-là défile, le reste de la
   page reste normal. Le fond/l'arrondi/l'ombre du tableau viennent d'ici plutôt que de .gs-table
   lui-même, pour qu'ils restent visibles même une fois le contenu scrollé. */
.gs-table-scroll { overflow-x: auto; border-radius: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.08); margin-bottom: 0.5rem; }
/* Grille Gestion > Base de données : hauteur bornée avec défilement vertical ET horizontal DANS ce
   cadre (contrairement à .gs-table-scroll seul, qui ne borne que la largeur) — une table à
   beaucoup de colonnes (user) et encore plus (predevis) grandirait sinon indéfiniment en hauteur
   avec le nombre de lignes, repoussant la barre de défilement horizontal tout en bas, hors de vue
   sans redescendre toute la page. thead sticky : les en-têtes de colonnes restent visibles en
   défilant verticalement à l'intérieur de ce cadre borné. */
.gs-bdd-table-scroll { max-height: 65vh; overflow-y: auto; }
.gs-bdd-table-scroll thead th { position: sticky; top: 0; z-index: 1; }
/* min-width : empêche les colonnes de se tasser jusqu'à devenir illisibles sur petit écran — le
   tableau garde une largeur confortable minimale et déclenche le défilement horizontal du cadre
   ci-dessus plutôt que de se comprimer. width:100% reste prioritaire dès que la place le permet
   (aucun changement par rapport à avant sur un écran normal/large). */
.gs-table { width: 100%; min-width: 600px; border-collapse: collapse; background: white; }
/* Gris ardoise, pas bleu marine : un en-tête de tableau (liste de données) n'est pas de la
   navigation, sa couleur ne doit pas non plus être confondue avec la nav principale ni avec
   aucune autre couleur "de rôle" de l'app (voir .gs-entete-spectacle, .gs-sous-onglet.active). */
.gs-table th { background: #3a4250; color: white; text-align: left; padding: 0.8rem 1rem; font-weight: 600; font-size: 0.9rem; }
.gs-table td { padding: 0.8rem 1rem; border-bottom: 1px solid #dde1e8; }
.gs-table tbody tr[data-clickable] { cursor: pointer; }
.gs-table tbody tr[data-clickable]:hover { background: #fff8ea; }
/* Grille brute de Gestion > Base de données (admin) : cellule éditable en place (voir gs-bdd-cellule
   dans app.js) plutôt qu'un vrai formulaire par ligne, pour rester compact sur une table qui peut
   avoir beaucoup de colonnes. Clé primaire en lecture seule (fond gris ardoise très clair, jamais
   confondu avec le gris ardoise plein des en-têtes) : jamais modifiable depuis cet écran. */
.gs-bdd-cle { background: #f4f5f8; color: #556; font-weight: 600; white-space: nowrap; }
.gs-bdd-cellule { width: 100%; min-width: 100px; padding: 0.35rem 0.5rem; border: 1px solid transparent; border-radius: 6px; font-size: 0.85rem; font-family: inherit; }
.gs-bdd-cellule:hover, .gs-bdd-cellule:focus { border-color: #dde1e8; background: #fafbfc; }
.gs-vide-inline { color: #99a; font-style: italic; }
/* Colonne Notes de la vue liste (tableau de bord) : une note peut être longue, on tronque avec
   "..." plutôt que d'élargir toute la ligne ; le texte complet reste lisible au survol (title). */
.gs-notes-cell { max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.gs-badge-count { display: inline-block; background: #f7d379; color: #1b2340; font-weight: 600; padding: 0.15rem 0.6rem; border-radius: 999px; font-size: 0.85rem; }

/* Bandeau "titre" du spectacle (date/lieu/département/responsable) au-dessus des onglets
   Gestion/Affectation/Demande de devis (voir detail-infos dans index.php/app.js) : un repère
   visuel fort et toujours au même endroit pour ne jamais perdre de vue dans quel spectacle on se
   trouve, même après avoir défilé loin dans un long formulaire. Bleu-vert pétrole : couleur dédiée
   à ce type de bandeau "entête de fiche", différente du bleu marine (nav principale), du violet
   (sous-onglets), du gris ardoise (en-têtes de tableaux, voir .gs-table th) et du doré (réservé aux
   titres de section de formulaire + au badge de type de compte connecté) — chaque rôle a sa
   propre couleur, aucune n'est réutilisée pour un autre rôle. */
.gs-entete-spectacle {
    display: flex;
    flex-direction: column;
    gap: 6px;
    background: #1e5f74;
    color: white;
    border-radius: 10px;
    padding: 0.7rem 1rem;
    margin-bottom: 1rem;
    box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}
.gs-entete-titre { font-size: 1.15rem; font-weight: 700; }
.gs-entete-meta { display: flex; flex-wrap: wrap; gap: 6px; }
.gs-badge-meta { background: rgba(255,255,255,0.18); color: white; font-size: 0.78rem; padding: 0.2rem 0.6rem; border-radius: 999px; white-space: nowrap; }
/* Place le bouton "Bon de commande" (voir bandeau-bon-commande-zone dans app.js) à droite du
   titre/des badges, sur la même ligne quand la place le permet (repasse en dessous sinon, voir
   flex-wrap) : seul élément interactif du bandeau, jamais un simple repère visuel comme le reste. */
.gs-entete-ligne { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.gs-btn-desactive { opacity: 0.55; cursor: not-allowed; }
/* Le bouton "Bon de commande" peut etre un <a> (une fois genere, lien de telechargement, voir
   afficherBoutonBonCommande dans app.js) : .gs-btn seul ne neutralise pas le style natif des liens
   (bleu, souligne), d'ou le fond blanc qui "faisait lien hypertexte" plutot que vrai bouton. Et la
   croix de suppression (.gs-btn-retirer), pensee pour un fond blanc ailleurs dans l'appli, est trop
   grise pour rester lisible sur le bandeau teal fonce : variante plus claire propre a cette zone. */
#bandeau-bon-commande-zone .gs-btn-retirer { color: rgba(255,255,255,0.75); }
#bandeau-bon-commande-zone .gs-btn-retirer:hover { color: #ffb3a7; }

.gs-colonnes { display: flex; gap: 1.5rem; flex-wrap: wrap; }
.gs-colonne { flex: 1; min-width: 280px; background: white; border-radius: 10px; padding: 1rem; box-shadow: 0 2px 8px rgba(0,0,0,0.08); min-height: 220px; }
.gs-colonne h3 { margin-top: 0; font-size: 1rem; border-bottom: 2px solid #dde1e8; padding-bottom: 0.5rem; }
/* Fiche artificier (Gestion) : le formulaire a beaucoup plus de champs que "Ses spectacles" à
   côté, flex:2 lui laisse la place de mettre plusieurs champs par ligne (voir .gs-formulaire
   plus bas) au lieu d'un empilement vertical qui obligeait à défiler très loin. */
.gs-colonne-principale { flex: 2; min-width: 480px; }
/* Sur écran étroit, gs-colonnes empile déjà les colonnes (flex-wrap) : un min-width de 480px
   dépasserait quand même la largeur de l'écran sur mobile (débordement horizontal), d'où ce
   retour à un comportement normal en dessous de ce seuil. */
@media (max-width: 600px) {
    .gs-colonne-principale { min-width: 0; }
    /* Padding allégé : sur un écran de téléphone, garder 1.5rem de chaque côté (48px au total)
       grignote une part non négligeable des ~320-375px disponibles pour les tableaux/formulaires. */
    #gs-main { padding: 1rem; }
}

/* Liste "Ses spectacles" de la fiche artificier : hauteur plafonnée avec défilement propre,
   sinon un artificier avec beaucoup de spectacles étire toute la page bien plus bas que la
   colonne du formulaire à côté. */
#fiche-spectacles-liste { max-height: 640px; overflow-y: auto; }

/* Barre d'actions d'un formulaire (utilisée sur la plupart des gs-formulaire-actions) : reste
   visible en bas de l'écran pendant le défilement plutôt qu'accessible seulement tout en bas du
   formulaire ou de la page. Utile même sur un formulaire "court" dès que l'écran est étroit
   (champs qui s'empilent) ou qu'il y a du contenu après la barre (ex: carte des secteurs). */
.gs-actions-collantes { position: sticky; bottom: 0; background: white; margin-top: 0.5rem; padding-top: 0.75rem; padding-bottom: 0.25rem; border-top: 1px solid #dde1e8; box-shadow: 0 -4px 8px rgba(0,0,0,0.05); }

/* min-height évite que la colonne s'effondre à 0px quand la liste est vide,
   ce qui la rendrait difficile à cibler comme zone de dépôt (drag & drop). */
.gs-liste { list-style: none; margin: 0; padding: 0; min-height: 60px; }
/* Retour visuel appliqué en JS (app.js) quand un élément est glissé au-dessus de la liste. */
.gs-liste.gs-drag-over { background: #fff8ea; outline: 2px dashed #e6a817; outline-offset: -4px; border-radius: 6px; }

.gs-item { background: #f4f5f8; border: 1px solid #dde1e8; border-radius: 8px; padding: 0.6rem 0.9rem; margin-bottom: 0.5rem; display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; user-select: none; }
.gs-item[draggable="true"] { cursor: grab; }
/* Élément estompé pendant qu'il est en cours de glisser-déposer (classe posée par app.js au dragstart). */
.gs-item.gs-dragging { opacity: 0.4; }
.gs-item .gs-poignee { color: #99a; font-size: 0.85rem; }
.gs-item .gs-actions { display: flex; align-items: center; gap: 6px; }

/* gs-item-responsable : bloc "Mes responsables" (fiche artificier). Nom, puis téléphone, puis
   email, TOUJOURS chacun sur sa propre ligne, dans cet ordre — un flex-wrap laissant le navigateur
   décider où revenir à la ligne (essayé d'abord) donnait une disposition différente d'une carte à
   l'autre selon la longueur du nom/de l'email (parfois contact sur la même ligne que le nom,
   parfois pas). Empilé en colonne de façon fixe : la position de chaque ligne ne dépend plus du
   contenu, seule sa hauteur peut varier (word-break sur une valeur très longue). */
.gs-item.gs-item-responsable { flex-direction: column; align-items: flex-start; gap: 4px; }
.gs-item-responsable .gs-resp-contact { display: flex; flex-direction: column; gap: 2px; font-size: 0.85rem; color: #556; width: 100%; }

/* gs-item-devis : ligne d'un devis (onglet Pièces jointes) — même empilement fixe en colonne que
   gs-item-responsable ci-dessus (libellé/statut, puis le plan de tir rattaché juste en dessous,
   jamais un flex-wrap laissé au navigateur qui replacerait les éléments de façon incohérente). */
.gs-item.gs-item-devis { flex-direction: column; align-items: flex-start; gap: 6px; }
.gs-item-devis .gs-devis-entete { display: flex; justify-content: space-between; align-items: center; width: 100%; gap: 6px; flex-wrap: wrap; }
/* Libellé du devis (ex: "Budget réduit") : un simple commentaire à côté du nom de fichier réel,
   jamais son remplacement (voir afficherDocsDevis dans app.js) - couleur atténuée pour bien rester
   secondaire visuellement par rapport au nom de fichier. */
/* Rendu en petite étiquette arrondie (même famille visuelle que gs-badge-gris, une simple info
   neutre) plutôt qu'un texte italique brut - demande explicite de l'utilisateur ("rend plus jolie"). */
.gs-devis-libelle { display: inline-block; background: #e8eaf0; color: #556; font-weight: 600; font-style: normal; font-size: 0.78rem; padding: 0.15rem 0.6rem; border-radius: 999px; white-space: nowrap; }

/* Zone de dépôt du nouveau devis : occupe toute la largeur du formulaire, sur sa propre ligne sous le
   libellé (pas côte à côte, l'un a besoin de place pour respirer, voir gs-dropzone). */
#doc-nouveau-devis-zone { flex-basis: 100%; }

/* Diff ancien/nouveau numéro (voir proposerNumeroDetecte dans app.js) : ancien barré en rouge atténué,
   nouveau en vert (même famille que gs-badge-confirme, cohérent avec le sens "ce qui sera retenu"),
   flèche neutre entre les deux - demande explicite de l'utilisateur, jamais juste une phrase en texte
   brut qui mélangerait les deux valeurs. */
.gs-diff-numero { display: flex; align-items: center; gap: 10px; font-family: monospace; font-size: 1.05rem; flex-wrap: wrap; }
.gs-diff-ancien { color: #b03030; text-decoration: line-through; }
.gs-diff-nouveau { color: #2e8b57; font-weight: 600; }
.gs-diff-fleche { color: #99a; }
.gs-item-devis .gs-devis-plantir { display: flex; flex-direction: column; gap: 4px; width: 100%; padding-top: 6px; border-top: 1px dashed #dde1e8; font-size: 0.85rem; color: #556; }
/* La ligne interne du plan de tir réutilise gs-devis-entete (même flex + space-between que la ligne
   du devis juste au-dessus) : demande explicite de l'utilisateur, les icônes de téléchargement/
   suppression des deux lignes doivent s'aligner verticalement, pas juste être "quelque part à droite"
   selon la longueur du texte de chaque ligne. */
.gs-item-devis .gs-devis-plantir .gs-devis-entete { font-size: inherit; color: inherit; }

/* gs-dropzone : zone d'import d'un document (pièces jointes de spectacle) — clic OU glisser-déposer,
   voir initialiserZoneDepot dans app.js. Contenu empilé en colonne (icône, texte, format accepté)
   plutôt que sur une seule ligne comme le <input type="file"> natif dans un <label> précédemment
   utilisé ici (demande explicite de l'utilisateur : le texte "Importer..." ne doit jamais se
   retrouver collé au bouton natif du navigateur). gs-dropzone-petite : variante plus compacte pour le
   plan de tir imbriqué sous un devis (espace déjà restreint dans gs-devis-plantir). */
.gs-dropzone { border: 2px dashed #c3c9d6; border-radius: 10px; padding: 1.1rem 0.8rem; text-align: center; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 3px; background: #fafbfc; transition: border-color 0.15s ease, background-color 0.15s ease; }
.gs-dropzone:hover, .gs-dropzone.gs-dropzone-survol { border-color: #6b8afd; background: #eef2ff; }
.gs-dropzone.gs-dropzone-envoi { cursor: wait; opacity: 0.7; pointer-events: none; }
.gs-dropzone-icone { font-size: 1.6rem; line-height: 1; }
.gs-dropzone-texte { font-size: 0.9rem; color: #445; }
.gs-dropzone-texte strong { color: #4a63d6; }
.gs-dropzone-format { font-size: 0.75rem; color: #99a; }
.gs-dropzone.gs-dropzone-petite { flex-direction: row; justify-content: center; padding: 0.6rem; gap: 8px; }
.gs-dropzone-petite .gs-dropzone-icone { font-size: 1.1rem; }
.gs-dropzone-petite .gs-dropzone-format { display: none; }

/* gs-item-affecte : ligne "Artificiers affectés" (onglet Affectation) — badge + boutons +
   salaire ne tiennent pas sur une seule ligne en dessous d'une certaine largeur, contrairement
   aux autres .gs-item qui n'ont qu'un badge/bouton à afficher (voir renderDetail dans app.js). */
.gs-item.gs-item-affecte { flex-wrap: wrap; }
.gs-item-affecte .gs-actions { flex-wrap: wrap; justify-content: flex-end; }
.gs-input-salaire { width: 5.5em; padding: 0.3rem 0.5rem; border: 1px solid #dde1e8; border-radius: 6px; font-size: 0.85rem; }

/* gs-item-departement : ligne "Gestion > Départements" (voir index.php) — même principe que
   gs-item-affecte ci-dessus, le nom du département et les 2 champs de saisie (lieu + mail) ne
   tiennent pas toujours sur une seule ligne sur mobile. */
.gs-item.gs-item-departement { flex-wrap: wrap; }
.gs-input-departement-cerfa { flex: 1 1 220px; min-width: 160px; padding: 0.3rem 0.5rem; border: 1px solid #dde1e8; border-radius: 6px; font-size: 0.85rem; }
/* Icône + valeur dans un même flex : la valeur (numéro/email) peut se couper (word-break) sans
   jamais isoler l'icône seule sur la ligne du dessus, contrairement à une simple césure de texte.
   Largeur d'icône fixe (voir gs-resp-icone) : le numéro ET l'email démarrent donc toujours à la
   même position horizontale, sur toutes les cartes, quelle que soit la largeur de l'icône SVG. */
.gs-resp-ligne { display: flex; align-items: flex-start; gap: 6px; }
.gs-resp-icone { flex: 0 0 14px; line-height: 1.4; }
.gs-resp-valeur { min-width: 0; word-break: break-word; }

/* Copie visuelle de l'artificier suivie du doigt pendant le glisser tactile (voir
   activerGlisserTactile dans app.js). pointer-events:none pour que le doigt "voie" les
   éléments en dessous (nécessaire à document.elementFromPoint pour détecter la zone de dépôt). */
.gs-drag-fantome { position: fixed; pointer-events: none; z-index: 1000; opacity: 0.85; box-shadow: 0 4px 12px rgba(0,0,0,0.25); }

.gs-vide { color: #99a; font-style: italic; padding: 0.5rem; font-size: 0.9rem; }

/* Carte d'une demande de devis (voir chargerListePredevis dans app.js) : date de création en
   avant, puis les points qui différencient le plus souvent plusieurs demandes d'un même spectacle
   (client, budget, calibre, date de tir) en petites pastilles — plus lisible d'un coup d'œil
   qu'une seule ligne de texte à parenthèses. Bordure gauche + chevron : même code visuel qu'un
   item cliquable ailleurs dans l'appli (couleur neutre, le doré étant réservé aux titres de
   section de formulaire et au badge de type de compte connecté). */
.gs-carte-predevis {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    background: white;
    border: 1px solid #dde1e8;
    border-left: 4px solid #778;
    border-radius: 8px;
    padding: 0.65rem 0.9rem;
    margin-bottom: 0.5rem;
    cursor: pointer;
    transition: box-shadow 0.15s, transform 0.1s;
}
.gs-carte-predevis:hover { box-shadow: 0 2px 8px rgba(0,0,0,0.12); transform: translateY(-1px); }
/* Devis actif (voir predevis_activer.php) : porté par la bordure + un léger fond, pas mélangé aux
   pastilles d'infos du devis (client/budget/calibre/date) qui restent, elles, propres au contenu
   de LA demande — vert (même famille que gs-badge-confirme) pour rester dans le même code couleur
   "état positif/courant" que le reste de l'appli. */
.gs-carte-predevis.gs-carte-predevis-active { border-left-color: #2e8b57; background: #f3faf5; }
.gs-carte-predevis-principal { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1; }
.gs-carte-predevis-date { font-weight: 700; color: #1b2340; font-size: 0.95rem; }
.gs-carte-predevis-badges { display: flex; flex-wrap: wrap; gap: 6px; }
.gs-badge-budget { background: #e2f6f1; color: #16a085; font-size: 0.78rem; font-weight: 600; padding: 0.15rem 0.6rem; border-radius: 999px; white-space: nowrap; }
.gs-carte-predevis-badges .gs-badge-meta { background: #eef1f8; color: #556; }
/* gs-carte-predevis-side : bouton "devis actif" + chevron regroupés dans un bloc de largeur fixe,
   toujours collé à droite de la carte (voir gs-carte-predevis, display:flex + justify-content:
   space-between) — sa position ne dépend donc plus du nombre de pastilles affichées à gauche. */
.gs-carte-predevis-side { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.gs-carte-predevis-chevron { color: #99a; font-size: 1.3rem; flex-shrink: 0; }
/* Bouton "devis actif" : plus visible qu'une simple icône (étoile ⭐ colorée, en plus grand, +
   texte) puisque toutes les générations de DUE/futurs documents reposeront sur cette information —
   largeur fixe pour que le texte différent ("Actif"/"Activer") ne fasse pas non plus bouger le
   chevron juste à côté. */
.gs-btn-devis-actif {
    display: flex; align-items: center; gap: 6px; justify-content: center;
    min-width: 92px; padding: 5px 12px; border: 1px solid #dde1e8; border-radius: 20px;
    background: white; color: #667; font-size: 0.82rem; font-weight: 600; cursor: pointer;
}
.gs-btn-devis-actif .gs-devis-actif-icone { font-size: 1.3rem; line-height: 1; }
.gs-btn-devis-actif.active { border-color: #e8c547; background: #fffaf0; color: #8a6d1a; }

/* Vert = confirmé, orange = en attente : même code couleur repris pour les pastilles
   de légende plus bas, afin que le sens des couleurs reste cohérent dans toute l'appli. */
.gs-badge-statut { font-size: 0.75rem; font-weight: 600; padding: 0.15rem 0.55rem; border-radius: 999px; white-space: nowrap; }
.gs-badge-confirme { background: #e6f4ea; color: #2e8b57; }
.gs-badge-attente { background: #fdf1e0; color: #b7791f; }
/* Rouge = statut CERFA "à faire" (rien envoyé) : distinct du orange "en attente" utilisé pour
   les artificiers, pour ne pas confondre les deux échelles de statut. */
.gs-badge-manque { background: #fde8e8; color: #c0392b; }
/* Statut commercial (voir STATUTS_COMMERCIAUX dans app.js) : gris = en attente de retour (neutre,
   rien à faire), bleu = devis à envoyer. Pas d'orange/jaune ici : réservé au statut "Reporté"
   (voir .gs-note-lien/.gs-badge-attente), pour ne jamais confondre les deux. Vert et rouge
   réutilisent les badges confirmé/manque existants (même sens de couleur : bon/mauvais). */
.gs-badge-gris { background: #e8eaf0; color: #556; }
.gs-badge-bleu { background: #e3f0fc; color: #2266aa; }
/* "Marché obtenu, tir non géré" : un dégradé/nuance du vert de gs-badge-confirme plutôt qu'une
   couleur sans rapport — les deux statuts partagent la même issue (marché gagné), seule la
   gestion du tir diffère ; garder la même famille de couleur rend ce lien explicite d'un coup
   d'œil, tout en restant assez distinct pour ne pas les confondre. */
.gs-badge-vert-nuance { background: #e2f6f1; color: #16a085; }

.gs-btn-icone { border: none; background: transparent; cursor: pointer; padding: 3px 6px; border-radius: 6px; font-size: 0.9rem; }
/* Bouton "Chef d'équipe"/"Devis actif" (☆/★, voir boutonChef dans app.js et la carte devis) : fond
   neutre discret quand actif pour rester repérable au milieu des autres icônes de la ligne (pas de
   doré, réservé aux formulaires/badge de compte — voir la palette par rôle). font-size fixe : ★/☆
   sont des symboles texte (pas des emoji couleur comme ⭐) qui rendent à la même taille dans une
   police donnée, mais on fixe quand même la valeur pour ne pas dépendre du contexte environnant. */
.gs-btn-chef { font-size: 1rem; line-height: 1; }
.gs-btn-chef.gs-chef-actif { background: #e8eaf0; }
.gs-btn-confirmer { border: 1px solid #2e8b57; color: #2e8b57; }
.gs-btn-retirer { color: #778; }
.gs-btn-retirer:hover { color: #c0392b; }

/* flex-wrap : 3e item ajouté (aide "cliquez sur un spectacle...") - sans ça, la légende dépassait sur
   un écran étroit au lieu de passer à la ligne (voir feedback_design_responsive). */
.gs-legende { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 8px; font-size: 0.8rem; color: #667; }
.gs-legende span { display: flex; align-items: center; gap: 5px; }

/* Espace + séparation visuelle avant "Valider le spectacle", pour ne pas le coller
   à la légende Confirmé/En attente juste au-dessus. */
#btn-valider-spectacle-global { margin-top: 1.2rem; padding-top: 1rem; border-top: 1px solid #dde1e8; width: 100%; }
.gs-pastille { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.gs-pastille-verte { background: #2e8b57; }
.gs-pastille-orange { background: #b7791f; }

/* Encadré de message (succès/erreur). La mise en forme de base (padding, coins arrondis) était
   historiquement scopée à #message-zone uniquement ; elle s'applique désormais à tout .gs-msg
   (bloc "Mon compte", section Sécurité...) — #message-zone garde sa marge basse spécifique. */
.gs-msg { padding: 0.8rem 1rem; border-radius: 8px; font-size: 0.9rem; }
#message-zone .gs-msg { margin-bottom: 0.8rem; }
.gs-msg-ok { background: #e6f4ea; color: #2e8b57; border: 1px solid #b7e0c3; }
.gs-msg-err { background: #fbe9e7; color: #c0392b; border: 1px solid #f0c2bb; }
/* Avertissement inline sous un champ (ex: couleur de secteur déjà prise, voir input-sect-couleur) :
   même code couleur que .gs-msg-err mais plus compact, pensé pour se glisser sous un seul champ
   plutôt que prendre toute la largeur d'un bandeau de message en haut de formulaire. */
.gs-avertissement-inline { display: block; font-size: 0.8rem; color: #c0392b; margin-top: -4px; }

.gs-btn { border: none; border-radius: 10px; padding: 0.6rem 1.1rem; font-size: 0.95rem; cursor: pointer; font-weight: 600; background: white; border: 1px solid #dde1e8; color: #1b2340; text-decoration: none; display: inline-block; }
.gs-btn-save { background: #e6a817; color: #1b2340; border-color: #e6a817; }
.gs-btn-retour { margin-bottom: 1rem; }
/* "Annuler" et "Enregistrer" doivent faire la même taille dans .gs-formulaire-actions,
   malgré leurs textes de longueur différente : largeur minimale commune. */
.gs-formulaire-actions .gs-btn-save,
.gs-formulaire-actions .gs-btn-retour { min-width: 140px; text-align: center; }

/* Niveaux 1 et 2 de la sidebar (voir .gs-nav-btn juste au-dessus pour le niveau 0) : chaque
   "groupe" est la liste des sous-menus d'un parent, avec un filet vertical qui les relie
   visuellement à lui (comme un arbre de dossiers) et un alinéa qui grandit avec la profondeur. */
.gs-side-groupe {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding-left: 20px;
    margin: 3px 0 3px 10px;
}
.gs-side-groupe::before {
    content: '';
    position: absolute;
    left: 0; top: 4px; bottom: 4px;
    width: 2px;
    background: rgba(255,255,255,0.16);
    border-radius: 2px;
}
.gs-sous-onglet {
    width: 100%;
    text-align: left;
    background: transparent;
    border: none;
    cursor: pointer;
    border-radius: 7px;
}
/* Niveau 1 : Gestion > Spectacles/Artificiers/Responsables, Tableau de bord > Par spectacle/Par
   artificier. Violet foncé pour l'état actif — ni bleu marine (niveau 0), ni doré (réservé aux
   titres de section de formulaire + au badge de compte connecté, voir .gs-formulaire-titre/
   .gs-badge-admin), une famille de teinte à part pour ce niveau. */
.gs-side-groupe .gs-sous-onglet {
    color: rgba(255,255,255,0.64);
    padding: 0.42rem 0.6rem;
    font-weight: 600;
    font-size: 0.76rem;
}
.gs-side-groupe .gs-sous-onglet.active { background: #4a3a7a; color: white; }

/* Niveau 2 : encore un cran plus profond, à l'intérieur de la fiche d'un spectacle précis —
   Infos spectacle/Affectation/Demande de devis (voir aussi #detail-sous-onglets, masqué par
   défaut et affiché seulement quand un spectacle est ouvert : afficherNiveau2Sidebar dans app.js).
   Même famille violette que le niveau 1 mais nettement plus claire : plus on descend dans la
   hiérarchie, plus la couleur s'éclaircit. Règles après celles du niveau 1 pour les emporter à
   spécificité égale (source order). */
/* padding-left/margin déjà hérités de .gs-side-groupe (mêmes valeurs) : comme ce groupe est lui-même
   imbriqué dans un .gs-side-groupe de niveau 1, l'indentation cumulée est déjà plus profonde sans
   rien ajouter ici. Seule la couleur du filet change, pour rester cohérente avec le violet plus
   clair du niveau 2 (voir .gs-side-groupe-niveau2 .gs-sous-onglet.active plus bas). */
.gs-side-groupe-niveau2::before { background: rgba(138,111,194,0.4); }
.gs-side-groupe-niveau2 .gs-sous-onglet {
    color: rgba(255,255,255,0.56);
    padding: 0.36rem 0.55rem;
    font-weight: 600;
    font-size: 0.7rem;
}
.gs-side-groupe-niveau2 .gs-sous-onglet.active { background: #8a6fc2; color: white; }

/* Regroupe le filtre Saison et la bascule Cartes/Liste du tableau de bord sur la même ligne :
   space-between (pas flex-end) pour les écarter aux deux extrémités — la saison mise en avant à
   gauche (axe de navigation à part entière, voir gs-filtre-saison plus bas), le réglage d'affichage
   à droite comme avant (voir index.php, gs-page-dashboard). */
.gs-dash-entete { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 1.2rem; }

/* Filtre Saison mis en avant (demande explicite de l'utilisateur), sur la même ligne que la
   bascule Cartes/Liste (.gs-toggle-btn juste au-dessus) : mêmes bordure/rayon/couleurs/typo pour
   que les deux contrôles de cette ligne forment un seul ensemble visuellement cohérent, plutôt
   qu'un select de filtre ordinaire à côté de boutons d'un style différent. Pas de couleur de rôle
   empruntée (nav/sous-onglets/entêtes ont chacune la leur, le doré est réservé aux
   formulaires/badge compte — voir la convention du projet). */
.gs-filtre-saison {
    padding: 0.5rem 0.8rem;
    border: 1px solid #dde1e8;
    border-radius: 8px;
    background: white;
    color: #1b2340;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
}

.gs-cartes-grille { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; }
/* min-width:0 : par défaut, un item de grille ne rétrécit jamais sous la largeur de son contenu
   le plus long (min-width:auto implicite) — un seul texte un peu long (lieu, nom...) suffit alors
   à forcer toute la grille à ne plus tenir qu'une seule carte par ligne. overflow-wrap en renfort
   pour qu'un mot/texte inhabituellement long se coupe plutôt que de déborder de la carte. */
.gs-carte { background: white; border-radius: 10px; padding: 1rem; box-shadow: 0 2px 8px rgba(0,0,0,0.08); border-left: 6px solid transparent; min-width: 0; overflow-wrap: anywhere; }
/* Code couleur visible dès le tableau de bord (demande explicite) : même palette que les badges
   de statut commercial (gs-badge-gris/confirme/bleu/manque), appliquée en bordure de carte pour
   être repérable même sans lire le texte. Classe posée en JS via renderDashboardSpectacles. */
.gs-carte.statut-a_envoyer { border-left-color: #2266aa; }
.gs-carte.statut-en_attente { border-left-color: #99a3b3; }
.gs-carte.statut-obtenu { border-left-color: #2e8b57; }
.gs-carte.statut-obtenu_sans_gestion { border-left-color: #16a085; }
.gs-carte.statut-perdu { border-left-color: #c0392b; }
/* Orange = spectacle reporté (une fiche séparée existe pour la nouvelle date, voir
   spectacle_reporter.php) : remplace la couleur du statut commercial une fois reporté, celui-ci
   n'étant plus la fiche de référence pour ce spectacle. */
.gs-carte.statut-reporte { border-left-color: #b7791f; }
.gs-carte .gs-titre { font-weight: 600; color: #1b2340; margin: 0 0 4px; }
.gs-carte .gs-sous-titre { font-size: 0.85rem; color: #667; margin: 0 0 8px; }
.gs-carte ul { list-style: none; margin: 0; padding: 0; }
.gs-carte li { font-size: 0.85rem; padding: 6px 0; border-top: 1px solid #dde1e8; display: flex; justify-content: space-between; align-items: center; }

.gs-entete-profil { display: flex; align-items: center; gap: 12px; margin-bottom: 1rem; }
.gs-avatar { width: 48px; height: 48px; border-radius: 50%; background: #f7d379; color: #1b2340; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 1.1rem; }
.gs-nom-profil { font-size: 1.2rem; font-weight: 600; margin: 0; color: #1b2340; }

.gs-barre-actions { display: flex; justify-content: flex-end; align-items: center; gap: 10px; margin-bottom: 0.75rem; flex-wrap: wrap; }
/* Sélecteur de compte à nommer Admin entreprise (voir Gestion > Admins) : même style que les
   selects de .gs-barre-outils, cette barre-ci n'en ayant pas encore. */
.gs-barre-actions select { padding: 0.5rem 0.8rem; border: 1px solid #dde1e8; border-radius: 8px; font-size: 0.9rem; background: white; }
.gs-formulaire { display: flex; gap: 10px; flex-wrap: wrap; background: white; border-radius: 10px; padding: 1rem; margin-bottom: 0.75rem; box-shadow: 0 2px 8px rgba(0,0,0,0.08); }
.gs-formulaire label { display: flex; flex-direction: column; font-size: 0.8rem; color: #556; gap: 4px; flex: 1; min-width: 160px; }
/* Force un champ à occuper toute la largeur du formulaire (retour à la ligne avant/après),
   utilisé pour Notes/commentaires dont le contenu peut être plus long qu'un champ classique. */
.gs-formulaire label.gs-champ-large { flex-basis: 100%; }
/* Liste de cases à cocher (ex: Responsables d'un artificier, relation plusieurs-à-plusieurs) :
   grille de petites étiquettes plutôt qu'un menu déroulant multi-sélection natif, plus pratique
   au tactile et plus lisible d'un coup d'œil sur qui est déjà coché. */
.gs-checkbox-liste { display: flex; flex-wrap: wrap; gap: 6px 14px; padding: 0.6rem 0.7rem; border: 1px solid #dde1e8; border-radius: 8px; background: white; max-height: 160px; overflow-y: auto; }
.gs-checkbox-liste label { flex-direction: row !important; align-items: center; gap: 6px; font-size: 0.85rem; color: #333; min-width: 0; flex: 0 0 auto; }
.gs-checkbox-liste input[type="checkbox"] { width: auto; }

/* Petit rond de couleur devant le nom d'un secteur (Gestion > Secteurs) : repère visuel rapide,
   même couleur que celle utilisée sur la carte pour ce secteur (sect_couleur, libre par secteur —
   n'entre pas en conflit avec la palette réservée par rôle, c'est une dimension différente). */
.gs-pastille-couleur { display: inline-block; width: 12px; height: 12px; border-radius: 50%; vertical-align: middle; margin-right: 4px; border: 1px solid rgba(0,0,0,0.15); }

/* Carte de France interactive (Gestion > Secteurs > formulaire) : le SVG injecté par app.js
   s'étire à la largeur disponible (viewBox le garde proportionné) sans jamais dépasser le
   formulaire, y compris sur mobile (design responsive obligatoire) — pas de largeur fixe. */
.gs-carte-departements { flex-basis: 100%; max-width: 100%; margin: 0.4rem 0; }
/* max-height généreux (voir demande d'agrandissement) : la largeur reste toujours contrainte par
   le formulaire (width:100%), donc pas de risque de débordement horizontal même en grand — sur un
   écran étroit c'est de toute façon la largeur qui limite d'abord, pas cette hauteur max. */
.gs-carte-departements svg { display: block; width: 100%; height: auto; max-height: min(82vh, 820px); }
/* Contour bien visible même sur un écran très lumineux (contraste insuffisant remonté par un
   utilisateur : un trait blanc de 0.5px sur fond gris très clair devient quasi invisible dès que
   la luminosité de l'écran est poussée) : gris moyen plutôt que blanc, et plus épais. Le remplissage
   par défaut est aussi légèrement plus soutenu que l'ancien #f4f5f8, trop proche du blanc du
   formulaire autour pour qu'on distingue la carte de son cadre. */
.gs-carte-departements path { cursor: pointer; fill: #e2e6ee; stroke: #8b93a8; stroke-width: 0.6; transition: fill 0.15s ease; }
.gs-carte-departements path.gs-dep-selectionne { stroke: #1b2340; stroke-width: 1.4; }
/* Carte en lecture seule (aperçu Gestion > Secteurs, voir construireCarteApercuSecteurs) : pas de
   changement de couleur au survol (induirait en erreur, rien n'est cliquable pour "sélectionner"
   comme dans le formulaire), juste un curseur pointer sur les secteurs cliquables pour voir leurs
   responsables — d'où l'exclusion explicite de cette variante ici plutôt qu'une règle générique. */
.gs-carte-departements:not(.gs-carte-lecture-seule) path:hover { fill: #c7cfdd; }
.gs-carte-departements.gs-carte-lecture-seule path.gs-dep-sans-secteur { cursor: default; }
/* Encart (Île-de-France zoomée, cartouches DOM-TOM) : cadre discret pour bien le détacher du
   fond de carte plutôt que de laisser deviner où s'arrête la métropole. */
.gs-carte-departements .gs-carte-encart-cadre { fill: none; stroke: #8b93a8; stroke-width: 0.8; stroke-dasharray: 3 2; }
.gs-carte-departements .gs-carte-encart-titre { fill: #556; font-size: 9px; }
/* Étiquettes nom + code injectées par ajouterLabelsDepartements (app.js) : pointer-events:none pour
   que le clic sur un département continue de cibler le <path> en dessous, pas le texte par-dessus.
   Halo blanc (paint-order + stroke) plutôt qu'une couleur de texte fixe : reste lisible que le
   département soit en gris par défaut, coloré (secteur choisi) ou en dégradé (partagé) — pas besoin
   de recalculer une couleur de texte contrastée à chaque recoloration. */
.gs-carte-departements .gs-dep-etiquette { pointer-events: none; }
.gs-carte-departements .gs-dep-etiquette text {
    fill: #262b38;
    font-family: inherit;
    font-weight: 600;
    paint-order: stroke;
    stroke: rgba(255,255,255,0.88);
    stroke-width: 2px;
    stroke-linejoin: round;
}
/* Liste de secours (mêmes départements, en cases à cocher) : toujours affichée sous la carte, pas
   seulement en absence de carte — reste le moyen le plus fiable sur un tout petit écran/au clavier. */
.gs-carte-departements-liste-secours { flex-basis: 100%; max-height: 220px; }

/* Aperçu Gestion > Secteurs ("page d'accueil", voir index.php).
   position:relative : sert de repère pour positionner la bulle des responsables (position:absolute,
   voir .gs-apercu-secteur-panneau) par rapport à la carte, pas par rapport à toute la page. Plus de
   flex ici (avant : carte + panneau côte à côte) : la carte seule occupe maintenant toute la largeur
   disponible, plus grande d'autant — voir la demande d'agrandissement. */
.gs-carte-secteurs-apercu { position: relative; margin-bottom: 0.75rem; }

/* Bulle flottante (voir afficherResponsablesSecteur dans app.js) : affichée seulement au clic sur un
   secteur de la carte, positionnée dynamiquement près du département cliqué plutôt qu'un panneau
   fixe à côté en permanence (souvent vide, ça grignotait de la place sur la carte pour rien).
   z-index au-dessus de la carte ; box-shadow plus prononcée qu'une carte "posée" normalement
   (.gs-carte), pour bien la détacher visuellement de ce qu'il y a en dessous. */
.gs-apercu-secteur-panneau {
    position: absolute;
    z-index: 10;
    min-width: 220px;
    max-width: 320px;
    background: white;
    border: 1px solid #dde1e8;
    border-radius: 10px;
    padding: 0.9rem 1rem;
    box-shadow: 0 10px 28px rgba(0,0,0,0.22);
}
.gs-apercu-secteur-panneau h4 { margin: 0 0 8px; color: #1b2340; display: flex; align-items: center; }
.gs-apercu-secteur-panneau ul { list-style: none; margin: 0; padding: 0; }
.gs-apercu-secteur-panneau li { font-size: 0.85rem; padding: 6px 0; border-top: 1px solid #dde1e8; }
.gs-apercu-secteur-panneau li:first-child { border-top: none; }
.gs-apercu-secteur-panneau .gs-apercu-secteur-groupe + .gs-apercu-secteur-groupe { margin-top: 10px; padding-top: 10px; border-top: 1px dashed #dde1e8; }
/* Fermeture manuelle (voir afficherResponsablesSecteur) : en plus de re-cliquer sur un autre
   département/un département sans secteur, qui ferme aussi la bulle automatiquement. */
.gs-apercu-secteur-fermer {
    position: absolute;
    top: 6px;
    right: 8px;
    background: none;
    border: none;
    font-size: 1.1rem;
    line-height: 1;
    color: #99a;
    cursor: pointer;
    padding: 2px 4px;
}
.gs-apercu-secteur-fermer:hover { color: #556; }

/* Regroupe visuellement 2 champs qui vont ensemble (ex: Nbr + Salaire net d'un même tarif, voir
   la demande de devis) : bordure + fond légèrement teinté pour bien les distinguer d'un autre
   groupe voisin, plutôt que 4 champs isolés à la suite sans lien visuel entre eux. */
.gs-sous-groupe { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; flex-basis: 100%; padding: 0.6rem 0.7rem; border: 1px solid #dde1e8; border-radius: 8px; background: #fafbfc; }
.gs-sous-groupe strong { flex-basis: 100%; font-size: 0.8rem; color: #556; }
.gs-sous-groupe label { flex: 1; min-width: 160px; }

/* Grille de champs homogènes (ex: Prestations à déduire d'une demande de devis) : contrairement à
   .gs-formulaire (flex-wrap), une grille ne fait pas grossir la dernière case isolée sur sa ligne
   pour occuper toute la largeur restante — chaque case garde la même taille, peu importe si leur
   nombre total est pair ou impair. flex-basis:100% est nécessaire ici (contrairement à un simple
   label.gs-champ-large) : sans largeur imposée, un conteneur grid se réduit à la largeur d'une
   seule colonne plutôt que de se répartir sur plusieurs comme les autres champs du formulaire. */
.gs-grille-champs { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 10px; flex-basis: 100%; }

/* Titre de section avec un champ compact intégré à droite (ex: coefficient de charges de Détails
   Artificiers, voir index.php) : le titre garde sa mise en forme habituelle (majuscules, gras),
   le champ associé reste volontairement discret (normal, plus petit, non gras) pour ne pas
   concurrencer visuellement le titre lui-même. */
.gs-titre-avec-champ { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.gs-titre-champ {
    font-weight: 400;
    font-size: 0.72rem;
    text-transform: none;
    letter-spacing: normal;
    color: #556;
    display: inline-flex;
    align-items: center;
    gap: 5px;
}
/* Spécificité .gs-formulaire .gs-titre-champ input (et pas juste .gs-titre-champ input) : sinon
   .gs-formulaire input, plus bas dans la feuille de style et de même spécificité, l'emporterait et
   redonnerait à ce champ le padding/bordure standard d'un champ de formulaire classique. */
.gs-formulaire .gs-titre-champ input {
    width: 4.4em;
    padding: 2px 4px;
    font-size: 0.8rem;
    text-align: center;
    border: 1px solid #dde1e8;
    border-radius: 4px;
    font-family: inherit;
}

/* Récapitulatif financier de la demande de devis (voir recalculerRecapPredevis dans app.js) :
   collé en haut de l'écran pendant le défilement (position:sticky), pour rester visible tout au
   long d'un formulaire aussi long — sans ça, il faudrait remonter en haut de la page pour voir les
   totaux après avoir rempli les prestations tout en bas. TTC/H.T./Pyro restant (gs-recap-principal)
   sont ce qu'on regarde en premier, donc en plus grand ; le détail du calcul (gs-recap-secondaire)
   reste visible juste en dessous mais en plus discret. Vert foncé "argent" : couleur dédiée à ce
   panneau, indépendante du reste de la palette de rôles (nav/sous-onglets/entêtes/tableaux), sans
   lien avec le vert plus clair utilisé pour le statut "confirmé" ailleurs dans l'app. */
.gs-recap-predevis {
    position: sticky;
    top: 8px;
    z-index: 20;
    flex-basis: 100%;
    display: flex;
    flex-direction: column;
    gap: 6px;
    background: #1e4a3a;
    color: white;
    border-radius: 10px;
    padding: 0.7rem 1rem;
    margin-bottom: 4px;
    box-shadow: 0 4px 14px rgba(0,0,0,0.25);
}
.gs-recap-principal { display: flex; flex-wrap: wrap; gap: 4px 28px; }
.gs-recap-principal .gs-recap-ligne strong { font-size: 1.3rem; }
.gs-recap-secondaire {
    display: flex;
    flex-wrap: wrap;
    gap: 2px 20px;
    padding-top: 6px;
    border-top: 1px solid rgba(255,255,255,0.18);
    opacity: 0.8;
}
.gs-recap-secondaire .gs-recap-ligne strong { font-size: 0.8rem; }
.gs-recap-ligne { display: flex; flex-direction: column; font-size: 0.72rem; line-height: 1.3; }
.gs-recap-ligne span { opacity: 0.7; white-space: nowrap; }
.gs-recap-ligne strong { font-size: 0.95rem; white-space: nowrap; }
.gs-recap-final strong { color: #f7d379; font-size: 1.4rem; }

/* Montant calculé en direct affiché sous un % (Commission Apporteur/Commercial) : discret, juste
   au-dessus de la valeur de référence dans le récapitulatif du dessus, pas besoin d'aller le
   chercher ailleurs pour savoir combien représente le % qu'on vient de taper. */
.gs-montant-calcule { font-size: 0.75rem; color: #667; min-height: 1.1em; }
.gs-formulaire input,
.gs-formulaire select,
.gs-formulaire textarea { padding: 0.5rem 0.7rem; border: 1px solid #dde1e8; border-radius: 8px; font-size: 0.9rem; font-family: inherit; }
.gs-formulaire-actions { width: 100%; display: flex; gap: 8px; margin-top: 4px; }
/* Sous-titre de groupe dans un formulaire long (ex: "Identité", "Coordonnées", "Contact
   organisateur"...) : prend toute la largeur pour forcer un retour à la ligne avant le groupe
   suivant, avec un fond + bordure gauche colorée pour bien le distinguer des champs (plus qu'un
   simple texte en gras) — repère visuel rapide dans un long formulaire à plusieurs sections. */
.gs-formulaire-titre {
    width: 100%;
    font-weight: 700;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #1b2340;
    background: #eef1f8;
    border-left: 4px solid #e6a817;
    border-radius: 6px;
    padding: 0.5rem 0.7rem;
    margin-top: 14px;
}
.gs-formulaire-titre:first-of-type { margin-top: 0; }
/* Hors d'un .gs-formulaire (ex: onglet Affectation, voir index.php), le titre n'a pas le gap:10px
   qui espace normalement ses frères dans un formulaire — sans cette marge, le contenu juste en
   dessous (barre d'outils, liste...) touchait directement le titre. */
.gs-colonne > .gs-formulaire-titre,
.gs-due-verrouilles > .gs-formulaire-titre,
.gs-doc-chef > .gs-formulaire-titre { margin-bottom: 10px; }

/* Regroupe un champ et sa note associée (ex: statut d'un fichier envoyé) dans un même bloc plutôt
   que de les laisser comme deux enfants indépendants d'un .gs-formulaire flex-wrap : sans ce
   regroupement, le wrap du navigateur pouvait les séparer (une note affichée à côté d'un AUTRE champ
   que le sien). Voir feedback_disposition_fixe_vignettes : même principe, empilement fixe plutôt
   qu'un wrap laissé au navigateur. */
.gs-formulaire .gs-champ-groupe { flex-basis: 100%; display: flex; flex-direction: column; gap: 4px; }
.gs-formulaire .gs-champ-groupe .gs-note { margin: 0; }

/* Batteries de mortier de la société (Gestion > Matériel entreprise, déplacé depuis Entreprise ; voir
   project_materiel_plan_tir Refonte 2 et project_suivi_materiel_tir) : petit tableau éditable —
   liste des châssis (tubes / diamètre / droite ou éventaillée) + ligne d'ajout en pied de tableau.
   Reprend le code couleur du récap matériel (bleu = droite, violet = EV) pour que l'utilisateur
   fasse le lien avec les colonnes de l'onglet Matériel. */
#form-batteries-entreprise { flex-direction: column; align-items: stretch; }
.gs-batt-wrap { overflow-x: auto; width: 100%; }
.gs-batt-tableau { border-collapse: collapse; width: 100%; font-size: 0.9rem; min-width: 26rem; }
.gs-batt-tableau th, .gs-batt-tableau td { border: 1px solid #e3e6ee; padding: 0.4rem 0.6rem; text-align: left; vertical-align: middle; }
.gs-batt-tableau thead th { background: #2a3355; color: #fff; font-weight: 600; white-space: nowrap; }
/* En-tête déjà foncé : le hover générique .gs-th-tri:hover (fond #2a3355, pensé pour des en-têtes
   clairs) ne se verrait pas ici. On éclaircit à la place, et on force la flèche de tri en blanc
   (sinon elle hérite d'un gris trop peu contrasté sur ce fond sombre). */
.gs-batt-tableau thead .gs-th-tri:hover { background: #3a4570; }
.gs-batt-tableau thead .gs-fleche-tri { color: #fff; opacity: 0.85; }
.gs-batt-tableau td:first-child, .gs-batt-tableau th:first-child,
.gs-batt-tableau td:nth-child(2), .gs-batt-tableau th:nth-child(2) { white-space: nowrap; font-variant-numeric: tabular-nums; }
.gs-batt-tableau td:last-child { text-align: right; width: 1%; white-space: nowrap; }
/* Pastille de type : mêmes teintes que .type-droit / .type-ev du récap matériel. */
.gs-batt-type { display: inline-block; font-size: 0.72rem; font-weight: 600; padding: 0.1rem 0.5rem; border-radius: 999px; }
.gs-batt-type-droit { background: #e8f0f8; color: #3b6ea5; }
.gs-batt-type-ev { background: #f1e9fa; color: #8a5cc4; }
.gs-batt-repr { font-size: 0.78rem; color: #556; font-variant-numeric: tabular-nums; margin-left: 0.35rem; }
/* Ligne d'ajout en <tfoot> : fond légèrement teinté pour la distinguer des lignes de données. */
.gs-batt-ajout td { background: #f7f8fc; }
.gs-batt-ajout input { width: 4.5rem; padding: 0.35rem 0.5rem; border: 1px solid #dde1e8; border-radius: 6px; font: inherit; }
.gs-batt-ajout select { padding: 0.35rem 0.5rem; border: 1px solid #dde1e8; border-radius: 6px; font: inherit; }
/* Bouton compact (Retirer dans une ligne de tableau) : plus petit que le .gs-btn standard. */
.gs-btn-compact { padding: 0.25rem 0.6rem; font-size: 0.8rem; }

/* Matériel de tir attribué par secteur (Gestion > Matériel entreprise, voir project_suivi_materiel_tir) :
   une ligne par secteur, une cellule éditable (input number) par produit. Chaque cellule s'enregistre
   au blur / au clic sur les flèches. La couleur du secteur (sa seule identité, pas de nom propre)
   sert de pastille, jamais de fond de ligne (lisibilité). */
#form-materiel-entreprise { flex-direction: column; align-items: stretch; }
.gs-matent-wrap { overflow-x: auto; width: 100%; }
.gs-matent-tableau { border-collapse: collapse; width: 100%; font-size: 0.9rem; min-width: 30rem; }
.gs-matent-tableau th, .gs-matent-tableau td { border: 1px solid #e3e6ee; padding: 0.4rem 0.6rem; vertical-align: middle; }
.gs-matent-tableau thead th { background: #2a3355; color: #fff; font-weight: 600; white-space: nowrap; text-align: left; }
.gs-matent-tableau thead th:not(:first-child) { text-align: center; }
/* Cellule "Secteur" : pastille de couleur + départements, sur une seule ligne. */
.gs-matent-secteur { white-space: nowrap; }
.gs-matent-pastille { display: inline-block; width: 0.85rem; height: 0.85rem; border-radius: 3px; margin-right: 0.5rem; vertical-align: -1px; border: 1px solid rgba(0,0,0,.15); }
/* Cellule éditable : input + "(x dispo)" en dessous, centrés. */
.gs-matent-cell { text-align: center; white-space: nowrap; }
.gs-matent-input { width: 4rem; padding: 0.35rem 0.4rem; border: 1px solid #dde1e8; border-radius: 6px; font: inherit; text-align: center; font-variant-numeric: tabular-nums; }
.gs-matent-input:focus { outline: 2px solid #3b6ea5; outline-offset: 1px; }
.gs-matent-dispo { display: block; font-size: 0.72rem; color: #99a; margin-top: 2px; min-height: 0.9rem; }

/* Prêts de matériel de tir aux artificiers (Gestion > Prêts matériel, voir project_suivi_materiel_tir) :
   un <details> par secteur, chacun avec la synthèse du stock, un formulaire "Sortir du matériel",
   le tableau des prêts en cours et un <details> "Historique" imbriqué. Palette bleu-gris de la
   gestion (pas de doré, réservé aux formulaires/badge compte) ; la couleur du secteur ne sert que
   de pastille. Bouton neutre = petit bouton d'action secondaire (Modifier / Annuler). */
/* overflow:hidden en garde-fou : si un enfant (le tableau des prêts, notamment) calcule une largeur
   intrinsèque supérieure à la sienne malgré le overflow-x:auto de .gs-pret-wrap (constaté : un
   tableau HTML ne se comprime jamais sous la largeur minimale de son contenu, "width:100%" n'étant
   qu'un plancher), ce débordement est clippé ici plutôt que de déborder visuellement du bloc. */
.gs-pret-secteur { border: 1px solid #dde1e8; border-radius: 8px; margin-bottom: 0.8rem; background: #fafbfc; overflow: hidden; }
.gs-pret-secteur > summary { cursor: pointer; font-weight: 600; color: #1b2340; padding: 0.7rem 0.9rem; list-style-position: inside; }
.gs-pret-secteur[open] > summary { border-bottom: 1px solid #e3e6ee; margin-bottom: 0.6rem; }
.gs-pret-secteur > *:not(summary) { margin-left: 0.9rem; margin-right: 0.9rem; }
.gs-pret-secteur > *:last-child { margin-bottom: 0.9rem; }
.gs-pret-pastille { display: inline-block; width: 0.8rem; height: 0.8rem; border-radius: 3px; margin-right: 0.5rem; vertical-align: -1px; border: 1px solid rgba(0,0,0,.15); }

/* Synthèse du stock : une "carte" par produit. */
.gs-pret-stock { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-bottom: 0.9rem; }
.gs-pret-stock-item { display: flex; flex-direction: column; gap: 2px; background: #eef2f8; border: 1px solid #dbe4f0; border-radius: 6px; padding: 0.35rem 0.6rem; font-size: 0.85rem; }
.gs-pret-stock-item strong { color: #2a3355; }
.gs-pret-stock-chiffres { font-variant-numeric: tabular-nums; color: #1b2340; }
.gs-pret-stock-detail { color: #8a93a8; font-size: 0.78rem; }

/* Formulaire "Sortir du matériel" : grille responsive de champs. */
.gs-pret-form { background: #fff; border: 1px solid #e3e6ee; border-radius: 8px; padding: 0.8rem; margin-bottom: 0.9rem; }
.gs-pret-form-titre { font-weight: 600; color: #1b2340; margin-bottom: 0.6rem; }
/* align-items:end : chaque colonne peut avoir un libellé d'1 ou 2 lignes, mais on aligne les
   champs par le BAS -> tous les inputs restent sur la même ligne de base (le libellé "pousse" vers
   le haut). Sans ça, une colonne dont le libellé passe sur 2 lignes décale son input vers le bas. */
.gs-pret-form-grille { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: 0.7rem; margin-bottom: 0.7rem; align-items: end; }
.gs-pret-form-grille label { display: flex; flex-direction: column; gap: 3px; font-size: 0.85rem; color: #556; }
/* Le libellé occupe une hauteur fixe (2 lignes) pour que "(facultatif)" ne fasse pas grandir la
   case : il tient sur la 2e ligne réservée, jamais au prix d'un décalage vertical. */
.gs-pret-form-grille label > .gs-pret-libelle { min-height: 2.2em; display: block; line-height: 1.15; }
.gs-pret-form-grille input, .gs-pret-form-grille select { padding: 0.4rem 0.5rem; border: 1px solid #dde1e8; border-radius: 6px; font: inherit; }
.gs-pret-facultatif { color: #99a; font-weight: 400; font-size: 0.78rem; }

.gs-pret-encours-titre { font-weight: 600; color: #1b2340; margin: 0.4rem 0 0.5rem; }
.gs-pret-vide { margin: 0.2rem 0 0.6rem; }
/* min-width assez large pour que la colonne d'actions (Retour / Modifier / Supprimer) tienne
   entière : sur un écran plus étroit, c'est .gs-pret-wrap qui défile horizontalement, jamais les
   boutons qui débordent de leur cellule. */
/* max-width:100% (en plus de width:100%) : un tableau HTML ne se comprime jamais sous la largeur
   minimale exigée par son contenu (ici la colonne actions, 3 boutons non compressibles) - sans ce
   verrou, ce dépassement fuyait de quelques pixels hors de .gs-pret-wrap malgré overflow-x:auto. */
.gs-pret-wrap { overflow-x: auto; width: 100%; margin-bottom: 0.6rem; }
.gs-pret-tableau { border-collapse: collapse; width: 100%; max-width: 100%; font-size: 0.88rem; min-width: 48rem; table-layout: auto; }
.gs-pret-tableau th, .gs-pret-tableau td { border: 1px solid #e3e6ee; padding: 0.4rem 0.55rem; text-align: left; vertical-align: middle; }
.gs-pret-tableau thead th { background: #2a3355; color: #fff; font-weight: 600; white-space: nowrap; }
.gs-pret-tableau td:nth-child(3) { font-variant-numeric: tabular-nums; text-align: center; }
.gs-pret-tiret { color: #b9bfce; }
/* Colonne d'actions : largeur réservée pour que les 3 boutons (Retour / Modifier / Supprimer)
   tiennent sur une seule ligne. min-width + white-space:nowrap sur la cellule empêchent les autres
   colonnes de la comprimer ; le min-width:48rem du tableau + .gs-pret-wrap (overflow-x) gèrent le
   cas où l'écran est trop étroit — les boutons ne débordent jamais de la bordure. */
.gs-pret-actions { min-width: 15rem; white-space: nowrap; text-align: right; }
.gs-pret-actions-inner { display: inline-flex; flex-wrap: nowrap; gap: 0.3rem; }
.gs-pret-actions-inner .gs-btn-compact { padding: 0.25rem 0.55rem; white-space: nowrap; }
.gs-pret-edit-row td { background: #fffdf3; }

/* Historique replié (prêts rendus) : plus discret que les prêts en cours. */
.gs-pret-histo { margin-top: 0.4rem; }
.gs-pret-histo > summary { cursor: pointer; font-size: 0.85rem; color: #556; }
.gs-pret-tableau-histo thead th { background: #6b7488; }
.gs-pret-tableau-histo { min-width: 44rem; }

/* Bouton d'action secondaire (Modifier "✏", Annuler) : neutre, ni doré ni rouge. */
.gs-btn-neutre { background: #eef1f6; color: #3a4360; border-color: #dde1e8; }
.gs-btn-neutre:hover { background: #e2e6ef; }
.gs-erreur { color: #c0392b; }

/* Config CERFA par société (Gestion > Entreprise, voir project_multi_entreprise Phase 4) : une
   section <details> par groupe de champs, repliée par défaut — ~35 champs d'un coup serait illisible,
   chaque société ne déplie que ce qui la concerne. */
/* width:100% sur #cerfa-sections lui-même (pas seulement sur .gs-cerfa-section) : simple enfant
   d'un .gs-formulaire flex-wrap, sans largeur explicite il se réduit à la largeur de son contenu
   (shrink-to-fit) au lieu de réclamer toute la ligne — la grille de champs plus bas se retrouvait
   alors à toujours calculer 1 seule colonne disponible, même sur un écran large. */
#cerfa-sections { width: 100%; }
.gs-cerfa-section { width: 100%; border: 1px solid #dde1e8; border-radius: 8px; margin-bottom: 8px; padding: 0.6rem 0.8rem; background: #fafbfc; }
.gs-cerfa-section summary { cursor: pointer; font-weight: 600; color: #1b2340; }
.gs-cerfa-section[open] summary { margin-bottom: 10px; }
/* Grille (pas flex-wrap) : avec des libellés de longueurs très différentes (certains tiennent sur
   une ligne, d'autres passent sur deux), un flex-wrap laisse le navigateur décider où revenir à la
   ligne selon la largeur disponible — deux champs voisins se retrouvaient avec des hauteurs de case
   différentes selon que leur libellé avait ou non débordé sur 2 lignes (voir aussi
   feedback_disposition_fixe_vignettes : même principe, ne jamais laisser le wrap du navigateur fixer
   une disposition censée rester régulière). Une grille CSS donne à chaque rangée une hauteur commune,
   partagée par toutes les cases de cette rangée quelle que soit la longueur de leur libellé. */
.gs-cerfa-champs { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; align-items: stretch; }
.gs-cerfa-champs label { display: flex; flex-direction: column; font-size: 0.8rem; color: #556; gap: 4px; }
/* Hauteur de rangée harmonisée en JavaScript, pas en CSS pur (voir harmoniserHauteursLibellesCerfa
   dans app.js) : un min-height calculé en CSS (rem, line-height) donnait un résultat visiblement
   différent d'un moteur de rendu à l'autre (constaté par l'utilisateur, invisible dans les mesures
   prises avec un seul navigateur de test) — mesurer la vraie hauteur rendue et l'appliquer en pixels
   réels est fiable quel que soit le navigateur, puisque basé sur ce que CE navigateur a lui-même
   affiché. Le libellé reste un <span> dédié (gs-cerfa-libelle), jamais un texte flottant directement
   dans le <label> : plus simple à cibler/mesurer précisément en JS. */
.gs-cerfa-libelle { display: block; line-height: 1.3; }
.gs-cerfa-champs input[type="text"],
.gs-cerfa-champs input[type="date"],
.gs-cerfa-champs textarea { padding: 0.5rem 0.7rem; border: 1px solid #dde1e8; border-radius: 8px; font-size: 0.9rem; font-family: inherit; resize: vertical; }
/* Pousse la case tout en bas du libellé (margin-top: auto) : la partie libellé peut occuper 1 ou 2
   lignes selon sa longueur, mais la case elle-même reste toujours alignée sur la même position
   verticale d'un champ à l'autre au sein d'une même rangée. */
.gs-cerfa-champs label input[type="text"],
.gs-cerfa-champs label input[type="date"],
.gs-cerfa-champs label textarea { margin-top: auto; }
.gs-cerfa-champs label.gs-cerfa-champ-large { grid-column: 1 / -1; }
.gs-cerfa-champs label.gs-cerfa-case { grid-column: 1 / -1; flex-direction: row; align-items: center; gap: 6px; }
.gs-cerfa-champs label.gs-cerfa-case input[type="checkbox"] { width: auto; margin-top: 0; }

/* Liste de suggestions (champ Lieu, Adresse...) : positionnée sous le champ (position:relative
   posé sur le label parent, .gs-champ-autocomplete), au-dessus du reste du formulaire (z-index).
   display:block explicite : ce label n'est pas toujours dans un conteneur flex (ex: "Mon profil"
   artificier, formulaire simple sans classe gs-formulaire), un label inline positionnerait mal
   la liste en dessous. */
.gs-champ-autocomplete { position: relative; display: block; }
.gs-suggestions {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 20;
    margin: 2px 0 0;
    padding: 0;
    list-style: none;
    background: white;
    border: 1px solid #dde1e8;
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.12);
    max-height: 220px;
    overflow-y: auto;
}
.gs-suggestions li { padding: 0.5rem 0.7rem; font-size: 0.85rem; cursor: pointer; }
.gs-suggestions li:hover, .gs-suggestions li.gs-suggestion-active { background: #fff8ea; }

/* Liste de contacts organisateurs (0 à N par spectacle), générée dynamiquement par app.js.
   Chaque ligne regroupe 4 champs + un bouton pour la retirer. */
.gs-contacts-liste { width: 100%; display: flex; flex-direction: column; gap: 8px; }
.gs-contact-ligne { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.gs-contact-ligne input { flex: 1; min-width: 140px; padding: 0.5rem 0.7rem; border: 1px solid #dde1e8; border-radius: 8px; font-size: 0.9rem; }
.gs-contact-ligne select { flex: 0 0 auto; padding: 0.5rem 0.7rem; border: 1px solid #dde1e8; border-radius: 8px; font-size: 0.9rem; background: white; }

/* Toast : affiché brièvement par afficherToast() dans app.js (display:none par défaut, basculé en
   'flex' puis remis à 'none' après un délai via setTimeout — voir gs-duree-toast). position:fixed
   (plutôt qu'un bloc dans le flux, comme avant) : après l'enregistrement d'un formulaire long (ex:
   secteur avec la carte), la page revient en haut sur la liste, souvent hors du champ de vision de
   qui vient de cliquer "Enregistrer" tout en bas — fixe au centre de l'écran, cette confirmation
   reste visible quelle que soit la position de défilement au moment où le formulaire s'est fermé. */
.gs-toast {
    position: fixed;
    top: 18px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 200;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0.85rem 1.4rem;
    border-radius: 10px;
    font-size: 0.95rem;
    font-weight: 600;
    background: #2e8b57;
    color: white;
    box-shadow: 0 6px 20px rgba(0,0,0,0.2);
}
/* Variante erreur (voir afficherToast(texte, toastId, 'erreur') dans app.js) : même mécanisme que
   la confirmation de sauvegarde ci-dessus (position fixe, toujours visible), juste en rouge avec
   ⚠️ à la place de ✓ — pour qu'un blocage (ex: couleur de secteur déjà prise) s'affiche exactement
   comme une confirmation d'enregistrement plutôt que dans un bandeau différent selon les pages. */
.gs-toast-erreur { background: #c0392b; }
.gs-note { font-size: 0.9rem; color: #556; background: #f4f5f8; padding: 0.8rem 1rem; border-radius: 8px; margin-bottom: 1rem; }
/* Nom de spectacle cliquable (tableau de bord artificier, voir ouvrirMonSpectacleDetail dans
   app-artificier.js) : souligné au survol seulement (pas en permanence, resterait sinon un texte
   normal parmi d'autres au premier coup d'œil) pour signaler que c'est un vrai repère cliquable. */
.gs-lien-spectacle { cursor: pointer; }
.gs-lien-spectacle:hover { text-decoration: underline; }
/* Variante cliquable (voir detail-report-info dans index.php) : lien vers la fiche liée par un
   report, teintée orange comme le badge/bordure "Reporté" pour rester cohérent visuellement. */
.gs-note-lien { background: #fdf1e0; color: #b7791f; font-weight: 600; cursor: pointer; }
.gs-note-lien:hover { background: #fbe6c8; }
/* Variante "fiche active" (fin d'une chaîne de reports, voir estFicheActive dans app.js) : vert
   plutôt qu'orange, pour se distinguer clairement de gs-note-lien et signaler "vous êtes arrivé
   à la bonne fiche", pas juste "il y a un lien à suivre". */
.gs-note-actif { background: #e6f4ea; color: #2e8b57; font-weight: 600; cursor: pointer; }
.gs-note-actif:hover { background: #d5edda; }

/* Fenêtre superposée (report d'un spectacle) : couvre tout l'écran, indépendante du défilement
   de la page derrière, pour rester visible immédiatement quel que soit l'endroit où on se trouve
   dans un formulaire par ailleurs assez long (voir modal-report dans index.php). */
.gs-modal-fond {
    position: fixed;
    inset: 0;
    background: rgba(27, 35, 64, 0.55);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 500;
    padding: 1rem;
}
.gs-modal-boite {
    background: white;
    border-radius: 12px;
    padding: 1.5rem;
    width: 100%;
    max-width: 360px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}
.gs-modal-boite h3 { margin: 0 0 1rem; color: #1b2340; }
.gs-modal-boite label { display: flex; flex-direction: column; gap: 4px; font-size: 0.85rem; color: #556; margin-bottom: 1.2rem; }
.gs-modal-boite input { padding: 0.5rem 0.7rem; border: 1px solid #dde1e8; border-radius: 8px; font-size: 0.9rem; }
.gs-modal-boite .gs-formulaire-actions { margin: 0; }
/* Empilés verticalement plutôt que côte à côte (voir modal-quitter-non-enregistre dans index.php) :
   3 boutons aux libellés plus longs que les 2 habituels de gs-modal-confirm (Enregistrer et
   quitter/Quitter sans enregistrer/Rester sur cette page) ne tiennent pas proprement sur une seule
   ligne dans gs-modal-boite (max-width 360px), y compris en desktop — un empilement reste lisible
   à n'importe quelle largeur d'écran plutôt que de retomber sur un retour à la ligne au milieu
   d'un libellé. -->
/* Ciblage direct par id + !important : la règle de classe seule (gs-modal-actions-empilees) ne se
   reflétait pas à l'affichage chez l'utilisateur malgré un fichier confirmé à jour côté serveur (ni
   cache navigateur ni opcache en cause, écartés l'un et l'autre) — cette version ne laisse aucune
   place à un conflit de priorité avec une autre règle. */
#modal-quitter-non-enregistre .gs-formulaire-actions {
    flex-direction: column !important;
}
#modal-quitter-non-enregistre .gs-formulaire-actions .gs-btn {
    width: 100% !important;
    min-width: 0 !important;
    text-align: center !important;
}

/* Fenêtre de confirmation générique (voir modal-confirm dans index.php + confirmerAction dans
   app.js) : bande de couleur à gauche selon la gravité, mêmes teintes que gs-badge-manque
   (rouge, suppression/retrait définitif) et gs-badge-attente (ambre, simple écrasement d'une
   valeur) ailleurs dans l'app — jamais le doré, réservé aux titres de formulaire/badge de compte. */
.gs-modal-confirm { border-left: 5px solid transparent; }
.gs-modal-confirm-danger { border-left-color: #c0392b; }
.gs-modal-confirm-warn { border-left-color: #b7791f; }
#modal-confirm-message { white-space: pre-line; font-size: 0.92rem; color: #445; line-height: 1.5; }
.gs-btn-danger { background: #c0392b; color: white; border-color: #c0392b; }
.gs-btn-danger:hover { background: #a5311f; border-color: #a5311f; }
.gs-btn-warn { background: #b7791f; color: white; border-color: #b7791f; }
.gs-btn-warn:hover { background: #99640f; border-color: #99640f; }

/* ============================================
   Layout général (application autonome)
   ============================================ */

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
    background: #f4f5f8;
    color: #232838;
}

.gs-header {
    background: #1b2340;
    color: white;
    padding: 1.2rem 2rem;
    display: flex;
    align-items: center;
    /* flex-wrap : filet de sécurité sur très petit écran, si jamais ☰ + titre + compte ne tenaient
       vraiment plus sur une seule ligne malgré les allègements ci-dessous (voir @media) — le compte
       passe alors proprement sur une 2e ligne plutôt que de déborder hors de l'écran. */
    flex-wrap: wrap;
    row-gap: 0.5rem;
    /* Même couleur que la sidebar juste en dessous (voir .gs-sidebar) : sans ce filet, les deux se
       fondraient en un seul bloc marine sans repère visuel entre "bandeau titre" et "menu". */
    border-bottom: 1px solid rgba(255,255,255,0.12);
}
/* margin-right:auto absorbe tout l'espace restant : pousse gs-header-right à l'extrémité droite du
   bandeau, tout en gardant le titre collé au bouton ☰ (admin/responsable) juste avant lui quand il
   est présent — plus fiable que justify-content:space-between, qui aurait au contraire écarté les
   3 éléments les uns des autres au lieu de regrouper ☰+titre ensemble. */
.gs-header h1 { margin: 0 auto 0 0; font-size: 1.4rem; }
.gs-header-right { display: flex; align-items: center; gap: 14px; }
.gs-badge-admin { background: #e6a817; color: #1b2340; font-weight: 600; padding: 0.2rem 0.7rem; border-radius: 999px; font-size: 0.8rem; }
/* Distinct du doré de gs-badge-admin (réservé aux badges de rôle/formulaires, voir la convention
   de palette du projet) : rappel neutre de la société actuellement gérée par un super-admin, pas
   un badge de rôle. */
.gs-badge-entreprise-geree { background: rgba(255,255,255,0.12); color: white; font-weight: 600; padding: 0.2rem 0.7rem; border-radius: 999px; font-size: 0.8rem; }
.gs-logout { color: white; text-decoration: none; font-size: 0.9rem; border: 1px solid rgba(255,255,255,0.4); padding: 0.4rem 0.9rem; border-radius: 8px; }
.gs-logout:hover { background: rgba(255,255,255,0.1); }
/* Lien de gestion de compte : même forme de "pilule" que gs-logout (pour rester lisible comme
   bouton, pas comme un lien de texte perdu), mais sans bordure pleine ni fond plein au repos —
   volontairement plus discret pour bien le distinguer de la nav principale et de la déconnexion. */
.gs-lien-compte { display: inline-flex; align-items: center; gap: 6px; color: rgba(255,255,255,0.8); text-decoration: none; font-size: 0.9rem; padding: 0.4rem 0.8rem; border-radius: 8px; transition: background 0.15s, color 0.15s; }
.gs-lien-compte:hover { background: rgba(255,255,255,0.1); color: white; }
/* Réinitialise les styles par défaut d'un <button> (bordure, fond, police) quand gs-lien-compte
   est posé dessus plutôt que sur un <a> (voir btn-quitter-entreprise) : sans ça il resterait rendu
   comme un bouton natif du navigateur, pas comme un lien discret. */
button.gs-lien-compte { border: none; background: none; font: inherit; cursor: pointer; }
/* Sur petit écran, le bandeau doit faire tenir ☰ + titre + badge + Mon profil + Déconnexion sur une
   largeur bien plus réduite : padding/police allégés, texte "Mon profil" masqué (l'icône suffit à
   le repérer) pour gagner la place la plus utile en premier. */
@media (max-width: 600px) {
    .gs-header { padding: 0.8rem 1rem; }
    .gs-header h1 { font-size: 1.1rem; }
    .gs-header-right { gap: 8px; }
    .gs-texte-mon-profil { display: none; }
}

/* Contenu applicatif (admin/responsable ET artificier partagent ce même conteneur, un seul des
   deux existe réellement dans la page à la fois). Espace artificier : #gs-main est un bloc normal
   sous le bandeau, ce centrage par marges automatiques est fiable et suffit. Admin/responsable :
   #gs-main est un item flexible de .gs-colonne-app (voir index.php) — laissé volontairement SANS
   centrage ci-dessous (voir la règle .gs-colonne-app #gs-main juste après), qui prend le dessus
   pour ce cas précis. C'est #gs-app à l'intérieur (bloc normal, pas un item flexible) qui fait le
   vrai travail de largeur standard + centrage, de façon fiable quel que soit le contenu. */
#gs-main { max-width: 1200px; margin: 0 auto; padding: 1.5rem; }
/* Admin/responsable : remplit toujours toute la largeur laissée par la sidebar (pas de centrage
   ici, voir plus haut) — sans ça, en tant qu'item flexible avec des marges automatiques, #gs-main
   rétrécissait à la taille de son contenu au lieu de viser une largeur fixe, d'où une largeur de
   page différente sur chaque écran (bug identifié via les outils de développement). */
.gs-colonne-app #gs-main { width: 100%; max-width: none; margin: 0; }

/* Page "Mon profil" (responsable) : même largeur standard que le reste de l'appli (#gs-app), pas
   de conteneur étroit à part — naviguer d'une page à l'autre ne doit jamais changer la largeur
   visible à l'écran. Le titre reste centré, seule différence assumée avec les autres pages. */
.gs-compte-page h2 { text-align: center; }

/* ============================================
   Page de connexion
   ============================================ */

.gs-login-body {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    background: #1b2340;
    margin: 0;
    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
}
.gs-login-box {
    background: white;
    border-radius: 14px;
    padding: 2.5rem;
    width: 100%;
    max-width: 380px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.3);
}
.gs-login-box h1 { text-align: center; margin-top: 0; font-size: 1.3rem; color: #1b2340; }
.gs-login-box label { display: block; font-size: 0.85rem; color: #556; margin-bottom: 4px; }
.gs-login-box input {
    width: 100%;
    padding: 0.6rem 0.8rem;
    border: 1px solid #dde1e8;
    border-radius: 8px;
    font-size: 0.95rem;
    margin-top: 4px;
}

.gs-formulaire-vertical { display: flex; flex-direction: column; gap: 10px; }
.gs-formulaire-vertical label { display: flex; flex-direction: column; font-size: 0.8rem; color: #556; gap: 4px; }
.gs-formulaire-vertical input,
.gs-formulaire-vertical select { padding: 0.5rem 0.7rem; border: 1px solid #dde1e8; border-radius: 8px; font-size: 0.9rem; }
.gs-formulaire-vertical .gs-formulaire-actions { display: flex; gap: 8px; margin-top: 8px; }

/* ============================================
   Section "Mon compte" (index.php > gs-page-monprofil) — commune super-admin / admin entreprise /
   responsable. Page interne classique de la SPA : la mise en forme vient de .gs-formulaire /
   .gs-formulaire-titre communes ; on grise juste un peu les champs en lecture seule.
   ============================================ */
#gs-page-monprofil .gs-formulaire input:disabled { background: #f4f5f8; color: #556; cursor: not-allowed; }

/* Bloc "Changer mon mot de passe" partagé (gs_mot_de_passe.js) : section Sécurité de "Mon compte"
   (gs-page-monprofil) et bloc "Mon compte" du tableau de bord artificier. REPLIÉ par défaut
   (bouton seul, #gs-mdp-replie), les champs (#gs-mdp-deplie) n'apparaissent qu'au clic. L'attribut
   HTML `hidden` gère l'affichage — on neutralise juste un éventuel display:flex hérité. */
.gs-mdp-bloc { display: flex; flex-direction: column; gap: 10px; }
.gs-mdp-bloc [hidden] { display: none !important; }
.gs-mdp-bloc #gs-mdp-deplie { display: flex; flex-direction: column; gap: 10px; }
.gs-mdp-bloc .gs-formulaire-actions { margin-top: 4px; }

/* Message de succès à ACQUITTER : reste affiché (pas de disparition automatique) avec un bouton OK,
   contrairement au toast global. Le texte et le bouton sur la même ligne, bouton aligné à droite. */
.gs-msg-acquit { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.gs-btn-acquit { flex: none; padding: 0.35rem 0.9rem; font-size: 0.85rem; background: #2e8b57; color: #fff; border-color: #2e8b57; }

/* ============================================
   Barres d'outils (recherche + tri) et en-têtes de colonnes triables
   ============================================ */

.gs-barre-outils {
    display: flex;
    gap: 10px;
    margin-bottom: 1rem;
    flex-wrap: wrap;
}
.gs-barre-outils input[type="text"] {
    flex: 1;
    min-width: 200px;
    padding: 0.5rem 0.8rem;
    border: 1px solid #dde1e8;
    border-radius: 8px;
    font-size: 0.9rem;
}
.gs-barre-outils select {
    padding: 0.5rem 0.8rem;
    border: 1px solid #dde1e8;
    border-radius: 8px;
    font-size: 0.9rem;
    background: white;
}

/* Barre d'outils de génération du document DUE (onglet Affectation, voir index.php) : label +
   champ heure alignés avec le bouton de génération, wrap sur mobile comme le reste des barres
   d'outils (voir la règle .gs-barre-outils ci-dessus, réutilisée telle quelle). */
.gs-barre-outils-due { align-items: center; }
.gs-barre-outils-due label { display: flex; align-items: center; gap: 8px; font-size: 0.9rem; }
.gs-barre-outils-due input[type="time"] { padding: 0.4rem 0.6rem; border: 1px solid #dde1e8; border-radius: 8px; font-size: 0.9rem; }

/* Sous-section "Déjà couverts par un document DUE" (voir liste-affectes-due dans index.php) :
   fond légèrement grisé sur les lignes pour bien les distinguer visuellement de la liste
   "Affectés" juste au-dessus, qu'on peut encore glisser-déposer/modifier. */
.gs-due-verrouilles { margin-top: 1rem; }
.gs-due-verrouilles .gs-item { background: #eceef2; }
/* .gs-badge-meta est pensé pour un fond sombre (texte blanc, voir plus haut) : illisible sur le
   fond clair de .gs-item ici (salaire net affiché à côté de l'étoile, voir renderDetail dans
   app.js) — même correctif que .gs-carte-predevis-badges .gs-badge-meta plus haut. */
.gs-due-verrouilles .gs-badge-meta { background: #dde1e8; color: #334; }

/* Panneaux "document" de l'onglet Affectation (DUE déjà générés, chef de tir, artificiers — voir
   index.php, tous les 3 partagent cette classe pour rester visuellement identiques) : même style
   discret, et la même marge sous le bouton de génération que sous la liste au-dessus de lui. */
.gs-doc-chef { margin-bottom: 1rem; }
.gs-doc-chef .gs-item { font-size: 0.85rem; color: #556; }
.gs-doc-chef .gs-liste { margin-bottom: 10px; }

/* Bascule "Cartes / Liste" du tableau de bord (Par spectacle) : deux boutons collés,
   un seul actif à la fois (surlignage façon .gs-sous-onglet.active). */
.gs-toggle-affichage { display: flex; gap: 4px; }
.gs-toggle-btn {
    padding: 0.5rem 0.8rem;
    border: 1px solid #dde1e8;
    border-radius: 8px;
    background: white;
    color: #1b2340;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
}
.gs-toggle-btn.active { background: #1b2340; color: white; border-color: #1b2340; }

/* Interrupteur (switch) style iOS : plus discret qu'une paire de boutons dans un formulaire déjà
   dense (voir "Gestion du tir" du spectacle). L'input réel reste dans le DOM (accessibilité,
   lecteurs d'écran) mais visuellement masqué (opacity:0) au profit du curseur stylé à côté. */
/* .gs-champ-switch : même mise en forme qu'un label de gs-formulaire (voir .gs-formulaire label),
   mais en div — le switch (input+curseur) doit rester dans un <label> séparé et étroit, pas dans
   celui-ci, sinon toute la ligne (intitulé compris) deviendrait cliquable pour bascule. */
.gs-champ-switch { display: flex; flex-direction: column; gap: 4px; font-size: 0.8rem; color: #556; flex-basis: 100%; }
.gs-switch-ligne { flex-direction: row !important; align-items: center; gap: 10px; width: fit-content; }
.gs-switch { position: relative; display: inline-block; width: 42px; height: 24px; flex-shrink: 0; }
.gs-switch input { opacity: 0; width: 0; height: 0; }
.gs-switch-curseur { position: absolute; inset: 0; background: #ccc; border-radius: 999px; cursor: pointer; transition: background 0.15s; }
.gs-switch-curseur::before { content: ''; position: absolute; height: 18px; width: 18px; left: 3px; top: 3px; background: white; border-radius: 50%; transition: transform 0.15s; box-shadow: 0 1px 3px rgba(0,0,0,0.3); }
.gs-switch input:checked + .gs-switch-curseur { background: #1b2340; }
.gs-switch input:checked + .gs-switch-curseur::before { transform: translateX(18px); }

/* En-tête de colonne cliquable pour trier (tableaux de Gestion) */
.gs-th-tri {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}
.gs-th-tri:hover { background: #2a3355; }
.gs-fleche-tri { font-size: 0.75rem; opacity: 0.6; }

/* Éléments réservés à l'admin (colonne Responsable, options de tri par responsable),
   cachés en JS pour un responsable/artificier via display:none plutôt que retirés du DOM
   pour garder le code simple - IS_ADMIN est vérifié une seule fois au chargement. */
.gs-option-admin.gs-cache-non-admin { display: none; }

/* ===========================================================================
   ONGLET MATÉRIEL (fiche spectacle > Matériel) : récap des batteries de mortier
   par diamètre extrait d'un plan de tir (voir chargerMaterielSpectacle dans app.js).
   Palette neutre bleu-gris de la fiche spectacle - pas de doré (réservé aux
   formulaires + badge compte, voir feedback_couleur_dore_reservee).
   =========================================================================== */
.gs-materiel-bloc { border: 1px solid #dde1e8; border-radius: 10px; padding: 1rem 1.1rem; margin-bottom: 1.2rem; background: #fff; }
.gs-materiel-titre { font-weight: 700; color: #1b2340; margin-bottom: 0.7rem; }
/* Origine du récap (quel devis) quand plusieurs plans de tir coexistent - info secondaire. */
.gs-materiel-source { font-weight: 400; font-size: 0.85rem; color: #778; }

.gs-materiel-entete { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-bottom: 0.8rem; }
/* Badge de fiabilité : 3 niveaux (vert / orange / rouge) selon l'indice de confiance
   renvoyé par l'extraction. Familles de couleur déjà utilisées ailleurs (gs-msg-ok /
   gs-badge-manque) pour rester cohérent. */
.gs-materiel-conf { display: inline-block; font-size: 0.78rem; font-weight: 600; padding: 0.15rem 0.6rem; border-radius: 999px; }
.gs-materiel-conf-ok { background: #e6f4ea; color: #2e8b57; }
.gs-materiel-conf-moyen { background: #fdf2e0; color: #b7791f; }
.gs-materiel-conf-faible { background: #fde8e8; color: #c0392b; }
/* "comptage ajusté" : au moins un diamètre n'est plus sur le comptage auto (bascule de type)
   ou une valeur a été corrigée à la main. Même famille visuelle que l'ancien "corrigé". */
.gs-materiel-conf-ajuste { background: #e3f0fc; color: #2266aa; }
.gs-materiel-date { font-size: 0.78rem; color: #99a; }

/* Tableau du récap PAR TYPE DE BATTERIE (Refonte 2) : une colonne par type (5x75, 3x75 EV...),
   2 sous-lignes par diamètre. Conteneur à défilement horizontal propre pour ne jamais faire
   déborder la page sur écran étroit (voir feedback_design_responsive). */
.gs-materiel-tableau-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.gs-materiel-tableau { border-collapse: collapse; width: 100%; font-size: 0.88rem; font-variant-numeric: tabular-nums; min-width: 34rem; }
.gs-materiel-tableau th, .gs-materiel-tableau td { border: 1px solid #e3e6ee; padding: 0.42rem 0.6rem; text-align: center; vertical-align: middle; }
.gs-materiel-tableau thead th { background: #2a3355; color: #fff; font-weight: 600; white-space: nowrap; }
/* Liseré sous l'en-tête de type : bleu = batterie droite, violet = batterie éventaillée (EV).
   Deux produits distincts, jamais additionnés - le repère couleur aide à ne pas confondre. */
.gs-materiel-tableau thead th.type-droit { border-bottom: 3px solid #3b6ea5; }
.gs-materiel-tableau thead th.type-ev { border-bottom: 3px solid #8a5cc4; }
.gs-materiel-tableau thead th .ev-tag { display: block; font-size: 0.68rem; font-weight: 500; opacity: 0.85; }
.gs-materiel-tableau tbody th[scope="row"] { background: #f2f4f9; color: #1b2340; font-weight: 600; white-space: nowrap; text-align: left; }
.gs-materiel-tableau tbody td.prov-cell { text-align: left; white-space: nowrap; }
.gs-materiel-tableau tfoot th, .gs-materiel-tableau tfoot td { background: #f2f4f9; font-weight: 700; border-top: 2px solid #c3c9d6; }
.gs-materiel-tableau tfoot td.type-droit { color: #3b6ea5; }
.gs-materiel-tableau tfoot td.type-ev { color: #8a5cc4; }

/* Colonne "Provenance" : pastille + libellé court + représentation NxM en pastille discrète,
   jamais un bloc texte encombrant. */
.gs-materiel-prov { font-size: 0.78rem; color: #55607a; display: inline-flex; align-items: center; gap: 0.4rem; }
.gs-materiel-prov::before { content: ""; width: 0.6rem; height: 0.6rem; border-radius: 2px; flex: none; }
.gs-materiel-prov.chap::before { background: #3b6ea5; }
.gs-materiel-prov.indiv::before { background: #6b8afd; }
.gs-materiel-repr { font-size: 0.72rem; font-weight: 600; color: #3b6ea5; background: #e8f0f8; border-radius: 4px; padding: 0.02rem 0.3rem; margin-left: 0.35rem; }

/* Cellule d'un type : deux valeurs éditables séparément — .gs-materiel-nb (batteries, gros) au-dessus
   de .gs-materiel-bo ("N bombes", petit). Clic sur l'une ou l'autre -> champ nombre (editerCelluleMateriel). */
.gs-materiel-cell { border-radius: 3px; }
.gs-materiel-cell.vide { color: #99a; }
.gs-materiel-nb, .gs-materiel-bo { cursor: pointer; border-radius: 3px; display: inline-block; }
.gs-materiel-nb:hover, .gs-materiel-bo:hover { background: #eef2ff; outline: 1px solid #6b8afd; }
.gs-materiel-bo { display: block; font-size: 0.72rem; color: #99a; margin-top: 0.1rem; }
.gs-materiel-cell.vide .gs-materiel-nb:hover { background: #eef2ff; } /* "—" reste cliquable pour ajouter */
.gs-materiel-input { width: 3.4rem; padding: 0.12rem 0.3rem; font-size: 0.88rem; text-align: center; border: 1px solid #6b8afd; border-radius: 6px; }

/* Bascule "type droit / type EV" : sur la sous-ligne "bombes individuelles" uniquement, et
   seulement quand le choix change le nombre de batteries. Choix PERSISTÉ côté serveur. */
.gs-materiel-bascule { display: inline-flex; border: 1px solid #dde1e8; border-radius: 7px; overflow: hidden; font-size: 0.75rem; margin-top: 0.35rem; }
.gs-materiel-bascule button { border: none; background: #fff; color: #55607a; padding: 0.2rem 0.6rem; cursor: pointer; font: inherit; white-space: nowrap; }
.gs-materiel-bascule button + button { border-left: 1px solid #dde1e8; }
.gs-materiel-bascule button.actif.droit { background: #e8f0f8; color: #3b6ea5; font-weight: 700; }
.gs-materiel-bascule button.actif.ev { background: #f1e9fa; color: #8a5cc4; font-weight: 700; }
.gs-materiel-compare { font-size: 0.77rem; color: #55607a; margin-top: 0.28rem; }
.gs-materiel-compare b { color: #1b2340; }
.gs-materiel-compare .d { color: #3b6ea5; }
.gs-materiel-compare .e { color: #8a5cc4; }

.gs-materiel-aucun { color: #556; font-style: italic; margin: 0.4rem 0; }

/* Encart "lignes à vérifier" : liste des lignes du plan de tir que l'extraction n'a pas su
   classer avec certitude - même famille visuelle que gs-msg-err mais en encart persistant. */
.gs-materiel-verif { margin-top: 1rem; padding: 0.7rem 0.9rem; background: #fdf2e0; border: 1px solid #f0d9b5; border-radius: 8px; }
.gs-materiel-verif-titre { font-weight: 600; color: #b7791f; margin-bottom: 0.4rem; font-size: 0.9rem; }
.gs-materiel-verif ul { margin: 0; padding-left: 1.2rem; font-size: 0.85rem; color: #6a5423; }
.gs-materiel-verif li { margin: 0.2rem 0; }
.gs-materiel-verif-aide { margin: 0.5rem 0 0; font-size: 0.78rem; color: #99895f; font-style: italic; }
/* Référence produit cliquable dans l'encart (ex: "P170404") : ouvre l'aperçu du plan de tir à la
   bonne page. Rendu en bouton "lien" pour rester accessible au clavier, pas un <span> décoré. */
.gs-materiel-ref-lien {
    border: none; background: none; padding: 0; font: inherit; font-weight: 700;
    color: #2266aa; text-decoration: underline dotted; cursor: pointer;
}
.gs-materiel-ref-lien:hover { color: #17466e; }

.gs-materiel-actions { margin-top: 1rem; display: flex; gap: 0.6rem; flex-wrap: wrap; }

/* Aperçu du plan de tir (pdf.js) : panneau replié par défaut sous les actions, ouvert par le
   bouton "Voir le plan de tir" ou par un clic sur une référence à vérifier. Voir
   ouvrirApercuPlanTir dans app.js. */
.gs-materiel-apercu { margin-top: 1rem; border: 1px solid #dde1e8; border-radius: 8px; overflow: hidden; background: #f2f4f9; }
.gs-materiel-apercu-barre {
    display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
    padding: 0.5rem 0.7rem; background: #2a3355;
}
.gs-materiel-apercu-barre .gs-btn { padding: 0.25rem 0.6rem; font-size: 0.85rem; }
.gs-materiel-apercu-nav { min-width: 2rem; }
.gs-materiel-apercu-pos, .gs-materiel-apercu-zoom-grp { color: #fff; font-size: 0.85rem; display: inline-flex; align-items: center; gap: 0.4rem; }
.gs-materiel-apercu-zoom-grp { margin-left: auto; }
.gs-materiel-apercu-fermer { background: transparent; color: #fff; border-color: rgba(255,255,255,0.4); }
/* Zone de rendu : fond gris "visionneuse", la page centrée, défilement vertical si la page
   dépasse la hauteur max (évite un panneau démesuré sur un plan de tir de plusieurs pages). */
.gs-materiel-apercu-canvas-wrap {
    background: #525659; padding: 1rem; overflow: auto; max-height: 70vh;
    display: flex; justify-content: center;
}
.gs-materiel-apercu-canvas { background: #fff; box-shadow: 0 2px 12px rgba(0,0,0,0.4); max-width: 100%; height: auto; }
