/* ===========================================================
   Global-VZLA · Plataforma Web — Hub (app.)
   -----------------------------------------------------------
   Migrado al sistema de diseño compartido el 2026-08-09 (piloto).
   Reset, tipografía, botones, campos, tablas, modales, avisos y
   layout vienen de ../shared/. Acá vive SOLO lo que es propio del
   hub: la atmósfera orbital, la tarjeta de acceso, las tarjetas de
   herramienta y el panel de administración.

   Regla: ningún color fijo. Todo por var(--token).
   Ver ../shared/DESIGN.md.
   =========================================================== */

/* ===========================================================
   ATMÓSFERA ORBITAL
   -----------------------------------------------------------
   La identidad del hub: anillos concéntricos con dos nodos que
   los recorren, sobre una grilla que se desvanece hacia los
   bordes. Todo por token, así que respira con el tema.
   =========================================================== */
.bg-field{
  position:fixed; inset:0; z-index:0; overflow:hidden;
  background:
    radial-gradient(880px 620px at 80% 8%,  color-mix(in srgb, var(--cyan) 20%, transparent), transparent 62%),
    radial-gradient(980px 720px at 14% 92%, color-mix(in srgb, var(--accent) 26%, transparent), transparent 62%),
    var(--bg);
}
.orbit{
  position:absolute; top:50%; left:50%;
  border-radius:var(--r-full);
  border:1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  transform:translate(-50%,-50%);
}
.orbit--1{ width:520px;  height:520px;  animation:bg-spin 60s linear infinite; }
.orbit--2{ width:820px;  height:820px;  animation:bg-spin 90s linear infinite reverse;
           border-color:color-mix(in srgb, var(--cyan) 20%, transparent); }
.orbit--3{ width:1180px; height:1180px;
           border-color:color-mix(in srgb, var(--accent) 15%, transparent); }

.node{
  position:absolute; top:50%; left:50%;
  width:10px; height:10px; border-radius:var(--r-full);
  background:var(--cyan);
  box-shadow:0 0 22px 5px color-mix(in srgb, var(--cyan) 70%, transparent);
}
/* El transform-origin es el negativo exacto del translate: así el nodo gira
   alrededor del centro del anillo y no de sí mismo. */
.node--a{ transform:translate(248px,-262px);  animation:bg-spin 60s linear infinite;         transform-origin:-248px 262px; }
.node--b{ transform:translate(-408px,402px);  animation:bg-spin 90s linear infinite reverse; transform-origin:408px -402px;
          width:7px; height:7px; background:var(--accent-2);
          box-shadow:0 0 18px 4px color-mix(in srgb, var(--accent-2) 75%, transparent); }

/* La grilla de fondo. Es lo que le da el aire de consola de operaciones: sin
   ella, los halos solos quedan como un degradado genérico. Se desvanece hacia
   los bordes para que no compita con el contenido. */
