/* =========================================================================
   style.css — L'apparence du panel (thème Or de Luxury Studio : noir + or).

   Les "variables CSS" (--nom) en haut permettent de changer toutes les
   couleurs du panel d'un seul endroit. Change --accent et tout le panel
   change de couleur.

   POURQUOI un noir "chaud" (#0c0c0e) et pas un noir bleuté ? Parce que l'or
   est une couleur chaude : posé sur un fond froid (bleuté), il paraît sale et
   verdâtre. Un fond légèrement chaud le fait ressortir comme du vrai métal.
   ========================================================================= */

:root {
  --bg: #0c0c0e;
  --bg-soft: #141416;
  --surface: #1a1a1d;
  --surface-hover: #232327;
  --border: #2e2e33;

  --text: #f0ece4;
  --text-muted: #8f8a80;

  --accent: #d4af37;
  --accent-hover: #c19b2c;
  /* --accent-soft : de l'or très transparent. Sert de fond aux pastilles et
     icônes — on ne peut pas mettre de l'or plein derrière du texte, ça
     éblouit. Une couche à 14 % suffit à "teinter" sans agresser. */
  --accent-soft: rgba(212, 175, 55, 0.14);

  --success: #22c55e;
  --danger: #ef4444;
  --danger-hover: #dc2626;
  --warning: #f59e0b;

  --radius: 10px;
  --font: "Segoe UI", system-ui, -apple-system, sans-serif;
  --mono: "Cascadia Code", "Consolas", "Courier New", monospace;
}

/* Le reset : les navigateurs ont des marges par défaut différentes.
   On repart de zéro pour que le rendu soit identique partout. */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box; /* la largeur inclut les bordures : bien plus intuitif */
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  min-height: 100vh;
}

a {
  color: var(--accent);
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

/* ---------------------------------------------------------------- */
/* Barre du haut                                                     */
/* ---------------------------------------------------------------- */

.topbar {
  background: var(--bg-soft);
  border-bottom: 1px solid var(--border);
  padding: 0 24px;
  height: 60px;
  display: flex;
  align-items: center;
  gap: 24px;
  position: sticky; /* la barre reste visible quand on descend */
  top: 0;
  z-index: 50;
}

.topbar .brand {
  font-weight: 700;
  font-size: 18px;
  color: var(--text);
  letter-spacing: 0.5px;
}
.topbar .brand span {
  color: var(--accent);
}

.topbar nav {
  display: flex;
  gap: 4px;
  flex: 1; /* pousse le bloc utilisateur tout à droite */
}

.topbar nav a {
  color: var(--text-muted);
  padding: 8px 14px;
  border-radius: var(--radius);
  font-size: 14px;
  font-weight: 500;
}
.topbar nav a:hover {
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
}
.topbar nav a.active {
  background: var(--surface);
  color: var(--accent);
}

.topbar .user {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 14px;
  color: var(--text-muted);
}

/* ---------------------------------------------------------------- */
/* Structure                                                         */
/* ---------------------------------------------------------------- */

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 28px 24px 60px;
}

.page-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 22px;
  flex-wrap: wrap;
}

.page-head h1 {
  font-size: 24px;
  font-weight: 650;
}

.page-head .subtitle {
  color: var(--text-muted);
  font-size: 14px;
  margin-top: 2px;
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
  /* Transition douce si la bordure ou l'ombre change (état de survol, focus…). */
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}

.card + .card {
  margin-top: 16px;
}

.card h2 {
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 14px;
}

/* ---------------------------------------------------------------- */
/* Boutons                                                           */
/* ---------------------------------------------------------------- */

