@charset "UTF-8";

/* ===========================================================================
   NEBULA — design system
   ---------------------------------------------------------------------------
   Thème nébuleuse, futuriste, sombre.
   Aucune couleur en dur hors de ce bloc :root. Le HTML n'écrit jamais de
   couleur, il pose des classes et des attributs data-*.

   Sommaire
     1.  Variables
     2.  Reset
     3.  Fond nébuleuse
     4.  Typographie
     5.  Accessibilité (focus, lien d'évitement)
     6.  Mise en page (conteneur, sections, grilles)
     7.  En-tête et navigation
     8.  Pied de page
     9.  Composants — bouton
     10. Composants — carte
     11. Composants — raie spectrale et badge de grade
     12. Composants — champ de formulaire
     13. Composants — tableau
     14. Composants — pastille d'état, jauge, données
     15. Page d'accueil
     16. Mouvement réduit
   =========================================================================== */


/* ===========================================================================
   1. VARIABLES
   =========================================================================== */

:root {
  /* --- Palette de marque ------------------------------------------------- */
  --nuit-spatiale:    #0A0E1F;   /* fond, ~70 % de la surface               */
  --nuit-elevee:      #141A33;   /* cartes, panneaux                        */
  --bleu-electrique:  #2563EB;   /* remplissages, bordures actives          */
  --bleu-ciel:        #7DD3FC;   /* texte secondaire, icônes                */
  --rose-electrique:  #F0369E;   /* accent RARE — 1 seul élément par écran  */
  --blanc-froid:      #E8ECF8;   /* texte principal                         */

  /* --- Dérivés -----------------------------------------------------------
     --bleu-lien existe pour une raison d'accessibilité : #2563EB sur
     #0A0E1F donne 3,74:1, sous le seuil AA. Le bleu électrique reste donc
     réservé aux remplissages et aux bordures ; le texte de lien utilise
     #60A5FA (7,5:1).                                                       */
  --nuit-haute:       #1B2242;
  --nuit-bordure:     #222B4D;
  --bleu-lien:        #60A5FA;
  --sur-primaire:     #FFFFFF;   /* texte sur aplat bleu électrique, 5,1:1  */

  --texte-principal:  var(--blanc-froid);
  --texte-secondaire: #A9B4CE;   /* 8,2:1 sur --nuit-elevee                 */
  /* 6,1:1 sur --nuit-elevee et 5,6:1 sur la zone la plus claire du fond
     nébuleuse : AA tenu même sur le pire pixel de l'image de fond.        */
  --texte-attenue:    #8E9AB8;

  /* --- Couleurs d'état ---------------------------------------------------- */
  --succes:  #34D399;
  --alerte:  #FBBF24;
  --danger:  #F87171;

  /* --- Raies spectrales des grades ---------------------------------------
     Ordonnées comme un spectre. Ces valeurs doublent la colonne
     grades.couleur en base : la base fait foi, le CSS sert de repli.      */
  --grade-fondateur:      #F0369E;
  --grade-administrateur: #8B5CF6;
  --grade-developpeur:    #2563EB;
  --grade-moderateur:     #7DD3FC;
  --grade-helpeur:        #34D399;
  --raie-couleur:         var(--bleu-electrique);

  /* --- Rôles joueur (cumulables, aucune hiérarchie) ----------------------- */
  --role-whitelist: #34D399;
  --role-vip:       #F0369E;
  --role-membre:    #7DD3FC;

  /* --- Typographie -------------------------------------------------------- */
  --police-titre: 'Chakra Petch', 'Segoe UI Semibold', 'Segoe UI', sans-serif;
  --police-corps: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --police-mono:  'JetBrains Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;

  --taille-xs:  0.75rem;
  --taille-s:   0.875rem;
  --taille-m:   1rem;
  --taille-l:   clamp(1.0625rem, 1rem + 0.35vw, 1.25rem);
  --titre-xs:   clamp(1rem,     0.95rem + 0.3vw, 1.15rem);
  --titre-s:    clamp(1.15rem,  1.05rem + 0.5vw, 1.45rem);
  --titre-m:    clamp(1.45rem,  1.2rem  + 1.1vw, 2.1rem);
  --titre-l:    clamp(2rem,     1.45rem + 2.4vw, 3.4rem);

  --interligne-serre: 1.15;
  --interligne:       1.65;

  /* --- Espacements -------------------------------------------------------- */
  --esp-1: 0.25rem;
  --esp-2: 0.5rem;
  --esp-3: 0.75rem;
  --esp-4: 1rem;
  --esp-5: 1.5rem;
  --esp-6: 2rem;
  --esp-7: 3rem;
  --esp-8: 4.5rem;

  /* --- Formes ------------------------------------------------------------- */
  --rayon-s: 6px;
  --rayon-m: 10px;
  --rayon-l: 16px;
  --rayon-plein: 999px;

  --bordure:        1px solid var(--nuit-bordure);
  --bordure-active: 1px solid var(--bleu-electrique);

  --ombre-basse: 0 1px 2px rgba(0, 0, 0, 0.4);
  --ombre-carte: 0 12px 32px -18px rgba(0, 0, 0, 0.9);
  --lueur-bleue: 0 0 0 1px rgba(37, 99, 235, 0.35), 0 0 24px -8px rgba(37, 99, 235, 0.6);

  /* --- Mise en page ------------------------------------------------------- */
  --largeur-max:   1180px;
  --gouttiere:     clamp(1rem, 4vw, 2rem);
  --hauteur-entete: 64px;

  /* --- Mouvement ---------------------------------------------------------- */
  --transition: 160ms ease;
}