.grid-overlay{
  position:absolute; inset:0; opacity:.7;
  background-image:
    linear-gradient(color-mix(in srgb, var(--text-3) 26%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--text-3) 26%, transparent) 1px, transparent 1px);
  background-size:56px 56px;
  -webkit-mask-image:radial-gradient(circle at 50% 45%, #000 0%, transparent 72%);
  mask-image:radial-gradient(circle at 50% 45%, #000 0%, transparent 72%);
}
@keyframes bg-spin{ to{ transform:translate(-50%,-50%) rotate(360deg); } }

/* ===========================================================
   ACCESO
   =========================================================== */
/* En el login no hay barra superior, así que el control de tema e
   idioma flota arriba a la derecha. */
#prefs-login{ position:fixed; top:var(--sp-5); right:var(--sp-6); z-index:6; }

.login-stage{
  position:relative; z-index:1;
  min-height:100vh;
  display:grid; place-items:center;
  padding:var(--sp-8);
}
.login-card{
  position:relative; overflow:hidden;
  width:100%; max-width:430px;
  padding:var(--sp-10) var(--sp-8) var(--sp-6);
  background:linear-gradient(180deg, var(--surface-2), var(--surface));
  border:1px solid var(--border-2);
  border-radius:var(--r-xl);
  box-shadow:var(--shadow-lg);
  backdrop-filter:blur(14px);
  animation:rise .7s var(--ease) both;
}
/* Filo de luz sobre el borde superior. Es el único adorno de la tarjeta y hace
   el trabajo de decir "esto es de Global-VZLA" sin poner el logo dos veces:
   arranca en indigo y termina en cian, la lectura de la marca de izquierda a
   derecha. Se apaga en los extremos para que no parezca una barra pegada. */
.login-card::before{
  content:''; position:absolute; top:0; left:0; right:0; height:2px;
  background:var(--grad);
  -webkit-mask-image:linear-gradient(90deg, transparent, #000 22%, #000 78%, transparent);
  mask-image:linear-gradient(90deg, transparent, #000 22%, #000 78%, transparent);
}
@keyframes rise{ from{ opacity:0; transform:translateY(18px) scale(.985); } }

/* La marca centrada y con aire propio: es lo primero que se mira al entrar,
   y antes competía de igual a igual con el título en la misma fila. */
.login-brand{
  display:flex; flex-direction:column; align-items:center; gap:var(--sp-3);
  margin-bottom:var(--sp-8);
  text-align:center;
}
.mark{ flex-shrink:0; width:66px; height:66px;
       filter:drop-shadow(0 6px 20px color-mix(in srgb, var(--accent) 45%, transparent)); }
/* El nodo cian orbita el anillo → .gv-orbit-node en ../shared/layout.css */
.wordmark{
  display:flex; align-items:baseline; gap:7px;
  font-family:var(--font-display); font-weight:700; letter-spacing:-.5px;
}
.wm-1{ font-size:23px; color:var(--text); }
/* `--accent-text` y no `--accent-2`: acá el indigo es texto. Ver tokens.css. */
.wm-2{ font-size:23px; color:var(--accent-text); }

.login-kicker{
  margin-bottom:var(--sp-3);
  font-family:var(--font-mono); font-size:var(--fs-2xs);
  letter-spacing:.3em; text-transform:uppercase;
  color:var(--cyan);
}
/* Antes el título y el kicker tenían casi el mismo peso visual y la pantalla no
   decía por dónde empezar a leer. Ahora el kicker es una etiqueta y el título
   es el que manda. */
.login-title{
  margin-bottom:var(--sp-8);
  font-family:var(--font-display); font-size:29px;
  font-weight:600; letter-spacing:-.03em; line-height:1.15;
}

.field{ display:block; margin-bottom:var(--sp-5); }
.field-label{
  display:block; margin-bottom:var(--sp-2);
  font-family:var(--font-mono); font-size:var(--fs-2xs);
  font-weight:600; letter-spacing:.12em; text-transform:uppercase;
  color:var(--text-3);
}
.field input{
  width:100%; height:var(--h-lg);
  padding:0 var(--sp-4);
  background:var(--bg);
  border:1px solid var(--border-2);
  border-radius:var(--r-md);
  color:var(--text);
  font-family:var(--font-body); font-size:var(--fs-md);
  transition:border-color var(--t), box-shadow var(--t);
}
.field input::placeholder{ color:var(--text-3); }
.field input:hover{ border-color:var(--text-3); }
.field input:focus{ outline:none; border-color:var(--accent-2); box-shadow:var(--ring); }

/* Ojito de la contraseña. Se posiciona contra el envoltorio, nunca contra el
   campo: dentro de un <label> el input no es el bloque de referencia. */
.pass-wrap{ position:relative; display:block; }
.pass-wrap input{ width:100%; padding-right:var(--sp-10); }
.pass-toggle{
  position:absolute; right:var(--sp-2); top:50%; transform:translateY(-50%);
  display:grid; place-items:center; width:30px; height:30px;
  border-radius:var(--r-sm);
  color:var(--text-3); cursor:pointer;
  transition:color var(--t), background var(--t);
}
.pass-toggle:hover{ color:var(--accent-text); background:var(--surface-2); }

.login-error{
  margin:calc(var(--sp-1) * -1) 0 var(--sp-4);
  padding:var(--sp-2) var(--sp-3);
  background:var(--danger-soft);
  border:1px solid var(--danger-line);
  border-radius:var(--r-sm);
  color:var(--danger);
  font-size:var(--fs-base);
}

/* Botón principal. Vive acá y no en components.css porque el hub lo usa con su
   propio nombre desde antes; el aspecto sale del sistema igual. */
.btn-primary{
  display:flex; align-items:center; justify-content:center; gap:var(--sp-2);
  width:100%; height:52px; margin-top:var(--sp-6);
  background:var(--accent); color:var(--on-accent);
  border:none; border-radius:var(--r-md);
  font-family:var(--font-display); font-size:15px;
  font-weight:600; letter-spacing:.3px;
  cursor:pointer;
  box-shadow:0 12px 30px -12px var(--accent);
  transition:background var(--t), transform var(--t-fast), box-shadow var(--t);
}
.btn-primary:hover{ background:var(--accent-2); transform:translateY(-1px); box-shadow:0 18px 38px -12px var(--accent); }
.btn-primary:active{ transform:translateY(0); }
.btn-primary:disabled{ opacity:.45; pointer-events:none; }
.btn-primary .ico{ display:grid; place-items:center; transition:transform var(--t); }
.btn-primary:hover .ico{ transform:translateX(3px); }

.link-btn{
  margin-top:var(--sp-3); padding:0;
  background:none; border:none;
  color:var(--accent-text); font-family:var(--font-body); font-size:var(--fs-base);
  text-decoration:underline; text-underline-offset:3px;
  cursor:pointer;
}
.link-btn:hover{ color:var(--cyan); }

.login-foot{
  margin-top:var(--sp-5);
  font-family:var(--font-mono); font-size:var(--fs-xs);
  letter-spacing:.4px; text-align:center;
  color:var(--text-3);
}

/* ===========================================================
   HUB
   =========================================================== */
.hub{ position:relative; z-index:1; min-height:100vh; animation:fade .5s ease both; }
@keyframes fade{ from{ opacity:0; } }

/* Barra superior. Mismo orden que en las 5 herramientas: marca a la izquierda,
   tema / idioma / acciones / identidad a la derecha.
   Se aligeró a propósito: fondo semitransparente con desenfoque en vez de un
   bloque sólido, y borde apenas insinuado. Así la atmósfera orbital se ve pasar
   por debajo y la barra deja de leerse como una franja pegada arriba. */
.hub-top{
  position:sticky; top:0; z-index:var(--z-topbar);
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-4);
  min-height:60px;
  padding:var(--sp-2) clamp(var(--sp-4), 3vw, var(--sp-8));
  background:color-mix(in srgb, var(--bg-2) 76%, transparent);
  backdrop-filter:blur(14px) saturate(1.4);
  border-bottom:1px solid color-mix(in srgb, var(--border) 60%, transparent);
}
.hub-brand{ display:flex; align-items:center; gap:var(--sp-3); }
button.hub-brand{ background:none; border:none; padding:0; color:inherit; font:inherit; cursor:pointer; }
button.hub-brand:hover{ opacity:.85; }
.hub-brand-name{ font-family:var(--font-display); font-size:var(--fs-lg); font-weight:700; letter-spacing:.5px; }

.hub-actions{ display:flex; align-items:center; gap:var(--sp-4); }
.hub-user{ display:flex; align-items:center; gap:var(--sp-3); }
.hub-user-meta{ display:flex; flex-direction:column; align-items:flex-end; gap:2px; }
.hub-user-name{ font-size:var(--fs-base); font-weight:500; }

.hub-avatar{
  display:grid; place-items:center; flex:0 0 auto;
  width:var(--h-md); height:var(--h-md);
  border-radius:var(--r-md);
  background:var(--grad-solid); color:var(--on-solid);
  font-family:var(--font-display); font-size:var(--fs-base); font-weight:700;
  box-shadow:0 6px 16px -6px var(--accent);
}

.btn-ghost{
  display:inline-flex; align-items:center; gap:var(--sp-2);
  height:var(--h-md); padding:0 var(--sp-3);
  background:transparent;
  border:1px solid var(--border-2); border-radius:var(--r-md);
  color:var(--text-2);
  font-family:var(--font-body); font-size:var(--fs-base);
  cursor:pointer; white-space:nowrap;
  transition:color var(--t), border-color var(--t), background var(--t);
}
.btn-ghost:hover{ color:var(--text); border-color:var(--accent-2); background:var(--surface-2); }

.hub-main{ max-width:1120px; margin:0 auto; padding:var(--sp-12) var(--sp-8) var(--sp-12); }
/* El saludo necesita separarse de las tarjetas o se lee como si fuera parte de
   la primera. El aire de abajo es lo que lo convierte en encabezado. */
.hub-head{
  margin-bottom:var(--sp-12);
  padding-bottom:var(--sp-6);
  border-bottom:1px solid color-mix(in srgb, var(--border) 70%, transparent);
}
.hub-kicker{
  display:inline-flex; align-items:center; gap:var(--sp-2);
  margin-bottom:var(--sp-4);
  font-family:var(--font-mono); font-size:var(--fs-2xs);
  letter-spacing:.3em; text-transform:uppercase;
  color:var(--cyan);
}
/* Guion corto delante de la etiqueta: le da un punto de partida a la lectura,
   igual que la rayita del riel marca dónde estás. */
.hub-kicker::before{
  content:''; width:22px; height:1px; flex:0 0 auto;
  background:currentColor; opacity:.7;
}
.hub-greeting{ font-family:var(--font-display); font-size:38px; font-weight:600; letter-spacing:-.03em; line-height:1.1; }
/* El nombre en el gradiente de marca: el único texto de la pantalla que lo lleva.
   Va con `--grad-text`, que es la versión pensada para eso: acá el gradiente ES
   el texto y se apoya sobre el fondo de la página, así que en tema oscuro los
   extremos tienen que ser CLAROS. Ver tokens.css. */
.hub-greeting span{
  background:var(--grad-text);
  -webkit-background-clip:text; background-clip:text;
  -webkit-text-fill-color:transparent;
}
.hub-sub{ margin-top:var(--sp-2); color:var(--text-2); font-size:var(--fs-md); }

/* ===========================================================
   TARJETAS DE HERRAMIENTA
   -----------------------------------------------------------
   Estructura de arriba abajo: ícono → nombre + dominio → qué hace →
   pie con la acción. El pie va separado por una línea y empujado al
   fondo (`margin-top:auto`), así todas las tarjetas terminan a la
   misma altura aunque la descripción sea más corta o más larga.
   Antes el "Abrir" flotaba pegado al texto y cada tarjeta lo tenía a
   una altura distinta.
   =========================================================== */
/* `grid-auto-rows:1fr` para que TODAS las filas midan lo mismo, no solo las
   tarjetas dentro de una misma fila. Con dos filas de tres, una descripción de
   3 líneas arriba y de 2 abajo dejaba los pies desalineados entre filas. */
.tools-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(320px,1fr)); grid-auto-rows:1fr; gap:var(--sp-5); }

