/* =============================================================================
   Massignal — estilos propios de la aplicación.

   Aquí va solo el armazón: barra lateral, cabecera y las dos o tres piezas que no
   son reutilizables. Todo lo genérico (controles, grilla, paneles, alertas) vive
   en mas.css y se usa tal cual, con sus mismas variables --mas-*.
   ============================================================================= */

/* --- Armazón ------------------------------------------------------------- */

.app {
    display: grid;
    grid-template-columns: 232px 1fr;
    min-height: 100vh;
}

/* Menú plegado: la barra queda del ancho de un icono. La transición es de la
   rejilla, no de cada pieza, para que la lateral y el contenido se muevan juntos. */
.menu-plegado .app { grid-template-columns: 64px 1fr; }
.app { transition: grid-template-columns .16s ease; }

.app-lateral {
    background: linear-gradient(180deg, var(--mas-primario-900), var(--mas-primario-700));
    color: #dce9fb;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 18px 12px;
}

.app-principal {
    display: flex;
    flex-direction: column;
    min-width: 0; /* sin esto una grilla ancha desborda la rejilla en vez de scrollear */
}

.app-contenido {
    padding: var(--mas-espacio);
    display: flex;
    flex-direction: column;
    gap: var(--mas-espacio);
}

/* --- Marca --------------------------------------------------------------- */

.app-marca,
.acceso-marca {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 4px 10px 14px;
    font-weight: 600;
    letter-spacing: .2px;
}