.btn {
  background: var(--surface-hover);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 14px;
  font-size: 14px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  /* On liste ici TOUTES les propriétés susceptibles d'être animées. Le
     déplacement (transform) et l'ombre ne prennent réellement une valeur que
     dans le bloc @media (prefers-reduced-motion: no-preference) plus bas : les
     personnes qui coupent les animations n'auront donc AUCUN mouvement, juste le
     changement de couleur de fond, lui inoffensif. */
  transition: background 0.15s, opacity 0.15s, transform 0.12s ease, box-shadow 0.15s ease,
    border-color 0.15s ease;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
}
.btn:hover:not(:disabled) {
  background: var(--border);
}
.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* POURQUOI du texte SOMBRE sur le bouton or, et pas blanc ?
   L'or est une couleur CLAIRE. Du blanc sur de l'or, c'est du clair sur du
   clair : le contraste est d'environ 1.8:1 alors qu'il en faut 4.5:1 pour
   être lisible. On inverse donc : texte noir sur fond or (~9:1). C'est le
   piège classique quand on passe d'une palette bleue (foncée) à une dorée. */
.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #0c0c0e;
  font-weight: 600; /* le gras compense le fond clair, le texte reste net */
}
.btn-primary:hover:not(:disabled) {
  background: var(--accent-hover);
  color: #0c0c0e; /* on le redit : sinon .btn:hover pourrait reprendre la main */
}

.btn-success {
  background: var(--success);
  border-color: var(--success);
  color: #04210f;
}
.btn-success:hover:not(:disabled) {
  opacity: 0.88;
  background: var(--success);
}

.btn-danger {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
}
.btn-danger:hover:not(:disabled) {
  background: var(--danger-hover);
}

.btn-sm {
  padding: 5px 10px;
  font-size: 13px;
}

.btn-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

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

.field {
  margin-bottom: 14px;
}

.field label {
  display: block;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  margin-bottom: 6px;
}

.field .hint {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 5px;
  line-height: 1.45;
}

input,
select,
textarea {
  width: 100%;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  padding: 9px 12px;
  font-size: 14px;
  font-family: inherit;
}

input:focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--accent);
}

/* Cases à cocher et boutons radio : on force l'accent en OR. Sans cette règle,
   les navigateurs (Chrome, Edge, Firefox) utilisent leur accent par défaut, qui
   est BLEU — seule vraie rupture avec le thème doré (visible dans la modale des
   permissions des sous-utilisateurs). Bonus lisibilité : quand accent-color est
   une couleur claire comme l'or, le navigateur choisit tout seul une coche
   SOMBRE contrastée — donc pas de problème de blanc-sur-or. */
input[type="checkbox"],
input[type="radio"] {
  accent-color: var(--accent);
}

textarea {
  resize: vertical;
  min-height: 80px;
  font-family: var(--mono);
  font-size: 13px;
}

.grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

/* ---------------------------------------------------------------- */
/* Badges d'état                                                     */
/* ---------------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

/* Le point coloré devant le texte du badge */
.badge::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
}

/* Les fonds sont des rgba() codées en dur : ce sont les mêmes couleurs que les
   variables juste au-dessus, mais rendues transparentes à 14 %. On ne peut pas
   écrire rgba(var(--success), 0.14) en CSS classique, d'où la répétition.
   Les valeurs grises suivent le NOUVEAU --text-muted (#8f8a80 = 143,138,128),
   sinon les badges "éteint"/"inconnu" resteraient bleutés sur fond noir. */
.badge-running {
  background: rgba(34, 197, 94, 0.14);
  color: var(--success);
}
.badge-stopped {
  background: rgba(143, 138, 128, 0.14);
  color: var(--text-muted);
}
.badge-installing {
  background: rgba(245, 158, 11, 0.14);
  color: var(--warning);
}
.badge-failed,
.badge-missing {
  background: rgba(239, 68, 68, 0.14);
  color: var(--danger);
}
.badge-unknown {
  background: rgba(143, 138, 128, 0.14);
  color: var(--text-muted);
}

/* Petite animation pour l'état "installation en cours" */
.badge-installing::before {
  animation: pulse 1.2s ease-in-out infinite;
}
@keyframes pulse {
  50% {
    opacity: 0.25;
  }
}