.tool-card{
  position:relative; overflow:hidden;
  display:flex; flex-direction:column; gap:var(--sp-4);
  padding:var(--sp-6) var(--sp-6) 0;
  background:linear-gradient(180deg, var(--surface-2), var(--surface));
  border:1px solid var(--border);
  border-radius:var(--r-xl);
  transition:transform var(--t), border-color var(--t), box-shadow var(--t);
  animation:cardin .55s var(--ease) both;
}
@keyframes cardin{ from{ opacity:0; transform:translateY(14px); } }

/* Halo de marca que aparece al pasar el mouse. `pointer-events:none` para que
   no se coma el clic de la tarjeta. */
.tool-card::after{
  content:''; position:absolute; inset:0; z-index:0;
  border-radius:var(--r-xl);
  background:radial-gradient(420px 160px at 88% -12%, color-mix(in srgb, var(--accent) 22%, transparent), transparent 70%);
  opacity:0; pointer-events:none;
  transition:opacity var(--t-slow);
}
.tool-card > *{ position:relative; z-index:1; }
.tool-card.is-enabled:hover{ transform:translateY(-4px); border-color:var(--accent-line); box-shadow:var(--shadow-lg); }
.tool-card.is-enabled:hover::after{ opacity:1; }

/* El ícono deja de ser un cuadradito de relleno plano: gana tamaño, un
   degradado propio y un filo de luz arriba. Es lo que hace que la tarjeta se
   lea de un vistazo en una grilla de seis. */
