/* ==========================================================================
   TERMINAXAS — interface
   --------------------------------------------------------------------------
   Pensée pour le téléphone d'abord : c'est là qu'on s'en sert, debout dans un
   train, d'une main. Barre d'onglets en bas (le pouce y arrive, pas en haut),
   cibles à 44 px, texte jamais sous 12 px, champs à 16 px — sous cette taille
   iOS zoome tout seul à la saisie et casse la mise en page.
   ========================================================================== */

:root{
  --fond:#0b0d0f;
  --carte:#15181b;
  --carte-haute:#1d2125;
  --trait:#262c31;
  --trait-fort:#39424a;

  --encre:#e8edf0;
  --encre-douce:#96a2ab;
  --encre-tenue:#657079;

  /* Menthe : l'accent de Terminaxas. Assez saturé pour marquer un état sain
     sur fond sombre, assez sobre pour ne pas hurler à chaque jauge. */
  --vif:#4fd1a5;
  --vif-sourd:#12312a;
  --ambre:#eba75f;
  --ambre-sourd:#2e2213;
  --rouge:#f0736a;
  --rouge-sourd:#2f1614;

  --rayon:16px;
  --rayon-petit:10px;
  --ombre:0 8px 28px rgba(0,0,0,.45);
  --barre-h:78px;
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0;height:100%}
body{
  background:var(--fond);color:var(--encre);
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,system-ui,sans-serif;
  font-size:15px;line-height:1.5;-webkit-font-smoothing:antialiased;
  overscroll-behavior-y:none;
}
button,input,select,textarea{font-family:inherit;color:inherit}
button{cursor:pointer;border:0;background:none}
a{color:var(--vif);text-decoration:none}
.mono{font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace}

/* ------------------------------------------------------------- structure */
#app{display:flex;flex-direction:column;height:100%}
main{
  flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;
  padding:calc(env(safe-area-inset-top,0px) + 14px) 16px calc(var(--barre-h) + 24px);
}
.vue[hidden]{display:none !important}

h1{font-size:31px;font-weight:800;letter-spacing:-.03em;margin:6px 0 14px}
h2{font-size:17px;font-weight:700;margin:26px 0 10px;letter-spacing:-.01em}
h2:first-child{margin-top:0}
.sous{color:var(--encre-douce);font-size:13.5px;margin:-6px 0 16px}

/* ------------------------------------------------------ barre d'onglets */
nav.onglets{
  position:fixed;left:12px;right:12px;bottom:calc(env(safe-area-inset-bottom,0px) + 10px);
  height:60px;display:flex;align-items:center;justify-content:space-around;
  background:rgba(29,33,37,.92);backdrop-filter:blur(20px);
  border:1px solid var(--trait);border-radius:22px;box-shadow:var(--ombre);z-index:40;
}
nav.onglets button{
  display:flex;flex-direction:column;align-items:center;gap:3px;
  flex:1;height:100%;justify-content:center;border-radius:18px;
  color:var(--encre-tenue);font-size:11px;font-weight:600;
}
nav.onglets button svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
nav.onglets button.actif{color:var(--vif);background:var(--vif-sourd)}

/* ------------------------------------------------------------- éléments */
.champ{margin-bottom:14px}
.champ label{display:block;font-size:12px;font-weight:600;color:var(--encre-douce);
  text-transform:uppercase;letter-spacing:.05em;margin-bottom:6px}