/* ---------------------------------------------------------------- */
/* Liste des serveurs                                                */
/* ---------------------------------------------------------------- */

.server-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 14px;
}

.server-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
  cursor: pointer;
  transition: border-color 0.15s, transform 0.15s, box-shadow 0.15s;
}
/* Le changement de couleur de bordure reste TOUJOURS actif : c'est un simple
   retour visuel, sans mouvement. Le soulèvement (translateY) et l'ombre, eux,
   sont du MOUVEMENT : on les réserve au bloc prefers-reduced-motion plus bas. */
.server-card:hover {
  border-color: var(--accent);
}

.server-card .head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
}

.server-card .name {
  font-weight: 600;
  font-size: 16px;
}

/* Le TYPE du serveur, sous son nom (« Serveur Nova Life »).
   Volontairement discret : plus petit et en gris, pour qu'il informe sans
   voler la vedette au nom. */
.server-card .server-type {
  font-size: 12.5px;
  color: var(--text-muted);
  margin-top: 2px;
}

.server-card .meta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  font-size: 12.5px;
  color: var(--text-muted);
}

.server-card .meta b {
  color: var(--text);
  font-weight: 500;
}

/* ---------------------------------------------------------------- */
/* Onglets                                                           */
/* ---------------------------------------------------------------- */

.tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 18px;
  /* Sur téléphone, les 8 onglets sont plus larges que l'écran. Sans ceci, la
     barre pousserait TOUTE la page vers la droite (défilement horizontal
     général, très désagréable). overflow-x: auto enferme le débordement DANS la
     barre : elle défile toute seule, la page reste immobile.
     -webkit-overflow-scrolling: touch donne à ce défilement l'inertie d'iOS. */
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.tabs button {
  position: relative; /* repère pour placer le soulignement ::after */
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--text-muted);
  padding: 10px 16px;
  font-size: 14px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  margin-bottom: -1px; /* la bordure active recouvre celle du conteneur */
  transition: color 0.15s ease;
  /* Compléments indispensables au défilement ci-dessus : sans eux, flexbox
     préférerait rétrécir les boutons (et couper « Bases de données » sur deux
     lignes) plutôt que de laisser la barre déborder. flex-shrink: 0 interdit ce
     rétrécissement et white-space: nowrap garde chaque libellé sur une ligne :
     la barre déborde alors franchement… et devient donc défilable. */
  flex-shrink: 0;
  white-space: nowrap;
}
.tabs button:hover {
  color: var(--text);
}
.tabs button.active {
  color: var(--accent);
}

/* Le soulignement or de l'onglet actif. On le dessine avec un ::after (et non
   plus la bordure du bouton) pour pouvoir l'ANIMER : il grandit du centre vers
   les bords quand on change d'onglet. scaleX(0) = invisible, scaleX(1) = plein. */
.tabs button::after {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: -1px;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: center;
}
.tabs button.active::after {
  transform: scaleX(1);
}

/* .hidden est utilisé par le JS pour montrer/cacher les onglets */
.hidden {
  display: none !important;
}

/* ---------------------------------------------------------------- */
/* Console                                                           */
/* ---------------------------------------------------------------- */

/* Le fond de la console est encore plus noir que --bg : c'est volontaire, ça
   creuse la zone et imite un vrai terminal. #060607 est un noir neutre-chaud,
   raccord avec le reste (l'ancien #05080f tirait sur le bleu). */
.console {
  background: #060607;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px;
  height: 460px;
  overflow-y: auto;
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.55;
  /* pre-wrap : garde les retours à la ligne du serveur ET coupe les lignes trop longues.
     white-space: pre seul ferait défiler horizontalement à l'infini. */
  white-space: pre-wrap;
  word-break: break-word;
  /* Gris très légèrement crème (et non bleuté) : les logs se lisent des heures,
     un blanc pur fatiguerait les yeux. */
  color: #d8d3ca;
}