.app-lateral .app-marca { color: #ffffff; font-size: 15px; }

/* --- Botón de plegar ------------------------------------------------------ */

.app-plegar {
    margin-left: auto;
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; flex: none;
    padding: 0; border: 0; border-radius: var(--mas-radio-sm);
    background: rgba(255, 255, 255, .10); color: #dce9fb;
    cursor: pointer; transition: background .12s, color .12s;
}

.app-plegar:hover { background: rgba(255, 255, 255, .22); color: #ffffff; }
.app-plegar svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* La flecha es la misma: se da vuelta según el estado, así siempre apunta hacia
   donde va a moverse la barra. */
.menu-plegado .app-plegar svg { transform: rotate(180deg); }

/* Plegado no queda sitio para la marca: manda el botón, que es lo único
   accionable, y el logotipo vuelve al desplegar. */
.menu-plegado .app-marca { padding: 4px 0 14px; justify-content: center; }
.menu-plegado .app-marca-punto,
.menu-plegado .app-marca-texto { display: none; }
.menu-plegado .app-plegar { margin-left: 0; width: 30px; height: 30px; }

.app-marca-punto {
    width: 11px;
    height: 11px;
    border-radius: 3px;
    background: var(--mas-primario);
}

.app-lateral .app-marca-punto { background: #ffffff; }

/* --- Navegación ---------------------------------------------------------- */

.app-nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.app-nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    border-radius: var(--mas-radio-sm);
    color: #c3d8f5;
    text-decoration: none;
    font-size: 13.5px;
    white-space: nowrap;
    transition: background .12s, color .12s;
}

.app-nav-item:hover { background: rgba(255, 255, 255, .12); color: #ffffff; }

/* El icono hereda el color del ítem —incluido el activo— porque el trazo es
   currentColor: un solo juego de iconos sirve para los tres estados. */
.app-nav-icono {
    width: 18px; height: 18px; flex: none;
    fill: none; stroke: currentColor;
    stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
    opacity: .9;
}

.app-nav-activo .app-nav-icono { opacity: 1; stroke-width: 1.9; }

.app-nav-texto { overflow: hidden; text-overflow: ellipsis; }

/* Plegado: solo el icono, centrado. El texto se oculta en vez de achicarse
   —a medio tamaño no se lee y ensucia la columna—, y el nombre queda en el
   title, que el script pone al plegar. */
.menu-plegado .app-nav-item { justify-content: center; padding: 10px 0; gap: 0; }
.menu-plegado .app-nav-texto { display: none; }
.menu-plegado .app-lateral { padding: 18px 8px; }

/* La hoja de símbolos no se dibuja: solo alimenta a los <use>. */
.app-iconos { display: none; }

.app-nav-activo,
.app-nav-activo:hover {
    background: #ffffff;
    color: var(--mas-primario-900);
    font-weight: 600;
}

/* --- Cabecera ------------------------------------------------------------ */

.app-cabecera {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--mas-espacio);
    padding: 12px var(--mas-espacio);
    background: var(--mas-superficie);
    border-bottom: 1px solid var(--mas-borde);
}

.app-cabecera-titulo { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.app-cabecera-titulo h1 { margin: 0; font-size: 17px; font-weight: 600; }

.app-organizacion {
    font-size: 12.5px;
    color: var(--mas-texto-tenue);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.app-usuario { display: flex; align-items: center; gap: 18px; }

.app-usuario-datos {
    display: flex; flex-direction: column; align-items: flex-end;
    line-height: 1.2; min-width: 0;
}
.app-usuario-nombre {
    font-size: 13.5px; font-weight: 600; color: var(--mas-texto);
    text-decoration: none; white-space: nowrap;
}
.app-usuario-nombre:hover { color: var(--mas-primario); text-decoration: underline; }
.app-usuario-rol {
    font-size: 11.5px; color: var(--mas-texto-tenue);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 220px;
}

/* Separadores verticales entre nombre, reloj y estado: ordenan el bloque sin
   agregar cajas ni bordes que compitan con la cabecera. */
.app-usuario > .mas-reloj,
.app-usuario > .mas-conexion { position: relative; }
.app-usuario > .mas-reloj::before,
.app-usuario > .mas-conexion::before {
    content: ""; position: absolute; left: -9px; top: 50%; transform: translateY(-50%);
    width: 1px; height: 26px; background: var(--mas-borde);
}

.app-salir { margin: 0; }

@media (max-width: 900px) {
    .app-usuario > .mas-reloj .mas-reloj-fecha { display: none; }
    .app-usuario-rol { display: none; }
}
@media (max-width: 700px) {
    .app-usuario > .mas-conexion { display: none; }
}

/* --- Accesos rápidos del inicio ------------------------------------------ */

.inicio-accesos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 12px;
    margin-top: var(--mas-espacio);
}

.inicio-acceso {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 14px;
    border: 1px solid var(--mas-borde);
    border-radius: var(--mas-radio);
    background: var(--mas-superficie-2);
    text-decoration: none;
    color: inherit;
}

.inicio-acceso:hover { border-color: var(--mas-primario); box-shadow: var(--mas-sombra); }
.inicio-acceso span { font-size: 12.5px; color: var(--mas-texto-tenue); }

/* La ocupación como una tarjeta más de la rejilla de accesos. No es un enlace:
   no se ilumina al pasar por encima ni cambia el cursor, para que se lea como
   información y no como algo que se puede pulsar. */

.inicio-almacenamiento { gap: 6px; cursor: default; }
.inicio-almacenamiento:hover { border-color: var(--mas-borde); box-shadow: none; }
.inicio-almacenamiento span.inicio-almacenamiento-cifra { font-size: 13.5px; color: var(--mas-texto-suave); }
.inicio-almacenamiento b { color: var(--mas-texto); font-weight: 600; }
.inicio-almacenamiento .almacenamiento-barra { width: 100%; margin: 2px 0; }

/* --- Indicador de almacenamiento ----------------------------------------
   Vive DENTRO de la barra de acciones y se empuja a la izquierda con el
   margin auto: así comparte línea con los botones —que es donde se mira—
   sin necesidad de otra fila ni de posicionarlo a mano. */

.almacenamiento {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-right: auto;        /* empuja los botones al otro extremo */
    font-size: 13px;
    color: var(--mas-texto-suave);
}

.almacenamiento-titulo {
    color: var(--mas-texto-tenue);
    text-transform: uppercase;
    font-size: 11px;
    letter-spacing: .4px;
}

.almacenamiento-detalle strong { color: var(--mas-texto); font-weight: 600; }

.almacenamiento-barra {
    width: 140px; height: 6px; overflow: hidden;
    background: var(--mas-primario-100); border-radius: 999px;
}

.almacenamiento-relleno {
    width: 0; height: 100%; background: var(--mas-primario);
    border-radius: 999px; transition: width .2s linear;
}

/* El color cambia solo cuando ya conviene mirarlo. Un indicador siempre rojo
   deja de decir nada; uno que solo se enciende cerca del tope se nota. */
.almacenamiento-relleno.almacenamiento-alerta { background: var(--mas-advertencia); }
.almacenamiento-relleno.almacenamiento-critico { background: var(--mas-peligro); }

/* En pantalla angosta el indicador se va a su propia línea antes que apretar
   los botones: la barra de acciones ya envuelve. */
@media (max-width: 780px) {
    .almacenamiento { margin-right: 0; width: 100%; }
}

/* Barra de acciones de una pantalla de listado. Vive fuera de <mas-grilla>
   porque su barra interna no admite tag helpers como hijos. */
.pagina-acciones { display: flex; align-items: center; justify-content: flex-end; gap: 10px; flex-wrap: wrap; }

/* --- Acciones destructivas en la ficha ----------------------------------- */

.usuario-acciones { display: flex; flex-wrap: wrap; gap: 10px; }
.usuario-acciones form { margin: 0; }

.mas-lista-errores { margin: 4px 0 0; padding-left: 18px; }

/* --- Pantallas de acceso -------------------------------------------------- */

body.acceso {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: var(--mas-espacio);
}

.acceso-caja {
    width: 100%;
    max-width: 380px;
    padding: 26px;
    background: var(--mas-superficie);
    border: 1px solid var(--mas-borde);
    border-radius: var(--mas-radio);
    box-shadow: var(--mas-sombra-md);
}

.acceso-marca { justify-content: center; padding-bottom: 6px; }
.acceso-titulo { margin: 0 0 18px; font-size: 18px; font-weight: 600; text-align: center; }
.acceso-boton { width: 100%; justify-content: center; }
.acceso-pie { margin: 20px 0 0; text-align: center; font-size: 12px; color: var(--mas-texto-tenue); }

/* --- Pantallas angostas --------------------------------------------------- */

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

    .app-lateral {
        border-right: none;
        border-bottom: 1px solid var(--mas-borde);
    }

    .app-nav { flex-direction: row; flex-wrap: wrap; }
}

/* Texto explicativo de las pantallas de acceso (instalación, recuperación). */
.acceso-ayuda {
    margin: 0 0 var(--mas-espacio);
    color: var(--mas-texto-suave);
    font-size: 13.5px;
}

/* --- Franja de organización activa ---------------------------------------
   El administrador global puede estar operando sobre datos de un cliente sin
   darse cuenta. Esta franja es deliberadamente llamativa: el riesgo de crear
   un usuario en la organización equivocada es real. */

.app-contexto {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    padding: 9px var(--mas-espacio);
    background: var(--mas-advertencia-suave);
    border-bottom: 1px solid color-mix(in srgb, var(--mas-advertencia) 30%, transparent);
    color: var(--mas-advertencia);
    font-size: 13px;
}

.app-contexto form { margin: 0; }

/* --- Pantalla de parámetros ----------------------------------------------
   La grilla agrupada y el diálogo de edición salen del framework; lo único
   propio de esta pantalla es cómo se ven la clave técnica y la descripción. */

.parametro-clave {
    margin: 0 0 4px;
}

.parametro-descripcion {
    margin: 0 0 var(--mas-espacio);
    color: var(--mas-texto-suave);
    font-size: 13px;
    line-height: 1.5;
}

/* En la celda la descripción se recorta: es un apoyo de lectura, y el texto
   completo se ve en el diálogo de edición. Sin el recorte, una descripción
   larga estira la fila y descuadra la agrupación visual. */
.parametro-descripcion-celda {
    display: block;
    color: var(--mas-texto-suave);
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
}

.parametro-valor {
    font-family: var(--mas-fuente-mono);
    font-size: 12.5px;
    word-break: break-all;
}

/* ==========================================================================
   Biblioteca de contenido
   ========================================================================== */

.contenido-filtros {
    display: flex;
    gap: var(--mas-espacio);
    flex-wrap: wrap;
    padding: 12px 14px;
    border-bottom: 1px solid var(--mas-borde);
    background: var(--mas-superficie-2);
}

.contenido-filtro {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 170px;
}

.contenido-filtro > span {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--mas-texto-suave);
}

/* La grilla vive dentro de un panel sin relleno: sin esto tendría borde y sombra
   propios dentro de otro borde. */
.contenido-filtros + .mas-grilla {
    border: none;
    border-radius: 0;
    box-shadow: none;
}

/* Miniatura de la celda. Tamaño FIJO en los dos ejes con object-fit: cover para
   que una imagen vertical y una panorámica ocupen lo mismo; si el alto variara,
   cada fila de la tabla tendría una altura distinta. */
.contenido-mini {
    display: block;
    width: 64px;
    height: 40px;
    margin: 0 auto;
    object-fit: cover;
    border-radius: var(--mas-radio-sm);
    background: var(--mas-superficie-2);
    border: 1px solid var(--mas-borde);
}

/* Marcador mientras no hay miniatura: la inicial del tipo sobre el mismo hueco,
   para que la columna no se descuadre al aparecer la imagen real. */
.contenido-mini-vacia {
    display: grid;
    place-items: center;
    font-size: 15px;
    font-weight: 700;
    color: var(--mas-texto-tenue);
    background: var(--mas-primario-50);
}

.contenido-nombre {
    display: block;
    color: var(--mas-primario);
    text-decoration: none;
    font-weight: 500;
}
.contenido-nombre:hover { text-decoration: underline; }

.contenido-dimensiones {
    display: block;
    font-size: 11.5px;
    color: var(--mas-texto-tenue);
    font-variant-numeric: tabular-nums;
}

/* Ficha de solo lectura del diálogo de edición. */
.contenido-ficha {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 10px 16px;
    margin: 0 0 var(--mas-espacio);
    padding: 12px 14px;
    background: var(--mas-superficie-2);
    border: 1px solid var(--mas-borde);
    border-radius: var(--mas-radio-sm);
}
.contenido-ficha dt {
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--mas-texto-tenue);
}
.contenido-ficha dd {
    margin: 2px 0 0;
    font-size: 13px;
    word-break: break-word;
}