.tool-ico{
  position:relative;
  display:grid; place-items:center; flex:0 0 auto;
  width:58px; height:58px;
  border-radius:var(--r-lg);
  background:linear-gradient(150deg,
    color-mix(in srgb, var(--accent) 26%, transparent),
    color-mix(in srgb, var(--cyan) 12%, transparent));
  border:1px solid var(--accent-line);
  color:var(--accent-text);
  box-shadow:inset 0 1px 0 color-mix(in srgb, var(--accent) 34%, transparent);
}
.tool-ico svg{ width:26px; height:26px; }
.tool-card.is-enabled:hover .tool-ico{ border-color:var(--accent); }

.tool-name{ font-family:var(--font-display); font-size:19px; font-weight:700; letter-spacing:-.02em; }
/* El dominio es referencia, no información principal: baja de tamaño y de
   contraste para que el nombre se lea primero. */
.tool-domain{ margin-top:3px; font-family:var(--font-mono); font-size:var(--fs-2xs); letter-spacing:.02em; color:var(--text-3); }
.tool-desc{ flex:1; color:var(--text-2); font-size:var(--fs-base); line-height:var(--lh-loose); }

/* Pie de la tarjeta: separado por una línea y al ras de los bordes. */
.tool-cta{
  display:flex; align-items:center; gap:var(--sp-2);
  margin-top:auto;
  margin-inline:calc(var(--sp-6) * -1);
  padding:var(--sp-4) var(--sp-6);
  border-top:1px solid var(--border);
  font-family:var(--font-display); font-size:var(--fs-md); font-weight:600;
  color:var(--accent-text);
}
.tool-card.is-enabled:hover .tool-cta{ background:var(--accent-soft); }
.tool-cta .ico{ display:grid; place-items:center; transition:transform var(--t); }
.tool-card.is-enabled:hover .tool-cta .ico{ transform:translateX(4px); }