.console-line {
  /* Empêche une ligne sans espaces (une URL, une stacktrace) de déborder */
  overflow-wrap: anywhere;
}

.console-input {
  display: flex;
  gap: 8px;
  margin-top: 10px;
}

.console-input input {
  font-family: var(--mono);
  font-size: 13px;
}

/* ---------------------------------------------------------------- */
/* Page serveur : console à gauche, statistiques à droite            */
/* ---------------------------------------------------------------- */

/* La grille principale de l'onglet Console, façon Pterodactyl.
   "1fr 300px" = la console prend TOUT l'espace restant, la colonne de droite
   garde 300px fixes. POURQUOI fixe à droite ? Parce que les valeurs (CPU,
   RAM…) ont une largeur à peu près constante : si la colonne était souple,
   elle changerait de largeur à chaque mise à jour.
   minmax(0, 1fr) et non 1fr : sans ça, une longue ligne de log sans espace
   pousserait la colonne au-delà de l'écran (piège classique des grilles). */
.server-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 16px;
  align-items: start;
}

/* La colonne de droite : les cartes empilées les unes sous les autres */
.server-side {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* En dessous de 1000px (tablette, téléphone), 300px de stats à côté de la
   console rendraient les deux illisibles. On repasse donc en UNE colonne :
   les stats glissent naturellement sous la console. */
@media (max-width: 1000px) {
  .server-layout {
    grid-template-columns: 1fr;
  }
}

/* Une ligne de statistique : [icône] [libellé + valeur] */
.stat-card {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
/* Au survol, un liseré or très discret : la carte « répond » sans bouger. */
.stat-card:hover {
  border-color: rgba(212, 175, 55, 0.35);
}

.stat-card .icon {
  width: 38px;
  height: 38px;
  flex-shrink: 0; /* sinon l'icône s'écrase quand la valeur est longue */
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-soft);
  border-radius: 8px;
  color: var(--accent);
  font-size: 18px;
}

/* min-width: 0 permet au texte de se couper au lieu de faire déborder la
   carte : un enfant de flex refuse de rétrécir sous sa taille naturelle. */
.stat-card .body {
  min-width: 0;
}

.stat-card .label {
  font-size: 11px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.stat-card .value {
  font-size: 17px;
  font-weight: 700;
  /* INDISPENSABLE ici : tabular-nums force tous les chiffres à occuper la même
     largeur. Sans ça, un "1" plus étroit qu'un "8" fait sautiller la valeur à
     chaque rafraîchissement (1×/seconde) et ça clignote désagréablement. */
  font-variant-numeric: tabular-nums;
}

/* Le " / 8 GiB" collé après la valeur : présent mais discret */
.stat-card .value small {
  font-size: 12px;
  font-weight: 400;
  color: var(--text-muted);
}

/* ---------------------------------------------------------------- */
/* Graphiques (CPU / RAM / réseau)                                   */
/* ---------------------------------------------------------------- */

/* auto-fit + minmax(260px, 1fr) : 3 graphiques côte à côte s'il y a la place,
   sinon le navigateur en replie automatiquement. En dessous de 260px de large
   une courbe devient illisible — c'est le seuil qu'on lui donne. */
.charts-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 12px;
  margin-top: 16px;
}

.chart-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px;
}

.chart-title {
  font-size: 13px;
  color: var(--text-muted);
  margin-bottom: 8px;
}

/* display: block est obligatoire : un <canvas> est "inline" par défaut, ce qui
   lui ajoute quelques pixels fantômes en bas (la place de la ligne de texte).
   La hauteur fixe évite que le graphique change de taille en cours de route. */
.chart-box canvas {
  width: 100%;
  height: 140px;
  display: block;
}

/* Sur téléphone, une colonne unique : les 3 graphiques s'empilent. */
@media (max-width: 640px) {
  .charts-row {
    grid-template-columns: 1fr;
  }
}

/* ---------------------------------------------------------------- */
/* Tableaux (fichiers, utilisateurs)                                 */
/* ---------------------------------------------------------------- */

