:root {
    --columnas: 3;

    --bg: #060a10;
    --bg-grid: rgba(34, 211, 238, 0.05);
    --surface: #0d131b;
    --surface-2: #121a24;
    --border: #1f2a37;
    --border-strong: #2c3a4a;
    --text: #dce3ec;
    --text-dim: #7c8898;

    --accent: #ff505b;
    --accent-glow: rgba(255, 80, 91, 0.35);

    /* Acento "de sistema": contador, foco, barrido de fondo — todo lo que
       es interfaz/chrome en vez de una señal de estado semáforo. */
    --accent2: #22d3ee;
    --accent2-glow: rgba(34, 211, 238, 0.4);

    --ok: #22c55e;
    --ok-glow: rgba(34, 197, 94, 0.35);
    --warn: #f5a524;
    --warn-glow: rgba(245, 165, 36, 0.35);
    --err: #f14550;
    --err-glow: rgba(241, 69, 80, 0.4);

    --mono: ui-monospace, "Cascadia Code", "Segoe UI Mono", Consolas, monospace;
}

* {
    scrollbar-color: var(--border-strong) var(--surface);
}

html,
body {
    color-scheme: dark;
}

body {
    background-color: var(--bg);
    background-image:
        linear-gradient(var(--bg-grid) 1px, transparent 1px),
        linear-gradient(90deg, var(--bg-grid) 1px, transparent 1px);
    background-size: 40px 40px;
    background-attachment: fixed;
    color: var(--text);
}

/* --- navbar ---------------------------------------------------------- */

#navbar-panel {
    background-color: var(--surface);
    border-bottom: 1px solid var(--border);
    box-shadow: 0 1px 0 var(--accent), 0 8px 24px -12px var(--accent-glow);
}

#navbar-panel .navbar-brand {
    letter-spacing: .04em;
    font-weight: 600;
}

#navbar-panel .navbar-brand img {
    border-radius: 50%;
    box-shadow: 0 0 0 2px var(--surface-2), 0 0 14px 1px var(--accent-glow);
}

#cuenta-atras {
    font-family: var(--mono);
    font-size: 1.6rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: .03em;
    color: var(--accent2);
    text-shadow: 0 0 16px var(--accent2-glow);
}

#punto-vivo {
    display: inline-block;
    width: .6rem;
    height: .6rem;
    border-radius: 50%;
    background-color: var(--ok);
    box-shadow: 0 0 8px 2px var(--ok-glow);
    animation: pulso 2s ease-in-out infinite;
}

.boton-musica {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 50%;
    background-color: var(--surface-2);
    color: var(--text-dim);
    cursor: pointer;
    transition: color .15s ease, border-color .15s ease;
}

.boton-musica:hover {
    color: var(--accent2);
}

.boton-musica:focus-visible {
    outline: 2px solid var(--accent2);
    outline-offset: 2px;
}

.boton-musica .icono-musica-onda {
    opacity: .3;
    transition: opacity .15s ease;
}

.boton-musica[aria-pressed="true"] {
    border-color: var(--accent2);
    color: var(--accent2);
}

.boton-musica[aria-pressed="true"] .icono-musica-onda {
    opacity: 1;
}

.musica-config-wrap {
    position: relative;
    display: inline-flex;
}

.popover-musica {
    position: absolute;
    top: calc(100% + .5rem);
    right: 0;
    z-index: 20;
    width: 17rem;
    padding: .75rem;
    background-color: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: .5rem;
    box-shadow: 0 12px 32px -8px rgba(0, 0, 0, .6);
}

.popover-musica .form-control {
    background-color: var(--surface-2);
    border-color: var(--border);
    color: var(--text);
}

.popover-musica .form-control:focus {
    background-color: var(--surface-2);
    color: var(--text);
    border-color: var(--accent2);
    box-shadow: 0 0 0 .2rem var(--accent2-glow);
}

#musica-config-error {
    color: var(--err);
}

@keyframes pulso {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%      { opacity: .45; transform: scale(.75); }
}

/* --- alerta de daemon parado ------------------------------------------ */

#alerta-daemon {
    background-color: rgba(245, 165, 36, .08);
    border: 1px solid var(--warn);
    color: #ffd280;
    box-shadow: 0 0 24px -8px var(--warn-glow);
    font-family: var(--mono);
    letter-spacing: .01em;
}

/* --- resumen de clientes ---------------------------------------------- */

