/* ============ Temas ============ */
:root,
:root[data-theme="light"] {
  --bg: #8493ac;
  --bg-soft: #d8e0ea;
  --bg-card: #eef1f6;
  --bg-input: #e2e7ee;
  --bg-tab: #dbe3ee;
  --bg-tab-active: #f5f7fb;
  --border: #5e6e8c;
  --text: #141a24;
  --text-dim: #45506a;
  --accent: #2b6fdb;
  --accent-hover: #1f5bc0;
  --accent-soft: rgba(43, 111, 219, .14);
  --ok: #1f9d55;
  --ok-soft: rgba(31, 157, 85, .12);
  --warn: #b97b12;
  --warn-soft: rgba(185, 123, 18, .12);
  --err: #d6334a;
  --err-soft: rgba(214, 51, 74, .12);
  --shadow: 0 1px 2px rgba(20, 30, 50, .06), 0 8px 24px rgba(20, 30, 50, .05);
  --radius: 12px;
  --glass-sweep-gradient: linear-gradient(100deg,
    rgba(255, 143, 163, 0) 0%,
    rgba(255, 143, 163, .55) 18%,
    rgba(255, 217, 143, .55) 34%,
    rgba(255, 255, 255, .65) 50%,
    rgba(143, 211, 255, .55) 66%,
    rgba(183, 156, 255, .55) 82%,
    rgba(183, 156, 255, 0) 100%);
}

/* Tema noche, paleta tipo Steam (azules marinos + acento celeste) */
:root[data-theme="dark"] {
  --bg: #171a21;
  --bg-soft: #1b2838;
  --bg-card: #1b2838;
  --bg-input: #0f1720;
  --bg-tab: #24344a;
  --bg-tab-active: #2a3f5a;
  --border: #2a475e;
  --text: #c7d5e0;
  --text-dim: #8f98a0;
  --accent: #66c0f4;
  --accent-hover: #8fd3ff;
  --accent-soft: rgba(102, 192, 244, .12);
  --ok: #a4d007;
  --ok-soft: rgba(164, 208, 7, .14);
  --warn: #e1b74d;
  --warn-soft: rgba(225, 183, 77, .14);
  --err: #ff6b6b;
  --err-soft: rgba(255, 107, 107, .14);
  --shadow: 0 1px 2px rgba(0, 0, 0, .35), 0 10px 28px rgba(0, 0, 0, .35);
  --radius: 12px;
  --glass-sweep-gradient: linear-gradient(100deg,
    rgba(255, 143, 163, 0) 0%,
    rgba(255, 143, 163, .5) 18%,
    rgba(255, 217, 143, .5) 34%,
    rgba(255, 255, 255, .5) 50%,
    rgba(143, 211, 255, .5) 66%,
    rgba(183, 156, 255, .5) 82%,
    rgba(183, 156, 255, 0) 100%);
}

* { box-sizing: border-box; }

.hidden { display: none !important; }
.field-hint { display: block; margin-top: 5px; font-size: 11px; color: var(--text-dim); }

html, body {
  height: 100%;
}

/* El degradado decorativo vive en <html>, no en <body>: si solo lo pone
   body, el navegador lo "traslada" al lienzo entero de la página y lo
   vuelve a pintar anclado a la esquina de la ventana visible cada vez que
   haces scroll (en vez de quedarse arriba del todo, donde se puso). En
   páginas largas (servidores con muchos servicios) eso se veía como una
   mancha clara suelta por detrás de la tarjeta al bajar. Poniendo el color
   liso en <html> evita ese "traslado" y el degradado se queda fijo, de
   verdad, en la parte de arriba del documento. */
html {
  background: var(--bg);
}

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background:
    radial-gradient(1200px 500px at 10% -10%, var(--accent-soft), transparent 60%),
    var(--bg);
  color: var(--text);
  transition: background-color .25s ease, color .25s ease;
  /* body en columna (cabecera + resto) para que #appBody pueda ocupar
     siempre, como mínimo, lo que quede de alto de ventana (ver más abajo),
     y así en la vista "Barra lateral" la barra llegue hasta abajo del
     todo aunque haya pocos servidores. Si el contenido es más alto que la
     ventana, #appBody sigue pudiendo crecer más allá sin problema. */
  display: flex;
  flex-direction: column;
  min-height: 100%;
}
.topbar { flex-shrink: 0; }
#appBody { flex: 1 0 auto; display: flex; flex-direction: column; }