/* ---- Sin permiso ----
   La tarjeta NO se saca: esconderla ocultaría que la herramienta existe. Se
   apaga, y el motivo se dice en el pie, donde iría la acción — que es donde el
   ojo va a buscar qué se puede hacer. Antes era una etiqueta chiquita arriba a
   la derecha, lejos de donde se mira. */
.tool-card.is-locked{ opacity:.72; filter:saturate(.4); }
.tool-card.is-locked .tool-ico{
  background:var(--surface-3); border-color:var(--border-2); color:var(--text-3);
  box-shadow:none;
}
.tool-card.is-locked .tool-cta{ color:var(--text-3); font-weight:500; }
.lock-tag{
  display:flex; align-items:center; gap:var(--sp-2);
  margin-top:auto;
  margin-inline:calc(var(--sp-6) * -1);
  padding:var(--sp-4) var(--sp-6);
  border-top:1px solid var(--border);
  font-family:var(--font-mono); font-size:var(--fs-xs);
  letter-spacing:.04em; color:var(--text-3);
}
.lock-tag .ico{ display:grid; place-items:center; }
/* Con "Próximamente" no hay acción posible, así que el pie es la etiqueta. */
.status-soon{
  align-self:flex-start;
  padding:2px var(--sp-2);
  background:var(--warning-soft);
  border:1px solid var(--warning-line);
  border-radius:var(--r-full);
  color:var(--warning);
  font-family:var(--font-mono); font-size:var(--fs-2xs);
  letter-spacing:.1em; text-transform:uppercase;
}

/* ===========================================================
   PANEL DE ADMINISTRACIÓN
   Usuarios / Planes / Consumo / Auditoría.
   Riel persistente a la izquierda + contenido a la derecha: el
   menú no se esconde al cambiar de sección, solo cambia lo de al
   lado. Mismo patrón que el riel de Control de Activos.
   =========================================================== */
.topbar-btn{
  display:inline-flex; align-items:center; gap:var(--sp-2);
  height:var(--h-md); padding:0 var(--sp-3);
  background:var(--accent-soft);
  border:1px solid var(--accent-line); border-radius:var(--r-md);
  color:var(--accent-text);
  font-family:var(--font-body); font-size:var(--fs-base); font-weight:500;
  cursor:pointer; white-space:nowrap;
  transition:border-color var(--t), background var(--t);
}
.topbar-btn:hover{ border-color:var(--accent); background:color-mix(in srgb, var(--accent) 18%, transparent); }
.topbar-btn .ico{ display:grid; place-items:center; }

