/* ==========================================================================
   admin.css - Sistema de diseno de los workspaces privados
   CER Management Group LLC | Virtual Classroom
   --------------------------------------------------------------------------
   Misma paleta que el sitio publico, para que el cliente no sienta que cambio
   de producto al entrar. Todo cuelga de .admin-page, asi que una vista que no
   lleve esa clase queda exactamente como estaba: la migracion es pantalla por
   pantalla y sin riesgo.

   Se carga despues de layout.css y public.css, y antes del <style> local de
   cada vista, que conserva la ultima palabra.
   ========================================================================== */

.admin-page {
    font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
    color: var(--cer-ink, #1B2733);
}

.admin-page h1, .admin-page h2, .admin-page h3,
.admin-page h4, .admin-page h5, .admin-page h6, .admin-page h7 {
    font-family: 'Barlow Condensed', 'Inter', system-ui, sans-serif;
    font-weight: 700;
    color: var(--cer-navy, #14284B);
    letter-spacing: .01em;
}


/* --------------------------------------------------------------------------
   Tarjetas
   -------------------------------------------------------------------------- */

.admin-page .card {
    border: 1px solid var(--cer-line, #DCE5EC);
    border-radius: 12px;
    box-shadow: 0 2px 10px rgba(20, 40, 75, .05);
}

.admin-page .card-header {
    background: var(--cer-white, #FFFFFF);
    border-bottom: 1px solid var(--cer-line, #DCE5EC);
    border-radius: 12px 12px 0 0 !important;
    padding: 1rem 1.25rem;
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 700;
    font-size: 1.2rem;
    letter-spacing: .03em;
    text-transform: uppercase;
    color: var(--cer-navy, #14284B);
}

/* Cabecera destacada, para el encabezado de una seccion */
.admin-page .card-header.accent {
    background: linear-gradient(135deg, var(--cer-navy, #14284B), var(--cer-blue, #016599));
    color: #FFFFFF;
    border-bottom: 0;
}
.admin-page .card-header.accent small { color: rgba(255,255,255,.75); }


/* --------------------------------------------------------------------------
   Encabezado de pantalla
   -------------------------------------------------------------------------- */

.admin-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .75rem;
    margin-bottom: 1rem;
}

.admin-head h1 {
    font-size: clamp(1.4rem, 3vw, 1.9rem);
    margin: 0;
    text-transform: uppercase;
}

.admin-head .admin-sub {
    color: var(--cer-muted, #5C6B7A);
    font-size: .92rem;
    margin: .15rem 0 0;
}


/* --------------------------------------------------------------------------
   Botones
   -------------------------------------------------------------------------- */

.admin-page .btn-primary,
.admin-page .btn-info {
    background: var(--cer-blue, #016599);
    border-color: var(--cer-blue, #016599);
    font-weight: 600;
}
.admin-page .btn-primary:hover,
.admin-page .btn-info:hover {
    background: var(--cer-blue-light, #0B7FBF);
    border-color: var(--cer-blue-light, #0B7FBF);
}

.admin-page .btn-outline-primary {
    color: var(--cer-blue, #016599);
    border-color: var(--cer-blue, #016599);
}
.admin-page .btn-outline-primary:hover {
    background: var(--cer-blue, #016599);
    color: #FFFFFF;
}


/* --------------------------------------------------------------------------
   Menu lateral
   -------------------------------------------------------------------------- */

.admin-menu-user {
    text-align: center;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--cer-line, #DCE5EC);
    margin-bottom: 1rem;
}

.admin-menu-avatar {
    width: 84px;
    height: 84px;
    border-radius: 50%;
    object-fit: cover;
    border: 3px solid var(--cer-sky-bg, #EAF3F9);
    box-shadow: 0 2px 8px rgba(20,40,75,.12);
}

.admin-menu-name {
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 700;
    font-size: 1.1rem;
    color: var(--cer-navy, #14284B);
    margin: .6rem 0 0;
    line-height: 1.2;
}

.admin-menu-mail {
    color: var(--cer-muted, #5C6B7A);
    font-size: .8rem;
    word-break: break-word;
    margin: 0;
}

.admin-menu-role {
    display: inline-block;
    margin-top: .4rem;
    background: var(--cer-sky-bg, #EAF3F9);
    color: var(--cer-blue, #016599);
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    font-size: .7rem;
    padding: .15rem .6rem;
    border-radius: 999px;
}

.admin-menu-title {
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    font-size: .78rem;
    color: var(--cer-muted, #5C6B7A);
    margin-bottom: .5rem;
}

.admin-page .list-group-item-action.admin-menu-item {
    display: flex;
    align-items: center;
    gap: .65rem;
    border: 0;
    border-radius: 8px;
    padding: .6rem .75rem;
    margin-bottom: .15rem;
    color: var(--cer-ink, #1B2733);
    font-weight: 500;
    transition: background .15s ease, color .15s ease;
}
.admin-page .list-group-item-action.admin-menu-item i {
    color: var(--cer-blue, #016599);
    font-size: 1.05rem;
    width: 1.3rem;
    text-align: center;
}
.admin-page .list-group-item-action.admin-menu-item:hover {
    background: var(--cer-sky-bg, #EAF3F9);
    color: var(--cer-navy, #14284B);
}
.admin-page .list-group-item-action.admin-menu-item.active {
    background: var(--cer-navy, #14284B);
    color: #FFFFFF;
}
.admin-page .list-group-item-action.admin-menu-item.active i { color: var(--cer-sky, #9FD3EE); }


/* --------------------------------------------------------------------------
   KPIs del panel
   -------------------------------------------------------------------------- */

.kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 1rem;
}

.kpi {
    background: #FFFFFF;
    border: 1px solid var(--cer-line, #DCE5EC);
    border-left: 4px solid var(--cer-blue, #016599);
    border-radius: 10px;
    padding: 1rem 1.1rem;
}
.kpi.navy  { border-left-color: var(--cer-navy, #14284B); }
.kpi.sky   { border-left-color: var(--cer-sky, #9FD3EE); }
.kpi.warn  { border-left-color: #E0A800; }

.kpi-label {
    display: flex;
    align-items: center;
    gap: .4rem;
    font-size: .75rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--cer-muted, #5C6B7A);
    margin-bottom: .35rem;
}
.kpi-label i { color: var(--cer-blue, #016599); }

.kpi-value {
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 700;
    font-size: 2rem;
    line-height: 1;
    color: var(--cer-navy, #14284B);
}
.kpi-value small {
    font-family: 'Inter', sans-serif;
    font-size: .8rem;
    font-weight: 500;
    color: var(--cer-muted, #5C6B7A);
}

.kpi-foot {
    font-size: .78rem;
    color: var(--cer-muted, #5C6B7A);
    margin-top: .3rem;
}


/* --------------------------------------------------------------------------
   Barras de consumo contra cupo
   -------------------------------------------------------------------------- */

.usage-row { margin-bottom: .9rem; }

.usage-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: .5rem;
    font-size: .85rem;
    margin-bottom: .25rem;
}
.usage-head .lbl { color: var(--cer-ink, #1B2733); }
.usage-head .val {
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 700;
    color: var(--cer-navy, #14284B);
    white-space: nowrap;
}

.usage-bar {
    height: 9px;
    border-radius: 999px;
    background: var(--cer-sky-bg, #EAF3F9);
    overflow: hidden;
}
.usage-fill {
    height: 100%;
    border-radius: 999px;
    background: var(--cer-blue, #016599);
    transition: width .4s ease;
}
/* Cerca del cupo, o pasado */
.usage-fill.near { background: #E0A800; }
.usage-fill.over { background: #C6392F; }

.usage-tag {
    font-size: .7rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    font-weight: 700;
    padding: .1rem .5rem;
    border-radius: 999px;
}
.usage-tag.ok   { background: #E9F7EF; color: #1E6B41; }
.usage-tag.near { background: #FFF6E5; color: #7A5A12; }
.usage-tag.over { background: #FDECEC; color: #A32222; }


/* --------------------------------------------------------------------------
   Tablas
   -------------------------------------------------------------------------- */

.admin-page table.table thead th {
    background: var(--cer-navy, #14284B);
    color: #FFFFFF;
    border: 0;
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    font-size: .85rem;
    white-space: nowrap;
}
.admin-page table.table td { vertical-align: middle; }
.admin-page table.table tbody tr:hover { background: var(--cer-sky-bg, #EAF3F9); }

/* Iconos de accion en la primera columna */
.admin-page table.table td a i { font-size: 1rem; margin-right: .45rem; }

/* Estado */
.state-pill {
    display: inline-block;
    font-size: .72rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    font-weight: 700;
    padding: .15rem .55rem;
    border-radius: 999px;
}
.state-pill.on   { background: #E9F7EF; color: #1E6B41; }
.state-pill.off  { background: #F1F3F5; color: #6C757D; }
.state-pill.test { background: #FFF6E5; color: #7A5A12; }
/* Pendiente: espera una accion, por eso pesa mas que .test, que solo informa. */
.state-pill.pending { background: #FDECEA; color: #8A2A1B; }


/* --------------------------------------------------------------------------
   Contenedor de grafico
   -------------------------------------------------------------------------- */

.chart-box { width: 100%; height: 280px; }
.chart-box.tall { height: 340px; }


/* --------------------------------------------------------------------------
   Movil
   -------------------------------------------------------------------------- */

@media (max-width: 767.98px) {
    .kpi-grid       { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: .75rem; }
    .kpi            { padding: .8rem .9rem; }
    .kpi-value      { font-size: 1.6rem; }
    .chart-box      { height: 240px; }
    .admin-head     { align-items: flex-start; }
    .admin-head .btn { width: 100%; }
}


/* --------------------------------------------------------------------------
   Panel de banderas administrativas (pantalla Companies)
   --------------------------------------------------------------------------
   Las tres banderas cambian como se trata al inquilino, asi que van juntas y
   cada una explica su efecto. Antes estaban sueltas y sin contexto.
   -------------------------------------------------------------------------- */

.flag-panel {
    background: var(--cer-sky-bg, #EAF3F9);
    border: 1px solid var(--cer-line, #DCE5EC);
    border-radius: 10px;
    padding: 1rem 1.1rem .35rem;
}

.flag-panel-title {
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    font-size: .78rem;
    color: var(--cer-muted, #5C6B7A);
    margin-bottom: .75rem;
}
.flag-panel-title i { color: var(--cer-blue, #016599); }

.flag-row {
    padding-bottom: .8rem;
    margin-bottom: .8rem;
    border-bottom: 1px dashed var(--cer-line, #DCE5EC);
}

.flag-row .form-check-label {
    font-weight: 600;
    color: var(--cer-navy, #14284B);
    cursor: pointer;
}
.flag-row .form-check-label i { color: var(--cer-blue, #016599); margin-right: .2rem; }

.flag-row .form-check-input:checked {
    background-color: var(--cer-blue, #016599);
    border-color: var(--cer-blue, #016599);
}

.flag-help {
    display: block;
    color: var(--cer-muted, #5C6B7A);
    font-size: .8rem;
    line-height: 1.45;
    margin: .3rem 0 .5rem 2.5rem;
}

.flag-row .form-control-sm { margin-left: 2.5rem; width: calc(100% - 2.5rem); }

@media (max-width: 575.98px) {
    .flag-help                 { margin-left: 0; }
    .flag-row .form-control-sm { margin-left: 0; width: 100%; }
}


/* --------------------------------------------------------------------------
   Pantallas de subida de archivo
   --------------------------------------------------------------------------
   Patron compartido por todas las vistas que suben algo al sistema: foto de
   perfil, logo de empresa y material multimedia. Antes cada una resolvia el
   input de archivo a su manera y el resultado era desparejo.
   -------------------------------------------------------------------------- */

.upload-panel {
    max-width: 520px;
    margin: 0 auto;
    text-align: center;
}

/* Vista previa de lo que ya esta cargado */
.upload-preview {
    width: 190px;
    height: 190px;
    border-radius: 50%;
    object-fit: cover;
    border: 4px solid #FFFFFF;
    box-shadow: 0 6px 22px rgba(20,40,75,.16);
    background: var(--cer-sky-bg, #EAF3F9);
}
.upload-preview.square {
    border-radius: 12px;
    width: 100%;
    height: auto;
    max-height: 220px;
    object-fit: contain;
    padding: .75rem;
}

.upload-empty {
    width: 190px;
    height: 190px;
    border-radius: 50%;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 3.4rem;
    color: var(--cer-blue, #016599);
    background: var(--cer-sky-bg, #EAF3F9);
    border: 2px dashed var(--cer-line, #DCE5EC);
}

/* Zona para elegir el archivo */
.upload-drop {
    border: 2px dashed var(--cer-line, #DCE5EC);
    border-radius: 12px;
    background: var(--cer-sky-bg, #EAF3F9);
    padding: 1.25rem;
    margin-top: 1.5rem;
    transition: border-color .15s ease, background .15s ease;
}
.upload-drop:hover { border-color: var(--cer-blue, #016599); }
.upload-drop.has-file { border-color: var(--cer-blue, #016599); background: #FFFFFF; }

.upload-drop-icon {
    font-size: 1.9rem;
    color: var(--cer-blue, #016599);
    line-height: 1;
}

.upload-hint {
    color: var(--cer-muted, #5C6B7A);
    font-size: .82rem;
    margin: .5rem 0 0;
}

.upload-filename {
    font-weight: 600;
    color: var(--cer-navy, #14284B);
    word-break: break-all;
    margin: .5rem 0 0;
}

/* El input nativo se oculta: la etiqueta hace de boton */
.upload-input { display: none; }

.upload-actions {
    display: flex;
    gap: .6rem;
    justify-content: center;
    flex-wrap: wrap;
    margin-top: 1rem;
}

.upload-status { margin-top: 1rem; min-height: 1.5rem; }

@media (max-width: 575.98px) {
    .upload-preview, .upload-empty { width: 150px; height: 150px; }
    .upload-empty { font-size: 2.6rem; }
    .upload-actions .btn { width: 100%; }
}


/* --------------------------------------------------------------------------
   Alto de las columnas del workspace
   --------------------------------------------------------------------------
   Reglas pedidas:
     1. El menu lateral NUNCA scrollea: crece hacia abajo lo que necesite y es
        el que DEFINE el alto de la fila.
     2. La caja de contenido mide exactamente lo mismo que el menu.
     3. Si el contenido es mas largo que eso, scrollea POR DENTRO. No hay tope
        de ventana: el tope es el menu.

   Como se logra: el contenido se posiciona en absoluto dentro de su columna.
   Asi NO aporta altura intrinseca a la fila, y la fila termina midiendo lo que
   mide el menu. La columna, al ser un flex item con alto auto, se estira a esa
   altura (align-items: stretch de Bootstrap) y el contenido la llena exacto.

   Solo desde 768px: en telefono las columnas se apilan y el scroll natural de
   la pagina es el correcto.
   -------------------------------------------------------------------------- */

@media (min-width: 768px) {

    /* --- Menu: altura natural, jamas scrollea --- */
    .admin-page .mobile_lm {
        overflow: visible;
    }
    .admin-page .mobile_lm > .card {
        height: 100%;
    }

    /* --- Contenido: no aporta altura, la recibe --- */
    /* Solo cuando hay menu al lado: es el menu el que da el alto de referencia */
    .admin-page .mobile_lm ~ .mobile_cnt {
        position: relative;
    }

    /* Pantallas con una sola tarjeta de contenido */
    .admin-page .mobile_lm ~ .mobile_cnt > .card:only-child,
    /* Pantallas con encabezado propio: el envoltorio .cnt-scroll */
    .admin-page .mobile_lm ~ .mobile_cnt > .cnt-scroll {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        display: flex;
        flex-direction: column;
        min-height: 0;
    }

    /* El envoltorio scrollea entero (varias tarjetas apiladas) */
    .admin-page .mobile_cnt > .cnt-scroll {
        overflow-y: auto;
        overflow-x: hidden;
    }

    /* Con una sola tarjeta, el que scrollea es su cuerpo, para que la cabecera
       de la tarjeta quede fija a la vista */
    .admin-page .mobile_lm ~ .mobile_cnt > .card:only-child > .card-body {
        overflow-y: auto;
        overflow-x: hidden;
        min-height: 0;
        flex: 1 1 auto;
    }

    /* El ultimo bloque del area de scroll estira hasta el fondo, para que la
       caja de contenido cierre a la misma altura que el menu aunque tenga poco
       contenido.
       Se usa 1 0 auto (crece pero NO se encoge): cuando el contenido si es mas
       largo que el alto disponible no hay espacio libre, flex-grow no hace nada
       y manda el scroll. */
    .admin-page .cnt-scroll > :last-child {
        flex: 1 0 auto;
    }
    /* Solo si el ultimo bloque es una tarjeta se la vuelve columna flex, para
       que su card-body ocupe el alto. NO se toca cuando es un .row: ahi
       flex-direction lo maneja Bootstrap y forzar column apilaria las tarjetas. */
    .admin-page .cnt-scroll > :last-child.card {
        display: flex;
        flex-direction: column;
    }
    .admin-page .cnt-scroll > :last-child.card > .card-body {
        flex: 1 1 auto;
        min-height: 0;
    }
    /* Si el ultimo bloque es una fila de tarjetas, las tarjetas la acompanan */
    .admin-page .cnt-scroll > :last-child.row > [class*="col-"] > .card {
        height: 100%;
    }

    /* El ultimo bloque del area de scroll no debe dejar aire abajo: si lo deja,
       al llegar al final el contenido no cierra a la misma altura que el menu.
       Las utilidades mb-* de Bootstrap usan !important, asi que hay que ganarles. */
    .admin-page .cnt-scroll > :last-child,
    .admin-page .cnt-scroll > :last-child > [class*="col-"],
    .admin-page .cnt-scroll > :last-child > [class*="col "] {
        margin-bottom: 0 !important;
    }

    /* Barra de scroll discreta, solo en el contenido */
    .admin-page .mobile_cnt .cnt-scroll::-webkit-scrollbar,
    .admin-page .mobile_cnt .card-body::-webkit-scrollbar { width: 8px; }
    .admin-page .mobile_cnt .cnt-scroll::-webkit-scrollbar-thumb,
    .admin-page .mobile_cnt .card-body::-webkit-scrollbar-thumb {
        background: var(--cer-line, #DCE5EC);
        border-radius: 999px;
    }
    .admin-page .mobile_cnt .cnt-scroll::-webkit-scrollbar-thumb:hover,
    .admin-page .mobile_cnt .card-body::-webkit-scrollbar-thumb:hover {
        background: var(--cer-sky, #9FD3EE);
    }
}


/* El cuerpo de una pantalla de subida centra su panel: al estirarse la tarjeta
   hasta el fondo, el contenido no debe quedar pegado arriba. */
.admin-page .upload-body {
    display: flex;
    flex-direction: column;
    justify-content: center;
}


/* --------------------------------------------------------------------------
   Visor de multimedios
   --------------------------------------------------------------------------
   Compartido por el visor del administrador (dentro de un modal) y por el aula
   del alumno (en la propia pagina). Antes cada uno fijaba 50vh a mano y en un
   telefono el PDF quedaba en una franja inservible.

   La idea: el marco manda, el contenido se acomoda. El alto se calcula contra
   el viewport para que en cualquier pantalla se vea una porcion util, con un
   minimo que evita la franja y un maximo que evita el desborde.
   -------------------------------------------------------------------------- */

.media-frame {
    position: relative;
    width: 100%;
    background: #0E141B;               /* fondo oscuro: el video se apoya, no flota */
    border-radius: 8px;
    overflow: hidden;
}

/* Video: se respeta su proporcion y nunca pasa del alto disponible. Sin el
   tope, un video vertical empuja el modal fuera de la pantalla. */
.media-frame video {
    display: block;
    width: 100%;
    height: auto;
    max-height: 68vh;
    /* object-fit contain para que un video vertical se vea entero, con banda */
    object-fit: contain;
    background: #0E141B;
}

/* PDF: aca el alto SI se fija, porque un embed no tiene proporcion propia. */
.media-frame.pdf {
    height: 62vh;
    min-height: 320px;
    background: var(--cer-bg, #EEF3F7);
}
.media-frame.pdf > iframe,
.media-frame.pdf > div {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
}
/* Sin src el marco esta vacio a proposito (todavia no se abrio ningun
   documento, o se cerro para soltar la memoria): se pinta el fondo y ya. */
.media-frame.pdf > iframe:not([src]) { visibility: hidden; }

/* Nombre del archivo, arriba del marco */
.media-title {
    font-size: .82rem;
    color: var(--cer-muted, #5C6B7A);
    margin: 0 0 .5rem;
    word-break: break-word;
}
.media-title i { color: var(--cer-blue, #016599); margin-right: .35rem; }

/* Enlace de escape: siempre disponible, tambien cuando el embed si funciona.
   Un PDF largo se lee mejor en el visor del propio dispositivo. */
.media-open {
    display: inline-block;
    margin-top: .6rem;
    font-size: .82rem;
    color: var(--cer-blue, #016599);
}
.media-open i { margin-right: .3rem; }

/* --- Ancho del modal en tablet -------------------------------------------
   Bootstrap solo le da 1140 px a modal-xl desde 1200 px de ancho; entre 992 y
   1199 cae a 800 y por debajo de 992 a 500. Medido en iPad vertical: el modal
   ocupaba 500 px de 768 disponibles y el video quedaba en 262 px de alto.
   Aca se le deja usar la pantalla, con el mismo tope que modal-xl. */
@media (min-width: 768px) {
    .modal-media .modal-dialog {
        max-width: min(1140px, calc(100vw - 3rem));
    }
}

/* --- Tablet en vertical y pantallas bajas ------------------------------- */
@media (max-width: 991.98px) {
    .media-frame.pdf   { height: 58vh; }
    .media-frame video { max-height: 60vh; }
}

/* --- Telefono ------------------------------------------------------------
   El modal pasa a ocupar toda la pantalla. Bootstrap 4 no trae modal-fullscreen
   (llego en la 5), asi que se arma aca. En un telefono, un modal centrado con
   margenes desperdicia justo el espacio que al video le hace falta. */
@media (max-width: 767.98px) {
    .modal-media .modal-dialog {
        margin: 0;
        max-width: 100%;
        width: 100%;
        height: 100%;
    }
    .modal-media .modal-content {
        height: 100%;
        border: 0;
        border-radius: 0;
    }
    .modal-media .modal-body {
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        /* Con el modal a pantalla completa, el material se centra: si no, queda
           pegado arriba con medio telefono en blanco debajo. */
        display: flex;
        flex-direction: column;
        justify-content: center;
    }
    .modal-media .modal-body > #theater,
    .modal-media .modal-body > #reader { flex: 0 0 auto; }
    /* Con el modal a pantalla completa el marco puede crecer */
    .modal-media .media-frame.pdf   { height: 70vh; }
    .modal-media .media-frame video { max-height: 72vh; }

    /* En la pagina del alumno no hay modal, y el alto disponible es menor */
    .media-frame.pdf   { height: 55vh; min-height: 280px; }
    .media-frame video { max-height: 52vh; }
}

/* --- Pantalla baja: telefono acostado, o ventana chica ------------------
   Un telefono acostado mide entre 660 y 930 px de ancho, asi que no entra en el
   corte de arriba. Aca se decide por ALTO, que es lo que realmente escasea: con
   ~370 px disponibles, la cabecera y el pie se comen la mitad.

   El cuerpo del modal pasa a scrollear por dentro para que el pie con el boton
   Close quede siempre visible; si no, hay que salir tocando el fondo. */
@media (max-height: 560px) {
    .modal-media .modal-dialog {
        margin: 0;
        max-width: 100%;
        width: 100%;
        height: 100%;
    }
    .modal-media .modal-content {
        height: 100%;
        border: 0;
        border-radius: 0;
    }
    .modal-media .modal-header,
    .modal-media .modal-footer {
        padding-top: .4rem;
        padding-bottom: .4rem;
        flex: 0 0 auto;
    }
    .modal-media .modal-header .modal-title { font-size: 1.05rem; }
    .modal-media .modal-body {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        padding: .6rem .9rem;
        display: flex;
        flex-direction: column;
        justify-content: center;
    }
    /* Contra el viewport, descontando cabecera y pie. Un max-height en % no
       sirve: el marco es de altura automatica y el porcentaje no resuelve.
       Medido antes de esto: video de 462 px en una pantalla de 393. */
    .modal-media .media-frame video { max-height: calc(100vh - 130px); }
    .modal-media .media-frame.pdf   { height: calc(100vh - 130px); min-height: 180px; }

    /* El nombre del archivo se calla: en 370 px de alto no vale una linea */
    .modal-media .media-title { display: none; }

    /* Fuera del modal (aula del alumno) */
    .media-frame video { max-height: 80vh; }
    .media-frame.pdf   { height: 80vh; min-height: 180px; }
}


/* --------------------------------------------------------------------------
   Aula del alumno
   --------------------------------------------------------------------------
   El aula no es una consola de administracion: quien la usa no viene a operar
   registros, viene a estudiar. Por eso pesa mas la sensacion de avance (el
   anillo, las barras) que la densidad de datos.
   -------------------------------------------------------------------------- */

.admin-page .classroom-eyebrow {
    font-size: .68rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    font-weight: 700;
    color: var(--cer-blue, #016599);
    margin: 0 0 .15rem;
}

.classroom-hero {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    flex-wrap: wrap;
}
.classroom-hero-text { flex: 1 1 260px; min-width: 0; }
.classroom-title {
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 600;
    color: var(--cer-navy, #14284B);
    margin: 0;
    font-size: 1.7rem;
    line-height: 1.15;
}
.classroom-sub {
    margin: .25rem 0 0;
    color: var(--cer-muted, #5C6B7A);
    font-size: .9rem;
}

/* Anillo de avance. conic-gradient evita traer una libreria de graficos para
   dibujar un solo circulo. */
.classroom-ring {
    flex: 0 0 auto;
    width: 96px;
    height: 96px;
    border-radius: 50%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: conic-gradient(var(--cer-blue, #016599) calc(var(--pct) * 1%),
                               var(--cer-line, #DCE5EC) 0);
    position: relative;
}
.classroom-ring::before {
    content: "";
    position: absolute;
    inset: 8px;
    background: var(--cer-white, #FFFFFF);
    border-radius: 50%;
}
.classroom-ring span,
.classroom-ring small { position: relative; z-index: 1; }
.classroom-ring span {
    font-family: 'Barlow Condensed', sans-serif;
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--cer-navy, #14284B);
    line-height: 1;
}
.classroom-ring small {
    /* Cabe justo: el texto se sale del circulo si no se le limita el ancho. */
    font-size: .52rem;
    line-height: 1.15;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: var(--cer-muted, #5C6B7A);
    max-width: 62px;
    text-align: center;
}

/* Seguir donde quedo */
.classroom-resume { border-left: 3px solid var(--cer-blue, #016599); }
.classroom-resume-in {
    display: flex;
    align-items: center;
    gap: .9rem;
    flex-wrap: wrap;
}
.classroom-resume-icon {
    flex: 0 0 auto;
    width: 42px; height: 42px;
    border-radius: 10px;
    background: var(--cer-sky-bg, #EAF5FC);
    color: var(--cer-blue, #016599);
    display: flex; align-items: center; justify-content: center;
    font-size: 1.2rem;
}
.classroom-resume-text { flex: 1 1 200px; min-width: 0; }
.classroom-resume-label {
    font-size: .66rem; letter-spacing: .12em; text-transform: uppercase;
    color: var(--cer-muted, #5C6B7A); margin: 0;
}
.classroom-resume-name {
    margin: 0; font-weight: 600; color: var(--cer-navy, #14284B);
    font-size: .92rem; word-break: break-word;
}
.classroom-resume-course {
    margin: 0; font-size: .78rem; color: var(--cer-muted, #5C6B7A);
}

/* Encabezado del reproductor */
.classroom-player-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: .75rem;
}
.classroom-player-title {
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 600;
    color: var(--cer-navy, #14284B);
    margin: 0;
    font-size: 1.25rem;
}
.classroom-views {
    margin: .5rem 0 0;
    font-size: .76rem;
    color: var(--cer-muted, #5C6B7A);
}

/* Estado vacio: se usa tanto para "sin cursos" como para "elegi una leccion" */
.classroom-empty {
    text-align: center;
    padding: 2rem 1rem;
    color: var(--cer-muted, #5C6B7A);
}
.classroom-empty i {
    font-size: 2.2rem;
    color: var(--cer-sky, #9FD3EE);
    display: block;
    margin-bottom: .5rem;
}
.classroom-empty p { margin: 0; font-size: .88rem; }

/* Tarjeta de curso */
.course-card { border: 1px solid var(--cer-line, #DCE5EC); }
.course-card.open {
    border-color: var(--cer-blue, #016599);
    box-shadow: 0 0 0 1px var(--cer-blue, #016599) inset;
}
.course-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .5rem;
    margin-bottom: .4rem;
}
.course-title {
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 600;
    color: var(--cer-navy, #14284B);
    margin: 0;
    font-size: 1.1rem;
    line-height: 1.2;
    min-width: 0;
}
.course-head .state-pill { flex: 0 0 auto; white-space: nowrap; }
.course-details {
    font-size: .8rem;
    color: var(--cer-muted, #5C6B7A);
    margin: 0 0 .6rem;
}

.course-progress { margin-bottom: .6rem; }
.course-progress-bar {
    height: 6px;
    border-radius: 999px;
    background: var(--cer-line, #DCE5EC);
    overflow: hidden;
    margin-bottom: .25rem;
}
.course-progress-bar span {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--cer-blue, #016599), var(--cer-blue-light, #0B7FBF));
}
.course-progress small {
    font-size: .72rem;
    color: var(--cer-muted, #5C6B7A);
}

.course-score { font-size: .82rem; margin: 0 0 .6rem; }
.course-score.ok  { color: #1E6B41; }
.course-score.bad { color: #8A2A1B; }

.course-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    align-items: center;
}
.course-note {
    font-size: .74rem;
    color: var(--cer-muted, #5C6B7A);
    font-style: italic;
}

/* Constancia de los ultimos dias */
.classroom-activity { margin-top: 1.25rem; }
.spark {
    display: flex;
    align-items: flex-end;
    gap: 4px;
    height: 46px;
    margin-top: .4rem;
}
.spark-bar {
    flex: 1 1 0;
    min-width: 0;
    background: var(--cer-line, #DCE5EC);
    border-radius: 2px 2px 0 0;
    transition: background .15s ease;
}
.spark-bar.on { background: var(--cer-blue, #016599); }
.spark-bar:hover { background: var(--cer-blue-light, #0B7FBF); }

@media (max-width: 575.98px) {
    .classroom-hero { gap: .9rem; }
    .classroom-ring { width: 78px; height: 78px; }
    .classroom-ring span { font-size: 1.2rem; }
    .classroom-title { font-size: 1.4rem; }
    .course-head { flex-direction: column; }
    .course-actions .btn { flex: 1 1 auto; }
}


/* --------------------------------------------------------------------------
   Desborde horizontal dentro del area de scroll
   --------------------------------------------------------------------------
   Una .row de Bootstrap lleva margenes negativos (-15px por lado) que asume
   compensados por el padding de un .container. Dentro de .cnt-scroll, que no
   tiene padding, esos margenes se salen: medido en telefono, el documento daba
   405 px en una pantalla de 390. Pasaba en los TRES paneles.

   Se compensa aca, en el patron compartido, y no pantalla por pantalla.
   -------------------------------------------------------------------------- */

.admin-page .cnt-scroll > .row {
    margin-left: 0;
    margin-right: 0;
}
.admin-page .cnt-scroll > .row > [class*="col-"] {
    padding-left: 0;
    padding-right: 0;
}
/* Con el padding en cero, la separacion entre tarjetas la da el gap */
.admin-page .cnt-scroll > .row {
    display: flex;
    flex-wrap: wrap;
    gap: 0 1rem;
}
.admin-page .cnt-scroll > .row > [class*="col-"] {
    flex-basis: 100%;
    max-width: 100%;
}
@media (min-width: 576px) {
    .admin-page .cnt-scroll > .row > .col-6 {
        flex-basis: calc(50% - .5rem);
        max-width: calc(50% - .5rem);
    }
}
@media (min-width: 992px) {
    .admin-page .cnt-scroll > .row > .col-lg-3 {
        flex-basis: calc(25% - .75rem);
        max-width: calc(25% - .75rem);
    }
    .admin-page .cnt-scroll > .row > .col-lg-4 {
        flex-basis: calc(33.333% - .667rem);
        max-width: calc(33.333% - .667rem);
    }
    .admin-page .cnt-scroll > .row > .col-lg-6 {
        flex-basis: calc(50% - .5rem);
        max-width: calc(50% - .5rem);
    }
}
@media (min-width: 1200px) {
    .admin-page .cnt-scroll > .row > .col-xl-4 {
        flex-basis: calc(33.333% - .667rem);
        max-width: calc(33.333% - .667rem);
    }
    .admin-page .cnt-scroll > .row > .col-xl-5 {
        flex-basis: calc(41.666% - .584rem);
        max-width: calc(41.666% - .584rem);
    }
    .admin-page .cnt-scroll > .row > .col-xl-6 {
        flex-basis: calc(50% - .5rem);
        max-width: calc(50% - .5rem);
    }
    .admin-page .cnt-scroll > .row > .col-xl-7 {
        flex-basis: calc(58.333% - .417rem);
        max-width: calc(58.333% - .417rem);
    }
    .admin-page .cnt-scroll > .row > .col-xl-8 {
        flex-basis: calc(66.666% - .334rem);
        max-width: calc(66.666% - .334rem);
    }
}

/* Un elemento flex no encoge por debajo de su contenido si no se le dice.
   Sin esto, .table-responsive no llega a limitar nada y la tabla empuja la
   pagina: medido, 481 px en una pantalla de 390. */
.admin-page .cnt-scroll,
.admin-page .cnt-scroll > *,
.admin-page .cnt-scroll .card,
.admin-page .cnt-scroll .card-body,
.admin-page .mobile_cnt {
    min-width: 0;
}
.admin-page .table-responsive {
    max-width: 100%;
    overflow-x: auto;
}


/* --------------------------------------------------------------------------
   Piso de altura del workspace
   --------------------------------------------------------------------------
   El contenido se estira hasta donde llega el menu lateral. Eso funciona bien
   cuando el menu es largo, pero el del alumno tiene 4 opciones contra 11 del
   administrador: medido en un viewport de 900 px, su menu daba 591 y el area
   util quedaba 160 px mas corta de lo que la pantalla permitia.

   Se le pone un piso al menu, y el contenido lo hereda porque su alto sale del
   de la fila. Donde el menu ya es mas alto que el piso (administrador y
   operador) esta regla no cambia nada.

   El 170px descuenta la cabecera y deja aire para que el pie no quede pegado.
   -------------------------------------------------------------------------- */

@media (min-width: 768px) {
    .admin-page .mobile_lm > .card {
        min-height: calc(100vh - 170px);
    }
}

/* En pantallas bajas el piso estorbaria: con 500 px de alto, restar 170 deja un
   bloque mas alto que la pantalla y todo queda a media asta. */
@media (max-height: 620px) {
    .admin-page .mobile_lm > .card { min-height: 0; }
}


/* --------------------------------------------------------------------------
   Subida compacta
   --------------------------------------------------------------------------
   El .upload-panel ocupa la pantalla y sirve para una pantalla dedicada (la
   foto de perfil). Dentro de un formulario o un modal no cabe: ahi va esta
   variante, que resuelve lo mismo en una linea.

   Lo que aporta sobre un <input type="file"> pelado: se ve que hay una zona
   donde soltar, y se ve QUE archivo quedo elegido. Sin eso, la unica pista era
   el texto gris del propio control, distinto en cada navegador.
   -------------------------------------------------------------------------- */

.upload-drop.compact {
    padding: .7rem .9rem;
    margin: 0;
    text-align: left;
    display: flex;
    align-items: center;
    gap: .6rem;
    min-height: 0;
}
.upload-drop.compact .upload-drop-icon {
    font-size: 1.15rem;
    margin: 0;
    flex: 0 0 auto;
    line-height: 1;
}
.upload-drop.compact .upload-drop-label {
    font-weight: 600;
    color: var(--cer-navy, #14284B);
    font-size: .88rem;
    flex: 0 0 auto;
}
.upload-drop.compact .upload-filename {
    margin: 0;
    font-size: .8rem;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.upload-drop.compact .upload-hint {
    margin: 0 0 0 auto;
    font-size: .74rem;
    flex: 0 0 auto;
}

@media (max-width: 575.98px) {
    .upload-drop.compact { flex-wrap: wrap; }
    .upload-drop.compact .upload-hint { margin-left: 0; width: 100%; }
}


/* --------------------------------------------------------------------------
   Examen
   -------------------------------------------------------------------------- */

.exam-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}
.exam-head-text { flex: 1 1 240px; min-width: 0; }

/* Cronometro. Cambia de color al acercarse el final: el aviso tiene que
   entrar por el rabillo del ojo, no interrumpir. */
.exam-timer {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: .45rem;
    font-family: 'Barlow Condensed', sans-serif;
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--cer-navy, #14284B);
    background: var(--cer-sky-bg, #EAF5FC);
    border-radius: 8px;
    padding: .4rem .85rem;
    font-variant-numeric: tabular-nums;
}
.exam-timer i { font-size: 1.1rem; color: var(--cer-blue, #016599); }
.exam-timer.warn   { background: #FFF6E5; color: #7A5A12; }
.exam-timer.warn i { color: #7A5A12; }
.exam-timer.danger   { background: #FDECEA; color: #8A2A1B; }
.exam-timer.danger i { color: #8A2A1B; }

/* Las reglas del examen, a la vista antes de empezar */
.exam-rules {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem .5rem;
    list-style: none;
    padding: 0;
    margin: 1rem 0 0;
}
.exam-rules li {
    font-size: .78rem;
    color: var(--cer-muted, #5C6B7A);
    background: var(--cer-bg, #EEF3F7);
    border-radius: 999px;
    padding: .25rem .7rem;
}
.exam-rules li i { color: var(--cer-blue, #016599); margin-right: .25rem; }

/* Pregunta */
.exam-q {
    padding: 1rem 0;
    border-bottom: 1px solid var(--cer-line, #DCE5EC);
}
.exam-q:last-of-type { border-bottom: 0; }
.exam-q-title {
    font-weight: 600;
    color: var(--cer-navy, #14284B);
    margin: 0 0 .6rem;
    display: flex;
    gap: .55rem;
    align-items: baseline;
}
.exam-q-num {
    flex: 0 0 auto;
    font-family: 'Barlow Condensed', sans-serif;
    font-size: .8rem;
    font-weight: 700;
    color: #FFFFFF;
    background: var(--cer-blue, #016599);
    border-radius: 999px;
    min-width: 22px;
    height: 22px;
    line-height: 22px;
    text-align: center;
}

/* Opcion: toda la fila es pulsable, no solo el circulito */
.exam-opt {
    display: flex;
    align-items: flex-start;
    gap: .55rem;
    padding: .5rem .7rem;
    margin: 0 0 .35rem 2.2rem;
    border: 1px solid var(--cer-line, #DCE5EC);
    border-radius: 6px;
    cursor: pointer;
    font-weight: 400;
    transition: border-color .12s ease, background .12s ease;
}
.exam-opt:hover { border-color: var(--cer-sky, #9FD3EE); background: var(--cer-sky-bg, #EAF5FC); }
.exam-opt input { margin-top: .25rem; flex: 0 0 auto; }
.exam-opt input:checked + span { font-weight: 600; color: var(--cer-navy, #14284B); }

.exam-text { margin-left: 2.2rem; width: calc(100% - 2.2rem); resize: vertical; }

.exam-actions {
    display: flex;
    justify-content: flex-end;
    gap: .5rem;
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--cer-line, #DCE5EC);
}

/* Resultado */
.exam-result { padding: 1rem 0; }
.exam-score { text-align: center; padding: 1.5rem 1rem; }
.exam-score i { font-size: 2.6rem; display: block; margin-bottom: .4rem; }
.exam-score.ok  i { color: #1E6B41; }
.exam-score.bad i { color: #8A2A1B; }
.exam-score-value {
    font-family: 'Barlow Condensed', sans-serif;
    font-size: 3rem;
    font-weight: 700;
    line-height: 1;
    margin: 0;
    color: var(--cer-navy, #14284B);
}
.exam-score-label {
    font-size: .8rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    font-weight: 700;
    margin: .2rem 0 0;
}
.exam-score.ok  .exam-score-label { color: #1E6B41; }
.exam-score.bad .exam-score-label { color: #8A2A1B; }
.exam-score-detail {
    font-size: .82rem;
    color: var(--cer-muted, #5C6B7A);
    margin: .35rem 0 0;
}

@media (max-width: 575.98px) {
    .exam-opt  { margin-left: 0; }
    .exam-text { margin-left: 0; width: 100%; }
    .exam-actions { flex-direction: column-reverse; }
    .exam-actions .btn { width: 100%; }
}


/* --------------------------------------------------------------------------
   Editor del acuerdo y su lectura
   --------------------------------------------------------------------------
   Quill trae su propia hoja (libs/quill/quill.snow.css). Aca solo se le da el
   alto y se lo alinea con el resto del sistema de diseno.
   -------------------------------------------------------------------------- */

.editor-acuerdo {
    /* Alto util sin que el editor se coma la pantalla entera. El de abajo es
       el minimo para que se vea un parrafo completo mientras se escribe. */
    height: 46vh;
    min-height: 260px;
    background: var(--cer-white, #FFFFFF);
}
.ql-toolbar.ql-snow,
.ql-container.ql-snow {
    border-color: var(--cer-line, #DCE5EC);
}
.ql-toolbar.ql-snow {
    border-top-left-radius: 6px;
    border-top-right-radius: 6px;
    background: var(--cer-bg, #EEF3F7);
}
.ql-container.ql-snow {
    border-bottom-left-radius: 6px;
    border-bottom-right-radius: 6px;
}
.ql-editor { font-size: .92rem; line-height: 1.6; }
.ql-snow .ql-stroke { stroke: var(--cer-navy, #14284B); }
.ql-snow .ql-fill   { fill:   var(--cer-navy, #14284B); }
.ql-snow.ql-toolbar button:hover .ql-stroke,
.ql-snow.ql-toolbar button.ql-active .ql-stroke { stroke: var(--cer-blue, #016599); }
.ql-snow.ql-toolbar button:hover .ql-fill,
.ql-snow.ql-toolbar button.ql-active .ql-fill  { fill:   var(--cer-blue, #016599); }

/* La lectura del alumno: sin editor, solo el texto.
   Se le pone su propio scroll para que el acuerdo largo no estire la pagina. */
.acuerdo-texto {
    max-height: 52vh;
    overflow-y: auto;
    padding: 1.1rem 1.25rem;
    border: 1px solid var(--cer-line, #DCE5EC);
    border-radius: 8px;
    background: var(--cer-white, #FFFFFF);
    font-size: .92rem;
    line-height: 1.65;
    color: var(--cer-ink, #1B2733);
}
.acuerdo-texto h1, .acuerdo-texto h2, .acuerdo-texto h3 {
    font-family: 'Barlow Condensed', sans-serif;
    color: var(--cer-navy, #14284B);
    margin-top: 1.1rem;
}
.acuerdo-texto h1:first-child,
.acuerdo-texto h2:first-child,
.acuerdo-texto h3:first-child { margin-top: 0; }
.acuerdo-texto a { color: var(--cer-blue, #016599); }
/* Una tabla pegada en el acuerdo no puede ensanchar la pagina */
.acuerdo-texto table { max-width: 100%; }
.acuerdo-texto img   { max-width: 100%; height: auto; }

@media (max-width: 575.98px) {
    .editor-acuerdo { height: 40vh; min-height: 200px; }
    .acuerdo-texto  { max-height: 46vh; padding: .9rem 1rem; }
}