/* ===========================================================================
   2. RESET
   =========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--hauteur-entete) + var(--esp-4));
}

body {
  margin: 0;
  min-height: 100vh;
  background-color: var(--nuit-spatiale);
  color: var(--texte-principal);
  font-family: var(--police-corps);
  font-size: var(--taille-m);
  line-height: var(--interligne);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
}

img,
svg,
video {
  display: block;
  max-width: 100%;
  height: auto;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--police-titre);
  font-weight: 600;
  line-height: var(--interligne-serre);
  letter-spacing: 0.01em;
}

p,
dl,
dt,
dd,
figure {
  margin: 0;
}


/* ===========================================================================
   3. FOND NÉBULEUSE
   ---------------------------------------------------------------------------
   Deux couches : l'image à 18 % d'opacité, puis un voile dégradé qui
   assombrit progressivement. Le voile n'est pas décoratif : il garantit que
   le contenu dense (tableaux, listes) tombe sur un fond quasi uni, pas sur
   les zones claires de la nébuleuse.
   =========================================================================== */

.fond-nebuleuse {
  position: fixed;
  inset: 0;
  z-index: -1;
  background-color: var(--nuit-spatiale);
  pointer-events: none;
}

.fond-nebuleuse::before,
.fond-nebuleuse::after {
  content: '';
  position: absolute;
  inset: 0;
}

.fond-nebuleuse::before {
  background-image: url('/assets/img/nebuleuse.svg');
  background-size: cover;
  background-position: 50% 30%;
  background-repeat: no-repeat;
  opacity: 0.18;
}

.fond-nebuleuse::after {
  background:
    linear-gradient(
      180deg,
      rgba(10, 14, 31, 0.25) 0%,
      rgba(10, 14, 31, 0.80) 48%,
      rgba(10, 14, 31, 0.96) 100%
    );
}


/* ===========================================================================
   4. TYPOGRAPHIE
   =========================================================================== */

a {
  color: var(--bleu-lien);
  text-decoration-color: rgba(96, 165, 250, 0.4);
  text-underline-offset: 3px;
  transition: color var(--transition), text-decoration-color var(--transition);
}

a:hover {
  color: var(--bleu-ciel);
  text-decoration-color: currentColor;
}

.titre-page {
  font-size: var(--titre-l);
  letter-spacing: -0.015em;
}

.titre-section {
  font-size: var(--titre-m);
}

.titre-carte {
  font-size: var(--titre-s);
}

.sur-titre {
  display: inline-block;
  font-family: var(--police-mono);
  font-size: var(--taille-xs);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--bleu-ciel);
}

.texte-secondaire {
  color: var(--texte-secondaire);
}

.texte-attenue {
  color: var(--texte-attenue);
  font-size: var(--taille-s);
}

.texte-mesure {
  max-width: 62ch;
}

.mono {
  font-family: var(--police-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}


/* ===========================================================================
   5. ACCESSIBILITÉ
   =========================================================================== */

.visuellement-cache {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Anneau de focus unique pour tout le site. */
:focus {
  outline: 2px solid var(--bleu-ciel);
  outline-offset: 3px;
  border-radius: var(--rayon-s);
}

:focus:not(:focus-visible) {
  outline: none;
}

:focus-visible {
  outline: 2px solid var(--bleu-ciel);
  outline-offset: 3px;
  border-radius: var(--rayon-s);
}

.lien-evitement {
  position: absolute;
  top: var(--esp-2);
  left: var(--esp-2);
  z-index: 100;
  padding: var(--esp-2) var(--esp-4);
  background: var(--bleu-electrique);
  color: var(--sur-primaire);
  border-radius: var(--rayon-s);
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform var(--transition);
}

.lien-evitement:focus {
  transform: translateY(0);
}


/* ===========================================================================
   6. MISE EN PAGE
   =========================================================================== */

.conteneur {
  width: 100%;
  max-width: var(--largeur-max);
  margin-inline: auto;
  padding-inline: var(--gouttiere);
}

.contenu {
  display: block;
  min-height: 60vh;
  padding-block: var(--esp-6) var(--esp-8);
}

.section {
  padding-block: var(--esp-7);
}

.section + .section {
  padding-top: 0;
}

.entete-section {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--esp-3);
  margin-bottom: var(--esp-5);
}

.grille {
  display: grid;
  gap: var(--esp-4);
}

/* Colonnes fluides : passent seules à une colonne sous ~420 px. */
.grille-auto {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}

.grille-2 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
}

.pile {
  display: flex;
  flex-direction: column;
  gap: var(--esp-4);
}

.ligne {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--esp-3);
}


/* ===========================================================================
   7. EN-TÊTE ET NAVIGATION
   =========================================================================== */

.entete {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(10, 14, 31, 0.82);
  backdrop-filter: blur(14px);
  border-bottom: var(--bordure);
}

.entete__interieur {
  display: flex;
  align-items: center;
  gap: var(--esp-4);
  min-height: var(--hauteur-entete);
}