#resumen-clientes .badge {
    font-family: var(--mono);
    font-weight: 600;
    letter-spacing: .02em;
    padding: .45em .7em;
}

/* --- selector de columnas ---------------------------------------------- */

#selector-columnas {
    background-color: var(--surface-2);
    border-color: var(--border-strong);
    color: var(--text);
}

#selector-columnas:focus {
    border-color: var(--accent2);
    box-shadow: 0 0 0 .2rem var(--accent2-glow);
}

label[for="selector-columnas"] {
    text-transform: uppercase;
    font-size: .7rem;
    letter-spacing: .08em;
    color: var(--text-dim) !important;
}

/* --- tarjetas ------------------------------------------------------- */

#tarjetas {
    display: grid;
    grid-template-columns: repeat(var(--columnas), 1fr);
    gap: 1.1rem;
    align-items: start;
}

@media (max-width: 700px) {
    #tarjetas {
        grid-template-columns: 1fr;
    }
}

.tarjeta-cliente {
    position: relative;
    overflow: hidden;
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: .5rem;
    cursor: pointer;
    transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}

.tarjeta-cliente:hover {
    transform: translateY(-2px);
}

.tarjeta-cliente:focus-visible {
    outline: 2px solid var(--accent2);
    outline-offset: 2px;
}

.tarjeta-cliente:hover::after {
    filter: brightness(1.6);
}

/* Franja superior en degradado: la señal de color principal del estado. */
.tarjeta-cliente::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: linear-gradient(90deg, var(--franja-color), transparent 85%);
}

/* Esquinas tipo "mira", puramente estructurales/técnicas (color neutro),
   con 4 capas de background-image (2 tramos por esquina) en un único
   pseudo-elemento: no hace falta marcado adicional en el HTML. */
.tarjeta-cliente::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background-repeat: no-repeat;
    background-image:
        linear-gradient(var(--border-strong), var(--border-strong)),
        linear-gradient(var(--border-strong), var(--border-strong)),
        linear-gradient(var(--border-strong), var(--border-strong)),
        linear-gradient(var(--border-strong), var(--border-strong)),
        linear-gradient(var(--border-strong), var(--border-strong)),
        linear-gradient(var(--border-strong), var(--border-strong)),
        linear-gradient(var(--border-strong), var(--border-strong)),
        linear-gradient(var(--border-strong), var(--border-strong));
    background-size:
        14px 2px, 2px 14px,
        14px 2px, 2px 14px,
        14px 2px, 2px 14px,
        14px 2px, 2px 14px;
    background-position:
        top 6px left 6px, top 6px left 6px,
        top 6px right 6px, top 6px right 6px,
        bottom 6px left 6px, bottom 6px left 6px,
        bottom 6px right 6px, bottom 6px right 6px;
    transition: filter .2s ease;
}

.tarjeta-cliente.estado-OK {
    --franja-color: var(--ok);
    box-shadow: 0 0 0 1px var(--border), 0 6px 20px -10px var(--ok-glow);
}

.tarjeta-cliente.estado-WARNING {
    --franja-color: var(--warn);
    box-shadow: 0 0 0 1px var(--border), 0 6px 20px -10px var(--warn-glow);
}

.tarjeta-cliente.estado-ERROR {
    --franja-color: var(--err);
    box-shadow: 0 0 0 1px var(--border), 0 6px 24px -8px var(--err-glow);
}

/* Parpadeo puntual (una vez) cuando el estado de un cliente cambia de un
   refresco al siguiente — ver estadosPrevios en panel.js. Independiente
   del box-shadow del estado: usa outline, así no pisa el glow normal y
   al terminar la animación la tarjeta vuelve sola a su aspecto de siempre. */
.tarjeta-cliente.recien-cambiado {
    animation: flash-cambio 1.8s ease-out;
}

@keyframes flash-cambio {
    0%   { outline: 2px solid var(--accent2); outline-offset: 3px; }
    100% { outline: 2px solid rgba(34, 211, 238, 0); outline-offset: 3px; }
}

.cabecera-tarjeta {
    padding: 1.1rem 1.25rem .9rem;
}

.partner-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    row-gap: .25rem;
    gap: .45rem;
    margin-bottom: .4rem;
}

.partner-avatar {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--mono);
    font-size: .72rem;
    font-weight: 700;
    color: #06070a;
    flex: none;
}

.partner-avatar-icono {
    background: #f5f5f5;
    object-fit: contain;
    padding: 3px;
}

