/* ==========================================================================
   Nube Zenercom — portal de clientes.
   Reutiliza los tokens del sitio (/css/zenercom.css) y añade lo propio del
   portal: acceso, tarjetas de equipo y la gráfica de telemetría.
   ========================================================================== */

body.nube { background: var(--fondo-suave); }

/* ------------------------------------------------------------ Acceso --- */
.acceso {
    min-height: 100vh; display: grid; place-items: center; padding: 24px;
    background: radial-gradient(900px 500px at 70% -10%, rgba(21,144,232,.25), transparent 60%),
                linear-gradient(160deg, #04101C 0%, #0B2138 60%, #12314F 100%);
}
.acceso__caja { width: 100%; max-width: 440px; background: #fff; border-radius: 16px;
                padding: 32px; box-shadow: 0 30px 70px rgba(2,10,20,.45); }
.acceso__marca { display: flex; align-items: center; gap: .6rem; margin-bottom: 1.5rem; }
.acceso__pie { text-align: center; margin: 18px 0 0; font-size: .82rem; color: var(--gris-500); }
.acc-panel { display: none; }
.acc-panel.activo { display: block; }
.acceso .tabs { margin-bottom: 20px; }

/* ------------------------------------------------------------- Barra --- */
.nube-barra { background: var(--navy-900); position: sticky; top: 0; z-index: 90; }
.nube-barra__fila { display: flex; align-items: center; gap: 1rem; height: 64px; }
.nube-barra .logo__marca { color: #fff; }
.nube-barra .logo__marca span { color: var(--azul-vivo); }
.nube-barra .logo__tag { color: #7E96AF; }
.nube-barra .logo__marca-img-plano { filter: invert(1) brightness(1.8); height: 28px; }
.nube-barra__acciones { margin-left: auto; display: flex; align-items: center; gap: .6rem; }

.menu-cuenta { position: relative; }
.menu-cuenta__lista {
    position: absolute; right: 0; top: calc(100% + 8px); min-width: 190px;
    background: #fff; border: 1px solid var(--linea); border-radius: var(--radio);
    box-shadow: var(--sombra-lg); padding: 6px; display: none; z-index: 95;
}
.menu-cuenta__lista.abierto { display: block; }
.menu-cuenta__lista a { display: block; padding: .55rem .7rem; border-radius: var(--radio-sm);
                        font-size: .9rem; color: var(--gris-700); cursor: pointer; }
.menu-cuenta__lista a:hover { background: var(--fondo-suave); color: var(--tinta); }

.nube-main { padding: clamp(24px, 4vw, 40px) 24px 64px; }
.nube-cab { display: flex; justify-content: space-between; align-items: flex-start;
            gap: 24px; flex-wrap: wrap; margin-bottom: 28px; }
.nube-cab h1 { font-size: clamp(1.5rem, 3vw, 2rem); margin-bottom: .3rem; }
.nube-cab .lead { margin: 0; font-size: .95rem; }

/* ------------------------------------------------- Tarjetas de equipo --- */
.kpis-nube { display: flex; gap: 10px; flex-wrap: wrap; }
.kpi-mini { background: #fff; border: 1px solid var(--linea); border-radius: var(--radio);
            padding: 12px 18px; min-width: 104px; }
.kpi-mini__n { font-size: 1.5rem; font-weight: 680; color: var(--tinta); letter-spacing: -.03em; line-height: 1.1; }
.kpi-mini__t { font-size: .74rem; color: var(--gris-500); margin-top: 2px; font-weight: 550; }
.kpi-mini--alerta .kpi-mini__n { color: var(--rojo); }
.kpi-mini--ok .kpi-mini__n { color: var(--verde); }

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

.eq-card { background: #fff; border: 1px solid var(--linea); border-radius: var(--radio-lg);
           padding: 20px; cursor: pointer; transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease; }
.eq-card:hover { border-color: #C9D8E7; box-shadow: var(--sombra); transform: translateY(-2px); }
.eq-card__cab { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; margin-bottom: 14px; }
.eq-card__nom { font-weight: 640; color: var(--tinta); font-size: 1.02rem; letter-spacing: -.015em; }
.eq-card__sitio { font-size: .8rem; color: var(--gris-500); margin-top: 2px; }
.eq-card__id { font-family: var(--mono); font-size: .72rem; color: var(--gris-400); margin-top: 4px; }

.eq-metricas { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-top: 14px;
               padding-top: 14px; border-top: 1px solid var(--linea-suave); }
.eq-met__v { font-size: 1.12rem; font-weight: 650; color: var(--tinta); letter-spacing: -.02em; }
.eq-met__v small { font-size: .62em; font-weight: 500; color: var(--gris-500); margin-left: 1px; }
.eq-met__t { font-size: .68rem; color: var(--gris-500); text-transform: uppercase;
             letter-spacing: .07em; font-weight: 620; margin-top: 2px; }

/* Barra de carga de batería */
.bat-barra { height: 7px; border-radius: 4px; background: var(--linea); overflow: hidden; margin-top: 10px; }
.bat-barra i { display: block; height: 100%; border-radius: 4px; transition: width .4s ease; }

/* ------------------------------------------------------------ Estados --- */
/* Los colores de estado nunca van solos: siempre con texto (y con punto), para
   que se lean sin depender del color (daltonismo, impresión, alto contraste). */
.estado { display: inline-flex; align-items: center; gap: .4rem; padding: .22rem .6rem;
          border-radius: 100px; font-size: .74rem; font-weight: 640; white-space: nowrap; }
.estado i { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.estado--ok     { background: #E4F6EE; color: #0A7350; } .estado--ok i     { background: var(--verde); }
.estado--alerta { background: var(--ambar-claro); color: #8A5A07; } .estado--alerta i { background: var(--ambar); }
.estado--critico{ background: #FCEAEA; color: #A32C2C; } .estado--critico i{ background: var(--rojo); }
.estado--gris   { background: var(--linea-suave); color: var(--gris-600); } .estado--gris i { background: var(--gris-400); }
.estado--vivo i { animation: latido 2s infinite; }

/* ---------------------------------------------------------- Detalle ---- */
.volver { display: inline-flex; align-items: center; gap: .4rem; font-size: .88rem;
          color: var(--gris-600); margin-bottom: 16px; cursor: pointer; }
.volver:hover { color: var(--azul); }

.detalle-cab { display: flex; justify-content: space-between; align-items: flex-start;
               gap: 20px; flex-wrap: wrap; margin-bottom: 24px; }
.panel-blanco { background: #fff; border: 1px solid var(--linea); border-radius: var(--radio-lg);
                padding: 22px; margin-bottom: 20px; }
.panel-blanco h3 { font-size: .78rem; letter-spacing: .1em; text-transform: uppercase;
                   color: var(--gris-500); margin-bottom: 14px; font-weight: 650; }

.metricas-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 16px; }
.met-big__v { font-size: 1.7rem; font-weight: 680; color: var(--tinta); letter-spacing: -.035em; line-height: 1.1; }
.met-big__v small { font-size: .5em; font-weight: 500; color: var(--gris-500); margin-left: 2px; }
.met-big__t { font-size: .72rem; color: var(--gris-500); text-transform: uppercase;
              letter-spacing: .08em; font-weight: 620; margin-top: 4px; }

/* ---------------------------------------------------------- Gráfica ---- */
/* Una sola serie (voltaje): sin leyenda — el título de la tarjeta la nombra.
   Las franjas de "sin red eléctrica" llevan etiqueta propia, no solo color. */
.gr-wrap { position: relative; width: 100%; }
.gr-svg { width: 100%; height: auto; display: block; overflow: visible; }
.gr-grid line { stroke: var(--linea); stroke-width: 1; }
.gr-eje { font-size: 10px; fill: var(--gris-500); font-family: var(--fuente); }
.gr-linea { fill: none; stroke: var(--azul); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.gr-area { fill: url(#gradVolt); }
.gr-banda { fill: var(--rojo); opacity: .09; }
.gr-cursor { stroke: var(--gris-400); stroke-width: 1; stroke-dasharray: 3 3; display: none; }
.gr-punto { fill: var(--azul); stroke: #fff; stroke-width: 2; r: 5; display: none; }
.gr-hit { fill: transparent; cursor: crosshair; }
.gr-tip {
    position: absolute; pointer-events: none; display: none; z-index: 5;
    background: var(--navy-900); color: #fff; padding: 8px 11px; border-radius: 7px;
    font-size: .78rem; line-height: 1.45; box-shadow: 0 8px 24px rgba(4,16,28,.3);
    white-space: nowrap; transform: translate(-50%, -115%);
}
.gr-tip b { font-family: var(--mono); font-weight: 600; }
.gr-tip span { color: #93A9C0; }
.gr-leyenda { display: flex; gap: 1.1rem; flex-wrap: wrap; align-items: center;
              margin-top: 10px; font-size: .78rem; color: var(--gris-600); }
.gr-leyenda i { display: inline-block; width: 11px; height: 11px; border-radius: 3px;
                margin-right: .35rem; vertical-align: -1px; }
.gr-rangos { display: flex; gap: .4rem; }
.gr-rangos button { padding: .3rem .7rem; font-size: .78rem; border: 1px solid var(--linea);
                    background: #fff; border-radius: var(--radio-sm); cursor: pointer;
                    color: var(--gris-600); font-family: inherit; font-weight: 550; }
.gr-rangos button:hover { border-color: var(--gris-400); color: var(--tinta); }
.gr-rangos button.activo { background: var(--azul); border-color: var(--azul); color: #fff; }

/* ---------------------------------------------------------- Eventos ---- */
.ev-lista { max-height: 360px; overflow-y: auto; }
.ev-item { display: flex; gap: 12px; align-items: flex-start; padding: 10px 0;
           border-bottom: 1px solid var(--linea-suave); font-size: .88rem; }
.ev-item:last-child { border-bottom: 0; }
.ev-item__t { flex: 1; }
.ev-item__f { color: var(--gris-500); font-size: .78rem; white-space: nowrap; }

.acciones-fila { display: flex; gap: .6rem; flex-wrap: wrap; }

@media (max-width: 760px) {
    .nube-cab { flex-direction: column; }
    .eq-metricas { grid-template-columns: repeat(2, 1fr); }
    .nube-barra__fila { height: auto; padding: 12px 0; flex-wrap: wrap; }
    .nube-barra__acciones { width: 100%; }
}

/* ------------------------------------------------------------- Modal --- */
/* Propios del portal: los del panel interno viven en /admin/admin.css, que
   aquí no se carga (son dos aplicaciones distintas). */
.modal-fondo {
    position: fixed; inset: 0; background: rgba(6,18,30,.55); backdrop-filter: blur(3px);
    z-index: 100; display: none; align-items: flex-start; justify-content: center;
    padding: 40px 20px; overflow-y: auto;
}
.modal-fondo.abierto { display: flex; }
.modal { background: #fff; border-radius: 14px; width: 100%; max-width: 620px;
         box-shadow: 0 30px 80px rgba(2,10,20,.35); animation: subir .2s ease; }
.modal--angosto { max-width: 470px; }
@keyframes subir { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
.modal__cab { padding: 18px 24px; border-bottom: 1px solid var(--linea); display: flex; align-items: center; gap: 12px; }
.modal__cab h2 { margin: 0; font-size: 1.06rem; }
.modal__cerrar { margin-left: auto; background: none; border: 0; cursor: pointer; color: var(--gris-500);
                 font-size: 1.5rem; line-height: 1; padding: 0 4px; }
.modal__cerrar:hover { color: var(--tinta); }
.modal__cuerpo { padding: 24px; }
.modal__pie { padding: 16px 24px; border-top: 1px solid var(--linea); display: flex; gap: .6rem;
              justify-content: flex-end; background: var(--fondo-suave);
              border-radius: 0 0 14px 14px; flex-wrap: wrap; }

/* El botón de cuenta va sobre la barra oscura: .btn--linea usa tinta sobre
   blanco y aquí quedaba texto oscuro sobre fondo oscuro, es decir invisible. */
.nube-barra .btn--linea {
    color: #D5E2EE; border-color: rgba(255,255,255,.22); background: rgba(255,255,255,.06);
}
.nube-barra .btn--linea:hover { background: rgba(255,255,255,.14); color: #fff; border-color: rgba(255,255,255,.35); }

/* ------------------------------------------- Actualización remota (OTA) ---
   El equipo tarda entre uno y tres minutos, y durante ese rato deja de
   reportar a propósito: suelta la sesión MQTT para dejarle RAM al TLS de la
   descarga y luego se reinicia. Sin nada que mirar, ese silencio se lee como
   una caída — y la reacción natural es ir a cortarle la corriente, que es
   justo lo único que puede dejar el equipo inservible.
   De ahí el aro girando (dice "sigue vivo" sin necesitar un número) y los
   cuatro pasos (dicen POR DÓNDE va, que es lo que responde "¿falta mucho?"). */
.ota-cab { text-align: center; padding: 6px 0 2px; }
.ota-cab h3 { margin: 14px 0 5px; font-size: 1.04rem; }
.ota-cab p { margin: 0; font-size: .87rem; color: var(--gris-600); line-height: 1.45; }
.spinner--g { width: 42px; height: 42px; border-width: 3px; }
.ota-marca { width: 42px; height: 42px; margin: 0 auto; display: block; }
.ota-marca--ok { color: var(--verde); }
.ota-marca--err { color: var(--rojo); }

.ota-pasos { list-style: none; margin: 20px 0 0; padding: 0; display: grid; gap: 2px; }
.ota-paso { display: flex; align-items: center; gap: 11px; padding: 9px 11px;
            border-radius: var(--radio); font-size: .88rem; color: var(--gris-500); }
.ota-paso__n { width: 23px; height: 23px; border-radius: 50%; border: 1.5px solid var(--linea);
               display: grid; place-items: center; font-size: .72rem; font-weight: 600; flex-shrink: 0; }
.ota-paso--hecho { color: var(--gris-700); }
.ota-paso--hecho .ota-paso__n { background: var(--verde); border-color: var(--verde); color: #fff; }
.ota-paso--actual { color: var(--tinta); font-weight: 600; background: var(--linea-suave); }
.ota-paso--actual .ota-paso__n { border-color: var(--azul); color: var(--azul); }
.ota-paso--fallo { color: var(--rojo); }
.ota-paso--fallo .ota-paso__n { background: var(--rojo); border-color: var(--rojo); color: #fff; }

/* Distintivo en la ficha y en la lista, para el que cierra el modal y se va:
   al volver tiene que seguir viendo que ese equipo está a medias. */
.ota-chip { display: inline-flex; align-items: center; gap: 7px; padding: .3rem .65rem;
            border-radius: 999px; font-size: .78rem; font-weight: 600;
            background: var(--azul-claro); color: var(--azul); }
.ota-chip .spinner { width: 13px; height: 13px; border-width: 2px; margin: 0; }

/* ------------------------------------------------ Alertas WhatsApp ----- */
.nota-alerta { margin: 0 0 14px; font-size: .86rem; color: var(--gris-600);
    background: var(--fondo-suave); border-radius: var(--radio-sm); padding: .6rem .8rem; }
.vacio-alerta { margin: 0; font-size: .9rem; color: var(--gris-500); }
.pista { font-size: .8rem; color: var(--gris-500); }

/* Números destinatarios */
.dest-fila { display: flex; align-items: center; justify-content: space-between; gap: 14px;
    padding: .8rem 0; border-bottom: 1px solid var(--linea-suave); flex-wrap: wrap; }
.dest-fila:last-child { border-bottom: 0; }
.dest-fila__tel { display: flex; align-items: center; gap: .5rem; font-weight: 600;
    color: var(--tinta); font-family: var(--mono); letter-spacing: -.01em; }
.dest-fila__nom { font-size: .82rem; color: var(--gris-500); margin-top: 3px; }
.dest-fila__acc { display: flex; gap: .4rem; flex-wrap: wrap; }

/* Reglas */
.alerta-fila { display: flex; align-items: flex-start; gap: 14px; padding: 1rem 0;
    border-bottom: 1px solid var(--linea-suave); transition: background .3s ease; }
.alerta-fila:last-of-type { border-bottom: 0; }
.alerta-fila.guardada { background: #EAF7F1; }
.alerta-fila__cuerpo { flex: 1; min-width: 0; }
.alerta-fila__tit { font-weight: 620; color: var(--tinta); font-size: .98rem; }
.alerta-fila__tit em { font-style: normal; font-weight: 500; color: var(--gris-500); font-size: .86rem; }
.alerta-fila__desc { font-size: .84rem; color: var(--gris-600); margin-top: 2px; }
.alerta-fila__del { background: none; border: 0; color: var(--gris-400); font-size: 1.4rem;
    line-height: 1; cursor: pointer; padding: 0 .2rem; }
.alerta-fila__del:hover { color: var(--rojo); }

.alerta-ctl { display: flex; flex-wrap: wrap; gap: .5rem .9rem; margin-top: .7rem; align-items: center; }
.ctl { display: inline-flex; align-items: center; gap: .35rem; font-size: .82rem; color: var(--gris-600); }
.ctl input[type="number"] { width: 68px; padding: .3rem .4rem; font-size: .85rem;
    border: 1px solid var(--linea); border-radius: var(--radio-sm); font-family: var(--mono); }
.ctl select { padding: .3rem .4rem; font-size: .85rem; border: 1px solid var(--linea);
    border-radius: var(--radio-sm); max-width: 170px; }
.ctl--check { cursor: pointer; }
.ctl--check input { accent-color: var(--azul); }

/* Interruptor de encendido/apagado de cada alerta */
.sw { position: relative; display: inline-block; width: 40px; height: 23px; flex-shrink: 0; margin-top: 2px; }
.sw input { opacity: 0; width: 0; height: 0; }
.sw span { position: absolute; inset: 0; cursor: pointer; background: var(--gris-400);
    border-radius: 999px; transition: background .2s ease; }
.sw span::before { content: ''; position: absolute; height: 17px; width: 17px; left: 3px; top: 3px;
    background: #fff; border-radius: 50%; transition: transform .2s ease; }
.sw input:checked + span { background: var(--verde); }
.sw input:checked + span::before { transform: translateX(17px); }
.sw input:focus-visible + span { outline: 2px solid var(--azul); outline-offset: 2px; }

/* Historial */
.hist-alertas { display: flex; flex-direction: column; }
.hist-fila { display: flex; align-items: center; gap: 12px; padding: .5rem 0;
    border-bottom: 1px solid var(--linea-suave); font-size: .85rem; }
.hist-fila:last-child { border-bottom: 0; }
.hist-fila__ts { color: var(--gris-500); white-space: nowrap; font-size: .78rem; min-width: 96px; }
.hist-fila__txt { flex: 1; color: var(--gris-600); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hist-fila__est { white-space: nowrap; }

@media (max-width: 640px) {
    .dest-fila { align-items: flex-start; }
    .hist-fila { flex-wrap: wrap; }
    .hist-fila__txt { white-space: normal; flex-basis: 100%; }
}

.eq-met__nota { margin-top: 4px; color: var(--gris-600); font-size: .75rem; }
.corriente-nota { margin: 14px 0 0; color: var(--gris-500); font-size: .8rem; line-height: 1.5; }
.gr-muestra { fill: var(--azul); stroke: #fff; stroke-width: 1; }