/* Botones de la columna de acciones: en una sola línea, pegados al borde derecho. */
/* --- Ficha de contenido (diálogo de vista previa) ------------------------

   El visor tiene alto máximo y no fijo: un afiche vertical y un video 16:9 no
   pueden ocupar la misma caja sin que a uno le sobren bandas negras. */

.contenido-visor {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: var(--mas-espacio);
    padding: 8px;
    background: #0f172a;               /* fondo oscuro: es lo que no compite con la imagen */
    border-radius: var(--mas-radio);
}

.contenido-visor img,
.contenido-visor video {
    max-width: 100%;
    max-height: 46vh;                  /* deja ver los datos sin tener que scrollear */
    border-radius: var(--mas-radio-sm);
}

/* DOS PARES POR FILA: etiqueta-valor, etiqueta-valor. Con un par por fila la
   ficha crecía hacia abajo hasta dejar el video y los botones fuera de la
   pantalla; los valores son cortos (un tamaño, una fecha) y desperdiciaban
   media línea cada uno.

   minmax(0, 1fr) y no 1fr: sin el mínimo en cero, un valor largo —el nombre de
   un archivo— ensancha su columna y descuadra las otras. */
.contenido-datos {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto minmax(0, 1fr);
    gap: 6px 14px;
    margin: 0;
    font-size: 13.5px;
}