.partner-nombre {
    font-family: var(--mono);
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--text-dim);
}

.chip-campania {
    font-family: var(--mono);
    font-size: .68rem;
    letter-spacing: .02em;
    color: var(--accent2);
    background: rgba(34, 211, 238, 0.1);
    border: 1px solid var(--accent2-glow);
    border-radius: .35rem;
    padding: .1rem .45rem;
    white-space: nowrap;
}

.nombre-cliente {
    font-family: var(--mono);
    font-size: 1.55rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .02em;
    margin-bottom: 0;
    color: var(--text);
}

.chip-heartbeat {
    display: inline-block;
    margin-top: .45rem;
    font-family: var(--mono);
    font-size: .68rem;
    letter-spacing: .02em;
    color: var(--text-dim);
}

/* Más de 30 min sin un heartbeat nuevo (ver UMBRAL_HEARTBEAT_DESCOLGADO_SEG
   en panel.js): agente fallando, colgado o sin conectividad, independiente
   del estado OK/WARNING/ERROR de las comprobaciones de esa planta. */
.chip-heartbeat-descolgado {
    color: var(--err);
    font-weight: 600;
    text-shadow: 0 0 10px var(--err-glow);
}

.fila-modulo {
    display: flex;
    align-items: center;
    gap: .6rem;
    font-size: 1rem;
    padding: .55rem 1.25rem;
    border-top: 1px solid var(--border);
    color: var(--text-dim);
}

.fila-modulo:first-of-type {
    border-top: none;
}

.fila-modulo span:nth-child(2) {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--mono);
    letter-spacing: .01em;
    color: var(--text);
}

.badge-estado-OK {
    background-color: var(--ok);
    color: #06210f;
}

.badge-estado-WARNING {
    background-color: var(--warn);
    color: #2b1c00;
}

.badge-estado-ERROR {
    background-color: var(--err);
    color: #2b0507;
}

.fila-modulo .punto {
    width: .6rem;
    height: .6rem;
    border-radius: 50%;
    flex: none;
}

.punto-OK {
    background-color: var(--ok);
    box-shadow: 0 0 6px 1px var(--ok-glow);
}

.punto-WARNING {
    background-color: var(--warn);
    box-shadow: 0 0 6px 1px var(--warn-glow);
}

.punto-ERROR {
    background-color: var(--err);
    box-shadow: 0 0 6px 1px var(--err-glow);
    animation: pulso 1.4s ease-in-out infinite;
}

.badge-sin-datos {
    background-color: var(--surface-2);
    color: var(--text-dim);
    border: 1px solid var(--border-strong);
}

.punto-sin-datos {
    background-color: var(--border-strong);
}

/* --- panel de detalle (al pinchar una tarjeta) ------------------------ */

.overlay-detalle {
    position: fixed;
    inset: 0;
    background: rgba(3, 6, 10, .7);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 4rem 1rem;
    z-index: 10;
}

.panel-detalle {
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: .6rem;
    box-shadow: 0 20px 60px -20px rgba(0, 0, 0, .6), 0 0 0 1px var(--border);
    width: 100%;
    max-width: 640px;
    max-height: 80vh;
    overflow-y: auto;
}

.cabecera-panel-detalle {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    padding: 1.25rem 1.4rem;
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    background: var(--surface);
    /* Por encima del contenido que se desplaza: los elementos "vistos" tienen
       opacity (crean su propio contexto de apilado) y sin esto se pintaban
       encima de la cabecera al hacer scroll. */
    z-index: 5;
}

.cerrar-detalle {
    background: transparent;
    border: 1px solid var(--border-strong);
    color: var(--text-dim);
    width: 30px;
    height: 30px;
    border-radius: 50%;
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    flex: none;
}

.cerrar-detalle:hover {
    color: var(--text);
    border-color: var(--accent2);
}

.seccion-producto-detalle {
    padding: 1rem 1.4rem;
    border-bottom: 1px solid var(--border);
}

.seccion-producto-detalle:last-child {
    border-bottom: none;
}

.cabecera-producto-detalle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    background: transparent;
    border: none;
    padding: 0;
    margin-bottom: .6rem;
    cursor: pointer;
    color: inherit;
    font: inherit;
    text-align: left;
}

.cabecera-producto-detalle:focus-visible {
    outline: 2px solid var(--accent2);
    outline-offset: 3px;
}