.marque {
  display: inline-flex;
  align-items: center;
  gap: var(--esp-3);
  margin-right: auto;
  text-decoration: none;
  color: var(--texte-principal);
}

.marque__logo {
  width: 28px;
  height: 28px;
  flex: none;
}

/* Le logo est peint ici, pas dans le balisage injecté par layout.js. */
.marque__anneau   { stroke: var(--bleu-electrique); opacity: 0.55; }
.marque__halo     { stroke: var(--bleu-ciel); }
.marque__noyau    { fill:   var(--blanc-froid); }
.marque__filament { stroke: var(--bleu-ciel); opacity: 0.8; }

.marque__nom {
  font-family: var(--police-titre);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.marque__mention {
  display: none;
  font-family: var(--police-mono);
  font-size: var(--taille-xs);
  letter-spacing: 0.1em;
  color: var(--texte-attenue);
}

.bascule-nav {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  padding: 0;
  background: transparent;
  border: var(--bordure);
  border-radius: var(--rayon-s);
  color: var(--bleu-ciel);
  cursor: pointer;
}

.bascule-nav__barres,
.bascule-nav__barres::before,
.bascule-nav__barres::after {
  display: block;
  width: 18px;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
  transition: transform var(--transition), opacity var(--transition);
}

.bascule-nav__barres::before,
.bascule-nav__barres::after {
  content: '';
  position: relative;
}

.bascule-nav__barres::before { top: -6px; }
.bascule-nav__barres::after  { top: 4px; }

.bascule-nav[aria-expanded='true'] .bascule-nav__barres {
  background: transparent;
}

.bascule-nav[aria-expanded='true'] .bascule-nav__barres::before {
  transform: translateY(6px) rotate(45deg);
}

.bascule-nav[aria-expanded='true'] .bascule-nav__barres::after {
  transform: translateY(-4px) rotate(-45deg);
}

.nav {
  display: none;
}

.nav.est-ouverte {
  display: block;
  position: absolute;
  top: var(--hauteur-entete);
  left: 0;
  right: 0;
  padding: var(--esp-4) var(--gouttiere) var(--esp-5);
  background: var(--nuit-elevee);
  border-bottom: var(--bordure);
  box-shadow: var(--ombre-carte);
}

.nav__liste {
  display: flex;
  flex-direction: column;
  gap: var(--esp-1);
}

.nav__lien {
  display: block;
  padding: var(--esp-3) var(--esp-3);
  border-left: 3px solid transparent;
  border-radius: var(--rayon-s);
  color: var(--texte-secondaire);
  text-decoration: none;
  font-size: var(--taille-s);
  letter-spacing: 0.02em;
  transition: color var(--transition), background var(--transition),
              border-color var(--transition);
}

.nav__lien:hover {
  color: var(--texte-principal);
  background: var(--nuit-haute);
}

.nav__lien[aria-current='page'] {
  color: var(--texte-principal);
  border-left-color: var(--bleu-electrique);
  background: var(--nuit-haute);
}

.nav__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--esp-2);
  margin-top: var(--esp-4);
  padding-top: var(--esp-4);
  border-top: var(--bordure);
}


/* ===========================================================================
   8. PIED DE PAGE
   =========================================================================== */

.pied {
  margin-top: var(--esp-8);
  border-top: var(--bordure);
  background: rgba(20, 26, 51, 0.6);
}

.pied__interieur {
  display: grid;
  gap: var(--esp-6);
  padding-block: var(--esp-6);
  grid-template-columns: 1fr;
}

.pied__titre {
  font-family: var(--police-titre);
  font-size: var(--taille-s);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bleu-ciel);
  margin-bottom: var(--esp-3);
}

.pied__liste {
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
  font-size: var(--taille-s);
}

.pied__bas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--esp-3);
  padding-block: var(--esp-4);
  border-top: var(--bordure);
  font-size: var(--taille-xs);
  color: var(--texte-attenue);
}


/* ===========================================================================
   9. COMPOSANT — BOUTON
   =========================================================================== */

.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--esp-2);
  min-height: 44px;              /* cible tactile confortable */
  padding: var(--esp-3) var(--esp-5);
  border: 1px solid transparent;
  border-radius: var(--rayon-s);
  font-family: var(--police-corps);
  font-size: var(--taille-s);
  font-weight: 600;
  letter-spacing: 0.02em;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition),
              color var(--transition), transform var(--transition);
}

.bouton:active {
  transform: translateY(1px);
}

.bouton--primaire {
  background: var(--bleu-electrique);
  color: var(--sur-primaire);
  box-shadow: var(--lueur-bleue);
}

.bouton--primaire:hover {
  background: #1D4FD8;
  color: var(--sur-primaire);
}

.bouton--secondaire {
  background: var(--nuit-haute);
  border-color: var(--nuit-bordure);
  color: var(--texte-principal);
}

.bouton--secondaire:hover {
  border-color: var(--bleu-electrique);
  color: var(--texte-principal);
}

.bouton--fantome {
  background: transparent;
  border-color: transparent;
  color: var(--texte-secondaire);
}

.bouton--fantome:hover {
  background: var(--nuit-haute);
  color: var(--texte-principal);
}

.bouton--large {
  width: 100%;
}

.bouton[aria-disabled='true'],
.bouton:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}


