/*
 * ============================================================
 *  educa20.css  —  Sistema de Diseño Educa20
 *  Versión: 1.0  —  Marzo 2026
 * ============================================================
 *
 *  Cómo usar (en cualquier template):
 *    {% load static %}
 *    <link rel="stylesheet" href="{% static 'css/educa20.css' %}">
 *
 *  Índice de secciones:
 *    1. Variables (Custom Properties)
 *    2. Layout — Panel de 2 columnas
 *    3. Panel Title Area (título flotante)
 *    4. Neo-Cards (base, large, small, alineación)
 *    5. Icon Wrapper & Icon Circle
 *    6. Colores de módulo (gradientes e iconos)
 *    7. Textos de módulo
 *    8. Pill Buttons
 *    9. Animaciones de entrada
 *   10. Responsive
 *   11. Botones Redondeados
 *   12. Cinta de Íconos
 *   13. Tablas y Filtros
 *   14. Sistema de Pestañas
 * ============================================================
 */


/* ============================================================
   1. VARIABLES
   ============================================================ */
:root {
    --e20-font: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    --e20-card-bg-start: #eeefefad;
    --e20-card-bg-end: #dee7fc74;
    --e20-card-shadow: 3px 3px 10px rgba(0, 0, 0, 0.122), -3px -3px 10px rgba(0, 0, 0, 0.12);
    --e20-card-radius: 18px;
    --e20-card-resalte3d-shadow:
        inset 0 4px 7px rgba(255, 255, 255, .7),
        inset 4px 0 7px rgba(255, 255, 255, .7),
        inset 0 -4px 6px rgba(0, 0, 0, .3),
        inset -4px 0 6px rgba(0, 0, 0, .3),
        0 4px 5px rgba(0, 0, 0, .38);
    --e20-dialog-bg: rgba(230, 230, 230, .5);
    --e20-dialog-info: #003399;
    --e20-dialog-success: #276749;
    --e20-dialog-warning: var(--e20-dialog-info);
    --e20-dialog-danger: #b02a2a;
}

/* Modal de actividad evaluada: superficie sólida de la paleta institucional. */
.e20-modal-actividad .modal-content {
    background: #f4f7fb;
    border: 1px solid rgba(25, 66, 126, 0.18);
    color: #172033;
}

.e20-modal-actividad .modal-header {
    background: #19427e;
    color: #fff;
}

.e20-modal-actividad .modal-body,
.e20-modal-actividad .modal-footer {
    background: #f4f7fb;
}



/* ============================================================
   4. e20-cards
   ============================================================ */

/*
 *  Jerarquía de clases:
 *    .e20-card                   — base común (siempre presente)
 *
 *  Ejemplo:
 *    <div class="e20-card e20-card--large anim-card-1">
 *      <div class="e20-icon-wrapper"> ... </div>
 *      <div class="e20-card-inner">
 *        <div class="e20-card-title e20-text-teal">Módulo</div>
 *        <div class="e20-card-subtitle e20-text-teal">SUBTÍTULO</div>
 *        <br>
 *        <a href="#" class="e20-pill-btn">Opción</a>
 *      </div>
 *    </div>
 */

/* -- Base -- */
.e20-card {
    background: linear-gradient(135deg, var(--e20-card-bg-start), var(--e20-card-bg-end));
    border-radius: var(--e20-card-radius);
    position: relative;
    box-shadow: var(--e20-card-shadow);
    border: 1.5px solid rgba(255, 255, 255, 1);
    display: flex;
    flex-direction: column;
    justify-content: center;
    margin-bottom: 0.5rem;
}



/* Variante cenefa: esquinas inferiores redondeadas, sin sombra/borde blanco superior */
.e20-card-cenefa {
    border-radius: 0 0 40px 40px;
    box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.10);
    border: 1.5px solid rgba(255, 255, 255, 1);
    border-top: none;
    background: linear-gradient(135deg, var(--e20-card-bg-start), var(--e20-card-bg-end));
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: center;
    overflow: visible;
    z-index: 1031;
}

/* Resalte 3D: triple sombra (luz arriba inset + sombra abajo inset + drop exterior).
   Pensado para tarjetas/contenedores destacados (ej. la card de Inicio de Sesión).
   El background-color lo define quien aplica la clase. */
.resalte3d {
    box-shadow:
        inset  0    3px 3px rgba(255, 255, 255, 0.3),   /* luz arriba    */
        inset  3px  0   3px rgba(255, 255, 255, 0.3),   /* luz izquierda */
        inset  0   -3px 3px rgba(0,   0,   0,   0.19),  /* sombra abajo  */
        inset -3px  0   3px rgba(0,   0,   0,   0.19),  /* sombra derecha*/
        0 8px 32px rgba(0, 0, 0, 0.38);                 /* drop exterior */
}

/* Variante card con resalte 3D incorporado.
   Toma el layout de .e20-card (radius, flex, margin) pero SIN el borde
   blanco y SIN el background-gradient que enmascaran el efecto.
   El background-color lo define quien aplica la clase. */
.e20-card-resalte3d {
    border-radius: var(--e20-card-radius);
    border: none;
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: center;
    margin-bottom: 0.5rem;
    box-shadow:
        inset  0    2px 4px rgba(255, 255, 255, 0.7),  /* luz arriba    */
        inset  2px  0   4px rgba(255, 255, 255, 0.7),  /* luz izquierda */
        inset  0   -2px 3px rgba(0,   0,   0,   0.3),  /* sombra abajo  */
        inset -2px  0   3px rgba(0,   0,   0,   0.3),  /* sombra derecha*/
        0 2px 3px rgba(0, 0, 0, 0.38);                /* drop exterior */
}

/* -- Mini-dashboard administrativo del panel de usuario (b_panelusuario) -- */
.panel-stat {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.1rem 0.2rem;
    margin-bottom: 0.1rem;
    background: none;
    border-radius: 0;
}
.panel-stat-ico {
    font-size: 1rem;
    width: 1.2rem;
    text-align: center;
    flex-shrink: 0;
}
.panel-stat-body {
    display: flex;
    flex-direction: column;
    line-height: 1.05;
    min-width: 0;
}
.panel-stat-num {
    font-size: 0.95rem;
    font-weight: 700;
    text-shadow: none;
}
.panel-stat-lbl {
    font-size: 0.66rem;
    font-weight: 600;
    opacity: 0.88;
}

/* ============================================================
   11. BOTONES REDONDEADOS
   ============================================================ */

