/* NYXUS – Server Control */
:root{
  --bg:#0d1117; --bg2:#131a24; --card:#161d29; --line:#232c3b;
  --txt:#e6edf6; --muted:#8b98ab; --acc:#3d8bff; --acc2:#1f6feb;
  --ok:#2ea043; --warn:#d29922; --bad:#f04747; --online:#00c389;
  --radius:12px; --mono:ui-monospace,"Cascadia Mono",Consolas,monospace;
}
*{box-sizing:border-box}
html,body{height:100%}
/* Nichts darf seitlich hinauslaufen - auf schmalen Bildschirmen entsteht
   sonst eine Scrollleiste, und alles wirkt verschoben. */
html,body{max-width:100%;overflow-x:hidden}
body{
  margin:0;background:var(--bg);color:var(--txt);
  font:15px/1.5 "Segoe UI",system-ui,-apple-system,sans-serif;
  overscroll-behavior:none;
}

/* Fuehlt sich wie ein Programm an, nicht wie eine Webseite:
   Bedienelemente sind nicht markierbar, Inhalte schon. */
body,.topbar,.sidebar,.tabs,.detail-head,.online-box,.tile,.btn,.tab,.srv{user-select:none}
.console,.data-table,table.kv,.issue-detail,.issue-evidence,.online-url,input,textarea{user-select:text}
::-webkit-scrollbar{width:11px;height:11px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:#26313f;border-radius:99px;border:3px solid var(--bg)}
::-webkit-scrollbar-thumb:hover{background:#33404f}

/* ---------- Lebendiger Hintergrund ----------
   Liegt hinter allem, nimmt keine Klicks entgegen und bleibt beim Blättern
   stehen. Die Farbe darunter ist dieselbe wie vorher - fällt das Canvas aus,
   sieht die Seite aus wie zuvor. */
#hintergrund{
  position:fixed;inset:0;z-index:0;
  pointer-events:none;   /* klickt man hindurch, als wäre es nicht da */
}
/* Ein sehr weicher Schein aus der Bildmitte legt sich über den Code. Er nimmt
   der Mitte den letzten Rest Unruhe und gibt der Fläche Tiefe - ohne ihn
   wirkt der Hintergrund flach, als klebte er auf dem Glas. */
body::before{
  content:'';position:fixed;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(58% 46% at 50% 42%, rgba(11,15,22,.92), rgba(11,15,22,.55) 55%, transparent 78%),
    radial-gradient(120% 80% at 50% 0%, rgba(45,230,180,.05), transparent 62%);
}
/* Alles Bedienbare liegt darüber. Ohne das läge der Hintergrund über der
   Oberfläche und würde sie verdecken. */
.layout,.modal,.splash,.toasts{position:relative;z-index:1}

/* ---------- Startbild ----------
   Der Grund ist nicht ganz deckend: Der Code-Hintergrund läuft schon beim
   Öffnen und scheint an den Rändern durch. Das Programm wirkt dadurch von der
   ersten Sekunde an lebendig, statt aus einer schwarzen Fläche zu erscheinen.

   Die Mitte bleibt dabei fast undurchsichtig – dort stehen Marke und
   Schriftzug, und die sollen klar dastehen, nicht mit dem Code um
   Aufmerksamkeit ringen. Der Code ist hier Beiwerk, nicht der Auftritt. */
.splash{
  position:fixed;inset:0;z-index:100;display:grid;place-items:center;
  background:
    radial-gradient(52% 46% at 50% 46%, rgba(7,11,18,.985), rgba(7,11,18,.94) 62%, rgba(7,11,18,.80) 88%),
    radial-gradient(120% 90% at 50% 0%,rgba(45,230,180,.10),transparent 60%),
    radial-gradient(90% 70% at 50% 110%,rgba(106,125,255,.12),transparent 60%),
    rgba(7,11,18,.93);
  transition:opacity .5s ease, visibility .5s;
}
.splash.gone{opacity:0;visibility:hidden}
.splash-inner{display:flex;flex-direction:column;align-items:center}

/* Marke mit zwei Ringen, die nach aussen laufen */
.splash-mark{position:relative;width:132px;height:132px;display:grid;place-items:center}
.splash-mark .puls{
  position:absolute;inset:14px;border-radius:34px;
  border:1.5px solid rgba(64,230,190,.55);
  opacity:0;animation:puls 2.4s cubic-bezier(.2,.7,.3,1) .25s infinite;
}
.splash-mark .puls.verzoegert{animation-delay:1s}
.splash-icon{
  width:104px;height:104px;border-radius:27px;position:relative;
  opacity:0;transform:scale(.7) rotate(-8deg);
  animation:markeRein .6s cubic-bezier(.18,.9,.28,1) forwards;
  filter:drop-shadow(0 16px 40px rgba(34,225,175,.32));
}

/* Wortmarke: die Buchstaben kommen einzeln hoch */
.splash-name{margin-top:22px;display:flex;gap:14px}
.splash-name span{
  font-size:34px;font-weight:800;line-height:1;
  background:linear-gradient(150deg,#5df3d2,#6a7dff);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  opacity:0;transform:translateY(14px);
  animation:buchstabe .5s cubic-bezier(.2,.8,.3,1) forwards;
}
.splash-name span:nth-child(1){animation-delay:.20s}
.splash-name span:nth-child(2){animation-delay:.27s}
.splash-name span:nth-child(3){animation-delay:.34s}
.splash-name span:nth-child(4){animation-delay:.41s}
.splash-name span:nth-child(5){animation-delay:.48s}

.splash-sub{
  margin-top:12px;font-size:11px;letter-spacing:6px;text-transform:uppercase;color:#55647a;
  opacity:0;animation:splashName .5s ease .58s forwards;
}
.splash-linie{
  margin-top:22px;height:1px;width:0;
  background:linear-gradient(90deg,transparent,#3ad6b0,#6a7dff,transparent);
  animation:linieAuf .7s cubic-bezier(.4,0,.2,1) .5s forwards;
}

@keyframes markeRein{to{opacity:1;transform:scale(1) rotate(0)}}
@keyframes buchstabe{to{opacity:1;transform:none}}
@keyframes splashName{to{opacity:1}}
@keyframes linieAuf{to{width:210px}}
@keyframes puls{
  0%{opacity:.7;transform:scale(1)}
  100%{opacity:0;transform:scale(1.75)}
}

/* Uebergang vom Startbild zur App: der Inhalt faehrt weich hoch. */
#login,#app,#setup{opacity:0;transform:translateY(14px) scale(.995)}
body.ready #login,body.ready #app,body.ready #setup{
  opacity:1;transform:none;
  transition:opacity .55s ease, transform .55s cubic-bezier(.2,.8,.3,1);
}
body.ready #app.hidden,body.ready #login.hidden,body.ready #setup.hidden{transition:none}

@media(prefers-reduced-motion:reduce){
  .splash-icon,.splash-name span,.splash-sub,.splash-linie,.splash-mark .puls{
    animation-duration:.01s;animation-delay:0s;animation-iteration-count:1;
  }
  body.ready #login,body.ready #app{transition:none}
}
.hidden{display:none !important}
.muted{color:var(--muted);font-size:13px}
.mono{font-family:var(--mono);font-size:12.5px}
.spacer{flex:1}
.err{color:var(--bad);font-size:13px;min-height:18px;margin:6px 0 0}
.hint{color:var(--muted);font-size:12px;text-align:center;margin:10px 0 0}
/* Umschalten zwischen Anmeldung und Registrierung */
/* "Angemeldet bleiben" im Anmeldefenster */
.check.bleiben{display:flex;align-items:center;gap:8px;margin:2px 0 14px;font-size:13px;color:var(--muted);cursor:pointer}
.check.bleiben input{cursor:pointer;margin:0}
.hint.wechsel{margin-top:14px;padding-top:12px;border-top:1px solid rgba(255,255,255,.07)}
.hint.wechsel a{font-weight:600;text-decoration:none}
.hint.wechsel a:hover{text-decoration:underline}
code{font-family:var(--mono);background:#0b1017;padding:1px 5px;border-radius:4px;font-size:12px}
a{color:var(--acc)}
h3.sec{font-size:13px;text-transform:uppercase;letter-spacing:1px;color:var(--muted);margin:22px 0 10px}

/* ---------- Buttons ---------- */
.btn{
  background:var(--card);color:var(--txt);border:1px solid var(--line);
  padding:9px 14px;border-radius:9px;cursor:pointer;font-size:14px;font-weight:600;
  transition:.15s;white-space:nowrap;
}
.btn:hover{background:#1e2635;border-color:#31405a}
.btn:disabled{opacity:.4;cursor:not-allowed}
.btn.primary{background:var(--acc2);border-color:var(--acc2)}
.btn.primary:hover{background:var(--acc)}
.btn.ok{background:#18492a;border-color:#1f6b3c}
.btn.ok:hover{background:#1f6b3c}
.btn.danger{background:#4a1d20;border-color:#6d2b2f}
.btn.danger:hover{background:#6d2b2f}
.btn.danger.ghost{background:transparent;color:#ff8e8e;border-color:#6d2b2f}
.btn.ghost{background:transparent}
.btn.sm{padding:6px 10px;font-size:13px}
.btn.block{width:100%}
.btn.online{
  background:linear-gradient(135deg,#00c389,#00916a);border:none;color:#04150f;
  font-size:15px;padding:12px 20px;letter-spacing:.3px;
  box-shadow:0 4px 18px rgba(0,195,137,.28);
}
.btn.online:hover{filter:brightness(1.1)}

/* ---------- Login ---------- */
.login{
  position:fixed;inset:0;display:grid;place-items:center;z-index:50;overflow:hidden;
  background:
    radial-gradient(90% 60% at 15% 0%,rgba(45,230,180,.10),transparent 55%),
    radial-gradient(80% 60% at 90% 100%,rgba(106,125,255,.14),transparent 55%),
    #080d15;
}
/* Langsam wandernder Lichtschein im Hintergrund */
.login-glanz{
  /* Fest am Bildbereich verankert, nicht im Fluss: sonst zieht der 760 Pixel
     breite Kreis auf einem Telefon die Anmeldebox aus der Mitte. */
  position:absolute;top:50%;left:50%;margin:-380px 0 0 -380px;
  width:760px;height:760px;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(58,214,176,.13),transparent 62%);
  animation:glanz 16s ease-in-out infinite alternate;
}
@keyframes glanz{
  0%{transform:translate(-24%,-22%)}
  100%{transform:translate(24%,18%)}
}

.login-box{
  position:relative;width:min(380px,92vw);text-align:center;padding:34px 30px 28px;border-radius:20px;
  background:linear-gradient(180deg,rgba(23,32,47,.92),rgba(15,21,32,.92));
  border:1px solid rgba(120,160,210,.13);
  box-shadow:0 30px 70px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.05);
  backdrop-filter:blur(14px);
}
/* Feiner Farbrand oben auf der Karte */
.login-box::before{
  content:"";position:absolute;left:26px;right:26px;top:0;height:1px;
  background:linear-gradient(90deg,transparent,#3ad6b0,#6a7dff,transparent);
}
.login-mark{
  width:84px;height:84px;margin:0 auto 16px;display:grid;place-items:center;border-radius:24px;
  background:radial-gradient(circle at 50% 35%,rgba(58,214,176,.18),transparent 70%);
}
.login-mark img{width:76px;height:76px;border-radius:21px;filter:drop-shadow(0 12px 28px rgba(34,225,175,.30))}
.login-sub{margin:6px 0 24px;font-size:11px;letter-spacing:5px;text-transform:uppercase;color:#55647a}

.feld{display:block;text-align:left;margin-bottom:16px}
.feld-titel{display:block;font-size:11px;letter-spacing:1.4px;text-transform:uppercase;color:var(--muted);margin-bottom:7px}
.feld input{
  width:100%;padding:12px 14px;border-radius:11px;font-size:15px;letter-spacing:2px;
  background:rgba(6,10,17,.75);border:1px solid rgba(120,160,210,.16);
}
.feld input:focus{border-color:#3ad6b0;box-shadow:0 0 0 3px rgba(58,214,176,.13)}
.login-box .btn.primary{
  padding:12px;border-radius:11px;font-size:15px;letter-spacing:.4px;
  background:linear-gradient(135deg,#2fd3a8,#4d7dff);border:none;color:#04140f;font-weight:700;
  box-shadow:0 8px 24px rgba(45,180,220,.22);
}
.login-box .btn.primary:hover{filter:brightness(1.08)}
.brand{
  font-weight:800;letter-spacing:4px;font-size:19px;display:flex;align-items:center;gap:10px;justify-content:center;
  background:linear-gradient(100deg,#00e6a4,#3d8bff);-webkit-background-clip:text;background-clip:text;color:transparent;
}
.brand-icon{width:24px;height:24px;border-radius:7px;flex:none}
/* "Development" steht neben dem Schriftzug, aber nicht in dessen Farbverlauf
   und kleiner - so bleibt NYXUS der Name und der Zusatz die Tätigkeit. */
.brand-zusatz{
  font-weight:600;font-size:12px;letter-spacing:3px;color:var(--muted);
  -webkit-text-fill-color:var(--muted);align-self:center;
}
/* Name der Anlage neben dem Schriftzug: bewusst schlicht und nicht im
   Farbverlauf, damit man ihn als Zusatz liest und nicht als Teil des Namens. */
.anlage{font-weight:600;letter-spacing:1px;font-size:12px;color:var(--muted);
  background:#0b1017;border:1px solid var(--line);border-radius:99px;
  padding:3px 10px;margin-left:10px;white-space:nowrap}
.anlage:empty{display:none}
.login-box .brand{font-size:25px;letter-spacing:9px;text-indent:9px}

/* ---------- Eingaben ---------- */
input,textarea,select{
  background:#0b1017;border:1px solid var(--line);color:var(--txt);
  padding:9px 11px;border-radius:8px;font:inherit;width:100%;
}
input:focus,textarea:focus{outline:none;border-color:var(--acc)}
textarea{font-family:var(--mono);font-size:13px;resize:vertical}
label{display:block;font-size:13px;color:var(--muted);margin-bottom:12px}
label>input,label>textarea,label>.row{margin-top:5px}
.row{display:flex;gap:8px;align-items:center}
.row input{flex:1}
.mini{width:200px;padding:6px 10px;font-size:13px}
.mini.wide{width:280px}
.check{display:flex;align-items:center;gap:8px;color:var(--txt);font-size:14px}
.check input{width:auto;margin:0}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.fs{border:1px solid var(--line);border-radius:10px;padding:14px;margin:4px 0 14px}
.fs legend{color:var(--muted);font-size:12px;padding:0 6px}

/* Ein/Aus-Schalter */
.switch{display:flex;align-items:center;gap:8px;margin:0;cursor:pointer;user-select:none}
.switch input{display:none}
.slider{width:42px;height:23px;border-radius:99px;background:#3a2325;border:1px solid #6d2b2f;position:relative;transition:.2s}
.slider::after{content:"";position:absolute;top:2px;left:2px;width:17px;height:17px;border-radius:50%;background:#ff8e8e;transition:.2s}
.switch input:checked + .slider{background:#12492c;border-color:#1f6b3c}
.switch input:checked + .slider::after{left:21px;background:#5ee08a}
.switch-label{font-size:13px;color:var(--muted);min-width:22px}

/* ---------- Layout ---------- */
/* Die Höhe des Fensters, nicht die des Bildschirms.
 *
 * Am Telefon ist 100vh grösser als das, was man sieht: die Adressleiste ist
 * mitgerechnet. Die Folge waeren eine abgeschnittene Fusszeile und ein
 * Wackeln beim Scrollen. `dvh` meint den wirklich sichtbaren Bereich und
 * waechst mit, wenn die Adressleiste einfaehrt - `vh` bleibt als Rueckfall
 * fuer aeltere Browser darueber stehen. */
.app{display:flex;flex-direction:column;height:100vh;height:100dvh}
/* Die Kopfzeile liegt über dem Inhalt.
   Der z-index ist hier entscheidend und kein Beiwerk: Stünden Kopfzeile und
   Inhalt beide auf 1, gewänne bei Gleichstand das, was später im Dokument
   kommt - der Inhalt. Das aufgeklappte Menü ragt aus der Kopfzeile heraus und
   läge dann dahinter. Man sieht es noch durchscheinen, trifft aber keinen
   Knopf mehr, weil der Inhalt die Klicks abfängt. */
.topbar{display:flex;align-items:center;gap:10px;padding:12px 18px;background:var(--bg2);border-bottom:1px solid var(--line);position:relative;z-index:20}
.top-meta{display:flex;gap:8px;flex-wrap:wrap}
.chip{background:#0b1017;border:1px solid var(--line);border-radius:99px;padding:3px 11px;font-size:12px;color:var(--muted)}
.chip.good{color:var(--online);border-color:#12503c}
.chip.bad{color:var(--warn);border-color:#4a3c12}

/* Die Speicheranzeige in der Kopfzeile.
   Ein Balken statt bloßer Zahlen: Ob "3,4 von 5 GB" viel oder wenig ist,
   muss man ausrechnen - beim Balken sieht man es. Die Farbe wechselt erst
   spät, damit sie etwas bedeutet, wenn sie wechselt. */
.platz{display:flex;align-items:center;gap:9px;white-space:nowrap}
.platz-balken{
  width:120px;height:7px;border-radius:99px;overflow:hidden;
  background:#0b1017;border:1px solid var(--line);
}
.platz-balken i{display:block;height:100%;width:0;background:var(--acc);transition:width .4s ease}
.platz.knapp .platz-balken i{background:var(--warn)}
.platz.voll .platz-balken i{background:var(--bad)}
.platz-text{font-size:12px;color:var(--muted)}
.platz.knapp .platz-text{color:var(--warn)}
.platz.voll .platz-text{color:var(--bad);font-weight:600}

/* Das Menue hinter den drei Strichen.
 *
 * Zwoelf Knoepfe nebeneinander waren eine Wand: Man las jedes Mal die ganze
 * Reihe, um einen davon zu finden. Jetzt haengt alles in drei benannten
 * Gruppen unter dem Knopf, und in der Kopfzeile bleibt nur, was staendig
 * gebraucht wird oder im Notfall sofort da sein muss.
 *
 * Am Rechner ein Kaestchen rechts unter dem Knopf, am Telefon (weiter unten)
 * die volle Breite - dort ist fuer ein schwebendes Kaestchen kein Platz.
 */
.top-actions{
  display:none;position:absolute;top:calc(100% + 6px);right:12px;z-index:30;
  flex-direction:column;align-items:stretch;gap:5px;min-width:230px;
  background:var(--bg2);border:1px solid var(--line);border-radius:12px;
  padding:10px;box-shadow:0 18px 40px rgba(0,0,0,.6);
  max-height:calc(100vh - 70px);overflow-y:auto;
}
.top-actions.offen{display:flex}
.top-actions .btn{width:100%;justify-content:flex-start;padding:9px 12px}

/* Ueberschriften der Gruppen. */
.menue-titel{
  font-size:10.5px;letter-spacing:1.6px;text-transform:uppercase;
  color:var(--muted);margin:9px 0 2px;padding-left:4px;
}
.menue-titel:first-child{margin-top:2px}

/* Der Punkt am Menueknopf: im Menue wartet etwas. Eine Zahl waere hier zu
   klein zu lesen - die steht drinnen am Knopf, der sie betrifft. */
.schnell{position:relative;padding:8px 12px;font-size:16px;line-height:1;min-width:40px;justify-content:center}
.punkt{
  position:absolute;top:5px;right:6px;width:8px;height:8px;border-radius:50%;
  background:var(--bad);box-shadow:0 0 0 2px var(--bg2);
}
.wer{font-size:12.5px;color:var(--muted);padding:4px 11px;border-radius:99px;background:#0b1017;border:1px solid var(--line);white-space:nowrap}
.wer.rolle-admin{color:#5df3d2;border-color:#1c4a3e}
.wer.rolle-bediener{color:#8ab4ff;border-color:#22355c}

/* Warnkasten in der Benutzerverwaltung */
.warnbox{
  margin-top:16px;padding:12px 14px;border-radius:10px;font-size:13px;line-height:1.55;
  background:#241a10;border:1px solid #4a3c12;color:#f0d9a0;
}
.nur-lesen{opacity:.65}
select{
  background:#0b1017;border:1px solid var(--line);color:var(--txt);
  padding:8px 10px;border-radius:8px;font:inherit;width:100%;
}
select:focus{outline:none;border-color:var(--acc)}

.layout{flex:1;display:grid;grid-template-columns:290px 1fr;min-height:0}
.sidebar{border-right:1px solid var(--line);background:var(--bg2);display:flex;flex-direction:column;min-height:0}
.side-head{display:flex;align-items:center;justify-content:space-between;padding:14px 14px 8px}
.side-head h2{margin:0;font-size:14px;letter-spacing:1px;color:var(--muted);text-transform:uppercase}
.server-list{flex:1;overflow:auto;padding:6px 10px}
.side-foot{padding:10px;border-top:1px solid var(--line);display:grid;gap:6px}

.srv{background:var(--card);border:1px solid var(--line);border-radius:10px;padding:11px 12px;margin-bottom:8px;cursor:pointer;transition:.15s}
.srv:hover{border-color:#31405a}
.srv.active{border-color:var(--acc);background:#182338}
.srv.off{opacity:.55}
.srv-top{display:flex;align-items:center;gap:8px}
.srv-name{font-weight:600;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.led{width:9px;height:9px;border-radius:50%;background:#4b5563;flex:none}
.led.running{background:var(--ok);box-shadow:0 0 8px var(--ok)}
.led.starting,.led.restarting{background:var(--warn);box-shadow:0 0 8px var(--warn)}
.led.crashed{background:var(--bad);box-shadow:0 0 8px var(--bad)}
.led.off{background:#3a3f4a}
.srv-sub{font-size:12px;color:var(--muted);margin-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.srv-online{font-size:11px;color:var(--online);margin-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Zu welcher Abteilung ein Server gehoert - nur Administratoren sehen das. */
.srv-sub.abteilung{font-size:11px;opacity:.72;font-style:italic}
/* Wem der Server gehoert - klein hinter Zustand und Port. Etwas heller als der
   Rest der Zeile, damit der Name beim Ueberfliegen hervortritt, ohne dem
   Servernamen darueber die Aufmerksamkeit zu nehmen. */
.srv-wem{color:var(--text);opacity:.65;font-weight:600}

/* Der Balken über einer Abteilung.
   Er klebt beim Blättern oben fest: Bei zwanzig Servern sähe man sonst
   irgendwann nur noch Kacheln und wüsste nicht mehr, in wessen Abteilung
   man gerade liest. */
.gruppe{margin-bottom:10px}
.gruppe-kopf{
  position:sticky;top:0;z-index:2;
  display:flex;align-items:center;gap:8px;width:100%;
  padding:7px 10px;margin-bottom:6px;
  background:#141b26;border:1px solid var(--line);border-radius:9px;
  color:var(--text);font:inherit;font-size:12.5px;font-weight:700;
  letter-spacing:.4px;cursor:pointer;text-align:left;
}
.gruppe-kopf:hover{border-color:var(--acc)}
.gruppe-pfeil{color:var(--muted);font-size:11px;transition:transform .15s ease}
.gruppe.zu .gruppe-pfeil{transform:rotate(-90deg)}
.gruppe-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Wie viele davon laufen - die Zahl, die man beim Zuklappen behalten will. */
.gruppe-zahl{
  color:var(--muted);font-weight:600;font-size:11.5px;
  background:#0b1017;border:1px solid var(--line);border-radius:99px;padding:1px 8px;
}
.gruppe.zu .gruppe-inhalt{display:none}

/* Der Balken über der Liste, wenn ohne Verbindung der zuletzt bekannte Stand
   gezeigt wird. Bewusst auffällig in Warnfarbe: Er ist der einzige Hinweis
   darauf, dass die Namen darunter zwar stimmen, die Zustände aber von
   vorhin sind. */
.stand-balken{
  margin:0 0 10px;padding:9px 11px;border-radius:9px;
  background:#3d3312;border:1px solid #5a4a18;color:#f0cc63;
  font-size:12.5px;line-height:1.45;
}
.stand-balken div{color:var(--muted);margin-top:3px}
.badge{background:var(--bad);color:#fff;border-radius:99px;font-size:11px;font-weight:700;padding:1px 7px;min-width:19px;text-align:center}

.detail{padding:20px 24px;overflow:auto;min-height:0;display:flex;flex-direction:column}
.empty{margin:auto;text-align:center;color:var(--muted)}
.empty h1{color:var(--txt);font-size:20px}
.detail-head{display:flex;justify-content:space-between;align-items:flex-start;gap:16px;flex-wrap:wrap}
.detail-head h1{margin:0 0 6px;font-size:22px}
.sub{display:flex;gap:12px;align-items:center;flex-wrap:wrap}
.detail-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.pill{font-size:12px;padding:3px 10px;border-radius:99px;background:#2a3444;color:var(--muted);font-weight:600}
.pill.running,.pill.ok{background:#123d22;color:#5ee08a}
.pill.crashed,.pill.bad{background:#3d1517;color:#ff8e8e}
.pill.starting,.pill.restarting,.pill.warn{background:#3d3312;color:#f0cc63}
.pill.off{background:#2a2f38;color:#9aa4b2}

/* ---------- Online-Box ---------- */
.online-box{
  display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap;
  margin:18px 0;padding:16px 18px;border-radius:var(--radius);
  background:linear-gradient(135deg,#10261f,#111a24);border:1px solid #1d4438;
}
.online-title{font-weight:700;font-size:15px}
.online-state{font-size:13px;color:var(--muted);margin-top:3px}
.online-url{display:flex;align-items:center;gap:10px;margin-top:8px;flex-wrap:wrap}
.online-url a{font-family:var(--mono);font-size:14px;color:var(--online);word-break:break-all}
.online-right{display:flex;flex-direction:column;gap:8px;align-items:stretch}

/* ---------- Links ---------- */
.links-box{
  margin-bottom:18px;padding:14px 18px;border-radius:var(--radius);
  background:var(--card);border:1px solid var(--line);
}
.links-head{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-bottom:10px}
.links-title{font-weight:700;font-size:15px}
.scope{display:flex;background:#0b1017;border:1px solid var(--line);border-radius:9px;padding:2px}
.scope-btn{
  background:none;border:none;color:var(--muted);font:inherit;font-size:13px;font-weight:600;
  padding:5px 12px;border-radius:7px;cursor:pointer;
}
.scope-btn:hover:not(:disabled){color:var(--txt)}
.scope-btn.active{background:var(--acc2);color:#fff}
.scope-btn:disabled{opacity:.35;cursor:not-allowed}
.link-list{display:grid;gap:6px}
.link-row{display:flex;align-items:center;gap:12px;padding:7px 10px;border-radius:8px;background:#0b1017;flex-wrap:wrap}
.link-label{min-width:120px;font-size:13.5px;font-weight:600}
.link-url{flex:1;font-family:var(--mono);font-size:12.5px;color:var(--acc);word-break:break-all;text-decoration:none}
.link-url:hover{text-decoration:underline}
.link-guess{color:var(--warn);font-weight:700;cursor:help}
.link-row.blocked{opacity:.55}
.blocked-url{flex:1;color:var(--muted);text-decoration:line-through}

/* ---------- Tabs ---------- */
.tabs{display:flex;gap:4px;border-bottom:1px solid var(--line);margin-bottom:14px;flex-wrap:wrap}
.tab{background:none;border:none;color:var(--muted);padding:9px 14px;cursor:pointer;font-size:14px;font-weight:600;border-bottom:2px solid transparent;display:flex;align-items:center;gap:7px}
.tab.active{color:var(--txt);border-bottom-color:var(--acc)}
.tabpane{flex:1;display:flex;flex-direction:column;min-height:0}

/* ---------- Kacheln & Tabellen ---------- */
.tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:10px}
.tiles.small{grid-template-columns:repeat(auto-fill,minmax(120px,1fr));margin-bottom:14px}
.tile{background:var(--card);border:1px solid var(--line);border-radius:10px;padding:12px 14px}
.tile.warn{border-color:#4a3c12;background:#1e1a10}
.tile.good{border-color:#12503c}
.tile-v{font-size:20px;font-weight:700}
.tile-l{font-size:12px;color:var(--muted);margin-top:2px}

table.kv{width:100%;border-collapse:collapse}
table.kv td{padding:7px 6px;border-bottom:1px solid var(--line);font-size:13px;vertical-align:top}
table.kv td:first-child{color:var(--muted);width:38%}

.checks{display:grid;gap:6px}
.check-row{display:flex;align-items:center;gap:10px;background:var(--card);border:1px solid var(--line);border-radius:9px;padding:9px 12px}
.check-label{flex:1;font-size:14px}
.dot-state{width:9px;height:9px;border-radius:50%;flex:none;background:#4b5563}
.dot-state.ok{background:var(--ok);box-shadow:0 0 8px var(--ok)}
.dot-state.bad{background:var(--bad);box-shadow:0 0 8px var(--bad)}
.dot-state.neutral{background:#4b5563}

/* ---------- Konsole ---------- */
.console-bar{display:flex;gap:12px;align-items:center;margin-bottom:8px;flex-wrap:wrap}
.console{
  flex:1;min-height:240px;max-height:50vh;overflow:auto;margin:0;
  background:#080b10;border:1px solid var(--line);border-radius:10px;padding:12px;
  font-family:var(--mono);font-size:12.5px;line-height:1.55;white-space:pre-wrap;word-break:break-word;
}
.console .l-t{opacity:.4}
.console .l-err{color:#ff9d9d}
.console .l-sys{color:#63b3ff}
.console .l-tun{color:#00c389}
.console .l-fix{color:#c792ea}
.console .l-in{color:#f0cc63}
.console .l-out{color:#cbd5e1}
.console-input{display:flex;gap:8px;margin-top:8px}

/* ---------- Fehler ---------- */
.issue-list{display:grid;gap:10px;overflow:auto}
.issue{background:var(--card);border:1px solid var(--line);border-left:3px solid var(--muted);border-radius:10px;padding:12px 14px}
.issue.bad{border-left-color:var(--bad)}
.issue.warn{border-left-color:var(--warn)}
.issue.ok{border-left-color:var(--online)}
.issue-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:6px}
.issue-title{font-weight:700}
.issue-detail{font-size:14px}
.issue-advice{font-size:13px;color:#f0cc63;margin-top:6px}
.issue-evidence{background:#080b10;border:1px solid var(--line);border-radius:7px;padding:8px 10px;margin:8px 0 0;font-family:var(--mono);font-size:11.5px;color:#ff9d9d;white-space:pre-wrap;word-break:break-word;max-height:110px;overflow:auto}
.issue-actions{margin:8px 0 0;padding-left:18px;font-size:13px;color:#b6c2d2}
.issue-actions li{margin:2px 0}
.issue .btn{margin-top:10px}

/* ---------- Daten ---------- */
.data-wrap{display:grid;grid-template-columns:220px 1fr;gap:16px;min-height:0;flex:1}
.data-nav{display:flex;flex-direction:column;gap:6px;overflow:auto;max-height:60vh}
.data-dir{font-family:var(--mono);font-size:11px;word-break:break-all;margin-bottom:4px}
.data-item{background:var(--card);border:1px solid var(--line);border-radius:9px;padding:9px 11px;text-align:left;cursor:pointer;color:var(--txt)}
.data-item:hover{border-color:#31405a}
.data-item.active{border-color:var(--acc);background:#182338}
.data-item b{display:block;font-size:13.5px}
.data-item span{font-size:11.5px;color:var(--muted)}
.data-main{min-width:0;display:flex;flex-direction:column}
.table-wrap{overflow:auto;border:1px solid var(--line);border-radius:10px;max-height:48vh}
.data-table{width:100%;border-collapse:collapse;font-size:13px}
.data-table th{position:sticky;top:0;background:#111823;text-align:left;padding:9px 11px;border-bottom:1px solid var(--line);cursor:pointer;white-space:nowrap;font-size:12px;color:var(--muted)}
.data-table th:hover{color:var(--txt)}
.data-table td{padding:8px 11px;border-bottom:1px solid #1b2430;max-width:280px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.data-table tbody tr{cursor:pointer}
.data-table tbody tr:hover{background:#182338}
.pager{display:flex;align-items:center;gap:12px;margin-top:10px}

/* ---------- Code ----------
 *
 * Links die Dateien des Arbeitsordners, rechts der Editor. Der Editor liegt
 * auf demselben dunklen Grund wie die Konsole: beides ist Maschinentext, und
 * beides soll sich sofort vom Rest der Oberfläche unterscheiden.
 */
.code-wrap{display:grid;grid-template-columns:240px 1fr;gap:16px;min-height:0;flex:1}
.code-nav{display:flex;flex-direction:column;gap:6px;min-height:0}
.code-dir{font-family:var(--mono);font-size:11px;word-break:break-all;margin:2px 0}
.code-liste{display:flex;flex-direction:column;gap:3px;overflow:auto;max-height:56vh}
.code-gruppe{font-size:11px;color:var(--muted);font-family:var(--mono);margin:8px 0 2px;word-break:break-all}
.code-item{
  display:flex;align-items:center;gap:8px;background:var(--card);border:1px solid var(--line);
  border-radius:8px;padding:6px 9px;text-align:left;cursor:pointer;color:var(--txt);font-size:12.5px;
}
.code-item:hover{border-color:#31405a}
.code-item.active{border-color:var(--acc);background:#182338}
.code-name{font-family:var(--mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}
.code-groesse{font-size:10.5px;color:var(--muted);white-space:nowrap}

/* Fundstellen aus der Inhaltssuche. Nach Datei gruppiert, jede Zeile zum
   Anklicken - der Treffer im Text ist hervorgehoben, damit das Auge ihn in
   der Zeile sofort findet. */
.code-suchhinweis{font-size:11.5px;margin:2px 0 4px}
.code-treffer{
  display:flex;flex-direction:column;gap:2px;max-height:34vh;overflow:auto;
  border:1px solid var(--line);border-radius:9px;padding:7px;margin-bottom:9px;
  background:#111722;
}
.treffer-datei{
  font-size:11px;font-family:var(--mono);color:#7fd4ff;
  margin:7px 0 3px;word-break:break-all;
}
.treffer-datei:first-child{margin-top:0}
.treffer{
  display:flex;gap:8px;align-items:baseline;text-align:left;cursor:pointer;
  background:none;border:none;padding:3px 5px;border-radius:5px;color:var(--txt);
}
.treffer:hover{background:#1b2536}
.treffer-nr{font-family:var(--mono);font-size:10.5px;color:var(--muted);min-width:28px;text-align:right;flex:none}
.treffer code{
  font-family:var(--mono);font-size:11.5px;color:#cbd5e1;
  white-space:pre-wrap;word-break:break-word;overflow:hidden;
}
.treffer mark{background:#3d5a2a;color:#d8f0b8;border-radius:3px;padding:0 2px}

.code-main{min-width:0;display:flex;flex-direction:column}
.code-bar{margin-bottom:8px}
.code-titel{font-family:var(--mono);font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:46%}
.code-titel.dirty::after{content:' •';color:var(--acc)}

/* Zeilennummern und Text scrollen gemeinsam, deshalb dieselbe Schrift,
 * Zeilenhöhe und Innenabstand oben. */
.code-editor-wrap{
  display:flex;flex:1;min-height:300px;max-height:60vh;overflow:hidden;
  background:#080b10;border:1px solid var(--line);border-radius:10px;
}
.code-zeilen{
  flex:0 0 auto;min-width:42px;overflow:hidden;padding:12px 8px 12px 12px;margin:0;
  font-family:var(--mono);font-size:12.5px;line-height:1.55;white-space:pre;text-align:right;
  color:#3d4b60;user-select:none;border-right:1px solid var(--line);
}
.code-editor{
  flex:1;min-width:0;overflow:auto;padding:12px;margin:0;resize:none;
  background:transparent;border:0;outline:none;color:#cbd5e1;
  font-family:var(--mono);font-size:12.5px;line-height:1.55;white-space:pre;tab-size:2;
}
.code-editor:read-only{color:#93a3b8}
.code-hinweis{margin:8px 0 0;font-size:12px}

/* ---------- Ankündigung ----------
 *
 * Links geschrieben, rechts sofort gesehen: die Vorschau bildet den Kasten
 * nach, den Discord daraus macht. Wer eine Nachricht an alle schickt, soll
 * vorher wissen, wie sie aussieht.
 */
.ansage-wrap{display:grid;grid-template-columns:1fr 380px;gap:20px;align-items:start}
.ansage-links{display:flex;flex-direction:column;gap:12px;min-width:0}
.ansage-rechts{min-width:0}
.ansage-bot{
  font-size:12.5px;color:var(--muted);background:var(--card);border:1px solid var(--line);
  border-radius:9px;padding:9px 12px;
}
.bot-kopf{color:var(--txt)}
/* Die Discord-Server, auf denen dieser Bot steckt. Wo er nichts sehen darf,
   steht der Eintrag blass da - das erklärt eine leere Kanalliste sofort. */
.bot-server{list-style:none;margin:7px 0 0;padding:0;display:flex;flex-direction:column;gap:3px}
.bot-server li{display:flex;gap:9px;align-items:baseline;flex-wrap:wrap;font-size:12px}
.bot-server li b{color:var(--txt);font-weight:600}
.bot-server li.stumm b{color:var(--muted);font-weight:500}
.bot-server li.stumm{opacity:.7}
.ansage-schalter{display:flex;flex-direction:column;gap:6px;justify-content:flex-end;padding-bottom:2px}
.mini-hint{margin:-6px 0 0;font-size:11.5px}
.hinweis{
  background:#1b1424;border:1px solid #43305c;border-left:3px solid var(--acc);
  border-radius:8px;padding:12px 14px;font-size:13px;line-height:1.55;color:var(--txt);
}

.ansage-vorschau{
  background:#1a1d21;border:1px solid var(--line);border-radius:10px;padding:14px;
  min-height:140px;font-size:13.5px;line-height:1.5;
}
.vs-ping{color:#c9d5f0;margin-bottom:8px;font-size:13px}
.vs-embed{background:#20242a;border-left:4px solid var(--acc);border-radius:5px;padding:12px 14px}
.vs-titel{font-weight:700;font-size:15px;margin-bottom:7px;color:#f2f5fa}
.vs-text{color:#d3d8de;white-space:normal;word-break:break-word}
.vs-text code{background:#111418;padding:1px 5px;border-radius:4px;font-family:var(--mono);font-size:12px}
.vs-text .zitat{display:block;border-left:3px solid #4a5158;padding-left:9px;color:#aeb6c0}
.vs-fuss{margin-top:9px;font-size:11.5px;color:#8d95a0}
/* Bild im Kasten: als Banner füllt es die Breite, klein steht es rechts
   neben dem Text - genau wie Discord es anzeigt. */
.vs-bild{display:block;width:100%;border-radius:5px;margin-top:9px}
.vs-banner{padding:0;overflow:hidden}
.vs-banner .vs-bild{margin:0;border-radius:0}
.vs-kopf{display:flex;gap:12px;align-items:flex-start}
.vs-kopf-text{min-width:0;flex:1}
.vs-mini{width:78px;height:78px;object-fit:cover;border-radius:6px;flex:none}

/* Rollen zum Anklicken. Jede trägt ihre Discord-Farbe, damit man sie
   wiedererkennt; angeklickte sind ausgefüllt statt nur umrandet. */
.rollen-liste{display:flex;flex-wrap:wrap;gap:6px;max-height:150px;overflow:auto;margin-bottom:4px}
.rollen-gruppe{margin:10px 0}
.gruppe-titel{font-size:11px;letter-spacing:1.5px;text-transform:uppercase;color:var(--muted);margin-bottom:5px}
.warnfarbe{color:#f0cc63}
.rolle{
  --rf:#8d95a0;
  background:transparent;border:1px solid var(--rf);color:var(--rf);
  border-radius:20px;padding:4px 11px;font-size:12.5px;cursor:pointer;
  white-space:nowrap;line-height:1.3;
}
.rolle:hover{background:color-mix(in srgb, var(--rf) 18%, transparent)}
.rolle.an{background:var(--rf);border-color:var(--rf);color:#0b0f16;font-weight:700}
.rollen-zeile{
  font-size:12.5px;background:#111722;border:1px solid var(--line);
  border-radius:8px;padding:8px 11px;word-break:break-word;
}
.rollen-zeile b{color:#7fd4ff}

/* Bildauswahl im Formular */
.bild-zeile{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:10px}
.bild-zeile .muted{font-size:12px;word-break:break-all}
.bild-wo{display:flex;gap:16px;flex-wrap:wrap;margin-top:10px}
.mini-label{display:block;font-size:12.5px}
.vs-knopf{
  display:inline-block;margin-top:9px;background:#4a4d55;color:#e6eaf0;
  border-radius:6px;padding:7px 13px;font-size:13px;font-weight:600;
}

/* ---------- Modals ---------- */
.modal{position:fixed;inset:0;background:rgba(3,6,10,.72);display:grid;place-items:center;z-index:40;padding:20px}
.modal-box{background:var(--card);border:1px solid var(--line);border-radius:16px;padding:24px;width:min(660px,96vw);max-height:90vh;overflow:auto}
.modal-box h2{margin:0 0 4px;font-size:18px}
.templates{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px;margin:14px 0 18px}
.tpl{background:#0b1017;border:1px solid var(--line);border-radius:9px;padding:10px;cursor:pointer;text-align:left;color:var(--txt);font-size:13px}
.tpl:hover{border-color:var(--acc)}
.tpl b{display:block;margin-bottom:3px}
.tpl span{color:var(--muted);font-size:11px;font-family:var(--mono)}
.path{font-family:var(--mono);font-size:12px;color:var(--muted);margin:10px 0;word-break:break-all}
.browse-list{max-height:44vh;overflow:auto;border:1px solid var(--line);border-radius:9px;margin-bottom:14px}
/* ---- Ordnerauswahl: Schnellzugriffe, Suche, Pfadeingabe ---- */
.browse-quick{display:flex;flex-wrap:wrap;gap:6px;margin:12px 0 10px}
.chip.klick{cursor:pointer;font-family:inherit}
.chip.klick:hover{color:var(--text);border-color:var(--acc)}
.browse-suche{display:flex;gap:8px;margin-bottom:10px}
.browse-suche input{flex:1;min-width:0}
.browse-pfad{width:100%;box-sizing:border-box;font-size:12px}
.browse-info{padding:8px 12px;font-size:12px;color:var(--muted);border-bottom:1px solid var(--line);background:#0b1017}
.browse-pfad-klein{display:block;font-family:var(--mono);font-size:11px;color:var(--muted);
  margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.browse-item.muted{color:var(--muted);cursor:default}
/* Dateien werden angezeigt, aber nicht angeklickt */
.browse-item.datei{cursor:default;opacity:.72}
.browse-item.datei:hover{background:transparent}
/* Werkzeugleiste: hochladen und Ordner anlegen */
.browse-werkzeuge{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0 0 12px}
.browse-werkzeuge .muted{font-size:12px}
.fortschritt{height:4px;background:#0b1017;border-radius:99px;overflow:hidden;margin:0 0 12px}
.fortschritt-balken{height:100%;width:0;background:var(--acc);transition:width .2s}
.browse-item{padding:8px 12px;cursor:pointer;border-bottom:1px solid #1b2430;font-size:13px}
.browse-item:hover{background:#1b2534}
.net-body{margin:14px 0;font-size:14px}
/* "Alles ruhig" in der Sicherheitsuebersicht. Eine leere Liste ohne Wort dazu
   liest sich wie ein Fehler - deshalb steht die Entwarnung ausdruecklich da,
   und zwar in der Farbe, die im Panel sonst "laeuft" bedeutet. */
.ok-text{color:var(--ok);font-weight:600}
/* Wer hinter einem Sicherheitsvorfall steckt. Die erste Frage beim Blick auf
   die Liste - deshalb in voller Textfarbe statt gedaempft wie der Rest. */
.wache-wer{margin-top:4px;font-size:13px;font-weight:600}
/* ---- Formular "Neuen Server anlegen": Vorlagen als kleine Chips ---- */
.templates.schmal{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin:-6px 0 4px}
.templates.schmal .tpl{display:inline-block;background:#0b1017;border:1px solid var(--line);
  border-radius:99px;padding:4px 11px;font-size:12px;color:var(--muted);cursor:pointer;font-family:inherit}
.templates.schmal .tpl:hover{color:var(--text);border-color:var(--acc)}
.tpl-titel{font-size:12px;color:var(--muted);margin-right:2px}
.feld-hilfe{display:block;font-size:12px;color:var(--muted);margin-top:6px;line-height:1.5}
.mehr{border:1px solid var(--line);border-radius:9px;padding:0;margin:4px 0}
.mehr>summary{padding:10px 14px;cursor:pointer;font-size:13px;color:var(--muted);user-select:none}
.mehr>summary:hover{color:var(--text)}
.mehr[open]>summary{border-bottom:1px solid var(--line)}
.mehr-inhalt{padding:14px}
.mehr-inhalt>label{display:block;margin-bottom:12px}

/* ---- Notizen: links die Liste, rechts der Text ----
   Auf schmalen Bildschirmen untereinander - nebeneinander waere dort weder
   die Liste noch der Text zu gebrauchen. */
.notiz-leiste{display:flex;gap:10px;align-items:center;margin:14px 0 10px}
.notiz-leiste input{flex:1;margin:0}
.notiz-raum{display:grid;grid-template-columns:240px 1fr;gap:14px;min-height:46vh}
@media(max-width:760px){.notiz-raum{grid-template-columns:1fr}}

.notiz-liste{display:flex;flex-direction:column;gap:6px;max-height:52vh;overflow:auto;
  border:1px solid var(--line);border-radius:11px;padding:8px;background:#0b1017}
.notiz-eintrag{display:block;width:100%;text-align:left;background:transparent;border:1px solid transparent;
  border-radius:8px;padding:8px 10px;color:var(--txt);cursor:pointer;font:inherit;font-size:13px}
.notiz-eintrag:hover{border-color:var(--line)}
.notiz-eintrag.aktiv{background:rgba(255,255,255,.06);border-color:var(--acc)}
.notiz-eintrag b{display:block;margin-bottom:2px;font-weight:600}
.notiz-eintrag .stelle{display:block;color:var(--muted);font-size:11.5px;line-height:1.4}

.notiz-schreib{display:flex;flex-direction:column;gap:10px}
.notiz-schreib input,.notiz-schreib textarea{margin:0}
.notiz-schreib textarea{flex:1;min-height:34vh;font-family:ui-monospace,Consolas,monospace;font-size:13px;line-height:1.55}
.notiz-fuss{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.notiz-fuss .wachse{flex:1}
.anheften{display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--muted);cursor:pointer}
.anheften input{margin:0;cursor:pointer}
.notiz-stand{margin:0;font-size:11.5px;color:var(--muted)}
.notiz-leer{display:grid;place-items:center;color:var(--muted);font-size:13.5px;
  border:1px dashed var(--line);border-radius:11px;padding:24px;text-align:center}

/* ---- NYXUS selbst: Konsole und Steuerung ---- */
.modal-box.gross{max-width:900px;width:94vw}
.panel-werkzeuge{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:14px 0 10px}
.check.klein{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--muted);cursor:pointer}
.check.klein input{margin:0;cursor:pointer}
#panelKonsole{max-height:38vh;min-height:180px}
.panel-gefahr{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin:16px 0 4px;padding-top:14px;border-top:1px solid var(--line)}
.panel-gefahr .muted{flex:1 1 100%;font-size:12px;line-height:1.5;margin:4px 0 0}

/* Hinweiskasten fuer Einschraenkungen, die keine Fehler sind */
.warn-box{background:rgba(230,170,60,.10);border:1px solid rgba(230,170,60,.32);
  border-radius:8px;padding:10px 12px;margin:0 0 14px;font-size:13px;line-height:1.5;color:var(--muted)}
.form{max-width:760px}
.form-actions{display:flex;gap:10px;margin-top:6px}

/* ---------- Ohne Verbindung ----------
 *
 * Ein Balken am unteren Rand statt einer kurzen Einblendung: Solange keine
 * Verbindung besteht, soll er stehen bleiben. Unten, weil oben die Kopfzeile
 * sitzt und am Telefon der Daumen unten ist. */
.netz-balken{
  position:fixed;left:0;right:0;bottom:0;z-index:70;
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  background:#3b1d22;border-top:1px solid #7a2f3a;color:#ffc9c9;
  padding:12px 16px calc(12px + env(safe-area-inset-bottom));
  font-size:13px;line-height:1.5;
  box-shadow:0 -8px 24px rgba(0,0,0,.4);
}
.netz-balken b{color:#ff9d9d}
.netz-balken .btn{margin-left:auto}
@media(max-width:820px){
  .netz-balken{font-size:12.5px;padding:11px 13px calc(11px + env(safe-area-inset-bottom))}
  .netz-balken .btn{margin-left:0;flex:1 1 100%}
}

/* ---------- Toasts ---------- */
.toasts{position:fixed;right:18px;bottom:18px;display:flex;flex-direction:column;gap:8px;z-index:60}
.toast{background:var(--card);border:1px solid var(--line);border-left:3px solid var(--acc);padding:11px 15px;border-radius:9px;font-size:13px;max-width:340px;box-shadow:0 8px 26px rgba(0,0,0,.45)}
.toast.ok{border-left-color:var(--online)}
.toast.bad{border-left-color:var(--bad)}

@media(max-width:980px){
  .data-wrap{grid-template-columns:1fr}
  .data-nav{flex-direction:row;max-height:none;flex-wrap:wrap}
  /* Auf schmalen Bildschirmen steht die Dateiliste über dem Editor, sonst
   * bliebe für den Text keine lesbare Breite mehr. */
  .code-wrap{grid-template-columns:1fr}
  .code-liste{max-height:30vh}
  .code-titel{max-width:100%}
  /* Auf schmalen Bildschirmen rutscht die Vorschau unter das Formular. */
  .ansage-wrap{grid-template-columns:1fr}
}

/* ------------------------------------------------------------------ Handy
 *
 * Auf einem Telefon ist nebeneinander kein Platz. Statt alles zu schrumpfen,
 * bis nichts mehr lesbar ist, zeigt der Bildschirm nur eines: entweder die
 * Serverliste oder den gewählten Server. Ein Knopf führt zurück.
 *
 * Die Knopfleiste oben wird zu einem Menü - acht Schaltflächen nebeneinander
 * passen auf keine Telefonbreite.
 */
.nur-handy{display:none}

@media(max-width:820px){
  .grid2{grid-template-columns:1fr}

  /* --- Kopfzeile ---
     Der z-index ist hier entscheidend: Kopfzeile und Inhalt stehen weiter
     oben beide auf z-index 1, und bei Gleichstand gewinnt das, was spaeter
     im Dokument kommt - der Inhalt. Das aufgeklappte Menue lag dadurch
     dahinter und schimmerte nur durch. Die Kopfzeile muss also selbst hoeher
     liegen; der z-index des Menues allein reicht nicht, weil er nur
     innerhalb der Kopfzeile zaehlt. */
  .topbar{flex-wrap:wrap;gap:8px;padding:10px 12px;position:relative;z-index:20}
  .nur-handy{display:inline-flex}
  /* Beschriftungen, fuer die auf einem Telefon kein Platz ist - beim NOTAUS
     bleibt das Zeichen allein stehen, das erkennt man auch ohne Wort. */
  .nur-breit{display:none}
  .brand{font-size:16px;letter-spacing:2px;gap:7px}
  .brand-icon{width:20px;height:20px}
  .anlage{font-size:10px;padding:2px 7px;margin-left:6px}
  .top-meta{display:none}
  /* Der eigene Name hat neben vier Knoepfen keinen Platz mehr. Er steht im
     Menue ohnehin nicht mehr - dafuer sagt es "Mein Portal", wer man ist. */
  .topbar .wer{display:none}

  /* Der freie Platz bleibt sichtbar - er ist die eine Zahl, die man auch
     unterwegs wissen will. Nur schmaler, und die Leiste rutscht in eine
     eigene Zeile unter Namen und Knoepfe. */
  .platz{order:9;flex:0 0 100%;gap:7px;margin-top:2px}
  .platz-balken{width:auto;flex:1}
  .platz-text{font-size:11.5px}

  /* Am Telefon nimmt das Menue die volle Breite: fuer ein schwebendes
     Kaestchen ist daneben kein Platz, und die Knoepfe sollen gross genug zum
     Treffen bleiben. Die Hoehengrenze laesst es in sich scrollen, wenn der
     Bildschirm kuerzer ist als die Liste. */
  .top-actions{
    top:100%;left:0;right:0;min-width:0;
    border-radius:0;border:none;border-bottom:1px solid var(--line);
    padding:12px;gap:6px;
    max-height:calc(100dvh - 100%);
  }
  .top-actions .btn{padding:13px 16px;font-size:15px}
  .menue-titel{margin:10px 0 2px}
  .menue-titel:first-of-type{margin-top:4px}

  /* Am Telefon groessere Trefferflaechen fuer die Knoepfe der Kopfzeile. */
  .schnell{padding:9px 13px;font-size:17px;line-height:1;min-width:44px}
  .topbar .spacer{flex:1}

  /* --- Liste oder Detail, nie beides --- */
  .layout{grid-template-columns:1fr;position:relative}
  .sidebar{border-right:none;max-height:none}
  .detail{padding:14px 14px 24px}

  /* Ist ein Server gewählt, tritt die Liste zurück. */
  .app.zeigt-detail .sidebar{display:none}
  .app:not(.zeigt-detail) .detail{display:none}
  .zurueck{align-self:flex-start;margin-bottom:12px}

  /* --- Kopfzeile unter der Statusleiste ---
     Die App laeuft mit durchscheinender Statusleiste, damit der Bildschirm
     ganz genutzt wird. Ohne diesen Abstand lauefe der Schriftzug darunter
     und waere halb verdeckt. */
  .topbar{padding-top:calc(10px + env(safe-area-inset-top))}
  .topbar,.detail,.sidebar{
    padding-left:max(12px, env(safe-area-inset-left));
    padding-right:max(12px, env(safe-area-inset-right));
  }
  /* Unten die Leiste, mit der man am iPhone nach Hause wischt. */
  .detail{padding-bottom:calc(24px + env(safe-area-inset-bottom))}

  /* --- Fenster fast bildschirmfüllend --- */
  .modal{padding:0;place-items:stretch}
  .modal-box{
    width:100%;max-width:none;max-height:100vh;max-height:100dvh;border-radius:0;
    border-left:none;border-right:none;
    padding:calc(18px + env(safe-area-inset-top)) 16px calc(28px + env(safe-area-inset-bottom));
  }
  .modal-box.gross{width:100%}

  /* --- Anmeldung ---
     Breite ueber den Rahmen statt ueber vw: eine Prozentangabe vom Fenster
     rechnet auf manchen Telefonen mit der Breite ohne Scrollleiste und faellt
     dann zu gross aus. Ein Innenabstand am Rahmen ist verlaesslicher. */
  .login{padding:16px;place-items:center}
  .login-box{width:100%;max-width:400px;padding:26px 22px}
  .login-box .brand{font-size:20px;letter-spacing:5px;text-indent:5px}

  /* --- Sonstiges, das sonst überläuft --- */
  table.kv td:first-child{width:42%}
  .console{font-size:11px}
  .templates.schmal{gap:5px}
  .browse-suche{flex-wrap:wrap}
  .browse-suche input{flex:1 1 100%}
  .panel-werkzeuge,.panel-gefahr,.form-actions{flex-wrap:wrap}
  .panel-gefahr .btn,.form-actions .btn{flex:1 1 auto}
}

/* ------------------------------------------------------ Handy: neue Bereiche
 *
 * Code, Ankündigung, Terminal und Assistent sind nach der ersten Handyfassung
 * dazugekommen. Was sie am Telefon brauchen:
 *
 * **Die Reiter scrollen, statt umzubrechen.** Acht Reiter ergeben umgebrochen
 * drei Zeilen und schieben den Inhalt nach unten. Eine waagerecht scrollbare
 * Leiste ist das, was Apps am Telefon tun - und man sieht am angeschnittenen
 * Reiter am Rand, dass es weitergeht.
 *
 * **Eingabefelder mit 16px.** Ist die Schrift kleiner, zoomt iOS beim
 * Antippen ins Feld hinein und der Rest der Seite rutscht weg.
 *
 * **Fingerbreite Knöpfe.** Alles, was angetippt wird, ist mindestens 44px
 * hoch - darunter trifft man mit dem Daumen daneben.
 */
@media(max-width:820px){
  /* --- Reiterleiste --- */
  .tabs{
    flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;
    scrollbar-width:none;-webkit-overflow-scrolling:touch;
    scroll-snap-type:x proximity;margin-bottom:12px;
  }
  .tabs::-webkit-scrollbar{display:none}
  .tab{flex:0 0 auto;scroll-snap-align:start;padding:11px 13px;font-size:13.5px}

  /* --- Eingaben: 16px gegen das Hineinzoomen --- */
  input,select,textarea{font-size:16px}
  .mini,.btn.sm{font-size:14px}

  /* --- Ankündigung --- */
  .ansage-wrap{gap:14px}
  .ansage-rechts{order:-1}            /* Vorschau nach oben: man schreibt und sieht */
  .ansage-vorschau{max-height:40vh;overflow:auto}
  .rollen-liste{max-height:34vh}
  .rolle{padding:8px 13px;font-size:13.5px}    /* fingerbreit */
  .bild-zeile .btn{flex:1 1 auto}
  .bild-wo{flex-direction:column;gap:9px}
  .bot-server li{font-size:12.5px}

  /* --- Code --- */
  .code-liste{max-height:26vh}
  .code-item{padding:9px 11px;font-size:13px}
  .code-editor-wrap{min-height:44vh;max-height:60vh}
  .code-editor,.code-zeilen{font-size:12px;line-height:1.6}
  .code-bar{gap:8px}
  .code-bar .btn{flex:1 1 auto}

  /* --- Assistent ---
     Das Fenster ist am Telefon bildschirmfüllend; die eigene Breite aus der
     Grundfassung muss dafür weichen. */
}

/* Sehr schmale Geräte */
@media(max-width:380px){
  .brand{font-size:14px}
  .detail{padding:12px 10px 20px}
  .modal-box{padding:14px 12px 24px}
  .tab{padding:10px;font-size:13px}
  .rollen-liste{max-height:28vh}
  .ansage-vorschau{max-height:34vh}
}

/* ---------- Terminal ----------
   Die Kommandozeile steckt in einem eingebetteten Rahmen: ttyd bringt seine
   eigene Darstellung mit, das Panel gibt nur den Platz und den Rahmen. Hoehe
   wie beim Code-Editor, damit beide Reiter gleich gross wirken. */
.terminal-rahmen{
  display:flex;flex:1;min-height:300px;max-height:60vh;overflow:hidden;
  background:#0b0e14;border:1px solid var(--line);border-radius:10px;
}
.terminal-rahmen iframe{flex:1;width:100%;border:0;background:#0b0e14}

/* Tasten, die es auf einer Handytastatur nicht gibt. Sie duerfen umbrechen -
   auf einem schmalen Bildschirm stehen sie dann eben in zwei Reihen. */
.terminal-tasten{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:8px}
.terminal-tasten .btn{font-family:var(--mono);min-width:46px}
.terminal-tasten .spacer{flex:1;min-width:0}

#terminalZeile{font-family:var(--mono)}

/* Am Handy zaehlt jeder Millimeter Hoehe: dort bekommt das Terminal mehr
   Platz, und die Zusatztasten ruecken enger zusammen. */
@media (max-width:760px){
  .terminal-rahmen{min-height:46vh;max-height:64vh}
  .terminal-tasten{gap:6px}
  .terminal-tasten .spacer{flex:0 0 100%;height:0}
}