.admin-shell{ display:flex; align-items:flex-start; gap:var(--sp-6); padding:var(--sp-6) var(--sp-8); }
.admin-nav{
  display:flex; flex-direction:column; gap:var(--sp-1);
  flex:0 0 190px; width:190px;
  padding:var(--sp-2);
  background:linear-gradient(180deg, var(--surface-2), var(--surface));
  border:1px solid var(--border);
  border-radius:var(--r-lg);
}
.admin-nav-btn{
  position:relative;
  display:flex; align-items:center; gap:var(--sp-3);
  width:100%; height:42px; padding:0 var(--sp-3);
  background:transparent; border:none; border-radius:var(--r-md);
  color:var(--text-2);
  font-family:var(--font-body); font-size:var(--fs-base);
  text-align:left; cursor:pointer;
  transition:background var(--t), color var(--t);
}
.admin-nav-btn .ico{ display:grid; place-items:center; flex:0 0 auto; }
.admin-nav-btn:hover{ color:var(--text); background:var(--surface-2); }
/* Activo: fondo tenue + barra de acento. Antes era indigo sólido con texto
   blanco, que en tema claro quedaba blanco sobre casi blanco. */
.admin-nav-btn.is-active{ background:var(--accent-soft); color:var(--accent-text); font-weight:600; }
.admin-nav-btn.is-active::before{
  content:''; position:absolute; left:0; top:9px; bottom:9px;
  width:3px; border-radius:var(--r-full); background:var(--accent);
}
.admin-content{ flex:1; min-width:0; }

.admin-head{
  display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap;
  gap:var(--sp-3); margin-bottom:var(--sp-4);
}
.admin-head h2{ font-family:var(--font-display); font-size:var(--fs-xl); font-weight:700; }
.admin-head-actions{ display:flex; align-items:center; flex-wrap:wrap; gap:var(--sp-3); }
/* El "Agregar usuario" del encabezado es un botón, no un bloque: sin esto
   hereda el width:100% del .btn-primary del login. */
.admin-head .btn-primary{ width:auto; height:var(--h-md); margin-top:0; padding:0 var(--sp-4); font-size:var(--fs-base); }

.admin-note{ margin:calc(var(--sp-1) * -1) 0 var(--sp-4); color:var(--text-2); font-size:var(--fs-base); }
.modal-note{ margin:var(--sp-2) 0 2px; color:var(--text-2); font-size:var(--fs-sm); }

/* ---- Tablas del panel ----
   La estructura (encabezado centrado, ancho ajustable, orden por columna) la da
   .gv-table de ../shared/components.css. Acá solo lo propio del panel. */
.admin-table-wrap{ overflow:auto; border:1px solid var(--border); border-radius:var(--r-lg); }
.admin-table{ width:100%; border-collapse:collapse; }
.admin-table tfoot td{ padding-top:var(--sp-2); border-top:1px solid var(--border-2); font-weight:600; }
/* Cliente que no gastó nada en el período: se ve, pero apagado. Que falte se
   leería como un error del panel; que grite, como un problema que no es. */
.admin-table tr.is-idle td{ opacity:.6; }

.chip{
  display:inline-block; margin:2px;
  padding:2px var(--sp-2);
  border:1px solid var(--border); border-radius:var(--r-full);
  background:var(--surface-2); color:var(--text-2);
  font-family:var(--font-mono); font-size:var(--fs-xs);
}
.chip-all{ border-color:var(--accent-line); background:var(--accent-soft); color:var(--accent-text); }

.role-badge{
  display:inline-block;
  padding:1px var(--sp-2);
  border:1px solid var(--border); border-radius:var(--r-full);
  color:var(--text-2);
  font-family:var(--font-mono); font-size:var(--fs-2xs);
  letter-spacing:.1em; text-transform:uppercase;
}
.role-badge[data-role="Admin"],
.role-badge[data-role="admin"]{ border-color:var(--accent-line); background:var(--accent-soft); color:var(--accent-text); }
.role-badge[data-role="General"],
.role-badge[data-role="general"]{ border-color:var(--info-line); background:var(--info-soft); color:var(--info); }

.badge-on{ color:var(--success); font-size:var(--fs-base); }
.badge-off{ color:var(--text-3); font-size:var(--fs-base); }
.muted{ color:var(--text-2); }
.mono{ font-family:var(--font-mono); font-size:var(--fs-sm); white-space:nowrap; }

