/* ==========================================================================
   Base — reset, typographie, boutons, champs, utilitaires
   ========================================================================== */

*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

html, body {
    max-width: 100%;
    width: 100%;
    overflow-x: hidden;
}

body {
    display: flex;
    flex-direction: column;
    font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, sans-serif;
    color: var(--couleur-texte);
    background: linear-gradient(160deg, var(--fond-page-debut) 0%, var(--fond-page-fin) 100%);
    min-height: 100vh;
    line-height: 1.6;
    transition: background var(--transition-douce), color var(--transition-douce);
}

/* Fond constant : halos doux fixes au viewport, présents sur toutes les pages */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(circle at 18% 12%, color-mix(in srgb, var(--couleur-primaire) 10%, transparent), transparent 42%),
        radial-gradient(circle at 85% 85%, color-mix(in srgb, var(--couleur-accent) 9%, transparent), transparent 45%);
}

a {
    color: var(--couleur-lien);
}

h1, h2, h3, h4, h5, h6 {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    color: var(--couleur-texte);
    line-height: 1.2;
}

img {
    max-width: 100%;
    display: block;
}

/* Focus clavier visible partout, sans casser le style au clic à la souris */
:focus-visible {
    outline: 2px solid var(--couleur-primaire);
    outline-offset: 2px;
}

/* ==========================================================================
   Conteneurs
   ========================================================================== */
.conteneur {
    width: min(1200px, calc(100% - 2.5rem));
    margin-inline: auto;
}

.conteneur--etroit {
    width: min(760px, calc(100% - 2.5rem));
    margin-inline: auto;
}

/* ==========================================================================
   Cartes glassmorphism
   ========================================================================== */
.carte-glass {
    background: var(--glass-bg);
    backdrop-filter: blur(18px) saturate(160%);
    -webkit-backdrop-filter: blur(18px) saturate(160%);
    border: 1px solid var(--glass-border);
    border-radius: var(--rayon-l);
    box-shadow: var(--ombre-douce);
}

.carte-glass--compacte { padding: 1.5rem; }
.carte-glass--pleine { padding: clamp(1.75rem, 4vw, 2.75rem); }

.surface {
    background: var(--surface-bg);
    border: 1px solid var(--couleur-bordure);
    border-radius: var(--rayon-m);
}

/* Légère élévation au survol, réutilisable sur cartes cliquables */
.carte-survol {
    transition: transform var(--transition-douce), box-shadow var(--transition-douce);
}
.carte-survol:hover {
    transform: translateY(-3px);
    box-shadow: var(--ombre-flottante);
}

/* ==========================================================================
   Boutons
   ========================================================================== */
.bouton {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    font-family: 'Rajdhani', sans-serif;
    font-weight: 600;
    font-size: 1rem;
    padding: 0.75rem 1.6rem;
    border-radius: var(--rayon-pilule);
    border: none;
    cursor: pointer;
    text-decoration: none;
    transition: transform var(--transition-douce), box-shadow var(--transition-douce);
    white-space: nowrap;
}

.bouton--principal {
    color: #fff;
    background: linear-gradient(135deg, var(--couleur-primaire) 0%, var(--couleur-primaire-fonce) 100%);
    box-shadow: 0 10px 24px -10px color-mix(in srgb, var(--couleur-primaire) 55%, transparent);
}
.bouton--principal:hover { transform: translateY(-2px); box-shadow: 0 16px 30px -10px color-mix(in srgb, var(--couleur-primaire) 65%, transparent); }