/* ===========================================================================
   10. COMPOSANT — CARTE
   =========================================================================== */

.carte {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--esp-3);
  padding: var(--esp-5);
  background: var(--nuit-elevee);
  border: var(--bordure);
  border-radius: var(--rayon-m);
  box-shadow: var(--ombre-carte);
}

.carte--liante {
  transition: border-color var(--transition), transform var(--transition);
}

.carte--liante:hover {
  border-color: var(--bleu-electrique);
  transform: translateY(-2px);
}

.carte__entete {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--esp-3);
}

.carte__pied {
  margin-top: auto;
  padding-top: var(--esp-3);
  border-top: var(--bordure);
}


/* ===========================================================================
   11. COMPOSANT — RAIE SPECTRALE ET BADGE DE GRADE
   ---------------------------------------------------------------------------
   Signature visuelle du site. La couleur ENCODE le grade, elle ne décore pas.
   --raie-couleur est posée par un attribut data-grade / data-role, ou par le
   JS via setProperty quand la couleur vient de la base.
   =========================================================================== */

.raie {
  position: relative;
  padding-left: calc(var(--esp-4) + 3px);
}

.raie::before {
  content: '';
  position: absolute;
  left: 0;
  top: var(--esp-1);
  bottom: var(--esp-1);
  width: 3px;
  border-radius: 2px;
  background: var(--raie-couleur);
  box-shadow: 0 0 10px -2px var(--raie-couleur);
}

/* Variante pour une carte : la raie court sur toute la hauteur, collée au bord. */
.carte.raie {
  padding-left: calc(var(--esp-5) + 3px);
}

.carte.raie::before {
  top: 0;
  bottom: 0;
  border-radius: var(--rayon-m) 0 0 var(--rayon-m);
}

/* Variante pour une ligne de tableau. */
tr.raie > td:first-child {
  position: relative;
  padding-left: calc(var(--esp-4) + 3px);
}

tr.raie::before {
  display: none;
}

tr.raie > td:first-child::before {
  content: '';
  position: absolute;
  left: 0;
  top: 6px;
  bottom: 6px;
  width: 3px;
  border-radius: 2px;
  background: var(--raie-couleur);
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--esp-2);
  padding: 2px var(--esp-3);
  border: var(--bordure);
  border-radius: var(--rayon-plein);
  font-family: var(--police-mono);
  font-size: var(--taille-xs);
  letter-spacing: 0.06em;
  color: var(--texte-secondaire);
  white-space: nowrap;
}

/* Badge de grade : raie spectrale intégrée, jamais de fond coloré. */
.badge-grade {
  display: inline-flex;
  align-items: center;
  gap: var(--esp-2);
  padding: 3px var(--esp-3) 3px var(--esp-2);
  background: var(--nuit-haute);
  border: var(--bordure);
  border-radius: var(--rayon-s);
  font-family: var(--police-titre);
  font-size: var(--taille-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--texte-principal);
}

.badge-grade::before {
  content: '';
  width: 3px;
  height: 1.1em;
  flex: none;
  border-radius: 2px;
  background: var(--raie-couleur);
  box-shadow: 0 0 8px -2px var(--raie-couleur);
}

/* Badge posé à l'intérieur d'un élément qui porte déjà la raie du grade. */
.badge-grade--sans-raie::before {
  display: none;
}

.badge-grade__niveau {
  font-family: var(--police-mono);
  font-size: 0.6875rem;
  color: var(--texte-attenue);
  letter-spacing: 0;
}

/* Assignation des couleurs de raie. */
[data-grade='fondateur']      { --raie-couleur: var(--grade-fondateur); }
[data-grade='administrateur'] { --raie-couleur: var(--grade-administrateur); }
[data-grade='developpeur']    { --raie-couleur: var(--grade-developpeur); }
[data-grade='moderateur']     { --raie-couleur: var(--grade-moderateur); }
[data-grade='helpeur']        { --raie-couleur: var(--grade-helpeur); }

[data-role='whitelist'] { --raie-couleur: var(--role-whitelist); }
[data-role='vip']       { --raie-couleur: var(--role-vip); }
[data-role='membre']    { --raie-couleur: var(--role-membre); }


/* ===========================================================================
   12. COMPOSANT — CHAMP DE FORMULAIRE
   =========================================================================== */

.champ {
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
}

.champ__etiquette {
  font-size: var(--taille-s);
  font-weight: 500;
  color: var(--texte-secondaire);
}

.champ__saisie,
.champ__zone,
.champ__liste {
  width: 100%;
  min-height: 44px;
  padding: var(--esp-3) var(--esp-4);
  background: var(--nuit-spatiale);
  border: var(--bordure);
  border-radius: var(--rayon-s);
  color: var(--texte-principal);
  transition: border-color var(--transition), box-shadow var(--transition);
}

.champ__zone {
  min-height: 120px;
  resize: vertical;
  line-height: var(--interligne);
}

.champ__saisie::placeholder,
.champ__zone::placeholder {
  color: var(--texte-attenue);
}

.champ__saisie:hover,
.champ__zone:hover,
.champ__liste:hover {
  border-color: var(--bleu-electrique);
}

.champ__saisie:focus-visible,
.champ__zone:focus-visible,
.champ__liste:focus-visible {
  border-color: var(--bleu-electrique);
  box-shadow: var(--lueur-bleue);
}