.contenido-datos dt { color: var(--mas-texto-tenue); white-space: nowrap; }
.contenido-datos dd { margin: 0; word-break: break-word; }

/* Lo que no cabe en media fila —una descripción— se lleva el ancho completo. */
.contenido-datos dd.contenido-dato-ancho { grid-column: 2 / -1; }

@media (max-width: 900px) {
    .contenido-datos { grid-template-columns: auto minmax(0, 1fr); }
    .contenido-datos dd.contenido-dato-ancho { grid-column: 2; }
}

@media (max-width: 560px) {
    .contenido-datos { grid-template-columns: 1fr; gap: 2px; }
    .contenido-datos dd { margin-bottom: 8px; }
    .contenido-datos dd.contenido-dato-ancho { grid-column: 1; }
}

/* El nombre de la grilla es un <button> —abre un diálogo, no navega— pero se lee
   como un enlace, que es lo que la gente espera de un nombre pinchable. */
button.contenido-nombre {
    display: block;
    padding: 0;
    border: none;
    background: none;
    color: var(--mas-primario);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

button.contenido-nombre:hover { text-decoration: underline; }

/* Botones de acción de una fila. Contenedor propio para que se mantengan en una
   sola línea aunque la columna quede justa, en vez de apilarse y estirar la fila. */
.contenido-acciones,
.fila-acciones {
    display: inline-flex;
    gap: 6px;
    justify-content: flex-end;
    white-space: nowrap;
}

/* Barra de acciones de Contenido: filtro a la izquierda, botón a la derecha. */
.pagina-acciones .contenido-filtro { margin-right: auto; }
.pagina-acciones .contenido-filtro .mas-control { min-width: 200px; }

/* Aviso de proceso fallido bajo el nombre. No ocupa columna propia porque solo
   aparece cuando algo salió mal. */
.contenido-problema {
    display: block;
    font-size: 12px;
    color: var(--mas-peligro);
    cursor: help;
}

/* Barra de contexto: organización y cliente, más el selector para cambiar de cliente. */
.app-contexto-texto { display: flex; gap: 18px; flex-wrap: wrap; }
.app-contexto-cliente { display: flex; align-items: center; gap: 8px; margin: 0; }
/* La etiqueta es de dos palabras y en un flex se parte en dos líneas, dejando el
   selector descolgado. Cabe de sobra: lo que hay que impedir es el salto. */
.app-contexto-cliente label { white-space: nowrap; }
.app-contexto-cliente .mas-control { padding: 4px 8px; font-size: 13px; min-width: 180px; }