.titulo-producto-detalle {
    display: flex;
    align-items: center;
    gap: .5rem;
}

.chevron-producto {
    flex: none;
    width: 0;
    height: 0;
    border-left: 5px solid var(--text-dim);
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    transition: transform .15s ease;
}

.cabecera-producto-detalle[aria-expanded="true"] .chevron-producto {
    transform: rotate(90deg);
}

.cabecera-producto-detalle h3 {
    font-family: var(--mono);
    font-size: 1rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    margin: 0;
    color: var(--text);
}

.seccion-producto-detalle.plegada .cabecera-producto-detalle {
    margin-bottom: 0;
}

.seccion-producto-detalle.plegada .cuerpo-producto-detalle {
    display: none;
}

.comprobacion-detalle {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-left: 3px solid var(--chip-color);
    border-radius: .35rem;
    padding: .6rem .8rem;
    margin-bottom: .5rem;
    font-size: .85rem;
}

.comprobacion-detalle:last-child {
    margin-bottom: 0;
}

.comprobacion-detalle .fila-cabecera {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: .5rem;
    margin-bottom: .3rem;
}

.comprobacion-detalle .nombre-check {
    font-family: var(--mono);
    color: var(--text);
}

.comprobacion-detalle .meta {
    color: var(--text-dim);
    font-size: .78rem;
    font-family: var(--mono);
}

.comprobacion-detalle pre {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: .3rem;
    padding: .5rem .6rem;
    font-size: .76rem;
    color: var(--text-dim);
    margin: .4rem 0 0;
    white-space: pre-wrap;
    word-break: break-word;
}

/* --- modo compacto (pantallas muy bajas de altura, p.ej. tiras de TV/kiosco) ---
   A 1472x491 (una tele real probada) solo entraban 12 de 13 tarjetas: se
   reduce el "chrome" (navbar, margenes, tipografía) para que quepan más
   filas sin scroll, en vez de depender de que quepa por casualidad. */
@media (max-height: 560px) {
    #navbar-panel {
        margin-bottom: .4rem;
    }

    #navbar-panel .container-fluid {
        min-height: auto;
        padding-top: .3rem;
        padding-bottom: .3rem;
    }

    #navbar-panel .navbar-brand img {
        width: 20px;
        height: 20px;
    }

    #navbar-panel .navbar-brand {
        font-size: .85rem;
    }

    #cuenta-atras {
        font-size: 1rem;
    }

    #punto-vivo {
        width: .45rem;
        height: .45rem;
    }

    .boton-musica {
        width: 1.6rem;
        height: 1.6rem;
    }

    .boton-musica svg {
        width: 14px;
        height: 14px;
    }

    .popover-musica {
        width: 15rem;
    }

    #contenedor-panel {
        padding-bottom: .5rem;
    }

    #alerta-daemon {
        padding: .25rem .5rem;
        font-size: .72rem;
        margin-bottom: .4rem;
    }

    #fila-resumen {
        margin-bottom: .4rem;
    }

    #resumen-clientes .badge {
        font-size: .68rem;
        padding: .3em .55em;
    }

    #tarjetas {
        gap: .45rem;
    }

    .cabecera-tarjeta {
        padding: .4rem .6rem .3rem;
    }

    .partner-row {
        gap: .3rem;
        margin-bottom: .15rem;
    }

    .partner-avatar {
        width: 14px;
        height: 14px;
        font-size: .52rem;
    }

    .partner-nombre {
        font-size: .55rem;
    }

    .chip-campania {
        font-size: .5rem;
        padding: .05rem .35rem;
    }

    .nombre-cliente {
        font-size: .82rem;
        line-height: 1.15;
    }

    .chip-heartbeat {
        margin-top: .2rem;
        font-size: .52rem;
    }

    .fila-modulo {
        padding: .2rem .6rem;
        font-size: .68rem;
        gap: .35rem;
    }

    .fila-modulo .punto {
        width: .4rem;
        height: .4rem;
    }
}

/* --- botón "Enviar informe" del panel de detalle ----------------------- */
.detalle-informe {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-top: 0.7rem;
}

.boton-informe {
    background: transparent;
    border: 1px solid var(--accent2);
    color: var(--accent2);
    border-radius: 6px;
    padding: 0.25rem 0.8rem;
    font-size: 0.8rem;
    cursor: pointer;
}

.boton-informe:hover:not(:disabled) {
    background: var(--accent2-glow);
    color: var(--text);
}