.champ__aide {
  font-size: var(--taille-xs);
  color: var(--texte-attenue);
}

.champ__erreur {
  font-size: var(--taille-xs);
  color: var(--danger);
}

.champ--erreur .champ__saisie,
.champ--erreur .champ__zone {
  border-color: var(--danger);
}


/* ===========================================================================
   13. COMPOSANT — TABLEAU
   ---------------------------------------------------------------------------
   À 360 px un tableau ne tient pas : il défile horizontalement dans son
   propre conteneur, jamais la page.
   =========================================================================== */

.tableau-defilant {
  width: 100%;
  overflow-x: auto;
  border: var(--bordure);
  border-radius: var(--rayon-m);
  background: var(--nuit-elevee);
}

.tableau {
  width: 100%;
  min-width: 520px;
  border-collapse: collapse;
  font-size: var(--taille-s);
}

.tableau th,
.tableau td {
  padding: var(--esp-3) var(--esp-4);
  text-align: left;
  vertical-align: middle;
}

.tableau thead th {
  position: sticky;
  top: 0;
  background: var(--nuit-haute);
  font-family: var(--police-titre);
  font-size: var(--taille-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bleu-ciel);
  border-bottom: var(--bordure);
}

.tableau tbody tr + tr {
  border-top: var(--bordure);
}

.tableau tbody tr:hover {
  background: rgba(37, 99, 235, 0.07);
}

.tableau td.mono,
.tableau .cellule-id {
  font-family: var(--police-mono);
  font-size: var(--taille-xs);
  color: var(--texte-secondaire);
}


/* ===========================================================================
   14. COMPOSANT — PASTILLE D'ÉTAT, JAUGE, DONNÉES
   =========================================================================== */

.pastille {
  display: inline-flex;
  align-items: center;
  gap: var(--esp-2);
  font-size: var(--taille-s);
  color: var(--texte-secondaire);
}

.pastille::before {
  content: '';
  width: 8px;
  height: 8px;
  flex: none;
  border-radius: 50%;
  background: var(--texte-attenue);
  box-shadow: 0 0 0 3px rgba(124, 137, 168, 0.18);
}

.pastille[data-etat='en-ligne']::before {
  background: var(--succes);
  box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.2);
  animation: pulsation 2.4s ease-in-out infinite;
}

.pastille[data-etat='degrade']::before {
  background: var(--alerte);
  box-shadow: 0 0 0 3px rgba(251, 191, 36, 0.2);
}

.pastille[data-etat='hors-ligne']::before {
  background: var(--danger);
  box-shadow: 0 0 0 3px rgba(248, 113, 113, 0.2);
}

@keyframes pulsation {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}

.jauge {
  width: 100%;
  height: 6px;
  border-radius: var(--rayon-plein);
  background: var(--nuit-haute);
  overflow: hidden;
}

.jauge__barre {
  height: 100%;
  width: var(--jauge-remplissage, 0%);
  border-radius: inherit;
  background: linear-gradient(90deg, var(--bleu-electrique), var(--bleu-ciel));
  transition: width 600ms ease;
}

.donnee {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.donnee__valeur {
  font-family: var(--police-mono);
  font-size: var(--titre-s);
  font-variant-numeric: tabular-nums;
  color: var(--texte-principal);
}

.donnee__libelle {
  font-size: var(--taille-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--texte-attenue);
}


/* ===========================================================================
   15. PAGE D'ACCUEIL
   =========================================================================== */

.hero {
  display: flex;
  flex-direction: column;
  gap: var(--esp-5);
  padding-block: var(--esp-7) var(--esp-6);
}

.hero__titre {
  font-size: var(--titre-l);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.hero__accroche {
  font-size: var(--taille-l);
  color: var(--texte-secondaire);
  max-width: 54ch;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--esp-3);
}

.hero__reperes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--esp-5);
  padding-top: var(--esp-4);
  border-top: var(--bordure);
}

/* --- Annonce épinglée -----------------------------------------------------
   Pas de raie spectrale ici : la raie encode un GRADE, et une annonce n'en
   porte pas. La mise en avant passe par la bordure bleue, et l'accent rose
   est dépensé sur la seule pastille — un unique élément rose par écran.     */
.annonce-epinglee {
  border-color: var(--bleu-electrique);
}

.etiquette-epingle {
  display: inline-flex;
  align-items: center;
  gap: var(--esp-2);
  padding: 2px var(--esp-3);
  border-radius: var(--rayon-plein);
  background: var(--rose-electrique);
  color: var(--nuit-spatiale);   /* aplat rose, texte sombre — 5,2:1 */
  font-family: var(--police-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* --- Encart statut serveur ------------------------------------------------ */
.statut {
  gap: var(--esp-4);
}

.statut__entete {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--esp-3);
}

.statut__chiffres {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 120px), 1fr));
  gap: var(--esp-4);
}

.statut__demo {
  display: none;
  font-size: var(--taille-xs);
  color: var(--texte-attenue);
  padding: var(--esp-2) var(--esp-3);
  border: 1px dashed var(--nuit-bordure);
  border-radius: var(--rayon-s);
}

.statut[data-demo='true'] .statut__demo {
  display: block;
}