/* ---- Login ----
   Paleta fija oscura, independiente del tema claro/oscuro del resto de la
   web (el login siempre se ve igual de "techy", como un panel de acceso). */
.login-body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background:
    radial-gradient(1000px 600px at 50% -10%, rgba(79, 209, 197, .10), transparent 60%),
    #0b0f16;
}
.login-box {
  --lg-bg: #121926;
  --lg-border: #223049;
  --lg-text: #e7edf5;
  --lg-text-dim: #7f8ea3;
  --lg-input: #0c121c;
  --lg-accent: #37d67a;
  --lg-accent-hover: #2bc06a;

  background: linear-gradient(180deg, var(--lg-bg), #0e1420);
  border: 1px solid var(--lg-border);
  border-radius: 18px;
  box-shadow: 0 1px 0 rgba(255,255,255,.03) inset, 0 20px 60px rgba(0,0,0,.55);
  padding: 40px 38px 34px;
  width: 340px;
  text-align: center;
  position: relative;
  color: var(--lg-text);
}
.login-badge {
  width: 92px; height: 92px; margin: 0 auto 16px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #1b2638, #0b0f16 70%);
  border: 1px solid var(--lg-border);
  box-shadow: 0 0 0 6px rgba(79, 209, 197, .06), 0 10px 26px rgba(0,0,0,.45);
}
.login-box h1 {
  margin: 2px 0 2px; font-size: 19px; font-weight: 800;
  letter-spacing: 2.5px; text-transform: uppercase; color: var(--lg-text);
}
.login-box .subtitle {
  margin: 0 0 18px; color: var(--lg-text-dim); font-size: 11px;
  letter-spacing: 1.8px; text-transform: uppercase;
}
.login-divider {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  margin: 4px 0 22px; color: var(--lg-text-dim); font-size: 13px;
}
.login-divider::before, .login-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--lg-border);
}
.login-box label {
  display: block; margin-bottom: 16px; font-size: 10.5px; text-align: left;
  color: var(--lg-text-dim); font-weight: 700; letter-spacing: 1.4px; text-transform: uppercase;
}
.login-box input {
  display: block; width: 100%; margin-top: 7px; padding: 12px 13px;
  background: var(--lg-input); border: 1px solid var(--lg-border); border-radius: 9px;
  color: var(--lg-text); font-size: 14px; transition: border-color .15s ease, box-shadow .15s ease;
}
.login-box input:focus {
  outline: none; border-color: var(--lg-accent); box-shadow: 0 0 0 3px rgba(55, 214, 122, .15);
}
.login-submit {
  width: 100%; margin-top: 10px; padding: 13px 16px; font-size: 13px;
  font-weight: 800; letter-spacing: 1.5px; text-transform: uppercase;
  border: none; border-radius: 10px; cursor: pointer; color: #06241a;
  background: linear-gradient(180deg, var(--lg-accent), var(--lg-accent-hover));
  box-shadow: 0 8px 20px rgba(55, 214, 122, .25);
  transition: filter .15s ease, transform .1s ease;
}
.login-submit:hover { filter: brightness(1.06); }
.login-submit:active { transform: translateY(1px); }

.pass-field { position: relative; display: flex; align-items: center; }
.pass-field input { padding-right: 42px; flex: 1; min-width: 0; }
.pass-eye {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  background: none; border: none; cursor: pointer; font-size: 15px;
  padding: 4px 6px; line-height: 1; color: var(--lg-text-dim); z-index: 1;
}
.login-box .pass-eye:hover { color: var(--lg-accent); }
.login-box .alert.error {
  background: rgba(255, 107, 107, .12); color: #ff8080;
  text-align: left; font-size: 12px;
}