.bouton--accent {
    color: #fff;
    background: linear-gradient(135deg, var(--couleur-accent) 0%, #6F5222 100%);
    box-shadow: 0 10px 24px -10px color-mix(in srgb, var(--couleur-accent) 55%, transparent);
}
.bouton--accent:hover { transform: translateY(-2px); }

.bouton--contour {
    background: transparent;
    border: 1px solid var(--couleur-bordure);
    color: var(--couleur-texte);
}
.bouton--contour:hover { background: var(--surface-bg); transform: translateY(-2px); }

.bouton--succes { color: #fff; background: var(--couleur-succes); }
.bouton--danger { color: #fff; background: var(--couleur-erreur); }

.bouton--pleine-largeur { width: 100%; justify-content: center; }

.bouton--sm { padding: 0.5rem 1.1rem; font-size: 0.86rem; }

.bouton:disabled,
.bouton[aria-disabled="true"] {
    opacity: 0.55;
    cursor: not-allowed;
    transform: none !important;
}

/* Bouton icône seule, carré arrondi — utilisé dans les tableaux/listes */
.bouton-icone {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.86rem;
    font-weight: 600;
    padding: 0.55rem 1rem;
    border-radius: var(--rayon-s);
    border: 1px solid var(--couleur-bordure);
    background: var(--surface-bg);
    color: var(--couleur-texte);
    cursor: pointer;
    text-decoration: none;
    transition: background var(--transition-rapide), border-color var(--transition-rapide), color var(--transition-rapide), transform var(--transition-rapide);
}
.bouton-icone:hover { transform: translateY(-1px); }
.bouton-icone--voir:hover { border-color: var(--couleur-primaire); color: var(--couleur-primaire); }
.bouton-icone--valider { background: rgba(76, 175, 125, 0.12); border-color: rgba(76, 175, 125, 0.35); color: var(--couleur-succes); }
.bouton-icone--refuser { background: rgba(232, 93, 107, 0.10); border-color: rgba(232, 93, 107, 0.30); color: var(--couleur-erreur); }

/* Bouton rond, icône seule (ex. burger, thème, notification) */
.bouton-rond {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    flex-shrink: 0;
    border-radius: 50%;
    border: 1px solid var(--couleur-bordure);
    background: var(--surface-bg);
    color: var(--couleur-texte);
    cursor: pointer;
    transition: background var(--transition-rapide), border-color var(--transition-rapide), transform var(--transition-rapide);
}
.bouton-rond:hover { border-color: var(--couleur-primaire); color: var(--couleur-primaire); transform: translateY(-2px); }

/* ==========================================================================
   Champs de formulaire
   ========================================================================== */
.champ {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    flex: 1 1 220px;
}

.champ label { font-size: 0.86rem; font-weight: 600; color: var(--couleur-texte); }
.champ .obligatoire { color: var(--couleur-accent); }

.champ input[type="text"],
.champ input[type="email"],
.champ input[type="password"],
.champ input[type="tel"],
.champ input[type="number"],
.champ input[type="date"],
.champ input[type="search"],
.champ input[type="url"],
.champ select,
.champ textarea {
    width: 100%;
    padding: 0.8rem 1rem;
    border: 1px solid var(--couleur-bordure);
    border-radius: var(--rayon-s);
    background: var(--champ-bg);
    color: var(--couleur-texte);
    font-family: inherit;
    font-size: 0.95rem;
    transition: border-color var(--transition-rapide), background var(--transition-rapide), box-shadow var(--transition-rapide);
}

.champ input::placeholder,
.champ textarea::placeholder {
    color: var(--couleur-texte-doux);
    opacity: 0.7;
}

.champ input:focus,
.champ select:focus,
.champ textarea:focus {
    outline: none;
    border-color: var(--couleur-primaire);
    background: var(--champ-bg-focus);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--couleur-primaire) 14%, transparent);
}

.champ input.champ--erreur,
.champ select.champ--erreur,
.champ textarea.champ--erreur {
    border-color: var(--couleur-erreur);
}

.champ input:disabled,
.champ select:disabled,
.champ textarea:disabled {
    background: var(--couleur-bordure);
    color: var(--couleur-texte-doux);
    cursor: not-allowed;
}

.champ textarea { resize: vertical; min-height: 120px; }

.aide-champ { font-size: 0.8rem; color: var(--couleur-texte-doux); }
.erreur-champ { font-size: 0.8rem; color: var(--couleur-erreur); }

.ligne-champs {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    margin-bottom: 1rem;
}

/* Case à cocher et bouton radio, taille tactile confortable */
.champ input[type="checkbox"],
.champ input[type="radio"] {
    width: 20px;
    height: 20px;
    accent-color: var(--couleur-primaire);
    cursor: pointer;
}

/* ==========================================================================
   Badges de statut
   ========================================================================== */
.badge-statut {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.78rem;
    font-weight: 600;
    padding: 0.3rem 0.75rem;
    border-radius: var(--rayon-pilule);
    white-space: nowrap;
}
.badge-statut--valide  { background: rgba(76, 175, 125, 0.14); color: var(--couleur-succes); }
.badge-statut--attente { background: rgba(240, 168, 96, 0.16); color: #B7791F; }
.badge-statut--refuse  { background: rgba(232, 93, 107, 0.14); color: var(--couleur-erreur); }
.badge-statut--archive { background: rgba(107, 111, 140, 0.14); color: var(--couleur-texte-doux); }
.badge-statut--info    { background: rgba(91, 159, 232, 0.14); color: var(--couleur-info); }

/* ==========================================================================
   États vides
   ========================================================================== */
.etat-vide {
    text-align: center;
    padding: 3.5rem 1.5rem;
}
.etat-vide-icone {
    width: 96px;
    height: 96px;
    margin: 0 auto 1.25rem;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2.2rem;
    color: var(--couleur-primaire);
    background: linear-gradient(145deg, color-mix(in srgb, var(--couleur-primaire) 16%, transparent), color-mix(in srgb, var(--couleur-primaire) 4%, transparent));
    box-shadow: 0 0 0 12px color-mix(in srgb, var(--couleur-primaire) 5%, transparent);
    animation: etat-vide-flotte 3.5s ease-in-out infinite;
}
@keyframes etat-vide-flotte {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-6px); }
}
.etat-vide-titre {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 1.25rem;
    color: var(--couleur-texte);
    margin-bottom: 0.5rem;
}
.etat-vide-texte {
    color: var(--couleur-texte-doux);
    font-size: 0.92rem;
    max-width: 420px;
    margin: 0 auto 1.5rem;
    line-height: 1.6;
}
@media (prefers-reduced-motion: reduce) {
    .etat-vide-icone { animation: none; }
}