/* --- Cartes de section ----------------------------------------------------
   Cartes cliquables vers les 5 sections. Les pages arrivent au lot 2 : les
   liens pointent dès maintenant vers leurs URL définitives.                 */
.carte-section {
  text-decoration: none;
  color: inherit;
}

.carte-section .titre-carte {
  color: var(--texte-principal);
}

.carte-section:hover .titre-carte {
  color: var(--bleu-ciel);
}

.carte-section__fleche {
  display: inline-block;
  margin-left: var(--esp-2);
  font-family: var(--police-mono);
  color: var(--bleu-ciel);
  transition: transform var(--transition);
}

.carte-section:hover .carte-section__fleche {
  transform: translateX(3px);
}

@media (prefers-reduced-motion: reduce) {
  .carte-section:hover .carte-section__fleche {
    transform: none;
  }
}


/* ===========================================================================
   16. PAGES INTÉRIEURES (LOT 2)
   ---------------------------------------------------------------------------
   Serveur · Règlement · Équipe · Rejoindre · FAQ · Légal.
   Tout le contenu textuel de ces pages vient de la table contenu_site et est
   injecté par assets/js/contenu.js — le HTML ne contient que la structure.
   =========================================================================== */

/* --- En-tête de page ------------------------------------------------------ */
.entete-page {
  display: flex;
  flex-direction: column;
  gap: var(--esp-3);
  padding-block: var(--esp-7) var(--esp-5);
  margin-bottom: var(--esp-6);
  border-bottom: var(--bordure);
}

.entete-page__titre {
  font-size: var(--titre-m);
  letter-spacing: -0.01em;
}

/* --- Prose ----------------------------------------------------------------
   Rythme des paragraphes injectés. La couleur reste le texte secondaire :
   le texte principal est réservé aux titres et aux valeurs.               */
.prose {
  color: var(--texte-secondaire);
}

.prose p + p {
  margin-top: var(--esp-3);
}

.contenu-chapeau {
  margin-bottom: var(--esp-6);
}

.contenu-chapeau p {
  font-size: var(--taille-l);
  color: var(--texte-secondaire);
}

.contenu-chapeau p + p {
  margin-top: var(--esp-3);
}

/* --- Sections (page Serveur, page Légal) ---------------------------------- */
.bloc-contenu + .bloc-contenu {
  margin-top: var(--esp-6);
}

.bloc-contenu__titre {
  margin-bottom: var(--esp-3);
}

/* --- Articles numérotés (page Règlement) ---------------------------------- */
.article-regle__entete {
  display: flex;
  align-items: baseline;
  gap: var(--esp-3);
  margin-bottom: var(--esp-2);
}

.article-regle__numero {
  flex: none;
  font-size: var(--titre-s);
  font-weight: 500;
  color: var(--bleu-ciel);
}

/* --- Accordéon (page FAQ) -------------------------------------------------
   <details>/<summary> natifs : ouverture au clavier et à la souris sans une
   ligne de JavaScript, et le contenu reste trouvable par la recherche du
   navigateur.                                                              */
.accordeon {
  padding: 0;
  gap: 0;
  overflow: hidden;
}

.accordeon__question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--esp-4);
  padding: var(--esp-4) var(--esp-5);
  font-family: var(--police-titre);
  font-size: var(--titre-xs);
  font-weight: 600;
  color: var(--texte-principal);
  cursor: pointer;
  list-style: none;
}

.accordeon__question::-webkit-details-marker {
  display: none;
}

.accordeon__question:hover {
  color: var(--bleu-ciel);
}

.accordeon__marque {
  flex: none;
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  border: var(--bordure);
  border-radius: var(--rayon-s);
  font-family: var(--police-mono);
  color: var(--bleu-ciel);
  transition: transform var(--transition), border-color var(--transition);
}

.accordeon[open] .accordeon__marque {
  transform: rotate(45deg);
  border-color: var(--bleu-electrique);
}

.accordeon__reponse {
  padding: 0 var(--esp-5) var(--esp-5);
}

/* --- Étapes numérotées (page Rejoindre) ----------------------------------- */
.etapes {
  display: flex;
  flex-direction: column;
  gap: var(--esp-4);
}

.etape {
  display: flex;
  gap: var(--esp-4);
  padding: var(--esp-5);
  background: var(--nuit-elevee);
  border: var(--bordure);
  border-radius: var(--rayon-m);
  box-shadow: var(--ombre-carte);
}

.etape__numero {
  flex: none;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border: 1px solid var(--bleu-electrique);
  border-radius: 50%;
  font-size: var(--taille-s);
  color: var(--bleu-ciel);
}

.etape__corps {
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
  min-width: 0;
}

/* --- Fiches staff (page Équipe) -------------------------------------------
   La raie spectrale porte la couleur du grade, posée par equipe.js depuis
   grades.couleur. La couleur ENCODE le grade, elle ne décore pas.          */
.groupe-grade + .groupe-grade {
  margin-top: var(--esp-7);
}

/* auto-fill et non auto-fit : un grade à un seul membre garde une fiche de
   taille normale au lieu de s'étirer sur toute la largeur. Les fiches ont
   ainsi la même largeur d'un grade à l'autre. */
.liste-staff {
  list-style: none;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
}