/* ---- Top bar ---- */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 28px; border-bottom: 1px solid var(--border);
  background: var(--bg-card);
}
/* En modo día, que la barra de arriba no sea blanca del todo: el mismo
   tono que las pestañas/tarjetas (var(--bg-tab)), para que no deslumbre
   y además quede a juego con ellas. */
:root[data-theme="light"] .topbar {
  background: var(--bg-tab);
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand-icon {
  width: 26px; height: 26px; flex-shrink: 0;
  color: var(--accent);
}
.brand-icon-led { fill: #8fd3ff; }
.brand-icon-vent { fill: rgba(255,255,255,.55); }
:root[data-theme="light"] .brand-icon-vent { fill: rgba(255,255,255,.75); }
.topbar h1 { font-size: 18px; margin: 0; letter-spacing: 1.5px; word-spacing: 3px; }
.brand-version {
  font-size: 10px; font-weight: 700; color: var(--text-dim);
  background: var(--bg-soft); border: 1px solid var(--border); border-radius: 20px;
  padding: 2px 7px; letter-spacing: .02em; align-self: center;
}
.topbar-right { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text-dim); }
.session-user { margin-right: 4px; }

/* ---- Buttons ---- */
.btn {
  border: none; border-radius: 8px; padding: 9px 16px; font-size: 13px;
  cursor: pointer; font-weight: 600; text-decoration: none; display: inline-block;
  transition: background-color .15s ease, color .15s ease, transform .1s ease;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--accent); color: #05131f; }
:root[data-theme="light"] .btn-primary { color: #ffffff; }
.btn-primary:hover { background: var(--accent-hover); }
.btn-ghost { background: transparent; color: var(--text-dim); border: 1px solid var(--border); }
.btn-ghost:hover { color: var(--text); border-color: var(--text-dim); }
.btn-icon { background: var(--bg-soft); border: 1px solid var(--border); padding: 8px 11px; font-size: 14px; }
.btn-sm { padding: 6px 10px; font-size: 12px; border-radius: 6px; }
.btn-ok { background: var(--ok); color: #06241a; }
.btn-warn { background: var(--warn); color: #241c06; }
.btn-danger { background: var(--err); color: #2a0608; }
.btn-outline { background: transparent; border: 1px solid var(--border); color: var(--text); }
.btn-purple { background: #7c5cff; color: #ffffff; }
.btn-purple:hover { background: #6a48f0; }
.btn-green { background: #22c55e; color: #06241a; }
.btn-green:hover { background: #1ea853; }
.btn-lightblue { background: #7dd3fc; color: #06283d; }
.btn-lightblue:hover { background: #5fc3f5; }
.btn-orange-light { background: #ff9f43; color: #2a1403; }
.btn-orange-light:hover { background: #ff8c1f; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

/* ---- Pestañas en filas, centradas, máximo 8 por fila ----
   En vez de una sola fila con scroll horizontal, las pestañas se agrupan
   en filas de hasta 8 (ver app.js) que se centran en la pantalla; si hay
   más de 8 servidores, los siguientes bajan a otra fila debajo.
   El propio contenedor es una "caja" aparte (como la tarjeta del
   servidor, pero algo más ancha): no llega a los bordes de la pantalla y
   queda separado de la cabecera. Esto aplica a Filas, Desplegable y
   Tarjetas; la Barra lateral tiene su propio ajuste más abajo, pegada al
   borde izquierdo como un menú lateral normal. */
.tabs {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: calc(100% - 56px);
  max-width: 1200px;
  margin: 18px auto 0;
  padding: 16px 24px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-card);
  box-shadow: var(--shadow);
}
.tabs-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
}

/* ---- Vista "Filas" ----
   igual que en "Tarjetas": cuadrícula de 6 columnas fijas en vez de dejar
   que el ajuste de línea del navegador decida cuántas caben (eso dejaba
   filas descompensadas, como 5+6+1, cuando algún nombre era más largo).
   El cuadro también se ensancha un poco, como el de Tarjetas, para que
   quepan más cómodas. */
html[data-view="rows"] .tabs {
  max-width: 1320px;
  padding: 16px 28px;
}
html[data-view="rows"] .tabs-row {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  justify-content: stretch;
}
@media (max-width: 1100px) {
  html[data-view="rows"] .tabs-row {
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  }
}
html[data-view="rows"] .tab-btn {
  width: 100%;
  overflow: hidden;
}
html[data-view="rows"] .tab-btn .tab-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

/* ---- Selector "Vista" (icono de cuadritos, junto al logo) ---- */
.view-mode-picker {
  display: flex; align-items: center; gap: 5px;
  margin-left: 14px;
  padding-left: 14px;
  border-left: 1px solid var(--border);
}
.view-mode-icon {
  font-size: 15px; color: var(--text-dim); line-height: 1;
}
.view-mode-picker select {
  background: var(--bg-input); color: var(--text); border: 1px solid var(--border);
  border-radius: 7px; padding: 5px 7px; font-size: 12px; cursor: pointer;
}

/* ---- Vista "Barra lateral" ----
   nav y main pasan a ir uno al lado del otro; las filas de pestañas se
   convierten en una única columna que hace de menú lateral. */
html[data-view="sidebar"] #appBody {
  display: flex;
  flex-direction: row;
  align-items: stretch;
}
html[data-view="sidebar"] .tabs {
  flex-direction: column;
  width: 240px;
  max-width: 240px;
  flex-shrink: 0;
  margin: 0;
  padding: 10px 10px 10px 0;
  border: none;
  border-right: 1px solid var(--border);
  border-radius: 0;
  box-shadow: none;
  background: transparent;
}
html[data-view="sidebar"] .tabs-row {
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
}
html[data-view="sidebar"] .tab-btn {
  border-radius: 8px;
  border: 1px solid transparent;
  justify-content: flex-start;
  width: 100%;
  overflow: hidden;
}
html[data-view="sidebar"] .tab-btn .tab-name {
  overflow: hidden;
  text-overflow: ellipsis;
}
html[data-view="sidebar"] .tab-btn.active {
  box-shadow: none;
  border-left: 3px solid var(--accent);
  border-radius: 0 8px 8px 0;
}
html[data-view="sidebar"] .panel { flex: 1; min-width: 0; }

/* ---- Vista "Desplegable" ----
   un único <select> con todos los servidores, en vez de pestañas. */
html[data-view="dropdown"] .tabs {
  flex-direction: row;
  padding: 14px 28px;
}
.tabs-select {
  display: flex; align-items: center; gap: 10px;
}
.tabs-select-label { font-size: 13px; color: var(--text-dim); }
.tabs-select select {
  background: var(--bg-input); color: var(--text); border: 1px solid var(--border);
  border-radius: 8px; padding: 9px 12px; font-size: 13px; min-width: 260px; cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.tabs-select select:hover {
  border-color: var(--accent);
  box-shadow: 0 4px 12px rgba(43, 111, 219, .18);
}
/* Mismo destello de "cristal" arcoíris que las pestañas/tarjetas, pero
   aplicado al envoltorio del <select> (los navegadores no dejan dibujar
   un ::after sobre el propio <select>). */
.select-wrap {
  position: relative;
  isolation: isolate;
  display: inline-block;
  border-radius: 8px;
  overflow: hidden;
}
.select-wrap::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 16%;
  background: var(--glass-sweep-gradient);
  transform: translateX(-320%) skewX(-18deg);
  pointer-events: none;
}
.select-wrap.shine::after {
  animation: tab-glass-sweep .7s ease-out;
}

/* ---- Vista "Tarjetas" ----
   cada servidor en su propia tarjeta, en una cuadrícula que se adapta al
   ancho de la pantalla. */
html[data-view="cards"] .tabs {
  max-width: 1320px;
  padding: 16px 28px;
}
html[data-view="cards"] .tabs-row {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  justify-content: stretch;
}
/* En pantallas más estrechas, 6 columnas fijas dejarían las tarjetas
   diminutas: a partir de ahí se deja que se acomoden solas (mínimo 150px)
   en vez de forzar siempre 6. */
@media (max-width: 1100px) {
  html[data-view="cards"] .tabs-row {
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  }
}
.tab-btn.tab-card {
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  border-radius: 12px;
  padding: 14px 16px;
  gap: 5px;
  white-space: normal;
  background: var(--bg-tab);
}
.tab-card-top {
  display: flex; align-items: center; gap: 8px; width: 100%;
  font-size: 14px; font-weight: 700; color: var(--text);
}
.tab-card-host { font-size: 11px; color: var(--text-dim); }
.tab-card-count { font-size: 11px; color: var(--text-dim); }
.tab-btn.tab-card.active {
  background: var(--bg-tab-active);
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent) inset;
}

.tab-btn {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 8px;
  background: var(--bg-tab); color: var(--text-dim);
  border: 1px solid var(--border); border-bottom: none;
  padding: 10px 16px; border-radius: 10px 10px 0 0;
  font-size: 13px; font-weight: 600; cursor: pointer;
  white-space: nowrap;
  transition: transform .15s ease, box-shadow .15s ease,
    border-color .15s ease, background-color .15s ease, color .15s ease;
}
/* Destello de "cristal" arcoíris: una franja diagonal, fina, translúcida y
   con degradado de colores suaves, que cruza el botón de izquierda a
   derecha una sola vez al hacer clic — como el reflejo que recorre un
   cristal al moverlo. Recortada al propio botón (overflow:hidden en
   .tab-btn), sin eventos de ratón para no estorbar al clic, y solo se
   anima cuando JS añade la clase .shine (no al pasar el ratón, que ya
   tiene su propio efecto de "levantarse"). */
.tab-btn::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 16%;
  background: var(--glass-sweep-gradient);
  transform: translateX(-320%) skewX(-18deg);
  pointer-events: none;
}
.tab-btn.shine::after {
  animation: tab-glass-sweep .7s ease-out;
}
@keyframes tab-glass-sweep {
  from { transform: translateX(-320%) skewX(-18deg); }
  to { transform: translateX(620%) skewX(-18deg); }
}
/* Efecto al pasar el ratón por encima: se "levanta" un poco y se le marca
   el borde con el color de acento, para que quede claro sobre cuál estás,
   en las cuatro vistas (Filas, Tarjetas, Barra lateral, Desplegable usa su
   propio <select> nativo así que no aplica). La que ya está activa no
   necesita el efecto, ya se distingue de sobra. */
.tab-btn:hover:not(.active):not(.dragging) {
  transform: translateY(-2px);
  border-color: var(--accent);
  color: var(--text);
  box-shadow: 0 6px 16px rgba(43, 111, 219, .22);
}
html[data-view="sidebar"] .tab-btn:hover:not(.active):not(.dragging) {
  transform: translateX(4px);
  background: var(--bg-tab-active);
}
.tab-btn.tab-card:hover:not(.active):not(.dragging) {
  transform: translateY(-3px);
  box-shadow: 0 10px 22px rgba(43, 111, 219, .25);
}
.tab-btn .tab-dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--text-dim);
}
.tab-btn .tab-dot.ok { background: var(--ok); }
.tab-btn .tab-dot.err { background: var(--err); }
.tab-btn.active {
  background: var(--bg-tab-active); color: var(--text);
  border-color: var(--border);
  box-shadow: inset 0 2px 0 var(--accent);
}
.tab-btn { cursor: grab; }
.tab-btn.dragging { opacity: .4; cursor: grabbing; }
.tab-btn.drag-over { border-left: 2px solid var(--accent); }
.tabs-empty { color: var(--text-dim); font-size: 13px; padding: 10px 4px; }

/* ---- Panel del servidor activo ---- */
.panel { padding: 22px 28px 40px; max-width: 1040px; margin: 0 auto; }
.empty-state { color: var(--text-dim); text-align: center; padding: 60px 0; }

.server-panel-card {
  background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px;
}
/* En modo día la tarjeta (blanca) y el fondo de la página (gris muy claro)
   quedaban casi del mismo tono y costaba distinguir dónde acababa una y
   empezaba el otro. Le damos a la tarjeta un borde azulado más marcado y
   una sombra algo más presente solo en modo día (en modo noche ya se
   distinguía bien). */
:root[data-theme="light"] .server-panel-card {
  border-color: #9fb6e0;
  box-shadow: 0 1px 2px rgba(20, 30, 50, .08), 0 10px 26px rgba(43, 111, 219, .12);
}
.server-card-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
.server-card-header h2 { margin: 0; font-size: 17px; }
.server-host { color: var(--text-dim); font-size: 12px; margin-top: 2px; }
.server-actions { display: flex; gap: 5px; flex-wrap: wrap; justify-content: flex-end; }
.server-actions .btn { padding: 8px 11px; font-size: 12px; white-space: nowrap; }

.services-list { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; }

.service-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px; background: var(--bg-input); border: 1px solid var(--border);
  border-radius: 9px; gap: 10px; flex-wrap: wrap;
}
.service-name { font-size: 13px; font-weight: 600; }
.service-pills { display: flex; gap: 6px; margin-top: 4px; }
.service-controls { display: flex; gap: 4px; align-items: flex-start; flex-wrap: wrap; }
.service-controls .icon-btn[data-act-restart] { margin-top: -3px; }
/* La "✕" de quitar servicio tiene que quedar a la misma altura que el
   botón de reiniciar y los interruptores (su pista, no la etiqueta de
   texto de debajo), así que se le da la misma caja de 28px y el mismo
   ajuste de -3px que al botón de reiniciar, en vez de centrarla respecto
   a toda la fila (que es más alta por culpa de las etiquetas "Encendido"
   / "Auto" de debajo de los interruptores). */
.service-controls > .link-btn[data-remove-svc] {
  align-self: flex-start;
  display: inline-flex; align-items: center; justify-content: center;
  height: 28px; margin-top: -3px;
}

.status-pill {
  font-size: 11px; padding: 3px 9px; border-radius: 999px; font-weight: 700; letter-spacing: .2px;
}
.pill-unknown { background: var(--bg-soft); color: var(--text-dim); }
.pill-ok { background: var(--ok-soft); color: var(--ok); }
.pill-err { background: var(--err-soft); color: var(--err); }
.pill-warn { background: var(--warn-soft); color: var(--warn); }
.pill-auto-ok { background: rgba(43, 111, 219, .14); color: #2b6fdb; }

/* ---- Interruptores (power / arranque automático) ---- */
.switch {
  position: relative; display: inline-block; width: 40px; height: 22px; flex: 0 0 auto;
}
.switch.switch-sm { width: 32px; height: 18px; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch-slider {
  position: absolute; inset: 0; cursor: pointer; border-radius: 999px;
  background: var(--err-soft); border: 1px solid var(--err);
  transition: background-color .15s ease, border-color .15s ease;
}
.switch-slider::before {
  content: ""; position: absolute; height: 16px; width: 16px; left: 2px; top: 2px;
  background: var(--err); border-radius: 50%; transition: transform .15s ease;
}
.switch.switch-sm .switch-slider::before { height: 12px; width: 12px; top: 2px; left: 2px; }
.switch input:checked + .switch-slider {
  background: var(--ok-soft); border-color: var(--ok);
}
.switch input:checked + .switch-slider::before {
  background: var(--ok); transform: translateX(18px);
}
.switch.switch-sm input:checked + .switch-slider::before { transform: translateX(14px); }
.switch input:disabled + .switch-slider { opacity: .5; cursor: not-allowed; }

/* "Auto" (arranque automático) usa un verde distinto al de "Encendido"
   cuando está activado, para distinguirlos de un vistazo. Apagado sigue
   siendo rojo, igual que el otro interruptor. */
.switch-auto input:checked + .switch-slider {
  background: rgba(43, 111, 219, .18); border-color: #2b6fdb;
}
.switch-auto input:checked + .switch-slider::before { background: #2b6fdb; }
.switch-label { font-size: 10px; color: var(--text-dim); display: block; text-align: center; margin-top: 3px; letter-spacing: .3px; }

.icon-btn {
  width: 28px; height: 28px; border-radius: 7px; border: 1px solid var(--border);
  background: var(--bg-soft); color: var(--text); cursor: pointer; font-size: 13px;
  display: inline-flex; align-items: center; justify-content: center;
}
.icon-btn:hover { border-color: var(--accent); color: var(--accent); }
.icon-btn:disabled { opacity: .5; cursor: not-allowed; }

.service-controls-group { display: flex; flex-direction: column; align-items: center; }

.add-service-row { text-align: center; padding-top: 14px; display: flex; gap: 10px; justify-content: center; }
.link-btn {
  background: none; border: none; color: var(--accent); cursor: pointer; font-size: 12px; font-weight: 600;
}
.link-btn-danger { color: var(--err); }
.link-btn-danger:hover { text-decoration: underline; }

/* ---- Modal ---- */
.modal {
  position: fixed; inset: 0; background: rgba(5, 8, 14, .6);
  display: flex; align-items: center; justify-content: center; z-index: 50;
  backdrop-filter: blur(2px);
}
.modal.hidden { display: none; }
.modal-box {
  background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 24px; width: 400px; max-width: 92vw;
}
.modal-box h2 { margin: 0 0 6px; font-size: 16px; }
.modal-hint { color: var(--text-dim); font-size: 12px; margin: 0 0 14px; }
.modal-box label { display: block; margin-bottom: 12px; font-size: 13px; color: var(--text-dim); }
.modal-box input,
.modal-box select {
  display: block; width: 100%; margin-top: 6px; padding: 9px 10px;
  background: var(--bg-input); border: 1px solid var(--border); border-radius: 7px;
  color: var(--text); font-size: 13px; font-family: inherit;
}
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 10px; }

#modalTermHelp .modal-box { width: 640px; }
.term-help-text {
  max-height: 50vh;
  overflow: auto;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 12px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 11.5px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
}

/* Casilla "Seleccionar todos" del modal de descubrir servicios. Por
   defecto va desmarcada (igual que antes): solo marca todo de golpe
   cuando el usuario la pulsa, no selecciona nada por sí sola. Se oculta
   cuando no tiene sentido (viendo los servicios ocultos, sin resultados). */
.discover-select-all {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; margin-bottom: 8px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-soft); color: var(--text-dim);
  font-size: 13px; font-weight: 600; cursor: pointer;
}
.discover-select-all input { width: auto; margin: 0; }

.discover-list { max-height: 280px; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; }
.discover-item {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  background: var(--bg-input); border: 1px solid var(--border); border-radius: 8px; font-size: 13px;
}
.discover-item input { width: auto; margin: 0; }

/* ---- Toast ---- */
.toast {
  position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%);
  background: var(--bg-card); border: 1px solid var(--border); padding: 12px 18px;
  border-radius: 9px; font-size: 13px; box-shadow: var(--shadow); z-index: 99;
}
.toast.hidden { display: none; }
.toast.ok { border-color: var(--ok); color: var(--ok); }
.toast.err { border-color: var(--err); color: var(--err); }

.alert { padding: 8px 10px; border-radius: 6px; font-size: 12px; margin-bottom: 12px; }
.alert.error { background: var(--err-soft); color: var(--err); }

@media (max-width: 640px) {
  .topbar { padding: 14px; flex-wrap: wrap; gap: 10px; }
  .tabs, .panel { padding-left: 14px; padding-right: 14px; }
  .session-user { display: none; }
}

/* Seguridad: lista de IPs bloqueadas */
.security-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 8px;
  background: var(--bg-input);
}
.security-row-locked { border-color: #d64545; }
.badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .03em;
  padding: 2px 7px;
  border-radius: 20px;
  margin-left: 8px;
  vertical-align: middle;
}
.badge-err { background: #d64545; color: #fff; }

/* Barra de estadísticas del servidor (CPU/RAM/disco/uptime), dentro del
   propio box de cada servidor, al final del todo. */
.stats-bar {
  margin-top: 14px;
  padding: 8px 12px;
  font-size: 11px;
  color: var(--text-dim);
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: 7px;
  white-space: nowrap;
  overflow-x: auto;
}