/* ==========================================================================
   Animation d'entrée douce (cartes, listes) — à poser sur un élément
   pour qu'il apparaisse en fondu-glissé au chargement
   ========================================================================== */
@keyframes fondu-glisse-haut {
    from { opacity: 0; transform: translateY(15px); }
    to   { opacity: 1; transform: translateY(0); }
}
.anim-entree {
    opacity: 0;
    animation: fondu-glisse-haut 0.6s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
    will-change: opacity, transform;
}
@media (prefers-reduced-motion: reduce) {
    .anim-entree { animation: none; opacity: 1; }
}

/* Cascade automatique pour une grille de cartes : chaque enfant décale son délai */
.anim-cascade > *:nth-child(1) { animation-delay: 0.05s; }
.anim-cascade > *:nth-child(2) { animation-delay: 0.12s; }
.anim-cascade > *:nth-child(3) { animation-delay: 0.19s; }
.anim-cascade > *:nth-child(4) { animation-delay: 0.26s; }
.anim-cascade > *:nth-child(5) { animation-delay: 0.33s; }
.anim-cascade > *:nth-child(6) { animation-delay: 0.40s; }

/* ==========================================================================
   Chargement — effet skeleton (à utiliser en attendant des données AJAX)
   ========================================================================== */
.skeleton {
    position: relative;
    overflow: hidden;
    background: var(--couleur-bordure);
    border-radius: var(--rayon-xs);
    color: transparent !important;
}
.skeleton::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent);
    animation: skeleton-brille 1.4s infinite;
}
html[data-theme="sombre"] .skeleton::after {
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.08), transparent);
}
@keyframes skeleton-brille { to { transform: translateX(100%); } }

/* ==========================================================================
   Utilitaires
   ========================================================================== */
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Lien d'évitement, premier élément focusable de la page */
.lien-evitement {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 999;
    background: var(--couleur-primaire);
    color: #fff;
    font-weight: 600;
    padding: 0.7rem 1.25rem;
    border-radius: var(--rayon-s);
    text-decoration: none;
}
.lien-evitement:focus { left: 1rem; top: 1rem; }

::selection {
    background: var(--couleur-primaire-clair);
    color: #fff;
}

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--couleur-bordure); border-radius: 999px; }
::-webkit-scrollbar-thumb:hover { background: var(--couleur-texte-doux); }

@media (prefers-reduced-motion: reduce) {
    * { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
}

/* ==========================================================================
   Le pied de page reste toujours en bas de l'écran, même si le contenu
   de la page est court, plutôt qu'un vide en dessous.
   ========================================================================== */
#contenu-principal {
    flex: 1 0 auto;
}
.pied-site,
.bo-footer {
    flex-shrink: 0;
}

/* ==========================================================================
   Bascule de thème — icône affichée selon le thème actif, quel que soit
   le composant qui porte le bouton (public, back-office, menu déroulant)
   ========================================================================== */
[data-toggle-theme] .icone-sombre { display: inline-block; }
[data-toggle-theme] .icone-clair  { display: none; }
html[data-theme="sombre"] [data-toggle-theme] .icone-sombre { display: none; }
html[data-theme="sombre"] [data-toggle-theme] .icone-clair  { display: inline-block; }

/* ==========================================================================
   Visibilité responsive — bascule entre un élément desktop et son
   équivalent mobile, au même point de rupture que la sidebar
   ========================================================================== */
.masque-mobile { display: inline-flex; }
.masque-desktop { display: none; }
@media (max-width: 992px) {
    .masque-mobile { display: none !important; }
    .masque-desktop { display: flex !important; }
}