.carte.raie.fiche-staff {
  flex-direction: row;
  align-items: center;
  gap: var(--esp-4);
  padding: var(--esp-4);
  padding-left: calc(var(--esp-4) + 3px);
}

.fiche-staff__portrait {
  flex: none;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--nuit-haute);
  border: var(--bordure);
  border-radius: 50%;
  font-family: var(--police-titre);
  font-size: var(--taille-s);
  font-weight: 600;
  color: var(--bleu-ciel);
}

.fiche-staff__portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.fiche-staff__infos {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--esp-2);
  min-width: 0;
}

.fiche-staff__pseudo {
  font-family: var(--police-titre);
  font-size: var(--titre-xs);
  font-weight: 600;
  color: var(--texte-principal);
  overflow-wrap: anywhere;
}

/* --- États vides ----------------------------------------------------------
   Une page sans données dit pourquoi, elle ne reste pas blanche.          */
.etat-vide {
  padding: var(--esp-5);
  border: 1px dashed var(--nuit-bordure);
  border-radius: var(--rayon-m);
  color: var(--texte-attenue);
  text-align: center;
}

.etat-vide-carte {
  align-items: flex-start;
}


/* ===========================================================================
   17. CONNEXION ET PANEL (LOT 3)
   =========================================================================== */

.conteneur--etroit {
  max-width: 520px;
}

.connexion {
  gap: var(--esp-4);
  margin-top: var(--esp-6);
}

/* Bandeau d'avertissement — mode de test, maintenance.
   Ambre et non rose : le rose reste l'accent rare, il n'est pas un signal. */
.bandeau-alerte {
  padding: var(--esp-3) var(--esp-4);
  border: 1px solid rgba(251, 191, 36, 0.35);
  border-left: 3px solid var(--alerte);
  border-radius: var(--rayon-s);
  background: rgba(251, 191, 36, 0.08);
  color: var(--texte-principal);
  font-size: var(--taille-s);
}

.liste-permissions {
  display: flex;
  flex-direction: column;
  gap: var(--esp-1);
}

.puce-permission {
  font-size: var(--taille-xs);
  color: var(--texte-secondaire);
  padding-left: var(--esp-3);
  border-left: 2px solid var(--nuit-bordure);
  overflow-wrap: anywhere;
}


/* ---------------------------------------------------------------------------
   Bannière de démonstration
   ---------------------------------------------------------------------------
   Seule entorse assumée à la règle « un seul élément rose par écran » : ici la
   couleur n'orne pas, elle alerte. Texte sombre sur aplat rose = 5,2:1, AA
   tenu. Non fermable, fixée, au-dessus de tout le reste.
   Elle disparaît avec DEMO_MODE.
   --------------------------------------------------------------------------- */

.banniere-demo {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  padding: var(--esp-2) var(--gouttiere);
  background: var(--rose-electrique);
  color: var(--nuit-spatiale);
  font-family: var(--police-titre);
  font-size: var(--taille-s);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-align: center;
  text-transform: uppercase;
}

/* Le contenu descend d'autant, et l'en-tête collant se cale sous la bannière.
   --hauteur-banniere-demo est MESURÉE par panel-noyau.js et posée sur body :
   la bannière tient sur une ligne en grand écran et jusqu'à trois à 360 px,
   aucune valeur en dur ne peut couvrir les deux cas. Le repli ne sert que
   pendant la frame précédant la mesure. */
body.demo {
  padding-top: var(--hauteur-banniere-demo, 40px);
}

body.demo .panel-entete {
  top: var(--hauteur-banniere-demo, 40px);
}

body.demo .panel-nav__liste {
  top: calc(var(--hauteur-banniere-demo, 40px) + var(--hauteur-entete) + var(--esp-4));
}


/* ---------------------------------------------------------------------------
   Coquille du panel (LOT 4)
   ---------------------------------------------------------------------------
   Pas de fond nébuleuse ici, volontairement. La règle de la direction
   artistique est de tester la lisibilité sur le contenu le plus dense : les
   tableaux du panel LE sont. Un fond uni leur laisse tout le contraste.
   --------------------------------------------------------------------------- */

body.panel {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto auto minmax(0, 1fr);
  min-height: 100vh;
  background: var(--nuit-spatiale);
}

.panel-entete {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(10, 14, 31, 0.92);
  backdrop-filter: blur(14px);
  border-bottom: var(--bordure);
}

.panel-entete__interieur {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--esp-3);
  min-height: var(--hauteur-entete);
  padding-inline: var(--gouttiere);
}

.panel-entete__etiquette {
  font-family: var(--police-mono);
  font-size: var(--taille-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--bleu-ciel);
  border: var(--bordure);
  border-radius: var(--rayon-plein);
  padding: 1px var(--esp-2);
}

.panel-entete__identite {
  display: flex;
  align-items: center;
  gap: var(--esp-2);
  margin-left: auto;
}

.panel-entete__pseudo {
  font-family: var(--police-titre);
  font-weight: 600;
  font-size: var(--taille-s);
}

/* Navigation : bande défilante en mobile, colonne fixe en grand écran. */
.panel-nav {
  border-bottom: var(--bordure);
  background: rgba(20, 26, 51, 0.5);
  overflow-x: auto;
}

.panel-nav__liste {
  display: flex;
  gap: var(--esp-1);
  padding: var(--esp-2) var(--gouttiere);
  white-space: nowrap;
}