/* Un tableau ne rétrécit pas en dessous de la largeur de ses colonnes.
   POURQUOI ce conteneur : sans lui, c'est la PAGE ENTIÈRE qui défile de
   gauche à droite sur téléphone. Ici, seul le tableau défile, dans sa carte. */
.table-wrap {
  overflow-x: auto;
  /* Défilement à l'inertie sous iOS, comme le reste du système */
  -webkit-overflow-scrolling: touch;
}

.table-wrap table {
  min-width: 620px; /* somme des colonnes fixes + place pour le nom */
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

th {
  text-align: left;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}

td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

tbody tr:hover {
  background: var(--surface-hover);
}

.file-name {
  display: flex;
  align-items: center;
  gap: 9px;
  cursor: pointer;
  font-weight: 500;
}
.file-name:hover {
  color: var(--accent);
}

.file-icon {
  width: 18px;
  text-align: center;
  flex-shrink: 0;
}

.breadcrumb {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 13.5px;
  margin-bottom: 14px;
  color: var(--text-muted);
  font-family: var(--mono);
}

.breadcrumb a {
  cursor: pointer;
}

/* ---------------------------------------------------------------- */
/* Fenêtres modales                                                  */
/* ---------------------------------------------------------------- */

.modal-backdrop {
  position: fixed;
  inset: 0; /* raccourci pour top/right/bottom/left: 0 */
  background: rgba(0, 0, 0, 0.65);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 100;
}

.modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 24px;
  width: 100%;
  max-width: 540px;
  max-height: 88vh;
  overflow-y: auto;
}

.modal h2 {
  margin-bottom: 16px;
  font-size: 18px;
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 20px;
}

/* ---------------------------------------------------------------- */
/* Notifications (toasts)                                            */
/* ---------------------------------------------------------------- */

#toasts {
  position: fixed;
  bottom: 20px;
  right: 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 200;
  max-width: 380px;
}

.toast {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  padding: 12px 16px;
  font-size: 14px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  /* L'animation d'entrée (glissement) est dans le bloc prefers-reduced-motion :
     sans mouvement demandé, le toast apparaît simplement, sans glisser. */
}

.toast.error {
  border-left-color: var(--danger);
}
.toast.success {
  border-left-color: var(--success);
}

@keyframes slide-in {
  from {
    opacity: 0;
    transform: translateX(20px);
  }
}

/* ---------------------------------------------------------------- */
/* Page de connexion                                                 */
/* ---------------------------------------------------------------- */

.login-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.login-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 34px;
  width: 100%;
  max-width: 400px;
}

.login-box .logo {
  text-align: center;
  font-size: 26px;
  font-weight: 700;
  margin-bottom: 6px;
}
.login-box .logo span {
  color: var(--accent);
}

.login-box .tagline {
  text-align: center;
  color: var(--text-muted);
  font-size: 13.5px;
  margin-bottom: 26px;
}

.error-box {
  background: rgba(239, 68, 68, 0.1);
  border: 1px solid rgba(239, 68, 68, 0.3);
  color: #fca5a5;
  border-radius: 8px;
  padding: 10px 12px;
  font-size: 13.5px;
  margin-bottom: 14px;
}

.empty {
  text-align: center;
  padding: 50px 20px;
  color: var(--text-muted);
}

.empty .big {
  font-size: 40px;
  margin-bottom: 10px;
  opacity: 0.5;
}

/* ---------------------------------------------------------------- */
/* Écrans étroits (téléphone)                                        */
/* ---------------------------------------------------------------- */

@media (max-width: 640px) {
  .grid-2 {
    grid-template-columns: 1fr;
  }
  .topbar {
    padding: 0 14px;
    gap: 12px;
  }
  .topbar .user span {
    display: none; /* on cache le nom, on garde le bouton déconnexion */
  }
  .container {
    padding: 18px 14px 40px;
  }
}