/* ==========================================================================
   Avatars — photo ou initiales, tailles communes à tout le projet
   ========================================================================== */
.avatar-image {
    border-radius: 50%;
    object-fit: cover;
    display: block;
    flex-shrink: 0;
    border: 2px solid var(--glass-border);
}

.avatar-initiales {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    border-radius: 50%;
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    color: #fff;
    background: linear-gradient(135deg, var(--couleur-primaire) 0%, var(--couleur-primaire-fonce) 100%);
}

.avatar-image--sm,
.avatar-initiales--sm {
    width: 36px;
    height: 36px;
    font-size: 0.82rem;
}

.avatar-image--md,
.avatar-initiales--md {
    width: 48px;
    height: 48px;
    font-size: 1rem;
}

.avatar-image--lg,
.avatar-initiales--lg {
    width: 72px;
    height: 72px;
    font-size: 1.6rem;
}

/* ==========================================================================
   Logo issu des réglages, en remplacement de l'icône par défaut
   ========================================================================== */
.marque-logo {
    height: 28px;
    width: auto;
    max-width: 140px;
    object-fit: contain;
    flex-shrink: 0;
}

/* La sidebar déployée mesure 264 pixels, moins 24 de marge de chaque côté :
   190 pixels de large restent disponibles, autant que dans l'en-tête public. */
.bo-sidebar__logo .marque-logo {
    height: var(--logo-hauteur-sidebar);
    max-width: 190px;
}

/* Sidebar réduite : le favicon remplace le logo. Un logo comportant du
   texte, réduit à quelques dizaines de pixels, deviendrait illisible ;
   le favicon est précisément conçu pour cette taille. */
.bo-sidebar__logo .marque-favicon {
    display: none;
    width: 34px;
    height: 34px;
    object-fit: contain;
    flex-shrink: 0;
    font-size: 1.35rem;
    color: var(--couleur-primaire-clair);
}

body.sidebar-reduite .bo-sidebar__logo .marque-logo {
    display: none;
}

body.sidebar-reduite .bo-sidebar__logo .marque-favicon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* En mobile, la sidebar s'ouvre toujours en pleine largeur : la classe de
   repli subsiste dans le corps de page mais ne doit rien masquer ici. */
@media (max-width: 992px) {
    body.sidebar-reduite .bo-sidebar__logo .marque-logo { display: block; }
    body.sidebar-reduite .bo-sidebar__logo .marque-favicon { display: none; }
}

/* ==========================================================================
   Champ appât des formulaires publics
   --------------------------------------------------------------------------
   Volontairement sorti du flux plutôt que masqué par « display:none » :
   certains robots reconnaissent cette règle et ignorent alors le champ.
   Le conteneur porte par ailleurs aria-hidden et le champ tabindex="-1",
   pour rester inatteignable au clavier comme aux lecteurs d'écran.
   ========================================================================== */
.protection-appat {
    position: absolute;
    left: -9999px;
    top: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
}

/* ==================================================================
   Formulaires générés — espacements
   Le gabarit de module produit des blocs « .champ » consécutifs sans
   marge propre : elle est déclarée ici plutôt que dans chaque vue.
   ================================================================== */

.champ + .champ,
.champ + .ligne-champs,
.ligne-champs + .champ {
    margin-top: 1.25rem;
}

.champ label {
    display: block;
    margin-bottom: 0.5rem;
}

/* Case à cocher : le libellé accompagne la case, il ne la surplombe pas. */
.champ--case label {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    margin-bottom: 0;
    cursor: pointer;
}

.champ--case input[type="checkbox"] {
    width: auto;
    margin: 0;
    flex-shrink: 0;
}

/* ==================================================================
   Barre d'action au-dessus d'une liste
   ================================================================== */

.entete-action {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 1.5rem;
}


/* ==========================================================================
   Logo selon le thème
   ==========================================================================

   Placé en fin de feuille : à spécificité égale, ces règles doivent passer
   après celles de « .marque-logo ». */
.marque-logo--sombre {
    display: none;
}

html[data-theme="sombre"] .marque-logo--clair {
    display: none;
}

html[data-theme="sombre"] .marque-logo--sombre {
    display: inline-block;
}


/* ==========================================================================
   Taille du logo par emplacement
   ==========================================================================

   Les hauteurs viennent de variables.css : c'est là qu'on les ajuste. */
.entete-site__marque .marque-logo,
.pied-site__logo .marque-logo {
    height: var(--logo-hauteur);
    max-width: var(--logo-largeur-max);
}

.auth-marque .marque-logo {
    height: var(--logo-hauteur-auth);
    max-width: var(--logo-largeur-max);
}