.champ input,.champ select,.champ textarea{
  width:100%;padding:13px 14px;font-size:16px;
  background:var(--carte);border:1px solid var(--trait);border-radius:var(--rayon-petit);
  color:var(--encre);min-height:48px;
}
.champ textarea{min-height:120px;font-family:ui-monospace,Menlo,monospace;font-size:13px;line-height:1.5}
.champ input:focus,.champ select:focus,.champ textarea:focus{outline:none;border-color:var(--vif)}
.champ .aide{font-size:12px;color:var(--encre-tenue);margin-top:6px;line-height:1.45}
.rangee{display:flex;gap:10px}
.rangee .champ{flex:1;min-width:0}

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  padding:0 18px;min-height:48px;border-radius:var(--rayon-petit);
  background:var(--carte-haute);border:1px solid var(--trait);
  font-size:15px;font-weight:600;color:var(--encre);
}
.btn:active{transform:scale(.98)}
.btn:disabled{opacity:.45;pointer-events:none}
.btn.principal{background:var(--vif);border-color:transparent;color:#06231a}
.btn.danger{color:var(--rouge);border-color:rgba(240,115,106,.35)}
.btn.large{width:100%}
.btn svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.btn-rangee{display:flex;gap:10px;margin-top:6px}
.btn-rangee .btn{flex:1}

.recherche{position:relative;margin-bottom:16px}
.recherche input{
  width:100%;padding:13px 14px 13px 42px;font-size:16px;min-height:48px;
  background:var(--carte);border:1px solid var(--trait);border-radius:14px;color:var(--encre);
}
.recherche svg{position:absolute;left:14px;top:50%;transform:translateY(-50%);
  width:18px;height:18px;stroke:var(--encre-tenue);fill:none;stroke-width:2}

/* --------------------------------------------------------- carte serveur
   Reprend la lecture de ServerCat : deux anneaux (processeur, mémoire) et
   quatre compteurs. On voit l'essentiel sans ouvrir la fiche. */
.srv{
  background:var(--carte);border:1px solid var(--trait);border-radius:var(--rayon);
  padding:16px;margin-bottom:12px;
}
.srv-tete{display:flex;align-items:center;gap:10px;margin-bottom:14px}
.srv-nom{font-size:16px;font-weight:700;flex:1;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.srv-adr{font-size:11.5px;color:var(--encre-tenue);margin-top:1px}
.pastille{width:10px;height:10px;border-radius:50%;flex-shrink:0;background:var(--encre-tenue)}
.pastille.en-ligne{background:var(--vif);box-shadow:0 0 0 4px var(--vif-sourd)}
.pastille.hors-ligne{background:var(--rouge);box-shadow:0 0 0 4px var(--rouge-sourd)}
.pastille.attente{background:var(--ambre);box-shadow:0 0 0 4px var(--ambre-sourd);animation:pulse 1.4s ease-in-out infinite}
/* Relevé en cours alors qu'on a déjà des chiffres : la pastille respire, mais
   les valeurs affichées ne bougent pas. On ne vide jamais l'écran. */
.pastille.relit{animation:pulse 1.1s ease-in-out infinite}
@keyframes pulse{50%{opacity:.35}}
.srv-act{display:flex;gap:6px;flex-shrink:0}
.icone-btn{
  width:40px;height:40px;border-radius:11px;display:grid;place-items:center;
  border:1px solid var(--trait);color:var(--encre-douce);background:var(--carte-haute);
}
.icone-btn svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.icone-btn.vif{color:var(--vif);border-color:rgba(79,209,165,.35)}

.srv-corps{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.anneaux{display:flex;gap:14px}
.anneau{position:relative;width:66px;height:66px;flex-shrink:0}
.anneau svg{width:66px;height:66px;transform:rotate(-90deg)}
.anneau circle{fill:none;stroke-width:6;stroke-linecap:round}
.anneau .piste{stroke:var(--trait)}
.anneau .jauge{stroke:var(--vif);transition:stroke-dashoffset .5s ease,stroke .3s}
/* `display:grid` mettait le nombre et le « % » sur DEUX lignes : dans une
   grille, un nœud de texte et un <span> deviennent deux éléments distincts,
   donc deux rangées. Flex les garde sur la même ligne. */
.anneau .val{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  gap:1px;font-size:13.5px;font-weight:700;letter-spacing:-.02em}
.anneau .lib{text-align:center;font-size:10.5px;color:var(--encre-tenue);
  margin-top:2px;font-weight:600;text-transform:uppercase;letter-spacing:.05em}
.anneau-bloc{display:flex;flex-direction:column;align-items:center}

.compteurs{display:grid;grid-template-columns:1fr 1fr;gap:4px 18px;flex:1;min-width:150px}
.cpt{display:flex;flex-direction:column}
.cpt b{font-size:16px;font-weight:700;letter-spacing:-.02em}
.cpt b span{font-size:11px;font-weight:600;color:var(--encre-tenue);margin-left:2px}
.cpt small{font-size:11px;color:var(--encre-tenue)}

.srv-courbe{margin-top:12px;position:relative}
.srv-courbe .courbe{height:26px}
.srv-courbe-lib{display:block;font-size:10.5px;color:var(--encre-tenue);
  margin-top:3px;text-transform:uppercase;letter-spacing:.05em;font-weight:600}
.srv-erreur{
  margin-top:12px;padding:10px 12px;border-radius:var(--rayon-petit);
  background:var(--rouge-sourd);color:var(--rouge);font-size:12.5px;line-height:1.45;
  display:flex;align-items:center;justify-content:space-between;gap:10px;
}
.srv-erreur button{color:var(--rouge);font-size:12.5px;font-weight:700;flex-shrink:0}

/* -------------------------------------------------------- liste générale */
.ligne{
  display:flex;align-items:center;gap:12px;padding:14px 16px;
  background:var(--carte);border:1px solid var(--trait);border-radius:var(--rayon-petit);
  margin-bottom:8px;width:100%;text-align:left;min-height:56px;
}
.ligne:active{background:var(--carte-haute)}
.ligne-corps{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
/* `display:block` est indispensable : sur un <span> laissé en inline,
   `overflow:hidden` et `text-overflow:ellipsis` n'ont AUCUN effet — le texte
   sort de la carte, passe sous les badges et court hors de l'écran. C'est
   exactement ce qui arrivait aux empreintes de clés. */
.ligne-nom{display:block;font-size:15px;font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ligne-sous{display:block;font-size:11.5px;color:var(--encre-tenue);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
/* Les repères passent SOUS le nom plutôt qu'à côté : sur 390 px, deux badges
   posés à droite ne laissaient au nom qu'une dizaine de caractères, et
   « Sauvegarde RSA longue portée » devenait « Sauvegarde RSA lo… ». Le nom
   est l'information principale : il prend toute la largeur. */
.ligne-meta{display:flex;align-items:center;gap:6px;min-width:0;margin-top:3px}
.ligne-meta .etiquette{flex-shrink:0}
.ligne-meta .ligne-sous{flex:1;min-width:0}
.ligne svg.chev{width:18px;height:18px;stroke:var(--encre-tenue);fill:none;stroke-width:2;flex-shrink:0}
.etiquette{
  font-size:10.5px;font-weight:700;padding:3px 8px;border-radius:6px;
  background:var(--carte-haute);color:var(--encre-douce);flex-shrink:0;
  text-transform:uppercase;letter-spacing:.04em;
}
.etiquette.vif{background:var(--vif-sourd);color:var(--vif)}
/* Une clé que rien n'utilise mérite d'être signalée sans être alarmante :
   c'est souvent une clé oubliée, donc un accès qu'on ne surveille plus. */
.etiquette.terne{background:transparent;color:var(--encre-tenue);
  border:1px solid var(--trait)}

.vide{text-align:center;padding:60px 20px;color:var(--encre-tenue)}
.vide svg{width:52px;height:52px;stroke:var(--trait-fort);fill:none;stroke-width:1.5;margin-bottom:14px}
.vide b{display:block;font-size:17px;color:var(--encre-douce);margin-bottom:6px}
.vide p{font-size:13.5px;margin:0;max-width:34ch;margin-inline:auto;line-height:1.5}

/* ------------------------------------------------------------- feuille
   Panneau qui monte du bas — le geste attendu sur téléphone. */
.voile{position:fixed;inset:0;background:rgba(0,0,0,.6);backdrop-filter:blur(3px);z-index:50}
.voile[hidden]{display:none !important}
.feuille{
  position:fixed;left:0;right:0;bottom:0;z-index:51;
  max-height:92vh;overflow-y:auto;
  background:var(--fond);border-top:1px solid var(--trait);
  border-radius:24px 24px 0 0;
  padding:10px 16px calc(env(safe-area-inset-bottom,0px) + 24px);
  box-shadow:var(--ombre);
}
.feuille[hidden]{display:none !important}
/* Barre de tête de la feuille : la poignée au centre, la croix à droite.
   Le glissement vers le bas ferme aussi (voir app.js) — mais un geste ne
   s'affiche pas, d'où le bouton. */
.feuille-barre{position:relative;display:flex;align-items:center;justify-content:center;
  height:34px;margin-bottom:8px;touch-action:none}
.poignee{width:38px;height:4px;border-radius:2px;background:var(--trait-fort)}
.feuille-fermer{
  position:absolute;right:0;top:-2px;width:38px;height:38px;border-radius:11px;
  display:grid;place-items:center;color:var(--encre-douce);
  background:var(--carte-haute);border:1px solid var(--trait);
}
.feuille-fermer svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round}
.feuille{transition:transform .18s ease}
.feuille.glisse{transition:none}
.feuille h3{font-size:20px;font-weight:700;margin:0 0 4px;letter-spacing:-.02em}
.feuille .sous{margin-bottom:18px}

.avis{padding:12px 14px;border-radius:var(--rayon-petit);font-size:13px;line-height:1.5;margin-bottom:14px}
.avis.info{background:var(--vif-sourd);color:var(--vif)}
.avis.attention{background:var(--ambre-sourd);color:var(--ambre)}
.avis.erreur{background:var(--rouge-sourd);color:var(--rouge)}
.avis b{display:block;margin-bottom:3px}
.avis code{font-size:11.5px;word-break:break-all;font-family:ui-monospace,Menlo,monospace}

#toast{
  position:fixed;left:16px;right:16px;bottom:calc(var(--barre-h) + 20px);z-index:60;
  background:var(--carte-haute);border:1px solid var(--trait-fort);border-radius:12px;
  padding:13px 16px;font-size:14px;box-shadow:var(--ombre);
  opacity:0;transform:translateY(10px);transition:opacity .2s,transform .2s;pointer-events:none;
}
#toast.visible{opacity:1;transform:translateY(0)}
#toast.mauvais{border-color:var(--rouge);color:var(--rouge)}

/* --------------------------------------------------------- fiche serveur */
.bloc{background:var(--carte);border:1px solid var(--trait);border-radius:var(--rayon);padding:16px;margin-bottom:12px}
.bloc-tete{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:12px}
.bloc-titre{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:var(--encre-tenue)}
.grand{font-size:38px;font-weight:800;letter-spacing:-.03em;line-height:1}
.grand span{font-size:17px;font-weight:600;color:var(--encre-tenue)}
.parts{display:grid;grid-template-columns:repeat(auto-fit,minmax(80px,1fr));gap:12px;margin-top:14px}
.part{display:flex;flex-direction:column;gap:2px}
.part i{width:8px;height:8px;border-radius:2px;display:inline-block;margin-right:5px}
.part .l{font-size:10.5px;color:var(--encre-tenue);text-transform:uppercase;letter-spacing:.05em;font-weight:600}
.part .v{font-size:15px;font-weight:700}
.barre-empilee{display:flex;height:8px;border-radius:4px;overflow:hidden;background:var(--trait);margin-top:12px;gap:2px}
.barre-empilee i{display:block;height:100%;border-radius:2px}

.mesure{display:flex;align-items:center;justify-content:space-between;padding:11px 0;border-bottom:1px solid var(--trait);font-size:14px}
.mesure:last-child{border-bottom:0}
.mesure .l{color:var(--encre-douce)}
.mesure .v{font-weight:600;font-variant-numeric:tabular-nums}

/* ---------------------------------------------------------- statistiques */
.courbe{width:100%;height:38px;display:block;margin-top:6px}
.courbe-vide{font-size:12.5px;color:var(--encre-tenue);line-height:1.5;padding:6px 0}
.stat-ligne + .stat-ligne{margin-top:16px;padding-top:14px;border-top:1px solid var(--trait)}
.stat-tete{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.stat-nom{font-size:13px;color:var(--encre-douce);font-weight:600}
.stat-val{font-size:15px;font-weight:700;text-align:right;font-variant-numeric:tabular-nums}
.stat-val em{display:block;font-style:normal;font-size:11px;font-weight:500;
  color:var(--encre-tenue);margin-top:1px}

/* ------------------------------------------------------------- terminal */
body.terminal{background:#000;overflow:hidden}
/* `position:relative` et un z-index SUPÉRIEUR à celui de #term-etat : sans
   cela, l'écran d'état (opaque, inset:0) recouvrait l'en-tête — donc le bouton
   retour. Dès qu'une connexion échouait, il n'y avait plus aucun moyen de
   sortir du terminal. C'est le pire des défauts : une impasse. */
#term-tete{
  position:relative;z-index:30;
  display:flex;align-items:center;gap:10px;padding:calc(env(safe-area-inset-top,0px) + 10px) 12px 10px;
  background:var(--carte);border-bottom:1px solid var(--trait);
}
#term-tete .nom{flex:1;min-width:0;font-size:14px;font-weight:700;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#term-tete .adr{font-size:11px;color:var(--encre-tenue);font-weight:400}
#term-hote{flex:1;min-width:0}
#terminal{position:absolute;inset:0;top:var(--tete-h,56px);bottom:var(--clavier-h,52px);padding:8px 6px}
/* Rangée de touches que l'iPhone n'a pas : sans elle, ni Échap, ni Ctrl, ni
   tabulation — donc ni vim, ni complétion, ni interruption d'un processus. */
#term-touches{
  position:fixed;left:0;right:0;bottom:0;z-index:20;
  display:flex;gap:6px;overflow-x:auto;scrollbar-width:none;
  padding:8px 10px calc(env(safe-area-inset-bottom,0px) + 8px);
  background:var(--carte);border-top:1px solid var(--trait);
}
#term-touches::-webkit-scrollbar{display:none}
#term-touches button{
  flex:0 0 auto;min-width:46px;height:38px;padding:0 12px;border-radius:9px;
  background:var(--carte-haute);border:1px solid var(--trait);
  font-size:13px;font-weight:600;color:var(--encre-douce);
  font-family:ui-monospace,Menlo,monospace;
}
#term-touches button.armee{background:var(--vif);color:#06231a;border-color:transparent}
#term-touches .sep{flex:0 0 1px;align-self:stretch;background:var(--trait);margin:0 2px}
#term-etat{
  /* Sous l'en-tête, jamais par-dessus. */
  position:absolute;left:0;right:0;top:var(--tete-h,56px);bottom:0;
  display:grid;place-items:center;padding:30px;overflow-y:auto;
  text-align:center;color:var(--encre-douce);font-size:14px;background:#000;z-index:10;
}
#term-etat[hidden]{display:none !important}

@media (min-width:760px){
  main{padding-left:max(16px,calc((100% - 720px) / 2));padding-right:max(16px,calc((100% - 720px) / 2))}
  nav.onglets{left:50%;transform:translateX(-50%);width:420px}
  .feuille{left:50%;transform:translateX(-50%);width:560px;border-radius:24px;bottom:24px;max-height:84vh}
}
@media (prefers-reduced-motion:reduce){*{animation:none !important;transition:none !important}}

/* ── Terminal : copier/coller et retours brefs ─────────────────────────── */
/* Les deux actions les plus utilisées se distinguent des touches brutes :
   elles agissent sur la page, pas sur le serveur distant. */
#term-touches button.action{
  background:var(--carte);border-color:var(--trait-fort,#39424a);
  color:var(--encre);font-family:inherit;font-weight:600;
}
#term-touches button.action:active{background:var(--vif);color:#06231a;border-color:transparent}

/* Message d'une seconde et demie, posé juste au-dessus de la barre de touches
   et jamais sous le clavier : il suit la même variable que le terminal. */
#term-info{
  position:fixed;left:50%;transform:translateX(-50%);
  bottom:calc(var(--clavier-h,52px) + 14px);z-index:30;
  padding:8px 16px;border-radius:999px;
  background:rgba(20,24,27,.94);border:1px solid var(--trait);
  color:var(--encre);font-size:13px;font-weight:600;
  pointer-events:none;
}
#term-info[hidden]{display:none}

#term-collage{
  position:fixed;inset:0;z-index:40;display:grid;place-items:center;
  padding:20px;background:rgba(0,0,0,.72);
}
#term-collage[hidden]{display:none}
#term-collage .boite{
  width:100%;max-width:440px;padding:18px;
  background:var(--carte);border:1px solid var(--trait);border-radius:16px;
}
#term-collage label{display:block;margin-bottom:10px;font-size:13.5px;color:var(--encre-douce)}
#term-collage textarea{
  width:100%;padding:12px;border-radius:10px;resize:vertical;
  background:#000;border:1px solid var(--trait);color:var(--encre);
  font-family:ui-monospace,Menlo,monospace;font-size:16px;
}
#term-collage .rangee{display:flex;gap:10px;justify-content:flex-end;margin-top:14px}