/* ---------------------------------------------------------------- */
/* Menu déroulant des fichiers (le bouton « ⋮ »)                     */
/* ---------------------------------------------------------------- */

/* La cellule d'actions d'une ligne de fichier : alignée à droite. */
.file-actions {
  text-align: right;
  white-space: nowrap;
}

/* Le bouton à trois points : compact et discret. */
.file-menu-btn {
  padding: 4px 9px;
  font-size: 17px;
  line-height: 1;
}

/* Le menu lui-même. position: fixed + coordonnées calculées en JS : il flotte
   PAR-DESSUS toute la page, donc il n'est jamais rogné par le cadre défilant du
   tableau (overflow), et le JS l'empêche de déborder du bord droit de l'écran. */
.file-menu {
  position: fixed;
  z-index: 150;
  min-width: 168px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 6px;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.5);
}

.file-menu-item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  color: var(--text);
  font-family: inherit;
  font-size: 14px;
  padding: 8px 10px;
  border-radius: 7px;
  cursor: pointer;
  transition: background 0.12s ease;
}
.file-menu-item:hover {
  background: var(--surface-hover);
}
/* L'entrée « Supprimer » en rouge : l'œil comprend tout de suite que c'est
   l'action destructive, celle sur laquelle on ne clique pas par mégarde. */
.file-menu-item.danger {
  color: var(--danger);
}
.file-menu-item.danger:hover {
  background: rgba(239, 68, 68, 0.12);
}

/* ---------------------------------------------------------------- */
/* Réglages : valeurs en lecture seule + infos de debug             */
/* ---------------------------------------------------------------- */

/* Une valeur qu'on peut lire (et copier) mais pas modifier : ressemble à un
   champ, mais sans être un <input>. Police à chasse fixe pour les adresses. */
.readonly-value {
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 9px 12px;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text);
  word-break: break-all;
}