.row-actions{ display:flex; align-items:center; gap:var(--sp-1); }
.row-actions button{
  display:grid; place-items:center;
  width:30px; height:30px;
  background:none; border:1px solid var(--border); border-radius:var(--r-sm);
  color:var(--text-2); cursor:pointer; line-height:0;
  transition:border-color var(--t), color var(--t), background var(--t);
}
.row-actions button:hover{ border-color:var(--accent); color:var(--accent-text); background:var(--accent-soft); }
/* Acción que no aplica a esta fila (ej. "entrar al ambiente" en el admin, que
   no tiene ambiente propio): se dibuja SIEMPRE en el mismo lugar, apagada, para
   que las filas queden alineadas. Sacarla desalinea toda la columna. */
.row-actions button:disabled{ opacity:.3; cursor:default; pointer-events:none; }
.row-actions button:disabled:hover{ border-color:var(--border); color:var(--text-2); background:none; }
/* Fila en la que el admin está parado ahora mismo. Mismo ámbar que el cartel
   de arriba: los dos hablan de lo mismo. */
.row-actions button.is-inside{ border-color:var(--warning); background:var(--warning-soft); color:var(--warning); }
.row-actions button.is-inside:hover{ border-color:var(--warning); color:var(--warning); }

/* ---- Auditoría ---- */
.audit-sub{ margin:var(--sp-6) 0 var(--sp-2); font-family:var(--font-display); font-size:var(--fs-lg); font-weight:600; }
.audit-filters{ display:flex; align-items:flex-end; gap:var(--sp-3); margin-bottom:var(--sp-3); }
.audit-filters label{ display:flex; flex-direction:column; gap:var(--sp-1); font-size:var(--fs-sm); color:var(--text-2); }
.audit-filters select{
  height:var(--h-sm); padding:0 var(--sp-2);
  background:var(--bg); border:1px solid var(--border-2); border-radius:var(--r-sm);
  color:var(--text); font-family:var(--font-body); font-size:var(--fs-base);
}
/* Entrada a un ambiente que quedó sin cerrar. La entrada no caduca sola, así
   que una abierta es lo que hay que ver de un vistazo. */
#audit-abiertas .is-open td{ background:var(--warning-soft); }

/* ---- Consumo ---- */
.periodo-tabs{ display:flex; gap:2px; padding:3px; background:var(--surface-2); border-radius:var(--r-md); }
.periodo-tabs button{
  padding:var(--sp-1) var(--sp-3);
  border:none; border-radius:var(--r-sm);
  background:none; color:var(--text-2);
  font-family:var(--font-body); font-size:var(--fs-base);
  cursor:pointer;
  transition:background var(--t), color var(--t);
}
.periodo-tabs button:hover{ color:var(--text); }
.periodo-tabs button.is-on{ background:var(--accent); color:var(--on-accent); font-weight:600; }

.espacio-box{
  display:flex; align-items:baseline; flex-wrap:wrap; gap:var(--sp-3);
  margin-bottom:var(--sp-4); padding:var(--sp-3) var(--sp-4);
  background:var(--surface-2); border:1px solid var(--border); border-radius:var(--r-md);
  font-size:var(--fs-base);
}
.espacio-box .muted{ font-size:var(--fs-sm); }

/* ===========================================================
   MODALES DEL PANEL
   =========================================================== */
.modal-backdrop{
  position:fixed; inset:0; z-index:var(--z-modal);
  display:flex; align-items:center; justify-content:center;
  padding:var(--sp-4);
  background:rgba(4,7,14,.62);
  backdrop-filter:blur(4px);
}
.modal-card{
  position:relative;
  width:min(460px,100%); max-height:90vh; overflow:auto;
  padding:var(--sp-6);
  background:var(--surface);
  border:1px solid var(--border-2);
  border-radius:var(--r-xl);
  box-shadow:var(--shadow-pop);
  animation:gv-modal-in var(--t-slow) var(--ease) both;
}
.modal-card h3{ margin-bottom:var(--sp-4); font-family:var(--font-display); font-size:var(--fs-lg); font-weight:700; }
.modal-close{
  position:absolute; top:var(--sp-3); right:var(--sp-3);
  display:grid; place-items:center;
  width:30px; height:30px;
  background:transparent; border:1px solid var(--border-2); border-radius:var(--r-sm);
  color:var(--text-3); font-size:var(--fs-xl); line-height:1;
  cursor:pointer;
  transition:color var(--t), background var(--t);
}
.modal-close:hover{ color:var(--text); background:var(--surface-2); }