.boton-texto {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 35px;
    width: auto;
    min-width: 90px;
    padding: 10px 34px;
    /* El color lo aporta cada boton en --boton-bg; el alfa lo manda el CSS.
       Cambiar --boton-alfa aqui afecta a TODOS los .boton-texto de la app. */
    --boton-bg: #ffffff;
    --boton-alfa: 0.30;
    background-color: rgba(255, 255, 255, 0.30);   /* respaldo para navegadores sin color relativo */
    background-color: rgb(from var(--boton-bg) r g b / var(--boton-alfa));
    color: #ffffff;
    font-size: 0.8em;
    line-height: 1.1;
    text-align: center;
    text-decoration: none;
    border-radius: 20px;
    border: none;
    cursor: pointer;
    box-shadow:
        inset 0  3px 5px rgba(255, 255, 255, 0.29),   /* resalte blanco hover */
        inset 0 -3px 4px rgba(0,   0,   0,   0.19),   /* sombra oscura abajo  */
        0 7px 18px rgba(0, 0, 0, 0.38) !important;    /* sombra exterior      */
    transition: box-shadow 0.3s ease, transform 0.3s ease;
    z-index: 1;
    isolation: isolate;
    pointer-events: auto;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.boton-texto:hover,
.boton-texto:focus,
.boton-texto:focus-visible,
.boton-texto:active {
    transform: translateY(-2px);
    box-shadow:
        inset 0  5px 5px rgba(255, 255, 255, 0.29),   /* resalte blanco hover */
        inset 0 -5px 4px rgba(0,   0,   0,   0.19),   /* sombra oscura abajo  */
        0 7px 18px rgba(0, 0, 0, 0.38) !important;    /* sombra exterior      */
    color: white;
    text-decoration: none;
    outline: none;
}

/* Variante: botón desactivado — se ve, pero no hace nada.
   Se usa para funciones que existen en la pantalla pero están fuera de servicio. */
.boton-texto-desactivado,
.boton-texto-desactivado:hover,
.boton-texto-desactivado:focus,
.boton-texto-desactivado:active {
    opacity: 0.5;
    /* !important porque style_e.css fuerza cursor y pointer-events en .boton-texto */
    cursor: not-allowed !important;
    pointer-events: none !important;
    transform: none !important;
}

/* Variante: ancho ajustado al texto + padding-x cómodo.
   Usar cuando se quiere que cada botón mida lo que su texto + 28px laterales. */
.boton-texto-fit {
    width: max-content !important;
    min-width: 0 !important;
    margin: 0 !important;
}

/* ============================================================
   11b. ENCABEZADOS DE VISTA (títulos y subtítulos coherentes)
   ============================================================ */

/* Acción de solo ícono: combinar con boton-texto y declarar --boton-bg.
   --boton-tamano permite ajustar el diámetro; el ícono mide el 50% de él. */
.boton-redondo,
.boton-texto.boton-redondo {
    --boton-tamano: 44px;
    --boton-alfa: .3;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 var(--boton-tamano);
    width: var(--boton-tamano) !important;
    height: var(--boton-tamano) !important;
    min-width: var(--boton-tamano) !important;
    min-height: var(--boton-tamano);
    padding: 0 !important;
    margin: 0;
    border: 0;
    border-radius: 50% !important;
    background: color-mix(in srgb, var(--boton-bg, #0b1a53) 30%, transparent);
    color: var(--boton-bg, #0b1a53);
    font-size: calc(var(--boton-tamano) * .5);
    line-height: 1;
    text-decoration: none;
    box-shadow: none !important;
    cursor: pointer;
    transform: none;
}
.boton-redondo > :is(i, svg, img) {
    font-size: inherit;
    line-height: 1;
    flex-shrink: 0;
}
.boton-redondo > :is(svg, img) {
    width: 50%;
    height: 50%;
    object-fit: contain;
}
.boton-redondo:is(:hover, :focus, :active) {
    color: var(--boton-bg, #0b1a53);
    text-decoration: none;
    box-shadow: none !important;
    transform: none;
}
.boton-redondo:focus-visible {
    outline: 3px solid var(--boton-bg, #0b1a53);
    outline-offset: 3px;
}
.boton-redondo:disabled,
.boton-redondo[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }

/*  Tipografía estándar para títulos de encabezado.
    Cualquier cambio aquí se refleja en todas las vistas que usen .enc-titulo. */
.enc-titulo {
    font-size: clamp(1.2rem, 4vw, 1.6rem);
    font-weight: 700;
    text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.545);
    color: #ffffff;
}

.enc-subtitulo {
    font-size: clamp(0.9rem, 2vw, 1.1rem);
    color: #ffffff;
}

/* Variante para botones de carga de archivos: ancho 180px */
.boton-texto-file {
    width: 180px !important;
    min-width: 150px !important;
    justify-content: center;
    text-align: center;
}

.boton-texto-file label {
    cursor: pointer;
    margin: 0;
    width: 100%;
}

/* Variante para botones de IA: ancho 120px, alto 40px */
.boton-texto-ia {
    display: flex;
    align-items: center;
    justify-content: center;
    /* Si también quieres centrar horizontalmente */
    height: 40px;
    width: 120px;
    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.4);
    color: white;
    font-size: 0.8em;
    border-radius: 20px 20px 20px 20px;
    line-height: 1.1;
    /* Estilos específicos del botón */
    background-color: #4f73f6;
    color: #ffffff;
    border: none;
    padding: 10px 20px;
    text-align: center;
    text-decoration: none;
    /* Quitar subrayado */
    padding: 0.25rem !important;
    /* espaciado de relleno (p-1), !important para asegurar la prioridad */
    cursor: pointer;
    /* Estilo del cursor como un puntero */

    margin: 0.25rem !important;
    /* margen (mx-1), !important para asegurar la prioridad */
    margin-bottom: 0.5rem !important;
    /* margen (mx-1), !important para asegurar la prioridad */

    /* Estilos de transición y transformación para el efecto de zoom */
    transition: transform .5s;
    /* Animación de la transición */
    margin: 0 auto;
    /* Centrar automáticamente */
}

.boton-texto-ia:hover {
    /* Efecto de escala al pasar el ratón por encima para el zoom */
    transform: scale(1.1);
    /* Zoom de 110% */
    text-decoration: none;
    /* Quitar subrayado */
    color: white;
}


/* ============================================================
   12. CINTA DE ÍCONOS
   ============================================================
   Uso:
     <div class="cinta-container">
       <a href="..." class="cinta-item">
         <i class="fas fa-icon cinta-icon registro-text"></i>
         <span class="cinta-label">Etiqueta</span>
       </a>
     </div>
*/
.cinta-container {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: 0 0;
    padding: 0.15rem 0 0;
}

.cinta-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    text-decoration: none !important;
    color: inherit;
    padding: 0.15rem 0.4rem;
    min-width: 72px;
    transition: transform 0.15s ease;
}

.cinta-item:hover {
    transform: translateY(-3px);
}

.cinta-icon {
    font-size: 2.6rem;
    filter: drop-shadow(1px 2px 2px rgba(0, 0, 0, 0.2));
    margin-bottom: 0.15rem;
}

/* Variante con imagen: los cursos traen su propio ícono, no un glifo de
   FontAwesome. Va por encima de .cinta-icon para que la cinta de cursos
   pese un poco más que las de accesos, sin desbordarlas.
   Los !important son obligatorios: style_e.css se carga antes pero fija
   `img { max-width:100% !important; height:auto !important }`. */
.cinta-icon-img {
    width: 3.52rem !important;
    height: 3.52rem !important;
    max-width: 3.52rem !important;
    max-height: 3.52rem !important;
    object-fit: contain;
    filter: var(--e20-sombra-icono-curso);
    margin-bottom: 0.15rem;
}

/* El nombre de un curso es largo: se le fija el ancho para que envuelva en
   vez de estirar la fila. */
.cinta-item-curso {
    width: 5.6rem;
    position: relative;
}

/* Birrete del curso virtual ya terminado, sobre la esquina de su ícono. El
   ícono mide 3.52rem dentro de un item de 5.6rem, así que su borde derecho
   cae a 1.04rem del borde del item. */
.e20-birrete {
    position: absolute;
    top: 0;
    right: 0.65rem;
    font-size: 1.05rem;
    color: #1567d8;
    background: #fff;
    border-radius: 50%;
    padding: 2px 3px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
}

/* Los íconos de los cursos virtuales (IA) traen margen transparente: se
   agranda la imagen y el margen negativo conserva el alto de la fila. */
.cinta-item-virtual .cinta-icon-img {
    width: 4.6rem !important;
    height: 4.6rem !important;
    max-width: 4.6rem !important;
    max-height: 4.6rem !important;
    margin: -0.54rem 0 -0.39rem;
}

/* Avance del curso virtual, sobre la esquina inferior derecha de su ícono:
   el ícono mide 3.52rem y arranca bajo el padding de 0.15rem del item. */
.e20-avance-badge {
    position: absolute;
    top: 2.55rem;
    right: 0.45rem;
    min-width: 2rem;
    padding: 1px 5px;
    border-radius: 10px;
    background: #1e9e57;
    color: #fff;
    font-size: 0.62rem;
    font-weight: 700;
    line-height: 1.3;
    text-align: center;
    font-variant-numeric: tabular-nums;
    border: 1.5px solid #fff;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
}

.cinta-label {
    font-size: 0.74rem;
    font-weight: 600;
    line-height: 1.2;
    color: #333;
    font-family: var(--e20-font);
}

.cinta-card-title {
    font-size: 1.05rem;
    font-weight: 700;
    font-family: var(--e20-font);
    letter-spacing: -0.2px;
    padding-left: 0.5rem;
    margin: 0 0 0.05rem;
}

/* Colores de cinta por sección */
.registro-text {
    color: #1f8a8e;
}

.progra-text {
    color: #2e4d8c;
}

.admin-text {
    color: #5b21b6;
}

.config-text {
    color: #ac7e24;
}

.pensum-text {
    color: #0e7c6b;
}

.accesos-text {
    color: #0891b2;
}

.estud-text {
    color: #1565c0;
}

.profe-text {
    color: #c2410c;
}

.cartera-text {
    color: #1a3a6e;
}

.caja-text {
    color: #005f60;
}

.reportes-text {
    color: #1b5e4a;
}

.configpagos-text {
    color: #7a5a10;
}

/* ============================================================
   13. TABLAS Y FILTROS (Prefix: e20-tabla-)
   ============================================================ */

.e20-tabla-filtro-bar {
    background-color: rgba(0, 0, 0, 0.277);
}

.e20-tabla-filtro-label {
    color: #ffffff;
    font-weight: 500;
    margin-bottom: 2px;
}

.e20-tabla-filtro-input {
    background-color: rgba(255, 255, 255, 0.15) !important;
    color: #ffffff !important;
    border: 1px solid rgba(255, 255, 255, 0.2) !important;
}

.e20-tabla-filtro-input:focus {
    background-color: rgba(255, 255, 255, 0.25) !important;
    box-shadow: 0 0 0 0.2rem rgba(255, 255, 255, 0.1);
}

/* Fix para opciones del select en Chrome/Firefox */
.e20-tabla-filtro-input option {
    background-color: #2d1060;
    color: white;
}

.e20-tabla {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0 2px;
}

.e20-tabla tbody td {
    padding-top: 4px !important;
    padding-bottom: 4px !important;
    vertical-align: middle !important;
}

.e20-tabla tbody tr:not(.e20-tabla-header-row):not(.e20-tabla-footer-row) {
    line-height: 1.2;
}

.e20-tabla tbody tr:not(.e20-tabla-header-row):not(.e20-tabla-footer-row) > td {
    background-color: rgba(255, 255, 255, 0.4);
}

.e20-tabla tbody tr:not(.e20-tabla-header-row):not(.e20-tabla-footer-row):hover > td {
    background-color: rgba(0, 26, 83, 0.2) !important;
}

.e20-tabla tbody tr[onclick],
.e20-tabla tbody tr.e20-tabla-row,
.e20-tabla tbody tr.fila-grupo {
    cursor: pointer;
}

/* Lista de grupos: cada fila toma el color de su plan de estudios, que la
   plantilla aporta en --programa-bg; el alfa lo manda el CSS. rgb(from ...)
   descarta el alfa que traiga el color y deja el exacto, igual que en
   .boton-texto: cambiar --programa-alfa aqui reajusta todas las filas. */
.e20-tabla tbody tr.fila-grupo.fila-programa > td {
    --programa-alfa: 0.1;
    background-color: rgb(from var(--programa-bg) r g b / var(--programa-alfa));
}

.e20-tabla-header-row {
    background-color: rgba(0, 26, 83, 0.514);
    color: white;
    vertical-align: middle;
    border-radius: 10px 10px 0 0;
}

.e20-tabla-footer-row {
    background-color: rgba(0, 26, 83, 0.514);
    color: white;
    vertical-align: middle;
    border-radius: 0 0 10px 10px;
}

.e20-tabla-header-row th,
.e20-tabla-footer-row td,
.e20-tabla-footer-row th {
    background-color: rgba(0, 26, 83, 0.514);
}

.e20-tabla-header-row th {
    vertical-align: middle;
}

.e20-tabla-header-corner-l {
    border-top-left-radius: 10px;
}

.e20-tabla-header-corner-r {
    border-top-right-radius: 10px;
}

.e20-tabla-footer-corner-l {
    border-bottom-left-radius: 10px;
}

.e20-tabla-footer-corner-r {
    border-bottom-right-radius: 10px;
}

.e20-tabla-paginacion-label {
    color: #444;
    margin-right: 8px;
    font-size: 0.9em;
    font-weight: 600;
}

.e20-tabla-paginacion-link {
    background-color: #f8f9fa;
    border: 1px solid #dee2e6;
    border-radius: 15px;
    color: #495057 !important;
    font-size: 0.8em;
    margin: 0 2px;
    transition: all 0.2s ease;
}

.e20-tabla-paginacion-link:hover {
    background-color: #e9ecef;
    color: #0b1a53 !important;
    transform: translateY(-1px);
}

.e20-tabla-paginacion-active {
    background-color: #0b1a53 !important;
    border: 1px solid #0b1a53 !important;
    border-radius: 15px;
    color: #ffffff !important;
    font-size: 0.8em;
    margin: 0 2px;
    font-weight: bold;
}

/* ============================================================
   14. SISTEMA DE PESTAÑAS  (Prefix: e20-pestanas-)
   ============================================================
   Replica exactamente el estilo de /pensum/update_programa/.
   Color base: #2f4e6a  |  Activa: fondo 47% opac, texto blanco
                         |  Inactiva: fondo 20% opac, texto #2f4e6a

   NOTA: educa20.css carga ANTES que Bootstrap, por eso:
     - Las CSS vars se declaran en .nav-tabs.e20-pestanas-nav
       (especificidad 0,2,0 > 0,1,0 de Bootstrap → gana siempre)
     - Las reglas de color usan !important como red de seguridad

   Uso:
     <ul class="nav nav-tabs e20-pestanas-nav" role="tablist">
       <li class="nav-item">
         <a class="nav-link active" data-bs-toggle="tab"
            data-bs-target="#panel-1" href="#">Pestaña 1</a>
       </li>
     </ul>
     <div class="e20-card e20-pestanas-contenido">
       <div class="tab-pane fade show active" id="panel-1">...</div>
     </div>
*/

/* ── Variables Bootstrap (especificidad 0,2,0 para ganar a Bootstrap) ── */
.nav-tabs.e20-pestanas-nav {
    --bs-nav-tabs-link-active-color: #ffffff;
    --bs-nav-tabs-link-active-bg: #2f4e6a77;
    --bs-nav-tabs-link-active-border-color: #dee2e6 #dee2e6 #2f4e6a77;
    gap: 3px;
    flex-wrap: wrap;
}

/* ── Pestaña inactiva ── */
.e20-pestanas-nav .nav-link {
    font-size: 1.1em !important;
    color: #2f4e6a !important;
    background-color: #2f4e6a33 !important;
}

/* ── Pestaña activa ── */
.e20-pestanas-nav .nav-link.active {
    background-color: #2f4e6a77 !important;
    color: #ffffff !important;
    font-weight: 600;
}

/* ── Hover en inactiva ── */
.e20-pestanas-nav .nav-link:hover:not(.active) {
    color: #2f4e6a !important;
    background-color: #2f4e6a55 !important;
}

/* ── Panel de contenido ──
   Sobreescribe el flex de e20-card para que el alto sea automático
   según el contenido del tab activo (evita espacio en blanco). ── */
.e20-pestanas-contenido {
    display: block !important;
    height: auto !important;

}

.e20-entrada-texto {
    width: 100%;
    padding: 2px 10px;
    margin: 5px 5px;
    box-sizing: border-box;
    /* Hace que el ancho del elemento incluya el relleno y el borde */
    font-size: 1em;
    background-color: rgb(247, 247, 247, 0.5);
    border-top: 1px solid rgba(160, 160, 160, 0.8);
    border-left: 1px solid rgb(160, 160, 160, 0.8);
    border-bottom: 1px solid rgba(255, 255, 255);
    border-right: 1px solid rgba(255, 255, 255);
    border-radius: 10px;
}


/* ============================================================
   15. MÓDULOS TIMELINE  (Prefix: e20-tl-)
   ============================================================
   Layout de timeline vertical: línea punteada + círculos
   numerados (4 capas) + tarjetas con estados y badges.

   Clases de círculo por estado:
     .e20-circulo-verde    → presencial visto  (estado ≥ 2)
     .e20-circulo-amarillo → presencial actual (estado == 1)
     .e20-circulo-azul     → presencial no visto (estado == 0)
     .e20-circulo-cielo    → virtual no visto  (visto: .e20-circulo-verde + card virtual-visto)

   Clases de tarjeta:
     .e20-tl-card--presencial        → blanco 50%
     .e20-tl-card--presencial-visto  → gris 50%, texto 70%
     .e20-tl-card--virtual           → azul bebé 50%
   ============================================================ */

/* ── Contenedor principal con línea punteada ── */
.e20-tl-container {
    position: relative;
    padding-left: 0;
}

.e20-tl-container::before {
    content: '';
    position: absolute;
    left: 32px;
    top: 24px;
    bottom: 24px;
    border-left: 2px dashed #b0b8c8;
    z-index: 0;
}

/* ── Fila de módulo ── */
.e20-tl-row {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin-bottom: 10px;
    position: relative;
    z-index: 1;
}

/* ── Fila virtual: indentada + conector horizontal punteado ── */
.e20-tl-row--virtual {
    margin-left: 50px;
    padding-top: 6px;
    padding-bottom: 6px;
}

/* Conector horizontal punteado: desde línea principal (32px del contenedor)
   hasta el borde izquierdo del círculo virtual (50px del contenedor).
   Relativo al row: left = 32 - 50 = -18px; ancho = 18px */
.e20-tl-row--virtual::before {
    content: '';
    position: absolute;
    top: 34px;
    /* padding-row(6) + padding-col(10) + mitad-círculo(24) - 6 = 34 */
    left: -18px;
    width: 18px;
    height: 0;
    border-top: 2px dashed #b0b8c8;
    z-index: 0;
    pointer-events: none;
}

/* ── Círculo virtual: 70% opacidad ── */
.e20-tl-row--virtual .e20-tl-circle {
    opacity: 0.70;
}

/* ── Columna del círculo ── */
.e20-tl-circle-col {
    flex: 0 0 48px;
    display: flex;
    justify-content: center;
    padding-top: 10px;
}

/* ── Círculo base (capa 1 + 2: color y sombra) ── */
.e20-tl-circle {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.15);
    z-index: 2;
}

/* ── Capa 3: brillo (óvalo blanco ~50% opacidad) ── */
.e20-tl-circle::after {
    content: '';
    position: absolute;
    width: 52%;
    height: 34%;
    background: rgba(255, 255, 255, 0.50);
    border-radius: 50%;
    top: 14%;
    left: 22%;
    pointer-events: none;
    z-index: 3;
}

/* ── Capa 4: número del módulo ── */
.e20-tl-circle-num {
    color: white;
    font-size: 1.25em;
    font-weight: 700;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
    position: relative;
    z-index: 4;
    font-family: var(--e20-font);
    letter-spacing: -0.5px;
}

/* ── Colores de círculo (capa 1: gradiente base) ── */
.e20-circulo-verde {
    background: linear-gradient(145deg, #5dcf6e, #3daa52);
}

.e20-circulo-amarillo {
    background: linear-gradient(145deg, #ffd84e, #f5a623);
}

.e20-circulo-azul {
    background: linear-gradient(145deg, #2e3e9e, #1f2069);
}

.e20-circulo-cielo {
    background: linear-gradient(145deg, #5fc3ef, #3498c8);
}

/* ── Columna de tarjeta ── */
.e20-tl-card-col {
    flex: 1;
    min-width: 0;
}

/* ── Tarjeta base ── */
.e20-tl-card {
    border-radius: 10px;
    padding: 10px 14px;
    display: flex;
    align-items: stretch;
    gap: 10px;
    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.18);
    border: 1.5px solid rgba(255, 255, 255, 0.80);
    transition: transform 0.22s ease, box-shadow 0.22s ease;
    cursor: pointer;
    min-height: 70px;
}

.e20-tl-card:hover {
    transform: scale(1.018);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.13);
}

/* ── Variantes de fondo (50% transparencia) ── */
.e20-tl-card--presencial {
    background: rgba(255, 255, 255, 0.30);
}

.e20-tl-card--presencial-visto {
    background: rgba(200, 205, 210, 0.30);
}

.e20-tl-card--presencial-visto .e20-tl-titulo,
.e20-tl-card--presencial-visto .e20-tl-desc {
    opacity: 0.70;
}

/* Virtual: esquinas inferiores redondeadas al 50% */
.e20-tl-card--virtual {
    background: rgba(181, 220, 242, 0.30);
    border-radius: 10px 10px 40px 40px;
}

/* Virtual ya visto: fondo azul petroleo 0.2 y titulo del mismo azul lleno */
.e20-tl-card--virtual-visto {
    background: rgba(0, 95, 115, 0.20);
}

.e20-tl-card--virtual-visto .e20-tl-titulo {
    color: #005f73;
}

/* ── Cuerpo de la tarjeta (col izquierda flexible) ── */
.e20-tl-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.e20-tl-titulo {
    font-size: 1.2em;
    font-weight: 700;
    color: #2d2d3a;
    line-height: 1.3;
    margin-bottom: 2px;
}

.e20-tl-desc {
    font-size: 0.82em;
    color: #555;
    line-height: 1.4;
}

/* ── Col tipo: badge (top) + actividades/icono-contenido (bottom) ── */
.e20-tl-col-tipo {
    flex: 0 0 100px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 4px 0;
}

/* ── Col duración: texto de duración centrado ── */
.e20-tl-col-dur {
    flex: 0 0 64px;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    font-size: 0.85em;
    color: #333;
    white-space: nowrap;
}

/* ── Col estado (solo módulos virtuales) ── */
.e20-tl-col-estado {
    flex: 0 0 36px;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ── Badges ── */
.e20-badge-pres {
    background: rgba(1, 39, 154, 0.50);
    color: #fff;
    padding: 3px 12px;
    border-radius: 20px;
    font-size: 0.9em;
    font-weight: 600;
    white-space: nowrap;
}

.e20-badge-virt {
    background: rgba(52, 152, 200, 0.55);
    color: #fff;
    padding: 3px 12px;
    border-radius: 20px;
    font-size: 0.75em;
    font-weight: 600;
    white-space: nowrap;
}

/* ── Icono de estado virtual ── */
.e20-tl-estado-img {
    width: 32px;
    height: 32px;
    object-fit: contain;
}

/* ── Iconos de actividades y tipo de contenido ── */
.e20-tl-actividades {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
    justify-content: center;
}

.e20-tl-act-img {
    width: 40px;
    height: 40px;
    object-fit: contain;
}

.e20-tl-tipo-img {
    width: 40px;
    height: 40px;
    object-fit: contain;
    opacity: 0.85;
}

/* ── Encabezado de sección (clase==2) ── */
.e20-tl-seccion {
    color: #1f2069;
    font-size: 1.12em;
    font-weight: 700;
    padding: 1.1rem 0 0.4rem 0;
    position: relative;
    z-index: 1;
}

/* ── Seminario (clase==3) ── */
.e20-circulo-seminario {
    background: linear-gradient(145deg, #e89a5f, #c0632a);
}

.e20-tl-card--seminario {
    background: rgba(255, 184, 142, 0.50);
}

.e20-tl-titulo--seminario {
    color: rgb(57, 13, 87);
}

.e20-badge-seminario {
    background: rgba(190, 120, 60, 0.35);
    color: #6b2a00;
    padding: 2px 10px;
    border-radius: 20px;
    font-size: 0.72em;
    font-weight: 600;
    white-space: nowrap;
}

/* ── Convenciones de actividades ── */
.flex-container-cintafoot {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    height: auto;
}

.e20-tl-conv-item {
    font-size: 0.7em;
    height: 40px;
    width: 60px;
    align-items: initial;
}

.e20-tl-conv-img {
    height: 40px;
    width: 40px;
    object-fit: contain;
}

/* ── Timeline pequeño — sidebar módulos virtuales (e20-tl-sm-*) ── */
.e20-tl-sm-container {
    position: relative;
    padding: 0;
}

/* Línea punteada vertical centrada con los círculos (36px ancho → center=18px) */
.e20-tl-sm-container::before {
    content: '';
    position: absolute;
    left: 18px;
    top: 0;
    bottom: 0;
    border-left: 2px dashed #90b8d8;
    z-index: 0;
    pointer-events: none;
}

.e20-tl-sm-row {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-bottom: 5px;
    position: relative;
    z-index: 1;
}

.e20-tl-sm-circle-col {
    flex: 0 0 36px;
    display: flex;
    justify-content: center;
}

.e20-tl-sm-circle {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: linear-gradient(145deg, #5fc3ef, #3498c8);
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    z-index: 2;
    opacity: 0.85;
    flex-shrink: 0;
}

.e20-tl-sm-num {
    color: white;
    font-size: 0.75em;
    font-weight: 700;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
}

.e20-tl-sm-card {
    flex: 1;
    min-width: 0;
    background: rgba(181, 220, 242, 0.45);
    border-radius: 8px 8px 16px 16px;
    padding: 7px 9px;
    display: flex;
    align-items: center;
    gap: 6px;
    border: 1.5px solid rgba(255, 255, 255, 0.70);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.11);
    cursor: pointer;
    transition: transform 0.15s ease;
    text-decoration: none;
    color: inherit;
}

.e20-tl-sm-card:hover {
    transform: scale(1.015);
    text-decoration: none;
    color: inherit;
}

.e20-tl-sm-card--active {
    background: rgba(52, 152, 200, 0.55);
    border-color: rgba(52, 152, 200, 0.60);
}

.e20-tl-sm-titulo {
    flex: 1;
    min-width: 0;
    font-size: 0.82em;
    font-weight: 700;
    color: #2d2d3a;
    line-height: 1.3;
}

.e20-tl-sm-titulo--active {
    color: #fff;
}

.e20-tl-sm-icon {
    width: 22px;
    height: 22px;
    object-fit: contain;
    opacity: 0.70;
    flex-shrink: 0;
}

.e20-tl-sm-estado {
    width: 26px;
    height: 26px;
    object-fit: contain;
    flex-shrink: 0;
}

/* Encabezado de sección dentro del timeline pequeño */
.e20-tl-sm-seccion {
    font-size: 0.78em;
    font-weight: 700;
    color: #2a7a4a;
    padding: 0.6rem 0 0.25rem 43px;
    position: relative;
    z-index: 1;
}

/* Tarjeta/Chiclet de curso (simplificada) */
.caja-curso {
    --bg-color: #3b82f6;
    position: relative;
    width: 100%;
    aspect-ratio: 3 / 1;
    border-radius: 18px;
    background: transparent;
    box-shadow: 0 10px 16px rgba(0, 0, 0, 0.25);
    border: 1px solid rgba(255, 255, 255, 0.5);
    border-bottom-color: rgba(0, 0, 0, 0.3);
    border-right-color: rgba(0, 0, 0, 0.3);
    overflow: hidden;
    container-type: inline-size;
}

/* Capa de fondo sólida del curso */
.caja-curso-fondo {
    position: absolute;
    inset: 0;
    background: var(--bg-color);
    z-index: 0;
}

/* Brillo superior (20% del alto) */
.caja-curso-brillo {
    position: absolute;
    inset: 0 0 auto 0;
    height: 20%;
    background: linear-gradient(to bottom, rgba(255, 255, 255, 0.5), transparent);
    border-radius: 18px 18px 0 0;
    pointer-events: none;
    z-index: 1;
}

.caja-curso .contenido {
    position: relative;
    z-index: 2;
    height: 100%;
    gap: 12px;
    padding: 0 5%;
}

.caja-curso .icono img {
    height: 30%;
    width: auto;
    object-fit: contain;
}

.caja-curso .titulo {
    color: #fff;
    font-weight: 300;
    line-height: 1.2;
    font-size: clamp(0.5rem, 7cqw, 2rem);
}

/* ============================================================
   16. MODALES  (Prefix: e20-ventana-modal)
   ============================================================
     Estilo base de modales para wrappers Bootstrap y parciales AJAX.
     Variantes disponibles:
     - .e20-ventana-modal--soft
     - .e20-ventana-modal--lg
     - .e20-ventana-modal--sm
*/

/* -- Contenedor principal: borde redondo, sombra fuerte abajo-derecha
      El gradiente azul vive en .modal-body para no pisar el header -- */
.e20-ventana-modal .modal-content {
    background: transparent;
    border: none;
    border-radius: 20px;
    box-shadow: 10px 10px 24px rgba(0, 0, 0, 0.35);
    overflow: hidden;
}

/* -- Header con gradiente azul institucional, texto blanco -- */
.e20-ventana-modal .modal-header {
    background: linear-gradient(135deg, #1e3a8a 0%, #3730a3 100%);
    color: #fff;
    border: none;
    padding: 0.7rem 1.25rem;
}

.e20-ventana-modal .modal-title {
    font-family: var(--e20-font);
    font-weight: 700;
    letter-spacing: 0.3px;
    color: #fff;
    margin: 0;
}

/* X de cerrar en blanco sobre header oscuro */
.e20-ventana-modal .modal-header .btn-close {
    filter: brightness(0) invert(1);
    opacity: 0.85;
}
.e20-ventana-modal .modal-header .btn-close:hover { opacity: 1; }

/* -- Body con gradiente azul de la paleta:
      claro abajo-izq → más saturado arriba-der -- */
.e20-ventana-modal .modal-body {
    background: linear-gradient(45deg, rgba(213, 219, 251, 0.88) 0%, rgba(166, 178, 252, 0.88) 100%);
    padding: 0.85rem 1.25rem;
    text-align: left;
}

/* -- Footer azul lavanda (mismo color del fin del gradiente del body) -- */
.e20-ventana-modal .modal-footer {
    background: rgba(166, 178, 252, 0.884);
    border-top: 1px solid rgba(30, 58, 138, 0.18);
    padding: 0.7rem 1.25rem;
    gap: 0.5rem;
}

/* ─── Variantes ─── */
.e20-ventana-modal.e20-ventana-modal--soft .modal-content {
    box-shadow:
        6px 6px 16px rgba(0, 0, 0, 0.20),
        2px 2px 6px rgba(0, 0, 0, 0.12);
}

.e20-ventana-modal.e20-ventana-modal--lg .modal-dialog { max-width: 920px; }
.e20-ventana-modal.e20-ventana-modal--sm .modal-dialog { max-width: 420px; }

/* -- Variante: el fondo del usuario dentro de la ventana --------------
      El wall que el usuario eligio para la aplicacion entra tambien en
      los modales, para que la ventana se sienta suya y no una pantalla
      prestada. base.html publica `--e20-wall` una sola vez; aqui solo se
      usa. Encima va un velo claro: hay walls oscuros y de mucho detalle,
      y sin el velo el formulario deja de leerse. */
/* El selector es largo a proposito: mas abajo en este mismo archivo hay un
   `.modal.e20-ventana-modal .modal-body` que pinta el fondo con el atajo
   `background`, y con tres clases gana. Para que el wall sobreviva hay que
   igualar el peso, no solo llegar despues. */
.modal.e20-ventana-modal.e20-ventana-modal--fondo-usuario .modal-body {
    position: relative;
    background-image: var(--e20-wall, none);
    background-size: var(--e20-wall-size, 100% auto);
    background-repeat: var(--e20-wall-repeat, repeat-y);
    background-position: top center;
}

.modal.e20-ventana-modal.e20-ventana-modal--fondo-usuario .modal-body::before {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(45deg,
                rgba(236, 240, 255, 0.80) 0%,
                rgba(206, 215, 253, 0.76) 100%);
    pointer-events: none;
}

/* El contenido flota sobre el velo; sin esto el velo lo tapa. */
.modal.e20-ventana-modal.e20-ventana-modal--fondo-usuario .modal-body > * { position: relative; }

/* Agenda del día: su imagen se aplica también en línea porque el contenido
   llega por AJAX. El velo más tenue conserva la lectura sin ocultar el wall. */
.modal.e20-ventana-modal.e20-ventana-modal--fondo-usuario
.e20-agenda-dia__cuerpo::before {
    background: linear-gradient(45deg,
                rgba(255, 255, 255, 0.24) 0%,
                rgba(224, 232, 255, 0.20) 100%);
}

.e20-agenda-dia__tareas {
    display: block;
    width: calc(100% - 1.5rem);
    min-height: 0;
    margin: 0.75rem;
    padding: 0.85rem;
    overflow: visible;
    background: rgba(245, 247, 251, 0.70);
}

.e20-agenda-dia__titulo {
    margin-bottom: 0.35rem;
    color: #5f6673;
    font-size: 0.95rem;
    font-weight: 600;
}

.e20-agenda-dia__editor {
    display: flex;
    align-items: center;
    width: 100%;
    gap: 0.5rem;
    margin-top: 0.65rem;
}

.e20-agenda-dia__editor .e20-entrada-texto {
    min-width: 0;
    min-height: 44px;
    flex: 1 1 auto;
    margin: 0;
    border: 1px solid rgba(1, 76, 67, 0.3);
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.86);
}

.e20-agenda-dia__ok {
    width: auto;
    min-width: 58px;
    height: 44px;
    flex: 0 0 58px;
    padding: 0.4rem 0.65rem;
    background-color: rgba(1, 76, 67, 0.72);
}

.e20-agenda-dia__agregar {
    display: flex;
    justify-content: flex-end;
    margin-top: 0.75rem;
}

.e20-agenda-dia__boton-agregar {
    min-width: 210px;
    height: 44px;
    padding-inline: 1rem;
    background-color: rgba(1, 76, 67, 0.72);
}

.e20-agenda-dia__acciones {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    padding: 0.35rem 0.75rem 0.9rem;
}

.e20-agenda-dia__accion {
    min-width: 132px;
    height: 44px;
    padding-inline: 1.25rem;
}

@media (max-width: 420px) {
    .e20-agenda-dia__tareas {
        width: calc(100% - 1rem);
        margin: 0.5rem;
        padding: 0.65rem;
    }

    .e20-agenda-dia__acciones {
        gap: 0.5rem;
        padding-inline: 0.5rem;
    }

    .e20-agenda-dia__accion {
        min-width: 0;
        flex: 1 1 0;
    }
}

/* -- Bloques de un formulario largo ----------------------------------
      Un formulario de doce campos sin agrupar se lee como una lista de
      la compra. Cada bloque lleva su rotulo con icono. */
.e20-bloque-campos {
    background: rgba(255, 255, 255, 0.62);
    border: 1px solid rgba(30, 58, 138, 0.10);
    border-radius: 14px;
    padding: 0.85rem 1rem 0.6rem;
    margin-bottom: 0.85rem;
}

.e20-bloque-campos__titulo {
    font-family: var(--e20-font);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: #1e3a8a;
    display: flex;
    align-items: center;
    gap: 0.45rem;
    margin-bottom: 0.7rem;
}

.e20-bloque-campos__titulo::after {
    content: '';
    flex: 1;
    height: 1px;
    background: linear-gradient(to right, rgba(30, 58, 138, 0.22), transparent);
}

.e20-etiqueta-campo {
    font-size: 0.74rem;
    font-weight: 600;
    color: #33406b;
    margin-bottom: 0.2rem;
}

/* -- Carga de imagen: el marco ES el boton ---------------------------
      El patron de <input file> escondido detras de una etiqueta ya vive
      en la tienda; aqui se estandariza. Se ve la foto que hay, y al
      pasar por encima aparece la camara: no hace falta explicar nada. */
.e20-foto-carga {
    position: relative;
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    border-radius: 14px;
    overflow: hidden;
    cursor: pointer;
    border: 1px solid rgba(30, 58, 138, 0.18);
    background: rgba(255, 255, 255, 0.75);
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
    /* Curva de salida fuerte: la del navegador se queda corta y el gesto
       pierde intencion. Solo transform y box-shadow, que no repintan. */
    transition: transform 180ms cubic-bezier(0.23, 1, 0.32, 1),
                box-shadow 180ms cubic-bezier(0.23, 1, 0.32, 1);
}

/* En pantalla tactil el hover se dispara al tocar y deja el marco elevado. */
@media (hover: hover) and (pointer: fine) {
    .e20-foto-carga:hover {
        transform: translateY(-3px);
        box-shadow: 0 10px 20px rgba(0, 0, 0, 0.22);
    }
}

.e20-foto-carga:active { transform: scale(0.985); }

.e20-foto-carga__vista {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.e20-foto-carga__velo {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    color: #fff;
    font-size: 0.78rem;
    font-weight: 600;
    /* Texto blanco: el velo tiene que ser oscuro de verdad, no gris. */
    background: rgba(13, 18, 45, 0.74);
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
    opacity: 0;
    transition: opacity 180ms cubic-bezier(0.23, 1, 0.32, 1);
}

.e20-foto-carga__velo i { font-size: 1.5rem; }
.e20-foto-carga:hover .e20-foto-carga__velo,
.e20-foto-carga:focus-within .e20-foto-carga__velo { opacity: 1; }

.e20-foto-carga__rotulo {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 0.3rem 0.6rem;
    font-size: 0.74rem;
    font-weight: 600;
    color: #fff;
    /* El rotulo cae sobre fotos claras: sin un negro fuerte y su sombra,
       el texto blanco desaparece justo en las aulas mejor iluminadas. */
    background: linear-gradient(to top, rgba(0, 0, 0, 0.82), rgba(0, 0, 0, 0.15) 70%, transparent);
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

/* ============================================================
   16b. VENTANAS MODALES UNIFICADAS (e20-ventana-modal)
   ============================================================
    Núcleo unificado para overlays custom y modales Bootstrap.
*/

/* -- Overlay custom (Aula y similares) -- */
.e20-ventana-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.55);
    backdrop-filter: blur(3px);
    z-index: 100100;
    display: none;
    align-items: center;
    justify-content: center;
    overflow-y: auto;
    padding: clamp(14px, 3.5vh, 34px) 12px;
}

.e20-ventana-modal-overlay.abierto {
    display: flex;
}

.e20-ventana-modal-overlay .e20-ventana-modal {
    background: var(--e20-vm-bg, #b5cbf8c7);
    border-radius: 22px;
    max-width: min(var(--e20-vm-overlay-max-width, var(--e20-vm-modal-max-width, 680px)), 95vw);
    width: 100%;
    box-shadow: var(--e20-vm-shadow, 0 24px 60px rgba(0, 0, 0, 0.4));
    padding: 22px 24px;
    max-height: calc(100vh - 92px);
    overflow-y: auto;
    border: var(--e20-vm-border, 1px solid #e2e8f0);
}

.e20-ventana-modal-cerrar,
.av-cerrar {
    border: none;
    background: #edf2f7;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    font-size: 1rem;
    color: #4a5568;
    cursor: pointer;
    transition: all .2s;
}

.e20-ventana-modal-cerrar:hover,
.av-cerrar:hover {
    background: #c53030;
    color: #fff;
    transform: rotate(90deg);
}

/* -- Variante Bootstrap para modales con look Aula/Educa20 -- */
.modal.e20-ventana-modal,
.modal .modal-dialog.e20-ventana-modal {
    z-index: var(--e20-vm-z-index, 100050) !important;
}

.modal.e20-ventana-modal .modal-dialog,
.modal .modal-dialog.e20-ventana-modal {
    margin: 1.2rem auto;
}

.modal.e20-ventana-modal .modal-dialog:not(.modal-sm):not(.modal-lg):not(.modal-xl):not(.modal-fullscreen),
.modal .modal-dialog.e20-ventana-modal:not(.modal-sm):not(.modal-lg):not(.modal-xl):not(.modal-fullscreen) {
    max-width: min(var(--e20-vm-modal-max-width, 980px), 95vw);
}

.modal.e20-ventana-modal .modal-content,
.modal .modal-dialog.e20-ventana-modal .modal-content {
    border-radius: var(--e20-vm-radius, 20px);
    border: var(--e20-vm-border, none);
    box-shadow: var(--e20-vm-shadow, 10px 10px 24px rgba(0, 0, 0, 0.35));
    background: var(--e20-vm-bg, #b5cbf8c7);
}

.modal.e20-ventana-modal .modal-header,
.modal .modal-dialog.e20-ventana-modal .modal-header {
    background: var(--e20-vm-header-bg, #b5cbf8c7);
    color: #fff;
    border: none;
    padding: 0.7rem 1.25rem;
}

.modal.e20-ventana-modal .modal-footer,
.modal .modal-dialog.e20-ventana-modal .modal-footer {
    background: var(--e20-vm-footer-bg, #b5cbf8c7);
    border-top: 1px solid rgba(30, 58, 138, 0.18);
    padding: 0.7rem 1.25rem;
    gap: 0.5rem;
}

.modal.e20-ventana-modal .modal-body,
.modal .modal-dialog.e20-ventana-modal .modal-body {
    max-height: calc(100vh - 230px);
    overflow-y: auto;
    background: var(--e20-vm-body-bg, #b5cbf8c7);
    padding: 0.85rem 1.25rem;
    text-align: left;
}

.modal.e20-ventana-modal .modal-content .form-control,
.modal .modal-dialog.e20-ventana-modal .modal-content .form-control,
.modal.e20-ventana-modal .modal-content textarea,
.modal .modal-dialog.e20-ventana-modal .modal-content textarea,
.modal.e20-ventana-modal .modal-content select,
.modal .modal-dialog.e20-ventana-modal .modal-content select {
    border-radius: 12px;
}

/* Entradas estandarizadas: look e20-entrada-texto en todas las modales */
.modal.e20-ventana-modal :is(input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="color"]):not([type="range"]):not([type="hidden"]):not([type="button"]):not([type="submit"]):not([type="reset"]), textarea, select),
.modal .modal-dialog.e20-ventana-modal :is(input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="color"]):not([type="range"]):not([type="hidden"]):not([type="button"]):not([type="submit"]):not([type="reset"]), textarea, select),
.e20-ventana-modal-overlay .e20-ventana-modal :is(input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="color"]):not([type="range"]):not([type="hidden"]):not([type="button"]):not([type="submit"]):not([type="reset"]), textarea, select) {
    width: 100%;
    padding: 2px 10px;
    box-sizing: border-box;
    font-size: 1em;
    background-color: rgba(247, 247, 247, 0.5);
    border-top: 1px solid rgba(160, 160, 160, 0.8);
    border-left: 1px solid rgba(160, 160, 160, 0.8);
    border-bottom: 1px solid rgba(255, 255, 255, 1);
    border-right: 1px solid rgba(255, 255, 255, 1);
    border-radius: 10px;
}

/* -- Anchos utilitarios para modales (bootstrap y overlay custom) -- */
.e20-ventana-modal--w-550 {
    --e20-vm-modal-max-width: 550px;
    --e20-vm-overlay-max-width: 550px;
}

.e20-ventana-modal--w-760 {
    --e20-vm-modal-max-width: 760px;
    --e20-vm-overlay-max-width: 760px;
}

.e20-ventana-modal--w-820 {
    --e20-vm-modal-max-width: 820px;
    --e20-vm-overlay-max-width: 820px;
}

/* -- Popup anclado: el JS que lo abre le pone left/top junto a la celda que se edita; sin ancla queda centrado. -- */
.modal .modal-dialog.e20-vm-popup {
    --e20-vm-modal-max-width: 300px;
    position: absolute;
    margin: 0;
    width: 300px;
    max-width: calc(100vw - 16px);
    left: 50%;
    top: 10vh;
    transform: translateX(-50%);
}

/* El fondo apenas se insinúa: es un popup, no una ventana que tape la tabla. */
.modal-backdrop.e20-backdrop-tenue {
    /* !important: bootstrap.min.css se carga después y fija opacity .5 */
    opacity: 0.12 !important;
}

/* ============================================================
   16c. VARIANTE REGISTRO: CATALOGO DE PROGRAMAS
   ============================================================ */
.modal.e20-ventana-modal.e20-ventana-modal-catalogo {
    --e20-vm-z-index: 100060;
    --e20-vm-bg: #b5cbf8c7;
    --e20-vm-border: none;
    --e20-vm-radius: 12px;
    --e20-vm-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.7);
    --e20-vm-modal-max-width: 900px;
    padding-right: 0 !important;
}

.modal.e20-ventana-modal.e20-ventana-modal-catalogo .catalog-modal-content {
    color: #fff;
    position: relative;
    overflow: hidden;
}

.modal.e20-ventana-modal.e20-ventana-modal-catalogo .custom-close-btn {
    position: absolute;
    top: 20px;
    right: 20px;
    z-index: 1055;
    background-color: rgba(0, 0, 0, 0.5);
    border-radius: 50%;
    padding: 12px;
    transition: background-color 0.2s;
}

.modal.e20-ventana-modal.e20-ventana-modal-catalogo .custom-close-btn:hover {
    background-color: rgba(0, 0, 0, 0.8);
}

.modal.e20-ventana-modal.e20-ventana-modal-catalogo .catalog-modal-body {
    max-height: 85vh;
    overflow-y: auto;
    overflow-x: hidden;
}

.modal.e20-ventana-modal.e20-ventana-modal-catalogo .catalog-modal-hero {
    position: relative;
    width: 100%;
    height: 450px;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

.modal.e20-ventana-modal.e20-ventana-modal-catalogo .catalog-hero-overlay {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: linear-gradient(to top, #181818 0%, rgba(24, 24, 24, 0.6) 40%, transparent 100%);
}

.modal.e20-ventana-modal.e20-ventana-modal-catalogo .catalog-hero-content {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    padding: 0 40px 30px;
    z-index: 5;
}

.modal.e20-ventana-modal.e20-ventana-modal-catalogo .catalog-hero-title {
    font-size: 3rem;
    font-weight: 800;
    margin-bottom: 10px;
    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.6);
}

.modal.e20-ventana-modal.e20-ventana-modal-catalogo .catalog-meta-match {
    color: #46d369;
    font-weight: 700;
    margin-right: 10px;
}

.modal.e20-ventana-modal.e20-ventana-modal-catalogo .catalog-meta-year {
    margin-right: 10px;
    color: #bcbcbc;
}

.modal.e20-ventana-modal.e20-ventana-modal-catalogo .catalog-meta-rating {
    border: 1px solid rgba(255, 255, 255, 0.4);
    padding: 0 5px;
    border-radius: 3px;
    font-size: 0.8rem;
    color: #bcbcbc;
}

.modal.e20-ventana-modal.e20-ventana-modal-catalogo .catalog-modal-details {
    padding: 0 40px 40px;
}

/* La confirmación de matrícula se superpone al selector de programas. */
.modal.e20-ventana-modal.e20-ventana-modal-matricula {
    --e20-vm-z-index: 100130;
}

/* Retratos de personas
 * El tamano lo define cada vista; estas reglas garantizan recorte cuadrado,
 * borde por rol y una apariencia consistente en toda la plataforma.
 */
.Foto-profe,
.Foto-usr {
    aspect-ratio: 1 / 1 !important;
    height: auto !important;
    border-radius: 50% !important;
    object-fit: cover !important;
    object-position: center;
    box-sizing: border-box;
    flex-shrink: 0;
    vertical-align: middle;
    box-shadow:
        inset 0 3px 5px rgba(255, 255, 255, 0.29),
        inset 0 -3px 4px rgba(0, 0, 0, 0.19),
        0 7px 18px rgba(0, 0, 0, 0.38) !important;
}

.Foto-usr,
.Foto-usr--admin {
    border: 2px solid #dfaf49 !important;
}

.Foto-usr--estudiante {
    border: 2px solid #ffffff !important;
}

.Foto-profe,
.Foto-usr.Foto-usr--profesor {
    border: 2px solid #00d4bd !important;
}

/* Panel de usuario: la foto grande lleva borde de 3px */
.Foto-usr.Foto-usr--panel {
    border-width: 3px !important;
}

@media (max-width: 768px) {
    .e20-ventana-modal-overlay .e20-ventana-modal {
        padding: 16px 14px;
        border-radius: 18px;
    }
}

/* ============================================================
   Asistente de alta de campus
   Todos los selectores quedan aislados para no alterar otras vistas.
   ============================================================ */
.e20-campus-wizard {
    --campus-ink: #243246;
    --campus-muted: #667085;
    --campus-primary: #007f75;
    --campus-primary-dark: #00665f;
    --campus-accent: #00d4bd;
    --campus-line: #d7e2e7;
    max-width: 1180px;
    margin-inline: auto;
    padding-bottom: 72px !important;   /* aire sobre la barra de estado fija */
    color: var(--campus-ink);
    scroll-margin-top: 76px;
}

.e20-campus-wizard__intro {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1.5rem;
    margin-bottom: 1.5rem;
    /* Sobre el fondo del usuario (una foto, un morado) el texto gris no se
       leía: la introducción va sobre una superficie clara como las tarjetas. */
    padding: 1.1rem 1.35rem;
    border: 1.5px solid rgba(255, 255, 255, .95);
    border-radius: var(--e20-card-radius, 18px);
    background: linear-gradient(135deg, rgba(255, 255, 255, .9), rgba(238, 241, 243, .84));
    box-shadow: 0 6px 18px rgba(0, 0, 0, .08);
}

.e20-campus-wizard__intro h1 {
    margin: 0 0 .35rem;
    font-size: clamp(1.55rem, 3vw, 2.15rem);
    font-weight: 750;
    letter-spacing: -.025em;
}

.e20-campus-wizard__intro p {
    margin: 0;
    color: var(--campus-muted);
}

.e20-campus-wizard__eyebrow {
    margin-bottom: .35rem !important;
    color: var(--campus-primary) !important;
    font-size: .78rem;
    font-weight: 800;
    letter-spacing: .12em;
    text-transform: uppercase;
}

.e20-campus-wizard__secure {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    gap: .5rem;
    padding: .55rem .8rem;
    border: 1px solid #b8ddd8;
    border-radius: 999px;
    background: #e9f8f6;
    color: #075e57;
    font-size: .82rem;
    font-weight: 700;
}

.e20-campus-wizard__status:empty {
    display: none;
}

.e20-campus-wizard__error-summary {
    margin-bottom: 1.25rem;
    padding: 1rem 1.1rem;
    border: 1px solid #f3b4b4;
    border-left: 5px solid #c62828;
    border-radius: 12px;
    background: #fff5f5;
    color: #7d1b1b;
}

.e20-campus-wizard__error-summary h2 {
    margin: 0 0 .55rem;
    font-size: 1rem;
    font-weight: 750;
}

.e20-campus-wizard__error-summary ul {
    margin: 0;
    padding-left: 1.25rem;
}

.e20-campus-wizard__error-summary a {
    color: #7d1b1b;
}

.e20-campus-wizard__progress {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: .6rem;
    margin: 0 0 1.25rem;
    padding: 0;
    list-style: none;
}

.e20-campus-wizard__progress button {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 58px;
    gap: .65rem;
    padding: .65rem .75rem;
    border: 1px solid var(--campus-line);
    border-radius: 12px;
    background: rgba(255, 255, 255, .75);
    color: var(--campus-muted);
    text-align: left;
    transition: border-color .18s ease, background-color .18s ease, transform .18s ease;
}

.e20-campus-wizard__progress button span {
    display: grid;
    width: 30px;
    height: 30px;
    flex: 0 0 30px;
    place-items: center;
    border-radius: 50%;
    background: #edf1f3;
    font-size: .8rem;
    font-weight: 800;
}

.e20-campus-wizard__progress button strong {
    font-size: .8rem;
    line-height: 1.15;
}

.e20-campus-wizard__progress button[aria-current="step"] {
    border-color: var(--campus-primary);
    background: #e9f8f6;
    color: #075e57;
    box-shadow: 0 5px 16px rgba(0, 127, 117, .12);
}

.e20-campus-wizard__progress button[aria-current="step"] span {
    background: var(--campus-primary);
    color: white;
}

.e20-campus-wizard__mobile-progress {
    display: none;
    margin-bottom: .8rem;
    color: var(--campus-primary);
    font-size: .9rem;
    font-weight: 800;
}

.e20-campus-wizard--enhanced .e20-campus-wizard__step[hidden] {
    display: none !important;
}

.e20-campus-wizard__step {
    display: block;
    margin-bottom: 1rem;
    padding: clamp(1rem, 3vw, 2rem);
}

.e20-campus-wizard__step-heading {
    display: flex;
    align-items: flex-start;
    gap: .9rem;
    margin-bottom: 1.4rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--campus-line);
}

.e20-campus-wizard__step-heading > span {
    display: grid;
    width: 42px;
    height: 42px;
    flex: 0 0 42px;
    place-items: center;
    border-radius: 13px;
    background: linear-gradient(145deg, var(--campus-primary), var(--campus-accent));
    color: white;
    font-size: .8rem;
    font-weight: 850;
    box-shadow: 0 7px 16px rgba(0, 127, 117, .2);
}

.e20-campus-wizard__step-heading h2 {
    margin: 0;
    font-size: clamp(1.2rem, 2vw, 1.55rem);
    font-weight: 750;
}

.e20-campus-wizard__step-heading h2 em {
    display: inline-block;
    margin-left: .4rem;
    padding: .2rem .5rem;
    border-radius: 999px;
    background: #eef2f4;
    color: var(--campus-muted);
    font-size: .68rem;
    font-style: normal;
    vertical-align: middle;
}

.e20-campus-wizard__step-heading p {
    margin: .25rem 0 0;
    color: var(--campus-muted);
    font-size: .9rem;
}

.e20-campus-wizard__grid,
.e20-campus-wizard__uploads,
.e20-campus-wizard__repeat-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
}

.e20-campus-wizard__grid--grades {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

.e20-campus-wizard__field--wide {
    grid-column: 1 / -1;
}

.e20-campus-wizard__field label {
    display: block;
    margin-bottom: .4rem;
    color: #344054;
    font-size: .84rem;
    font-weight: 750;
}

.e20-campus-wizard__field label span {
    color: #b42318;
}

.e20-campus-wizard__field > input:not([type="checkbox"]):not([type="file"]),
.e20-campus-wizard__field > select,
.e20-campus-wizard__field > textarea,
.e20-campus-wizard__repeat-row input:not([type="color"]),
.e20-campus-wizard__repeat-row select {
    width: 100%;
    min-height: 44px;
    padding: .65rem .75rem;
    border: 1px solid #bccbd2;
    border-radius: 10px;
    background: rgba(255, 255, 255, .88);
    color: var(--campus-ink);
}

.e20-campus-wizard__field > textarea {
    min-height: 105px;
    resize: vertical;
}

.e20-campus-wizard__field > input[type="file"] {
    width: 100%;
    min-height: 48px;
    padding: .5rem;
    border: 1px dashed #9eb7c0;
    border-radius: 10px;
    background: rgba(255, 255, 255, .72);
}

.e20-campus-wizard__field small {
    display: block;
    margin-top: .3rem;
    color: var(--campus-muted);
    font-size: .74rem;
}

.e20-campus-wizard .errorlist {
    margin: .35rem 0 0;
    padding: 0;
    color: #b42318;
    font-size: .78rem;
    font-weight: 650;
    list-style: none;
}

.e20-campus-wizard__switches {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .75rem;
    margin-bottom: 1.2rem;
}

.e20-campus-wizard__switches > label {
    display: flex;
    align-items: flex-start;
    min-height: 72px;
    gap: .75rem;
    padding: .85rem;
    border: 1px solid var(--campus-line);
    border-radius: 12px;
    background: rgba(255, 255, 255, .6);
    cursor: pointer;
}

.e20-campus-wizard__switches input {
    width: 20px;
    height: 20px;
    flex: 0 0 20px;
    margin-top: .1rem;
    accent-color: var(--campus-primary);
}

.e20-campus-wizard__switches strong,
.e20-campus-wizard__switches small {
    display: block;
}

.e20-campus-wizard__switches small {
    margin-top: .15rem;
    color: var(--campus-muted);
    font-size: .76rem;
}

.e20-campus-wizard__repeat {
    margin-top: 1.2rem;
    padding: 1rem;
    border: 1px solid var(--campus-line);
    border-radius: 14px;
    background: rgba(255, 255, 255, .48);
}

.e20-campus-wizard__repeat-grid .e20-campus-wizard__repeat {
    margin-top: 1.2rem;
}

.e20-campus-wizard__repeat-heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: .75rem;
}

.e20-campus-wizard__repeat-heading h3 {
    margin: 0;
    font-size: .95rem;
    font-weight: 750;
}

.e20-campus-wizard__repeat-heading button,
.e20-campus-wizard__repeat-row button {
    min-height: 40px;
    padding: .45rem .7rem;
    border: 1px solid #a7c9c5;
    border-radius: 9px;
    background: #e9f8f6;
    color: #075e57;
    font-size: .78rem;
    font-weight: 750;
}

.e20-campus-wizard__repeat-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: .55rem;
    margin-top: .55rem;
}

.e20-campus-wizard__repeat-row button {
    width: 44px;
    padding-inline: 0;
    border-color: #edc4c1;
    background: #fff1f0;
    color: #b42318;
}

.e20-campus-wizard__color-row {
    grid-template-columns: 52px minmax(0, 1fr) auto;
}

.e20-campus-wizard__color-row input[type="color"] {
    width: 52px;
    height: 44px;
    padding: 3px;
    border: 1px solid #bccbd2;
    border-radius: 10px;
    background: white;
}

/* ── Alta desde el Campus Muestra: pasos, planes, paleta, vista previa ── */
.e20-campus-wizard__progress--4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

.e20-campus-wizard__progress button.is-done span {
    background: #cfeee9;
    color: #075e57;
}

.e20-campus-wizard__field code {
    padding: .1rem .4rem;
    border-radius: 6px;
    background: #eef2f4;
    color: var(--campus-ink);
    font-size: .78rem;
    font-weight: 700;
}

.e20-campus-wizard__grid--ano {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
}

.e20-campus-wizard__calendario {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .6rem;
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
}

.e20-campus-wizard__calendario legend {
    grid-column: 1 / -1;
    margin-bottom: .4rem;
    padding: 0;
    color: #344054;
    font-size: .84rem;
    font-weight: 750;
}

.e20-campus-wizard__calendario legend span {
    color: #b42318;
}

.e20-campus-wizard__radio {
    display: flex;
    align-items: flex-start;
    min-height: 44px;
    gap: .6rem;
    padding: .6rem .75rem;
    border: 1px solid var(--campus-line);
    border-radius: 10px;
    background: rgba(255, 255, 255, .7);
    cursor: pointer;
}

/* El span del radio no es el asterisco de `label span`: texto normal. */
.e20-campus-wizard__field .e20-campus-wizard__radio > span {
    color: var(--campus-ink);
}

.e20-campus-wizard__radio input {
    width: 18px;
    height: 18px;
    flex: 0 0 18px;
    margin-top: .15rem;
    accent-color: var(--campus-primary);
}

.e20-campus-wizard__radio strong,
.e20-campus-wizard__radio small {
    display: block;
}

.e20-campus-wizard__radio small {
    color: var(--campus-muted);
    font-size: .74rem;
}

.e20-campus-wizard__hint {
    margin: 1rem 0 0;
    color: var(--campus-muted);
    font-size: .82rem;
}

.e20-campus-wizard__hint i {
    color: var(--campus-primary);
}

.e20-campus-wizard__planes-tools {
    display: flex;
    justify-content: flex-end;
    gap: 1rem;
    margin-bottom: .6rem;
}

.e20-campus-wizard__link {
    padding: .35rem .2rem;
    border: 0;
    background: none;
    color: var(--campus-primary);
    font-size: .8rem;
    font-weight: 750;
    text-decoration: underline;
    text-underline-offset: .2em;
}

.e20-campus-wizard__planes {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: .85rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.e20-campus-wizard__plan {
    position: relative;
    display: flex;
    min-height: 100%;
    gap: .8rem;
    padding: 1rem 1rem 1rem 1.1rem;
    border: 1.5px solid var(--campus-line);
    border-left: 6px solid var(--plan-color, #7f7f7f);
    border-radius: 14px;
    background: rgba(255, 255, 255, .78);
    cursor: pointer;
    transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}

.e20-campus-wizard__plan:hover {
    transform: translateY(-1px);
    box-shadow: 0 8px 20px rgba(31, 42, 55, .08);
}

.e20-campus-wizard__plan input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

.e20-campus-wizard__plan-check {
    display: grid;
    width: 26px;
    height: 26px;
    flex: 0 0 26px;
    place-items: center;
    margin-top: .15rem;
    border: 2px solid #bccbd2;
    border-radius: 8px;
    background: #fff;
    color: transparent;
    font-size: .8rem;
    transition: background-color .18s ease, border-color .18s ease;
}

.e20-campus-wizard__plan.is-seleccionado {
    border-color: var(--campus-primary);
    background: #f1fbf9;
    box-shadow: 0 6px 18px rgba(0, 127, 117, .12);
}

.e20-campus-wizard__plan.is-seleccionado .e20-campus-wizard__plan-check {
    border-color: var(--campus-primary);
    background: var(--campus-primary);
    color: #fff;
}

.e20-campus-wizard__plan input:focus-visible + .e20-campus-wizard__plan-check {
    outline: 3px solid #00a896;
    outline-offset: 2px;
}

.e20-campus-wizard__plan-body {
    display: flex;
    flex-direction: column;
    min-width: 0;
    gap: .3rem;
}

.e20-campus-wizard__plan-body > strong {
    font-size: 1rem;
    line-height: 1.2;
}

.e20-campus-wizard__plan-nivel {
    color: var(--campus-primary);
    font-size: .7rem;
    font-weight: 800;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.e20-campus-wizard__plan-metricas {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem 1rem;
    color: var(--campus-muted);
    font-size: .8rem;
    font-weight: 650;
}

.e20-campus-wizard__plan-metricas i {
    margin-right: .25rem;
    color: var(--campus-primary);
}

.e20-campus-wizard__plan-grados {
    display: flex;
    flex-wrap: wrap;
    gap: .3rem;
    margin-top: .2rem;
}

.e20-campus-wizard__plan-grados em {
    padding: .12rem .5rem;
    border-radius: 999px;
    background: #eef2f4;
    color: var(--campus-ink);
    font-size: .7rem;
    font-style: normal;
    font-weight: 700;
}

.e20-campus-wizard__vacio {
    margin: 0;
    padding: 1rem;
    border: 1px dashed #9eb7c0;
    border-radius: 12px;
    background: rgba(255, 255, 255, .6);
    color: var(--campus-muted);
}

.e20-campus-wizard__presets {
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
    margin-bottom: 1rem;
}

.e20-campus-wizard__preset {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    gap: .6rem;
    padding: .45rem .85rem .45rem .55rem;
    border: 1.5px solid var(--campus-line);
    border-radius: 999px;
    background: rgba(255, 255, 255, .8);
    color: var(--campus-ink);
    font-size: .82rem;
    font-weight: 750;
    transition: border-color .18s ease, box-shadow .18s ease;
}

.e20-campus-wizard__preset.is-activo {
    border-color: var(--campus-primary);
    box-shadow: 0 0 0 3px rgba(0, 127, 117, .15);
}

.e20-campus-wizard__preset-muestra {
    display: inline-flex;
    gap: 2px;
}

.e20-campus-wizard__preset-muestra i {
    display: block;
    width: 14px;
    height: 22px;
    border-radius: 4px;
}

.e20-campus-wizard__preview {
    margin-bottom: 1.2rem;
    overflow: hidden;
    border: 1px solid var(--campus-line);
    border-radius: 14px;
    background: #f5f7f9;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .9);
}

.e20-campus-wizard__preview-nave {
    position: relative;
    display: flex;
    align-items: center;
    height: 46px;
    gap: .8rem;
    padding: 0 1rem;
    background: #001a53;
    color: #fff;
    font-size: .85rem;
    transition: background-color .18s ease;
}

.e20-campus-wizard__preview-logo {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .85);
}

.e20-campus-wizard__preview-menu {
    display: flex;
    gap: .4rem;
    margin-left: auto;
}

.e20-campus-wizard__preview-menu i {
    display: block;
    width: 36px;
    height: 8px;
    border-radius: 4px;
    background: rgba(255, 255, 255, .55);
}

.e20-campus-wizard__preview-linea {
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    height: 3px;
    background: #00d4bd;
}

.e20-campus-wizard__preview-cuerpo {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: .9rem 1rem;
}

.e20-campus-wizard__preview-boton {
    padding: .35rem .9rem;
    border-radius: 999px;
    background: #00a896;
    color: #fff;
    font-size: .75rem;
    font-weight: 750;
}

.e20-campus-wizard__preview-tarjeta {
    flex: 1 1 auto;
    height: 26px;
    border-radius: 8px;
    background: #dce8ff;
}

.e20-campus-wizard__preview-estado {
    padding: .45rem 1rem;
    background: #1f2a44;
    color: #fff;
    font-size: .78rem;
    font-weight: 700;
}

.e20-campus-wizard__paleta {
    display: grid;
    gap: .65rem;
}

.e20-campus-wizard__color {
    display: grid;
    grid-template-columns: 56px minmax(0, 1fr) 140px;
    align-items: center;
    gap: .9rem;
    padding: .7rem .8rem;
    border: 1px solid var(--campus-line);
    border-left: 6px solid var(--slot-color, transparent);
    border-radius: 12px;
    background: rgba(255, 255, 255, .7);
}

.e20-campus-wizard__color.has-error {
    border-color: #f3b4b4;
}

.e20-campus-wizard__color input[type="color"] {
    width: 56px;
    height: 44px;
    padding: 3px;
    border: 1px solid #bccbd2;
    border-radius: 10px;
    background: #fff;
}

.e20-campus-wizard__color input[type="text"] {
    width: 100%;
    min-height: 44px;
    padding: .6rem .7rem;
    border: 1px solid #bccbd2;
    border-radius: 10px;
    background: rgba(255, 255, 255, .9);
    color: var(--campus-ink);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .9rem;
    text-transform: uppercase;
}

.e20-campus-wizard__color-texto label {
    display: block;
    margin-bottom: .15rem;
    color: #344054;
    font-size: .88rem;
    font-weight: 750;
}

.e20-campus-wizard__color-texto small {
    display: block;
    color: var(--campus-muted);
    font-size: .76rem;
    line-height: 1.35;
}

.e20-campus-wizard__resumen {
    margin-top: 1.25rem;
    padding: 1rem 1.1rem;
    border: 1px solid #a8ddd6;
    border-radius: 14px;
    background: #edf9f7;
}

.e20-campus-wizard__resumen h3 {
    margin: 0 0 .6rem;
    font-size: 1rem;
    font-weight: 750;
}

.e20-campus-wizard__resumen h3 i {
    margin-right: .35rem;
    color: var(--campus-primary);
}

.e20-campus-wizard__resumen dl {
    display: grid;
    gap: .45rem;
    margin: 0;
}

.e20-campus-wizard__resumen dl > div {
    display: grid;
    grid-template-columns: 130px minmax(0, 1fr);
    gap: .6rem;
    font-size: .86rem;
}

.e20-campus-wizard__resumen dt {
    color: var(--campus-muted);
    font-weight: 750;
}

.e20-campus-wizard__resumen dd {
    margin: 0;
}

.e20-campus-wizard__advanced {
    overflow: hidden;
    border: 1px solid var(--campus-line);
    border-radius: 14px;
    background: rgba(255, 255, 255, .55);
}

.e20-campus-wizard__advanced summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 56px;
    gap: 1rem;
    padding: .85rem 1rem;
    cursor: pointer;
    font-weight: 750;
}

.e20-campus-wizard__advanced summary small {
    padding: .2rem .55rem;
    border-radius: 999px;
    background: #eef2f4;
    color: var(--campus-muted);
    font-size: .7rem;
}

.e20-campus-wizard__advanced-body {
    padding: .25rem 1rem 1rem;
    border-top: 1px solid var(--campus-line);
}

.e20-campus-wizard__confirmation {
    display: flex;
    align-items: flex-start;
    gap: .8rem;
    margin-top: 1.25rem;
    padding: 1rem;
    border: 1px solid #a8ddd6;
    border-radius: 14px;
    background: #edf9f7;
}

.e20-campus-wizard__confirmation > i {
    margin-top: .15rem;
    color: var(--campus-primary);
    font-size: 1.25rem;
}

.e20-campus-wizard__confirmation h3,
.e20-campus-wizard__confirmation p {
    margin: 0;
}

.e20-campus-wizard__confirmation h3 {
    font-size: 1rem;
}

.e20-campus-wizard__confirmation p {
    margin-top: .25rem;
    color: var(--campus-muted);
    font-size: .84rem;
}

.e20-campus-wizard__noscript {
    padding: .8rem 1rem;
    border-radius: 10px;
    background: #fff7dc;
    color: #704f00;
}

.e20-campus-wizard__actions {
    position: sticky;
    /* La barra de estado del pie es fija y mide 54 px: pegada a 0 quedaba
       debajo de ella y los botones no se podían pulsar. */
    bottom: 62px;
    z-index: 10;
    display: flex;
    justify-content: flex-end;
    gap: .65rem;
    margin-top: 1rem;
    padding: .8rem;
    border: 1px solid rgba(215, 226, 231, .9);
    border-radius: 14px;
    background: rgba(246, 248, 249, .94);
    box-shadow: 0 -5px 24px rgba(31, 42, 55, .08);
    backdrop-filter: blur(10px);
}

.e20-campus-wizard__button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    gap: .45rem;
    padding: .65rem 1rem;
    border: 1px solid transparent;
    border-radius: 10px;
    font-weight: 750;
    text-decoration: none;
}

.e20-campus-wizard__button--secondary {
    border-color: #bdcbd1;
    background: #fff;
    color: #344054;
}

.e20-campus-wizard__button--primary,
.e20-campus-wizard__button--submit {
    background: var(--campus-primary);
    color: white;
    box-shadow: 0 6px 15px rgba(0, 127, 117, .2);
}

.e20-campus-wizard__button--primary:hover,
.e20-campus-wizard__button--submit:hover {
    background: var(--campus-primary-dark);
    color: white;
}

.e20-campus-wizard__button:disabled {
    cursor: wait;
    opacity: .7;
}

.e20-campus-wizard :focus-visible {
    outline: 3px solid #00a896;
    outline-offset: 2px;
}

@media (max-width: 991.98px) {
    .e20-campus-wizard__grid--grades {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .e20-campus-wizard__progress button {
        display: grid;
        justify-items: center;
        text-align: center;
    }
}

@media (max-width: 767.98px) {
    .e20-campus-wizard {
        padding-top: 1rem !important;
    }

    .e20-campus-wizard__intro {
        display: block;
        padding: 1rem;
    }

    .e20-campus-wizard__secure {
        margin-top: .8rem;
    }

    .e20-campus-wizard__progress {
        display: none;
    }

    .e20-campus-wizard__mobile-progress {
        display: block;
    }

    .e20-campus-wizard__grid,
    .e20-campus-wizard__grid--grades,
    .e20-campus-wizard__uploads,
    .e20-campus-wizard__repeat-grid,
    .e20-campus-wizard__switches {
        grid-template-columns: 1fr;
    }

    .e20-campus-wizard__step {
        padding: 1rem;
        border-radius: 14px;
    }

    .e20-campus-wizard__step-heading > span {
        width: 36px;
        height: 36px;
        flex-basis: 36px;
    }

    .e20-campus-wizard__grid--ano,
    .e20-campus-wizard__calendario {
        grid-template-columns: 1fr;
    }

    .e20-campus-wizard__color {
        grid-template-columns: 56px minmax(0, 1fr);
    }

    .e20-campus-wizard__color input[type="text"] {
        grid-column: 1 / -1;
    }

    .e20-campus-wizard__resumen dl > div {
        grid-template-columns: 1fr;
        gap: .1rem;
    }

    .e20-campus-wizard__actions {
        display: grid;
        grid-template-columns: 1fr 1fr;
    }

    .e20-campus-wizard__button {
        width: 100%;
    }

    .e20-campus-wizard__button--submit {
        grid-column: 1 / -1;
    }
}

@media (prefers-reduced-motion: reduce) {
    .e20-campus-wizard * {
        scroll-behavior: auto !important;
        transition: none !important;
    }
}


/* ============================================================
   FORMULARIO DENTRO DE UNA VENTANA  (Prefix: e20-modal-, e20-boton-modal)
   ============================================================ */

/* Subtitulo del encabezado: blanco sobre el degradado azul oscuro. */
.e20-modal-subtitulo {
    font-size: 0.78rem;
    color: rgba(255, 255, 255, 0.82);
}

/* Aviso de error: rojo oscuro sobre rojo palido. Texto oscuro sobre fondo
   claro se lee mejor que blanco sobre rojo medio. */
.e20-modal-aviso {
    background: rgba(176, 42, 55, 0.12);
    border: 1px solid rgba(176, 42, 55, 0.38);
    border-radius: 10px;
    padding: 0.55rem 0.85rem;
    color: #8a1c26;
    font-size: 0.85rem;
}

.e20-error-campo {
    font-size: 0.72rem;
    font-weight: 600;
    color: #a12030;
    padding-left: 5px;
}

/* Botones del pie: fondos oscuros, porque el texto va en blanco y el pie
   es azul claro. Los tonos medios dejaban las letras a medio leer. */
.e20-boton-modal {
    transition: transform 160ms cubic-bezier(0.23, 1, 0.32, 1),
                box-shadow 160ms cubic-bezier(0.23, 1, 0.32, 1);
}

/* Responde al dedo: sin esto el boton no acusa recibo de la pulsacion. */
.e20-boton-modal:active { transform: scale(0.97); }

.e20-boton-modal--guardar  { background-color: #146c43; }
.e20-boton-modal--neutro   { background-color: #495057; }
.e20-boton-modal--peligro  { background-color: #a52834; }

/* Contactos familiares: formulario compacto y legible dentro de la modal. */
.modal.e20-contactos-modal .modal-content {
    background: linear-gradient(135deg,
                var(--e20-card-bg-start),
                var(--e20-card-bg-end));
    border: 1.5px solid #fff;
}

.modal.e20-contactos-modal .e20-contactos-modal__header,
.modal.e20-contactos-modal .e20-contactos-modal__footer {
    background: rgba(0, 32, 74, 0.50);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}

.modal.e20-contactos-modal .e20-contactos-modal__body {
    background: linear-gradient(135deg,
                var(--e20-card-bg-start),
                var(--e20-card-bg-end));
    color: #172033;
}

.modal.e20-contactos-modal .e20-contacto-card {
    border: 1.5px solid #fff;
    background: rgba(255, 255, 255, 0.46);
    box-shadow: var(--e20-card-shadow);
}

.modal.e20-contactos-modal .e20-bloque-campos {
    padding: 0.65rem 0 0.35rem;
    border: 0;
    border-radius: 0;
    border-top: 2px solid #00d3c5;
    background: transparent;
}

.modal.e20-contactos-modal .e20-bloque-campos__titulo {
    color: #00204a;
}

.modal.e20-contactos-modal .e20-bloque-campos__titulo::after {
    background: linear-gradient(to right, rgba(0, 211, 197, 0.48), transparent);
}

.modal.e20-ventana-modal.e20-contactos-modal .modal-content :is(input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="color"]):not([type="range"]):not([type="hidden"]):not([type="button"]):not([type="submit"]):not([type="reset"]), textarea, select) {
    min-height: 44px;
    padding: 0.5rem 0.75rem;
    border: 1px solid #d1d5db;
    border-radius: 0.5rem;
    background-color: #fff;
    color: #172033;
    font-size: 1rem;
    transition: border-color 0.2s, box-shadow 0.2s;
}

.modal.e20-ventana-modal.e20-contactos-modal .modal-content :is(input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="color"]):not([type="range"]):not([type="hidden"]):not([type="button"]):not([type="submit"]):not([type="reset"]), textarea, select):focus {
    border-color: #00d3c5;
    box-shadow: 0 0 0 3px rgba(0, 212, 189, 0.10);
    outline: 0;
}

.e20-boton-contactos,
.e20-boton-contactos:hover,
.e20-boton-contactos:focus {
    min-height: 44px;
    background-color: #0048ba;
    color: #fff;
    border: 1px solid rgba(0, 32, 74, 0.42);
}

.e20-modal-cargando {
    min-height: 180px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #1e3a8a;
    font-weight: 600;
}

.e20-contactos-formset {
    color: #172554;
}

.e20-contacto-card {
    min-width: 0;
    margin: 0;
    padding: 0.9rem;
    border: 1px solid rgba(30, 58, 138, 0.22);
    border-radius: 16px;
    background: rgba(255, 255, 255, 0.52);
    box-shadow: 0 5px 14px rgba(30, 58, 138, 0.10);
}

.e20-contacto-card__titulo {
    width: auto;
    float: none;
    display: flex;
    align-items: center;
    gap: 0.55rem;
    margin: 0 0 0.7rem;
    padding: 0;
    color: #173782;
    font-size: 0.95rem;
    font-weight: 700;
}

.e20-contacto-card__numero {
    width: 30px;
    height: 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 30px;
    border-radius: 50%;
    background: #173782;
    color: #fff;
    box-shadow: 0 3px 8px rgba(23, 55, 130, 0.28);
}

.modal.e20-ventana-modal .e20-contacto-card :is(input:not([type="checkbox"]), select) {
    min-height: 44px;
    margin: 2px 0 0;
}

.e20-contacto-opciones {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.55rem;
}

.e20-contacto-opcion {
    min-height: 52px;
    display: flex;
    align-items: center;
    gap: 0.65rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid rgba(30, 58, 138, 0.15);
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.58);
    cursor: pointer;
}

.e20-contacto-opcion span {
    min-width: 0;
    display: flex;
    flex-direction: column;
    line-height: 1.25;
}

.e20-contacto-opcion strong {
    color: #233c75;
    font-size: 0.82rem;
}

.e20-contacto-opcion small {
    color: #52617f;
    font-size: 0.72rem;
}

.e20-contacto-check {
    width: 24px;
    height: 24px;
    flex: 0 0 24px;
    margin: 0;
    cursor: pointer;
}

.e20-contacto-activo {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.65rem;
    padding: 0 0.65rem;
    color: #33406b;
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
}

.e20-contacto-verificacion {
    min-height: 74px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.65rem;
    border: 1px solid rgba(30, 58, 138, 0.15);
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.58);
}

.e20-contacto-verificacion__datos {
    min-width: 0;
    display: flex;
    flex-direction: column;
    color: #33406b;
    font-size: 0.78rem;
}

.e20-contacto-verificacion__datos strong,
.e20-contacto-verificacion__datos small,
.e20-contacto-verificacion__datos span {
    overflow-wrap: anywhere;
}

@media (max-width: 767.98px) {
    .e20-contacto-opciones {
        grid-template-columns: 1fr;
    }

    .e20-contacto-card {
        padding: 0.7rem;
    }

    .e20-contacto-verificacion {
        align-items: flex-start;
        flex-direction: column;
    }
}

@media (prefers-reduced-motion: reduce) {
    .e20-foto-carga,
    .e20-boton-modal {
        transition: none;
    }
    .e20-foto-carga:hover,
    .e20-foto-carga:active,
    .e20-boton-modal:active {
        transform: none;
    }
}

/* ══════════════════════════════════════════════════════════════
   SUDOKU · tablero de programación de clases (e20-sudoku-*)
   ══════════════════════════════════════════════════════════════ */
.e20-sudoku-tab.active { border-top: 3px solid var(--tab-color, #336699) !important; }
.e20-sudoku-barra { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: .5rem .75rem; padding: .5rem .25rem 2px; }
.e20-sudoku-acciones { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.e20-sudoku-acciones .boton-texto { font-size: .85rem; padding: .35rem .8rem; }
.e20-sudoku-acciones .boton-texto:disabled { opacity: .45; cursor: not-allowed; }
.e20-sudoku-pendientes { display: inline-block; min-width: 1.4em; margin-left: .35em; padding: 0 .35em; border-radius: 1em; background: #ffcc00; color: #222; font-size: .75em; font-weight: 700; }
/* Va en su propia línea, debajo de los botones y alineado a la derecha */
.e20-sudoku-bloqueo { font-size: .85rem; color: #555; display: flex; align-items: center; justify-content: flex-end; gap: .4rem; flex-basis: 100%; }
.e20-sudoku-bloqueo--propio { color: #0e7c6b; font-weight: 600; }
.e20-sudoku-bloqueo--ajeno { color: #b23a48; font-weight: 600; }
.e20-sudoku-wrap { position: relative; overflow: auto; max-height: calc(100vh - 290px); min-height: 240px; border: 1px solid #cfd8e3; border-radius: 8px; background: #fff; }
.e20-sudoku-vacio { padding: 2rem; text-align: center; color: #667; }
.e20-sudoku-tabla { border-collapse: separate; border-spacing: 0; font-size: .8rem; font-family: Arial, Helvetica, sans-serif; white-space: nowrap; }
.e20-sudoku-tabla th, .e20-sudoku-tabla td { border-right: 1px solid #e3e8ef; border-bottom: 1px solid #e3e8ef; padding: 0 .3rem; height: 26px; line-height: 26px; text-align: center; box-sizing: border-box; }
.e20-sudoku-tabla thead th { position: sticky; z-index: 3; background: #f4f6f9; }
.e20-sudoku-h1 th { top: 0; height: 48px; line-height: 48px; }
.e20-sudoku-h2 th { top: 48px; height: 34px; line-height: 34px; }
.e20-sudoku-h3 th { top: 82px; height: 26px; line-height: 26px; background: #9aa0a6 !important; color: #fff; font-weight: 600; }
.e20-sudoku-esq { left: 0; z-index: 5 !important; background: #5f6b7a !important; color: #fff; font-weight: 600; min-width: 44px; width: 44px; }
.e20-sudoku-esq-hora { left: 44px; min-width: 64px; width: 64px; }
.e20-sudoku-col-dia { position: sticky; left: 0; z-index: 2; background: #4a5568; color: #fff; font-weight: 700; min-width: 44px; width: 44px; vertical-align: middle; }
.e20-sudoku-col-dia span { display: inline-block; writing-mode: vertical-rl; transform: rotate(180deg); letter-spacing: .05em; }
.e20-sudoku-col-hora { position: sticky; left: 44px; z-index: 2; background: #e9edf2; color: #333; font-size: .75rem; min-width: 64px; width: 64px; }
.e20-sudoku-dia-inicio td { border-top: 3px solid rgba(74, 111, 165, .3); }
.e20-sudoku-sep {
  min-width: 9px; width: 9px; padding: 0 !important; background: transparent !important;
  border-top: 0 !important; border-bottom: 0 !important;
  border-left: 2px solid #e3e8ef !important; border-right: 1px solid #e3e8ef !important;
}
/* En el encabezado sticky el separador necesita fondo opaco: si no, las filas se ven por debajo al hacer scroll */
.e20-sudoku-tabla thead th.e20-sudoku-sep { background: #fff !important; }
.e20-sudoku-grupo { background: var(--grupo-color, #9aa5b1) !important; color: #fff; font-weight: 700; font-size: 1rem; text-align: center; vertical-align: middle; }
/* El encabezado del grupo se ve como un bloque: sin bordes entre sus celdas ni entre sus dos filas */
.e20-sudoku-tabla .e20-sudoku-grupo { border-right: 0; border-bottom: 0; }
.e20-sudoku-tabla .e20-sudoku-prog { border-right: 0; }
.e20-sudoku-grupo--inactivo { filter: grayscale(1); opacity: .75; }
.e20-sudoku-grupo-num { display: block; font-size: 1.9em; line-height: 1.1; text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.545); }
.e20-sudoku-grupo-nombre { display: block; font-size: .62rem; font-weight: 600; line-height: 1.1; color: #fff; text-shadow: 1px 1px 3px rgba(0, 0, 0, .45); }
/* .e20-sudoku-activo es el <label> que envuelve el checkbox; el switch se pinta en el input.
   Mismo estilo que /accesos/matriz/ (.acc-switch-rol) y usuarios/user_editar.html (.e20-switch-onoff) */
.e20-sudoku-activo { vertical-align: middle; }
.e20-sudoku-activo input[type="checkbox"] {
  appearance: none; -webkit-appearance: none; width: 34px; height: 18px;
  background-color: #cbd5e1; border-radius: 999px; position: relative;
  cursor: pointer; transition: background-color .15s ease-in-out; vertical-align: middle;
}
.e20-sudoku-activo input[type="checkbox"]::before {
  content: ''; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px;
  border-radius: 50%; background: #fff; transition: left .15s ease-in-out;
  box-shadow: 0 1px 2px rgba(0,0,0,.25);
}
.e20-sudoku-activo input[type="checkbox"]:checked { background-color: #2f855a; }
.e20-sudoku-activo input[type="checkbox"]:checked::before { left: 18px; }
.e20-sudoku-activo input[type="checkbox"]:disabled { opacity: .35; cursor: not-allowed; }
.e20-sudoku-activo input[type="checkbox"]:hover:not(:disabled) { filter: brightness(1.08); }
.e20-sudoku-prog { background-color: var(--grupo-color, #9aa5b1) !important; background-image: linear-gradient(rgba(255,255,255,.62), rgba(255,255,255,.62)); color: #1f2d3d; font-weight: 600; }
.e20-sudoku-prog--izq { text-align: left; }
.e20-sudoku-prog--est { text-align: right; }
.e20-sudoku-prog-alias { font-size: 1.2em; }
.e20-sudoku-nivel { display: inline-block; margin-left: .5rem; width: 1.7em; height: 1.7em; line-height: 1.7em; padding: 0; border-radius: 50%; background: rgba(0,0,0,.25); color: #fff; font-size: 1.05rem; font-weight: 700; text-align: center; vertical-align: middle; }
.e20-sudoku-est-num { display: block; font-size: 1.2em; font-weight: 700; line-height: 1.15; }
.e20-sudoku-est-txt { display: block; font-size: .55rem; font-weight: 600; line-height: 1; opacity: .7; }
.e20-sudoku-celda { min-width: 92px; cursor: default; user-select: none; }
.e20-sudoku-celda--curso { background: #F0E8B9; min-width: 118px; }
.e20-sudoku-celda--aula { background: #FFFFCC; }
.e20-sudoku-celda--profesor { background: #D9EAD3; }
.e20-sudoku-celda--vacia { background: #fff; }
/* Relieve de las celdas ocupadas: resalte claro arriba y sombra oscura abajo */
.e20-sudoku-celda--curso:not(.e20-sudoku-celda--vacia),
.e20-sudoku-celda--aula:not(.e20-sudoku-celda--vacia),
.e20-sudoku-celda--profesor:not(.e20-sudoku-celda--vacia) {
  box-shadow: inset 0 2px 4px rgba(255, 255, 255, .4), inset 0 -2px 4px rgba(0, 0, 0, .2);
}
.e20-sudoku-celda--cruce { background: #f8b4b4 !important; color: #8a1c1c; font-weight: 700; }
.e20-sudoku-celda--sel { outline: 2px solid #1a73e8; outline-offset: -2px; }
.e20-sudoku-celda--guardando { opacity: .55; }
.e20-sudoku-atajos { margin: .4rem .25rem 0; font-size: .78rem; color: #667; }
.e20-sudoku-atajos b { color: #334; }
/* Clase marcada con doble clic: las tres celdas del bloque, listas para arrastrar */
.e20-sudoku-celda--clase { outline: 2px solid #b45f06; outline-offset: -2px; cursor: grab; }
.e20-sudoku-celda--clase:active { cursor: grabbing; }
.e20-sudoku-celda--arrastrando { opacity: .45; }
/* Bloque sobre el que se soltaría la clase */
.e20-sudoku-celda--destino { outline: 2px dashed #b45f06; outline-offset: -2px; background-image: linear-gradient(rgba(180, 95, 6, .18), rgba(180, 95, 6, .18)); }
/* Celda o clase copiada con Ctrl+C: punteado por dentro, para no tapar la selección; se quita con Esc */
.e20-sudoku-celda--copiada { position: relative; }
.e20-sudoku-celda--copiada::after { content: ''; position: absolute; inset: 4px; border: 2px dashed #0e7c6b; border-radius: 2px; pointer-events: none; }
.e20-sudoku-menu { position: fixed; z-index: 1080; min-width: 260px; max-width: 340px; max-height: 60vh; overflow: auto; background: #fff; border: 1px solid #cfd8e3; border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.25); padding: .35rem 0; font-size: .85rem; }
.e20-sudoku-menu-cab { padding: .25rem .75rem; font-weight: 700; color: #334; border-bottom: 1px solid rgba(0,0,0,.12); }
.e20-sudoku-menu-buscar { width: calc(100% - 1.5rem); margin: .35rem .75rem; padding: .25rem .5rem; border: 1px solid #cfd8e3; border-radius: 6px; font-size: .85rem; }
.e20-sudoku-menu-sec { padding: .35rem .75rem .15rem; font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; color: #778; }
.e20-sudoku-menu-item { display: flex; align-items: baseline; gap: .5rem; width: 100%; border: 0; background: transparent; text-align: left; padding: .3rem .75rem; cursor: pointer; }
.e20-sudoku-menu-item:hover, .e20-sudoku-menu-item:focus { background: rgba(0,0,0,.09); outline: 0; }
.e20-sudoku-menu-item small { color: #667; font-size: .75em; }
.e20-sudoku-menu-item em { margin-left: auto; font-style: normal; font-size: .7em; color: #b23a48; white-space: nowrap; }
.e20-sudoku-menu-item--actual span { font-weight: 700; color: #1a73e8; }
.e20-sudoku-menu-item--ocupado span { color: #999; text-decoration: line-through; }
/* El menú toma el color de la celda que edita: curso habano, lugar amarillo, profesor verde */
.e20-sudoku-menu--curso { background: #F0E8B9; }
.e20-sudoku-menu--aula { background: #FFFFCC; }
.e20-sudoku-menu--profesor { background: #D9EAD3; }
.e20-sudoku-informe { max-height: 40vh; overflow: auto; font-size: .85rem; font-family: monospace; }
/* Panel "Horario por profesor": selector arriba y el horario de la jornada abierta,
   con la estructura de /registro/horario_consultaprofe/ y los estilos del Sudoku. */
.e20-sudoku-hp-barra { display: flex; align-items: center; gap: .6rem; margin-bottom: .6rem; }
.e20-sudoku-hp-barra select { max-width: 24rem; }
.e20-sudoku-hp-jornada { padding: .35rem .6rem; text-align: center; color: #fff; font-size: 1.4em; font-weight: 700;
  text-shadow: 2px 2px 5px rgba(0, 0, 0, .5); border-radius: 6px 6px 0 0;
  background-color: var(--jornada-color, #336699); }
.e20-sudoku-hp { width: 100%; table-layout: fixed; }
.e20-sudoku-hp thead th { background: #9aa0a6; color: #fff; font-weight: 600; font-size: .75rem; }
.e20-sudoku-hp th, .e20-sudoku-hp td { font-size: .8rem; height: 26px; line-height: 26px; overflow: hidden; text-overflow: ellipsis; }
.e20-sudoku-hp-cab-dia, .e20-sudoku-hp-dia { width: 34px; padding: 0 !important; }
.e20-sudoku-hp-cab-hora, .e20-sudoku-hp-hora { width: 68px; }
.e20-sudoku-hp-dia { background: #4a5568; color: #fff; font-weight: 700; vertical-align: middle; }
.e20-sudoku-hp-dia span { display: inline-block; writing-mode: vertical-rl; transform: rotate(180deg); letter-spacing: .04em; }
.e20-sudoku-hp-hora { background: #e9edf2; color: #333; font-size: .75rem; }
.e20-sudoku-hp-grupo { background: #D9D2E9; color: #2b2b40; font-weight: 700; }
.e20-sudoku-hp-curso { background: #F0E8B9; color: #3a3320; }
.e20-sudoku-hp-lugar { background: #FFFFCC; color: #3a3320; }
.e20-sudoku-hp-dia-inicio td { border-top: 3px solid rgba(74, 111, 165, .3); }
/* Panel de ocupación de aulas: filas día × bloque, dos columnas por sala (grupo y materia),
   con la congestión (aulas ocupadas a esa hora) fija a la izquierda. */
.e20-sudoku-ocu-wrap { position: relative; overflow: auto; max-height: 68vh; border: 1px solid #cfd8e3; border-radius: 8px; background: #fff; }
.e20-sudoku-ocu th, .e20-sudoku-ocu td { font-size: .72rem; height: 24px; line-height: 1.15; padding: .1rem .35rem; }
.e20-sudoku-ocu .e20-sudoku-ocu-h1 th { top: 0; height: 26px; line-height: 26px; }
.e20-sudoku-ocu .e20-sudoku-ocu-h2 th { top: 26px; height: 20px; line-height: 20px; background: #9aa0a6; color: #fff; font-weight: 600; font-size: .66rem; }
.e20-sudoku-ocu-jornada { left: 28px; z-index: 5 !important; background-color: var(--jornada-color, #336699) !important; color: #fff; font-weight: 700; font-size: .85rem; }
.e20-sudoku-ocu-sala { font-weight: 700; text-shadow: 0 1px 2px rgba(0, 0, 0, .25); }
/* Columnas fijas: congestión, día y hora */
.e20-sudoku-ocu-cong-cab { left: 0; z-index: 6 !important; background: #f2d98d !important; color: #6b5300; }
.e20-sudoku-ocu-cong-cab span { display: inline-block; writing-mode: vertical-rl; transform: rotate(180deg); font-size: .58rem; font-weight: 600; letter-spacing: .02em; }
.e20-sudoku-ocu-cong-cab, .e20-sudoku-ocu-cong { width: 28px; min-width: 28px; padding: 0 !important; }
.e20-sudoku-ocu-cong { position: sticky; left: 0; z-index: 2; background: #fbeec4; color: #6b5300; font-weight: 700; font-size: .68rem; }
.e20-sudoku-ocu-dia-cab, .e20-sudoku-ocu-dia { width: 26px; min-width: 26px; padding: 0 !important; }
.e20-sudoku-ocu-dia-cab { left: 28px; z-index: 6 !important; }
.e20-sudoku-ocu-dia { position: sticky; left: 28px; z-index: 2; background: #4a5568; color: #fff; font-weight: 700; vertical-align: middle; }
.e20-sudoku-ocu-dia span { display: inline-block; writing-mode: vertical-rl; transform: rotate(180deg); letter-spacing: .04em; }
.e20-sudoku-ocu-hora-cab, .e20-sudoku-ocu-hora { width: 58px; min-width: 58px; }
.e20-sudoku-ocu-hora-cab { left: 54px; z-index: 6 !important; }
.e20-sudoku-ocu-hora { position: sticky; left: 54px; z-index: 2; background: #e9edf2; color: #333; }
/* Cada sala son dos columnas: el grupo (angosto) y la materia */
.e20-sudoku-ocu-g { border-left: 2px solid #cfd8e3; width: 44px; min-width: 44px; font-weight: 700; }
.e20-sudoku-ocu-m { min-width: 96px; }
.e20-sudoku-ocu-grupo { background: #D9D2E9; color: #2b2b40; }
.e20-sudoku-ocu-materia { background: #F0E8B9; color: #3a3320; }
.e20-sudoku-ocu-vacia { background: #fff; }
.e20-sudoku-ocu tbody tr:nth-child(even) .e20-sudoku-ocu-vacia { background: #f5f6f8; }
.e20-sudoku-ocu-dia-inicio td { border-top: 3px solid rgba(74, 111, 165, .3); }
.e20-sudoku-panel th, .e20-sudoku-panel td { font-size: .7rem; height: auto; line-height: 1.15; padding: .15rem .3rem; }
.e20-sudoku-panel thead th { position: static; }
.e20-sudoku-panel-aula { position: sticky; left: 0; background: #e9edf2; font-weight: 700; z-index: 1; }
.e20-sudoku-panel-dia { border-left: 3px solid #4a6fa5; }


/* ============================================================
   ACCESOS DEL PANEL DE ASIGNATURA  (Prefix: e20-acceso)
   ============================================================
   Los seis accesos —Contenidos, Aula Virtual, Sesiones Clase,
   Lista de Clase, Notas y Asistencia— eran PNG de 181x69 px.
   Como imagen no escalaban sin verse borrosos, su rótulo no lo
   leía un lector de pantalla ni se podía traducir, y cambiar una
   palabra obligaba a reexportar el archivo. Aquí se dibujan: una
   pastilla con el rótulo y un cuadro de color con el icono.

   El color de cada acceso vive en su modificador; el tamaño, en
   `--e20-acceso-alto`, del que se derivan ancho, tipografía,
   relleno e icono. Cambiar esa variable escala el botón entero.

   Uso:
     <div class="e20-accesos">
       <a class="e20-acceso e20-acceso--aula" href="...">
         <span class="e20-acceso__texto">Aula Virtual</span>
         <span class="e20-acceso__icono"><i class="fas fa-chalkboard-teacher"></i></span>
       </a>
     </div>
   ============================================================ */

.e20-accesos {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: .45rem;
    width: 100%;
}

/* El aula presenta los accesos un 20% mas grandes que el panel. */
.e20-accesos--grande .e20-acceso {
    --e20-acceso-alto: 90px;
    --e20-acceso-ancho: 260px;
}

/* Movil y tablet: la columna pasa a ocupar todo el ancho y los
   accesos, alineados a la derecha, quedaban descolgados. */
.e20-accesos--centro {
    align-items: center;
}

@media (max-width: 991.98px) {
    .e20-accesos {
        align-items: center;
    }
}

.e20-acceso {
    --e20-acceso-alto: 75px;
    --e20-acceso-ancho: 217px;
    --e20-acceso-color: #336699;
    /* Todo —icono, tipografia, relleno— se deriva de esta escala. Por
       defecto es el alto pedido; con container queries baja sola cuando
       la columna es mas estrecha que el ancho ideal. */
    --e20-acceso-escala: var(--e20-acceso-alto);
    display: flex;
    align-items: center;
    justify-content: flex-end;
    width: 100%;
    max-width: var(--e20-acceso-ancho);
    min-height: var(--e20-acceso-escala);
    padding: 0;
    border: 0;
    background: none;
    text-decoration: none;
    transition: transform .3s ease;
}

/* Una columna estrecha encogia el boton pero no su rotulo, que acababa
   cortado («Sesiones Cla…»). Con la escala atada al ancho real el
   acceso entero encoge en proporcion y el texto siempre cabe.
   34.6cqw es la proporcion 75/217 del boton, la misma que 90/260. */
@supports (container-type: inline-size) {
    .e20-acceso {
        container-type: inline-size;
    }

    .e20-acceso__texto,
    .e20-acceso__icono {
        --e20-acceso-escala: min(var(--e20-acceso-alto), 34.6cqw);
    }
}

.e20-acceso:hover,
.e20-acceso:focus-visible {
    transform: scale(1.06);
    text-decoration: none;
}

.e20-acceso:focus-visible {
    outline: 3px solid var(--e20-acceso-color);
    outline-offset: 3px;
}

/* La pastilla pasa por detras del cuadro: de ahi el margen negativo y
   el relleno derecho que reserva el hueco del icono. */
.e20-acceso__texto {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    min-width: 0;
    height: calc(var(--e20-acceso-escala) * .74);
    padding-left: calc(var(--e20-acceso-escala) * .20);
    padding-right: calc(var(--e20-acceso-escala) * .70);
    margin-right: calc(var(--e20-acceso-escala) * -.64);
    overflow: hidden;
    border: 1px solid #fff;
    border-radius: 999px;
    /* La pastilla lleva el mismo color que el cuadro del icono, a media
       tinta: asi cada acceso se reconoce por su color y no por un gris
       igual para todos. El respaldo es el color plano, para navegadores
       sin color relativo. */
    background: var(--e20-acceso-color);
    background: rgb(from var(--e20-acceso-color) r g b / .5);
    color: #fff;
    font-size: calc(var(--e20-acceso-escala) * .20);
    font-weight: 700;
    line-height: 1.15;
    text-overflow: ellipsis;
    text-shadow: 0 1px 2px rgba(0, 0, 0, .28);
    white-space: nowrap;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, .55),
        0 2px 5px rgba(0, 0, 0, .18);
}

.e20-acceso__icono {
    position: relative;
    z-index: 1;
    display: grid;
    flex: 0 0 auto;
    place-items: center;
    width: var(--e20-acceso-escala);
    height: var(--e20-acceso-escala);
    border: 3px solid #fff;
    border-radius: 24%;
    background: var(--e20-acceso-color);
    color: #fff;
    font-size: calc(var(--e20-acceso-escala) * .42);
    box-shadow: 0 3px 8px rgba(0, 0, 0, .28);
}

/* Un color por acceso, el mismo que tenian los PNG. */
.e20-acceso--contenidos { --e20-acceso-color: #336699; }
.e20-acceso--aula       { --e20-acceso-color: #003399; }
.e20-acceso--sesiones   { --e20-acceso-color: #7688A6; }
.e20-acceso--lista      { --e20-acceso-color: #32CC99; }
.e20-acceso--notas      { --e20-acceso-color: #6699FF; }
.e20-acceso--asistencia { --e20-acceso-color: #F28B24; }
.e20-acceso--online     { --e20-acceso-color: #035964; }
.e20-acceso--chat       { --e20-acceso-color: #25D366; }
.e20-acceso--chat .e20-acceso__texto { background: rgba(37, 211, 102, .5); }
.e20-acceso--chat .e20-acceso__icono { font-size: calc(var(--e20-acceso-escala) * .52); }

@media (prefers-reduced-motion: reduce) {
    .e20-acceso {
        transition: none;
    }

    .e20-acceso:hover,
    .e20-acceso:focus-visible {
        transform: none;
    }
}

/* ============================================================
   PANEL DEL CURSO VIRTUAL  (Prefix: e20-panelvirtual)
   ============================================================ */

/* Cenefa del curso virtual: el area sustituye al grupo y al periodo, que en un
   curso que se estudia solo no dicen nada. */
.e20-panelvirtual-cenefa {
    background-size: cover;
    background-position: center;
    min-height: 15vh;
    display: flex;
    align-items: center;
    padding: 14px 0;
}

.e20-panelvirtual-cenefa__fila {
    display: flex;
    align-items: center;
    gap: 18px;
    width: 100%;
    padding-left: 4%;
}

.e20-panelvirtual-cenefa__icono img {
    height: 10vh !important;
    width: 10vh !important;
    max-height: 10vh !important;
    max-width: 10vh !important;
}

.e20-panelvirtual-cenefa__etiquetas {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin-bottom: 2px;
}

.e20-panelvirtual-cenefa__tipo {
    background: rgba(0, 0, 0, 0.45);
    color: #7fb3ff;
    font-weight: 700;
    font-size: 1.15rem;
    padding: 2px 14px;
    border-radius: 6px;
}

.e20-panelvirtual-cenefa__area {
    background: rgba(59, 130, 246, 0.85);
    color: #fff;
    font-weight: 600;
    font-size: 1.05rem;
    padding: 4px 28px;
    border-radius: 10px;
}

.e20-panelvirtual-cenefa__nombre {
    color: #fff;
    font-size: 2.2rem;
    line-height: 1.1;
    text-shadow: 1px 1px 6px #000;
}

.e20-panelvirtual-cenefa__modulos {
    color: #fff;
    font-size: 1.2rem;
    text-shadow: 1px 1px 6px #000;
}

/* El poster manda en la columna izquierda: es la cara del curso. */
.e20-panelvirtual-poster {
    width: 100% !important;
    height: auto !important;
    max-width: 100% !important;
    max-height: none !important;
    border-radius: 12px;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.22);
}

/* De que va el curso, bajo el poster. */
.e20-panelvirtual-acerca {
    margin-top: 12px;
    text-align: justify;
    color: #2e5be8;
    font-size: 1.05rem;
    line-height: 1.35;
}

.e20-panelvirtual-acerca__titulo {
    margin-top: 14px;
    font-weight: 700;
    color: #2f4e6a;
}

/* El curso, como marca, encabezando el bloque de reanudar. */
.e20-panelvirtual-marca {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    background: linear-gradient(180deg, #2f8bfd 0%, #1567d8 100%);
    border-radius: 14px;
    padding: 12px 16px;
    color: #fff;
    font-weight: 700;
    font-size: 1.1rem;
    line-height: 1.15;
    text-decoration: none;
    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.18);
}

.e20-panelvirtual-marca:hover {
    color: #fff;
    filter: brightness(1.06);
}

.e20-panelvirtual-marca img {
    height: 56px !important;
    width: 56px !important;
    max-height: 56px !important;
    max-width: 56px !important;
}

.e20-panelvirtual-cuenta {
    font-size: 1.05rem;
    font-weight: 700;
    color: #2f4e6a;
}

.e20-panelvirtual-barra {
    position: relative;
    height: 14px;
    margin: 6px 0;
    border-radius: 10px;
    background: rgba(180, 190, 220, 0.3);
    box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.18);
    overflow: hidden;
}

.e20-panelvirtual-barra__relleno {
    height: 100%;
    border-radius: 10px;
    background: linear-gradient(180deg, #5a8fff 0%, #2e5be8 45%, #1a3fc4 100%);
    transition: width 0.6s ease;
}

/* Estado B: el bloque de reanudar encogido, con el modulo ya sonando. */
/* `flex-direction: row` no sobra: .e20-card apila en columna, y en columna la
   barra se queda sin ancho porque align-items:center le ajusta el eje cruzado. */
.e20-panelvirtual-barra-fina {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 0.9rem;
}

.e20-panelvirtual-barra-fina .e20-panelvirtual-cuenta {
    flex: 0 0 auto;
    font-size: 0.85rem;
    white-space: nowrap;
}

.e20-panelvirtual-barra-fina .e20-panelvirtual-barra {
    flex: 1 1 auto;
    height: 10px;
    margin: 0;
}

.e20-panelvirtual-restante {
    font-size: 0.78rem;
    color: #6c757d;
}

.e20-panelvirtual-siguiente-nombre {
    margin-top: 6px;
    font-size: 0.82rem;
    color: #555;
}

/* Sin esto el boton queda blanco sobre blanco: .boton-texto por defecto no
   trae color propio, lo pone quien lo usa. */
.e20-panelvirtual-continuar {
    --boton-bg: rgba(46, 91, 232, 0.92);
}

/* El paso al siguiente modulo va a todo el ancho bajo el video: es la accion
   que el estudiante busca al terminar, no un enlace perdido en una esquina. */
.e20-panelvirtual-siguiente {
    --boton-bg: rgba(46, 91, 232, 0.55);
    display: block;
    width: 100%;
    margin-top: 10px;
    text-align: center;
}

.e20-panelvirtual-completo {
    font-size: 1rem;
    font-weight: 700;
    color: #0a7a0a;
}

.e20-panelvirtual-recursos {
    margin-top: 1.2rem;
    text-align: center;
}

.e20-panelvirtual-recursos__titulo {
    font-size: 0.63rem;
    color: #999;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    margin-bottom: 5px;
}

.e20-panelvirtual-recurso {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    width: 38px;
    margin: 0 4px;
    text-decoration: none;
    font-size: 0.7rem;
    color: #666;
}

.e20-panelvirtual-recurso img {
    width: 24px !important;
    height: 24px !important;
    max-width: 24px !important;
    max-height: 24px !important;
    object-fit: contain;
}

.e20-panelvirtual-horas {
    margin-top: 1.2rem;
}

.e20-panelvirtual-horas__titulo {
    font-size: 0.6rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: #6c757d;
    text-align: center;
    font-weight: 700;
    margin-bottom: 6px;
}

.e20-panelvirtual-horas__fila {
    display: flex;
    justify-content: space-around;
    gap: 4px;
}

.e20-panelvirtual-hora {
    flex: 1;
    text-align: center;
    padding: 6px 2px;
    border-radius: 8px;
    background: rgba(26, 63, 196, 0.1);
    border: 1px solid rgba(26, 63, 196, 0.15);
}

.e20-panelvirtual-hora--total {
    background: rgba(10, 122, 10, 0.1);
    border-color: rgba(10, 122, 10, 0.2);
}

.e20-panelvirtual-hora__valor {
    font-size: 1.1rem;
    font-weight: 800;
    color: #1a3fc4;
}

.e20-panelvirtual-hora--total .e20-panelvirtual-hora__valor {
    color: #0a7a0a;
}

.e20-panelvirtual-hora__rotulo {
    font-size: 0.48rem;
    color: #555;
    line-height: 1.2;
    margin-top: 2px;
}

/* La burbuja que teclea sola mientras el modulo corre. */
.e20-panelvirtual-burbuja {
    background: rgba(255, 255, 255, 0.5);
    border-radius: 20px 0 20px 20px;
    padding: 8px 14px;
    font-size: 1rem;
    color: rgba(27, 27, 39, 0.65);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.13);
    min-height: 2.6em;
}

.e20-panelvirtual-entendido {
    height: 60px;
    width: 160px;
    font-size: 1.2em;
    border: none;
    --boton-bg: rgba(8, 188, 1, 0.92);
    animation: e20-panelvirtual-late 1.4s ease-in-out infinite;
}

@keyframes e20-panelvirtual-late {
    0%   { transform: scale(1);    box-shadow: 0 0 0 0    rgba(8, 188, 1, 0.70); }
    50%  { transform: scale(1.06); box-shadow: 0 0 0 14px rgba(8, 188, 1, 0); }
    100% { transform: scale(1);    box-shadow: 0 0 0 0    rgba(8, 188, 1, 0); }
}

.e20-panelvirtual-playlist__titulo {
    background: rgba(46, 62, 158, 0.8);
    color: #fff;
    font-size: 1.05rem;
    font-weight: 700;
    border-radius: 8px 8px 0 0;
}

/* Marca de agua de la columna izquierda: el icono del curso a 0.1, detras del texto y sin ocupar espacio. */
.e20-panelvirtual-col {
    position: relative;
}

.e20-panelvirtual-col > *:not(.e20-panelvirtual-marcagua) {
    position: relative;
    z-index: 1;
}

.e20-panelvirtual-marcagua {
    position: absolute;
    top: 170px;
    left: 0;
    right: 0;
    z-index: 0;
    text-align: center;
    pointer-events: none;
}

.e20-panelvirtual-marcagua img {
    width: 100% !important;
    height: auto !important;
    max-width: 100% !important;
    max-height: none !important;
    opacity: 0.1;
}

/* Ruta del curso: burbuja del nombre + linea punteada de los modulos (gruesa, alfa 0.5). */
.e20-panelvirtual-ruta {
    --ruta-linea: rgba(47, 90, 190, 0.5);
    --ruta-grosor: 4px;
}

.e20-panelvirtual-ruta__cabeza {
    position: relative;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1.5rem;
    margin-bottom: 1rem;
}

/* Tramo que baja de la burbuja hasta empalmar con la linea de los modulos. */
.e20-panelvirtual-ruta__cabeza::before {
    content: '';
    position: absolute;
    left: 32px;
    top: 40px;
    bottom: -40px;
    width: var(--ruta-grosor);
    background: repeating-linear-gradient(to bottom, var(--ruta-linea) 0 6px, transparent 6px 11px);
    z-index: 0;
}

.e20-panelvirtual-ruta .e20-tl-container::before {
    border-left: 0;
    width: var(--ruta-grosor);
    background: repeating-linear-gradient(to bottom, var(--ruta-linea) 0 6px, transparent 6px 11px);
}

.e20-panelvirtual-ruta .e20-tl-row--virtual::before {
    border-top: 0;
    top: 38px;
    left: calc(32px + var(--ruta-grosor) - 50px - 0.5rem);
    width: calc(50px + 0.5rem - 32px - var(--ruta-grosor));
    height: var(--ruta-grosor);
    background: repeating-linear-gradient(to right, var(--ruta-linea) 0 6px, transparent 6px 10px);
}

/* La burbuja con el nombre del curso, a la cabeza de la ruta. */
.e20-panelvirtual-marca--ruta {
    position: relative;
    z-index: 1;
    flex: 0 1 40%;
    justify-content: flex-start;
    margin-top: 40px;
    padding: 18px 26px;
    border-radius: 16px;
    background: linear-gradient(180deg, #1f93ff 0%, #0b63e5 100%);
    font-size: 1.45rem;
    box-shadow: 0 6px 16px rgba(11, 99, 229, 0.35);
}

/* Boton Editar en la esquina inferior derecha de la burbuja: solo administracion. */
.e20-panelvirtual-marca--ruta .e20-panelvirtual-marca__editar {
    position: absolute;
    right: 10px;
    bottom: 8px;
    --boton-bg: rgba(255, 255, 255, 0.25);
    padding: 2px 12px;
    font-size: 0.8rem;
    color: #fff;
}

.e20-panelvirtual-marca--ruta:has(.e20-panelvirtual-marca__editar) {
    padding-bottom: 36px;
}

.e20-panelvirtual-marca--ruta img {
    height: 70px !important;
    width: 70px !important;
    max-height: 70px !important;
    max-width: 70px !important;
}

/* Tarjeta de avance, arriba de la columna izquierda: dona + datos + continuar. */
.e20-panelvirtual-avance {
    position: relative;
    z-index: 1;
    width: 100%;
    margin-bottom: 0.5rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.85rem 1.1rem;
    background: rgba(255, 255, 255, 0.35);
    border: 3px solid #ffffff;
    border-radius: 18px;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.1);
}

.e20-panelvirtual-dona {
    --pct: 0;
    position: relative;
    flex: 0 0 128px;
    width: 128px;
    height: 128px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.e20-panelvirtual-dona::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: conic-gradient(#0a6b2e calc(var(--pct) * 1%), rgba(98, 205, 120, 0.35) 0);
    -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 19px), #000 calc(100% - 18px));
    mask: radial-gradient(farthest-side, transparent calc(100% - 19px), #000 calc(100% - 18px));
}

.e20-panelvirtual-dona__valor {
    position: relative;
    color: #0a7a2e;
    font-size: 1.7rem;
    font-weight: 400;
}

.e20-panelvirtual-avance__datos {
    flex: 1 1 auto;
    min-width: 0;
}

.e20-panelvirtual-avance__dona {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
}

.e20-panelvirtual-avance__titulo {
    color: #0a9a5a;
    font-size: 1.15rem;
    font-weight: 700;
}

.e20-panelvirtual-avance__nombre {
    font-size: 1.5rem;
    font-weight: 600;
    line-height: 1.1;
    color: #1b1b1b;
}

.e20-panelvirtual-avance__usuario {
    color: #2e5be8;
    font-size: 0.95rem;
    overflow-wrap: anywhere;
}

.e20-panelvirtual-compartir {
    min-width: 200px;
    padding: 10px 26px;
    font-size: 1.05rem;
    border: 1px solid rgba(60, 60, 60, 0.6);
}

.e20-panelvirtual-avance .e20-panelvirtual-cuenta {
    margin-top: 6px;
    color: #2e5be8;
}

.e20-panelvirtual-avance__inicio {
    margin-top: 2px;
    font-size: 0.75rem;
    color: #444;
}

.e20-panelvirtual-avance__boton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-width: 70%;
    margin-top: 12px;
    padding: 7px 18px;
    border-radius: 14px;
    background: linear-gradient(180deg, #2fc24a 0%, #0f9a2c 100%);
    color: #fff;
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
    animation: e20-panelvirtual-invita 1.8s ease-out infinite;
    transition: filter 0.2s ease;
}

.e20-panelvirtual-avance__boton:hover {
    color: #fff;
    filter: brightness(1.08);
}

/* Sombra que palpita: invita a continuar o empezar el curso. */
@keyframes e20-panelvirtual-invita {
    0%   { box-shadow: 0 4px 10px rgba(15, 154, 44, 0.35), 0 0 0 0 rgba(47, 194, 74, 0.55); }
    70%  { box-shadow: 0 4px 10px rgba(15, 154, 44, 0.35), 0 0 0 14px rgba(47, 194, 74, 0); }
    100% { box-shadow: 0 4px 10px rgba(15, 154, 44, 0.35), 0 0 0 0 rgba(47, 194, 74, 0); }
}

@media (prefers-reduced-motion: reduce) {
    .e20-panelvirtual-avance__boton { animation: none; }
}

.e20-panelvirtual-avance .e20-panelvirtual-siguiente-nombre {
    font-size: 0.75rem;
    color: #8a8a8a;
}

/* En pantalla angosta: el avance arriba y la burbuja debajo, pegada a la ruta. */
@media (max-width: 991px) {
    .e20-panelvirtual-ruta__cabeza {
        flex-direction: column-reverse;
        align-items: stretch;
    }
    .e20-panelvirtual-marca--ruta {
        margin-top: 0;
    }
    .e20-panelvirtual-ruta__cabeza::before {
        top: auto;
        height: 40px;
    }
}

@media (max-width: 575px) {
    .e20-panelvirtual-avance {
        flex-direction: column;
        text-align: center;
    }
}

/* El lapiz de editar un modulo, para profesor y admin. */
.e20-tl-editar {
    align-self: center;
    padding: 0 0.6rem;
    color: #6c757d;
    text-decoration: none;
}

.e20-tl-editar:hover {
    color: #2f4e6a;
}

/* Confirmar la inscripcion a un curso virtual. */
.e20-confirmar-gratuito {
    --boton-bg: rgba(8, 188, 1, 0.92);
    padding: 0.9rem 2.4rem;
    font-size: 1.1em;
}

/* El error se pinta en la ventana: un alert() lo puede suprimir el navegador. */
.e20-confirmar-gratuito__error {
    margin: 0 auto 12px;
    max-width: 420px;
    padding: 0.6rem 0.9rem;
    border-radius: 10px;
    background: rgba(220, 53, 69, 0.12);
    color: #a01927;
    font-size: 0.92em;
}

/* Confirmacion de un curso suelto recien inscrito. */
.e20-exito-curso__titulo {
    font-size: 1.6rem;
    font-weight: 800;
    color: #0a7a0a;
}

/* Mis inscripciones: variante virtual de las cards y tablas Educa20.
   Conserva las superficies, sombras y botones compartidos. */
.e20-campus-virtual {
    --cv-ink: #233f5a;
    --cv-muted: #51687b;
    --cv-accent: #087b8d;
    --cv-blue: #305fa8;
    --cv-line: rgba(47, 78, 106, .15);
    margin: 30px 0 24px;
    color: var(--cv-ink);
}
.e20-card.e20-campus-virtual__cabecera {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 16px;
    padding: 20px 24px;
    margin-bottom: 12px;
    overflow: hidden;
    --e20-card-bg-start: rgba(235, 244, 253, .94);
    --e20-card-bg-end: rgba(216, 232, 237, .86);
}
.e20-campus-virtual__cabecera::after {
    content: "";
    position: absolute;
    inset: 0 0 0 auto;
    width: 190px;
    background-image: radial-gradient(rgba(47, 95, 145, .16) 1px, transparent 1px);
    background-size: 12px 12px;
    mask-image: linear-gradient(90deg, transparent, #000);
    pointer-events: none;
}
.e20-campus-virtual__emblema {
    display: grid;
    place-items: center;
    flex: 0 0 58px;
    height: 58px;
    border-radius: 18px;
    border: 1px solid rgba(255, 255, 255, .9);
    background: linear-gradient(145deg, #3d658d, #214365);
    color: #c0f2f2;
    box-shadow: inset 0 1px 2px #ffffff55, 0 4px 9px #193b5b33;
    font-size: 24px;
}
.e20-campus-virtual__titulo { min-width: 0; }
.e20-campus-virtual__titulo h2 {
    margin: 0;
    color: var(--cv-ink);
    font-size: 1.35rem;
    font-weight: 700;
    line-height: 1.25;
    text-shadow: 0 1px #ffffff;
}
.e20-campus-virtual__titulo p { margin: 4px 0 0; color: var(--cv-muted); font-size: .82rem; }
.e20-campus-virtual__contador {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-left: auto;
    padding-left: 24px;
    border-left: 1px solid var(--cv-line);
    position: relative;
    z-index: 1;
}
.e20-campus-virtual__contador strong { font-size: 1.8rem; font-weight: 600; line-height: 1; font-variant-numeric: tabular-nums; }
.e20-campus-virtual__contador span { font-size: .72rem; line-height: 1.3; color: var(--cv-muted); }
.e20-campus-virtual__lista { overflow-x: auto; }
.e20-campus-virtual.e20-cabecera-seccion { margin: 18px 0 0; }
.e20-tabla.e20-campus-virtual__tabla { border-spacing: 0 6px; margin-top: -6px; font-size: .82rem; }
.e20-campus-virtual__tabla th { padding: 10px 8px; font-size: .73rem; font-weight: 500; line-height: 1.3; white-space: nowrap; }
.e20-campus-virtual__tabla .e20-tabla-header-row { background: transparent; }
.e20-campus-virtual__tabla .e20-tabla-header-row th { background-color: rgba(35, 64, 91, .8); }
.e20-campus-virtual .e20-tabla.e20-campus-virtual__tabla tbody tr.e20-campus-virtual__fila > td {
    padding: 12px 8px !important;
    background-color: rgba(248, 251, 255, .79);
    border-top: 1px solid rgba(255, 255, 255, .95);
    border-bottom: 1px solid var(--cv-line);
}
.e20-campus-virtual .e20-tabla.e20-campus-virtual__tabla tbody tr.e20-campus-virtual__fila > td:first-child { border-radius: 12px 0 0 12px; }
.e20-campus-virtual .e20-tabla.e20-campus-virtual__tabla tbody tr.e20-campus-virtual__fila > td:last-child { border-radius: 0 12px 12px 0; border-right: 1px solid rgba(255, 255, 255, .7); }
.e20-campus-virtual .e20-tabla.e20-campus-virtual__tabla tbody tr.e20-campus-virtual__fila:hover > td { background-color: rgba(229, 241, 251, .94) !important; }
.e20-campus-virtual__icono { display: grid; place-items: center; width: 52px; height: 52px; border-radius: 50%; color: var(--cv-blue); background: rgba(255, 255, 255, .65); font-size: 22px; }
.e20-campus-virtual__icono img { width: 48px; height: 48px !important; object-fit: contain; }
.e20-campus-virtual__curso { width: 30%; min-width: 180px; }
.e20-campus-virtual__enlace { display: flex; flex-direction: column; justify-content: center; gap: 6px; min-height: 44px; color: var(--cv-ink); text-decoration: none; }
.e20-campus-virtual__enlace > span { font-size: .94rem; font-weight: 600; line-height: 1.35; }
.e20-campus-virtual__enlace small { display: flex; align-items: center; gap: 10px; color: var(--cv-muted); font-size: .71rem; line-height: 1.2; overflow-wrap: anywhere; }
.e20-campus-virtual__enlace small i { color: var(--cv-accent); font-size: .65rem; }
.e20-campus-virtual__enlace:hover { color: var(--cv-blue); text-decoration: none; }
.e20-campus-virtual__enlace:hover > span { text-decoration: underline; text-underline-offset: 3px; }
.e20-campus-virtual__birrete { color: #977014; margin-left: 3px; }
.e20-campus-virtual__total { text-align: center; font-size: 1.05rem; }
.e20-campus-virtual__total strong { font-weight: 500; }
.e20-campus-virtual__avance { min-width: 106px; }
.e20-campus-virtual__avance > div { display: flex; align-items: baseline; gap: 10px; }
.e20-campus-virtual__avance strong { font-size: .88rem; }
.e20-campus-virtual__avance strong span { font-size: .76rem; font-weight: 400; color: var(--cv-muted); }
.e20-campus-virtual__avance small { margin-left: auto; color: var(--cv-accent); font-size: .71rem; font-weight: 600; }
.e20-campus-virtual__avance progress { appearance: none; display: block; width: 100%; height: 5px; margin-top: 8px; overflow: hidden; border: 0; border-radius: 4px; background: #cedde7; color: var(--cv-accent); }
.e20-campus-virtual__avance progress::-webkit-progress-bar { background: #cedde7; border-radius: 4px; }
.e20-campus-virtual__avance progress::-webkit-progress-value { background: linear-gradient(90deg, var(--cv-blue), #15989e); border-radius: 4px; }
.e20-campus-virtual__avance progress::-moz-progress-bar { background: linear-gradient(90deg, var(--cv-blue), #15989e); border-radius: 4px; }
.e20-campus-virtual__insignia { display: inline-flex; align-items: center; gap: 5px; padding: 6px 8px; border-radius: 7px; background: #dfeaf5; color: #2d5785; font-size: .7rem; font-weight: 600; white-space: nowrap; }
.e20-campus-virtual__insignia--completa { color: #236451; background: #dcece4; }
.e20-campus-virtual__insignia--pendiente { color: #566575; background: #e7ebef; }
.e20-campus-virtual__inicio, .e20-campus-virtual__visita, .e20-campus-virtual__tiempo { font-variant-numeric: tabular-nums; white-space: nowrap; }
.e20-campus-virtual__tiempo { font-weight: 500; }
.e20-campus-virtual__tiempo i { color: var(--cv-muted); margin-right: 3px; font-size: .73rem; }
.e20-campus-virtual__muted { color: var(--cv-muted); font-size: .76rem; }
.e20-campus-virtual .boton-texto.e20-campus-virtual__eliminar {
    --boton-bg: #e2e9ef;
    --boton-alfa: .75;
    color: #526779;
    width: 34px;
    min-width: 34px;
    height: 34px;
    padding: 0;
    margin: 0;
    font-size: .85rem;
    box-shadow: inset 0 1px 2px #fff, 0 2px 4px #233f5a22 !important;
    transition: color 160ms ease-out, background-color 160ms ease-out;
}
.e20-campus-virtual .boton-texto.e20-campus-virtual__eliminar:hover { background: #f2dfdf; color: #943f46; transform: none; }
.e20-campus-virtual a:focus-visible { outline: 2px solid var(--cv-accent); outline-offset: 3px; border-radius: 5px; }
.e20-card.e20-campus-virtual__vacio { flex-direction: row; justify-content: flex-start; align-items: center; gap: 20px; padding: 30px; }
.e20-campus-virtual__vacio > i { font-size: 2rem; color: var(--cv-blue); }
.e20-campus-virtual__vacio strong { font-size: .95rem; }
.e20-campus-virtual__vacio p { margin: 5px 0 0; font-size: .85rem; color: var(--cv-muted); }
@media (pointer: coarse) {
    .e20-campus-virtual .boton-texto.e20-campus-virtual__eliminar { min-width: 44px; width: 44px; height: 44px; }
}
@media (max-width: 767px) {
    .e20-card.e20-campus-virtual__cabecera { padding: 18px 14px; gap: 12px; }
    .e20-campus-virtual__emblema { flex-basis: 44px; height: 44px; font-size: 20px; border-radius: 14px; }
    .e20-campus-virtual__titulo h2 { font-size: 1.05rem; }
    .e20-campus-virtual__titulo p { font-size: .75rem; }
    .e20-campus-virtual__etiqueta { font-size: .56rem; letter-spacing: .09em; }
    .e20-campus-virtual__contador { padding-left: 10px; gap: 4px; flex-direction: column; }
    .e20-campus-virtual__contador strong { font-size: 1.3rem; }
    .e20-campus-virtual__contador span { font-size: .6rem; text-align: center; }
    .e20-campus-virtual__lista { overflow: visible; }
    .e20-campus-virtual__tabla, .e20-campus-virtual__tabla tbody { display: block; }
    .e20-campus-virtual__tabla thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
    .e20-campus-virtual__tabla .e20-campus-virtual__fila {
        display: grid;
        grid-template-columns: 52px minmax(0, 1fr) minmax(0, 1fr) 44px;
        gap: 16px 10px;
        margin: 12px 0;
        padding: 16px 14px;
        border-radius: var(--e20-card-radius);
        background: rgba(245, 249, 253, .89);
        border: 1px solid #fff;
        box-shadow: var(--e20-card-shadow);
    }
    .e20-campus-virtual .e20-tabla.e20-campus-virtual__tabla tbody tr.e20-campus-virtual__fila > td,
    .e20-campus-virtual .e20-tabla.e20-campus-virtual__tabla tbody tr.e20-campus-virtual__fila:hover > td {
        padding: 0 !important; border: 0; border-radius: 0; background: none !important;
        min-width: 0; width: auto; text-align: left;
    }
    .e20-campus-virtual__tabla td[data-label]::before { content: attr(data-label); display: block; margin-bottom: 7px; font-size: .72rem; color: var(--cv-muted); font-weight: 400; }
    .e20-campus-virtual__imagen { grid-area: 1 / 1 / 2 / 2; }
    .e20-campus-virtual__curso { grid-area: 1 / 2 / 2 / -1; }
    .e20-campus-virtual__fila--editable .e20-campus-virtual__curso { grid-column-end: 4; }
    .e20-campus-virtual__acciones { grid-area: 1 / 4 / 2 / 5; align-self: center; }
    .e20-campus-virtual__total { grid-area: 2 / 1 / 3 / 3; }
    .e20-campus-virtual__avance { grid-area: 2 / 3 / 3 / 5; }
    .e20-campus-virtual__estado { grid-area: 3 / 1 / 4 / 3; }
    .e20-campus-virtual__tiempo { grid-area: 3 / 3 / 4 / 5; }
    .e20-campus-virtual__inicio { grid-area: 4 / 1 / 5 / 3; }
    .e20-campus-virtual__visita { grid-area: 4 / 3 / 5 / 5; }
    .e20-campus-virtual__enlace > span { font-size: .95rem; }
    .e20-campus-virtual__enlace small { font-size: .75rem; }
    .e20-campus-virtual .boton-texto.e20-campus-virtual__eliminar { width: 44px; min-width: 44px; height: 44px; }
}
@media (prefers-reduced-motion: reduce) {
    .e20-campus-virtual .boton-texto { transition: none; transform: none; }
}

/* ============================================================
   CENTRO PERSONAL DE CURSOS VIRTUALES
   ============================================================ */
.e20-cv-dashboard {
    --cv-ink: #0b1a53;
    --cv-muted: #65738a;
    --cv-teal: #0e7c6b;
    --cv-line: rgba(11, 26, 83, .12);
    color: var(--cv-ink);
    font-family: var(--e20-font);
}
.e20-cv-dashboard__inicio > [class*="col-"] { display: flex; }
.e20-card.e20-cv-dashboard__resumen {
    width: 100%;
    height: 100%;
    margin-bottom: 0;
    min-height: 160px;
    padding: 26px 30px;
    display: grid;
    grid-template-columns: minmax(240px, 1.2fr) minmax(340px, 1fr);
    gap: 28px;
    overflow: hidden;
}
.e20-cv-dashboard__resumen::after {
    content: "";
    position: absolute;
    width: 240px;
    height: 240px;
    right: -90px;
    top: -120px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(14, 124, 107, .16), transparent 68%);
    pointer-events: none;
}
.e20-cv-dashboard__eyebrow,
.e20-cv-dashboard__seccion-titulo span,
.e20-cv-dashboard__reto-copia > span {
    display: block;
    color: var(--cv-teal);
    font-size: .72rem;
    font-weight: 800;
    letter-spacing: .09em;
    text-transform: uppercase;
}
.e20-cv-dashboard__resumen h2 { margin: 5px 0 8px; font-size: clamp(1.25rem, 3vw, 1.85rem); }
.e20-cv-dashboard__resumen p { margin: 0; max-width: 620px; color: var(--cv-muted); line-height: 1.55; }
.e20-cv-dashboard__stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-content: center; gap: 15px 18px; z-index: 1; }
.e20-cv-dashboard__stats .panel-stat { gap: 10px; }
.e20-cv-dashboard__stats .panel-stat-ico { width: 34px; font-size: 1.15rem; color: var(--cv-teal); }
.e20-cv-dashboard__stats .panel-stat-num { font-size: 1.3rem; color: var(--cv-ink); }
.e20-cv-dashboard__stats .panel-stat-lbl { color: var(--cv-muted); }
.e20-card.e20-cv-dashboard__reto {
    width: 100%;
    height: 100%;
    min-height: 210px;
    margin: 0;
    padding: 20px 24px;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: "icono copia" "accion accion";
    align-items: center;
    align-content: center;
    gap: 16px;
    overflow: hidden;
    background: linear-gradient(125deg, rgba(222, 245, 236, .96), rgba(210, 231, 246, .92), rgba(235, 225, 249, .9), rgba(222, 245, 236, .96));
    background-size: 260% 260%;
}
.e20-cv-dashboard__reto::before {
    content: "";
    position: absolute;
    width: 180px;
    height: 180px;
    right: -68px;
    top: -78px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(79, 115, 246, .24), transparent 68%);
    pointer-events: none;
}
.e20-cv-dashboard__reto > * { position: relative; z-index: 1; }
.e20-cv-dashboard__reto-icono { grid-area: icono; display: grid; place-items: center; width: 54px; height: 54px; border-radius: 50%; color: white; background: var(--cv-teal); font-size: 1.35rem; box-shadow: 0 6px 14px rgba(14, 124, 107, .22); }
.e20-cv-dashboard__reto-copia { grid-area: copia; }
.e20-cv-dashboard__reto h2 { margin: 2px 0 4px; font-size: 1.08rem; }
.e20-cv-dashboard__reto p { margin: 0; color: var(--cv-muted); font-size: .86rem; }
.e20-cv-dashboard__reto .e20-cv-dashboard__reto-accion { grid-area: accion; justify-self: stretch; width: 100% !important; }
.e20-cv-dashboard__seccion { margin-top: 32px; }
.e20-cv-dashboard__seccion-titulo {
    display: flex;
    align-items: center;
    gap: 14px;
    min-height: 52px;
    margin: 0 0 14px;
    padding: 11px 16px 12px;
    border-radius: 18px;
}
.e20-cv-dashboard__seccion-titulo h2 { margin: 0; font-size: 1.3rem; }
.e20-cv-dashboard__seccion-titulo--progreso { background: rgba(14, 124, 107, .13); }
.e20-cv-dashboard__seccion-titulo--iniciar { background: rgba(88, 105, 122, .11); }
.e20-cv-dashboard__seccion-titulo--logros { background: rgba(151, 112, 20, .14); }
.e20-cv-dashboard__seccion-titulo--pausados { background: rgba(118, 83, 90, .13); }
.e20-cv-dashboard__seccion-titulo--logros span { color: #85620f; }
.e20-cv-dashboard__seccion-titulo--pausados span { color: #76535a; }
.e20-cv-dashboard__seccion-titulo .e20-cv-dashboard__conteo { display: grid; place-items: center; width: 30px; height: 30px; margin-left: auto; border-radius: 50%; color: white; background: var(--cv-ink); font-size: .8rem; letter-spacing: 0; }
.e20-card.e20-cv-curso { display: block; padding: 18px; margin-bottom: 14px; }
.e20-card.e20-cv-curso--logro { --e20-card-bg-start: rgba(248, 242, 218, .91); --e20-card-bg-end: rgba(232, 239, 229, .8); }
.e20-card.e20-cv-curso--cancelado { padding: 10px 14px; --e20-card-bg-start: rgba(247, 245, 246, .93); --e20-card-bg-end: rgba(235, 239, 243, .82); }
.e20-cv-curso__layout { display: grid; grid-template-columns: 220px minmax(0, 1fr) 76px; align-items: center; gap: 20px; }
.e20-cv-curso__poster {
    width: 220px;
    height: 174px;
    overflow: hidden;
    border-radius: 18px;
    background: rgba(11, 26, 83, .08);
    box-shadow: 0 8px 20px rgba(11, 26, 83, .14);
}
.e20-cv-curso__poster > img { width: 100%; height: 100% !important; object-fit: cover; }
.e20-cv-curso__poster-vacio {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    padding: 14px;
    color: rgba(255, 255, 255, .92);
    background: radial-gradient(circle at 75% 20%, rgba(14, 124, 107, .72), transparent 38%), linear-gradient(145deg, #162968, #0b1a53);
    text-align: center;
}
.e20-cv-curso--logro .e20-cv-curso__poster-vacio { background: radial-gradient(circle at 75% 20%, rgba(207, 164, 59, .68), transparent 38%), linear-gradient(145deg, #645019, #2d371f); }
.e20-cv-curso__poster-vacio i { margin-bottom: 13px; font-size: 2rem; }
.e20-cv-curso__poster-vacio span { font-size: .72rem; font-weight: 800; letter-spacing: .08em; }
.e20-cv-curso__contenido { min-width: 0; }
.e20-cv-curso__principal { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 15px; }
.e20-cv-curso__icono { display: grid; place-items: center; width: 58px; height: 58px; color: var(--cv-ink); background: transparent; font-size: 1.45rem; overflow: hidden; }
.e20-cv-curso--logro .e20-cv-curso__icono { color: #85620f; background: transparent; }
.e20-cv-curso__icono img { width: 100%; height: 100% !important; object-fit: contain; }
.e20-cv-curso__icono--compacto { width: 42px; height: 42px; border-radius: 13px; font-size: 1rem; }
.e20-cv-curso__identidad { min-width: 0; }
.e20-cv-curso__identidad-linea { display: flex; align-items: center; gap: 8px; min-width: 0; white-space: nowrap; }
.e20-cv-curso__chips { display: flex; flex: 0 0 auto; flex-wrap: nowrap; gap: 6px; margin: 0; }
.e20-cv-chip { display: inline-flex; align-items: center; min-height: 23px; padding: 4px 8px; border-radius: 999px; color: white; font-size: .65rem; font-weight: 750; line-height: 1; }
.e20-cv-chip--progreso { background: #2e4d8c; }
.e20-cv-chip--nuevo { background: #58697a; }
.e20-cv-chip--logro { background: #85620f; }
.e20-cv-chip--cancelado { background: #76535a; }
.e20-cv-chip--area { background: #0e7c6b; }
.e20-cv-curso__identidad h3 { min-width: 0; margin: 0; overflow: hidden; font-size: 1.28rem; line-height: 1.3; text-overflow: ellipsis; white-space: nowrap; }
.e20-cv-curso__identidad p { margin: 3px 0 0; color: var(--cv-muted); font-size: .77rem; }
.e20-cv-curso__porcentaje { display: flex; flex-direction: column; align-items: end; min-width: 78px; }
.e20-cv-curso__porcentaje strong { font-size: 1.5rem; line-height: 1; font-variant-numeric: tabular-nums; }
.e20-cv-curso__porcentaje span { margin-top: 4px; color: var(--cv-muted); font-size: .65rem; }
.e20-cv-curso__barra { height: 7px; margin: 18px 0; overflow: hidden; border-radius: 999px; background: #cbd5df; }
.e20-cv-curso__barra span { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, #2e4d8c, var(--cv-teal)); }
.e20-cv-curso--logro .e20-cv-curso__barra span { background: linear-gradient(90deg, #85620f, #4f8061); }
.e20-cv-curso__metricas { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); align-items: center; gap: 0; }
.e20-cv-curso__metricas > div { min-width: 0; padding: 4px 14px; border-left: 1px solid var(--cv-line); }
.e20-cv-curso__metricas > div:first-child { padding-left: 0; border-left: 0; }
.e20-cv-curso__metricas i { color: var(--cv-teal); font-size: .84rem; margin-right: 4px; }
.e20-cv-curso__metricas span { display: inline; color: var(--cv-muted); font-size: .76rem; font-weight: 650; }
.e20-cv-curso__metricas > div > strong { display: block; margin-top: 6px; overflow-wrap: anywhere; font-size: .9rem; line-height: 1.35; }
.e20-cv-curso__metricas .e20-cv-curso__metrica-modulos { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px; padding-top: 0; padding-bottom: 0; }
.e20-cv-modulos-grafico {
    display: grid;
    place-items: center;
    width: 58px;
    height: 58px;
    border-radius: 50%;
    background: conic-gradient(var(--cv-teal) calc(var(--e20-cv-pct) * 1%), rgba(11, 26, 83, .12) 0);
    position: relative;
}
.e20-cv-modulos-grafico::before {
    content: "";
    position: absolute;
    inset: 7px;
    border-radius: 50%;
    background: rgba(248, 250, 252, .9);
}
.e20-cv-modulos-grafico strong {
    position: relative;
    z-index: 1;
    margin: 0;
    color: var(--cv-ink);
    font-size: .86rem;
    font-weight: 900;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
.e20-cv-curso__acciones {
    display: grid;
    grid-template-columns: 76px;
    align-items: center;
    justify-items: center;
    justify-content: center;
    gap: 8px;
    margin: 0;
}
.e20-cv-curso__acciones--estudio { grid-template-rows: 38px 76px 38px; }
.e20-cv-curso__acciones--logro { grid-template-rows: 76px 38px; }
.e20-cv-curso__acciones .boton-texto.e20-cv-accion {
    width: var(--e20-cv-accion-size, 38px) !important;
    min-width: var(--e20-cv-accion-size, 38px) !important;
    height: var(--e20-cv-accion-size, 38px);
    padding: 0;
    border-radius: 50%;
    color: var(--cv-accion-color, #2e4d8c);
    background-color: rgb(from var(--boton-bg) r g b / var(--boton-alfa));
    box-shadow: 0 5px 14px rgba(11, 26, 83, .14), inset 0 2px 3px rgba(255, 255, 255, .34) !important;
    font-size: .88rem;
}
.e20-cv-curso__acciones .boton-texto.e20-cv-accion:hover,
.e20-cv-curso__acciones .boton-texto.e20-cv-accion:focus-visible {
    --boton-alfa: .78;
    color: white;
    box-shadow: 0 7px 17px rgba(11, 26, 83, .22), inset 0 2px 3px rgba(255, 255, 255, .28) !important;
}
.e20-cv-curso__acciones .e20-cv-accion--principal { --cv-accion-color: #18794e; font-size: 1.55rem; }
.e20-cv-curso__acciones--estudio .e20-cv-accion--principal { grid-column: 1; grid-row: 2; }
.e20-cv-curso__acciones--logro .e20-cv-accion--principal { grid-column: 1; grid-row: 1; }
.e20-cv-curso__acciones .e20-cv-accion--logro { --cv-accion-color: #85620f; }
.e20-cv-curso__acciones .e20-cv-accion--cancelar { grid-column: 1; grid-row: 1; --cv-accion-color: #9a3e48; }
.e20-cv-curso__acciones--estudio .e20-cv-accion--evolucion { grid-column: 1; grid-row: 3; }
.e20-cv-curso__acciones--logro .e20-cv-accion--evolucion { grid-column: 1; grid-row: 2; }
.e20-cv-curso__acciones .e20-cv-accion--retomar { --cv-accion-color: #18794e; }
.e20-cv-curso__pausado { display: grid; grid-template-columns: 42px minmax(0, 1fr) auto; align-items: center; gap: 13px; min-height: 46px; }
.e20-cv-curso__identidad--pausado { display: flex; align-items: center; gap: 10px; min-width: 0; }
.e20-cv-curso__identidad--pausado h3 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.e20-cv-curso__acciones--pausado { display: flex; gap: 8px; }
.e20-cv-curso__acciones--pausado .e20-cv-accion--evolucion { grid-column: auto; grid-row: auto; }
.e20-cv-curso__evolucion { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--cv-line); }
.e20-cv-curso__evolucion.show { visibility: visible; }
.e20-cv-curso__evolucion h4 { margin: 0 0 12px; font-size: .9rem; }
.e20-cv-curso__evolucion ol { list-style: none; margin: 0; padding: 0; }
.e20-cv-curso__evolucion li { display: grid; grid-template-columns: 30px minmax(0, 1fr); align-items: center; gap: 10px; padding: 10px 0; border-top: 1px solid var(--cv-line); }
.e20-cv-curso__evolucion li:first-child { border-top: 0; }
.e20-cv-curso__paso-icono { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; color: white; background: #607184; font-size: .67rem; }
.e20-cv-curso__evolucion li:has(.fa-check) .e20-cv-curso__paso-icono { background: var(--cv-teal); }
.e20-cv-curso__evolucion strong { display: block; font-size: .8rem; }
.e20-cv-curso__evolucion small { display: block; margin-top: 3px; color: var(--cv-muted); font-size: .7rem; }
.e20-card.e20-cv-dashboard__vacio,
.e20-card.e20-cv-dashboard__sin-cursos { flex-direction: row; align-items: center; justify-content: flex-start; gap: 18px; padding: 24px; }
.e20-cv-dashboard__vacio > i, .e20-cv-dashboard__sin-cursos > i { color: var(--cv-teal); font-size: 1.7rem; }
.e20-cv-dashboard__vacio p, .e20-cv-dashboard__sin-cursos p { margin: 0; color: var(--cv-muted); }
.e20-cv-dashboard__sin-cursos h2 { margin: 0 0 5px; font-size: 1.05rem; }
.e20-cv-dashboard__sin-cursos .boton-texto { margin-left: auto !important; }
.e20-cv-dashboard a:focus-visible, .e20-cv-dashboard button:focus-visible { outline: 3px solid #4f73f6; outline-offset: 3px; }
@media (prefers-reduced-motion: no-preference) {
    .e20-cv-dashboard__resumen, .e20-cv-curso { animation: e20-cv-reveal .42s ease-out both; }
    .e20-cv-dashboard__reto { animation: e20-cv-reveal .42s ease-out both, e20-cv-reto-color 9s ease-in-out .42s infinite; }
    .e20-cv-dashboard__reto-icono { animation: e20-cv-reto-objetivo 2.8s ease-in-out .6s infinite; }
    .e20-cv-dashboard__reto-accion { animation: e20-cv-reto-llamado 2.8s ease-in-out 1s infinite; }
    .e20-cv-curso:nth-of-type(2) { animation-delay: .05s; }
    .e20-cv-curso:nth-of-type(3) { animation-delay: .1s; }
    @keyframes e20-cv-reveal { from { opacity: 0; transform: translateY(9px); } to { opacity: 1; transform: translateY(0); } }
    @keyframes e20-cv-reto-color { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }
    @keyframes e20-cv-reto-objetivo { 0%, 100% { box-shadow: 0 6px 14px rgba(14, 124, 107, .22); } 50% { box-shadow: 0 7px 22px rgba(14, 124, 107, .42); } }
    @keyframes e20-cv-reto-llamado { 0%, 100% { filter: brightness(1); } 50% { filter: brightness(1.12); } }
}
@media (max-width: 991px) {
    .e20-card.e20-cv-dashboard__resumen { grid-template-columns: 1fr; }
    .e20-cv-curso__layout { grid-template-columns: 190px minmax(0, 1fr) 76px; gap: 16px; }
    .e20-cv-curso__poster { width: 190px; height: 160px; }
    .e20-cv-curso__metricas { grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: 14px; }
    .e20-cv-curso__metricas > div:nth-child(4) { padding-left: 0; border-left: 0; }
}
@media (max-width: 575px) {
    .e20-cv-dashboard { padding-left: 12px; padding-right: 12px; }
    .e20-card.e20-cv-dashboard__resumen { padding: 22px 18px; }
    .e20-cv-dashboard__stats { grid-template-columns: 1fr 1fr; gap: 14px 6px; }
    .e20-card.e20-cv-dashboard__reto { grid-template-columns: auto 1fr; padding: 18px; }
    .e20-cv-dashboard__reto .boton-texto { grid-column: 1 / -1; justify-self: stretch; width: 100% !important; }
    .e20-cv-dashboard__seccion-titulo { min-height: 50px; padding: 9px 13px 10px; border-radius: 15px; }
    .e20-cv-dashboard__seccion-titulo h2 { font-size: 1.12rem; }
    .e20-card.e20-cv-curso { padding: 13px; }
    .e20-card.e20-cv-curso--cancelado { padding: 9px 11px; }
    .e20-cv-curso__layout { grid-template-columns: 132px minmax(0, 1fr); align-items: start; gap: 12px; }
    .e20-cv-curso__poster { width: 132px; height: 132px; border-radius: 14px; }
    .e20-cv-curso__poster-vacio { padding: 8px; }
    .e20-cv-curso__poster-vacio i { margin-bottom: 9px; font-size: 1.5rem; }
    .e20-cv-curso__poster-vacio span { font-size: .6rem; }
    .e20-cv-curso__principal { grid-template-columns: 44px minmax(0, 1fr); gap: 10px; }
    .e20-cv-curso__icono { width: 44px; height: 44px; border-radius: 13px; font-size: 1.05rem; }
    .e20-cv-curso__porcentaje { grid-column: 1 / -1; align-items: start; flex-direction: row; gap: 6px; }
    .e20-cv-curso__porcentaje strong { font-size: 1.15rem; }
    .e20-cv-curso__metricas { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 14px; }
    .e20-cv-curso__metricas > div:nth-child(odd) { padding-left: 0; border-left: 0; }
    .e20-cv-curso__metricas > div:nth-child(even) { border-left: 1px solid var(--cv-line); }
    .e20-cv-curso__layout > .e20-cv-curso__acciones { grid-column: 2; justify-content: center; margin-top: 2px; }
    .e20-cv-curso__pausado { grid-template-columns: 38px minmax(0, 1fr) auto; gap: 9px; }
    .e20-cv-curso__icono--compacto { width: 38px; height: 38px; border-radius: 12px; }
    .e20-cv-curso__identidad--pausado { display: block; }
    .e20-cv-curso__identidad--pausado .e20-cv-chip { margin-top: 4px; }
    .e20-cv-curso__acciones--pausado { grid-column: auto; margin: 0; }
    .e20-card.e20-cv-dashboard__sin-cursos { align-items: flex-start; flex-wrap: wrap; }
    .e20-cv-dashboard__sin-cursos .boton-texto { width: 100% !important; margin-left: 0 !important; }
}

/* ============================================================
   MENSAJES Y CONFIRMACIONES — E20Dialog / dialog_header.html
   Alcance explícito: nunca se aplica a formularios ni a visores.
   Misma estructura para SweetAlert2 y confirmaciones Bootstrap.
   ============================================================ */
.e20-dialog,
.e20-dialog-bootstrap {
    --e20-dialog-accent: var(--e20-dialog-info);
    --e20-dialog-tint: #eef2fb;
}
.e20-dialog-bootstrap { --e20-vm-modal-max-width: 30rem; }
.e20-dialog--success { --e20-dialog-accent: var(--e20-dialog-success); --e20-dialog-tint: #edf6f0; }
.e20-dialog--warning { --e20-dialog-accent: var(--e20-dialog-warning); --e20-dialog-tint: #fff6e9; }
.e20-dialog--error,
.e20-dialog--delete { --e20-dialog-accent: var(--e20-dialog-danger); --e20-dialog-tint: #fceeee; }
/* Heredar la variante del .modal-dialog en el contenido Bootstrap. */
.e20-dialog-bootstrap .e20-dialog { --e20-dialog-accent: inherit; --e20-dialog-tint: inherit; }

.swal2-container.e20-dialog-container {
    z-index: 100300;
    padding: 20px 12px;
}
.swal2-container.e20-dialog-container.swal2-backdrop-show { background: rgba(15, 23, 42, .55); }
.swal2-popup.e20-dialog,
.e20-dialog-overlay .e20-dialog,
.modal .modal-dialog.e20-dialog-bootstrap .modal-content.e20-dialog,
.e20-dialog-bootstrap .e20-dialog {
    padding: 0;
    border: 0;
    border-radius: var(--e20-card-radius);
    background: var(--e20-dialog-bg);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    color: #000;
    font-family: var(--e20-font);
    font-size: 1rem;
    box-shadow: var(--e20-card-resalte3d-shadow);
    overflow: hidden;
}
.swal2-popup.e20-dialog { width: 30rem; max-width: 100%; }
.e20-dialog-overlay {
    position: fixed;
    inset: 0;
    z-index: 100300;
    display: none;
    align-items: center;
    justify-content: center;
    overflow-y: auto;
    padding: 20px 12px;
    background: rgba(15, 23, 42, .55);
}
.e20-dialog-overlay .e20-dialog { width: 30rem; max-width: 100%; }
.modal .modal-dialog.e20-dialog-bootstrap,
.modal.e20-ventana-modal .modal-dialog.e20-dialog-bootstrap {
    width: calc(100% - 24px);
    max-width: 30rem;
    margin: 20px auto;
    min-height: calc(100% - 40px);
    align-items: center;
}
.e20-dialog .e20-dialog__header,
.modal .e20-dialog-bootstrap .e20-dialog__header {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    padding: 28px 28px 0;
    background: transparent;
    border: 0;
    color: inherit;
}
.e20-dialog .e20-dialog__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 52px;
    height: 52px;
    margin: 0;
    border: 0;
    border-radius: 50%;
    background: var(--e20-dialog-tint);
    color: var(--e20-dialog-info);
    font-size: 23px;
    line-height: 1;
}
.swal2-popup.e20-dialog .e20-dialog__icon { margin: 28px auto 0; }
.e20-dialog .e20-dialog__icon .swal2-icon-content { font-size: inherit; }
.e20-dialog .e20-dialog__icon,
.e20-dialog .e20-dialog__icon .swal2-icon-content { animation: none; }
.e20-dialog .e20-dialog__icon::before,
.e20-dialog .e20-dialog__icon::after { display: none; }
.e20-dialog .e20-dialog__title,
.modal .e20-dialog-bootstrap .e20-dialog__title {
    margin: 0;
    padding: 0;
    color: #000;
    font-family: inherit;
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.4;
    letter-spacing: 0;
    text-align: center;
    text-shadow: none;
    overflow-wrap: anywhere;
}
.swal2-popup.e20-dialog .e20-dialog__title { padding: 16px 28px 0; }
.e20-dialog .e20-dialog__body,
.modal .e20-dialog-bootstrap .e20-dialog__body {
    margin: 0;
    padding: 14px 28px 24px;
    background: transparent;
    color: #000;
    font-size: .9375rem;
    font-weight: 400;
    line-height: 1.65;
    text-align: left;
    overflow-wrap: anywhere;
    max-height: 55vh;
    overflow-y: auto;
}
.swal2-popup.e20-dialog .e20-dialog__body { white-space: pre-line; }
.e20-dialog__body > :last-child { margin-bottom: 0; }
.swal2-popup.e20-dialog .e20-dialog__input { width: calc(100% - 56px); max-width: none; margin: 4px 28px 8px; box-sizing: border-box; }
.swal2-popup.e20-dialog textarea.e20-dialog__input { min-height: 96px; resize: vertical; }
.swal2-popup.e20-dialog .swal2-validation-message { margin: 0 28px; background: var(--e20-dialog-tint); color: var(--e20-dialog-danger); font-size: .85rem; }
/* Unificar acentos heredados de utilidades Bootstrap dentro del mensaje. */
.e20-dialog :is(.text-muted, .text-primary, .text-secondary, .text-success, .text-warning, .text-danger, .text-info) {
    color: var(--e20-dialog-info) !important;
}
.e20-dialog .e20-dialog__actions,
.modal .e20-dialog-bootstrap .e20-dialog__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    width: 100%;
    margin: 0;
    padding: 18px 24px;
    border-top: 1px solid rgba(0, 51, 153, .12);
    background: transparent;
}
.e20-dialog__actions > form { display: contents; }
.e20-dialog__content { min-width: 0; }
.e20-dialog .e20-dialog__button {
    --boton-alfa: 1;
    min-height: 42px;
    height: auto;
    min-width: 100px;
    max-width: 100%;
    margin: 0;
    padding: 11px 20px;
    border: 1px solid transparent;
    border-radius: 20px;
    font-size: .875rem;
    font-weight: 600;
    line-height: 1.35;
    white-space: normal;
    box-shadow: inset 0 1px 2px rgba(255, 255, 255, .18), 0 2px 4px rgba(15, 23, 42, .08) !important;
    transition: background-color .16s ease, box-shadow .16s ease;
    transform: none;
}
.e20-dialog .e20-dialog__confirm {
    --boton-bg: var(--e20-dialog-accent);
    background: var(--e20-dialog-accent);
    color: #fff;
}
.e20-dialog .e20-dialog__cancel,
.e20-dialog .e20-dialog__deny {
    --boton-bg: #fff;
    background: #fff;
    border-color: #cbd5e1;
    color: var(--e20-dialog-info);
    box-shadow: none !important;
}
.e20-dialog .e20-dialog__button:hover,
.e20-dialog .e20-dialog__button:active,
.e20-dialog .e20-dialog__button:focus {
    transform: none;
    box-shadow: inset 0 0 0 100px rgba(15, 23, 42, .07) !important;
}
.e20-dialog .e20-dialog__cancel:hover,
.e20-dialog .e20-dialog__cancel:focus,
.e20-dialog .e20-dialog__deny:hover,
.e20-dialog .e20-dialog__deny:focus { color: var(--e20-dialog-info); }
.e20-dialog .e20-dialog__button:focus-visible,
.e20-dialog .e20-dialog__close:focus-visible {
    outline: 3px solid var(--e20-dialog-accent);
    outline-offset: 3px;
}
.e20-dialog .e20-dialog__button:disabled { opacity: .55; cursor: wait; }
.e20-dialog .e20-dialog__close {
    position: absolute;
    top: 10px;
    right: 10px;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 36px;
    height: 36px;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--e20-dialog-info);
    font-size: 1.125rem;
    box-shadow: none;
    cursor: pointer;
}
.e20-dialog .e20-dialog__close:hover { background: #f1f5f9; color: var(--e20-dialog-info); }
.e20-dialog .e20-dialog__footer { margin: 0; padding: 12px 28px; border-top: 1px solid rgba(0, 51, 153, .12); font-size: .8125rem; }
.e20-dialog__summary { padding: 14px 16px; border: 1px solid rgba(0, 51, 153, .12); border-radius: 12px; background: var(--e20-dialog-bg); }
.e20-dialog__summary dt { color: var(--e20-dialog-info); font-size: .8125rem; font-weight: 400; }
.e20-dialog__summary dd { margin: 0 0 10px; color: #000; font-weight: 600; }
.e20-dialog__summary dd:last-child { margin-bottom: 0; }
.e20-dialog__image { display: block; width: 100%; max-width: 320px; height: auto; margin: 0 auto 16px; border-radius: 12px; }
.e20-dialog__notice { padding: 12px 14px; border-radius: 12px; background: var(--e20-dialog-tint); color: var(--e20-dialog-info); }
.e20-dialog__error { margin: 0 28px 18px; padding: 12px 14px; border-radius: 12px; background: #fceeee; color: var(--e20-dialog-info); }
.e20-dialog__error:empty { display: none; }
.e20-dialog-enter { animation: e20-dialog-in .18s ease-out; }
.e20-dialog-leave { animation: e20-dialog-out .12s ease-in forwards; }
@keyframes e20-dialog-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
@keyframes e20-dialog-out { to { opacity: 0; } }
@media (max-width: 480px) {
    .e20-dialog .e20-dialog__header,
    .modal .e20-dialog-bootstrap .e20-dialog__header { padding: 24px 20px 0; }
    .swal2-popup.e20-dialog .e20-dialog__icon { margin-top: 24px; }
    .swal2-popup.e20-dialog .e20-dialog__title { padding-left: 20px; padding-right: 20px; }
    .e20-dialog .e20-dialog__body,
    .modal .e20-dialog-bootstrap .e20-dialog__body { padding: 12px 20px 20px; }
    .e20-dialog .e20-dialog__actions,
    .modal .e20-dialog-bootstrap .e20-dialog__actions { padding: 16px 20px; }
    .e20-dialog .e20-dialog__button { flex: 1 1 auto; min-height: 44px; }
}
@media (prefers-reduced-motion: reduce) {
    .e20-dialog-enter, .e20-dialog-leave { animation: none; }
    .e20-dialog .e20-dialog__button { transition: none; }
}

/* Visibilidad del error administrada por el flujo de matrícula. */
.js-matricula-error.e20-dialog__error { display: none; }

/* Catálogo por linkclave: ficha editorial y recorrido completo del curso. */
.cv-showcase {
  position: relative;
  display: grid;
  grid-template-columns: minmax(280px, .72fr) minmax(480px, 1.28fr);
  gap: clamp(28px, 4vw, 64px);
  width: min(1440px, calc(100% - 8%));
  margin: 32px auto 140px;
  padding: clamp(24px, 4vw, 56px);
  overflow: hidden;
  color: #161616;
  background: rgba(230, 230, 230, .52);
  border: 1px solid rgba(255, 255, 255, .72);
  border-radius: var(--e20-card-radius);
  box-shadow: var(--e20-card-resalte3d-shadow);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.cv-showcase__identity,
.cv-showcase__route {
  position: relative;
  min-width: 0;
  z-index: 1;
}

.cv-showcase__watermark {
  position: absolute;
  top: -28px;
  left: -34px;
  width: min(92%, 420px);
  aspect-ratio: 1;
  opacity: .07;
  filter: grayscale(1) sepia(.15) hue-rotate(175deg) saturate(3);
  pointer-events: none;
  z-index: 0;
}

.cv-showcase__watermark img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.cv-showcase__poster {
  position: relative;
  z-index: 1;
  width: min(100%, 430px);
  aspect-ratio: 16 / 10;
  margin: clamp(180px, 24vw, 330px) 0 18px;
  overflow: hidden;
  background: #d8dbe0;
  border-radius: 12px;
  box-shadow: 0 10px 24px rgba(0, 0, 0, .22);
}

.cv-showcase__poster img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cv-showcase__copy h2 {
  margin: 0 0 10px;
  color: #003399;
  font-family: var(--e20-font);
  font-size: clamp(1.25rem, 2vw, 1.8rem);
  font-weight: 750;
}

.cv-showcase__copy {
  position: relative;
  z-index: 1;
}

.cv-showcase__description {
  color: #111;
  font-size: .98rem;
  line-height: 1.55;
}

.cv-showcase__description > :last-child { margin-bottom: 0; }

.cv-showcase__skills {
  margin-top: 20px;
  color: #003399;
  font-size: .94rem;
  line-height: 1.55;
}

.cv-showcase__skills h3 {
  margin: 0 0 7px;
  color: #161616;
  font-size: 1rem;
  font-weight: 750;
}

.cv-showcase__skills h3 i { color: #003399; }

.cv-showcase__route-header {
  display: flex;
  align-items: center;
  gap: 14px;
  width: min(100%, 420px);
  min-height: 86px;
  margin: 0 0 24px;
  padding: 14px 22px;
  color: #fff;
  background: linear-gradient(145deg, #084fc8, #007edc);
  border: 1px solid rgba(255, 255, 255, .6);
  border-radius: 14px;
  box-shadow: var(--e20-card-resalte3d-shadow);
}

.cv-showcase__route-header small,
.cv-showcase__route-header strong {
  display: block;
  line-height: 1.15;
}

.cv-showcase__route-header small {
  margin-bottom: 4px;
  font-size: .72rem;
  letter-spacing: .06em;
  opacity: .82;
  text-transform: uppercase;
}

.cv-showcase__route-header strong {
  font-size: 1.08rem;
  font-weight: 750;
}

.cv-showcase__route-icon {
  display: grid;
  flex: 0 0 46px;
  width: 46px;
  height: 46px;
  place-items: center;
  overflow: hidden;
  font-size: 1.45rem;
  border: 1px solid rgba(255, 255, 255, .8);
  border-radius: 50%;
}

.cv-showcase__route-icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cv-modules {
  position: relative;
  padding-left: 22px;
}

.cv-modules::before {
  position: absolute;
  top: -26px;
  bottom: 30px;
  left: 48px;
  content: '';
  border-left: 2px dashed rgba(50, 137, 209, .45);
}

.cv-module {
  position: relative;
  display: grid;
  grid-template-columns: 54px minmax(0, 1fr);
  gap: 12px;
  align-items: center;
  margin-bottom: 16px;
}

.cv-module__number {
  position: relative;
  z-index: 1;
  display: grid;
  width: 46px;
  height: 46px;
  place-items: center;
  color: #fff;
  font-size: .95rem;
  font-weight: 750;
  background: linear-gradient(145deg, #65cbe7, #299dc3);
  border: 2px solid rgba(255, 255, 255, .88);
  border-radius: 50%;
  box-shadow: 0 5px 12px rgba(0, 76, 130, .25), inset 0 2px 4px rgba(255, 255, 255, .45);
}

.cv-module__card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 86px 92px;
  gap: 14px;
  align-items: center;
  min-height: 96px;
  padding: 14px 18px;
  background: rgba(201, 231, 243, .58);
  border: 1px solid rgba(255, 255, 255, .88);
  border-radius: 12px 12px 34px 12px;
  box-shadow: 5px 6px 12px rgba(0, 0, 0, .13), inset 2px 2px 5px rgba(255, 255, 255, .72);
}

.cv-module__body { min-width: 0; }

.cv-module__body h3 {
  margin: 0 0 4px;
  color: #20242a;
  font-size: 1.05rem;
  font-weight: 750;
  line-height: 1.22;
}

.cv-module__description {
  margin: 0;
  color: #343b43;
  font-size: .82rem;
  line-height: 1.38;
}

.cv-module__type {
  display: flex;
  flex-direction: column;
  gap: 7px;
  align-items: center;
  color: #15222b;
  font-size: 1.55rem;
}

.cv-module__type span {
  padding: 3px 10px;
  color: #fff;
  font-size: .68rem;
  font-weight: 700;
  background: #54bdd9;
  border-radius: 999px;
}

.cv-module__type img {
  width: 34px;
  height: 34px;
  object-fit: contain;
}

.cv-module__duration {
  display: flex;
  gap: 5px;
  align-items: center;
  justify-content: flex-end;
  color: #303840;
  font-size: .76rem;
  white-space: nowrap;
}

.cv-modules__section {
  position: relative;
  margin: 20px 0 12px 66px;
  color: #003399;
  font-size: .94rem;
  font-weight: 750;
}

.cv-modules__empty {
  padding: 28px;
  color: #4d5660;
  text-align: center;
  background: rgba(255, 255, 255, .45);
  border-radius: 14px;
}

@media (max-width: 991.98px) {
  .cv-showcase {
    grid-template-columns: 1fr;
    width: calc(100% - 30px);
    padding: 24px;
  }
  .cv-showcase__identity {
    display: grid;
    grid-template-columns: minmax(180px, .75fr) 1fr;
    gap: 24px;
    align-items: end;
  }
  .cv-showcase__watermark { width: min(54%, 330px); }
  .cv-showcase__poster { margin-top: 150px; }
  .cv-showcase__route-header { margin-left: auto; margin-right: auto; }
}

@media (max-width: 575.98px) {
  .cv-showcase {
    gap: 34px;
    width: calc(100% - 20px);
    margin-top: 20px;
    padding: 18px 12px 28px;
  }
  .cv-showcase__identity { display: block; }
  .cv-showcase__watermark {
    top: -16px;
    left: 50%;
    width: 78%;
    transform: translateX(-50%);
  }
  .cv-showcase__poster {
    width: 100%;
    margin-top: 180px;
  }
  .cv-showcase__copy h2 { font-size: 1.25rem; }
  .cv-showcase__route-header { min-height: 76px; padding: 12px 16px; }
  .cv-modules { padding-left: 0; }
  .cv-modules::before { left: 22px; }
  .cv-module { grid-template-columns: 44px minmax(0, 1fr); gap: 6px; }
  .cv-module__number { width: 42px; height: 42px; font-size: .82rem; }
  .cv-module__card {
    grid-template-columns: minmax(0, 1fr) 60px;
    gap: 7px;
    min-height: 78px;
    padding: 11px 12px;
    border-radius: 10px 10px 24px 10px;
  }
  .cv-module__body h3 { margin: 0; font-size: .92rem; }
  .cv-module__description { display: none; }
  .cv-module__type { grid-row: 1 / 3; grid-column: 2; font-size: 1.25rem; }
  .cv-module__type span { padding: 2px 7px; font-size: .58rem; }
  .cv-module__type img { width: 28px; height: 28px; }
  .cv-module__duration {
    grid-row: 2;
    grid-column: 1;
    justify-content: flex-start;
    font-size: .68rem;
  }
  .cv-modules__section { margin-left: 52px; }
}

/* Presentación hablada del curso compartido; conserva el Aibot flotante. */
.aibot-course-intro {
  position: fixed;
  top: 72px;
  right: 190px;
  z-index: 100000;
  max-width: min(230px, calc(100vw - 40px));
}
.aibot-course-intro .boton-texto {
  --boton-bg: rgba(230, 230, 230, .95);
  color: #003399;
  min-height: 44px;
  font-size: .9rem;
  white-space: normal;
  box-shadow: var(--e20-card-resalte3d-shadow);
}
.aibot-course-companion #aibot-global-panel { max-width: calc(100vw - 24px); }
@media (max-width: 767.98px) {
  .aibot-course-intro {
    top: 68px;
    right: 130px;
    max-width: 170px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .aibot-course-companion .aibot-global-flotante { animation: none; }
}

/* Acceso al chat de la asignatura. */
.e20-acceso--chat       { --e20-acceso-color: #25D366; }
.e20-acceso--chat .e20-acceso__texto { background: rgba(37, 211, 102, .5); }
.e20-acceso--chat .e20-acceso__icono { font-size: calc(var(--e20-acceso-escala) * .52); }

/* ===== Botón CTA con pulso: invita a la acción principal de la vista (se suma a .boton-texto) ===== */
.boton-texto.e20-cta-pulso {
    position: relative;
    gap: .6em;
    --boton-alfa: 0.92;
    height: 42px;
    padding: 10px 26px;
    font-size: .95em;
    font-weight: 700;
    letter-spacing: .01em;
}
/* El aro vive en un pseudo-elemento: el box-shadow de .boton-texto es !important y una animación no lo supera */
.boton-texto.e20-cta-pulso::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    box-shadow: 0 0 0 0 rgba(14, 124, 107, .6);
    box-shadow: 0 0 0 0 rgb(from var(--boton-bg) r g b / .6);
    animation: e20-cta-pulso 1.9s ease-out infinite;
}
.boton-texto.e20-cta-pulso:hover::after,
.boton-texto.e20-cta-pulso:focus-visible::after { animation-play-state: paused; }
@keyframes e20-cta-pulso {
    0%   { box-shadow: 0 0 0 0 rgba(14, 124, 107, .6); box-shadow: 0 0 0 0 rgb(from var(--boton-bg) r g b / .6); }
    70%  { box-shadow: 0 0 0 16px rgba(14, 124, 107, 0); box-shadow: 0 0 0 16px rgb(from var(--boton-bg) r g b / 0); }
    100% { box-shadow: 0 0 0 0 rgba(14, 124, 107, 0); box-shadow: 0 0 0 0 rgb(from var(--boton-bg) r g b / 0); }
}
@media (prefers-reduced-motion: reduce) {
    .boton-texto.e20-cta-pulso::after { animation: none; box-shadow: 0 0 0 6px rgba(14, 124, 107, .25); box-shadow: 0 0 0 6px rgb(from var(--boton-bg) r g b / .25); }
}


/* ============================================================
   ÍCONO DE CURSO: sombra discreta abajo a la derecha, en toda la app
   ============================================================
   drop-shadow y no box-shadow: los íconos son redondos con exterior transparente y la sombra sigue su forma.
   Se reconoce por la ruta (media/cursos_iconos/ o el ícono por defecto), así cubre cada vista sin tocar plantillas;
   :where() deja la especificidad en cero para que un filtro propio (p. ej. la marca de agua) siga mandando. */
:root { --e20-sombra-icono-curso: drop-shadow(2px 3px 3px rgba(0, 0, 0, 0.28)); }
.e20-icono-curso,
:where(img[src*="/cursos_iconos/"], img[src*="default_icono_curso"]) {
    filter: var(--e20-sombra-icono-curso);
}