.panel-nav__lien {
  display: block;
  padding: var(--esp-2) var(--esp-3);
  border-radius: var(--rayon-s);
  border-left: 3px solid transparent;
  color: var(--texte-secondaire);
  text-decoration: none;
  font-size: var(--taille-s);
}

.panel-nav__lien:hover {
  background: var(--nuit-haute);
  color: var(--texte-principal);
}

.panel-nav__lien[aria-current='page'] {
  background: var(--nuit-haute);
  color: var(--texte-principal);
  border-left-color: var(--bleu-electrique);
}

.panel-bandeau {
  margin-bottom: var(--esp-5);
}

/* Notifications */
.notifications {
  position: fixed;
  right: var(--esp-4);
  bottom: var(--esp-4);
  z-index: 80;
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
  max-width: min(92vw, 380px);
}

.notification {
  padding: var(--esp-3) var(--esp-4);
  border: var(--bordure);
  border-left: 3px solid var(--bleu-electrique);
  border-radius: var(--rayon-s);
  background: var(--nuit-elevee);
  box-shadow: var(--ombre-carte);
  font-size: var(--taille-s);
}

.notification--succes { border-left-color: var(--succes); }
.notification--erreur { border-left-color: var(--danger); }

/* Barre d'outils au-dessus des tableaux */
.barre-outils {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--esp-3);
  margin-bottom: var(--esp-4);
}

.barre-outils__espace { margin-left: auto; }

/* Champs compacts dans les tableaux */
.champ--inline {
  display: flex;
  align-items: center;
  gap: var(--esp-2);
}

.champ__saisie--compact,
.champ__liste--compact {
  min-height: 36px;
  padding: var(--esp-2) var(--esp-3);
  font-size: var(--taille-s);
}

.champ__saisie--nombre {
  width: 5.5rem;
  text-align: right;
  font-family: var(--police-mono);
}

.bouton--compact {
  min-height: 36px;
  padding: var(--esp-2) var(--esp-3);
  font-size: var(--taille-xs);
}

.bouton--danger {
  background: transparent;
  border-color: rgba(248, 113, 113, 0.4);
  color: var(--danger);
}

.bouton--danger:hover {
  background: rgba(248, 113, 113, 0.12);
  color: var(--danger);
}

/* Marqueur d'état dans les tableaux */
.etiquette {
  display: inline-block;
  padding: 1px var(--esp-2);
  border-radius: var(--rayon-plein);
  border: var(--bordure);
  font-family: var(--police-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--texte-attenue);
}

.etiquette--actif   { color: var(--succes); border-color: rgba(52, 211, 153, 0.4); }
.etiquette--inactif { color: var(--danger); border-color: rgba(248, 113, 113, 0.4); }
.etiquette--verrou  { color: var(--alerte); border-color: rgba(251, 191, 36, 0.4); }
.etiquette--prive   { color: var(--alerte); border-color: rgba(251, 191, 36, 0.4); }

/* Zone d'édition dépliable sous une ligne */
.editeur {
  display: flex;
  flex-direction: column;
  gap: var(--esp-3);
  padding: var(--esp-4);
  border: var(--bordure);
  border-left: 3px solid var(--bleu-electrique);
  border-radius: var(--rayon-s);
  background: var(--nuit-spatiale);
}

.editeur__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--esp-2);
}

@media (min-width: 900px) {
  body.panel {
    grid-template-columns: 240px minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
  }

  .panel-entete { grid-column: 1 / -1; }

  .panel-nav {
    grid-row: 2;
    border-bottom: 0;
    border-right: var(--bordure);
    overflow-x: visible;
  }

  .panel-nav__liste {
    position: sticky;
    top: calc(var(--hauteur-entete) + var(--esp-4));
    flex-direction: column;
    white-space: normal;
    padding: var(--esp-4) var(--esp-3);
  }

  body.panel > main { grid-row: 2; }
}


/* ===========================================================================
   18. RESPONSIVE
   =========================================================================== */

@media (min-width: 560px) {
  .marque__mention {
    display: inline;
  }

  .bouton--large {
    width: auto;
  }
}

@media (min-width: 900px) {
  .bascule-nav {
    display: none;
  }

  .nav,
  .nav.est-ouverte {
    display: flex;
    position: static;
    align-items: center;
    gap: var(--esp-4);
    padding: 0;
    background: transparent;
    border: 0;
    box-shadow: none;
  }

  .nav__liste {
    flex-direction: row;
    gap: var(--esp-1);
  }

  .nav__lien {
    padding: var(--esp-2) var(--esp-3);
    border-left: 0;
    border-bottom: 2px solid transparent;
    border-radius: var(--rayon-s) var(--rayon-s) 0 0;
  }

  .nav__lien[aria-current='page'] {
    border-left: 0;
    border-bottom-color: var(--bleu-electrique);
    background: transparent;
  }

  .nav__actions {
    margin: 0;
    padding: 0;
    border: 0;
  }

  .pied__interieur {
    grid-template-columns: 2fr 1fr 1fr;
  }
}


/* ===========================================================================
   19. MOUVEMENT RÉDUIT
   =========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .bouton:active {
    transform: none;
  }

  .carte--liante:hover {
    transform: none;
  }
}