.modal-card label{ display:block; margin:var(--sp-3) 0; font-size:var(--fs-base); color:var(--text-2); }
.modal-card input,
.modal-card select{
  width:100%; height:var(--h-md); margin-top:var(--sp-1);
  padding:0 var(--sp-3);
  background:var(--bg); border:1px solid var(--border-2); border-radius:var(--r-md);
  color:var(--text); font-family:var(--font-body); font-size:var(--fs-md);
  transition:border-color var(--t), box-shadow var(--t);
}
.modal-card input:focus,
.modal-card select:focus{ outline:none; border-color:var(--accent-2); box-shadow:var(--ring); }
.modal-actions{ display:flex; justify-content:flex-end; gap:var(--sp-3); margin-top:var(--sp-5); }
.modal-actions .btn-primary{ width:auto; height:var(--h-md); margin-top:0; padding:0 var(--sp-4); font-size:var(--fs-base); }

.tools-fs{ margin-top:var(--sp-2); padding:var(--sp-2) var(--sp-3); border:1px solid var(--border); border-radius:var(--r-md); }
.tools-fs legend{ padding:0 var(--sp-1); font-size:var(--fs-sm); color:var(--text-2); }
.tools-fs .chk{
  display:inline-flex; align-items:center; gap:var(--sp-1);
  margin-right:var(--sp-4);
  font-size:var(--fs-base); color:var(--text); cursor:pointer;
}
.tools-fs .chk input{ accent-color:var(--accent); }

.forgot-msg{ margin-top:var(--sp-4); color:var(--text-2); font-size:var(--fs-base); line-height:var(--lh); }

/* ===========================================================
   PÁGINA DE RESTABLECER CONTRASEÑA (reset.html)
   =========================================================== */
.reset-page{
  display:flex; align-items:center; justify-content:center;
  min-height:100vh; padding:var(--sp-5);
  background:var(--bg);
}
.reset-card{
  width:min(420px,100%);
  padding:var(--sp-8);
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:var(--r-xl);
  box-shadow:var(--shadow-lg);
}
.reset-card h1{ margin-bottom:var(--sp-1); font-family:var(--font-display); font-size:var(--fs-xl); font-weight:700; color:var(--accent-text); }
.reset-card h2{ margin-bottom:var(--sp-6); font-family:var(--font-display); font-size:var(--fs-2xl); font-weight:700; }
.reset-card label{ display:block; margin:var(--sp-3) 0; font-size:var(--fs-base); color:var(--text-2); }
.reset-card input{
  width:100%; height:var(--h-md); margin-top:var(--sp-1);
  padding:0 var(--sp-3);
  background:var(--bg); border:1px solid var(--border-2); border-radius:var(--r-md);
  color:var(--text); font-family:var(--font-body); font-size:var(--fs-md);
  transition:border-color var(--t), box-shadow var(--t);
}
.reset-card input:focus{ outline:none; border-color:var(--accent-2); box-shadow:var(--ring); }
.reset-msg{ display:block; margin-top:var(--sp-4); font-size:var(--fs-md); line-height:var(--lh); }
.reset-msg.ok{ color:var(--success); }
.reset-msg.err{ color:var(--danger); }

/* ===========================================================
   RESPONSIVO
   =========================================================== */
@media (max-width:860px){
  .admin-shell{ flex-direction:column; align-items:stretch; padding:var(--sp-5) var(--sp-4); }
  .admin-nav{ flex:0 0 auto; flex-direction:row; width:auto; overflow-x:auto; }
  .admin-nav-btn{ width:auto; white-space:nowrap; }
}
@media (max-width:560px){
  .hub-top{ min-height:56px; padding:var(--sp-3) var(--sp-4); }
  .hub-actions{ gap:var(--sp-2); }
  .hub-main{ padding:var(--sp-8) var(--sp-4) var(--sp-10); }
  .hub-greeting{ font-size:var(--fs-2xl); }
  .hub-user-meta{ display:none; }
  .login-card{ padding:var(--sp-8) var(--sp-6) var(--sp-6); }
  #prefs-login{ top:var(--sp-3); right:var(--sp-3); }
}