.boton-informe:focus-visible {
    outline: 2px solid var(--accent2);
    outline-offset: 2px;
}

.boton-informe:disabled {
    border-color: var(--border-strong);
    color: var(--text-dim);
    cursor: not-allowed;
}

.informe-mensaje {
    font-size: 0.78rem;
    color: var(--text-dim);
}

.informe-mensaje.informe-ok {
    color: var(--ok);
}

.informe-mensaje.informe-error {
    color: var(--err);
}

/* --- elementos de un aviso y botón "visto" ------------------------------ */
.elementos-aviso {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    margin-top: .5rem;
}

.elemento-aviso {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--chip-color);
    border-radius: .3rem;
    background: var(--bg);
    font-family: var(--mono);
    font-size: .76rem;
    overflow: hidden;
}

.elemento-aviso .elemento-id {
    padding: .15rem .5rem;
    color: var(--text);
}

.boton-visto {
    background: transparent;
    border: 0;
    border-left: 1px solid var(--border-strong);
    color: var(--text-dim);
    padding: 0 .5rem;
    cursor: pointer;
    line-height: 1;
}

.boton-visto:hover:not(:disabled) {
    background: var(--accent2-glow);
    color: var(--text);
}

.boton-visto:focus-visible {
    outline: 2px solid var(--accent2);
    outline-offset: -2px;
}

.boton-visto:disabled {
    cursor: wait;
    opacity: .5;
}

/* Visto: sigue ahí, pero apagado y tachado para que no llame la atención. */
.elemento-aviso.visto {
    border-color: var(--border-strong);
    opacity: .55;
}

.elemento-aviso.visto .elemento-id {
    color: var(--text-dim);
    text-decoration: line-through;
}

.nota-avisos {
    margin-top: .4rem;
    color: var(--text-dim);
    font-size: .72rem;
}

/* Pesadas en tolva: lo normal. Se listan, pero apagadas y sin botón. */
.elemento-aviso.informativo {
    border-color: var(--border-strong);
}

.elemento-aviso.informativo .elemento-id {
    color: var(--text-dim);
}

/* Nota "en rojo porque fallan N de M módulos" en la cabecera del detalle. */
.detalle-estado-nota {
    margin-top: .5rem;
    color: var(--err);
    font-size: .78rem;
}

/* --- botón "Informe PDF" de la barra superior ---------------------------- */
.boton-informe-pdf {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    height: 2rem;
    padding: 0 .8rem;
    border: 1px solid var(--border);
    border-radius: 1rem;
    background-color: var(--surface-2);
    color: var(--text-dim);
    font-size: .78rem;
    white-space: nowrap;
    cursor: pointer;
    transition: color .15s ease, border-color .15s ease;
}

.boton-informe-pdf:hover:not(:disabled) {
    color: var(--text);
    border-color: var(--accent2);
}

.boton-informe-pdf:focus-visible {
    outline: 2px solid var(--accent2);
    outline-offset: 2px;
}

.boton-informe-pdf:disabled {
    cursor: progress;
    opacity: .7;
}

.popover-informe-pdf {
    width: 21rem;
}

.popover-informe-pdf .informe-pdf-texto {
    font-size: .8rem;
    color: var(--text-dim);
    margin-bottom: .5rem;
}

.popover-informe-pdf .informe-pdf-error {
    font-size: .8rem;
    color: var(--err);
    margin-bottom: .6rem;
}

.popover-informe-pdf .informe-pdf-lista {
    list-style: none;
    padding: 0;
    margin: 0 0 .6rem;
    font-size: .85rem;
}

.popover-informe-pdf .informe-pdf-lista li {
    padding: .2rem 0;
}

.popover-informe-pdf .informe-pdf-lista a {
    color: var(--accent2);
}

.popover-informe-pdf .informe-pdf-kb {
    color: var(--text-dim);
    font-size: .72rem;
    margin-left: .35rem;
}

.popover-informe-pdf .informe-pdf-carpeta {
    font-family: var(--mono);
    font-size: .68rem;
    color: var(--text-dim);
    word-break: break-all;
    margin-bottom: .6rem;
}

.popover-informe-pdf .informe-pdf-titulo {
    font-size: .68rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text-dim);
    margin: .5rem 0 .15rem;
}

.popover-informe-pdf .informe-pdf-scroll {
    max-height: 13rem;
    overflow-y: auto;
    padding-right: .4rem;
}