.debug-list {
  display: grid;
  gap: 12px;
}
.debug-list > div {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.debug-list .k {
  font-size: 11px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.debug-list .v {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--text);
  word-break: break-all;
}

/* ---------------------------------------------------------------- */
/* Petit bouton d'action sur une carte (ex : renommer un serveur)    */
/* ---------------------------------------------------------------- */

.head-right {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0; /* le bloc badge + crayon ne s'écrase pas si le nom est long */
}
/* Le crayon reste effacé (gris, sans bordure) et ne s'allume en or qu'au
   survol : présent mais discret, il n'encombre pas la carte. */
.card-action {
  background: none;
  border: 1px solid transparent;
  color: var(--text-muted);
  border-radius: 7px;
  padding: 3px 7px;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.card-action:hover {
  background: var(--surface-hover);
  color: var(--accent);
  border-color: var(--border);
}

/* ---------------------------------------------------------------- */
/* Indicateur de chargement réutilisable (.spinner)                 */
/* ---------------------------------------------------------------- */

/* Un anneau : bordure grise, sommet doré. Sans animation, il reste un joli
   rond fixe au sommet or ; l'animation (rotation) est ajoutée plus bas,
   uniquement si la personne n'a pas coupé les animations. */
.spinner {
  display: inline-block;
  width: 20px;
  height: 20px;
  border: 2.5px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  vertical-align: middle;
}

/* Une ligne « rond qui tourne + texte » pour remplir un onglet en chargement. */
.loading-row {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--text-muted);
  font-size: 14px;
  padding: 6px 0;
}

/* ================================================================ */
/* Animations « de confort »                                        */
/*                                                                  */
/* ⚠️ ACCESSIBILITÉ — tout ce qui BOUGE (déplacement, zoom, rotation, */
/* pulsation) est enfermé dans ce bloc. « prefers-reduced-motion:    */
/* no-preference » veut dire « la personne n'a PAS demandé de réduire */
/* les animations » : c'est seulement dans ce cas qu'on anime.       */
/*                                                                  */
/* Certaines personnes activent « Réduire les animations » dans leur */
/* système (mal des transports, troubles vestibulaires, migraines) : */
/* pour elles, ce bloc ne s'applique pas, l'interface reste STABLE — */
/* seuls les changements de couleur demeurent, eux inoffensifs. Ce   */
/* n'est pas un détail cosmétique : du mouvement non désiré peut      */
/* réellement provoquer une gêne physique. On respecte donc leur     */
/* réglage plutôt que de leur imposer nos effets.                    */
/* ================================================================ */

@media (prefers-reduced-motion: no-preference) {
  /* Boutons : léger soulèvement + ombre au survol, enfoncement au clic. */
  .btn:hover:not(:disabled) {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.28);
  }
  .btn:active:not(:disabled) {
    transform: translateY(0);
    box-shadow: none;
  }
  /* Le bouton or mérite une ombre dorée très subtile au survol. */
  .btn-primary:hover:not(:disabled) {
    box-shadow: 0 4px 16px rgba(212, 175, 55, 0.3);
  }
  .btn-danger:hover:not(:disabled) {
    box-shadow: 0 4px 14px rgba(239, 68, 68, 0.28);
  }

  /* Carte de serveur : elle se soulève et prend une ombre au survol. */
  .server-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 26px rgba(0, 0, 0, 0.35);
  }

  /* Onglets : le soulignement or grandit en douceur d'un onglet à l'autre. */
  .tabs button::after {
    transition: transform 0.25s ease;
  }

  /* Le point « en ligne » respire doucement (petit halo vert qui s'estompe). */
  .badge-running::before {
    animation: dot-pulse 2s ease-in-out infinite;
  }

  /* Menus, modales et toasts apparaissent en fondu + léger glissement, au lieu
     de surgir d'un coup. */
  .file-menu {
    animation: menu-pop 0.13s ease-out;
  }
  .modal-backdrop {
    animation: backdrop-fade 0.18s ease-out;
  }
  .modal {
    animation: modal-pop 0.2s cubic-bezier(0.2, 0.8, 0.3, 1);
  }
  .toast {
    animation: slide-in 0.2s ease-out;
  }

  /* Le rond de chargement tourne. */
  .spinner {
    animation: spin 0.7s linear infinite;
  }
}

/* Halo pulsé du point vert « en ligne » (voir .badge-running::before). */
@keyframes dot-pulse {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.5);
  }
  50% {
    box-shadow: 0 0 0 3px rgba(34, 197, 94, 0);
  }
}

/* Apparition du menu de fichier. */
@keyframes menu-pop {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
}

/* Le fond noir de la modale se fond. */
@keyframes backdrop-fade {
  from {
    opacity: 0;
  }
}

/* La fenêtre modale : fondu + léger zoom depuis le bas. */
@keyframes modal-pop {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.97);
  }
}

/* Rotation continue du rond de chargement. */
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* ------------------------------------------------------------------ */
/* Page « Mon compte » : 2FA et sessions                               */
/* ------------------------------------------------------------------ */

/* Pastilles Activée / Désactivée (réutilisent .badge, avec leurs couleurs). */
.badge-on {
  background: rgba(34, 197, 94, 0.15);
  color: var(--success);
}
.badge-on::before {
  background: var(--success);
}
.badge-off {
  background: rgba(143, 138, 128, 0.15);
  color: var(--text-muted);
}
.badge-off::before {
  background: var(--text-muted);
}

/* La clé secrète 2FA à recopier : police à chasse fixe, sélectionnable d'un clic. */
.code-block {
  font-family: var(--mono);
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 12px;
  margin: 8px 0;
  letter-spacing: 0.08em;
  word-break: break-all;
  user-select: all;
}

/* Liste d'étapes numérotées (activation de la 2FA). */
.steps {
  padding-left: 20px;
  display: grid;
  gap: 12px;
  margin: 0;
}
.steps li {
  color: var(--text);
}

/* Message d'erreur en ligne (dans une carte, une cellule de tableau). */
.error-text {
  color: var(--danger);
}
