@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@600;700;800&family=Source+Sans+3:wght@400;500;600;700;800&display=swap');

:root {
    /* Identidad institucional: azul marino + amarillo. El azul es el
       color de autoridad -titulares, portadas de curso, botones
       primarios, enlaces- y el amarillo es SIEMPRE acento y nunca
       texto: subraya el titular de cada página, llena la barra de
       progreso y remata el encabezado. Página clara y tarjetas blancas
       sólidas: la profundidad la da la sombra, no el color de fondo. */
    --cv-bg: #f4f6fb;
    --cv-surface: #ffffff;
    --cv-surface-2: #eef1f7;
    --cv-border: #e3e8f0;
    --cv-text: #1b2437;
    --cv-text-dim: #6b7590;
    /* Identidad tipo INTEVRA Academic: escala cian de marca (#0ea5e9),
       la misma que usan academic.intevra.com.co y el panel de intevra.com.co.
       El azul marino pasa a un cian profundo; el acento deja de ser amarillo
       y usa un cian claro, para un look cohesionado cian + pizarra + blanco. */
    --cv-navy: #0c4a6e;
    --cv-primary: #0284c7;
    --cv-primary-dark: #075985;
    --cv-primary-tint: #e0f2fe;
    --cv-accent: #38bdf8;
    --cv-accent-soft: #e0f2fe;
    /* Versión del acento legible como TEXTO sobre fondo claro. */
    --cv-accent-dark: #0369a1;
    --cv-success: #178a4c;
    --cv-warning: #b1710a;
    --cv-danger: #cc3340;

    /* Colores del simulador de red: NO son decorativos ni siguen la
       identidad institucional -son los mismos que llevan los íconos
       dibujados por topologia.js (ICONOS)-, así que viven aparte de la
       paleta de marca y no cambian cuando esta cambia: `--cv-cyan` es
       el azul de los switches (#0096d6), `--cv-led-*` los LED de
       estado de PC/Servidor/Router, y `--cv-orange` el naranja de
       router/fibra/VPN -que antes era el acento del sitio y aquí se
       queda porque una línea amarilla de 2.5px sobre lienzo blanco no
       se distingue-. */
    --cv-cyan: #0096d6;
    --cv-led-green: #3ddc84;
    --cv-led-amber: #f5a623;
    --cv-orange: #e2790f;

    --cv-shadow-sm: 0 1px 2px rgba(18, 41, 79, 0.06), 0 1px 3px rgba(18, 41, 79, 0.05);
    --cv-shadow-md: 0 8px 20px rgba(18, 41, 79, 0.10), 0 2px 6px rgba(18, 41, 79, 0.06);
    --cv-shadow-lift: 0 14px 28px rgba(18, 41, 79, 0.14), 0 4px 10px rgba(18, 41, 79, 0.08);

    /* Titulares en una sans geométrica pesada -el registro visual de la
       marca-; el cuerpo sigue en Source Sans, que lee mejor en párrafo
       largo. `--cv-font-serif` se conserva como alias para no romper
       reglas viejas que aún la nombren. */
    --cv-font-display: 'Montserrat', 'Source Sans 3', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --cv-font-sans: 'Source Sans 3', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --cv-font-serif: var(--cv-font-display);

    /* Sistema de movimiento -mismo criterio en todo el sitio, en vez de
       un valor de duración/curva distinto por componente-:
       - `--cv-ease-out` (desacelera, "cae" en su lugar) para todo lo que
         ENTRA o reacciona a un hover -se siente inmediato, como si ya
         estuviera en movimiento cuando el usuario lo nota-.
       - `--cv-ease-in` (acelera) para lo que SALE -se siente que se va
         rápido, no que se demora en desaparecer-.
       - `--cv-ease-spring` (con un leve rebote) para paneles/menús que
         se despliegan desde un punto -lanzador, notificaciones-, ya
         usada ahí; promovida a token para reusarla a propósito, no por
         accidente.
       - Duraciones cortas a propósito: una micro-interacción que se
         demora se siente pesada, no elegante. */
    --cv-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --cv-ease-in: cubic-bezier(0.7, 0, 0.84, 0);
    --cv-ease-spring: cubic-bezier(0.2, 0.85, 0.3, 1.3);
    --cv-dur-fast: 100ms;
    --cv-dur-base: 160ms;
    --cv-dur-slow: 240ms;
}

* { box-sizing: border-box; }

/* Red de seguridad global -sin importar qué transition/animation se
   defina en cualquier regla de este archivo (presente o futura), quien
   pida menos movimiento en su sistema operativo lo obtiene: todo pasa a
   durar ~0-, sin necesidad de acordarse de excluir cada componente uno
   por uno -antes solo 2 de ~15 piezas animadas del sitio lo hacían-. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* Fondo quieto y claro: el contenido vive en tarjetas blancas sobre un
   gris azulado muy tenue, con un solo lavado de color en el borde
   superior de la página para que el azul de marca se asome detrás del
   encabezado. Nada animado detrás del contenido -el color y el
   movimiento se reservan para lo que el estudiante sí debe mirar-. */
body.campus-virtual {
    margin: 0;
    background-color: var(--cv-bg);
    background-repeat: no-repeat;
    background-attachment: fixed;
    background-image: linear-gradient(180deg, rgba(20, 71, 158, 0.07) 0%, rgba(20, 71, 158, 0) 320px);
    color: var(--cv-text);
    font-family: var(--cv-font-sans);
    min-height: 100vh;
    -webkit-font-smoothing: antialiased;
    user-select: none;
    -webkit-user-select: none;
    -webkit-touch-callout: none;
}

/* Los campos de formulario quedan exceptuados del bloqueo de selección
   de arriba -si no, no se podría ni editar lo que uno mismo escribe en
   el editor de pseudocódigo/SQL/Java o en los campos de una tabla-. */
body.campus-virtual input,
body.campus-virtual textarea,
body.campus-virtual select {
    user-select: text;
    -webkit-user-select: text;
}

body.campus-virtual img {
    -webkit-user-drag: none;
    user-drag: none;
}

h1, h2, h3, h4, .cv-brand, .cv-seal-title {
    font-family: var(--cv-font-display);
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--cv-navy);
}

/* El titular de cada página lleva un filete amarillo de lado a lado:
   es el gesto que identifica al campus de un vistazo y el que separa
   "dónde estoy" del contenido, sin necesitar una clase en cada
   plantilla -basta con que el <h2> cuelgue directo del contenedor-. */
.cv-container > h1,
.cv-container > h2,
.cv-titulo {
    font-size: 1.9rem;
    font-weight: 800;
    margin: 0 0 1.4rem;
    padding-bottom: 0.5rem;
    border-bottom: 3px solid var(--cv-accent);
}

a { color: var(--cv-primary); }

/* ===== Encabezado ===== */

.cv-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 1.75rem;
    background: var(--cv-surface);
    border-bottom: 3px solid var(--cv-accent);
    box-shadow: var(--cv-shadow-sm);
    position: sticky;
    top: 0;
    z-index: 40;
}

.cv-header a.cv-brand, .cv-header span.cv-brand {
    display: inline-flex;
    align-items: center;
    color: var(--cv-navy);
    font-weight: 800;
    font-size: 1.2rem;
    text-decoration: none;
    letter-spacing: 0.01em;
}

.cv-header a.cv-brand::before, .cv-header span.cv-brand::before {
    content: '';
    display: inline-block;
    width: 2rem;
    height: 2rem;
    margin-right: 0.6em;
    border-radius: 9px;
    background: var(--cv-navy) center / 62% no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ffd100'%3E%3Cpath d='M12 3 1 8l11 5 9-4.1V15h2V8L12 3z'/%3E%3Cpath d='M5 12.2V16c0 1.7 3.1 3 7 3s7-1.3 7-3v-3.8l-7 3.2-7-3.2z'/%3E%3C/svg%3E");
    box-shadow: var(--cv-shadow-sm);
}

/* Institución con logo propio (Institucion.logo, ver views.logo_institucion):
   se reemplaza el "birrete" genérico de arriba por la imagen real. */
.cv-header a.cv-brand--logo::before, .cv-header span.cv-brand--logo::before {
    content: none;
}
.cv-brand-img {
    display: block;
    height: 2.7rem;
    width: auto;
    max-width: 15rem;
    object-fit: contain;
}
@media (max-width: 640px) {
    .cv-brand-img { height: 2.3rem; max-width: 11rem; }
}

.cv-header .cv-user {
    color: var(--cv-text-dim);
    font-size: 0.85rem;
    font-family: var(--cv-font-sans);
    display: flex;
    align-items: center;
    gap: 0.9rem;
}

.cv-header .cv-user a {
    color: var(--cv-navy);
    text-decoration: none;
    font-weight: 600;
    transition: color var(--cv-dur-fast) var(--cv-ease-out);
}

.cv-header .cv-user a:hover { text-decoration: underline; color: var(--cv-primary); }

/* En pantalla angosta el encabezado se parte en dos filas -marca
   arriba, sesión abajo- en vez de empujar "Cerrar sesión" fuera de la
   pantalla y dejar la página con desplazamiento horizontal. */
@media (max-width: 720px) {
    .cv-header {
        flex-wrap: wrap;
        gap: 0.5rem;
        padding: 0.8rem 1rem;
    }

    .cv-header .cv-user {
        width: 100%;
        justify-content: flex-end;
        flex-wrap: wrap;
        gap: 0.75rem;
        font-size: 0.8rem;
    }
}

.cv-container {
    max-width: 900px;
    margin: 0 auto;
    padding: 2.25rem 1.5rem 4rem;
}

/* Para páginas que necesitan aprovechar todo el ancho de la pantalla
   -el simulador de red, que ya de por sí obliga a hacer zoom para que
   quepa una topología grande- en vez del ancho de lectura de 900px de
   siempre. */
.cv-container-ancho { max-width: none; padding: 1.5rem 1.25rem 3rem; }

/* ===== Tarjetas ===== */

/* Aparece con un fundido + una leve subida -no de golpe con el resto
   de la página- para que el ojo registre cada tarjeta como algo que
   "llegó", no como texto plano que ya estaba ahí. */
@keyframes cv-tarjeta-entra {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}
.cv-card {
    /* Blanco sólido sobre el fondo claro: la tarjeta se separa por
       sombra y radio, no por transparencia -sin el mesh de color
       detrás, el vidrio esmerilado solo restaba contraste al texto-. */
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 16px;
    padding: 1.4rem 1.6rem;
    margin-bottom: 1.1rem;
    box-shadow: var(--cv-shadow-sm);
    transition: transform var(--cv-dur-base) var(--cv-ease-out), box-shadow var(--cv-dur-base) var(--cv-ease-out), border-color var(--cv-dur-base) var(--cv-ease-out);
    animation: cv-tarjeta-entra var(--cv-dur-slow) var(--cv-ease-out) both;
}

.cv-card:has(> a.cv-link-block):hover {
    transform: translateY(-3px);
    box-shadow: var(--cv-shadow-md);
    border-color: #ccd4ec;
}

/* Franja de color arriba de las tarjetas "vitrina" -tema de foro,
   cualquier .cv-card cuyo contenido entero es un enlace-, no en
   tarjetas de formulario/panel: marca lo que es *navegable* sin volver
   ruidosa una pantalla de configuración. Los dos colores de la marca,
   alternando por posición -antes rotaban 4 combinaciones distintas-. */
.cv-card:has(> a.cv-link-block) {
    position: relative;
    overflow: hidden;
}
.cv-card:has(> a.cv-link-block)::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 4px;
    background: linear-gradient(90deg, var(--cv-navy), var(--cv-primary));
}
.cv-card:has(> a.cv-link-block):nth-of-type(2n)::before { background: linear-gradient(90deg, var(--cv-accent), #7dd3fc); }

.cv-card h2, .cv-card h3 { margin-top: 0; }

.cv-card a.cv-link-block {
    display: block;
    color: inherit;
    text-decoration: none;
}

.cv-card a.cv-link-block:hover h3, .cv-card a.cv-link-block:hover h2 { color: var(--cv-primary); }

/* :not(.cv-pseudo-textarea) porque ese bloque ya trae su propio fondo
   oscuro + texto claro (editor de código) -si esta regla también le
   pisara el fondo, quedaría texto claro sobre fondo claro e
   ilegible, que es justo lo que pasaba en docente_evidencia.html-.

   :not(.cv-editor-numeros):not(.cv-lineas-num) porque las regletas de números
   de línea tienen que medir EXACTAMENTE igual que su textarea: si esta regla
   les cambia el tamaño de letra, cada línea se desvía un poco y al bajar por
   un archivo largo los números dejan de coincidir con el código.

   Los :not() van dentro de :where() a propósito: cada :not(.clase) suma
   especificidad, y con tres de ellos esta regla GENÉRICA le ganaba a todas las
   reglas de bloques oscuros (pre.cv-guia-codigo, pre.cv-guia-sql, los pre del
   modo presentación, la consola resaltada…): el fondo quedaba claro con el
   texto claro encima, ilegible. :where() pesa cero, así que esta regla vale lo
   mismo que ".cv-card pre" y las específicas vuelven a ganar. */
.cv-card pre:where(:not(.cv-pseudo-textarea):not(.cv-editor-numeros):not(.cv-lineas-num)) {
    overflow-x: auto;
    background: var(--cv-surface-2);
    border: 1px solid var(--cv-border);
    border-radius: 8px;
    padding: 0.9rem 1.1rem;
    font-size: 0.85rem;
    line-height: 1.5;
}

.cv-breadcrumb {
    color: var(--cv-text-dim);
    font-size: 0.85rem;
    margin-bottom: 1.25rem;
    font-weight: 500;
}

.cv-breadcrumb a { color: var(--cv-text-dim); text-decoration: none; }
.cv-breadcrumb a:hover { color: var(--cv-primary); text-decoration: underline; }

/* ===== Progreso ===== */

.cv-progress-track {
    background: #e6eaf2;
    border-radius: 999px;
    height: 10px;
    overflow: hidden;
    margin: 0.6rem 0;
}

.cv-progress-fill {
    background: var(--cv-accent);
    height: 100%;
    border-radius: 999px;
    transition: width 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

/* ===== Insignias ===== */

.cv-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.3em;
    padding: 0.2rem 0.7rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.cv-badge-pendiente { background: #fdf1e2; color: var(--cv-warning); }
.cv-badge-progreso { background: var(--cv-primary-tint); color: var(--cv-primary); }
.cv-badge-completa { background: #e5f6ec; color: var(--cv-success); }
.cv-badge-bloqueada { background: #eef0f5; color: var(--cv-text-dim); }

/* ===== Botones ===== */

.cv-btn {
    display: inline-block;
    background: var(--cv-primary);
    color: #ffffff;
    border: none;
    border-radius: 999px;
    padding: 0.6rem 1.4rem;
    font-weight: 700;
    font-size: 0.92rem;
    cursor: pointer;
    text-decoration: none;
    box-shadow: 0 2px 6px rgba(18, 41, 79, 0.18);
    transition: transform var(--cv-dur-fast) var(--cv-ease-out), box-shadow var(--cv-dur-fast) var(--cv-ease-out), filter var(--cv-dur-fast) var(--cv-ease-out);
}

.cv-btn:hover { background: var(--cv-primary-dark); transform: translateY(-1px); box-shadow: 0 6px 16px rgba(18, 41, 79, 0.24); }

/* Variante secundaria -gris clara- para el segundo botón de un par:
   misma píldora y misma altura, sin competir con la acción principal. */
.cv-btn-suave {
    background: var(--cv-surface-2);
    color: var(--cv-navy);
    box-shadow: none;
}
.cv-btn-suave:hover { background: #e2e7f1; color: var(--cv-navy); box-shadow: none; }
/* El "press" es la retroalimentación más importante de un botón -el
   usuario necesita sentir que el clic registró ANTES de esperar el
   resultado-: por eso baja de escala de inmediato (duración más corta
   que el resto, sin esperar a que termine el hover) en vez de solo
   cancelar el translateY del hover como antes. */
.cv-btn:active { transform: scale(0.96); filter: brightness(0.96); transition-duration: 70ms; }

.cv-btn:focus-visible { outline: 2px solid var(--cv-primary); outline-offset: 2px; }

.cv-btn[disabled] { opacity: 0.5; cursor: not-allowed; transform: none; box-shadow: none; }

/* ===== Formularios ===== */

.cv-form input[type=text], .cv-form input[type=password], .cv-form textarea, .cv-form input[type=file] {
    width: 100%;
    background: var(--cv-surface);
    border: 1.5px solid var(--cv-border);
    border-radius: 9px;
    color: var(--cv-text);
    padding: 0.65rem 0.85rem;
    margin-bottom: 1rem;
    font-size: 1rem;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.cv-form input:focus, .cv-form textarea:focus {
    outline: none;
    border-color: var(--cv-primary);
    box-shadow: 0 0 0 3px var(--cv-primary-tint);
}

.cv-form label { display: block; margin-bottom: 0.35rem; color: var(--cv-text-dim); font-size: 0.85rem; font-weight: 600; }

/* Antes aparecía de golpe junto con el resto de la página -sin avisar
   que es la CONSECUENCIA de la acción que el usuario acaba de hacer
   (enviar un formulario, por ejemplo)-. Una entrada corta y con
   `--cv-ease-out` -misma curva que el resto del sitio- basta para que
   el ojo la registre como una reacción, no como contenido estático más. */
@keyframes cv-alert-entra {
    from { opacity: 0; transform: translateY(-6px); }
    to { opacity: 1; transform: translateY(0); }
}
.cv-alert {
    padding: 0.8rem 1.1rem;
    border-radius: 10px;
    margin-bottom: 1rem;
    border: 1px solid transparent;
    font-size: 0.92rem;
    animation: cv-alert-entra var(--cv-dur-slow) var(--cv-ease-out);
}

.cv-alert-error { background: #fdedee; color: var(--cv-danger); border-color: #f6d3d6; }
.cv-alert-success { background: #e9f7ef; color: var(--cv-success); border-color: #cdedd9; }
.cv-alert-info { background: var(--cv-primary-tint); color: var(--cv-primary-dark); border-color: #cfe0f7; }

/* ===== Aviso de cierre de sesión por inactividad (ver inactividad.js) ===== */
.cv-inactividad {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: rgba(9, 18, 36, 0.55);
}
.cv-inactividad[hidden] { display: none; }
.cv-inactividad-caja {
    background: #fff;
    border-radius: 14px;
    padding: 1.6rem 1.7rem;
    max-width: 380px;
    width: 100%;
    text-align: center;
    box-shadow: 0 20px 60px rgba(9, 18, 36, 0.35);
}
.cv-inactividad-caja strong { display: block; font-size: 1.1rem; color: var(--cv-navy); margin-bottom: 0.5rem; }
.cv-inactividad-caja p { margin: 0 0 1.1rem; color: var(--cv-text-dim); line-height: 1.6; }
.cv-inactividad-caja #cv-inactividad-cuenta { font-weight: 700; color: var(--cv-navy); }

/* ===== Login ===== */

.cv-login-wrap {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background:
        radial-gradient(1100px 520px at 18% 6%, rgba(20, 71, 158, 0.13), transparent 62%),
        radial-gradient(900px 460px at 88% 92%, rgba(255, 209, 0, 0.16), transparent 58%),
        var(--cv-bg);
}

.cv-login-box {
    width: 100%;
    max-width: 380px;
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 18px;
    border-top: 5px solid var(--cv-accent);
    padding: 2.5rem 2.25rem;
    box-shadow: var(--cv-shadow-lift);
}

.cv-login-box h2 {
    display: flex;
    align-items: center;
    font-size: 1.4rem;
}

.cv-login-box h2::before {
    content: '';
    display: inline-block;
    width: 2rem;
    height: 2rem;
    margin-right: 0.7rem;
    border-radius: 9px;
    background: var(--cv-navy) center / 62% no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ffd100'%3E%3Cpath d='M12 3 1 8l11 5 9-4.1V15h2V8L12 3z'/%3E%3Cpath d='M5 12.2V16c0 1.7 3.1 3 7 3s7-1.3 7-3v-3.8l-7 3.2-7-3.2z'/%3E%3C/svg%3E");
    box-shadow: var(--cv-shadow-sm);
}

/* ===== Simulación (árbol de decisiones) ===== */

.cv-sim-nodo {
    background: var(--cv-surface-2);
    border: 1px solid var(--cv-border);
    border-radius: 12px;
    padding: 1.5rem;
    margin: 1rem 0;
    line-height: 1.6;
}

.cv-sim-opcion {
    display: block;
    width: 100%;
    text-align: left;
    background: var(--cv-surface);
    border: 1.5px solid var(--cv-border);
    color: var(--cv-text);
    border-radius: 9px;
    padding: 0.8rem 1.1rem;
    margin-bottom: 0.6rem;
    cursor: pointer;
    font-size: 0.95rem;
    transition: border-color 0.15s ease, background 0.15s ease, transform 0.1s ease;
}

.cv-sim-opcion:hover { border-color: var(--cv-primary); background: var(--cv-primary-tint); color: var(--cv-primary-dark); transform: translateX(2px); }

.cv-sim-vars {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
    font-size: 0.85rem;
    color: var(--cv-text-dim);
}

/* ===== Lecturas ilustradas ===== */

.cv-lectura-contenido h3 { margin-top: 1.75rem; }
.cv-lectura-contenido p { line-height: 1.7; }
.cv-lectura-contenido img {
    max-width: 100%;
    border-radius: 12px;
    background: #fff;
    margin: 1.25rem 0;
    display: block;
    border: 1px solid var(--cv-border);
    box-shadow: var(--cv-shadow-sm);
}
.cv-lectura-contenido ul, .cv-lectura-contenido ol { line-height: 1.8; padding-left: 1.3rem; }

/* ===== Lectura en modo presentación (diapositivas) ===== */

.cv-deck {
    --deck-min: 460px;
    border: 1px solid var(--cv-border);
    border-radius: 16px;
    background: var(--cv-surface);
    box-shadow: var(--cv-shadow-md);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.cv-deck-progreso {
    height: 4px;
    background: var(--cv-surface-2);
    flex: 0 0 auto;
}
.cv-deck-progreso-fill {
    height: 100%;
    width: 0;
    background: linear-gradient(90deg, var(--cv-primary), var(--cv-cyan));
    transition: width .35s var(--cv-ease-out);
}

.cv-deck-stage {
    position: relative;
    flex: 1 1 auto;
}

/* Cada diapositiva fluye a su altura natural y es la página la que hace
   scroll: antes iban en un panel fijo de 460px con scroll interno, y las
   diapositivas largas se veían "cortadas" (parecía que faltaba texto). */
.cv-slide {
    padding: 2.4rem clamp(1.4rem, 4vw, 3.6rem);
}
.cv-slide:not(.cv-slide-activa) {
    display: none;
}
.cv-slide.cv-slide-activa {
    animation: cv-slide-in .3s var(--cv-ease-out);
}
@keyframes cv-slide-in {
    from { opacity: 0; transform: translateX(18px); }
    to   { opacity: 1; transform: none; }
}

.cv-slide-kicker {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    font-family: var(--cv-font-display);
    font-size: 0.72rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--cv-text-dim);
    border-bottom: 1px solid var(--cv-border);
    padding-bottom: 0.7rem;
    margin-bottom: 1.4rem;
}
.cv-slide-num {
    color: var(--cv-primary);
    font-weight: 700;
    letter-spacing: .05em;
}

.cv-slide > h3 {
    font-family: var(--cv-font-display);
    font-size: clamp(1.35rem, 2.6vw, 2rem);
    line-height: 1.2;
    color: var(--cv-navy);
    margin: 0 0 1.1rem;
}
.cv-slide-cuerpo { font-size: clamp(1rem, 1.5vw, 1.12rem); }
.cv-slide-cuerpo p { line-height: 1.75; margin: 0 0 1rem; }
.cv-slide-cuerpo ul, .cv-slide-cuerpo ol { line-height: 1.85; }
.cv-slide-cuerpo li { margin-bottom: 0.35rem; }
/* La tarjeta de la lectura envuelve el mazo, y ".cv-card pre:not(.cv-pseudo-textarea)"
   -fondo claro- empataba/ganaba en especificidad a ".cv-slide-cuerpo pre" y dejaba
   el código con texto claro sobre fondo claro. Se sube la especificidad con
   ".cv-card .cv-deck" para ganarle sin depender del orden de las reglas. */
.cv-card .cv-deck .cv-slide-cuerpo pre {
    background: var(--cv-navy);
    color: #eaf1ff;
    border: 0;
    padding: 1rem 1.2rem;
    border-radius: 10px;
    overflow-x: auto;
    font-size: 0.95rem;
    line-height: 1.55;
}
.cv-slide-cuerpo code {
    background: var(--cv-primary-tint);
    color: var(--cv-primary-dark);
    padding: 0.05em 0.4em;
    border-radius: 5px;
    font-size: 0.92em;
}
.cv-card .cv-deck .cv-slide-cuerpo pre code { background: none; color: inherit; padding: 0; }

.cv-deck-bar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.8rem;
    padding: 0.8rem 1rem;
    background: var(--cv-surface-2);
    border-top: 1px solid var(--cv-border);
    flex: 0 0 auto;
}
.cv-deck-btn {
    font-family: var(--cv-font-display);
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--cv-primary-dark);
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 9px;
    padding: 0.5rem 0.95rem;
    cursor: pointer;
    transition: background .15s, box-shadow .15s, transform .1s;
}
.cv-deck-btn:hover:not(:disabled) { background: var(--cv-primary-tint); box-shadow: var(--cv-shadow-sm); }
.cv-deck-btn:active:not(:disabled) { transform: translateY(1px); }
.cv-deck-btn:disabled { opacity: 0.4; cursor: default; }
.cv-deck-btn-full { padding: 0.5rem 0.75rem; font-size: 1.05rem; line-height: 1; }
.cv-deck-contador {
    font-family: var(--cv-font-display);
    font-weight: 700;
    color: var(--cv-text-dim);
    min-width: 4.5rem;
    text-align: center;
}

/* Pantalla completa */
.cv-deck-full { border: none; border-radius: 0; }
.cv-deck-full .cv-deck-stage { overflow-y: auto; }
.cv-deck-full .cv-slide { padding: clamp(2rem, 6vh, 5rem) clamp(2rem, 10vw, 9rem); }
.cv-deck-full .cv-slide > h3 { font-size: clamp(1.8rem, 4vw, 3rem); }
.cv-deck-full .cv-slide-cuerpo { font-size: clamp(1.15rem, 2vw, 1.5rem); }

@media (max-width: 640px) {
    .cv-slide { padding: 1.6rem 1.2rem; }
    .cv-deck-btn { padding: 0.5rem 0.7rem; font-size: 0.8rem; }
}

/* ===== Videolección (lectura narrada con voz) ===== */

.cv-videolec { margin: 0 0 1.1rem; }

.cv-videolec-cta {
    display: flex;
    align-items: center;
    gap: 0.55rem 0.8rem;
    flex-wrap: wrap;
    width: 100%;
    text-align: left;
    padding: 0.85rem 1.1rem;
    border: 1px solid var(--cv-primary);
    border-radius: 12px;
    background: linear-gradient(100deg, var(--cv-primary-tint), var(--cv-surface));
    color: var(--cv-primary-dark);
    font-family: var(--cv-font-display);
    font-weight: 700;
    font-size: 0.98rem;
    cursor: pointer;
    transition: box-shadow .15s, transform .1s;
}
.cv-videolec-cta:hover { box-shadow: var(--cv-shadow-sm); }
.cv-videolec-cta:active { transform: translateY(1px); }
.cv-videolec-cta[hidden] { display: none; }
.cv-videolec-cta .cv-videolec-ico {
    display: inline-grid;
    place-items: center;
    width: 1.9rem;
    height: 1.9rem;
    border-radius: 50%;
    background: var(--cv-primary);
    color: #fff;
    font-size: 0.9rem;
}
.cv-videolec-cta small {
    flex: 1 1 100%;
    font-family: var(--cv-font-body, inherit);
    font-weight: 500;
    font-size: 0.82rem;
    color: var(--cv-text-dim);
}
.cv-videolec-cta-sinvoz { border-color: var(--cv-border); background: var(--cv-surface-2); color: var(--cv-navy); }

.cv-videolec-panel {
    border: 1px solid var(--cv-border);
    border-radius: 12px;
    background: var(--cv-surface-2);
    padding: 0.7rem 0.85rem;
}
.cv-videolec-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}
.cv-videolec-btn {
    font-family: var(--cv-font-display);
    font-size: 0.83rem;
    font-weight: 600;
    color: var(--cv-primary-dark);
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 9px;
    padding: 0.45rem 0.8rem;
    cursor: pointer;
    transition: background .15s;
}
.cv-videolec-btn:hover { background: var(--cv-primary-tint); }
.cv-videolec-btn-play { min-width: 7.5rem; }
.cv-videolec-sel {
    font-size: 0.82rem;
    padding: 0.4rem 0.5rem;
    border: 1px solid var(--cv-border);
    border-radius: 8px;
    background: var(--cv-surface);
    color: var(--cv-text);
    max-width: 13rem;
}
.cv-videolec-aviso {
    margin: 0.5rem 0 0;
    font-size: 0.82rem;
    color: var(--cv-text-dim);
}
.cv-videolec-guion {
    margin-top: 0.5rem;
    font-family: var(--cv-font-display);
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--cv-primary-dark);
    background: none;
    border: 0;
    padding: 0.3rem 0;
    cursor: pointer;
    text-decoration: underline;
}
.cv-videolec-guion-activo { color: var(--cv-navy); }

/* Subtítulos flotantes tipo video */
.cv-videolec-sub {
    position: fixed;
    left: 50%;
    bottom: clamp(0.8rem, 4vh, 2.2rem);
    transform: translateX(-50%);
    z-index: 60;
    max-width: min(48rem, 92vw);
    padding: 0.6rem 1.1rem;
    border-radius: 10px;
    background: rgba(12, 20, 33, 0.92);
    color: #f4f7ff;
    font-size: clamp(0.95rem, 2.4vw, 1.18rem);
    line-height: 1.5;
    text-align: center;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
}

/* Guion escrito revelado bajo el título de la diapositiva */
.cv-locucion { display: none; }
.cv-locucion.cv-locucion-visible {
    display: block;
    margin: 0 0 1rem;
    padding: 0.7rem 0.9rem;
    border-left: 3px solid var(--cv-primary);
    border-radius: 0 8px 8px 0;
    background: var(--cv-primary-tint);
    color: var(--cv-primary-dark);
    font-size: 0.95rem;
    line-height: 1.6;
}
.cv-locucion.cv-locucion-visible::before {
    content: "Narración";
    display: block;
    font-family: var(--cv-font-display);
    font-size: 0.68rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    opacity: 0.75;
    margin-bottom: 0.2rem;
}

@media (max-width: 640px) {
    .cv-videolec-btn-play { min-width: 0; }
}

/* ===== Interactivos de matemáticas (.cv-mate) ===== */

.cv-mate {
    border: 1px solid var(--cv-border);
    border-left: 4px solid var(--cv-primary);
    border-radius: 12px;
    background: var(--cv-surface);
    padding: 1rem 1.1rem 1.15rem;
    margin: 1.25rem 0;
}
.cv-slide-cuerpo .cv-mate { background: var(--cv-surface-2); }
.cv-mate-meta, .cv-mate-preg { margin: 0 0 0.8rem; font-weight: 600; color: var(--cv-navy); }
.cv-mate-preg { font-weight: 500; }

.cv-mate-btn {
    font-family: var(--cv-font-display);
    font-size: 0.9rem; font-weight: 700;
    color: #fff; background: var(--cv-primary);
    border: 0; border-radius: 10px;
    padding: 0.55rem 1.1rem; margin-top: 0.9rem; cursor: pointer;
}
.cv-mate-btn:hover { background: var(--cv-primary-dark); }
.cv-mate-btn-suave { background: var(--cv-surface); color: var(--cv-primary-dark); border: 1px solid var(--cv-border); margin-left: 0.5rem; }

.cv-mate-fb { margin: 0.9rem 0 0; padding: 0.55rem 0.8rem; border-radius: 9px; font-weight: 600; font-size: 0.92rem; }
.cv-mate-ok { background: color-mix(in srgb, var(--cv-success) 14%, #fff); color: var(--cv-success); }
.cv-mate-mal { background: color-mix(in srgb, var(--cv-danger) 12%, #fff); color: var(--cv-danger); }

/* vp: valor posicional */
.cv-mate-vp { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.cv-mate-vp-col {
    flex: 1 1 4.2rem; min-width: 4.2rem;
    display: flex; flex-direction: column; align-items: center; gap: 0.25rem;
    border: 1px solid var(--cv-border); border-radius: 10px;
    padding: 0.5rem 0.3rem; background: var(--cv-surface);
}
.cv-mate-vp-k { font-family: var(--cv-font-display); font-weight: 800; font-size: 0.78rem; letter-spacing: .05em; color: var(--cv-primary); }
.cv-mate-vp-b {
    width: 1.8rem; height: 1.8rem; border-radius: 8px; border: 1px solid var(--cv-border);
    background: var(--cv-surface-2); color: var(--cv-navy); font-size: 1.1rem; font-weight: 700; cursor: pointer; line-height: 1;
}
.cv-mate-vp-b:hover { background: var(--cv-primary-tint); }
.cv-mate-vp-d { font-family: var(--cv-font-display); font-weight: 800; font-size: 1.5rem; color: var(--cv-navy); }
.cv-mate-vp-blk { font-size: 0.7rem; color: var(--cv-primary); word-break: break-all; line-height: 1; min-height: 1rem; text-align: center; }
.cv-mate-vp-num { margin: 1rem 0 0.2rem; font-size: 1.15rem; }
.cv-mate-vp-num strong { font-size: 1.3rem; color: var(--cv-navy); }
.cv-mate-vp-exp { margin: 0.2rem 0; color: var(--cv-primary-dark); font-family: var(--cv-font-mono, monospace); font-size: 0.92rem; }
.cv-mate-vp-lee { margin: 0.2rem 0 0; color: var(--cv-text-dim); font-style: italic; }

/* opcion */
.cv-mate-ops { display: flex; flex-direction: column; gap: 0.45rem; }
.cv-mate-op {
    text-align: left; font: inherit; font-size: 0.95rem;
    padding: 0.6rem 0.85rem; border: 1.5px solid var(--cv-border); border-radius: 10px;
    background: var(--cv-surface); color: var(--cv-text); cursor: pointer;
}
.cv-mate-op:hover:not(:disabled) { border-color: var(--cv-primary); background: var(--cv-primary-tint); }
.cv-mate-op-ok { border-color: var(--cv-success) !important; background: color-mix(in srgb, var(--cv-success) 14%, #fff) !important; color: var(--cv-success) !important; font-weight: 700; }
.cv-mate-op-mal { border-color: var(--cv-danger) !important; background: color-mix(in srgb, var(--cv-danger) 10%, #fff) !important; color: var(--cv-danger) !important; }

/* comparar */
.cv-mate-cmp { display: flex; align-items: center; gap: 0.5rem; margin: 0.5rem 0; flex-wrap: wrap; }
.cv-mate-cmp-n { font-family: var(--cv-font-display); font-weight: 800; font-size: 1.2rem; color: var(--cv-navy); min-width: 4.5rem; text-align: center; }
.cv-mate-cmp-b {
    width: 2.3rem; height: 2.3rem; border-radius: 9px; border: 1.5px solid var(--cv-border);
    background: var(--cv-surface); font-size: 1.15rem; font-weight: 800; color: var(--cv-primary-dark); cursor: pointer;
}
.cv-mate-cmp-b:hover { background: var(--cv-primary-tint); }

/* construir / secuencia / calcula inputs */
.cv-mate-calc { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin: 0.4rem 0; }

/* division: cociente + residuo */
.cv-mate-div { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin: 0.4rem 0; }
.cv-mate-div-lbl { color: var(--cv-text-dim); font-size: 0.9rem; }
.cv-mate-div-r { width: 3.4rem; }

/* proporcion: tabla de variación */
.cv-mate-prop { border-collapse: collapse; margin: 0.5rem 0; }
.cv-mate-prop td, .cv-mate-prop th { border: 1px solid var(--cv-border); padding: 0.3rem 0.55rem; text-align: center; min-width: 3rem; }
.cv-mate-prop-h { background: var(--cv-primary-tint); color: var(--cv-primary-dark); font-family: var(--cv-font-display); font-weight: 800; }
.cv-mate-prop-n { font-family: var(--cv-font-display); font-weight: 700; color: var(--cv-navy); }
.cv-mate-prop .cv-mate-eq-in { width: 3.4rem; }
.cv-mate-eq, .cv-mate-seq { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.cv-mate-eq-n, .cv-mate-seq-n { font-family: var(--cv-font-display); font-weight: 800; color: var(--cv-navy); font-size: 1.05rem; }
.cv-mate-eq-op, .cv-mate-seq-fl { color: var(--cv-text-dim); font-weight: 700; }
.cv-mate-eq-in, .cv-mate-seq-in {
    width: 5.5rem; font: inherit; font-weight: 700; text-align: center;
    padding: 0.4rem 0.3rem; border: 1.5px solid var(--cv-border); border-radius: 8px; background: var(--cv-surface); color: var(--cv-navy);
}
.cv-mate-seq-in { width: 4.5rem; }
.cv-mate-eq-ok { border-color: var(--cv-success); background: color-mix(in srgb, var(--cv-success) 12%, #fff); }
.cv-mate-eq-mal { border-color: var(--cv-danger); background: color-mix(in srgb, var(--cv-danger) 10%, #fff); }

/* columna: operación en vertical (filas y columnas + llevadas) */
.cv-col { overflow-x: auto; margin: 0.7rem 0; }
.cv-col + .cv-col { margin-top: 1.1rem; }
.cv-col-grid {
    display: grid;
    grid-template-columns: 1.3rem repeat(var(--n, 3), 2rem);
    gap: 3px;
    width: max-content;
}
.cv-col-c {
    display: flex; align-items: center; justify-content: center;
    height: 2rem;
    font-family: var(--cv-font-display, monospace);
    font-size: 1.05rem; font-weight: 700;
}
.cv-col-sign { color: var(--cv-text-dim); }
.cv-col-d { color: var(--cv-navy); }
.cv-col-in {
    width: 2rem; height: 2rem; padding: 0;
    text-align: center; font: inherit; font-weight: 800;
    border: 1.5px solid var(--cv-border); border-radius: 7px;
    background: var(--cv-surface); color: var(--cv-navy);
}
.cv-col-llev {
    width: 1.5rem; height: 1.5rem;
    font-size: 0.8rem; color: var(--cv-primary-dark);
    border-style: dashed; align-self: start;
}
.cv-col-rule {
    grid-column: 1 / -1;
    height: 0; border-top: 2px solid var(--cv-navy);
    margin: 3px 0;
}
.cv-col-ok {
    border-color: var(--cv-success) !important;
    background: color-mix(in srgb, var(--cv-success) 16%, #fff) !important;
    color: var(--cv-success) !important;
}
.cv-col-mal {
    border-color: var(--cv-danger) !important;
    background: color-mix(in srgb, var(--cv-danger) 12%, #fff) !important;
    color: var(--cv-danger) !important;
}
/* multiplicación: posición vacía del producto parcial y casilla del parcial */
.cv-col-pt { color: var(--cv-text-dim); }
.cv-col-par { border-style: dashed; }

/* división larga tipo GALERA (caja) — estructura tradicional de primaria */
.cv-div-wrap { overflow-x: auto; margin: 0.9rem 0; }
.cv-div-titulo { margin: 0 0 0.4rem; font-family: var(--cv-font-display); font-weight: 800; color: var(--cv-navy); }
.cv-gal { display: inline-flex; align-items: flex-start; min-width: max-content; font-family: var(--cv-font-mono, monospace); }
.cv-gal-grid { display: grid; grid-auto-rows: 2rem; align-items: center; }
.cv-gal-c {
    display: flex; align-items: center; justify-content: center;
    font-family: var(--cv-font-display); font-weight: 800; font-size: 1.05rem; color: var(--cv-navy);
}
.cv-gal-sig { color: var(--cv-danger); }
.cv-gal-baja { color: var(--cv-text-dim); }
.cv-gal-in {
    width: 1.5rem; height: 1.8rem; padding: 0;
    text-align: center; font: inherit;
    font-family: var(--cv-font-display); font-weight: 800; font-size: 1rem;
    border: 1.5px solid var(--cv-border); border-radius: 6px;
    background: var(--cv-surface); color: var(--cv-navy);
}
.cv-gal-prod { border: 0; border-bottom: 2px solid var(--cv-navy); border-radius: 0; }
.cv-gal-der {
    border-left: 2px solid var(--cv-navy);
    padding: 0 0.4rem 0 0.6rem; margin-left: 0.3rem;
    align-self: stretch;
}
.cv-gal-dv {
    font-family: var(--cv-font-display); font-weight: 800; font-size: 1.05rem; color: var(--cv-navy);
    border-bottom: 2px solid var(--cv-navy);
    padding-bottom: 0.25rem; min-height: 2rem;
    display: flex; align-items: center; justify-content: center;
}
.cv-gal-coc { display: flex; gap: 0.15rem; padding-top: 0.35rem; justify-content: center; }

/* fracciones: fraccion / equivale / fracoper */
.cv-frac-fig { margin: 0.4rem 0; }
.cv-frac-fig svg [data-p]:hover { filter: brightness(0.94); }
.cv-frac-in { display: flex; justify-content: center; margin: 0.4rem 0; }
.cv-frac-chip, .cv-frac-barra {
    display: inline-flex; flex-direction: column; align-items: center;
    font-family: var(--cv-font-display); font-weight: 800;
}
.cv-frac-num, .cv-frac-den {
    color: var(--cv-navy); font-size: 1.15rem; min-width: 1.6rem; text-align: center;
    padding: 0.05rem 0.3rem;
}
.cv-frac-linea { display: block; width: 100%; min-width: 1.8rem; height: 2px; background: var(--cv-navy); margin: 2px 0; }
.cv-frac-hueco { width: 2.6rem; margin: 1px 0; }
.cv-frac-eq { display: flex; align-items: center; justify-content: center; gap: 0.55rem; flex-wrap: wrap; margin: 0.5rem 0; }
.cv-frac-igual { font-family: var(--cv-font-display); font-weight: 800; font-size: 1.25rem; color: var(--cv-text-dim); }

/* decimal: cuadrícula 10×10 + casilla */
.cv-dec-item { margin: 0.6rem 0; padding: 0.4rem; border: 1px dashed var(--cv-border); border-radius: 10px; }
.cv-dec-item .cv-mate-calc { justify-content: center; margin-top: 0.3rem; }

/* probabilidad: clasificar el suceso + escribir la fracción */
.cv-prob-fila { border: 1px solid var(--cv-border); border-radius: 10px; padding: 0.6rem 0.7rem; margin: 0.5rem 0; background: var(--cv-surface); }
.cv-prob-txt { margin: 0 0 0.5rem; font-weight: 600; color: var(--cv-navy); }
.cv-prob-w-wrap { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 0.5rem; }
.cv-prob-w {
    font: inherit; font-size: 0.88rem; font-weight: 700;
    padding: 0.35rem 0.7rem; border: 1.5px solid var(--cv-border); border-radius: 999px;
    background: var(--cv-surface); color: var(--cv-text); cursor: pointer;
}
.cv-prob-w:hover { border-color: var(--cv-primary); background: var(--cv-primary-tint); }
.cv-prob-w-on { border-color: var(--cv-primary) !important; background: var(--cv-primary-tint) !important; color: var(--cv-primary-dark) !important; }
.cv-prob-p { display: flex; align-items: center; gap: 0.5rem; }
.cv-prob-lbl { font-family: var(--cv-font-display); font-weight: 800; color: var(--cv-navy); }

/* experimento: simulador de un experimento aleatorio */
.cv-exp-vis { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; margin: 0.4rem 0; }
.cv-exp-svg { max-width: 260px; width: auto; height: 3rem; }
.cv-exp-ultimo { font-weight: 700; color: var(--cv-primary-dark); }
.cv-exp-ctr { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.5rem 0 0.2rem; }
.cv-exp-ctr .cv-mate-btn { margin-top: 0; }
.cv-exp-tabla { border-collapse: collapse; margin: 0.7rem 0; font-size: 0.9rem; width: 100%; max-width: 22rem; }
.cv-exp-tabla th, .cv-exp-tabla td { border: 1px solid var(--cv-border); padding: 0.3rem 0.55rem; text-align: center; }
.cv-exp-tabla th { background: var(--cv-primary-tint); color: var(--cv-primary-dark); font-family: var(--cv-font-display); font-weight: 800; }
.cv-exp-tabla td:first-child { text-align: left; font-weight: 700; color: var(--cv-navy); }
.cv-exp-fav td { background: color-mix(in srgb, var(--cv-accent) 14%, #fff); }
.cv-exp-tot td { font-weight: 800; background: var(--cv-surface-2); }
.cv-exp-comp { margin: 0.4rem 0; }
.cv-exp-comp p { margin: 0 0 0.3rem; font-weight: 600; color: var(--cv-navy); }
.cv-exp-bar { display: grid; grid-template-columns: 4.5rem 1fr auto; align-items: center; gap: 0.5rem; margin: 0.25rem 0; font-size: 0.85rem; }
.cv-exp-bar > span { color: var(--cv-text-dim); }
.cv-exp-bar > i { height: 0.7rem; border-radius: 999px; background: var(--cv-primary); display: block; min-width: 2px; }
.cv-exp-bar-obs > i { background: var(--cv-accent); }
.cv-exp-bar > b { font-family: var(--cv-font-display); color: var(--cv-navy); white-space: nowrap; }

/* volumen: simulador de cubos unidad */
.cv-vol-fig { margin: 0.3rem 0; }
.cv-vol-ctr { display: flex; flex-wrap: wrap; gap: 0.5rem 0.9rem; margin: 0.4rem 0; }
.cv-vol-step { display: flex; align-items: center; gap: 0.35rem; }
.cv-vol-lbl { font-family: var(--cv-font-display); font-weight: 800; color: var(--cv-navy); font-size: 0.85rem; min-width: 3rem; }
.cv-vol-b { width: 1.9rem; height: 1.9rem; border-radius: 8px; border: 1.5px solid var(--cv-border); background: var(--cv-surface-2); color: var(--cv-navy); font-size: 1.05rem; font-weight: 800; cursor: pointer; line-height: 1; }
.cv-vol-b:hover { background: var(--cv-primary-tint); }
.cv-vol-v { font-family: var(--cv-font-display); font-weight: 800; font-size: 1.15rem; color: var(--cv-navy); min-width: 1.1rem; text-align: center; }
.cv-vol-out { margin: 0.4rem 0 0; font-size: 1.02rem; color: var(--cv-primary-dark); }
.cv-vol-out strong { color: var(--cv-navy); }

/* transportador: ángulo interactivo */
.cv-transp-box { margin: 0.3rem 0; cursor: grab; }
.cv-transp-box:active { cursor: grabbing; }
.cv-transp-lect { margin: 0.3rem 0 0; font-size: 1.05rem; color: var(--cv-text-dim); }
.cv-transp-lect strong { font-family: var(--cv-font-display); font-size: 1.4rem; color: var(--cv-navy); }

/* ===== Ejercicios de inglés (.cv-lang) — estilo Duolingo ===== */
.cv-lang {
    border: 1px solid var(--cv-border);
    border-left: 4px solid var(--cv-accent);
    border-radius: 12px;
    background: var(--cv-surface);
    padding: 1rem 1.1rem 1.15rem;
    margin: 1.25rem 0;
}
.cv-slide-cuerpo .cv-lang { background: var(--cv-surface-2); }
.cv-lang-preg { margin: 0 0 0.7rem; font-weight: 600; color: var(--cv-navy); }
.cv-lang-cab { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.7rem; flex-wrap: wrap; }
.cv-lang-cab .cv-lang-preg { margin: 0; }

.cv-lang-audio {
    flex: 0 0 auto;
    width: 2.4rem; height: 2.4rem; border-radius: 50%;
    border: 0; background: var(--cv-accent); color: #fff;
    font-size: 1.1rem; cursor: pointer; line-height: 1;
}
.cv-lang-audio:hover { filter: brightness(1.06); }
.cv-lang-audio-g { width: 3rem; height: 3rem; font-size: 1.35rem; box-shadow: 0 3px 0 color-mix(in srgb, var(--cv-accent) 60%, #000); }
.cv-lang-audio-on { animation: cv-lang-pulso 0.9s ease-in-out infinite; }
@keyframes cv-lang-pulso {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--cv-accent) 55%, transparent); }
    50% { box-shadow: 0 0 0 8px color-mix(in srgb, var(--cv-accent) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) { .cv-lang-audio-on { animation: none; filter: brightness(1.12); } }
.cv-lang-mini {
    font: inherit; font-size: 0.82rem; font-weight: 700;
    padding: 0.3rem 0.7rem; border-radius: 999px; cursor: pointer;
    border: 1.5px solid var(--cv-border); background: var(--cv-surface); color: var(--cv-text-dim);
    margin-top: 0.5rem;
}
.cv-lang-btn {
    font-family: var(--cv-font-display); font-size: 0.9rem; font-weight: 800;
    color: #fff; background: var(--cv-primary); border: 0; border-radius: 10px;
    padding: 0.55rem 1.3rem; margin-top: 0.9rem; cursor: pointer;
    box-shadow: 0 3px 0 var(--cv-primary-dark);
}
.cv-lang-fb { margin: 0.9rem 0 0; padding: 0.55rem 0.8rem; border-radius: 9px; font-weight: 600; font-size: 0.92rem; }
.cv-lang-ok { background: color-mix(in srgb, var(--cv-success) 14%, #fff); color: var(--cv-success); }
.cv-lang-mal { background: color-mix(in srgb, var(--cv-danger) 12%, #fff); color: var(--cv-danger); }

/* audio: frase con traducción */
.cv-lang-frase { display: flex; align-items: center; gap: 0.8rem; }
.cv-lang-frase-txt { display: flex; flex-direction: column; }
.cv-lang-en { font-size: 1.25rem; font-weight: 800; color: var(--cv-navy); }
.cv-lang-es { font-size: 0.92rem; color: var(--cv-text-dim); font-style: italic; }

/* vocab: tarjetas */
.cv-lang-vocab { display: grid; grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr)); gap: 0.6rem; }
.cv-lang-vcard {
    display: flex; flex-direction: column; align-items: center; gap: 0.15rem;
    padding: 0.7rem 0.4rem 0.55rem; cursor: pointer;
    border: 2px solid var(--cv-border); border-radius: 14px; background: var(--cv-surface);
    box-shadow: 0 3px 0 var(--cv-border);
}
.cv-lang-vcard:hover { border-color: var(--cv-accent); }
.cv-lang-vemoji { font-size: 2rem; line-height: 1.1; }
.cv-lang-ven { font-weight: 800; color: var(--cv-navy); font-size: 0.98rem; text-align: center; }
.cv-lang-ves { font-size: 0.78rem; color: var(--cv-text-dim); text-align: center; }
.cv-lang-vspk { font-size: 0.85rem; opacity: 0.6; }

/* opciones */
.cv-lang-ops { display: flex; flex-direction: column; gap: 0.5rem; }
.cv-lang-ops-img { flex-direction: row; flex-wrap: wrap; }
.cv-lang-op {
    text-align: left; font: inherit; font-size: 1rem; font-weight: 600;
    padding: 0.7rem 0.95rem; border: 2px solid var(--cv-border); border-radius: 12px;
    background: var(--cv-surface); color: var(--cv-text); cursor: pointer;
    box-shadow: 0 3px 0 var(--cv-border);
}
.cv-lang-op:hover:not(:disabled) { border-color: var(--cv-accent); background: color-mix(in srgb, var(--cv-accent) 8%, #fff); }
.cv-lang-op-img { flex: 0 0 auto; width: 5.5rem; text-align: center; font-size: 2.2rem; padding: 0.6rem; }
.cv-lang-op-ok { border-color: var(--cv-success) !important; background: color-mix(in srgb, var(--cv-success) 14%, #fff) !important; color: var(--cv-success) !important; font-weight: 800; }
.cv-lang-op-mal { border-color: var(--cv-danger) !important; background: color-mix(in srgb, var(--cv-danger) 10%, #fff) !important; color: var(--cv-danger) !important; }

/* parea: dos columnas */
.cv-lang-parea { display: flex; gap: 1.2rem; justify-content: center; }
.cv-lang-pcol { display: flex; flex-direction: column; gap: 0.5rem; flex: 1 1 0; max-width: 12rem; }
.cv-lang-pchip {
    font: inherit; font-weight: 700; font-size: 0.95rem;
    padding: 0.6rem 0.7rem; border: 2px solid var(--cv-border); border-radius: 10px;
    background: var(--cv-surface); color: var(--cv-text); cursor: pointer;
}
.cv-lang-pchip-sel { border-color: var(--cv-primary); background: var(--cv-primary-tint); }
.cv-lang-pchip-ok { border-color: var(--cv-success) !important; background: color-mix(in srgb, var(--cv-success) 14%, #fff) !important; color: var(--cv-success) !important; cursor: default; }
.cv-lang-pchip-mal { border-color: var(--cv-danger) !important; background: color-mix(in srgb, var(--cv-danger) 10%, #fff) !important; }

/* banco: armar la frase */
.cv-lang-linea {
    min-height: 3rem; display: flex; flex-wrap: wrap; gap: 0.4rem; align-content: flex-start;
    border-bottom: 2px solid var(--cv-border); padding: 0.4rem 0 0.8rem; margin-bottom: 0.8rem;
}
.cv-lang-banco { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.cv-lang-tile {
    font: inherit; font-weight: 700; font-size: 0.98rem;
    padding: 0.5rem 0.8rem; border: 2px solid var(--cv-border); border-radius: 10px;
    background: var(--cv-surface); color: var(--cv-navy); cursor: pointer;
    box-shadow: 0 3px 0 var(--cv-border);
}
.cv-lang-tile:disabled { opacity: 0.25; box-shadow: none; }
.cv-lang-tile-on { background: var(--cv-primary-tint); border-color: var(--cv-primary); box-shadow: 0 3px 0 var(--cv-primary); }

/* completa: hueco */
.cv-lang-hueco { font-size: 1.15rem; font-weight: 600; color: var(--cv-navy); margin: 0.3rem 0 0.9rem; line-height: 1.9; }
.cv-lang-gap { display: inline-block; min-width: 4rem; text-align: center; border-bottom: 3px solid var(--cv-accent); font-weight: 800; padding: 0 0.3rem; color: var(--cv-text-dim); }
.cv-lang-gap-ok { color: var(--cv-success); border-color: var(--cv-success); }

/* dialogo */
.cv-lang-dialogo { display: flex; flex-direction: column; gap: 0.6rem; }
.cv-lang-turno { display: flex; align-items: flex-start; gap: 0.5rem; flex-wrap: wrap; padding: 0.6rem 0.8rem; border-radius: 14px 14px 14px 4px; background: var(--cv-surface); border: 1.5px solid var(--cv-border); max-width: 85%; }
.cv-lang-turno-tu { align-self: flex-end; border-radius: 14px 14px 4px 14px; background: var(--cv-primary-tint); border-color: var(--cv-primary); flex-direction: column; align-items: stretch; }
.cv-lang-quien { font-weight: 900; color: var(--cv-accent); font-size: 0.8rem; }
.cv-lang-btxt { font-weight: 600; color: var(--cv-navy); }
.cv-lang-say { border: 0; background: none; cursor: pointer; font-size: 0.95rem; padding: 0; }
.cv-lang-dop { text-align: left; font: inherit; font-weight: 700; padding: 0.5rem 0.7rem; border: 2px solid var(--cv-primary); border-radius: 10px; background: var(--cv-surface); color: var(--cv-navy); cursor: pointer; margin-top: 0.3rem; }
.cv-lang-turno-hecho { background: color-mix(in srgb, var(--cv-success) 12%, #fff); border-color: var(--cv-success); }

/* ===== Laboratorios de Ciencias Sociales (.cv-soc) ===== */
.cv-soc {
    border: 1px solid var(--cv-border);
    border-left: 4px solid var(--kid-mint, var(--cv-primary));
    border-radius: 12px;
    background: var(--cv-surface);
    padding: 1rem 1.1rem 1.15rem;
    margin: 1.25rem 0;
}
.cv-slide-cuerpo .cv-soc { background: var(--cv-surface-2); }
.cv-soc-preg { margin: 0 0 0.7rem; font-weight: 600; color: var(--cv-navy); }
.cv-soc-nota { margin: 0.6rem 0 0; font-size: 0.85rem; color: var(--cv-text-dim); }
.cv-soc-btn {
    font-family: var(--cv-font-display); font-size: 0.88rem; font-weight: 800;
    color: #fff; background: var(--cv-primary); border: 0; border-radius: 10px;
    padding: 0.5rem 1.1rem; cursor: pointer; box-shadow: 0 3px 0 var(--cv-primary-dark);
}
.cv-soc-btn-suave { background: var(--cv-surface); color: var(--cv-primary-dark); border: 1.5px solid var(--cv-border); box-shadow: none; }
.cv-soc-ctr { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.5rem 0 0.2rem; justify-content: center; }
.cv-soc-fb { margin: 0.8rem 0 0; padding: 0.55rem 0.8rem; border-radius: 9px; font-weight: 600; font-size: 0.92rem; }
.cv-soc-ok { background: color-mix(in srgb, var(--cv-success) 14%, #fff); color: var(--cv-success); }
.cv-soc-mal { background: color-mix(in srgb, var(--cv-danger) 12%, #fff); color: var(--cv-danger); }

/* mapa */
.cv-soc-reg { transition: fill-opacity .12s, stroke-width .12s; }
.cv-soc-reg:hover { fill-opacity: 0.92; }
.cv-soc-reg-sel { fill-opacity: 1 !important; stroke-width: 4 !important; }
.cv-soc-reg-ok { fill: var(--cv-success) !important; stroke: var(--cv-success) !important; fill-opacity: 0.9 !important; }
.cv-soc-reg-mal { fill: var(--cv-danger) !important; stroke: var(--cv-danger) !important; }
.cv-soc-info {
    margin: 0.5rem 0 0; padding: 0.7rem 0.9rem; border-radius: 10px;
    background: var(--cv-primary-tint); color: var(--cv-navy); font-size: 0.9rem;
}

/* globo */
.cv-soc-globo-hemis svg circle:first-of-type { fill: color-mix(in srgb, var(--cv-accent) 18%, #dff1fb); }

/* clasifica */
.cv-soc-banco { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 0.8rem; }
.cv-soc-chip {
    font: inherit; font-weight: 700; font-size: 0.9rem;
    padding: 0.45rem 0.75rem; border: 1.5px solid var(--cv-border); border-radius: 999px;
    background: var(--cv-surface); color: var(--cv-navy); cursor: pointer;
}
.cv-soc-chip-sel { border-color: var(--cv-primary); background: var(--cv-primary-tint); }
.cv-soc-chip-ok { border-color: var(--cv-success) !important; background: color-mix(in srgb, var(--cv-success) 14%, #fff) !important; color: var(--cv-success) !important; }
.cv-soc-chip-mal { border-color: var(--cv-danger) !important; background: color-mix(in srgb, var(--cv-danger) 10%, #fff) !important; }
.cv-soc-cajas { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.cv-soc-caja {
    flex: 1 1 8rem; min-width: 8rem; border: 2px dashed var(--cv-border); border-radius: 12px;
    padding: 0.5rem; background: var(--cv-surface); cursor: pointer;
}
.cv-soc-caja:hover { border-color: var(--cv-primary); }
.cv-soc-caja-t { display: block; font-family: var(--cv-font-display); font-weight: 800; font-size: 0.82rem; color: var(--cv-primary-dark); text-align: center; margin-bottom: 0.35rem; }
.cv-soc-caja-drop { display: flex; flex-direction: column; gap: 0.3rem; min-height: 1.5rem; }
.cv-soc-caja-drop .cv-soc-chip { width: 100%; }

/* linea de tiempo */
.cv-soc-linea-dest { display: flex; flex-direction: column; gap: 0.35rem; margin-bottom: 0.7rem; }
.cv-soc-ev-hito { padding: 0.4rem 0.7rem; border-radius: 9px; background: color-mix(in srgb, var(--cv-success) 12%, #fff); border-left: 3px solid var(--cv-success); font-size: 0.9rem; color: var(--cv-navy); }
.cv-soc-linea-fila { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.cv-soc-ev {
    font: inherit; font-weight: 700; font-size: 0.85rem; text-align: left;
    padding: 0.5rem 0.7rem; border: 1.5px solid var(--cv-border); border-radius: 10px;
    background: var(--cv-surface); color: var(--cv-navy); cursor: pointer; max-width: 14rem;
}
.cv-soc-ev-ok { border-color: var(--cv-success); background: color-mix(in srgb, var(--cv-success) 12%, #fff); opacity: 0.6; }
.cv-soc-ev-mal { border-color: var(--cv-danger); background: color-mix(in srgb, var(--cv-danger) 10%, #fff); }

/* coordenada */
.cv-soc-coord { margin: 0.3rem 0; cursor: grab; }
.cv-soc-coord-lect { margin: 0.3rem 0 0; font-size: 1rem; color: var(--cv-text-dim); }
.cv-soc-coord-lect strong { color: var(--cv-navy); font-family: var(--cv-font-display); }

/* ===== Taller creativo (.cv-taller) — lienzo con figuritas para Intevra Aprende ===== */
.cv-taller {
    margin: 1rem 0; padding: 0.9rem; border-radius: 16px;
    background: var(--cv-surface-2, #f4f8fc);
    border: 2px dashed var(--kid-grape, var(--cv-primary));
}
.cv-taller-tit {
    margin: 0 0 0.6rem; font-family: var(--cv-font-display, inherit);
    font-weight: 800; color: var(--cv-navy); font-size: 1.05rem;
}
.cv-taller-barra { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 0.5rem; }
.cv-taller-barra-sec { align-items: center; }
.cv-taller-sticker, .cv-taller-tool {
    font-size: 1.35rem; line-height: 1; padding: 0.35rem 0.5rem; cursor: pointer;
    border: 2px solid var(--cv-border); border-radius: 12px; background: var(--cv-surface);
}
.cv-taller-tool { font-size: 1.15rem; }
.cv-taller-sticker:hover, .cv-taller-tool:hover { border-color: var(--cv-primary); }
.cv-taller-arm { border-color: var(--cv-primary); background: var(--cv-primary-tint); box-shadow: 0 0 0 3px var(--cv-primary-tint); }
.cv-taller-color {
    width: 1.7rem; height: 1.7rem; border-radius: 50%; cursor: pointer;
    border: 2px solid var(--cv-surface); box-shadow: 0 0 0 1px var(--cv-border);
}
.cv-taller-color-sel { box-shadow: 0 0 0 3px var(--cv-navy); }
.cv-taller-tam { min-width: 2.1rem; font-weight: 800; font-family: var(--cv-font-display, inherit); }
.cv-taller-lienzo {
    display: block; width: 100%; height: auto; max-width: 560px; margin: 0.2rem auto;
    background: #fffdf7; border: 2px solid var(--cv-border); border-radius: 12px;
    touch-action: none;
}
.cv-taller-lienzo-edit { cursor: crosshair; }
.cv-taller-lienzo-edit:not(.cv-taller-dibujando) { cursor: default; }
.cv-taller-it { -webkit-user-select: none; user-select: none; }
.cv-taller-acc { display: flex; gap: 0.5rem; margin-top: 0.5rem; }
.cv-taller-btn {
    font: inherit; font-weight: 700; padding: 0.4rem 0.8rem; cursor: pointer;
    border: none; border-radius: 999px; background: var(--cv-primary); color: #fff;
}
.cv-taller-btn-suave { background: var(--cv-surface); color: var(--cv-navy); border: 1.5px solid var(--cv-border); }
.cv-taller-ayuda { margin: 0.5rem 0 0; font-size: 0.82rem; color: var(--cv-text-dim); }

/* guía del taller (dentro de las instrucciones de la actividad) */
.cv-taller-intro { margin: 0 0 1rem; }
.cv-taller-guia { list-style: none; margin: 0 0 1.2rem; padding: 0; counter-reset: none; }
.cv-taller-paso {
    margin: 0 0 0.9rem; padding: 0.8rem 0.9rem; border-radius: 14px;
    background: var(--cv-surface-2, #f4f8fc); border-left: 5px solid var(--kid-mint, var(--cv-primary));
}
.cv-taller-paso-t {
    display: flex; align-items: center; gap: 0.55rem; margin-bottom: 0.5rem;
    font-family: var(--cv-font-display, inherit); font-weight: 800; color: var(--cv-navy); font-size: 1rem;
}
.cv-taller-paso-n {
    flex: none; width: 1.7rem; height: 1.7rem; border-radius: 50%;
    display: grid; place-items: center; background: var(--kid-mint, var(--cv-primary)); color: #fff;
    font-size: 0.95rem;
}
.cv-taller-paso-c > :first-child { margin-top: 0; }
.cv-taller-paso-c > :last-child { margin-bottom: 0; }
.cv-taller-crear-t { margin: 1.2rem 0 0.3rem; color: var(--cv-navy); }
.cv-taller-crear-d { margin: 0 0 0.4rem; }
.cv-taller-guardar-nota { margin: 0.6rem 0 0; font-size: 0.9rem; color: var(--cv-text-dim); }

/* figuras: tarjetas con dibujos para marcar (geometría) */
.cv-mate-fig-rej, .cv-fig-rej { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center; }
.cv-fig-item {
    flex: 0 0 auto;
    width: 6.2rem;
    border: 2px solid var(--cv-border);
    border-radius: 12px;
    background: var(--cv-surface);
    padding: 0.3rem;
    cursor: pointer;
    transition: border-color .12s, background .12s, transform .1s;
}
.cv-fig-item svg { display: block; margin: 0 auto; max-width: 100%; height: auto; }
.cv-fig-item:hover { border-color: var(--cv-primary); }
.cv-fig-item.cv-fig-on { border-color: var(--cv-primary); background: var(--cv-primary-tint); }
.cv-fig-item.cv-fig-ok { border-color: var(--cv-success) !important; background: color-mix(in srgb, var(--cv-success) 16%, #fff) !important; }
.cv-fig-item.cv-fig-mal { border-color: var(--cv-danger) !important; background: color-mix(in srgb, var(--cv-danger) 12%, #fff) !important; }
.cv-fig-item.cv-fig-falta { border-color: var(--cv-warning) !important; background: color-mix(in srgb, var(--cv-warning) 20%, #fff) !important; }

/* cuadricula / chips */
.cv-mate-grid { display: grid; grid-template-columns: repeat(10, 1fr); gap: 0.3rem; }
.cv-mate-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.cv-mate-celda {
    font: inherit; font-weight: 700; font-size: 0.9rem;
    padding: 0.4rem 0.2rem; border: 1.5px solid var(--cv-border); border-radius: 8px;
    background: var(--cv-surface); color: var(--cv-text); cursor: pointer;
}
.cv-mate-chips .cv-mate-celda { min-width: 3.2rem; }
.cv-mate-celda:hover { border-color: var(--cv-primary); }
.cv-mate-celda-on { background: var(--cv-primary-tint); border-color: var(--cv-primary); color: var(--cv-primary-dark); }
.cv-mate-celda-ok { background: color-mix(in srgb, var(--cv-success) 20%, #fff) !important; border-color: var(--cv-success) !important; color: var(--cv-success) !important; }
.cv-mate-celda-mal { background: color-mix(in srgb, var(--cv-danger) 16%, #fff) !important; border-color: var(--cv-danger) !important; color: var(--cv-danger) !important; text-decoration: line-through; }
.cv-mate-celda-falta { background: color-mix(in srgb, var(--cv-warning) 22%, #fff) !important; border-color: var(--cv-warning) !important; color: var(--cv-warning) !important; }

/* ordenar */
.cv-mate-ord-dest { display: flex; flex-wrap: wrap; gap: 0.4rem; min-height: 2.4rem; padding: 0.4rem; border: 1.5px dashed var(--cv-border); border-radius: 10px; margin-bottom: 0.6rem; }
.cv-mate-ord-t { font-family: var(--cv-font-display); font-weight: 800; color: var(--cv-success); background: color-mix(in srgb, var(--cv-success) 12%, #fff); border-radius: 8px; padding: 0.3rem 0.6rem; }
.cv-mate-ord-fila { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.cv-mate-ord-b {
    font: inherit; font-weight: 800; font-size: 1rem; color: var(--cv-navy);
    padding: 0.45rem 0.8rem; border: 1.5px solid var(--cv-border); border-radius: 9px; background: var(--cv-surface); cursor: pointer;
}
.cv-mate-ord-b:hover:not(:disabled) { border-color: var(--cv-primary); background: var(--cv-primary-tint); }
.cv-mate-ord-b:disabled { opacity: 0.45; }

@media (max-width: 560px) {
    .cv-mate-grid { grid-template-columns: repeat(6, 1fr); }
}

/* ===== Video de YouTube en una lectura (.cv-video) ===== */

.cv-video { margin: 1.25rem 0; }
.cv-video-card {
    display: flex; flex-direction: column; gap: 0.7rem;
    border: 1px solid var(--cv-border);
    border-left: 4px solid var(--cv-danger);
    border-radius: 12px;
    background: var(--cv-surface);
    padding: 1rem 1.1rem;
}
.cv-video-info { display: flex; flex-direction: column; gap: 0.15rem; }
.cv-video-tag {
    font-family: var(--cv-font-display);
    font-size: 0.7rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
    color: var(--cv-danger);
}
.cv-video-titulo { color: var(--cv-navy); font-size: 1rem; line-height: 1.35; }
.cv-video-autor { color: var(--cv-text-dim); font-size: 0.85rem; }
.cv-video-play {
    align-self: flex-start;
    font-family: var(--cv-font-display); font-size: 0.92rem; font-weight: 700;
    color: #fff; background: var(--cv-danger);
    border: 0; border-radius: 10px; padding: 0.55rem 1.1rem; cursor: pointer;
    display: inline-flex; align-items: center; gap: 0.5rem;
}
.cv-video-play:hover { filter: brightness(1.06); }
.cv-video-tri { font-size: 0.8rem; }
.cv-video-abrir { font-size: 0.8rem; color: var(--cv-primary-dark); text-decoration: underline; align-self: flex-start; }

.cv-video-marco {
    position: relative; width: 100%; aspect-ratio: 16 / 9;
    border-radius: 12px; overflow: hidden; background: #000;
    border: 1px solid var(--cv-border);
}
.cv-video-marco iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* ===== Minijuegos de suma (.cv-juego) ===== */

.cv-juego {
    border: 1px solid var(--cv-border);
    border-left: 4px solid var(--cv-accent);
    border-radius: 14px;
    background: var(--cv-surface);
    padding: 1rem 1.1rem 1.15rem;
    margin: 1.5rem 0;
}
.cv-juego-cab { margin-bottom: 0.7rem; }
.cv-juego-tag {
    font-family: var(--cv-font-display);
    font-size: 0.7rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
    color: var(--cv-accent);
}
.cv-juego-titulo { margin: 0.2rem 0 0.3rem; color: var(--cv-navy); font-size: 1.1rem; }
.cv-juego-regla { margin: 0; color: var(--cv-text-dim); font-size: 0.9rem; line-height: 1.45; }

.cv-juego-hud {
    display: flex; flex-wrap: wrap; gap: 0.4rem 0.9rem;
    margin: 0.5rem 0 0.6rem;
}
.cv-juego-hud-i {
    font-family: var(--cv-font-display); font-weight: 800; font-size: 0.92rem;
    color: var(--cv-navy);
    background: var(--cv-surface-2);
    border: 1px solid var(--cv-border); border-radius: 999px;
    padding: 0.25rem 0.7rem;
}

.cv-juego-escena {
    position: relative;
    border-radius: 12px; overflow: hidden;
    border: 1px solid var(--cv-border);
    background: #0b1b33;
    line-height: 0;
}
.cv-juego-lienzo { display: block; width: 100%; height: auto; touch-action: none; }

.cv-juego-capa {
    position: absolute; inset: 0;
    display: none;
    align-items: center; justify-content: center;
    padding: 0.6rem;
    background: rgba(11, 27, 51, 0.74);
    line-height: 1.4;
    overflow-y: auto;
}
.cv-juego-capa-on { display: flex; }

.cv-juego-quiz, .cv-juego-msg {
    width: min(23rem, 100%);
    background: var(--cv-surface);
    border-radius: 14px;
    padding: 0.85rem 1rem 0.95rem;
    text-align: center;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.28);
}
.cv-juego-quiz-kick {
    margin: 0 0 0.35rem; font-size: 0.72rem; font-weight: 700;
    color: var(--cv-primary-dark); text-transform: uppercase; letter-spacing: .03em;
}
.cv-juego-quiz-op {
    margin: 0 0 0.6rem;
    font-family: var(--cv-font-display); font-weight: 800;
    font-size: 1.35rem; color: var(--cv-navy);
}
.cv-juego-quiz-fila { display: flex; gap: 0.5rem; justify-content: center; }
.cv-juego-quiz .cv-col { display: flex; justify-content: center; margin: 0.2rem 0 0.6rem; }
.cv-juego-quiz > .cv-juego-btn { display: block; margin: 0.6rem auto 0; }
.cv-juego-quiz > .cv-juego-pista { display: block; margin: 0.5rem auto 0; }
.cv-juego-quiz-in {
    width: 6.5rem; font: inherit; font-weight: 800; font-size: 1.15rem; text-align: center;
    padding: 0.45rem 0.4rem;
    border: 2px solid var(--cv-border); border-radius: 10px;
    background: var(--cv-surface); color: var(--cv-navy);
}
.cv-juego-pista {
    margin-top: 0.6rem;
    font: inherit; font-size: 0.82rem; font-weight: 700;
    color: var(--cv-primary-dark);
    background: none; border: 0; cursor: pointer; text-decoration: underline;
}
.cv-juego-pista:disabled { color: var(--cv-text-dim); text-decoration: none; cursor: default; }
.cv-juego-quiz-fb {
    margin: 0.7rem 0 0; padding: 0.5rem 0.7rem; border-radius: 9px;
    font-size: 0.88rem; font-weight: 600;
    background: var(--cv-surface-2); color: var(--cv-text);
}
.cv-juego-quiz-ok { background: color-mix(in srgb, var(--cv-success) 14%, #fff); color: var(--cv-success); }
.cv-juego-quiz-mal { background: color-mix(in srgb, var(--cv-danger) 12%, #fff); color: var(--cv-danger); }

.cv-juego-msg-t { margin: 0 0 0.4rem; font-family: var(--cv-font-display); font-weight: 800; font-size: 1.25rem; color: var(--cv-navy); }
.cv-juego-msg-s { margin: 0 0 0.9rem; color: var(--cv-text-dim); font-size: 0.92rem; }

.cv-juego-btn {
    font-family: var(--cv-font-display);
    font-size: 0.95rem; font-weight: 800;
    color: #fff; background: var(--cv-primary);
    border: 0; border-radius: 11px;
    padding: 0.6rem 1.3rem; cursor: pointer;
}
.cv-juego-btn:hover { background: var(--cv-primary-dark); }
.cv-juego-btn:disabled { opacity: 0.6; cursor: default; }

.cv-juego-mandos {
    display: flex; flex-wrap: wrap; gap: 0.5rem;
    margin-top: 0.7rem;
}
.cv-juego-mando {
    flex: 1 1 3.2rem; min-width: 3.2rem;
    font-family: var(--cv-font-display); font-weight: 800; font-size: 1.1rem;
    color: var(--cv-navy); background: var(--cv-surface-2);
    border: 1.5px solid var(--cv-border); border-radius: 11px;
    padding: 0.7rem 0.5rem; cursor: pointer;
    user-select: none; touch-action: manipulation;
}
.cv-juego-mando:hover { border-color: var(--cv-primary); background: var(--cv-primary-tint); }
.cv-juego-mando:active { background: var(--cv-primary); color: #fff; }
.cv-juego-mando-ancho { flex: 2 1 8rem; }

@keyframes cv-juego-sacude {
    0%, 100% { transform: translateX(0); }
    20% { transform: translateX(-7px); }
    40% { transform: translateX(6px); }
    60% { transform: translateX(-4px); }
    80% { transform: translateX(3px); }
}
.cv-juego-sacude { animation: cv-juego-sacude 0.4s ease; }

@media (prefers-reduced-motion: reduce) {
    .cv-juego-sacude { animation: none; }
}

/* ===== Editor de diagramas de flujo ===== */

.cv-diagrama-toolbar {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.75rem;
}

.cv-paleta-btn {
    background: var(--cv-surface);
    border: 1.5px solid var(--cv-border);
    color: var(--cv-text);
    border-radius: 8px;
    padding: 0.45rem 0.85rem;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}

.cv-paleta-btn:hover { border-color: var(--cv-primary); color: var(--cv-primary); background: var(--cv-primary-tint); }

.cv-diagrama-canvas {
    position: relative;
    min-width: 900px;
    min-height: 480px;
    background-image: radial-gradient(circle, #d7dcec 1.2px, transparent 1.2px);
    background-size: 22px 22px;
    background-color: var(--cv-surface-2);
    border: 1px solid var(--cv-border);
    border-radius: 14px;
    overflow: auto;
    margin-bottom: 1rem;
}

/* El "mundo" contiene los nodos y las flechas; se escala con transform
   para alejar/acercar. transform-origin arriba-izquierda para que las
   coordenadas y el scroll cuadren. */
.cv-diagrama-mundo { position: relative; transform-origin: 0 0; width: 900px; height: 480px; }

.cv-diagrama-svg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; }

.cv-diagrama-zoom {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.5rem;
    flex-wrap: wrap;
}
.cv-diagrama-zoom #cv-zoom-nivel {
    min-width: 3.2ch;
    text-align: center;
    font-size: 0.85rem;
    color: var(--cv-text-dim);
}

/* Flechas del diagrama en rojo, verticales, como PSeInt. */
:root { --cv-diag-flecha: #c0392b; }
.cv-conexion { stroke: var(--cv-diag-flecha); stroke-width: 2; fill: none; }
.cv-conexion-temporal { stroke-dasharray: 4 4; opacity: 0.6; }
.cv-conexion-etiqueta { font-size: 12px; font-weight: 700; fill: #0369a1; }
.cv-conexion-etiqueta-si, .cv-conexion-etiqueta-no { fill: #0369a1; }

.cv-nodo {
    position: absolute;
    /* (left, top) es el CENTRO del nodo -ver diagrama.js-: se centra con
       translate para que la columna quede alineada sin importar el ancho. */
    transform: translate(-50%, -50%);
    cursor: grab;
    user-select: none;
}

/* Mientras se arrastra una figura, el cursor "agarrando" en todo el lienzo. */
.cv-arrastrando, .cv-arrastrando .cv-nodo, .cv-arrastrando .cv-nodo-texto { cursor: grabbing !important; }

/*
 * La forma visible (con su clip-path si aplica) vive en un <div> interno
 * separado del <div> de posicionamiento (.cv-nodo). Un clip-path recorta
 * TODO lo que esté dentro del elemento que lo tiene -incluyendo el puerto
 * de conexión, el botón de borrar, la pista y el aviso de error, que a
 * propósito sobresalen del borde-, así que esos se cuelgan del <div>
 * externo (sin recorte) y solo el texto queda dentro de la forma.
 */
.cv-nodo-forma {
    min-width: 120px;
    max-width: 340px;
    min-height: 46px;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.45rem 1rem;
    background: var(--cv-surface);
    border: 2px solid #b9c0d4;
    color: #1b2437;
    font-family: 'Courier New', Consolas, monospace;
    font-size: 0.9rem;
    text-align: center;
    box-shadow: var(--cv-shadow-sm);
}

/* Inicio / Fin: píldora de borde naranja, fondo crema y texto azul -el
   terminal de PSeInt (Algoritmo / FinAlgoritmo)-. */
.cv-nodo-inicio, .cv-nodo-fin {
    border-radius: 999px;
    border-color: #e79b30;
    background: #fdf4df;
    color: #0369a1;
    font-weight: 700;
}

/* Entrada (Leer): romboide rosado. */
.cv-nodo-entrada {
    clip-path: polygon(14% 0, 100% 0, 86% 100%, 0 100%);
    padding-left: 1.5rem; padding-right: 1.5rem;
    background: #f7d7e6;
    border-color: #cf7ba6;
    color: #7a2b52;
}

/* Salida (Escribir): romboide verde. */
.cv-nodo-salida, .cv-nodo-documento {
    clip-path: polygon(14% 0, 100% 0, 86% 100%, 0 100%);
    padding-left: 1.5rem; padding-right: 1.5rem;
    background: #dbf0d2;
    border-color: #6fae5f;
    color: #2f5e26;
}
.cv-nodo-documento { clip-path: none; border-radius: 8px 8px 45% 45% / 8px 8px 55% 55%; }

/* Proceso / asignación: rectángulo amarillo pálido. */
.cv-nodo-proceso, .cv-nodo-subproceso, .cv-nodo-preparacion, .cv-nodo-definir {
    border-radius: 6px;
    background: #fbf3c4;
    border-color: #d7c14b;
    color: #5a4b12;
}
.cv-nodo-subproceso { box-shadow: inset 4px 0 0 #d7c14b, inset -4px 0 0 #d7c14b, var(--cv-shadow-sm); padding-left: 1.3rem; padding-right: 1.3rem; }
.cv-nodo-preparacion { clip-path: polygon(8% 0, 92% 0, 100% 50%, 92% 100%, 8% 100%, 0 50%); padding-left: 1.3rem; padding-right: 1.3rem; }
.cv-nodo-definir { border-style: dashed; }

/* Decisión: rombo azul claro. */
.cv-nodo-decision {
    clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
    min-height: 96px;
    min-width: 150px;
    background: #e6edff;
    border-color: #4a6bd8;
    color: #22307a;
}

.cv-nodo-conector {
    width: 54px; min-width: 0; height: 54px; min-height: 0;
    border-radius: 50%;
    padding: 0.3rem;
    background: var(--cv-surface-2);
    border-color: #b9c0d4;
}

.cv-nodo-seleccionado { outline: 2px solid #0369a1; outline-offset: 2px; }

/* Marco de selección (arrastrar en el vacío para elegir varias figuras). */
.cv-seleccion-marco {
    position: absolute;
    border: 1.5px dashed #0369a1;
    background: rgba(43, 58, 143, 0.08);
    pointer-events: none;
    z-index: 1;
}
.cv-nodo-activo { box-shadow: 0 0 0 3px rgba(41, 73, 184, 0.35); }
.cv-nodo-invalido { box-shadow: 0 0 0 2px var(--cv-danger); }

.cv-nodo-texto { outline: none; width: 100%; word-break: break-word; }
.cv-nodo-texto:empty::before {
    content: attr(data-placeholder);
    color: var(--cv-text-dim);
    font-style: italic;
}

.cv-nodo-pista {
    position: absolute;
    top: 50%; left: calc(100% + 12px);
    transform: translateY(-50%);
    width: 180px;
    font-size: 0.7rem;
    color: var(--cv-text-dim);
    text-align: left;
    white-space: normal;
    line-height: 1.2;
}

.cv-nodo-error {
    position: absolute;
    top: -1.5rem; left: 0;
    width: 100%;
    font-size: 0.7rem;
    color: var(--cv-danger);
    text-align: center;
    background: var(--cv-surface);
    border-radius: 6px;
    padding: 0.1rem 0.3rem;
}

.cv-nodo-borrar {
    position: absolute;
    top: -10px; right: -10px;
    width: 20px; height: 20px;
    border-radius: 50%;
    background: var(--cv-danger);
    color: #ffffff;
    border: 2px solid #fff;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    box-shadow: var(--cv-shadow-sm);
}

.cv-puerto {
    position: absolute;
    bottom: -8px; left: 50%;
    width: 14px; height: 14px;
    border-radius: 50%;
    background: var(--cv-diag-flecha);
    border: 2px solid var(--cv-surface);
    transform: translateX(-50%);
    cursor: crosshair;
    pointer-events: all;
    box-shadow: var(--cv-shadow-sm);
    z-index: 2;
}
.cv-puerto-si { left: 28%; background: var(--cv-success); }
.cv-puerto-no { left: 72%; background: var(--cv-danger); }
.cv-puerto-a { background: var(--cv-primary); }
.cv-puerto-b { background: var(--cv-orange); }

.cv-puerto-elegir {
    position: fixed;
    z-index: 500;
    min-width: 200px;
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    box-shadow: var(--cv-shadow-lift);
    padding: 0.4rem;
    font-family: var(--cv-font-sans);
}
.cv-puerto-elegir-titulo {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--cv-text-dim);
    padding: 0.3rem 0.5rem 0.4rem;
}
.cv-puerto-elegir-lista {
    max-height: 272px;
    overflow-y: auto;
}
.cv-puerto-elegir-opcion {
    display: block;
    width: 100%;
    text-align: left;
    padding: 0.45rem 0.6rem;
    border: none;
    border-radius: 6px;
    background: none;
    color: var(--cv-text);
    font-size: 0.85rem;
    cursor: pointer;
}
.cv-puerto-elegir-opcion:hover {
    background: var(--cv-primary-tint);
    color: var(--cv-primary-dark);
}
.cv-puerto-elegir-cancelar {
    display: block;
    width: 100%;
    text-align: left;
    margin-top: 0.15rem;
    padding: 0.4rem 0.6rem;
    border: none;
    border-top: 1px solid var(--cv-border);
    border-radius: 0;
    background: none;
    color: var(--cv-text-dim);
    font-size: 0.8rem;
    cursor: pointer;
}
.cv-puerto-elegir-cancelar:hover {
    color: var(--cv-danger);
}

/* ===== Editor de topología de red ===== */

.cv-red-layout { display: flex; gap: 1rem; flex-wrap: wrap; align-items: flex-start; }
.cv-red-lienzo { flex: 2; min-width: 320px; }
.cv-red-panel-lateral { flex: 1; min-width: 240px; }
/* #cv-red-canvas comparte clase con el editor de diagramas de flujo, que
   fija min-width:900px -bueno para ese editor, que no tiene panel lateral-.
   Acá sí hay un panel al lado, así que ese mínimo lo desborda fuera de su
   columna (flex:2) y lo tapa por completo cuando la tarjeta no tiene 900px+
   libres para esa columna; se anula con la especificidad del id. */
#cv-red-canvas {
    min-width: 0;
    width: 100%;
    height: 65vh;
    min-height: 480px;
    box-shadow: inset 0 1px 4px rgba(23, 33, 66, 0.07);
}

/* Barra de herramientas del simulador -dispositivos, tipo de cable y
   zoom, agrupados en una sola tira arriba del lienzo en vez de tres
   bloques sueltos-, con el mismo look de barra de herramientas de un
   programa real de redes (Packet Tracer/GNS3). */
.cv-red-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.55rem 0.7rem;
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 12px;
    padding: 0.6rem 0.8rem;
    margin-bottom: 0.75rem;
    box-shadow: var(--cv-shadow-sm);
}
/* Selector de tipo de arquitectura/topología en la galería de red -ver
   galeria_red.html-: una fila de píldoras, la activa resaltada con el
   color primario, igual criterio visual que el resto del sitio. */
.cv-galeria-red-tipos {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1.1rem;
}
.cv-galeria-red-tipo {
    display: inline-block;
    padding: 0.5rem 1rem;
    border-radius: 999px;
    border: 1.5px solid var(--cv-border);
    background: var(--cv-surface);
    color: var(--cv-text);
    font-weight: 600;
    font-size: 0.88rem;
    text-decoration: none;
    transition: transform var(--cv-dur-fast) var(--cv-ease-out), border-color var(--cv-dur-fast) var(--cv-ease-out), background var(--cv-dur-fast) var(--cv-ease-out), color var(--cv-dur-fast) var(--cv-ease-out);
}
.cv-galeria-red-tipo:hover { border-color: var(--cv-primary); color: var(--cv-primary); transform: translateY(-1px); }
.cv-galeria-red-tipo-activo, .cv-galeria-red-tipo-activo:hover {
    background: linear-gradient(135deg, var(--cv-primary), var(--cv-cyan));
    border-color: transparent;
    color: #fff;
}

.cv-red-toolbar-grupo { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.cv-red-toolbar-etiqueta {
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--cv-text-dim);
    margin-right: 0.15rem;
}
.cv-red-toolbar-separador { width: 1px; align-self: stretch; background: var(--cv-border); }

.cv-red-zoom-barra button {
    width: 28px;
    height: 28px;
    border-radius: 6px;
    border: 1px solid var(--cv-border);
    background: var(--cv-surface-2);
    color: var(--cv-text);
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
}
.cv-red-zoom-barra button:hover { border-color: var(--cv-primary); color: var(--cv-primary); }
.cv-red-zoom-nivel { font-size: 0.8rem; color: var(--cv-text-dim); min-width: 3.2em; text-align: center; }
.cv-red-zoom-ajustar { width: auto !important; padding: 0 0.6rem; font-size: 0.78rem !important; }

/* El transform-origin en 0,0 hace que "acercar" crezca hacia abajo/
   derecha -mismo sentido en el que ya crecen las coordenadas x/y de
   los dispositivos-, en vez de crecer desde el centro del lienzo. */
/* min-width/min-height explícitos -antes los ponía #cv-red-canvas
   directamente, ver .cv-diagrama-canvas-: un div con solo hijos
   position:absolute (los dispositivos, el SVG de los cables) no le
   hereda tamaño a su padre, así que sin esto el SVG -width/height:100%-
   colapsaba a 0 y los cables dejaban de dibujarse -aunque seguían
   existiendo en los datos, por eso parecía que "se desconectaban"-. */
.cv-red-zoom-lienzo { position: relative; min-width: 900px; min-height: 480px; transform-origin: 0 0; }

.cv-disp {
    position: absolute;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.15rem;
    padding: 0.4rem;
    background: var(--cv-surface);
    border: 2px solid var(--cv-border);
    color: var(--cv-text);
    font-size: 0.78rem;
    text-align: center;
    cursor: grab;
    user-select: none;
    box-shadow: var(--cv-shadow-sm);
    border-radius: 10px;
    transition: box-shadow 0.15s ease, border-color 0.15s ease;
}
.cv-disp:hover { box-shadow: var(--cv-shadow-md); }
.cv-disp:active { cursor: grabbing; }

.cv-disp-nombre { font-weight: 700; word-break: break-word; }
.cv-disp-icono { width: 40px; height: 40px; flex-shrink: 0; filter: drop-shadow(0 1px 1px rgba(0,0,0,0.15)); }
.cv-disp-icono svg { width: 100%; height: 100%; display: block; }

.cv-disp-pc { border-color: var(--cv-primary); }
.cv-disp-servidor { border-color: var(--cv-success); }
.cv-disp-switch { border-radius: 6px; background: var(--cv-surface-2); }
.cv-disp-router { border-radius: 50%; border-color: var(--cv-orange); }
.cv-disp-firewall { border-color: var(--cv-danger); }
.cv-disp-mikrotik { border-radius: 6px; border-color: #8e1b1b; }
.cv-disp-accesspoint { border-radius: 6px; border-color: #78be20; }
.cv-disp-nube { border-radius: 16px; border-color: #5c6f85; background: var(--cv-surface-2); }
.cv-disp-laptop { border-color: var(--cv-primary); }
.cv-disp-impresora { border-color: var(--cv-text-dim); }
.cv-disp-telefonoip { border-radius: 6px; border-color: #049fd9; }

/* Aparatos domésticos (IoT): mismo nodo de siempre, con un borde que
   los distingue de los equipos de trabajo -no son PC ni servidores-.
   La aspiradora va redonda porque lo es. */
.cv-disp-tv { border-radius: 6px; border-color: #5b6a7a; }
.cv-disp-smartphone { border-radius: 10px; border-color: #5b6a7a; }
.cv-disp-asistente { border-radius: 14px; border-color: #8695a3; }
.cv-disp-aspiradora { border-radius: 50%; border-color: #8695a3; }

.cv-disp-seleccionado { outline: 2px solid var(--cv-primary); box-shadow: var(--cv-shadow-md), 0 0 0 4px var(--cv-primary-tint); }

.cv-disp-estado {
    position: absolute;
    top: 6px;
    right: 6px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: 1.5px solid var(--cv-surface);
    box-shadow: 0 0 0 1px rgba(0,0,0,0.15);
}
.cv-disp-estado-ok { background: var(--cv-success); }
.cv-disp-estado-advertencia { background: var(--cv-warning); }
.cv-disp-estado-error { background: var(--cv-danger); }
.cv-disp-estado-sinprobar { background: var(--cv-border); }

.cv-cable { stroke: var(--cv-text-dim); stroke-width: 2.5; fill: none; }
.cv-cable-invalido { stroke: var(--cv-danger); stroke-dasharray: 5 4; }
/* Aspecto por medio -mismo criterio de colores que un patchcord real:
   naranja para fibra (multimodo), cable coaxial más grueso y oscuro-. */
.cv-cable-medio-fibra { stroke: var(--cv-orange); stroke-width: 2.5; }
.cv-cable-medio-coaxial { stroke: var(--cv-text); stroke-width: 4; }
.cv-cable-medio-wifi { stroke: #78be20; stroke-width: 2; stroke-dasharray: 1 5; stroke-linecap: round; }
.cv-cable-medio-fibra.cv-cable-invalido, .cv-cable-medio-coaxial.cv-cable-invalido, .cv-cable-medio-wifi.cv-cable-invalido { stroke: var(--cv-danger); }

.cv-red-toolbar-grupo-inactivo { opacity: 0.4; pointer-events: none; }

/* Dispositivos y cables de un compañero conectado por VPN -de solo lectura- */
.cv-disp-ajeno { opacity: 0.72; border-style: dashed; cursor: default; }
.cv-disp-ajeno-etiqueta { font-size: 0.65rem; font-weight: 600; color: var(--cv-text-dim); font-style: italic; }
.cv-cable-ajeno { opacity: 0.72; }
.cv-cable-vpn { stroke: var(--cv-orange); stroke-width: 2.5; stroke-dasharray: 2 6; stroke-linecap: round; fill: none; }

.cv-paquete {
    position: absolute;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--cv-primary);
    transform: translate(-50%, -50%);
    pointer-events: none;
    box-shadow: 0 0 6px 1px rgba(41, 73, 184, 0.7);
    transition: background-color 0.2s, box-shadow 0.2s;
    z-index: 5;
}
.cv-paquete-ok { background: var(--cv-success); box-shadow: 0 0 6px 1px rgba(23, 138, 76, 0.7); }
.cv-paquete-error { background: var(--cv-danger); box-shadow: 0 0 6px 1px rgba(204, 51, 64, 0.7); }

/* El comando "mail" se anima como un sobre -no un punto de color-, más
   lento que un ping, y al llegar deja ver la respuesta en el propio
   lienzo -mismo espíritu que el resultado de un PDU en Packet Tracer-. */
.cv-paquete-sobre {
    width: 22px;
    height: 22px;
    background: none;
    box-shadow: none;
    border-radius: 0;
    font-size: 18px;
    line-height: 22px;
    text-align: center;
}
.cv-respuesta-correo {
    position: absolute;
    /* La posición/escala (incluida la compensación de zoom) la pone
       JS en línea -acá solo la aparición gradual, un simple fade de
       opacidad no choca con un transform puesto por JS como sí lo
       haría una @keyframes que también anime transform-. */
    opacity: 0;
    transition: opacity 0.25s ease-out;
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 8px;
    padding: 0.3rem 0.6rem;
    font-size: 0.75rem;
    font-weight: 700;
    white-space: nowrap;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
    pointer-events: none;
    z-index: 6;
}
.cv-respuesta-correo-visible { opacity: 1; }
.cv-respuesta-correo-ok { color: var(--cv-success); border-color: var(--cv-success); }
.cv-respuesta-correo-error { color: var(--cv-danger); border-color: var(--cv-danger); }

.cv-red-config {
    background: var(--cv-surface-2);
    border: 1px solid var(--cv-border);
    border-top: 3px solid var(--cv-primary);
    border-radius: 10px;
    padding: 0.9rem;
    box-shadow: var(--cv-shadow-sm);
}
.cv-red-config h4 { margin: 0 0 0.6rem; }
.cv-red-config-vacio { color: var(--cv-text-dim); font-size: 0.85rem; margin: 0; }

/* "Configuración de red actual" de un aparato sin terminal -lo que en
   un PC se vería con `ipconfig`-: etiqueta a la izquierda, valor en
   monoespaciada a la derecha, para que una IP se lea como una IP. */
.cv-red-resumen {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.3rem 0.9rem;
    margin: 0.6rem 0 0;
    font-size: 0.82rem;
}

.cv-red-resumen dt { color: var(--cv-text-dim); }

.cv-red-resumen dd {
    margin: 0;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-weight: 600;
    color: var(--cv-text);
    text-align: right;
}

.cv-red-resumen dd.cv-red-resumen-vacio { color: var(--cv-text-dim); font-weight: 400; font-style: italic; }

.cv-red-resumen-error {
    margin: 0.6rem 0 0;
    font-size: 0.85rem;
    color: var(--cv-danger);
}

/* Panel con look de WebFig (la interfaz web real de un Mikrotik) -ver
   renderPanelMikrotik en topologia.js-. */
.cv-mikrotik {
    border: 1px solid #3a3a3a;
    border-radius: 6px;
    overflow: hidden;
    font-size: 0.82rem;
    background: #f4f4f4;
    color: #222;
}
.cv-mikrotik-cabecera {
    background: #8e1b1b;
    color: #fff;
    padding: 0.5rem 0.7rem;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
}
.cv-mikrotik-marca { font-weight: 700; letter-spacing: 0.02em; }
.cv-mikrotik-version { font-size: 0.7rem; opacity: 0.85; }
.cv-mikrotik-tabs {
    display: flex;
    background: #2b2b2b;
}
.cv-mikrotik-tab {
    flex: 1;
    background: transparent;
    border: none;
    border-right: 1px solid #3a3a3a;
    color: #ccc;
    padding: 0.4rem 0.3rem;
    font-size: 0.75rem;
    cursor: pointer;
}
.cv-mikrotik-tab:hover { background: #3a3a3a; }
.cv-mikrotik-tab-activa { background: #f4f4f4; color: #222; font-weight: 600; }
.cv-mikrotik-cuerpo { padding: 0.7rem; }
.cv-mikrotik-cuerpo .cv-red-campo span { color: #555; }
.cv-mikrotik-tabla { border-collapse: collapse; width: 100%; font-size: 0.78rem; }
.cv-mikrotik-tabla th {
    background: #dcdcdc;
    text-transform: uppercase;
    font-size: 0.68rem;
    letter-spacing: 0.02em;
    color: #444;
}
.cv-mikrotik-tabla th, .cv-mikrotik-tabla td {
    border: 1px solid #c8c8c8;
    padding: 0.35rem 0.5rem;
    text-align: left;
}
.cv-mikrotik-tabla input {
    width: 100%;
    box-sizing: border-box;
    border: 1px solid #c8c8c8;
    border-radius: 3px;
    padding: 0.2rem 0.35rem;
    font-size: 0.78rem;
}

/* Panel con look del administrador web de un switch HP -ver
   renderPanelHP en topologia.js-. Mismo patrón que el WebFig del
   Mikrotik, con la marca/colores de HP en vez de RouterOS. */
.cv-hp {
    border: 1px solid #b0b0b0;
    border-radius: 6px;
    overflow: hidden;
    font-size: 0.82rem;
    background: #f7f9fb;
    color: #222;
}
.cv-hp-cabecera {
    background: #0096d6;
    color: #fff;
    padding: 0.5rem 0.7rem;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
}
.cv-hp-marca { font-weight: 800; letter-spacing: 0.01em; text-transform: lowercase; font-size: 1.05rem; }
.cv-hp-version { font-size: 0.7rem; opacity: 0.9; }
.cv-hp-tabs { display: flex; background: #eef4f8; border-bottom: 1px solid #c9d6de; }
.cv-hp-tab {
    flex: 1;
    background: transparent;
    border: none;
    border-right: 1px solid #c9d6de;
    color: #33586b;
    padding: 0.4rem 0.3rem;
    font-size: 0.75rem;
    cursor: pointer;
}
.cv-hp-tab:hover { background: #dcebf3; }
.cv-hp-tab-activa { background: #fff; color: #0096d6; font-weight: 700; box-shadow: inset 0 -2px 0 #0096d6; }
.cv-hp-cuerpo { padding: 0.7rem; overflow-x: auto; }
.cv-hp-cuerpo .cv-red-campo span { color: #555; }

.cv-tplink {
    border: 1px solid #b0b0b0;
    border-radius: 6px;
    overflow: hidden;
    font-size: 0.82rem;
    background: #f7faf3;
    color: #222;
}
.cv-tplink-cabecera {
    background: #78be20;
    color: #fff;
    padding: 0.5rem 0.7rem;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
}
.cv-tplink-marca { font-weight: 800; letter-spacing: 0.01em; font-size: 1.05rem; }
.cv-tplink-version { font-size: 0.7rem; opacity: 0.9; }
.cv-tplink-tabs { display: flex; background: #eef6e2; border-bottom: 1px solid #cfe0bc; }
.cv-tplink-tab {
    flex: 1;
    background: transparent;
    border: none;
    border-right: 1px solid #cfe0bc;
    color: #4c6b2a;
    padding: 0.4rem 0.3rem;
    font-size: 0.75rem;
    cursor: pointer;
}
.cv-tplink-tab:hover { background: #e1efce; }
.cv-tplink-tab-activa { background: #fff; color: #5a9418; font-weight: 700; box-shadow: inset 0 -2px 0 #78be20; }
.cv-tplink-cuerpo { padding: 0.7rem; overflow-x: auto; }
.cv-tplink-cuerpo .cv-red-campo span { color: #555; }

.cv-cisco {
    border: 1px solid #b0b0b0;
    border-radius: 6px;
    overflow: hidden;
    font-size: 0.82rem;
    background: #f4fafc;
    color: #222;
}
.cv-cisco-cabecera {
    background: #049fd9;
    color: #fff;
    padding: 0.5rem 0.7rem;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
}
.cv-cisco-marca { font-weight: 800; letter-spacing: 0.01em; font-size: 1.05rem; }
.cv-cisco-version { font-size: 0.7rem; opacity: 0.9; }
.cv-cisco-cuerpo { padding: 0.7rem; overflow-x: auto; }
.cv-cisco-cuerpo .cv-red-campo span { color: #555; }
/* La tabla de VLAN (ID/Nombre/Red/Máscara/Gateway) no cabe cómoda en
   el ancho angosto del panel lateral -min-width evita que las
   columnas se aplasten hasta ser inusables; .cv-hp-cuerpo de arriba le
   da scroll horizontal propio en vez de desbordar la página-. */
.cv-hp-tabla { border-collapse: collapse; width: 100%; min-width: 420px; font-size: 0.78rem; margin-top: 0.5rem; }
/* La tabla de puertos de un switch puede tener hasta 24 filas -scroll
   vertical propio, con el encabezado fijo, para no alargar el panel-. */
.cv-hp-tabla-scroll { max-height: 280px; overflow-y: auto; overflow-x: auto; }
.cv-hp-tabla-scroll .cv-hp-tabla thead th { position: sticky; top: 0; z-index: 1; }
.cv-hp-tabla th {
    background: #dcebf3;
    text-transform: uppercase;
    font-size: 0.68rem;
    letter-spacing: 0.02em;
    color: #33586b;
}
.cv-hp-tabla th, .cv-hp-tabla td {
    border: 1px solid #c9d6de;
    padding: 0.35rem 0.5rem;
    text-align: left;
}
.cv-hp-tabla input {
    width: 100%;
    box-sizing: border-box;
    border: 1px solid #c9d6de;
    border-radius: 3px;
    padding: 0.2rem 0.35rem;
    font-size: 0.78rem;
}

.cv-red-config-puerto {
    border-top: 1px dashed var(--cv-border);
    padding-top: 0.5rem;
    margin-top: 0.5rem;
}
.cv-red-interfaz-cabecera {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.35rem;
}
.cv-red-campo {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
    font-size: 0.82rem;
}
.cv-red-campo span { color: var(--cv-text-dim); white-space: nowrap; }
.cv-red-campo input, .cv-red-campo select {
    flex: 1;
    min-width: 0;
    padding: 0.35rem 0.5rem;
    border: 1px solid var(--cv-border);
    border-radius: 6px;
    font-size: 0.85rem;
}
.cv-red-campo-area {
    flex-direction: column;
    align-items: stretch;
}
.cv-red-campo-area textarea {
    width: 100%;
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--cv-border);
    border-radius: 6px;
    font-size: 0.8rem;
    font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
    resize: vertical;
    box-sizing: border-box;
}

.cv-red-casilla {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.82rem;
    margin-bottom: 0.5rem;
    cursor: pointer;
}
.cv-red-casilla input { cursor: pointer; }

.cv-red-cola-impresion {
    list-style: none;
    margin: 0 0 0.6rem;
    padding: 0;
    max-height: 220px;
    overflow-y: auto;
}
.cv-red-cola-impresion li {
    font-size: 0.82rem;
    padding: 0.4rem 0.55rem;
    border: 1px solid var(--cv-border);
    border-radius: 6px;
    margin-bottom: 0.35rem;
    background: var(--cv-surface-2);
}

.cv-red-registro-dns {
    display: flex;
    gap: 0.4rem;
    align-items: center;
    margin-bottom: 0.4rem;
}
.cv-red-regla-firewall {
    display: flex;
    gap: 0.4rem;
    align-items: center;
    margin-bottom: 0.4rem;
    flex-wrap: wrap;
}
.cv-red-regla-firewall select {
    flex: 0 0 auto;
    padding: 0.3rem 0.3rem;
    border: 1px solid var(--cv-border);
    border-radius: 6px;
    font-size: 0.78rem;
}
.cv-red-regla-firewall input {
    flex: 1;
    min-width: 90px;
    padding: 0.3rem 0.45rem;
    border: 1px solid var(--cv-border);
    border-radius: 6px;
    font-size: 0.8rem;
}
.cv-red-registro-dns input {
    flex: 1;
    min-width: 0;
    padding: 0.3rem 0.45rem;
    border: 1px solid var(--cv-border);
    border-radius: 6px;
    font-size: 0.8rem;
}
.cv-red-quitar-registro {
    flex-shrink: 0;
    width: 22px; height: 22px;
    border-radius: 50%;
    border: none;
    background: var(--cv-danger);
    color: #fff;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
}

/* Bandeja de dispositivos -estilo la barra inferior de Packet Tracer- */
.cv-red-bandeja-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    background: var(--cv-surface-2);
    border: 1.5px solid var(--cv-border);
    border-radius: 8px;
    padding: 0.4rem 0.6rem;
    cursor: pointer;
    color: var(--cv-text);
    font-size: 0.68rem;
    font-weight: 600;
    transition: border-color 0.15s ease, color 0.15s ease, background-color 0.15s ease, transform 0.1s ease;
}
.cv-red-bandeja-btn:hover { border-color: var(--cv-primary); color: var(--cv-primary); background: var(--cv-primary-tint); transform: translateY(-1px); }
.cv-red-bandeja-icono { display: block; width: 30px; height: 30px; }
.cv-red-bandeja-icono svg { width: 100%; height: 100%; display: block; }

.cv-red-cable-btn { padding: 0.5rem 0.9rem; }
.cv-red-cable-activo { border-color: var(--cv-primary); color: var(--cv-primary); background: var(--cv-surface-2); }

/* Símbolo del sistema simulado -estilo consola clásica- */
#cv-red-terminal {
    display: none;
    margin-top: 0.75rem;
    background: #101418;
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    padding: 0.75rem;
    font-family: 'Courier New', Consolas, monospace;
    color: #d7ffd9;
    box-shadow: var(--cv-shadow-sm);
}
#cv-red-terminal h4 { margin: 0 0 0.5rem; color: #fff; font-family: var(--cv-font-sans); font-size: 0.85rem; }
.cv-red-terminal-salida {
    max-height: 220px;
    overflow-y: auto;
    font-size: 0.78rem;
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
}
.cv-red-terminal-entrada {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.4rem;
    font-size: 0.8rem;
}
.cv-red-terminal-entrada input {
    flex: 1;
    background: transparent;
    border: none;
    outline: none;
    color: #d7ffd9;
    font-family: 'Courier New', Consolas, monospace;
    font-size: 0.8rem;
}

/* Escritorio Windows 11 simulado -solo para PC, un Servidor se queda
   con la terminal clásica de arriba- */
.cv-win11 {
    background: linear-gradient(160deg, #2b5876, #0f3057 70%);
    border-radius: 10px;
    overflow: hidden;
    border: 1px solid var(--cv-border);
}
.cv-win11-escritorio { min-height: 260px; padding: 0.6rem; }
.cv-win11-taskbar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    background: rgba(15, 20, 30, 0.75);
    backdrop-filter: blur(6px);
    padding: 0.4rem 0.6rem;
}
.cv-win11-inicio { font-size: 1.1rem; color: #fff; margin-right: 0.4rem; }
.cv-win11-taskbtn {
    background: transparent;
    border: none;
    border-radius: 6px;
    padding: 0.35rem 0.6rem;
    font-size: 1rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    color: #fff;
}
.cv-win11-taskbtn span { font-size: 0.72rem; font-family: var(--cv-font-sans); }
.cv-win11-taskbtn:hover { background: rgba(255, 255, 255, 0.12); }
.cv-win11-taskbtn-activo { background: rgba(255, 255, 255, 0.22); }

.cv-win11-ventana {
    background: #101418;
    border-radius: 8px;
    padding: 0.75rem;
    font-family: 'Courier New', Consolas, monospace;
    color: #d7ffd9;
}
.cv-win11-ventana-barra {
    margin: -0.75rem -0.75rem 0.5rem;
    padding: 0.4rem 0.75rem;
    background: #1c2128;
    color: #fff;
    font-family: var(--cv-font-sans);
    font-size: 0.8rem;
    border-radius: 8px 8px 0 0;
}

.cv-win11-navegador { background: #f3f3f3; color: #222; padding: 0; overflow: hidden; }
.cv-win11-navegador-barra {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.7rem;
    background: #e4e4e4;
    border-bottom: 1px solid #ccc;
}
.cv-win11-navegador-punto { width: 8px; height: 8px; border-radius: 50%; background: #4caf50; flex-shrink: 0; }
.cv-win11-navegador-barra input {
    flex: 1;
    padding: 0.4rem 0.6rem;
    border-radius: 14px;
    border: 1px solid #ccc;
    font-family: var(--cv-font-sans);
    font-size: 0.8rem;
    background: #fff;
}
.cv-win11-navegador-barra button {
    padding: 0.4rem 0.9rem;
    border-radius: 14px;
    border: 1px solid var(--cv-primary);
    background: var(--cv-primary);
    color: #fff;
    font-size: 0.8rem;
    cursor: pointer;
}
.cv-win11-navegador-pagina {
    padding: 1.2rem;
    min-height: 160px;
    background: #fff;
    font-family: var(--cv-font-sans);
    display: flex;
    flex-direction: column;
}
.cv-win11-navegador-pagina h1 { font-size: 1.3rem; margin: 0 0 0.4rem; }
.cv-win11-navegador-marco {
    width: 100%;
    min-height: 320px;
    flex: 1;
    border: none;
    background: #fff;
}
.cv-win11-navegador-error { background: #fff; }
.cv-win11-navegador-error h2 { font-size: 1.05rem; color: #444; margin: 0 0 0.4rem; }
.cv-win11-navegador-error p { color: var(--cv-text-dim); font-size: 0.85rem; }

.cv-win11-explorador { background: #fff; color: #222; padding: 0; overflow: hidden; }
.cv-win11-explorador-cuerpo { display: flex; min-height: 180px; font-family: var(--cv-font-sans); font-size: 0.82rem; }
.cv-win11-explorador-lateral {
    width: 140px;
    flex-shrink: 0;
    background: #f7f7f7;
    border-right: 1px solid #e0e0e0;
    padding: 0.5rem 0;
}
.cv-win11-explorador-item { padding: 0.35rem 0.7rem; color: #444; }
.cv-win11-explorador-item-activo { background: #e3f0fd; color: var(--cv-primary); font-weight: 600; }
.cv-win11-explorador-principal { flex: 1; padding: 0.7rem; }
.cv-win11-explorador-equipo {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.3rem;
    border-bottom: 1px solid #f0f0f0;
}
.cv-win11-explorador-equipo span { font-size: 1.3rem; }
.cv-win11-explorador-equipo-nombre { font-weight: 600; }
.cv-win11-explorador-equipo-ip { color: var(--cv-text-dim); font-size: 0.75rem; }

.cv-prueba-vars { border-collapse: collapse; margin: 0.5rem 0; font-size: 0.85rem; width: 100%; }
.cv-prueba-vars th { background: var(--cv-surface-2); text-transform: uppercase; font-size: 0.72rem; letter-spacing: 0.03em; color: var(--cv-text-dim); }
.cv-prueba-vars th, .cv-prueba-vars td { border: 1px solid var(--cv-border); padding: 0.45rem 0.7rem; text-align: left; }
.cv-prueba-caso { font-size: 0.85rem; margin-bottom: 0.4rem; color: var(--cv-text-dim); }
.cv-prueba-salida { margin: 0.5rem 0; }

/* Tabla de la actividad "Subneteo" -actividad_subneteo.html/
   subneteo_ui.js-: IP y CIDR dados en negrita (no editables), el resto
   son celdas de entrada que se ponen en verde EN VIVO -sin recargar,
   sin pegarle al servidor- apenas el valor escrito coincide con el
   cálculo real para esa fila. */
/* Lista de "IP dada / CIDR dado" por ejercicio -ver actividad_subneteo
   .html-: la tabla de abajo ya no trae nada precargado, así que esto
   es lo único que le dice al estudiante qué transcribir en cada fila. */
.cv-subneteo-ejercicios { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.8rem 0; }
.cv-subneteo-ejercicio {
    display: inline-block; padding: 0.4rem 0.8rem; border-radius: 999px;
    background: var(--cv-primary-tint); color: var(--cv-primary-dark);
    font-family: 'Courier New', Consolas, monospace; font-size: 0.8rem; font-weight: 700;
}

.cv-subneteo-tabla-envoltura { overflow-x: auto; margin: 1rem 0; }
.cv-subneteo-tabla { border-collapse: collapse; width: 100%; font-size: 0.85rem; }
.cv-subneteo-tabla th {
    background: var(--cv-surface-2); text-transform: uppercase; font-size: 0.68rem;
    letter-spacing: 0.03em; color: var(--cv-text-dim); white-space: nowrap;
}
.cv-subneteo-tabla th, .cv-subneteo-tabla td {
    border: 1px solid var(--cv-border); padding: 0.5rem 0.6rem; text-align: left;
}
.cv-subneteo-input {
    width: 100%; min-width: 120px; padding: 0.4rem 0.5rem;
    border: 1.5px solid var(--cv-border); border-radius: 7px;
    font-family: 'Courier New', Consolas, monospace; font-size: 0.85rem;
    background: var(--cv-surface);
    transition: border-color var(--cv-dur-fast) var(--cv-ease-out), background var(--cv-dur-fast) var(--cv-ease-out), box-shadow var(--cv-dur-fast) var(--cv-ease-out);
}
.cv-subneteo-input:focus { outline: none; border-color: var(--cv-primary); box-shadow: 0 0 0 3px var(--cv-primary-tint); }
.cv-subneteo-input.cv-subneteo-correcto {
    border-color: var(--cv-success); background: #e9f7ef; color: var(--cv-success); font-weight: 700;
}

/* Laboratorio de subneteo -actividad_subneteo.html/subneteo_lab.js-,
   práctica libre encima de la tabla que sí califica: fondo con un
   ligero tinte cian para distinguirlo de un vistazo como "la parte
   que no cuenta". */
.cv-subneteo-lab {
    background: linear-gradient(180deg, rgba(0, 150, 214, 0.06), transparent 140px);
    border-color: #cfe8f5;
}

/* 1. Octeto binario ↔ decimal: 8 "fichas" clicables, cada una con su
   valor de potencia de 2 arriba y el dígito (0/1) abajo -se prende en
   azul cuando vale 1-. */
.cv-subneteo-bits { display: flex; gap: 0.4rem; flex-wrap: wrap; margin: 0.6rem 0; }
.cv-subneteo-bit {
    display: flex; flex-direction: column; align-items: center; gap: 0.15rem;
    width: 52px; padding: 0.5rem 0.3rem;
    border: 1.5px solid var(--cv-border); border-radius: 10px;
    background: var(--cv-surface); cursor: pointer;
    transition: transform var(--cv-dur-fast) var(--cv-ease-out), border-color var(--cv-dur-fast) var(--cv-ease-out), background var(--cv-dur-fast) var(--cv-ease-out), box-shadow var(--cv-dur-fast) var(--cv-ease-out);
}
.cv-subneteo-bit:hover { transform: translateY(-2px); box-shadow: var(--cv-shadow-sm); }
.cv-subneteo-bit:active { transform: scale(0.95); }
.cv-subneteo-bit-valor { font-size: 0.68rem; color: var(--cv-text-dim); }
.cv-subneteo-bit-digito { font-family: 'Courier New', Consolas, monospace; font-size: 1.15rem; font-weight: 700; color: var(--cv-text-dim); }
.cv-subneteo-bit-prendido {
    background: linear-gradient(135deg, var(--cv-primary), var(--cv-cyan));
    border-color: transparent;
}
.cv-subneteo-bit-prendido .cv-subneteo-bit-valor,
.cv-subneteo-bit-prendido .cv-subneteo-bit-digito { color: #fff; }
.cv-subneteo-octeto-decimal { display: flex; align-items: center; gap: 0.6rem; font-size: 1.1rem; }
.cv-subneteo-octeto-decimal strong { font-family: 'Courier New', Consolas, monospace; font-size: 1.4rem; color: var(--cv-primary); min-width: 2.5ch; }
.cv-subneteo-octeto-decimal input {
    padding: 0.4rem 0.6rem; border: 1.5px solid var(--cv-border); border-radius: 8px;
    font-family: 'Courier New', Consolas, monospace; font-size: 0.85rem; width: 220px;
}

/* 2. Constructor de máscara: slider de CIDR + 32 bits pintados en vivo
   -azules = red, grises = host-, agrupados de a 8 por octeto. */
.cv-subneteo-mascara-slider { display: flex; align-items: center; gap: 0.8rem; margin: 0.6rem 0; }
.cv-subneteo-mascara-slider input[type=range] { flex: 1; accent-color: var(--cv-primary); }
.cv-subneteo-mascara-slider strong { font-family: 'Courier New', Consolas, monospace; font-size: 1.1rem; color: var(--cv-primary); min-width: 3.5ch; }
.cv-subneteo-mascara-octetos { display: flex; gap: 0.7rem; flex-wrap: wrap; margin-bottom: 0.6rem; }
.cv-subneteo-mascara-octeto {
    display: flex; gap: 2px; padding: 0.4rem; border-radius: 8px; background: var(--cv-surface-2);
}
.cv-subneteo-mascara-bit {
    width: 14px; height: 20px; border-radius: 3px; background: var(--cv-border);
    transition: background var(--cv-dur-base) var(--cv-ease-out);
}
.cv-subneteo-mascara-bit-red { background: linear-gradient(180deg, var(--cv-primary), var(--cv-cyan)); }
.cv-subneteo-mascara-decimal { font-size: 0.88rem; color: var(--cv-text-dim); margin: 0 0 0.8rem; }
.cv-subneteo-mascara-decimal strong { color: var(--cv-text); font-family: 'Courier New', Consolas, monospace; }
.cv-subneteo-rango { margin-top: 0.8rem; }
.cv-subneteo-rango-linea {
    display: flex; align-items: center; gap: 0.5rem;
    font-size: 0.88rem; padding: 0.5rem 0; border-bottom: 1px dashed var(--cv-border);
}
.cv-subneteo-rango-linea:last-child { border-bottom: none; }
.cv-subneteo-rango-punto { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.cv-subneteo-rango-inicio { background: var(--cv-led-green); }
.cv-subneteo-rango-fin { background: var(--cv-danger); }

/* 3. ¿Cuántos hosts necesitas? -lista de intentos "h bits -> alcanza/
   no alcanza", la fila ganadora resaltada en verde para que se note
   de un vistazo cuál fue la que decidió el CIDR-. */
.cv-subneteo-hosts-filas { margin: 0.6rem 0; display: flex; flex-direction: column; gap: 0.3rem; }
.cv-subneteo-hosts-fila {
    display: flex; justify-content: space-between; gap: 0.6rem;
    padding: 0.4rem 0.7rem; border-radius: 8px; font-size: 0.82rem;
    background: var(--cv-surface-2); color: var(--cv-text-dim);
}
.cv-subneteo-hosts-fila-ok {
    background: #e9f7ef; color: var(--cv-success); font-weight: 700;
    border: 1px solid #cdedd9;
}

.cv-th-ordenable { cursor: pointer; user-select: none; white-space: nowrap; }
.cv-th-ordenable:hover { color: var(--cv-primary); }
.cv-th-ordenable::after { content: '\21C5'; display: inline-block; margin-left: 0.35rem; opacity: 0.35; font-size: 0.85em; }
.cv-th-orden-asc::after { content: '\2191'; opacity: 1; color: var(--cv-primary); }
.cv-th-orden-desc::after { content: '\2193'; opacity: 1; color: var(--cv-primary); }

.cv-prueba-nav {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-top: 0.75rem;
    font-size: 0.85rem;
    color: var(--cv-text-dim);
}

.cv-paleta-btn:disabled { opacity: 0.45; cursor: not-allowed; }

/* ===== Pestañas (Diagrama / Pseudocódigo) ===== */

.cv-tabs {
    display: flex;
    gap: 0.5rem;
    border-bottom: 1px solid var(--cv-border);
    margin: 1rem 0 1.25rem;
}

.cv-tab-btn {
    background: none;
    border: none;
    color: var(--cv-text-dim);
    padding: 0.6rem 0.2rem;
    margin-bottom: -1px;
    border-bottom: 2.5px solid transparent;
    font-size: 0.95rem;
    font-weight: 700;
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.cv-tab-btn + .cv-tab-btn { margin-left: 1rem; }

.cv-tab-btn:hover { color: var(--cv-text); }

.cv-tab-btn.cv-tab-activa { color: var(--cv-primary); border-bottom-color: var(--cv-primary); }

/* ===== Editor de pseudocódigo ===== */

.cv-pseudo-textarea {
    width: 100%;
    min-height: 320px;
    background: #10182c;
    color: #e7ebf7;
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    padding: 1rem;
    font-family: 'Courier New', Courier, monospace;
    font-size: 0.9rem;
    line-height: 1.5;
    tab-size: 4;
    resize: vertical;
    box-sizing: border-box;
}

.cv-pseudo-toolbar {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    margin-bottom: 0.6rem;
}

/* Regleta de números de línea (editor_lineas.js envuelve el textarea).
   Altura fija con desplazamiento por dentro, como el editor del espacio de
   trabajo: si el marco creciera con el código, una solución larga dejaría el
   resto de la actividad fuera de la pantalla. El tirador de abajo lo agranda. */
.cv-lineas {
    display: flex;
    height: min(58vh, 32rem);
    resize: vertical;
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    overflow: hidden;
    background: #10182c;
}
.cv-lineas .cv-pseudo-textarea {
    border: 0;
    border-radius: 0;
    flex: 1;
    min-width: 0;
    height: 100%;
    min-height: 0;
    resize: none;
    /* Sin ajuste de línea, como un editor de código: si una línea larga se
       partiera en dos filas, la regleta (un número por línea real) dejaría de
       coincidir. Se desplaza en horizontal. */
    white-space: pre;
    overflow-wrap: normal;
    overflow: auto;
}
.cv-lineas-num {
    margin: 0;
    padding: 1rem 0.55rem;
    text-align: right;
    color: #7c8bb0;
    background: #0c1327;
    border-right: 1px solid #2b3552;
    font-family: 'Courier New', Courier, monospace;
    font-size: 0.9rem;
    line-height: 1.5;
    white-space: pre;
    height: 100%;
    overflow: hidden;
    user-select: none;
    -webkit-user-select: none;
    min-width: 2.1rem;
    box-sizing: border-box;
}

.cv-autocomplete-menu {
    display: none;
    position: fixed;
    z-index: 50;
    background: #10182c;
    border: 1px solid #2b3552;
    border-radius: 8px;
    box-shadow: var(--cv-shadow-lift);
    min-width: 160px;
    max-height: 220px;
    overflow-y: auto;
    font-family: 'Courier New', Courier, monospace;
    font-size: 0.85rem;
}

.cv-autocomplete-item { padding: 0.35rem 0.7rem; cursor: pointer; color: #e7ebf7; }
.cv-autocomplete-item:hover, .cv-autocomplete-activo { background: var(--cv-primary); color: #ffffff; }

/* ===== Consola interactiva de pseudocódigo ===== */

.cv-consola {
    background: #0a0f1e;
    border: 1px solid #1e2740;
    border-radius: 10px;
    padding: 0.85rem 1rem;
    min-height: 140px;
    max-height: 320px;
    overflow-y: auto;
    font-family: 'Courier New', Courier, monospace;
    font-size: 0.85rem;
    line-height: 1.6;
}

.cv-consola-linea { white-space: pre-wrap; word-break: break-word; }
.cv-consola-salida { color: #e7ebf7; }
.cv-consola-eco { color: #7fa0ff; }
.cv-consola-error { color: #ff8f8f; }
.cv-consola-fin { color: #6fe0a0; margin-top: 0.3rem; }
.cv-consola-nota { color: #8b97ab; }

/* La consola guiada del ABP («construir desde la actividad», más abajo en este
   archivo) reusa las clases .cv-consola* con estilo claro. Sin este bloque, su
   `.cv-consola-error { background:#fff2f0 }` pinta un recuadro claro dentro de
   la consola oscura del pseudocódigo/Java. Se ancla por id, que gana siempre. */
#cv-pseudo-consola, #cv-java-consola { display: block; background: #0a0f1e; }
#cv-pseudo-consola .cv-consola-linea,
#cv-java-consola .cv-consola-linea { background: transparent; border: 0; padding: 0; }
#cv-pseudo-consola .cv-consola-error,
#cv-java-consola .cv-consola-error { background: transparent; color: #ff8f8f; }
#cv-pseudo-consola .cv-consola-eco,
#cv-java-consola .cv-consola-eco { background: transparent; color: #7fa0ff; border: 0; }
#cv-pseudo-consola .cv-consola-salida,
#cv-java-consola .cv-consola-salida { background: transparent; color: #e7ebf7; }

.cv-consola-entrada-form {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: #f5c168;
    margin-top: 0.2rem;
}

.cv-consola-input {
    background: #1a2340;
    border: 1px solid #4d6be0;
    border-radius: 5px;
    color: #e7ebf7;
    padding: 0.15rem 0.5rem;
    font-family: inherit;
    font-size: inherit;
    width: 140px;
}

/* ===== Lanzador de aplicaciones (accesos del curso) ===== */

.cv-launcher {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 0.9rem;
    margin: 1.1rem 0 1.4rem;
}

.cv-launcher-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.6rem;
    text-align: center;
    text-decoration: none;
    color: var(--cv-text);
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 16px;
    padding: 1.1rem 0.75rem 0.9rem;
    box-shadow: var(--cv-shadow-sm);
    transition: transform var(--cv-dur-base) var(--cv-ease-out), box-shadow var(--cv-dur-base) var(--cv-ease-out), border-color var(--cv-dur-base) var(--cv-ease-out);
}

.cv-launcher-tile:hover {
    transform: translateY(-4px);
    box-shadow: var(--cv-shadow-md);
    border-color: #ccd4ec;
}

.cv-launcher-icon {
    width: 3rem;
    height: 3rem;
    border-radius: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
}

.cv-launcher-icon svg { width: 1.6rem; height: 1.6rem; }

/* Un color por destino, todos dentro de la identidad del sitio -azul,
   azul marino y amarillo-: el estudiante reconoce el mosaico por
   color antes de leer la etiqueta. En el amarillo el ícono va en azul
   marino (`color`, que es lo que usan los SVG por currentColor):
   blanco sobre amarillo no se ve. */
.cv-launcher-icon-calificaciones { background: linear-gradient(135deg, var(--cv-primary), #4d6be0); }
.cv-launcher-icon-asistencia { background: linear-gradient(135deg, var(--cv-navy), #0369a1); }
.cv-launcher-icon-foro { background: linear-gradient(135deg, var(--cv-accent), #7dd3fc); color: var(--cv-navy); }
.cv-launcher-icon-laboratorio { background: linear-gradient(135deg, #0369a1, var(--cv-primary)); }
.cv-launcher-icon-basedatos { background: linear-gradient(135deg, var(--cv-primary-dark, #1f3a8a), #3f8fd6); }
.cv-launcher-icon-consola { background: linear-gradient(135deg, #1f2937, #4b5b74); }

.cv-launcher-label { font-weight: 700; font-size: 0.85rem; }

/* ===== Asistencia ===== */

.cv-asistencia-estado {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    padding: 1.5rem;
}

.cv-asistencia-icono {
    width: 3.5rem;
    height: 3.5rem;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 1.6rem;
}

.cv-asistencia-icono-ok { background: #e5f6ec; color: var(--cv-success); }
.cv-asistencia-icono-espera { background: var(--cv-primary-tint); color: var(--cv-primary); }
.cv-asistencia-icono-error { background: #fdedee; color: var(--cv-danger); }

/* Actividad TABLA: diseño multi-tabla + diagrama en vivo */
.cv-tabla-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(260px, 1fr);
    gap: 1.5rem;
    align-items: start;
}
@media (max-width: 900px) {
    .cv-tabla-layout { grid-template-columns: 1fr; }
}

.cv-tabla-bloque {
    border: 1.5px solid var(--cv-border);
    border-radius: 10px;
    padding: 1rem;
    margin-bottom: 1rem;
    background: var(--cv-surface-2);
    /* La tabla de campos (nombre/tipo/longitud/PK/FK/nulo/AI) no cabe en
       columnas angostas -sin esto, se desbordaba encima del panel del
       diagrama en vez de quedarse dentro de su propia columna-. */
    overflow-x: auto;
}
.cv-tabla-bloque table { min-width: 560px; }
.cv-tabla-bloque-encabezado {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.7rem;
    flex-wrap: wrap;
}
.cv-tabla-bloque-encabezado input.cv-tabla-nombre {
    flex: 1;
    min-width: 180px;
    padding: 0.5rem;
    font-weight: 600;
}

.cv-tabla-diagrama {
    position: sticky;
    top: 1rem;
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    padding: 1rem;
    background: var(--cv-surface);
}
.cv-tabla-diagrama-lienzo {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    position: relative; /* ancla el <svg> de las líneas de relación, ver tabla_ui.js */
}
.cv-tabla-diagrama-vacio {
    font-size: 0.85rem;
    color: var(--cv-text-dim);
}
/* Diagrama de una base LAB_BD real (lab_bd_diagrama.js): a diferencia del
   lienzo de arriba (columna fija, sin arrastre), acá las cajas se
   posicionan libremente -position:absolute- para poder organizarlas como
   en el Designer de phpMyAdmin, y la posición de cada una se autoguarda. */
.cv-lab-bd-lienzo {
    position: relative;
    min-height: 420px;
    max-height: 640px;
    overflow: auto;
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    background: var(--cv-surface-2);
}
.cv-tabla-caja-arrastrable {
    position: absolute;
}
.cv-tabla-caja-arrastrable .cv-tabla-caja-titulo {
    cursor: move;
    user-select: none;
}
/* Estilo tipo phpMyAdmin (pestaña Diseñador): cabecera clara con un
   badge cuadrado "T" en vez de un ícono decorativo, filas "nombre : tipo"
   con cebra e ícono de llave en la PK, esquinas rectas -sin líneas de
   relación en el estudiante, eso sigue siendo deliberado, ver
   tabla_ui.js-. Misma estructura la usa docente_tabla_diagrama.js para
   el diagrama de solo lectura del docente. */
.cv-tabla-caja {
    border: 1px solid #6c7680;
    border-radius: 0;
    overflow: hidden;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
    font-size: 0.8rem;
    box-shadow: 0 1px 2px rgba(20, 40, 60, 0.15);
    background: #fff;
}
.cv-tabla-caja-titulo {
    background: #eef0f2;
    color: #1a1a1a;
    padding: 0.35rem 0.55rem;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    border-bottom: 1px solid #6c7680;
}
.cv-tabla-caja-titulo-icono {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.2em;
    height: 1.2em;
    flex-shrink: 0;
    background: #2f3b52;
    color: #fff;
    font-size: 0.68em;
    font-weight: 700;
    border-radius: 2px;
}
.cv-tabla-caja-titulo-nombre { font-weight: 700; }
.cv-tabla-caja-campo {
    padding: 0.28rem 0.55rem;
    border-top: 1px solid #dcdfe3;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    background: #fff;
}
.cv-tabla-caja-campo:nth-child(even) { background: #f1f3f5; }
.cv-tabla-caja-campo:first-of-type { border-top: none; }
.cv-tabla-caja-campo-nombre { color: #1a1a1a; }
.cv-tabla-caja-campo-icono { display: inline-flex; width: 1.1em; justify-content: center; flex-shrink: 0; }
.cv-tabla-caja-campo-pk { font-weight: 700; }
.cv-tabla-caja-campo-dospuntos { color: #8a97a3; }
.cv-tabla-caja-campo-tipo { color: #5a6672; }

/* Modelo entidad-relación: campos clicables para conectar una relación
   (solo cuando la actividad trae relaciones_requeridas, ver tabla_ui.js). */
.cv-tabla-caja-campo-clic { cursor: pointer; }
.cv-tabla-caja-campo-clic:hover { background: #dfeaf5; }
.cv-tabla-caja-campo-armado { background: #fff3cd !important; outline: 2px dashed #c9a227; outline-offset: -2px; }

.cv-tabla-svg {
    position: absolute;
    top: 0; left: 0;
    pointer-events: none; /* las líneas no deben tapar el clic sobre los campos */
    overflow: visible;
}
.cv-tabla-linea-relacion {
    fill: none;
    stroke: #3f5a76;
    stroke-width: 1.5;
}
.cv-tabla-punto-relacion { fill: #3f5a76; }
.cv-tabla-etiqueta-relacion {
    font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
    font-size: 11px;
    font-weight: 700;
    fill: #3f5a76;
}

/* Consola SQL del modelo entidad-relación (modo_consola, ver tabla_ui.js):
   el estudiante escribe CREATE TABLE en vez de usar el formulario gráfico. */
.cv-tabla-consola-historial {
    background: #0a0f1e;
    border: 1px solid #1e2740;
    border-radius: 10px 10px 0 0;
    padding: 0.7rem 0.9rem;
    max-height: 260px;
    overflow-y: auto;
    font-family: 'Courier New', Consolas, monospace;
    font-size: 0.8rem;
    line-height: 1.55;
}
.cv-tabla-consola-linea { margin-bottom: 0.5rem; }
.cv-tabla-consola-linea:last-child { margin-bottom: 0; }
.cv-consola-eco { color: #7fa0ff; white-space: pre-wrap; word-break: break-word; }
.cv-tabla-consola-entrada {
    display: block;
    width: 100%;
    box-sizing: border-box;
    background: #10182e;
    border: 1px solid #1e2740;
    border-top: none;
    color: #e7ebf7;
    padding: 0.7rem 0.9rem;
    font-family: 'Courier New', Consolas, monospace;
    font-size: 0.83rem;
    line-height: 1.5;
    resize: vertical;
}
.cv-tabla-consola-entrada:focus { outline: none; border-color: #4d6be0; }
.cv-tabla-consola-barra {
    display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap;
    background: #10182e;
    border: 1px solid #1e2740;
    border-top: none;
    border-radius: 0 0 10px 10px;
    padding: 0.55rem 0.9rem;
}
.cv-tabla-consola-ayuda { font-size: 0.78rem; color: #8b97ab; }

/* Panel "Relaciones": una fila por relación dibujada, con su selector de
   cardinalidad -ver panelRelaciones en tabla_ui.js-. */
.cv-relacion-fila {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    padding: 0.5rem 0;
    border-top: 1px solid var(--cv-border);
    font-size: 0.82rem;
}
.cv-relacion-fila:first-of-type { border-top: none; }
.cv-relacion-campo {
    font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
    color: #2c3e50;
}
.cv-relacion-cardinalidad { padding: 0.3rem; font-size: 0.8rem; }
.cv-relacion-quitar { font-size: 0.75rem; padding: 0.25rem 0.5rem; }

/* Lanzador de aplicaciones (icono de nueve puntos) en el header: un
   acceso directo por curso, para saltar a uno sin pasar por el
   dashboard -mismo patrón visual/interacción que el lanzador de
   Intevra Workspace, adaptado a la paleta de Campus Virtual-. */
.cv-lanzador { position: relative; }
.cv-lanzador-boton {
    width: 32px; height: 32px;
    display: flex; align-items: center; justify-content: center;
    border: 1px solid var(--cv-border); border-radius: 8px;
    background: var(--cv-surface); color: var(--cv-text-dim); cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease, transform 0.15s ease;
}
.cv-lanzador-boton:hover { color: var(--cv-primary); border-color: var(--cv-primary); transform: translateY(-1px); }
.cv-lanzador-boton svg { width: 17px; height: 17px; transition: transform var(--cv-dur-slow) var(--cv-ease-spring); }
.cv-lanzador-boton[aria-expanded="true"] { color: var(--cv-primary); border-color: var(--cv-primary); background: var(--cv-primary-tint); }
.cv-lanzador-boton[aria-expanded="true"] svg { transform: rotate(90deg); }

.cv-lanzador-panel {
    position: absolute; right: 0; top: 42px; z-index: 1100;
    width: min(336px, calc(100vw - 2rem));
    padding: 0.9rem;
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 16px;
    box-shadow: var(--cv-shadow-lift);
    transform-origin: top right;
    opacity: 0; transform: scale(0.92) translateY(-8px);
    transition: opacity var(--cv-dur-base) var(--cv-ease-out), transform var(--cv-dur-slow) var(--cv-ease-spring);
    pointer-events: none;
}
.cv-lanzador-panel[hidden] { display: none; }
.cv-lanzador-panel.cv-abierto { opacity: 1; transform: scale(1) translateY(0); pointer-events: auto; }
.cv-lanzador-titulo {
    margin: 1rem 0 0.6rem; padding: 0 0.15rem;
    font-size: 0.7rem; font-weight: 800;
    text-transform: uppercase; letter-spacing: 0.06em; color: var(--cv-text-dim);
}
.cv-lanzador-cuerpo {
    max-height: min(72vh, 520px); overflow-y: auto;
    display: flex; flex-direction: column;
}

/* --- accesos generales: mosaico de 3 --- */
.cv-lanzador-rejilla {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.4rem;
}
.cv-lanzador-app {
    display: flex; flex-direction: column; align-items: center; gap: 0.45rem;
    padding: 0.75rem 0.3rem; border-radius: 12px;
    color: var(--cv-text); text-decoration: none; text-align: center;
    transition: background 0.15s ease, transform 0.15s ease;
}
.cv-lanzador-app:hover { background: var(--cv-primary-tint); transform: translateY(-2px); }
.cv-lanzador-icono {
    width: 40px; height: 40px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 12px; color: #fff;
    background: linear-gradient(145deg, var(--cv-primary), var(--cv-primary-dark));
    box-shadow: 0 6px 14px rgba(18, 41, 79, 0.24);
}
.cv-lanzador-icono svg { width: 20px; height: 20px; }
.cv-lanzador-app:nth-child(3n+2) .cv-lanzador-icono { background: linear-gradient(145deg, var(--cv-navy), #0369a1); }
.cv-lanzador-app:nth-child(3n+3) .cv-lanzador-icono {
    background: linear-gradient(145deg, var(--cv-accent), #7dd3fc);
    color: var(--cv-navy);
    box-shadow: 0 6px 14px rgba(196, 160, 0, 0.24);
}
.cv-lanzador-etiqueta { font-size: 0.72rem; font-weight: 700; line-height: 1.2; }

/* --- lista de cursos --- */
.cv-lanzador-cursos { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.15rem; }
.cv-lanzador-curso {
    display: flex; flex-direction: column; gap: 0.15rem;
    padding: 0.4rem 0.35rem;
    border-radius: 10px;
}
.cv-lanzador-curso + .cv-lanzador-curso { border-top: 1px solid var(--cv-border); }
.cv-lanzador-curso-nombre {
    display: flex; align-items: center; gap: 0.55rem;
    font-size: 0.86rem; font-weight: 700; color: var(--cv-navy);
    text-decoration: none;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cv-lanzador-curso-nombre:hover { color: var(--cv-primary); }
.cv-lanzador-curso-icono {
    flex: none; width: 26px; height: 26px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 8px; color: var(--cv-primary);
    background: var(--cv-primary-tint);
}
.cv-lanzador-curso-icono svg { width: 15px; height: 15px; }
.cv-lanzador-curso-accesos {
    display: flex; flex-wrap: wrap; gap: 0.3rem 0.5rem;
    padding-left: calc(26px + 0.55rem);
}
.cv-lanzador-curso-accesos a {
    font-size: 0.74rem; font-weight: 600;
    color: var(--cv-text-dim); text-decoration: none;
    padding: 0.1rem 0.5rem; border-radius: 999px;
    background: color-mix(in srgb, var(--cv-navy) 6%, transparent);
}
.cv-lanzador-curso-accesos a:hover { color: var(--cv-primary); background: var(--cv-primary-tint); }

/* Campanita de notificaciones del header -mismo patrón visual/de
   interacción que el lanzador de aplicaciones justo arriba, ver
   notificaciones.js-. */
.cv-notif { position: relative; }
.cv-notif-boton {
    width: 32px; height: 32px; position: relative;
    display: flex; align-items: center; justify-content: center;
    border: 1px solid var(--cv-border); border-radius: 8px;
    background: var(--cv-surface); color: var(--cv-text-dim); cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease, transform 0.15s ease;
}
.cv-notif-boton:hover { color: var(--cv-primary); border-color: var(--cv-primary); transform: translateY(-1px); }
.cv-notif-boton svg { width: 17px; height: 17px; }
.cv-notif-boton[aria-expanded="true"] { color: var(--cv-primary); border-color: var(--cv-primary); background: var(--cv-primary-tint); }
.cv-notif-badge {
    position: absolute; top: -5px; right: -5px;
    min-width: 16px; height: 16px; padding: 0 3px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 999px; background: var(--cv-danger); color: #fff;
    font-size: 0.65rem; font-weight: 800; line-height: 1;
}
.cv-notif-panel {
    position: absolute; right: 0; top: 42px; z-index: 1100;
    width: min(320px, calc(100vw - 2rem));
    padding: 1.1rem;
    background: rgba(255, 255, 255, 0.82);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border: 1px solid var(--cv-border);
    border-radius: 16px;
    box-shadow: var(--cv-shadow-lift);
    transform-origin: top right;
    opacity: 0; transform: scale(0.92) translateY(-8px);
    transition: opacity var(--cv-dur-base) var(--cv-ease-out), transform var(--cv-dur-slow) var(--cv-ease-spring);
    pointer-events: none;
}
.cv-notif-panel[hidden] { display: none; }
.cv-notif-panel.cv-abierto { opacity: 1; transform: scale(1) translateY(0); pointer-events: auto; }
.cv-notif-item {
    display: flex; flex-direction: column; gap: 0.15rem;
    padding: 0.6rem 0.5rem; border-radius: 10px;
    color: var(--cv-text); text-decoration: none;
    transition: background 0.15s ease;
    max-height: 320px;
}
.cv-notif-item + .cv-notif-item { margin-top: 0.2rem; }
.cv-notif-item:hover { background: var(--cv-primary-tint); }
.cv-notif-item strong { font-size: 0.85rem; }
.cv-notif-item span { font-size: 0.78rem; color: var(--cv-text-dim); }
.cv-notif-item small { font-size: 0.72rem; color: var(--cv-text-dim); }
.cv-notif-vacio { font-size: 0.82rem; color: var(--cv-text-dim); margin: 0; }

/* ===== Foro ===== */

.cv-foro-header { display: flex; align-items: center; gap: 0.9rem; margin-bottom: 0.3rem; }
.cv-foro-header-icono {
    width: 48px; height: 48px; border-radius: 14px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(145deg, var(--cv-primary), var(--cv-primary-dark));
    color: #fff; box-shadow: var(--cv-shadow-sm);
}
.cv-foro-header-icono svg { width: 24px; height: 24px; }
.cv-foro-header h2 { margin: 0; }
.cv-foro-header p { margin: 0.15rem 0 0; color: var(--cv-text-dim); font-size: 0.9rem; }

.cv-foro-composer { border-top: 3px solid var(--cv-primary); }

.cv-foro-avatar {
    width: 44px; height: 44px; border-radius: 50%; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    color: #fff; font-weight: 800; font-size: 1.05rem; font-family: var(--cv-font-serif);
    box-shadow: var(--cv-shadow-sm);
}
.cv-foro-avatar-sm { width: 36px; height: 36px; font-size: 0.92rem; }

.cv-foro-tema-card { display: flex; gap: 1rem; text-decoration: none; color: inherit; }
a.cv-foro-tema-card:hover { transform: translateY(-3px); box-shadow: var(--cv-shadow-md); border-color: #ccd4ec; }
.cv-foro-tema-cuerpo { flex: 1; min-width: 0; }
.cv-foro-tema-titulo-fila { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.3rem; }
.cv-foro-tema-titulo-fila h3 { margin: 0; font-size: 1.15rem; transition: color 0.15s ease; }
.cv-foro-tema-card:hover h3 { color: var(--cv-primary); }
.cv-foro-tema-extracto {
    margin: 0 0 0.6rem; color: var(--cv-text-dim); font-size: 0.9rem; line-height: 1.5;
    overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.cv-foro-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; font-size: 0.8rem; color: var(--cv-text-dim); }
.cv-foro-meta-sep { opacity: 0.6; }

.cv-badge-fijado { background: var(--cv-accent-soft); color: var(--cv-accent-dark); }
.cv-badge-docente { background: var(--cv-primary-tint); color: var(--cv-primary); }

.cv-foro-tema-encabezado { display: flex; gap: 1rem; align-items: flex-start; }
.cv-foro-tema-encabezado-cuerpo { flex: 1; min-width: 0; }
.cv-foro-tema-acciones { display: flex; justify-content: flex-end; margin-top: 0.6rem; }

.cv-foro-respuestas-titulo { display: flex; align-items: center; gap: 0.5rem; }
.cv-foro-respuestas-titulo .cv-badge { background: var(--cv-surface-2); color: var(--cv-text-dim); }

.cv-foro-respuesta { display: flex; gap: 0.85rem; }
.cv-foro-respuesta-cuerpo { flex: 1; min-width: 0; }
.cv-foro-respuesta-encabezado { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; margin-bottom: 0.4rem; }
.cv-foro-respuesta-autor { display: flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; flex-wrap: wrap; }
.cv-foro-respuesta-autor strong { color: var(--cv-text); }
.cv-foro-respuesta-fecha { color: var(--cv-text-dim); font-size: 0.78rem; }

.cv-foro-btn-icono {
    display: inline-flex; align-items: center; gap: 0.3rem;
    border: 1px solid var(--cv-border); background: var(--cv-surface); color: var(--cv-text-dim);
    border-radius: 8px; padding: 0.35rem 0.7rem; font-size: 0.78rem; font-weight: 600; cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.cv-foro-btn-icono:hover { color: var(--cv-danger); border-color: var(--cv-danger); background: #fdedee; }

.cv-foro-vacio { text-align: center; padding: 2.5rem 1.5rem; color: var(--cv-text-dim); }
.cv-foro-vacio-icono { font-size: 2.2rem; margin-bottom: 0.6rem; }

/* Contenido enriquecido -salida de foro_formato, ver templatetags/foro_extras.py-. */
.cv-foro-contenido { line-height: 1.7; font-size: 0.98rem; }
.cv-foro-contenido p { margin: 0 0 0.9rem; }
.cv-foro-contenido p:last-child { margin-bottom: 0; }
.cv-foro-contenido ul, .cv-foro-contenido ol { margin: 0 0 0.9rem; padding-left: 1.4rem; }
.cv-foro-contenido li { margin-bottom: 0.3rem; }
.cv-foro-contenido blockquote {
    margin: 0 0 0.9rem; padding: 0.5rem 1rem;
    border-left: 3px solid var(--cv-accent); background: var(--cv-surface-2);
    border-radius: 0 8px 8px 0; color: var(--cv-text-dim); font-style: italic;
}
.cv-foro-contenido code {
    background: var(--cv-surface-2); border: 1px solid var(--cv-border); border-radius: 4px;
    padding: 0.1rem 0.4rem; font-family: 'Courier New', monospace; font-size: 0.88em;
}
.cv-foro-contenido h3, .cv-foro-contenido h4 { margin: 0.9rem 0 0.4rem; }
.cv-foro-contenido a { color: var(--cv-primary); text-decoration: underline; text-underline-offset: 2px; }
.cv-foro-contenido a:hover { color: var(--cv-primary-dark); }

/* Editor con barra de formato -ver foro.js/_foro_editor.html-. */
.cv-editor {
    border: 1.5px solid var(--cv-border); border-radius: 10px; overflow: hidden;
    margin-bottom: 0.6rem; transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.cv-editor:focus-within { border-color: var(--cv-primary); box-shadow: 0 0 0 3px var(--cv-primary-tint); }
.cv-editor-toolbar {
    display: flex; align-items: center; gap: 0.15rem; padding: 0.4rem;
    background: var(--cv-surface-2); border-bottom: 1px solid var(--cv-border); flex-wrap: wrap;
}
.cv-editor-toolbar button {
    width: 28px; height: 28px; border: none; border-radius: 6px;
    background: transparent; color: var(--cv-text-dim); cursor: pointer; font-size: 0.85rem;
    display: flex; align-items: center; justify-content: center;
    transition: background 0.12s ease, color 0.12s ease;
}
.cv-editor-toolbar button:hover { background: var(--cv-surface); color: var(--cv-primary); }
.cv-editor-separador { width: 1px; align-self: stretch; margin: 0.2rem 0.3rem; background: var(--cv-border); }
.cv-editor textarea {
    border: none !important; border-radius: 0 !important; margin-bottom: 0 !important; resize: vertical;
}
.cv-editor textarea:focus { box-shadow: none !important; }
.cv-editor-ayuda { margin: 0.4rem 0 1rem; font-size: 0.76rem; color: var(--cv-text-dim); }

/* ===== Mensajes: widget flotante estilo LinkedIn (chat_widget.js) ===== */

.cv-chat-widget {
    position: fixed;
    right: 1.5rem;
    bottom: 0;
    z-index: 60;
    font-family: var(--cv-font-sans);
}

.cv-chat-widget-boton {
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.7rem 1.1rem;
    background: var(--cv-navy); color: #fff;
    border: none; border-radius: 12px 12px 0 0;
    font-weight: 700; font-size: 0.9rem; cursor: pointer;
    box-shadow: 0 -2px 10px rgba(18, 41, 79, 0.18);
    transition: background var(--cv-dur-fast) var(--cv-ease-out);
}
.cv-chat-widget-boton:hover { background: var(--cv-primary-dark); }
.cv-chat-widget-boton svg { width: 18px; height: 18px; }
/* .cv-notif-badge trae su propio display:flex -bien para el uso que ya
   tenía (el span ni se renderiza si no hay notificaciones), pero acá
   el badge del widget SIEMPRE está en el DOM y se oculta con hidden-. */
#cv-chat-widget-badge[hidden] { display: none; }

/* Panel apoyado justo arriba de la pastilla -mismo "ancla" visual que
   LinkedIn-. position:absolute con bottom:100% respecto a
   .cv-chat-widget (position:fixed), no position:fixed propio, para que
   quede pegado al botón sin recalcular su posición a mano. */
/* :not([hidden]) -mismo motivo que en .cv-chat-widget-cabecera button:
   un display:flex de clase le gana en especificidad al display:none
   que trae el atributo hidden por defecto, y el panel se seguía
   viendo aunque JS le pusiera hidden-. */
.cv-chat-widget-panel:not([hidden]) {
    position: absolute;
    right: 0; bottom: 100%;
    width: 320px; height: 440px;
    max-height: calc(100vh - 6rem);
    background: var(--cv-surface);
    border-radius: 14px 14px 0 0;
    box-shadow: var(--cv-shadow-lift);
    display: flex; flex-direction: column;
    overflow: hidden;
    animation: cv-tarjeta-entra var(--cv-dur-slow) var(--cv-ease-out) both;
}

.cv-chat-widget-cabecera {
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.75rem 1rem;
    background: var(--cv-navy); color: #fff;
    flex-shrink: 0;
}
.cv-chat-widget-titulo-bloque { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.cv-chat-widget-cabecera strong { font-size: 0.95rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Estado bajo el nombre -"En línea" o "Última vez hace..."-, solo
   ocupa espacio cuando hay una conversación abierta -mostrarLista()
   lo deja vacío-. */
#cv-chat-widget-estado { font-size: 0.72rem; color: rgba(255, 255, 255, 0.65); }
#cv-chat-widget-estado.cv-chat-widget-en-linea { color: #7be3a8; font-weight: 700; }
/* :not([hidden]) -si no, este display:flex le gana en especificidad al
   display:none que trae el atributo hidden por defecto, y el botón
   "atrás" se seguía viendo en la vista de lista aunque tuviera
   hidden-. */
.cv-chat-widget-cabecera button:not([hidden]) {
    display: flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; padding: 0;
    background: transparent; border: none; border-radius: 6px;
    color: #fff; cursor: pointer;
}
.cv-chat-widget-cabecera button:hover { background: rgba(255, 255, 255, 0.15); }
.cv-chat-widget-cabecera button svg { width: 16px; height: 16px; }

.cv-chat-widget-cuerpo {
    flex: 1; overflow-y: auto; padding: 0.5rem;
}

.cv-chat-widget-cargando, .cv-chat-widget-vacio {
    padding: 1.5rem 1rem; text-align: center; color: var(--cv-text-dim); font-size: 0.88rem;
}

.cv-chat-widget-seccion {
    margin: 0.6rem 0.5rem 0.3rem; font-size: 0.72rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.03em; color: var(--cv-text-dim);
}
.cv-chat-widget-curso { margin: 0.5rem 0.5rem 0.1rem; font-size: 0.78rem; font-weight: 700; color: var(--cv-primary); }

.cv-chat-widget-item {
    display: flex; align-items: center; gap: 0.6rem; width: 100%;
    padding: 0.55rem 0.5rem; background: transparent; border: none; border-radius: 10px;
    text-align: left; cursor: pointer;
    transition: background var(--cv-dur-fast) var(--cv-ease-out);
}
.cv-chat-widget-item:hover { background: var(--cv-primary-tint); }
.cv-chat-widget-item-cuerpo { flex: 1; min-width: 0; }
.cv-chat-widget-item-fila { display: flex; align-items: center; gap: 0.4rem; }
.cv-chat-widget-item-fila strong { color: var(--cv-navy); font-size: 0.88rem; }
.cv-chat-widget-item-preview {
    display: block; color: var(--cv-text-dim); font-size: 0.8rem;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cv-chat-widget-item-estado {
    display: block; font-size: 0.78rem; color: var(--cv-text-dim);
}
.cv-chat-widget-item-estado.cv-chat-widget-en-linea { color: var(--cv-success); font-weight: 700; }

/* Envoltorio del avatar -position:relative para anclar el puntico de
   presencia en la esquina, igual que .cv-notif-badge sobre la
   campanita-. */
.cv-chat-widget-avatar-wrap { position: relative; flex-shrink: 0; display: inline-flex; }
.cv-chat-widget-punto {
    position: absolute; right: -1px; bottom: -1px;
    width: 11px; height: 11px; border-radius: 50%;
    background: var(--cv-success); border: 2px solid var(--cv-surface);
}

/* Hilo de mensajes dentro del panel del widget -mismo concepto de
   burbujas que cualquier chat, con scroll propio-. */
.cv-chat-hilo {
    display: flex; flex-direction: column; gap: 0.5rem;
    padding: 0.75rem;
}
.cv-chat-widget-hilo { height: 100%; overflow-y: auto; }

.cv-chat-burbuja {
    max-width: 78%; padding: 0.5rem 0.75rem; border-radius: 14px;
    box-shadow: var(--cv-shadow-sm);
}
.cv-chat-burbuja p { margin: 0; white-space: pre-wrap; word-break: break-word; font-size: 0.88rem; }
.cv-chat-burbuja small { display: block; margin-top: 0.2rem; font-size: 0.68rem; opacity: 0.75; }

.cv-chat-burbuja-mia {
    align-self: flex-end;
    background: var(--cv-primary); color: #fff;
    border-bottom-right-radius: 4px;
}
.cv-chat-burbuja-otro {
    align-self: flex-start;
    background: var(--cv-surface-2); color: var(--cv-text);
    border-bottom-left-radius: 4px;
}

.cv-chat-composer:not([hidden]) {
    display: flex; gap: 0.5rem; align-items: flex-end;
    padding: 0.6rem; border-top: 1px solid var(--cv-border); flex-shrink: 0;
}
.cv-chat-composer textarea {
    flex: 1; resize: none; min-height: 2.3rem; max-height: 5rem; margin-bottom: 0; font-size: 0.85rem;
}
.cv-chat-composer .cv-btn { padding: 0.5rem 0.9rem; font-size: 0.82rem; }
.cv-chat-composer-icono {
    flex-shrink: 0; width: 2rem; height: 2rem; padding: 0.35rem;
    border: 0; background: transparent; color: var(--cv-text-dim);
    border-radius: 8px; cursor: pointer; line-height: 0;
}
.cv-chat-composer-icono:hover { background: var(--cv-surface-2); color: var(--cv-navy); }
.cv-chat-composer-icono svg { width: 100%; height: 100%; }
.cv-chat-composer-icono:disabled { opacity: 0.4; cursor: default; }
#cv-chat-widget-zumbido-btn { color: #d97706; }
#cv-chat-widget-zumbido-btn:hover { background: #fef3c7; color: #b45309; }

/* Zumbido (Nudge de MSN/Windows Live Messenger): aviso dentro del chat... */
.cv-chat-burbuja-zumbido { background: #fffbeb !important; border: 1px solid #fcd34d; }
.cv-chat-zumbido-aviso { display: block; font-weight: 600; color: #b45309; font-size: 0.9rem; }

/* ...y el temblor de TODA la pantalla al enviarlo/recibirlo -se aplica a
   <body> desde chat_widget.js::zumbarPantalla(), quitándose solo a los
   600ms-. Vaivén corto y decreciente, como el nudge clásico. */
@keyframes cv-zumbido-anim {
    0%, 100% { transform: translate(0, 0); }
    10% { transform: translate(-10px, -6px); }
    20% { transform: translate(10px, 6px); }
    30% { transform: translate(-9px, 5px); }
    40% { transform: translate(9px, -5px); }
    50% { transform: translate(-7px, -4px); }
    60% { transform: translate(7px, 4px); }
    70% { transform: translate(-4px, 3px); }
    80% { transform: translate(4px, -3px); }
    90% { transform: translate(-2px, 1px); }
}
body.cv-zumbido { animation: cv-zumbido-anim 0.6s ease-in-out; }

/* Sticker / adjunto dentro de una burbuja */
.cv-chat-burbuja-sticker { background: transparent !important; padding: 0.15rem !important; }
.cv-chat-sticker { display: block; width: 96px; height: 96px; }
.cv-chat-sticker-emoji { display: block; font-size: 3.2rem; line-height: 1.1; }
.cv-chat-adjunto-img {
    display: block; max-width: 200px; max-height: 200px; border-radius: 10px; margin-bottom: 0.25rem;
}
.cv-chat-adjunto-archivo {
    display: inline-block; margin-bottom: 0.25rem; padding: 0.4rem 0.6rem;
    background: var(--cv-surface-2); color: var(--cv-navy); border-radius: 8px;
    font-size: 0.82rem; text-decoration: none; word-break: break-all;
}
.cv-chat-burbuja-mia .cv-chat-adjunto-archivo { background: rgba(255, 255, 255, 0.25); color: #fff; }

/* Selector de stickers/emojis */
.cv-chat-picker {
    flex-shrink: 0; border-top: 1px solid var(--cv-border);
    max-height: 220px; display: flex; flex-direction: column; background: var(--cv-surface);
}
.cv-chat-picker[hidden] { display: none; }
.cv-chat-picker-tabs { display: flex; gap: 0.25rem; padding: 0.4rem 0.5rem 0; }
.cv-chat-picker-tab {
    border: 0; background: transparent; color: var(--cv-text-dim);
    padding: 0.3rem 0.6rem; font-size: 0.8rem; cursor: pointer; border-radius: 6px 6px 0 0;
}
.cv-chat-picker-tab-activa { color: var(--cv-navy); font-weight: 600; background: var(--cv-surface-2); }
.cv-chat-picker-panel {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(52px, 1fr));
    gap: 0.25rem; padding: 0.5rem; overflow-y: auto;
}
.cv-chat-picker-panel[hidden] { display: none; }
.cv-chat-picker-item {
    border: 0; background: transparent; cursor: pointer; padding: 0.3rem;
    border-radius: 8px; aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
}
.cv-chat-picker-item:hover { background: var(--cv-surface-2); }
.cv-chat-picker-item img { width: 100%; height: 100%; object-fit: contain; }
.cv-chat-picker-emoji { font-size: 1.5rem; }

@media (max-width: 480px) {
    .cv-chat-widget { right: 0.5rem; }
    .cv-chat-widget-panel { width: calc(100vw - 1rem); }
}

/* ===== Escritorio del estudiante (dashboard) ===== */

/* Ancho intermedio: más que el ancho de lectura de 900px que usa el
   resto del sitio -no cabrían la rejilla de cursos y la columna
   lateral-, menos que el ancho total que pide el simulador de red. */
.cv-container-medio { max-width: 1200px; }

/* Dos columnas: los cursos -lo que el estudiante viene a hacer- y una
   columna lateral fija con lo que "llegó" desde afuera (avisos del
   foro, clases presenciales de hoy). Bajo 1000px se apilan y la
   columna lateral queda debajo, no al lado. */
.cv-dash {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: 2rem;
    align-items: start;
}

@media (max-width: 1000px) {
    .cv-dash { grid-template-columns: minmax(0, 1fr); gap: 1.4rem; }
}

.cv-cursos-rejilla {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 1.1rem;
}

/* ======================================================================
   Barra de secciones del escritorio (Mis cursos / Mis logros / …)
   ====================================================================== */
.cv-dash-secciones {
    display: flex;
    gap: 0.3rem;
    flex-wrap: wrap;
    margin: 0 0 1.6rem;
    border-bottom: 2px solid var(--cv-border);
}
.cv-dash-seccion {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.7rem 1.1rem;
    font-weight: 700;
    color: var(--cv-text-dim);
    text-decoration: none;
    border-bottom: 3px solid transparent;
    margin-bottom: -2px;
    transition: color var(--cv-dur-base) var(--cv-ease-out);
}
.cv-dash-seccion svg { width: 1.15rem; height: 1.15rem; flex: none; }
.cv-dash-seccion:hover { color: var(--cv-text); }
.cv-dash-seccion--activa {
    color: var(--cv-primary);
    border-bottom-color: var(--cv-primary);
}

/* ======================================================================
   Mis logros
   ====================================================================== */
.cv-subtabs { display: flex; gap: 0.4rem; flex-wrap: wrap; margin: 0 0 1.5rem; }
.cv-subtab {
    padding: 0.5rem 1.1rem;
    border: 2px solid var(--cv-border);
    background: var(--cv-surface);
    border-radius: 999px;
    font: inherit;
    font-weight: 700;
    font-size: 0.92rem;
    color: var(--cv-text-dim);
    cursor: pointer;
}
.cv-subtab--activa {
    background: var(--cv-primary);
    border-color: var(--cv-primary);
    color: #fff;
}

.cv-logros-intro { color: var(--cv-text-dim); margin: 0 0 1.3rem; }

.cv-logros-hero {
    display: flex;
    gap: 1.6rem;
    align-items: center;
    flex-wrap: wrap;
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: var(--cv-radius-card, 14px);
    padding: 1.3rem 1.5rem;
    margin: 0 0 1.5rem;
    box-shadow: var(--cv-shadow-sm);
}
.cv-logros-grafica { flex: 0 0 180px; max-width: 190px; }
.cv-logros-cifras { display: flex; gap: 1.8rem; flex-wrap: wrap; flex: 1 1 220px; }
.cv-logros-cifra { display: flex; flex-direction: column; }
.cv-logros-cifra strong {
    font-size: 1.9rem;
    font-weight: 800;
    color: var(--cv-navy);
    line-height: 1;
}
.cv-logros-cifra span {
    font-size: 0.82rem;
    color: var(--cv-text-dim);
    margin-top: 0.35rem;
    max-width: 16rem;
}

.cv-logros-card { margin: 0 0 1.5rem; }
.cv-logros-card > h3 { margin: 0 0 0.3rem; font-size: 1.12rem; }
.cv-logros-card > h4 { margin: 1.3rem 0 0.5rem; font-size: 0.95rem; color: var(--cv-text-dim); }
.cv-logros-nota { color: var(--cv-text-dim); font-size: 0.85rem; margin: 0 0 1.1rem; }
.cv-logros-linea {
    display: flex;
    gap: 1.3rem;
    flex-wrap: wrap;
    margin: 1.1rem 0 0.3rem;
    font-size: 0.9rem;
    color: var(--cv-text-dim);
}
.cv-logros-linea strong { color: var(--cv-navy); font-weight: 800; }
.cv-logros-card svg { margin-top: 0.4rem; }

@media (max-width: 560px) {
    .cv-logros-hero { gap: 1rem; padding: 1rem; }
    .cv-logros-grafica { flex-basis: 140px; margin: 0 auto; }
}

/* ======================================================================
   Pruebas de competencias (Intevra School)
   ====================================================================== */
.cv-pruebas-areas {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 1rem;
    margin: 0 0 1.6rem;
}
.cv-pruebas-area {
    border-left: 5px solid var(--area, var(--cv-primary));
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.cv-pruebas-area-cab {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.cv-pruebas-area-cab h3 { margin: 0; font-size: 1.05rem; }
.cv-pruebas-nivel,
.cv-pruebas-badge {
    display: inline-block;
    font-size: 0.78rem;
    font-weight: 800;
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    color: var(--nivel, var(--cv-text-dim));
    background: color-mix(in srgb, var(--nivel, var(--cv-navy)) 14%, #fff);
}
.cv-pruebas-area-meta { font-size: 0.85rem; color: var(--cv-text-dim); margin: 0; flex: 1; }
.cv-pruebas-area .cv-btn { align-self: flex-start; }

.cv-pruebas-badges { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1rem; }
.cv-pruebas-badge { font-size: 0.8rem; }

.cv-pruebas-acciones { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-top: 1rem; }

/* contexto (estímulo compartido) dentro de una pregunta de la prueba */
.cv-prueba-contexto {
    background: color-mix(in srgb, var(--cv-navy) 5%, #fff);
    border: 1px solid var(--cv-border);
    border-radius: 12px;
    padding: 0.8rem 1rem;
    margin: 0.2rem 0 0.9rem;
    font-size: 0.95rem;
    line-height: 1.5;
}
.cv-prueba-contexto > p { margin: 0 0 0.6rem; }
.cv-prueba-contexto > *:last-child { margin-bottom: 0; }

/* tabla dentro del contexto */
.cv-prueba-tabla { margin: 0.6rem 0; overflow-x: auto; }
.cv-prueba-tabla table {
    border-collapse: collapse;
    width: 100%;
    background: #fff;
    border-radius: 10px;
    overflow: hidden;
    font-size: 0.92rem;
}
.cv-prueba-tabla th,
.cv-prueba-tabla td {
    padding: 0.45rem 0.7rem;
    text-align: left;
    border-bottom: 1px solid var(--cv-border);
}
.cv-prueba-tabla th {
    background: color-mix(in srgb, var(--cv-primary) 12%, #fff);
    color: var(--cv-navy);
    font-weight: 800;
}
.cv-prueba-tabla tr:last-child td { border-bottom: 0; }
.cv-prueba-tabla td:not(:first-child),
.cv-prueba-tabla th:not(:first-child) { text-align: center; }
.cv-prueba-tabla figcaption,
.cv-prueba-grafica figcaption {
    font-size: 0.8rem;
    color: var(--cv-text-dim);
    font-weight: 700;
    margin-top: 0.3rem;
    text-align: center;
}

/* gráfica dentro del contexto */
.cv-prueba-grafica {
    margin: 0.6rem 0 0;
    background: #fff;
    border-radius: 10px;
    padding: 0.5rem;
}

/* revisión de respuestas en el resultado */
.cv-prueba-rev {
    border-left: 4px solid var(--cv-border);
    padding: 0.6rem 0.9rem;
    margin: 0.6rem 0;
    border-radius: 0 10px 10px 0;
    background: color-mix(in srgb, var(--cv-navy) 3%, #fff);
}
.cv-prueba-rev--ok { border-left-color: var(--cv-success); }
.cv-prueba-rev--mal { border-left-color: var(--cv-danger); }
.cv-prueba-rev-enun { font-weight: 700; margin: 0 0 0.3rem; }
.cv-prueba-rev-enun small { font-weight: 600; color: var(--cv-text-dim); }
.cv-prueba-rev-linea { font-size: 0.9rem; margin: 0.2rem 0; }
.cv-prueba-rev-exp { font-size: 0.88rem; color: var(--cv-text-dim); margin: 0.3rem 0 0; }

.cv-curso-tarjeta {
    display: flex;
    flex-direction: column;
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 16px;
    padding: 0.7rem 0.7rem 1rem;
    box-shadow: var(--cv-shadow-sm);
    transition: transform var(--cv-dur-base) var(--cv-ease-out), box-shadow var(--cv-dur-base) var(--cv-ease-out);
    animation: cv-tarjeta-entra var(--cv-dur-slow) var(--cv-ease-out) both;
}

.cv-curso-tarjeta:hover { transform: translateY(-3px); box-shadow: var(--cv-shadow-md); }

/* Portada: la imagen del curso si el docente subió una, y si no un
   bloque azul marino con el birrete -que es lo que hace que una
   rejilla de cursos se lea como una rejilla aunque ningún curso tenga
   portada todavía-. */
.cv-curso-portada {
    position: relative;
    border-radius: 12px;
    overflow: hidden;
    background: var(--cv-navy);
    aspect-ratio: 4 / 3;
    display: block;
}

.cv-curso-portada img { width: 100%; height: 100%; object-fit: cover; display: block; }

.cv-curso-portada-icono {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.cv-curso-portada-icono svg { width: 46%; height: auto; fill: #ffffff; opacity: 0.95; }

/* El avance vive pegado al borde inferior de la portada -no en una
   línea suelta de texto-: se lee de un vistazo junto a la tarjeta a la
   que pertenece. */
.cv-curso-progreso {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 22px;
    background: #e6eaf2;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding: 0 0.55rem;
}

.cv-curso-progreso-fill {
    position: absolute;
    left: 0; top: 0; bottom: 0;
    background: var(--cv-accent);
    border-radius: 0 999px 999px 0;
    transition: width 0.6s var(--cv-ease-out);
}

/* Clase propia -no `.cv-curso-progreso span`-: ese selector también
   alcanzaba al relleno de al lado y, por ser más específico que
   `.cv-curso-progreso-fill`, le pisaba el `position: absolute` y lo
   dejaba con 0 de alto (barra invisible). */
.cv-curso-progreso-valor {
    position: relative;
    font-size: 0.72rem;
    font-weight: 800;
    color: var(--cv-navy);
}

.cv-curso-titulo {
    font-family: var(--cv-font-display);
    font-size: 1.02rem;
    font-weight: 700;
    line-height: 1.25;
    color: var(--cv-primary);
    text-decoration: none;
    margin: 0.85rem 0 0.5rem;
    display: block;
}

.cv-curso-titulo:hover { color: var(--cv-primary-dark); text-decoration: underline; }

.cv-curso-meta {
    margin: 0 0 0.3rem;
    font-size: 0.82rem;
    color: var(--cv-text-dim);
}

/* Empuja el par de botones al fondo para que todas las tarjetas de una
   fila los alineen a la misma altura, tengan el título una línea o
   tres. */
.cv-curso-acciones {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: auto;
    padding-top: 0.7rem;
}

.cv-curso-acciones .cv-btn { padding: 0.5rem 1.05rem; font-size: 0.85rem; }

/* ===== Oferta de cursos (escaparate público) ===== */

.cv-oferta-hero {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    margin: 0 0 1.8rem;
    padding: clamp(2rem, 5vw, 3.4rem) clamp(1.4rem, 4vw, 3rem);
    border-radius: 22px;
    color: #fff;
    background:
        radial-gradient(1000px 420px at 8% -30%, color-mix(in srgb, var(--cv-accent) 32%, transparent), transparent 62%),
        radial-gradient(760px 380px at 108% 130%, color-mix(in srgb, var(--cv-primary) 55%, transparent), transparent 58%),
        linear-gradient(135deg, var(--cv-navy) 0%, color-mix(in srgb, var(--cv-navy) 55%, var(--cv-primary)) 100%);
    box-shadow: 0 20px 50px color-mix(in srgb, var(--cv-navy) 35%, transparent);
}
/* Orbes suaves flotando en el fondo -movimiento discreto, se apaga con
   prefers-reduced-motion por la red de seguridad global-. */
.cv-oferta-hero-fondo { position: absolute; inset: 0; z-index: -1; }
.cv-oferta-hero-fondo span {
    position: absolute;
    border-radius: 50%;
    filter: blur(6px);
    opacity: 0.5;
    background: radial-gradient(circle at 30% 30%, color-mix(in srgb, var(--cv-accent) 70%, transparent), transparent 70%);
    animation: cv-hero-flota 14s ease-in-out infinite;
}
.cv-oferta-hero-fondo span:nth-child(1) { width: 220px; height: 220px; top: -70px; right: 8%; animation-delay: 0s; }
.cv-oferta-hero-fondo span:nth-child(2) { width: 150px; height: 150px; bottom: -50px; left: 12%; animation-delay: -5s; opacity: 0.35; }
.cv-oferta-hero-fondo span:nth-child(3) { width: 90px; height: 90px; top: 30%; right: 32%; animation-delay: -9s; opacity: 0.28; }
@keyframes cv-hero-flota {
    0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
    50% { transform: translate3d(0, -22px, 0) scale(1.08); }
}

.cv-oferta-hero-cont { position: relative; max-width: 52ch; animation: cv-hero-sube 0.6s var(--cv-ease-out) both; }
@keyframes cv-hero-sube { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

.cv-oferta-eyebrow {
    margin: 0 0 0.7rem;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--cv-accent) 75%, white);
}
.cv-oferta-hero h1 {
    margin: 0 0 0.5rem;
    padding: 0;
    border: 0;
    color: #fff;
    font-family: var(--cv-font-display);
    font-size: clamp(1.7rem, 4.4vw, 2.6rem);
    font-weight: 800;
    line-height: 1.12;
    letter-spacing: -0.02em;
}
.cv-oferta-lead {
    margin: 0 0 1.3rem;
    font-size: clamp(0.95rem, 2vw, 1.08rem);
    line-height: 1.6;
    color: rgba(255, 255, 255, 0.88);
}
.cv-oferta-chips {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.55rem 0.7rem;
}
.cv-oferta-chips li {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.85rem;
    border-radius: 999px;
    font-size: 0.82rem;
    font-weight: 600;
    color: #fff;
    background: rgba(255, 255, 255, 0.12);
    border: 1px solid rgba(255, 255, 255, 0.16);
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
}
.cv-oferta-chips svg {
    width: 16px; height: 16px;
    fill: none;
    stroke: color-mix(in srgb, var(--cv-accent) 82%, white);
    stroke-width: 1.9;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.cv-oferta-aviso {
    margin: 0 0 1.2rem;
    padding: 0.85rem 1.1rem;
    border-radius: 12px;
    background: var(--cv-primary-tint, #eef3ff);
    border: 1px solid color-mix(in srgb, var(--cv-primary) 22%, transparent);
    font-size: 0.9rem;
    color: var(--cv-navy);
}

.cv-cursos-rejilla { align-items: stretch; }

.cv-curso-tarjeta { padding: 0; overflow: hidden; }
.cv-curso-tarjeta:hover { box-shadow: var(--cv-shadow-lift); }

.cv-curso-portada { border-radius: 0; }

.cv-curso-etiqueta {
    position: absolute;
    top: 0.6rem;
    left: 0.6rem;
    padding: 0.2rem 0.6rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    backdrop-filter: blur(3px);
}
.cv-curso-etiqueta-gratis { background: rgba(22, 163, 74, 0.92); color: #fff; }
.cv-curso-etiqueta-pago { background: rgba(255, 255, 255, 0.94); color: var(--cv-navy); }

.cv-curso-cuerpo {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: 0.5rem 1rem 1.1rem;
}

.cv-curso-titulo { margin: 0.7rem 0 0.35rem; font-size: 1.05rem; }

.cv-curso-desc {
    margin: 0.15rem 0 0;
    font-size: 0.88rem;
    line-height: 1.55;
    color: var(--cv-text);
}

.cv-curso-pie {
    margin-top: auto;
    padding-top: 0.9rem;
}

.cv-curso-precio {
    margin: 0 0 0.55rem;
    font-family: var(--cv-font-display);
    font-size: 1.35rem;
    font-weight: 800;
    color: var(--cv-navy);
    line-height: 1;
}
.cv-curso-precio span { font-size: 0.72rem; font-weight: 700; color: var(--cv-text-dim); }

.cv-curso-acciones .cv-btn { width: 100%; text-align: center; }

.cv-oferta-nota {
    margin: 1.2rem 0 0;
    font-size: 0.85rem;
    color: var(--cv-text-dim);
}

.cv-contacto-card {
    margin-top: 2rem;
    padding: 1.4rem 1.6rem;
    border-radius: 16px;
    border: 1px solid var(--cv-border);
    background: var(--cv-surface);
    box-shadow: var(--cv-shadow-sm);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem 1.5rem;
}
.cv-contacto-card h2 {
    margin: 0 0 0.25rem;
    font-family: var(--cv-font-display);
    font-size: 1.15rem;
    font-weight: 800;
    color: var(--cv-navy);
}
.cv-contacto-card p { margin: 0; font-size: 0.9rem; color: var(--cv-text-dim); max-width: 42ch; }
.cv-contacto-acciones { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.cv-contacto-acciones .cv-btn { font-size: 0.85rem; }

/* Prosa redactada por el docente/plantilla en enunciados e instrucciones de
   actividad -mismo tratamiento tipográfico que el cuerpo de las lecturas-. */
.cv-prosa { line-height: 1.7; }
.cv-prosa > :first-child { margin-top: 0; }
.cv-prosa > :last-child { margin-bottom: 0; }
.cv-prosa p { margin: 0.6rem 0; line-height: 1.7; }
.cv-prosa ul, .cv-prosa ol { line-height: 1.75; padding-left: 1.3rem; margin: 0.6rem 0; }
.cv-prosa li { margin: 0.2rem 0; }
.cv-prosa h3, .cv-prosa h4 { margin: 1.1rem 0 0.4rem; color: var(--cv-navy); }
.cv-prosa code {
    background: var(--cv-surface-2, #eef1f6);
    padding: 0.1rem 0.35rem;
    border-radius: 5px;
    font-size: 0.9em;
}
.cv-prosa strong { color: var(--cv-navy); }

/* ===== Paneles de la columna lateral ===== */

.cv-panel {
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 16px;
    padding: 1.3rem 1.4rem;
    box-shadow: var(--cv-shadow-sm);
    margin-bottom: 1.2rem;
}

.cv-panel-cabecera {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.9rem;
}

.cv-panel-titulo {
    font-family: var(--cv-font-display);
    font-size: 1.3rem;
    font-weight: 800;
    color: var(--cv-navy);
    margin: 0;
}

.cv-panel-vacio {
    text-align: center;
    color: var(--cv-text-dim);
    font-size: 0.9rem;
    padding: 0.6rem 0 0.9rem;
}

.cv-panel-vacio svg {
    width: 54px;
    height: 54px;
    stroke: #cfd6e4;
    fill: none;
    stroke-width: 1.6;
    margin-bottom: 0.5rem;
}

.cv-panel-link {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--cv-primary);
    font-weight: 700;
    font-size: 0.92rem;
    text-decoration: none;
}

.cv-panel-link:hover { text-decoration: underline; }
.cv-panel-link svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2; }

.cv-panel-item {
    display: block;
    text-decoration: none;
    color: inherit;
    border-top: 1px solid var(--cv-border);
    padding: 0.7rem 0;
}

.cv-panel-item:first-of-type { border-top: none; padding-top: 0; }
.cv-panel-item:hover strong { color: var(--cv-primary); }
.cv-panel-item strong { display: block; font-weight: 700; font-size: 0.92rem; color: var(--cv-navy); }
.cv-panel-item span { display: block; font-size: 0.8rem; color: var(--cv-text-dim); }
.cv-panel-item small { font-size: 0.75rem; color: var(--cv-text-dim); }

/* Filtro de semanas (panel docente: docente_curso_detail.html,
   docente_estudiante_detail.html) -fila horizontal de chips arriba del
   contenido, cada uno un ancla a la tarjeta de esa semana-. Reemplaza
   al panel lateral fijo de la primera versión: con hasta 16 semanas
   el aside quedaba flotando de forma rara y no aportaba más que este
   renglón compacto arriba. */
.cv-semana-filtro {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0.9rem 0 1.4rem;
}

.cv-semana-filtro a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.2rem;
    height: 2.2rem;
    padding: 0 0.6rem;
    border-radius: 999px;
    background: var(--cv-surface-2);
    color: var(--cv-navy);
    font-weight: 700;
    font-size: 0.85rem;
    text-decoration: none;
    border: 1px solid transparent;
    transition: background var(--cv-dur-fast) var(--cv-ease-out), border-color var(--cv-dur-fast) var(--cv-ease-out);
}

.cv-semana-filtro a:hover { background: var(--cv-primary-tint); border-color: var(--cv-primary); }

/* Fila de actividad dentro de una tarjeta de semana, con la misma
   composición que usa el estudiante en semana_detail.html -título +
   badge de estado en una línea, tipo/puntos/calificación en una
   <small> debajo- en vez del link suelto que traía antes. No es un
   <a class="cv-link-block"> de tarjeta completa porque el docente
   necesita dos destinos (Ver actividad / Ver evidencia), no uno solo. */
.cv-actividad-fila {
    padding: 0.65rem 0;
    border-bottom: 1px solid var(--cv-border);
}

.cv-actividad-fila:last-child { border-bottom: none; }

.cv-actividad-fila-titulo {
    font-weight: 700;
    color: var(--cv-navy);
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.cv-actividad-fila-meta {
    display: block;
    color: var(--cv-text-dim);
    margin-top: 0.2rem;
}

.cv-actividad-fila-acciones {
    display: block;
    margin-top: 0.3rem;
    font-size: 0.85rem;
}

/* Actividad ML: entrenador de regresión lineal (ml_ui.js) */
.cv-ml-controles {
    display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: flex-end;
    margin: 1rem 0; padding: 1rem; background: var(--cv-surface-2); border-radius: 12px;
}
.cv-ml-campo { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.85rem; font-weight: 700; color: var(--cv-text-dim); }
.cv-ml-campo input {
    padding: 0.5rem 0.7rem; border: 1px solid var(--cv-border); border-radius: 8px;
    font-size: 0.95rem; font-family: var(--cv-font-sans); width: 140px;
}
.cv-ml-metricas { display: flex; gap: 1.5rem; margin-left: auto; }
.cv-ml-metricas > div { display: flex; flex-direction: column; gap: 0.15rem; font-size: 0.75rem; color: var(--cv-text-dim); }
.cv-ml-metricas strong { font-size: 1.05rem; font-family: var(--cv-font-serif); color: var(--cv-navy); }
.cv-ml-metricas strong.cv-ml-mse-logrado { color: var(--cv-success); }

.cv-ml-graficos { display: grid; grid-template-columns: 1.3fr 1fr; gap: 1rem; margin: 1rem 0; }
@media (max-width: 780px) { .cv-ml-graficos { grid-template-columns: 1fr; } }
.cv-ml-panel {
    border: 1px solid var(--cv-border); border-radius: 12px; padding: 0.9rem 1rem;
    background: var(--cv-surface); box-shadow: var(--cv-shadow-sm);
}
.cv-ml-panel h4 { margin: 0 0 0.6rem; font-size: 0.85rem; color: var(--cv-text-dim); }
.cv-ml-panel svg { width: 100%; height: auto; display: block; }

.cv-ml-eje { stroke: var(--cv-border); stroke-width: 1.5; }
.cv-ml-punto { fill: var(--cv-primary); opacity: 0.85; }
.cv-ml-linea { stroke: var(--cv-accent); stroke-width: 2.5; }
.cv-ml-curva { fill: none; stroke: var(--cv-primary); stroke-width: 2; }
.cv-ml-linea-objetivo { stroke: var(--cv-success); stroke-width: 1.3; stroke-dasharray: 5 4; }
.cv-ml-etiqueta-objetivo { fill: var(--cv-success); font-size: 10px; font-weight: 700; }

/* ===== Consola de MySQL dentro de una lectura (sql_lab.js) ===== */

.cv-sql-lab {
    border: 1px solid var(--cv-border);
    border-left: 4px solid var(--cv-primary);
    border-radius: 12px;
    background: var(--cv-surface-2);
    padding: 1rem 1.1rem;
    margin: 1.5rem 0;
}

/* Mientras no haya laboratorio (o antes de que corra el script) el bloque
   se ve como lo que es: un ejemplo de SQL para leer. */
.cv-sql-lab:not(.cv-sql-lab-listo) {
    white-space: pre-wrap;
    font-family: 'Courier New', Consolas, monospace;
    font-size: 0.85rem;
}

.cv-sql-lab-encabezado { margin-bottom: 0.6rem; }

.cv-sql-lab-editor {
    width: 100%;
    font-family: 'Courier New', Consolas, monospace;
    font-size: 0.85rem;
    line-height: 1.5;
    padding: 0.7rem 0.85rem;
    border: 1.5px solid var(--cv-border);
    border-radius: 9px;
    background: var(--cv-surface);
    color: var(--cv-text);
    resize: vertical;
}

.cv-sql-lab-editor:focus { outline: none; border-color: var(--cv-primary); }

.cv-sql-lab-barra {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin: 0.6rem 0;
}

.cv-sql-lab-estado { font-size: 0.8rem; color: var(--cv-text-dim); }

.cv-sql-lab-resultado {
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: 9px;
    padding: 0.6rem 0.8rem;
    margin-bottom: 0.6rem;
}

.cv-sql-lab-eco {
    display: block;
    font-size: 0.78rem;
    color: var(--cv-text-dim);
    margin-bottom: 0.45rem;
    word-break: break-word;
}

.cv-sql-lab-tabla-scroll { overflow-x: auto; }

.cv-sql-lab-error {
    color: var(--cv-danger);
    font-size: 0.85rem;
    margin: 0;
}

.cv-sql-lab-pie { font-size: 0.8rem; color: var(--cv-text-dim); margin: 0.4rem 0 0; }

.cv-sql-lab-estructura { font-size: 0.8rem; color: var(--cv-text-dim); }

.cv-sql-lab-objeto {
    font-family: 'Courier New', Consolas, monospace;
    font-size: 0.78rem;
    padding: 0.15rem 0;
    word-break: break-word;
}

/* ===== phpMyAdmin embebido en el curso (laboratorio_bd.html) ===== */

.cv-lab-bd-barra {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-bottom: 0.75rem;
}

.cv-lab-bd-estado { font-size: 0.8rem; color: var(--cv-text-dim); }

.cv-lab-bd-marco {
    border: 1px solid var(--cv-border);
    border-radius: 12px;
    overflow: hidden;
    background: var(--cv-surface);
    /* Alto suficiente para que se vea el árbol de bases y la tabla de
       resultados sin scroll doble; en pantalla completa ocupa todo. */
    height: min(78vh, 900px);
}

.cv-lab-bd-marco:fullscreen { height: 100vh; border-radius: 0; }

.cv-lab-bd-marco iframe {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}

@media (max-width: 640px) {
    .cv-lab-bd-marco { height: 70vh; }
}

/* ===== Tarjetas de motores de base de datos (clase de BD, semana 2) ===== */

.cv-dbms-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 0.9rem;
    margin-top: 1rem;
}

.cv-dbms {
    border: 1px solid var(--cv-border);
    border-radius: 12px;
    padding: 0.9rem 0.8rem;
    background: var(--cv-surface-2);
    text-align: center;
}

/* Los logos vienen en proporciones muy distintas -unos apaisados, otros
   casi cuadrados-, así que se fija el ALTO y el ancho se acomoda solo. */
.cv-dbms img {
    height: 42px;
    width: auto;
    max-width: 100%;
    object-fit: contain;
    margin-bottom: 0.55rem;
}

.cv-dbms strong { display: block; margin-bottom: 0.3rem; font-size: 0.92rem; }

.cv-dbms span {
    display: block;
    font-size: 0.78rem;
    line-height: 1.45;
    color: var(--cv-text-dim);
}

.cv-dbms-mini {
    /* Los logos de puro texto (Oracle) son mucho más anchos que los de
       símbolo a la misma altura; el tope de ancho evita que dominen la
       tarjeta al lado de los demás. */
    height: 22px;
    width: auto;
    max-width: 110px;
    object-fit: contain;
    display: block;
    margin-bottom: 0.45rem;
}

/* Selector de base en la Consola SQL del curso (sql_lab.js) */
.cv-sql-lab-bases {
    padding: 0.45rem 0.6rem;
    border: 1.5px solid var(--cv-border);
    border-radius: 8px;
    background: var(--cv-surface);
    color: var(--cv-text);
    font-size: 0.85rem;
    max-width: 220px;
}

/* En la página dedicada la consola es el contenido principal: sin marco
   propio (ya está dentro de una tarjeta) y con el editor más alto. */
.cv-card > .cv-sql-lab {
    border-left-width: 4px;
    margin-top: 0;
}

.cv-card > .cv-sql-lab .cv-sql-lab-editor { min-height: 190px; }

/* ===== Terminal de MySQL del curso (sql_terminal.js) ===== */

.cv-term {
    background: #10131a;
    border: 1px solid #2a3040;
    border-radius: 12px;
    padding: 0.9rem 1rem 1rem;
    font-family: 'Courier New', Consolas, Menlo, monospace;
    font-size: 0.85rem;
    line-height: 1.5;
    color: #d7dce5;
}

.cv-term-salida {
    height: min(52vh, 520px);
    overflow-y: auto;
    white-space: pre-wrap;
    word-break: break-word;
    outline: none;
}

.cv-term-salida > div { margin-bottom: 0.35rem; }

.cv-term-eco { color: #9aa4b8; }
.cv-term-prompt-eco { color: #6fd08c; }
.cv-term-ok { color: #6fd08c; }
.cv-term-error { color: #ff8080; }
.cv-term-nota { color: #8d97ab; }

.cv-term-clave { color: #7fb2ff; font-weight: 700; }
.cv-term-cadena { color: #f2b880; }
.cv-term-numero { color: #d9a7ff; }
.cv-term-comentario { color: #6b7488; font-style: italic; }

.cv-term-entrada-caja {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    border-top: 1px solid #2a3040;
    margin-top: 0.6rem;
    padding-top: 0.6rem;
}

.cv-term-prompt { color: #6fd08c; white-space: nowrap; padding-top: 1px; }

/* El textarea va TRANSPARENTE encima del <pre> con el resaltado; los dos
   comparten fuente y métricas exactas para que el texto calce al píxel. */
.cv-term-campo { position: relative; flex: 1; }

.cv-term-resaltado,
.cv-term-entrada {
    font-family: inherit;
    font-size: inherit;
    line-height: inherit;
    padding: 0;
    margin: 0;
    border: 0;
    white-space: pre-wrap;
    word-break: break-word;
    width: 100%;
    overflow: hidden;
}

/* El sitio le pone fondo y borde a los <pre> dentro de una tarjeta
   (.cv-card pre:not(.cv-pseudo-textarea)); acá hay que ganarle, porque
   este <pre> es la capa de color DEBAJO del textarea: con fondo propio
   se veía un rectángulo blanco sobre la terminal. */
.cv-card .cv-term pre.cv-term-resaltado,
.cv-term pre.cv-term-resaltado {
    background: transparent;
    border: 0;
    border-radius: 0;
    padding: 0;
    margin: 0;
    min-height: 1.5em;
    pointer-events: none;
    color: #d7dce5;
}

.cv-term-entrada {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    background: transparent;
    color: transparent;
    caret-color: #d7dce5;
    resize: none;
    outline: none;
}

.cv-term-entrada:focus { box-shadow: none !important; }

/* El menú de autocompletar es el mismo componente del resto de editores,
   pero acá va sobre fondo oscuro. */
.cv-term-menu-oscuro .cv-autocomplete-item { font-family: 'Courier New', Consolas, monospace; }

/* ===== Validación de la entrega práctica de BD (actividad_lab_bd.html) ===== */
.cv-lab-bd-checks { list-style: none; padding: 0; margin: 0.6rem 0; }
.cv-lab-bd-checks li {
    display: flex; align-items: flex-start; gap: 0.6rem;
    padding: 0.5rem 0.7rem; border-radius: 8px; margin-bottom: 0.35rem;
    font-size: 0.9rem; border: 1px solid var(--cv-border);
}
.cv-check-ok { background: #e9f7ef; border-color: #cdedd9; }
.cv-check-mal { background: #fdedee; border-color: #f6d3d6; }
.cv-check-icono { font-weight: 800; }
.cv-check-ok .cv-check-icono { color: var(--cv-success); }
.cv-check-mal .cv-check-icono { color: var(--cv-danger); }

/* ===== Guía paso a paso de la práctica de BD (actividad_lab_bd.html) ===== */
.cv-guia { list-style: none; counter-reset: paso; padding: 0; margin: 0.6rem 0; }
.cv-guia-paso {
    position: relative;
    border: 1px solid var(--cv-border);
    border-radius: 12px;
    padding: 0.9rem 1rem 0.9rem 3rem;
    margin-bottom: 0.8rem;
    background: var(--cv-surface-2);
}
.cv-guia-paso::before {
    counter-increment: paso;
    content: counter(paso);
    position: absolute;
    left: 0.9rem; top: 0.9rem;
    width: 1.5rem; height: 1.5rem;
    border-radius: 50%;
    background: var(--cv-primary); color: #fff;
    font-size: 0.85rem; font-weight: 700;
    display: flex; align-items: center; justify-content: center;
}
.cv-guia-titulo { font-weight: 700; margin-bottom: 0.25rem; }
.cv-guia-texto { font-size: 0.86rem; line-height: 1.55; margin: 0 0 0.6rem; }

/* El SQL de la guía NO se puede seleccionar ni copiar: el estudiante lo
   teclea en su consola. Aun así, se ve como código. El selector va con la
   tarjeta y la clase del <pre> para GANARLE a ".cv-card pre" del sitio, que
   si no le pone fondo claro y el texto gris quedaba invisible. */
.cv-card pre.cv-guia-sql {
    background: #10131a;
    color: #d7dce5;
    border-radius: 8px;
    padding: 0.7rem 0.85rem;
    margin: 0;
    font-family: 'Courier New', Consolas, monospace;
    font-size: 0.84rem;
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
    overflow-x: auto;
    -webkit-user-select: none;
    -moz-user-select: none;
    user-select: none;
    cursor: default;
}

/* Código de una guía de laboratorio en Colab: SÍ se puede seleccionar y
   copiar (el estudiante lo pega en una celda de Colab). */
.cv-guia-codigo-caja { position: relative; margin: 0; }
.cv-card pre.cv-guia-codigo {
    background: #10131a;
    color: #d7dce5;
    border-radius: 8px;
    padding: 0.7rem 0.85rem;
    margin: 0;
    font-family: 'Courier New', Consolas, monospace;
    font-size: 0.84rem;
    line-height: 1.5;
    white-space: pre;
    overflow-x: auto;
    user-select: text;
}
.cv-guia-copiar {
    position: absolute;
    top: 0.45rem; right: 0.45rem;
    padding: 0.2rem 0.55rem;
    font-size: 0.75rem; font-weight: 600;
    color: #d7dce5;
    background: rgba(255, 255, 255, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 6px;
    cursor: pointer;
}
.cv-guia-copiar:hover { background: rgba(255, 255, 255, 0.18); }

/* ===== Clase en vivo / compartir pantalla (clase_en_vivo.html) ===== */
.cv-pantalla-barra { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; margin-bottom: 0.6rem; }
.cv-pantalla-contador { font-size: 0.8rem; color: var(--cv-text-dim); }
.cv-pantalla-estado { font-size: 0.88rem; color: var(--cv-text-dim); margin: 0.4rem 0 0.8rem; }
.cv-pantalla-marco {
    background: #000;
    border: 1px solid var(--cv-border);
    border-radius: 12px;
    overflow: hidden;
    /* Ocupa casi todo el alto de la ventana para que se vea grande, sin
       forzar una relación fija: el video se ajusta dentro con object-fit. */
    height: min(82vh, 900px);
    display: flex; align-items: center; justify-content: center;
}
.cv-pantalla-marco video { width: 100%; height: 100%; object-fit: contain; background: #000; display: block; cursor: pointer; }

/* En pantalla completa el marco ocupa todo, sin bordes ni radios. */
.cv-pantalla-marco:fullscreen { height: 100vh; width: 100vw; border: 0; border-radius: 0; }
.cv-pantalla-marco:-webkit-full-screen { height: 100vh; width: 100vw; border: 0; border-radius: 0; }

/* La página de clase en vivo aprovecha todo el ancho disponible. */
#cv-pantalla { max-width: none; }

/* icono del acceso en la página del curso */
.cv-launcher-icon-envivo { background: linear-gradient(135deg, #b3261e, #e5484d); }

/* ===== Banner obligatorio "califícame" (evaluación de la plataforma) ===== */
.cv-eval-overlay {
    position: fixed; inset: 0; z-index: 3000;
    display: flex; align-items: center; justify-content: center;
    padding: 1rem;
    background: rgba(18, 41, 79, 0.55);
    backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
    animation: cvEvalFade 0.25s var(--cv-ease-out, ease-out);
}
@keyframes cvEvalFade { from { opacity: 0; } to { opacity: 1; } }
.cv-eval-modal {
    width: min(480px, 100%);
    max-height: 92vh; overflow-y: auto;
    background: var(--cv-surface); color: var(--cv-text);
    border: 1px solid var(--cv-border); border-radius: 18px;
    box-shadow: var(--cv-shadow-lift);
    padding: 1.6rem 1.5rem;
    animation: cvEvalPop 0.3s var(--cv-ease-spring, ease-out);
}
@keyframes cvEvalPop { from { opacity: 0; transform: scale(0.94) translateY(8px); } to { opacity: 1; transform: none; } }
.cv-eval-modal h2 {
    margin: 0 0 0.5rem; font-family: var(--cv-font-display, inherit);
    font-size: 1.25rem; color: var(--cv-navy);
}
.cv-eval-intro { margin: 0 0 1.2rem; font-size: 0.9rem; color: var(--cv-text-dim); line-height: 1.55; }
.cv-eval-filas { display: flex; flex-direction: column; gap: 0.35rem; margin-bottom: 1rem; }
.cv-eval-fila {
    display: flex; align-items: center; justify-content: space-between; gap: 0.6rem;
    flex-wrap: wrap; padding: 0.55rem 0.2rem; border-bottom: 1px solid var(--cv-surface-2);
}
.cv-eval-fila:last-child { border-bottom: none; }
.cv-eval-label { font-size: 0.92rem; font-weight: 600; }
.cv-eval-estrellas { display: flex; gap: 0.15rem; }
.cv-eval-estrella {
    background: none; border: none; padding: 0.15rem; cursor: pointer; line-height: 0;
    border-radius: 6px; transition: transform 0.1s ease;
}
.cv-eval-estrella:hover { transform: scale(1.15); }
.cv-eval-estrella svg { width: 26px; height: 26px; fill: #cfd6e4; transition: fill 0.12s ease; }
.cv-eval-estrella-activa svg { fill: var(--cv-accent); }
.cv-eval-label-bloque {
    display: block; font-size: 0.92rem; font-weight: 600;
    margin: 0.4rem 0 0.35rem;
}
.cv-eval-comentario {
    width: 100%; box-sizing: border-box; resize: vertical;
    border: 1.5px solid var(--cv-border); border-radius: 10px;
    padding: 0.6rem 0.75rem; font-family: inherit; font-size: 0.9rem;
    margin-bottom: 0.9rem; background: var(--cv-surface);
}
.cv-eval-comentario:focus { outline: none; border-color: var(--cv-primary); }
.cv-eval-error { margin: 0 0 0.8rem; color: var(--cv-danger); font-size: 0.85rem; font-weight: 600; }
.cv-eval-enviar { width: 100%; justify-content: center; }

/* ===== Editor de documento (anteproyecto APA 7) ===== */
.cv-doc-barra {
    display: flex; align-items: center; justify-content: space-between;
    gap: 0.75rem; flex-wrap: wrap; margin-bottom: 0.9rem;
}
.cv-doc-tabs { display: flex; gap: 0.4rem; }
.cv-doc-acciones { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }
.cv-doc-guardado { font-size: 0.8rem; color: var(--cv-text-dim); }

.cv-doc-editor { display: grid; grid-template-columns: 250px 1fr; gap: 1rem; align-items: start; }
.cv-doc-secciones {
    border: 1px solid var(--cv-border); border-radius: 12px; overflow-y: auto;
    max-height: 62vh; background: var(--cv-surface-2); padding: 0.4rem;
}
.cv-doc-grupo {
    font-family: var(--cv-font-display, inherit); font-size: 0.68rem; font-weight: 800;
    text-transform: uppercase; letter-spacing: .06em; color: var(--cv-text-dim);
    padding: 0.7rem 0.5rem 0.3rem;
}
.cv-doc-item {
    display: flex; gap: 0.4rem; align-items: baseline; width: 100%; text-align: left;
    background: none; border: none; border-radius: 8px; padding: 0.45rem 0.5rem;
    font-size: 0.86rem; color: var(--cv-text); cursor: pointer;
}
.cv-doc-item:hover { background: var(--cv-primary-tint); }
.cv-doc-item-activa { background: var(--cv-primary-tint); font-weight: 700; color: var(--cv-primary-dark); }
.cv-doc-check { color: var(--cv-success); font-weight: 700; }

.cv-doc-panel { border: 1px solid var(--cv-border); border-radius: 12px; padding: 1.1rem; background: var(--cv-surface); }
.cv-doc-semana-chip {
    display: inline-block; font-size: 0.7rem; font-weight: 700; color: var(--cv-primary-dark);
    background: var(--cv-primary-tint); border-radius: 999px; padding: 0.1rem 0.6rem;
}
.cv-doc-indicacion {
    background: var(--cv-accent-soft); border-left: 4px solid var(--cv-accent);
    padding: 0.7rem 0.9rem; border-radius: 8px; font-size: 0.9rem; line-height: 1.55; margin: 0.6rem 0 1rem;
}
.cv-doc-texto {
    width: 100%; box-sizing: border-box; min-height: 320px; resize: vertical;
    border: 1.5px solid var(--cv-border); border-radius: 10px; padding: 0.9rem 1rem;
    font-family: var(--cv-font-sans, inherit); font-size: 1rem; line-height: 1.6;
}
.cv-doc-texto:focus { outline: none; border-color: var(--cv-primary); }
.cv-doc-nav { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; margin-top: 0.8rem; }
.cv-doc-progreso { font-size: 0.85rem; color: var(--cv-text-dim); font-weight: 600; }

@media (max-width: 720px) {
    .cv-doc-editor { grid-template-columns: 1fr; }
    .cv-doc-secciones { max-height: 200px; }
}

/* ---- Vista previa / documento en norma APA 7 ---- */
.cv-doc-preview { background: #e9edf4; padding: 1.2rem; border-radius: 12px; }
.cv-doc-apa { max-width: 8.5in; margin: 0 auto; }
.cv-apa-pagina {
    background: #fff; color: #111; box-shadow: var(--cv-shadow-md);
    font-family: 'Times New Roman', Times, serif; font-size: 12pt; line-height: 2;
    padding: 1in; margin: 0 auto 1.2rem; box-sizing: border-box;
    min-height: 11in; width: 8.5in; max-width: 100%;
}
.cv-apa-pagina p { margin: 0; text-indent: 0.5in; text-align: justify; }
.cv-apa-h1 { text-align: center; font-weight: bold; font-size: 12pt; margin: 0; line-height: 2; }
.cv-apa-titulo-cuerpo { text-align: center; font-weight: bold; font-size: 12pt; margin: 0 0 0; line-height: 2; }
.cv-apa-portada { display: flex; flex-direction: column; align-items: center; text-align: center; }
.cv-apa-titulo-portada { font-weight: bold; margin-top: 3.5in; margin-bottom: 2in; }
.cv-apa-portada-datos p { text-indent: 0; text-align: center; }
.cv-apa-keywords { text-indent: 0.5in; }
.cv-apa-lista { margin: 0; padding-left: 0.9in; }
.cv-apa-lista li { text-align: justify; }
.cv-apa-refs p { text-indent: 0; padding-left: 0.5in; text-indent: -0.5in; margin-left: 0.5in; text-align: left; }

/* ---- Impresión / exportar a PDF: solo el documento APA ---- */
@media print {
    body.cv-imprimiendo-doc * { visibility: hidden; }
    body.cv-imprimiendo-doc #cv-doc-apa, body.cv-imprimiendo-doc #cv-doc-apa * { visibility: visible; }
    body.cv-imprimiendo-doc #cv-doc-apa { position: absolute; inset: 0; margin: 0; max-width: none; }
    body.cv-imprimiendo-doc .cv-apa-pagina { box-shadow: none; margin: 0; width: auto; min-height: 0; padding: 1in; page-break-after: always; }
    @page { size: letter; margin: 0; }
}

/* Acceso directo al documento del anteproyecto (banner en cada semana) */
.cv-doc-acceso {
    display: flex; align-items: center; gap: 0.9rem; text-decoration: none;
    background: linear-gradient(135deg, var(--cv-primary-tint), var(--cv-surface));
    border: 1px solid var(--cv-border); border-left: 5px solid var(--cv-primary);
    border-radius: 12px; padding: 0.85rem 1.1rem; margin: 0.4rem 0 1.2rem;
    color: var(--cv-text); transition: box-shadow .15s, transform .1s;
}
.cv-doc-acceso:hover { box-shadow: var(--cv-shadow-md); transform: translateY(-1px); }
.cv-doc-acceso-icono { font-size: 1.6rem; }
.cv-doc-acceso-txt { display: flex; flex-direction: column; flex: 1; }
.cv-doc-acceso-txt strong { color: var(--cv-navy); }
.cv-doc-acceso-txt small { color: var(--cv-text-dim); }
.cv-doc-acceso-ir { font-family: var(--cv-font-display, inherit); font-weight: 700; color: var(--cv-primary); white-space: nowrap; }

/* Sección del documento aún no habilitada (se abre en su semana) */
.cv-doc-item-bloq { opacity: 0.55; }
.cv-doc-item-bloq:hover { background: var(--cv-surface-2); }
.cv-doc-texto:disabled { background: var(--cv-surface-2); color: var(--cv-text-dim); cursor: not-allowed; }

/* Cajas de ejemplo e imágenes dentro de las diapositivas de la lectura */
.cv-slide-cuerpo .cv-ej {
    background: var(--cv-primary-tint); border-left: 4px solid var(--cv-primary);
    border-radius: 8px; padding: 0.7rem 0.95rem; margin: 0.9rem 0; font-size: 0.96em; line-height: 1.55;
}
.cv-slide-cuerpo .cv-ej b { color: var(--cv-primary-dark); }
.cv-slide-cuerpo figure { margin: 1rem 0; text-align: center; }
.cv-slide-cuerpo figure svg { max-width: 100%; height: auto; }
.cv-slide-cuerpo figure img,
.cv-lectura-contenido figure img {
    max-width: 100%;
    max-height: 46vh;
    width: auto;
    height: auto;
    border-radius: 12px;
    display: inline-block;
}
.cv-slide-cuerpo figcaption { font-size: 0.82rem; color: var(--cv-text-dim); margin-top: 0.3rem; }
/* Dos o tres fotos en fila cuando caben */
.cv-slide-cuerpo .cv-fig-fila,
.cv-lectura-contenido .cv-fig-fila {
    display: flex; flex-wrap: wrap; gap: 0.8rem; justify-content: center; margin: 1rem 0;
}
.cv-slide-cuerpo .cv-fig-fila figure,
.cv-lectura-contenido .cv-fig-fila figure { flex: 1 1 200px; margin: 0; max-width: 320px; }
.cv-slide-cuerpo .cv-fig-fila img,
.cv-lectura-contenido .cv-fig-fila img {
    width: 100%;
    height: 180px;
    max-height: 180px;
    object-fit: cover;
}

/* ===== Cuadro comparativo (actividad tipo MATRIZ) ===== */

.cv-matriz-scroll {
    overflow-x: auto;
    margin: 1.25rem 0;
    border: 1px solid var(--cv-border);
    border-radius: 12px;
}
.cv-matriz {
    border-collapse: collapse;
    width: 100%;
    min-width: 640px;
    font-size: 0.9rem;
}
.cv-matriz th,
.cv-matriz td {
    border: 1px solid var(--cv-border);
    padding: 0.55rem 0.7rem;
    text-align: left;
    vertical-align: top;
}
.cv-matriz thead th {
    background: var(--cv-surface-2);
    color: var(--cv-text);
    font-weight: 600;
    position: sticky;
    top: 0;
}
.cv-matriz-fila-cab {
    background: var(--cv-surface-2);
    font-weight: 600;
    position: sticky;
    left: 0;
    z-index: 1;
    white-space: nowrap;
}
.cv-matriz-esquina { background: var(--cv-surface-2); position: sticky; left: 0; top: 0; z-index: 2; }
.cv-matriz-td-dada { color: var(--cv-text-dim); background: #fbfcfe; }
.cv-matriz-td-blanco { background: var(--cv-surface); }
.cv-matriz-input {
    width: 100%;
    min-width: 140px;
    border: 1px solid var(--cv-primary-tint);
    border-radius: 8px;
    padding: 0.4rem 0.5rem;
    font: inherit;
    color: var(--cv-text);
    background: #fff;
    resize: none;
    overflow: hidden;
}
.cv-matriz-input:focus {
    outline: none;
    border-color: var(--cv-primary);
    box-shadow: 0 0 0 2px var(--cv-primary-tint);
}
.cv-matriz-input[readonly] { background: var(--cv-surface-2); color: var(--cv-text-dim); }

.cv-matriz-barra {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 1rem;
    margin-top: 0.5rem;
}
.cv-matriz-estado { font-size: 0.85rem; color: var(--cv-text-dim); }
.cv-matriz-estado.cv-matriz-ok { color: var(--cv-success); }
.cv-matriz-estado.cv-matriz-err { color: #b42318; }

/* En docente_evidencia: la respuesta del estudiante y la guía del docente */
.cv-matriz-resp { display: block; }
.cv-matriz-guia {
    display: block;
    margin-top: 0.35rem;
    padding-top: 0.35rem;
    border-top: 1px dashed var(--cv-border);
    font-size: 0.8rem;
    color: var(--cv-text-dim);
}

/* ===== Hoja teórica de una actividad TABLA (ver EscenarioTabla.hoja_teorica) ===== */
.cv-form select {
    width: 100%;
    background: var(--cv-surface);
    border: 1.5px solid var(--cv-border);
    border-radius: 9px;
    color: var(--cv-text);
    padding: 0.65rem 0.85rem;
    margin-bottom: 1rem;
    font-size: 1rem;
}
.cv-form select:focus {
    outline: none;
    border-color: var(--cv-primary);
    box-shadow: 0 0 0 3px var(--cv-primary-tint);
}
.cv-hoja-bloque {
    padding: 1rem 0;
    border-bottom: 1px solid var(--cv-border);
}
.cv-hoja-bloque:last-child { border-bottom: none; padding-bottom: 0; }
.cv-hoja-bloque h4 { margin: 0 0 0.4rem; }
.cv-hoja-descripcion { font-size: 0.85rem; color: var(--cv-text-dim); margin: 0 0 0.75rem; }
.cv-hoja-pregunta { margin-bottom: 0.25rem; }
.cv-hoja-estado { font-size: 0.85rem; color: var(--cv-text-dim); text-align: right; }
.cv-hoja-estado.cv-hoja-ok { color: var(--cv-success); }
.cv-hoja-estado.cv-hoja-err { color: #b42318; }

/* ==========================================================================
   Pantallazos / mockups para las lecturas (curso de Python y otros).
   Ventanas simuladas (terminal, editor tipo VS Code, navegador) que se ven
   como capturas reales y funcionan dentro del visor de diapositivas
   (lectura.js): son HTML+CSS, sin JS ni imágenes externas.
   ========================================================================== */
.cv-shot {
    border: 1px solid #2a3040;
    border-radius: 12px;
    overflow: hidden;
    margin: 1rem 0;
    box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18);
    font-family: 'Courier New', Consolas, Menlo, monospace;
    background: #10131a;
}
.cv-shot-bar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.8rem;
    background: #232a38;
    border-bottom: 1px solid #2a3040;
}
.cv-shot-bar i {
    width: 11px;
    height: 11px;
    border-radius: 50%;
    display: inline-block;
}
.cv-shot-bar i.r { background: #ff5f56; }
.cv-shot-bar i.y { background: #ffbd2e; }
.cv-shot-bar i.g { background: #27c93f; }
.cv-shot-title {
    margin-left: 0.4rem;
    font-family: var(--cv-font-sans, system-ui, sans-serif);
    font-size: 0.78rem;
    color: #aeb7c7;
    font-weight: 600;
}
/* --- Terminal --- */
.cv-shot-term {
    background: #10131a;
    color: #d7dce5;
    padding: 0.9rem 1rem;
    font-size: 0.84rem;
    line-height: 1.55;
    white-space: pre-wrap;
    word-break: break-word;
}
.cv-shot-term .p { color: #27c93f; font-weight: 700; }        /* prompt */
.cv-shot-term .path { color: #4aa3ff; }                        /* ruta */
.cv-shot-term .cmd { color: #eef2f8; }                         /* comando */
.cv-shot-term .out { color: #9aa4b6; }                         /* salida */
.cv-shot-term .ok { color: #4ade80; }
.cv-shot-term .err { color: #ff6b6b; }
/* --- Editor tipo VS Code (oscuro, con números de línea) --- */
.cv-shot-tabs {
    display: flex;
    background: #1c2230;
    border-bottom: 1px solid #2a3040;
}
.cv-shot-tab {
    padding: 0.4rem 0.9rem;
    font-family: var(--cv-font-sans, system-ui, sans-serif);
    font-size: 0.76rem;
    color: #dfe5ef;
    background: #10131a;
    border-right: 1px solid #2a3040;
}
.cv-shot-code {
    margin: 0;
    padding: 0.7rem 0;
    background: #10131a;
    color: #d7dce5;
    font-size: 0.84rem;
    line-height: 1.6;
    counter-reset: ln;
    overflow-x: auto;
}
.cv-shot-code .l {
    display: block;
    padding: 0 1rem 0 3rem;
    position: relative;
    white-space: pre;
}
.cv-shot-code .l::before {
    counter-increment: ln;
    content: counter(ln);
    position: absolute;
    left: 0;
    width: 2.2rem;
    text-align: right;
    color: #55607a;
    padding-right: 0.5rem;
}
.cv-shot-code .k { color: #ff7ab2; }     /* palabra clave */
.cv-shot-code .s { color: #9ece6a; }     /* cadena */
.cv-shot-code .n { color: #ff9e64; }     /* número */
.cv-shot-code .c { color: #6a7488; font-style: italic; }  /* comentario */
.cv-shot-code .fn { color: #7aa2f7; }    /* función */
.cv-shot-code .b { color: #2ac3de; }     /* builtin */
/* --- Navegador --- */
.cv-shot-web { background: #ffffff; }
.cv-shot-urlbar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.45rem 0.8rem;
    background: #eef1f6;
    border-bottom: 1px solid #d5dae3;
}
.cv-shot-url {
    flex: 1;
    background: #fff;
    border: 1px solid #d5dae3;
    border-radius: 999px;
    padding: 0.25rem 0.8rem;
    font-family: var(--cv-font-sans, system-ui, sans-serif);
    font-size: 0.76rem;
    color: #334155;
}
.cv-shot-webbody {
    padding: 1rem 1.1rem;
    background: #fff;
    color: #1f2937;
    font-family: var(--cv-font-sans, system-ui, sans-serif);
    font-size: 0.86rem;
    line-height: 1.5;
}
.cv-shot-btn {
    display: inline-block;
    background: #2563eb;
    color: #fff;
    border-radius: 8px;
    padding: 0.4rem 0.9rem;
    font-weight: 700;
    font-size: 0.8rem;
    margin: 0.3rem 0;
}
.cv-shot-btn.amarillo { background: #ffd43b; color: #3b3000; }
/* --- Diálogo / ventana genérica de app --- */
.cv-shot-dlg {
    background: #f3f5f9;
    color: #1f2937;
    padding: 1rem 1.1rem;
    font-family: var(--cv-font-sans, system-ui, sans-serif);
    font-size: 0.86rem;
    line-height: 1.5;
}
.cv-shot-check {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin: 0.5rem 0;
    padding: 0.5rem;
    border-radius: 8px;
}
.cv-shot-check.hl { background: #fff3bf; outline: 2px solid #f59f00; }
.cv-shot-check b.box { font-family: monospace; }
.cv-shot-cap {
    display: block;
    text-align: center;
    font-size: 0.8rem;
    color: var(--cv-text-dim);
    margin: -0.4rem 0 1rem;
}

/* ===== Simulador del modelo OSI (osi_simulador.js, dentro de una lectura) =====
   La escena tiene las dos pilas de siete capas, un carril a cada lado y la red
   en el centro; el paquete va suelto por encima y se mueve de una capa a otra
   con una transición, ganando y perdiendo cabeceras a la vista. Debajo, la
   tira del PDU -la misma información en detalle- y la explicación del paso.
   En pantalla estrecha las pilas se apilan, los carriles desaparecen y el
   paquete se pega al borde derecho de la capa que lo está procesando. */

.cv-osi {
    border: 1px solid var(--cv-border);
    border-radius: 14px;
    background: var(--cv-surface);
    box-shadow: var(--cv-shadow-sm);
    padding: 1rem 1.1rem 1.1rem;
    margin: 1.4rem 0;
}
.cv-osi-cab {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    flex-wrap: wrap;
}
.cv-osi-tag {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--cv-primary-dark);
    background: var(--cv-primary-tint);
    border-radius: 999px;
    padding: 0.2rem 0.6rem;
}
.cv-osi-sel {
    font: inherit;
    font-size: 0.86rem;
    padding: 0.3rem 0.5rem;
    border: 1px solid var(--cv-border);
    border-radius: 8px;
    background: var(--cv-surface);
    color: var(--cv-text);
    max-width: 100%;
}
.cv-osi-vel { font-size: 0.78rem; padding: 0.25rem 0.4rem; }
.cv-osi-resumen {
    margin: 0.6rem 0 0.9rem;
    font-size: 0.88rem;
    color: var(--cv-text-dim);
}

/* --- escena y pilas --- */
.cv-osi-escena { position: relative; }
.cv-osi-tablero {
    display: grid;
    grid-template-columns: 1fr 74px 92px 74px 1fr;
    gap: 0.4rem;
    align-items: start;
}
.cv-osi-carril { min-height: 100%; }
.cv-osi-extremo {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    padding: 0 0.15rem 0.4rem;
}
.cv-osi-extremo strong { font-size: 0.92rem; color: var(--cv-navy); }
.cv-osi-extremo-sub { font-size: 0.78rem; color: var(--cv-text-dim); }
.cv-osi-ip { font-size: 0.72rem; color: var(--cv-text-dim); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

.cv-osi-pila { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.25rem; }
.cv-osi-capa {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.32rem 0.5rem;
    border: 1px solid var(--cv-border);
    border-radius: 9px;
    background: var(--cv-surface-2);
    transition: background 0.25s ease-out, border-color 0.25s ease-out, transform 0.25s ease-out;
}
.cv-osi-num {
    flex: 0 0 auto;
    width: 1.35rem;
    height: 1.35rem;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.72rem;
    font-weight: 700;
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    color: var(--cv-text-dim);
}
.cv-osi-capa-cuerpo { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.cv-osi-capa-nombre { font-size: 0.83rem; font-weight: 600; color: var(--cv-text); line-height: 1.2; }
.cv-osi-capa-proto { font-size: 0.72rem; color: var(--cv-text-dim); line-height: 1.25; }
.cv-osi-tcpip {
    flex: 0 0 auto;
    font-size: 0.63rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--cv-text-dim);
    border-left: 1px solid var(--cv-border);
    padding-left: 0.4rem;
}
.cv-osi-capa-hecha { background: var(--cv-accent-soft); border-color: var(--cv-accent); }
.cv-osi-capa-activa {
    background: var(--cv-primary);
    border-color: var(--cv-primary-dark);
    box-shadow: 0 0 0 3px var(--cv-primary-tint);
}
.cv-osi-capa-activa .cv-osi-capa-nombre,
.cv-osi-capa-activa .cv-osi-capa-proto { color: #ffffff; }
.cv-osi-capa-activa .cv-osi-num { background: #ffffff; color: var(--cv-primary-dark); border-color: #ffffff; }
/* En la capa activa, la etiqueta de TCP/IP cede el sitio a lo que se le está
   haciendo al paquete ahora mismo. */
.cv-osi-capa-activa .cv-osi-tcpip { display: none; }
.cv-osi-accion {
    flex: 0 0 auto;
    font-size: 0.68rem;
    font-weight: 700;
    color: var(--cv-primary-dark);
    background: #ffffff;
    border-radius: 999px;
    padding: 0.1rem 0.45rem;
    white-space: nowrap;
    animation: cv-osi-pop 0.35s ease-out;
}

/* --- la red, en el centro --- */
.cv-osi-medio { display: flex; align-items: center; justify-content: center; min-height: 140px; }
.cv-osi-red {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.1rem;
    width: 100%;
    padding: 0.5rem 0.3rem;
    border: 1px dashed var(--cv-border);
    border-radius: 10px;
    color: var(--cv-text-dim);
    transition: background 0.25s ease-out, border-color 0.25s ease-out, color 0.25s ease-out;
}
.cv-osi-red-icono { font-size: 1.3rem; line-height: 1; }
.cv-osi-red-txt { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.05em; }
.cv-osi-medio-vivo .cv-osi-red {
    background: var(--cv-primary-tint);
    border-color: var(--cv-primary);
    border-style: solid;
    color: var(--cv-primary-dark);
}

/* --- el paquete que viaja --- */
.cv-osi-paquete {
    position: absolute;
    top: 0;
    left: 0;
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 0.22rem 0.28rem;
    background: var(--cv-surface);
    border: 1px solid var(--cv-primary);
    border-radius: 9px;
    box-shadow: var(--cv-shadow-md);
    white-space: nowrap;
    z-index: 3;
    transition: transform 0.7s cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform;
}
.cv-osi-paquete-viaje { border-style: dashed; }
.cv-osi-sin-anim { transition: none !important; }
.cv-osi-chip {
    display: inline-block;
    padding: 0.12rem 0.3rem;
    border-radius: 5px;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: #ffffff;
    background: var(--cv-text-dim);
}
.cv-osi-chip-carga {
    background: var(--cv-surface-2);
    color: var(--cv-text);
    border: 1px solid var(--cv-border);
}
.cv-osi-chip-entra, .cv-osi-cabecera.cv-osi-chip-entra { animation: cv-osi-pop 0.45s ease-out; }
.cv-osi-chip-sale, .cv-osi-cabecera.cv-osi-chip-sale { animation: cv-osi-fuera 0.7s ease-out forwards; }
@keyframes cv-osi-pop {
    from { transform: scale(0.25); opacity: 0; }
    60% { transform: scale(1.12); opacity: 1; }
    to { transform: scale(1); opacity: 1; }
}
@keyframes cv-osi-fuera {
    from { transform: translateY(0) scale(1); opacity: 1; }
    to { transform: translateY(-7px) scale(0.82); opacity: 0.3; }
}

/* --- tira del PDU --- */
.cv-osi-pdu {
    margin-top: 0.9rem;
    padding: 0.6rem 0.7rem;
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    background: var(--cv-surface-2);
    overflow-x: auto;
}
.cv-osi-pdu-tipo {
    display: block;
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--cv-text-dim);
    margin-bottom: 0.35rem;
}
.cv-osi-tira { display: flex; align-items: stretch; gap: 0.2rem; min-width: max-content; }
.cv-osi-cabecera {
    display: inline-flex;
    align-items: center;
    padding: 0.3rem 0.55rem;
    border-radius: 7px;
    font-size: 0.76rem;
    font-weight: 700;
    color: #ffffff;
    background: var(--cv-text-dim);
    white-space: nowrap;
}
.cv-osi-cab-eth { background: #475569; }
.cv-osi-cab-ip { background: #a16207; }
.cv-osi-cab-tcp { background: #15803d; }
.cv-osi-cab-udp { background: #1d4ed8; }
.cv-osi-cab-http, .cv-osi-cab-dns, .cv-osi-cab-ssh { background: var(--cv-primary); }
.cv-osi-carga {
    display: inline-flex;
    align-items: center;
    padding: 0.3rem 0.7rem;
    border-radius: 7px;
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    font-size: 0.78rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    color: var(--cv-text);
    white-space: nowrap;
}
.cv-osi-pdu-nota { display: block; margin-top: 0.35rem; font-size: 0.74rem; color: var(--cv-text-dim); }

/* --- explicación y controles --- */
.cv-osi-detalle {
    margin-top: 0.75rem;
    padding: 0.7rem 0.85rem;
    border: 1px solid var(--cv-border);
    border-left: 3px solid var(--cv-primary);
    border-radius: 10px;
    background: var(--cv-surface);
    min-height: 6.2rem;
}
.cv-osi-detalle-tit { margin: 0 0 0.3rem; font-size: 0.9rem; color: var(--cv-navy); }
.cv-osi-detalle-txt { margin: 0; font-size: 0.88rem; line-height: 1.55; color: var(--cv-text); }
.cv-osi-detalle-txt code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.85em;
    background: var(--cv-surface-2);
    padding: 0.05em 0.3em;
    border-radius: 4px;
}
.cv-osi-detalle-accion { margin: 0.4rem 0 0; font-size: 0.78rem; color: var(--cv-text-dim); }

.cv-osi-barra {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
    margin-top: 0.8rem;
}
.cv-osi-btn {
    font: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    padding: 0.35rem 0.7rem;
    border-radius: 8px;
    border: 1px solid var(--cv-border);
    background: var(--cv-surface);
    color: var(--cv-text);
    cursor: pointer;
    transition: background 0.15s ease-out, border-color 0.15s ease-out;
}
.cv-osi-btn:hover:not(:disabled) { background: var(--cv-surface-2); border-color: var(--cv-primary); }
.cv-osi-btn:disabled { opacity: 0.45; cursor: default; }
.cv-osi-btn-mini { padding: 0.35rem 0.55rem; }
.cv-osi-btn-p { background: var(--cv-primary); border-color: var(--cv-primary); color: #ffffff; }
.cv-osi-btn-p:hover:not(:disabled) { background: var(--cv-primary-dark); border-color: var(--cv-primary-dark); }
.cv-osi-btn-on { background: var(--cv-accent-soft); border-color: var(--cv-primary); color: var(--cv-primary-dark); }
.cv-osi-cuenta { font-size: 0.78rem; color: var(--cv-text-dim); margin: 0 0.2rem; }

@media (max-width: 760px) {
    .cv-osi-tablero { grid-template-columns: 1fr; }
    .cv-osi-carril { display: none; }
    .cv-osi-medio { min-height: 0; }
    .cv-osi-red { flex-direction: row; justify-content: center; gap: 0.5rem; padding: 0.35rem; }
    .cv-osi-tcpip { display: none; }
    /* Sin carriles, el paquete se pone encima del lado derecho de la capa
       activa: ahí ya no cabe el chip de la acción, y lo que se añade o se
       quita se ve igual en el propio paquete y en la tira del PDU. */
    .cv-osi-accion { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .cv-osi-paquete { transition: none; }
    .cv-osi-chip-entra, .cv-osi-chip-sale, .cv-osi-accion { animation: none; }
    .cv-osi-chip-sale { opacity: 0.35; }
}

/* ===== Consulta en grupo — ABP (abp_ui.js, actividad tipo ABP) =====
   El caso arriba, las etapas como pasos, y debajo lo que falta para enviar.
   Casi todo lo pinta el JS a partir del estado que manda el servidor. */

.cv-abp-caso {
    border: 1px solid var(--cv-border);
    border-left: 4px solid var(--cv-primary);
    border-radius: 12px;
    background: var(--cv-surface-2);
    padding: 0.9rem 1.1rem;
    margin: 1.2rem 0;
}
.cv-abp-caso p { margin: 0 0 0.7rem; line-height: 1.6; }
.cv-abp-tag {
    display: inline-block;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--cv-primary-dark);
    background: var(--cv-primary-tint);
    border-radius: 999px;
    padding: 0.15rem 0.6rem;
    margin-bottom: 0.6rem;
}
.cv-abp-pregunta {
    margin: 0.8rem 0 0 !important;
    padding-top: 0.7rem;
    border-top: 1px dashed var(--cv-border);
    font-weight: 700;
    color: var(--cv-navy);
}
.cv-abp-rubrica { margin: 0.8rem 0 1rem; font-size: 0.88rem; }
.cv-abp-rubrica summary { cursor: pointer; color: var(--cv-primary-dark); font-weight: 600; }
.cv-abp-rubrica ul { margin: 0.6rem 0 0; padding-left: 1.2rem; line-height: 1.6; }
.cv-abp-pts { color: var(--cv-text-dim); font-size: 0.82rem; }

/* --- cabecera del grupo --- */
.cv-abp-cab {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    flex-wrap: wrap;
    padding: 0.6rem 0.8rem;
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    background: var(--cv-surface);
    box-shadow: var(--cv-shadow-sm);
}
.cv-abp-cab-izq { display: flex; flex-direction: column; min-width: 0; }
.cv-abp-nombre { color: var(--cv-navy); font-size: 0.98rem; }
.cv-abp-quienes { font-size: 0.82rem; color: var(--cv-text-dim); }
.cv-abp-estado { font-size: 0.8rem; color: var(--cv-text-dim); }
.cv-abp-chip {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 700;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    background: var(--cv-surface-2);
    color: var(--cv-text-dim);
}
.cv-abp-chip-ok { background: #dcfce7; color: #166534; }

/* --- pasos --- */
.cv-abp-nav {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    margin: 0.9rem 0;
}
.cv-abp-paso {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font: inherit;
    font-size: 0.82rem;
    padding: 0.35rem 0.7rem;
    border: 1px solid var(--cv-border);
    border-radius: 999px;
    background: var(--cv-surface);
    color: var(--cv-text);
    cursor: pointer;
    transition: background 0.15s ease-out, border-color 0.15s ease-out;
}
.cv-abp-paso:hover { border-color: var(--cv-primary); }
.cv-abp-paso-num {
    width: 1.25rem;
    height: 1.25rem;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.7rem;
    font-weight: 700;
    background: var(--cv-surface-2);
    color: var(--cv-text-dim);
}
.cv-abp-paso-ok { color: var(--cv-success); font-weight: 700; }
.cv-abp-paso-activo {
    background: var(--cv-primary);
    border-color: var(--cv-primary);
    color: #ffffff;
}
.cv-abp-paso-activo .cv-abp-paso-num { background: #ffffff; color: var(--cv-primary-dark); }
.cv-abp-paso-activo .cv-abp-paso-ok { color: #ffffff; }

/* --- etapa --- */
.cv-abp-etapa {
    border: 1px solid var(--cv-border);
    border-radius: 12px;
    background: var(--cv-surface);
    padding: 1rem 1.1rem;
}
.cv-abp-etapa-tit { margin: 0 0 0.4rem; color: var(--cv-navy); font-size: 1.05rem; }
.cv-abp-etapa-ins { margin: 0 0 1rem; font-size: 0.92rem; line-height: 1.6; color: var(--cv-text); }
.cv-abp-nota { font-size: 0.84rem; color: var(--cv-text-dim); margin: 0.6rem 0; }

/* --- integrantes y roles --- */
.cv-abp-integrantes { list-style: none; margin: 0 0 0.8rem; padding: 0; display: grid; gap: 0.4rem; }
.cv-abp-integrante {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    flex-wrap: wrap;
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--cv-border);
    border-radius: 9px;
    background: var(--cv-surface-2);
}
.cv-abp-integrante-nombre { font-weight: 600; font-size: 0.9rem; }
.cv-abp-rol-fijo {
    font-size: 0.82rem;
    color: var(--cv-primary-dark);
    background: var(--cv-primary-tint);
    border: 1px solid #cfe0f7;
    border-radius: 999px;
    padding: 0.2rem 0.65rem;
}
.cv-abp-rol, .cv-abp-input {
    font: inherit;
    font-size: 0.86rem;
    padding: 0.3rem 0.5rem;
    border: 1px solid var(--cv-border);
    border-radius: 8px;
    background: var(--cv-surface);
    color: var(--cv-text);
    max-width: 100%;
}
.cv-abp-companeros {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.3rem;
    margin: 0.5rem 0 0.8rem;
}
.cv-abp-companero {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.88rem;
    padding: 0.3rem 0.45rem;
    border-radius: 8px;
    cursor: pointer;
}
.cv-abp-companero:hover { background: var(--cv-surface-2); }
.cv-abp-companero-off { color: var(--cv-text-dim); cursor: default; }
.cv-abp-acciones { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.6rem; }

/* --- campos de texto compartidos --- */
.cv-abp-campo { margin-bottom: 1.1rem; }
.cv-abp-campo-tit { display: block; font-weight: 700; color: var(--cv-navy); font-size: 0.92rem; }
.cv-abp-campo-ayuda { margin: 0.15rem 0 0.4rem; font-size: 0.84rem; color: var(--cv-text-dim); }
.cv-abp-texto {
    width: 100%;
    font: inherit;
    font-size: 0.92rem;
    line-height: 1.55;
    padding: 0.6rem 0.7rem;
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    background: var(--cv-surface);
    color: var(--cv-text);
    resize: vertical;
}
.cv-abp-texto:focus { outline: 2px solid var(--cv-primary); outline-offset: 1px; }
.cv-abp-texto:disabled { background: var(--cv-surface-2); color: var(--cv-text-dim); }
.cv-abp-cuenta { display: block; margin-top: 0.2rem; font-size: 0.76rem; color: var(--cv-text-dim); }
.cv-abp-cuenta-ok { color: var(--cv-success); }

/* --- fuentes --- */
.cv-abp-fuentes { margin: 0 0 1rem; padding-left: 1.2rem; display: grid; gap: 0.6rem; }
.cv-abp-fuente {
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    background: var(--cv-surface-2);
    padding: 0.55rem 0.7rem;
    list-style-position: outside;
}
.cv-abp-fuente-cab { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.cv-abp-fuente-ref { font-size: 0.82rem; color: var(--cv-primary-dark); word-break: break-word; }
.cv-abp-fuente-aporte { font-size: 0.88rem; margin-top: 0.25rem; line-height: 1.5; }
.cv-abp-fuente-quien { font-size: 0.76rem; color: var(--cv-text-dim); margin-top: 0.3rem; }
.cv-abp-quitar {
    font: inherit;
    font-size: 0.76rem;
    margin-top: 0.35rem;
    padding: 0.15rem 0.5rem;
    border: 1px solid var(--cv-border);
    border-radius: 7px;
    background: var(--cv-surface);
    color: var(--cv-danger);
    cursor: pointer;
}
.cv-abp-form {
    display: grid;
    gap: 0.45rem;
    padding: 0.8rem;
    border: 1px dashed var(--cv-border);
    border-radius: 10px;
    background: var(--cv-surface-2);
}
.cv-abp-form h4 { margin: 0; color: var(--cv-navy); font-size: 0.95rem; }
.cv-abp-form .cv-btn { justify-self: start; }
.cv-abp-form input[type="file"] { font-size: 0.85rem; }

/* --- editor del repositorio del equipo (taller_editor.js) ---
   Distribución de editor de código: explorador a la izquierda, pestañas
   arriba y el texto con su columna de números. No pretende ser un IDE: lo que
   se busca es que quien ya usó uno no tenga que aprender nada. */
.cv-editor-barra { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; margin-bottom: 0.6rem; }
.cv-editor-cuerpo {
    display: grid;
    grid-template-columns: minmax(11rem, 17rem) 1fr;
    gap: 0.7rem;
    align-items: start;
}
@media (max-width: 720px) { .cv-editor-cuerpo { grid-template-columns: 1fr; } }
.cv-editor-lateral {
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    background: var(--cv-surface-2);
    overflow: hidden;
}
.cv-editor-lateral-tit {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--cv-text-dim);
    padding: 0.5rem 0.7rem 0.35rem;
}
.cv-editor-arbol { max-height: min(70vh, 40rem); overflow: auto; padding: 0 0.3rem 0.4rem; }
.cv-editor-item {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    width: 100%;
    text-align: left;
    border: 0;
    background: none;
    font: inherit;
    font-size: 0.83rem;
    padding: 0.2rem 0.4rem;
    border-radius: 6px;
    cursor: pointer;
    color: var(--cv-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.cv-editor-item:hover { background: var(--cv-surface); }
.cv-editor-icono { flex: none; font-size: 0.8rem; }
.cv-editor-carpeta { font-weight: 600; }
.cv-editor-abierto { background: var(--cv-surface); font-weight: 600; }
.cv-editor-activo { background: var(--cv-primary); color: #fff; }
.cv-editor-punto { color: var(--cv-warning); margin-left: auto; font-size: 0.7rem; }

.cv-editor-panel { display: flex; flex-direction: column; min-width: 0; }
.cv-editor-pestanas {
    display: flex;
    gap: 0.25rem;
    overflow-x: auto;
    border-bottom: 1px solid var(--cv-border);
    padding-bottom: 0.3rem;
    margin-bottom: 0.4rem;
    min-height: 1.6rem;
}
.cv-editor-pestana {
    display: inline-flex;
    align-items: center;
    background: var(--cv-surface-2);
    border: 1px solid var(--cv-border);
    border-radius: 8px 8px 0 0;
    padding: 0.15rem 0.2rem 0.15rem 0.5rem;
    white-space: nowrap;
}
.cv-editor-pestana-activa { background: var(--cv-surface); border-bottom-color: var(--cv-surface); font-weight: 600; }
.cv-editor-pestana-nombre, .cv-editor-pestana-cerrar {
    border: 0; background: none; font: inherit; font-size: 0.8rem;
    cursor: pointer; color: var(--cv-text); padding: 0.1rem 0.25rem;
}
.cv-editor-pestana-cerrar { color: var(--cv-text-dim); }
.cv-editor-pestana-cerrar:hover { color: var(--cv-danger); }
.cv-editor-cab { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.4rem; }
.cv-editor-cab strong { font-size: 0.82rem; color: var(--cv-text-dim); word-break: break-all; }

.cv-editor-marco {
    /* La regleta y el código leen de aquí: una sola métrica para los dos. */
    --cv-codigo-fuente: ui-monospace, SFMono-Regular, Menlo, monospace;
    --cv-codigo-tam: 0.86rem;
    --cv-codigo-alto: 1.55;
    display: flex;
    /* Altura fija y el desplazamiento por dentro: si el marco creciera con el
       archivo, abrir uno de quinientas líneas dejaría el explorador y las
       pestañas fuera de la pantalla. El tirador de abajo lo agranda. */
    height: min(70vh, 40rem);
    resize: vertical;
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    background: var(--cv-surface);
    overflow: hidden;
}
.cv-editor-numeros {
    margin: 0;
    padding: 0.7rem 0.5rem;
    text-align: right;
    color: var(--cv-text-dim);
    background: var(--cv-surface-2);
    border-right: 1px solid var(--cv-border);
    font-family: var(--cv-codigo-fuente);
    font-size: var(--cv-codigo-tam);
    line-height: var(--cv-codigo-alto);
    height: 100%;
    overflow: hidden;
    user-select: none;
    min-width: 2.4rem;
}
.cv-editor-texto {
    flex: 1;
    min-width: 0;
    height: 100%;
    resize: none;
    border: 0;
    font-family: var(--cv-codigo-fuente);
    font-size: var(--cv-codigo-tam);
    line-height: var(--cv-codigo-alto);
    tab-size: 4;
    /* Sin ajuste de línea, como cualquier editor de código: si una línea larga
       se partiera en dos filas, ocuparía dos renglones y un solo número, y a
       partir de ahí la regleta dejaría de coincidir con el código. */
    white-space: pre;
    overflow-wrap: normal;
    overflow-x: auto;
    padding: 0.7rem 0.7rem;
    background: var(--cv-surface);
    color: var(--cv-text);
}
.cv-editor-texto:focus { outline: 2px solid var(--cv-primary); outline-offset: -2px; }

/* --- construir desde la actividad: pasos + consola del grupo --- */
.cv-consola { display: grid; gap: 0.6rem; }
.cv-consola-paso {
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    background: var(--cv-surface);
    padding: 0.55rem 0.7rem;
}
.cv-consola-paso summary {
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 600;
    color: var(--cv-navy);
}
.cv-consola-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 50%;
    background: var(--cv-primary);
    color: #fff;
    font-size: 0.78rem;
}
.cv-consola-texto { font-size: 0.9rem; line-height: 1.6; margin: 0.45rem 0; }
.cv-consola-codigo {
    background: var(--cv-surface-2);
    border-left: 3px solid var(--cv-primary);
    border-radius: 8px;
    padding: 0.5rem 0.65rem;
    font-size: 0.84rem;
    white-space: pre-wrap;
    margin: 0 0 0.4rem;
}
.cv-consola-caja {
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    background: var(--cv-surface-2);
    padding: 0.7rem 0.8rem;
}
.cv-consola-caja h4 { margin: 0 0 0.5rem; color: var(--cv-navy); font-size: 0.95rem; }
.cv-consola-historial {
    max-height: 18rem;
    overflow-y: auto;
    margin-bottom: 0.6rem;
}
.cv-consola-bloque { margin-bottom: 0.7rem; }
.cv-consola-autor { font-size: 0.76rem; color: var(--cv-text-dim); }
.cv-consola-historial pre {
    margin: 0.2rem 0 0;
    padding: 0.4rem 0.55rem;
    border-radius: 8px;
    font-size: 0.82rem;
    white-space: pre-wrap;
    word-break: break-word;
}
.cv-consola-eco { background: var(--cv-surface); border-left: 3px solid var(--cv-primary); }
.cv-consola-salida { background: var(--cv-surface); }
.cv-consola-error { background: #fff2f0; color: #b42318; }
.cv-consola-acciones {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-top: 0.5rem;
}

/* --- consola del taller (taller.js) --- */
.cv-taller-historial {
    max-height: 26rem;
    overflow-y: auto;
    padding: 0.6rem;
    margin-bottom: 0.8rem;
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    background: var(--cv-surface-2);
}
.cv-taller-bloque { margin-bottom: 0.9rem; }
.cv-taller-cab {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    font-size: 0.8rem;
    color: var(--cv-text-dim);
}
.cv-taller-hora { font-size: 0.74rem; }
.cv-taller-historial pre {
    margin: 0.2rem 0 0;
    padding: 0.45rem 0.6rem;
    border-radius: 8px;
    font-size: 0.84rem;
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
}
.cv-taller-codigo-eco { background: var(--cv-surface); border-left: 3px solid var(--cv-primary); }
.cv-taller-salida { background: var(--cv-surface); color: var(--cv-text); }
.cv-taller-error { background: #fff2f0; color: #b42318; }
.cv-taller-codigo {
    width: 100%;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.88rem;
    padding: 0.6rem 0.7rem;
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    background: var(--cv-surface);
    color: var(--cv-text);
    resize: vertical;
}
.cv-taller-codigo:focus { outline: 2px solid var(--cv-primary); outline-offset: 1px; }
.cv-taller-acciones {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-top: 0.5rem;
}

/* --- autoría de cada campo (quién lo escribió) --- */
.cv-abp-autor {
    display: block;
    margin-top: 0.2rem;
    font-size: 0.74rem;
    color: var(--cv-text-dim);
    font-style: italic;
}
.cv-matriz-td-blanco .cv-abp-autor { margin-top: 0.15rem; font-size: 0.68rem; }

/* --- generador de citas APA (cita_apa.js) --- */
.cv-cita {
    display: grid;
    gap: 0.5rem;
    padding: 0.75rem 0.85rem;
    margin-bottom: 0.8rem;
    border: 1px solid var(--cv-border);
    border-left: 3px solid var(--cv-primary);
    border-radius: 10px;
    background: var(--cv-surface);
}
.cv-cita-cab { display: grid; gap: 0.2rem; }
.cv-cita-cab strong { color: var(--cv-navy); font-size: 0.95rem; }
.cv-cita-ayuda { font-size: 0.82rem; color: var(--cv-text-dim); line-height: 1.5; }
.cv-cita-fila { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.cv-cita-url { flex: 1 1 16rem; min-width: 0; }
.cv-cita-aviso { margin: 0; font-size: 0.83rem; color: var(--cv-success); }
.cv-cita-aviso.cv-cita-error { color: var(--cv-danger); }
.cv-cita-resultado {
    display: grid;
    gap: 0.5rem;
    padding-top: 0.6rem;
    border-top: 1px dashed var(--cv-border);
}
.cv-cita-campos {
    display: grid;
    gap: 0.5rem;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}
.cv-cita-campo { display: grid; gap: 0.2rem; }
.cv-cita-etiqueta { font-size: 0.76rem; color: var(--cv-text-dim); font-weight: 600; }
.cv-cita-vista {
    margin: 0;
    padding: 0.55rem 0.7rem;
    border-radius: 8px;
    background: var(--cv-surface-2);
    font-size: 0.9rem;
    line-height: 1.6;
    /* La sangría francesa de APA, para que se vea como en el trabajo final. */
    padding-left: 2.2rem;
    text-indent: -1.5rem;
    word-break: break-word;
}
.cv-cita-acciones { display: flex; gap: 0.5rem; flex-wrap: wrap; }

/* --- archivos del grupo (diagrama / topología) --- */
.cv-abp-archivos { list-style: none; margin: 0 0 1rem; padding: 0; display: grid; gap: 0.7rem; }
.cv-abp-archivo {
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    background: var(--cv-surface-2);
    padding: 0.6rem 0.7rem;
}
.cv-abp-archivo-cab {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.35rem;
}
.cv-abp-archivo-cab a { font-weight: 600; word-break: break-all; }
.cv-abp-archivo-quien { font-size: 0.76rem; color: var(--cv-text-dim); }
.cv-abp-archivo-vista {
    display: block;
    max-width: 100%;
    max-height: 340px;
    margin-bottom: 0.5rem;
    border: 1px solid var(--cv-border);
    border-radius: 8px;
    background: var(--cv-surface);
}

/* --- cierre --- */
.cv-abp-final { margin-top: 1rem; }
.cv-abp-pendientes {
    border: 1px solid var(--cv-border);
    border-left: 3px solid var(--cv-warning);
    border-radius: 10px;
    background: var(--cv-surface);
    padding: 0.7rem 0.9rem;
    margin-bottom: 0.7rem;
    font-size: 0.88rem;
}
.cv-abp-pendientes ul { margin: 0.4rem 0 0; padding-left: 1.2rem; line-height: 1.6; }
.cv-abp-listo { color: var(--cv-success); font-weight: 600; font-size: 0.9rem; }
.cv-abp-bitacora { margin-top: 0.8rem; font-size: 0.82rem; color: var(--cv-text-dim); }
.cv-abp-bitacora summary { cursor: pointer; }
.cv-abp-bitacora ul { margin: 0.4rem 0 0; padding-left: 1.2rem; line-height: 1.6; }
.cv-abp-arranque {
    border: 1px solid var(--cv-border);
    border-radius: 12px;
    background: var(--cv-surface-2);
    padding: 1rem 1.1rem;
}
.cv-abp-arranque h3 { margin: 0 0 0.4rem; color: var(--cv-navy); }
.cv-abp-arranque p { margin: 0 0 0.8rem; font-size: 0.92rem; line-height: 1.6; }
.cv-abp-otros { margin: 0.8rem 0; }
.cv-abp-otros h4 { margin: 0 0 0.4rem; font-size: 0.9rem; color: var(--cv-navy); }
.cv-abp-otros-lista { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.3rem; }
.cv-abp-otro {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    flex-wrap: wrap;
    font-size: 0.88rem;
    padding: 0.4rem 0.6rem;
    border: 1px dashed var(--cv-border);
    border-radius: 9px;
}
.cv-abp-mas { margin-top: 0.3rem; font-size: 0.86rem; }
.cv-abp-mas summary { cursor: pointer; color: var(--cv-primary-dark); }
.cv-abp-mas ul { margin: 0.3rem 0 0; padding-left: 1.2rem; line-height: 1.6; }

/* ===== Espacio de trabajo del proyecto (.cv-ws) ===== */
.cv-ws-cab { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.cv-ws-rejilla {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: 1rem;
    margin-top: 1rem;
}
@media (max-width: 1000px) { .cv-ws-rejilla { grid-template-columns: 1fr; } }
.cv-ws-editor { border: 0; }

/* Navegador integrado */
.cv-ws-nav { display: flex; flex-direction: column; min-width: 0; }
.cv-ws-nav-barra { display: flex; gap: 0.4rem; align-items: center; margin-bottom: 0.4rem; }
.cv-ws-nav-ruta {
    flex: 1; min-width: 0;
    font-family: var(--cv-codigo-fuente, monospace); font-size: 0.82rem;
    padding: 0.35rem 0.5rem;
    border: 1px solid var(--cv-border); border-radius: 8px;
    background: var(--cv-surface); color: var(--cv-text);
}
.cv-ws-nav-ruta:focus { outline: none; border-color: var(--cv-primary); box-shadow: 0 0 0 3px var(--cv-primary-tint); }
.cv-ws-nav-marco {
    position: relative;
    height: min(70vh, 40rem);
    border: 1px solid var(--cv-border);
    border-radius: 10px;
    overflow: hidden;
    background: #fff;
}
.cv-ws-nav-marco iframe { width: 100%; height: 100%; border: 0; display: block; background: #fff; }
.cv-ws-nav-grande .cv-ws-nav-marco { height: min(78vh, 52rem); }
.cv-ws-nav-vacio {
    position: absolute; inset: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    text-align: center; padding: 1.5rem; gap: 0.3rem;
    background: var(--cv-surface-2); color: var(--cv-text);
}
/* `display:flex` le gana al `display:none` del atributo `hidden` (UA): sin
   esto el recuadro «Arrancando…» nunca se quita y tapa el proyecto ya cargado. */
.cv-ws-nav-vacio[hidden] { display: none; }
.cv-ws-nav-log {
    margin: 0.4rem 0 0; max-height: 9rem; overflow: auto;
    background: var(--cv-surface-2); border: 1px solid var(--cv-border); border-radius: 8px;
    padding: 0.5rem 0.6rem; font-size: 0.78rem; white-space: pre-wrap;
    color: var(--cv-danger);
}

/* Terminal */
.cv-ws-term { margin-top: 1.2rem; }
.cv-ws-term-cab { display: flex; gap: 0.6rem; align-items: baseline; flex-wrap: wrap; margin-bottom: 0.4rem; }
.cv-ws-term-historial {
    max-height: 22rem; overflow: auto;
    background: #0f172a; color: #e2e8f0;
    border-radius: 10px 10px 0 0; padding: 0.7rem 0.8rem;
    font-family: var(--cv-codigo-fuente, ui-monospace, Menlo, monospace); font-size: 0.82rem;
}
.cv-ws-term-bloque { margin-bottom: 0.7rem; }
.cv-ws-term-fila-cab { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.cv-ws-term-eco { color: #7dd3fc; white-space: pre-wrap; word-break: break-word; }
.cv-ws-term-meta { color: #64748b; font-size: 0.72rem; flex: none; }
/* Los <pre> de la terminal y de la consola MySQL viven sobre fondo oscuro: la
   regla genérica ".cv-card pre" (fondo claro, borde, relleno) NO aplica ahí. */
.cv-card .cv-ws-term-historial pre,
.cv-card .cv-ws-sql-historial pre {
    background: transparent; border: 0; border-radius: 0; padding: 0;
    font-size: inherit; line-height: 1.5; overflow: visible;
}
.cv-ws-term-salida { margin: 0.2rem 0 0; white-space: pre-wrap; word-break: break-word; color: #e2e8f0; }
.cv-ws-term-err { margin: 0.2rem 0 0; white-space: pre-wrap; word-break: break-word; color: #fca5a5; }
.cv-ws-term-ok { margin: 0.2rem 0 0; white-space: pre-wrap; color: #86efac; font-size: 0.85em; opacity: 0.9; }
.cv-ws-term-entrada {
    display: flex; align-items: flex-start; gap: 0.5rem;
    background: #1e293b; border-radius: 0 0 10px 10px; padding: 0.5rem 0.6rem;
}
.cv-ws-term-prompt { color: #7dd3fc; font-family: var(--cv-codigo-fuente, monospace); padding-top: 0.35rem; }
.cv-ws-term-codigo {
    flex: 1; min-width: 0; resize: none; border: 0; background: transparent; color: #e2e8f0;
    font-family: var(--cv-codigo-fuente, ui-monospace, Menlo, monospace); font-size: 0.85rem;
    line-height: 1.5; padding: 0.3rem 0; outline: none;
}
.cv-ws-term-codigo::placeholder { color: #64748b; }

/* ===== Tablero Kanban del equipo (.cv-kb) ===== */
.cv-kb-barra { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; margin: 1rem 0 0.8rem; }
.cv-kb-sm {
    background: var(--cv-primary-tint); color: var(--cv-primary-dark);
    border: 1px solid #cfe0f7; border-radius: 999px; padding: 0.3rem 0.8rem; font-size: 0.85rem;
}
.cv-kb-nota { font-size: 0.8rem; color: var(--cv-text-dim); }

.cv-kb-cols {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.8rem;
    align-items: start;
}
@media (max-width: 1000px) { .cv-kb-cols { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .cv-kb-cols { grid-template-columns: 1fr; } }

.cv-kb-col { background: var(--cv-surface-2); border: 1px solid var(--cv-border); border-radius: 12px; }
.cv-kb-col-cab {
    display: flex; align-items: center; justify-content: space-between;
    padding: 0.6rem 0.8rem; border-bottom: 1px solid var(--cv-border);
}
.cv-kb-col-tit { font-weight: 700; color: var(--cv-navy); font-size: 0.9rem; }
.cv-kb-col-n {
    background: var(--cv-surface); border: 1px solid var(--cv-border); border-radius: 999px;
    min-width: 1.5rem; text-align: center; font-size: 0.78rem; padding: 0.05rem 0.4rem;
}
.cv-kb-col-cuerpo { padding: 0.6rem; display: flex; flex-direction: column; gap: 0.55rem; min-height: 3rem; }
.cv-kb-col-sobre { background: var(--cv-primary-tint); border-radius: 0 0 12px 12px; }

.cv-kb-nueva {
    border: 1px dashed var(--cv-border); background: transparent; color: var(--cv-text-dim);
    border-radius: 9px; padding: 0.45rem; cursor: pointer; font: inherit; font-size: 0.82rem;
}
.cv-kb-nueva:hover { border-color: var(--cv-primary); color: var(--cv-primary); }

.cv-kb-card {
    background: var(--cv-surface); border: 1px solid var(--cv-border);
    border-left: 4px solid var(--cv-border); border-radius: 10px;
    padding: 0.6rem 0.7rem; box-shadow: var(--cv-shadow-soft, 0 1px 2px rgba(0,0,0,0.05));
}
.cv-kb-card[draggable="true"] { cursor: grab; }
.cv-kb-drag { opacity: 0.5; }
.cv-kb-card-por_hacer { border-left-color: #94a3b8; }
.cv-kb-card-en_curso { border-left-color: var(--cv-primary); }
.cv-kb-card-en_revision { border-left-color: #f5a524; }
.cv-kb-card-hecho { border-left-color: #17c964; }
.cv-kb-card-tit { font-weight: 600; font-size: 0.9rem; }
.cv-kb-card-desc { margin: 0.3rem 0 0; font-size: 0.82rem; color: var(--cv-text-dim); white-space: pre-wrap; }
.cv-kb-card-meta { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.45rem; }
.cv-kb-chip {
    background: var(--cv-surface-2); border: 1px solid var(--cv-border);
    border-radius: 999px; padding: 0.1rem 0.5rem; font-size: 0.74rem;
}
.cv-kb-fecha { font-size: 0.74rem; color: var(--cv-text-dim); }
.cv-kb-vencida { color: var(--cv-danger); font-weight: 700; }
.cv-kb-cierre { color: #7c6f00; }

.cv-kb-av { display: flex; align-items: center; gap: 0.4rem; margin-top: 0.5rem; }
.cv-kb-av-barra { flex: 1; height: 6px; background: var(--cv-surface-2); border-radius: 999px; overflow: hidden; }
.cv-kb-av-relleno { height: 100%; background: var(--cv-primary); border-radius: 999px; }
.cv-kb-av-rango { flex: 1; }
.cv-kb-av-pct { font-size: 0.74rem; color: var(--cv-text-dim); min-width: 2.4rem; text-align: right; }

.cv-kb-card-acc { display: flex; gap: 0.3rem; margin-top: 0.5rem; align-items: center; }
.cv-kb-mini {
    font: inherit; font-size: 0.76rem; padding: 0.15rem 0.3rem;
    border: 1px solid var(--cv-border); border-radius: 7px; background: var(--cv-surface); color: var(--cv-text);
}
.cv-kb-mini-btn { cursor: pointer; }
.cv-kb-mini-btn:hover { border-color: var(--cv-primary); }

.cv-kb-form { background: var(--cv-surface); border: 1px solid var(--cv-primary); border-radius: 10px; padding: 0.6rem 0.7rem; display: flex; flex-direction: column; gap: 0.45rem; }
.cv-kb-form-lbl { font-size: 0.76rem; color: var(--cv-text-dim); display: flex; flex-direction: column; gap: 0.2rem; }
.cv-kb-form-input { font: inherit; font-size: 0.85rem; padding: 0.3rem 0.4rem; border: 1px solid var(--cv-border); border-radius: 7px; background: var(--cv-surface); color: var(--cv-text); }
.cv-kb-form-acc { display: flex; gap: 0.4rem; margin-top: 0.2rem; }

/* ── Guiones de lección: el audio/video del docente dentro de la lectura ──
   La caja tiene que leerse como "esto lo dice una persona", distinta del texto
   que la rodea, sin robarle el sitio: por eso el borde de color a la izquierda
   y el fondo apenas separado del papel. */
.cv-guion-caja {
    margin: 1.1rem 0;
    padding: 0.85rem 1rem;
    border: 1px solid var(--cv-border);
    border-left: 4px solid var(--cv-primary);
    border-radius: 10px;
    background: var(--cv-surface-2);
}
.cv-guion-cab {
    display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap;
    margin-bottom: 0.6rem; font-size: 0.95rem;
}
.cv-guion-icono { font-size: 1.05rem; }
.cv-guion-autor { color: var(--cv-text-dim); font-size: 0.82rem; }
.cv-guion-media { width: 100%; border-radius: 8px; }
video.cv-guion-media { max-height: 26rem; background: #000; }
.cv-guion-yt iframe { width: 100%; aspect-ratio: 16 / 9; border: 0; border-radius: 8px; }
.cv-guion-pendiente {
    margin: 0 0 0.5rem; padding: 0.55rem 0.7rem;
    background: #fdf1e2; color: var(--cv-warning);
    border-radius: 8px; font-size: 0.85rem;
}
/* El libreto se lee mientras suena el audio, así que va con más aire y en un
   cuerpo algo mayor que el texto corrido. */
.cv-guion-texto { margin-top: 0.7rem; font-size: 1rem; line-height: 1.65; }
.cv-guion-texto p { margin: 0 0 0.4rem; }
.cv-guion-traduccion { margin-top: 0.4rem; font-size: 0.85rem; color: var(--cv-text-dim); }
.cv-guion-traduccion summary { cursor: pointer; }
.cv-guion-aviso-docente {
    margin: 0.6rem 0 0; font-size: 0.85rem; color: var(--cv-text-dim);
}

/* ── Estudio de grabación (docente) ── */
.cv-estudio-resumen { margin: 0.9rem 0 0.4rem; }
.cv-estudio-cifra { font-size: 0.95rem; }
.cv-estudio-barra {
    height: 8px; border-radius: 999px; background: var(--cv-surface-2);
    overflow: hidden; margin: 0.4rem 0 0.3rem; max-width: 26rem;
}
.cv-estudio-barra span { display: block; height: 100%; background: var(--cv-success); }
.cv-estudio-faltan { margin: 0; font-size: 0.85rem; color: var(--cv-text-dim); }
.cv-estudio-ayuda { margin-top: 1rem; font-size: 0.88rem; }
.cv-estudio-ayuda summary { cursor: pointer; color: var(--cv-primary); }
.cv-estudio-ayuda ul { margin: 0.5rem 0 0 1.1rem; color: var(--cv-text-dim); }
.cv-estudio-ayuda li { margin-bottom: 0.25rem; }

.cv-guion-ficha {
    border: 1px solid var(--cv-border); border-radius: 10px;
    padding: 0.9rem 1rem; margin-bottom: 0.9rem;
}
.cv-guion-ficha-cab {
    display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.5rem;
}
.cv-guion-dur { color: var(--cv-text-dim); font-size: 0.8rem; }
.cv-guion-libreto {
    background: var(--cv-surface-2); border-radius: 8px; padding: 0.6rem 0.8rem;
    font-size: 1rem; line-height: 1.6;
}
.cv-guion-libreto p { margin: 0 0 0.45rem; }
.cv-guion-libreto p:last-child { margin-bottom: 0; }
.cv-guion-trad, .cv-guion-indic { font-size: 0.85rem; color: var(--cv-text-dim); margin: 0.5rem 0 0; }
.cv-guion-actual { margin-top: 0.7rem; }
.cv-guion-firma { font-size: 0.78rem; color: var(--cv-text-dim); margin: 0.3rem 0 0; }
.cv-guion-acciones {
    display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; margin-top: 0.8rem;
    padding-top: 0.7rem; border-top: 1px dashed var(--cv-border);
}
.cv-guion-form { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; margin: 0; }
.cv-guion-form input[type="text"] { min-width: 16rem; margin: 0; }
.cv-guion-form input[type="file"] { font-size: 0.82rem; max-width: 15rem; }

/* ── Oferta partida por tipo de formación ──
   El índice de arriba es la promesa de que el catálogo está ordenado: se ve de
   un vistazo qué áreas hay y cuántos cursos tiene cada una, antes de bajar. */
.cv-oferta-indice {
    display: flex; flex-wrap: wrap; gap: 0.5rem;
    margin: 0 0 1.6rem;
}
.cv-oferta-indice a {
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.42rem 0.85rem;
    border: 1px solid var(--cv-border); border-radius: 999px;
    background: var(--cv-surface);
    color: var(--cv-text); text-decoration: none;
    font-size: 0.87rem; font-weight: 600;
    transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.cv-oferta-indice a:hover { border-color: var(--cv-primary); color: var(--cv-primary); }
.cv-oferta-indice a span {
    font-weight: 500; font-size: 0.78rem; color: var(--cv-text-dim);
    background: var(--cv-surface-2); border-radius: 999px; padding: 0.05rem 0.45rem;
}
.cv-oferta-area { margin-bottom: 2.4rem; scroll-margin-top: 1.5rem; }
.cv-oferta-area-tit {
    font-size: 1.18rem; margin: 0 0 0.9rem;
    padding-bottom: 0.45rem; border-bottom: 2px solid var(--cv-border);
}

/* ===== LAB_BD: base de partida (lab_bd_semilla.js) ===== */
.cv-lab-bd-semilla {
    border: 1px solid var(--cv-border);
    border-left: 4px solid var(--cv-warning);
    border-radius: 12px;
    background: var(--cv-surface-2);
    padding: 0.9rem 1.1rem;
    margin: 0.8rem 0 1.2rem;
}
.cv-lab-bd-semilla p { font-size: 0.92rem; line-height: 1.6; margin: 0 0 0.7rem; }
.cv-lab-bd-semilla-btns { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.cv-lab-bd-semilla-estado { font-size: 0.82rem; color: var(--cv-text-dim); }

/* ===== Laboratorio tipo proyecto (actividad PROYECTO) ===== */
.cv-proy-enunciado {
    border: 1px solid var(--cv-border);
    border-left: 4px solid var(--cv-primary);
    border-radius: 12px;
    background: var(--cv-surface-2);
    padding: 0.9rem 1.1rem;
    margin: 1rem 0;
}
.cv-proy-enunciado p { margin: 0 0 0.7rem; line-height: 1.6; }
.cv-proy-enunciado ul { line-height: 1.6; }
.cv-proy-lista { line-height: 1.7; padding-left: 1.3rem; }
.cv-proy-taller { border-left: 4px solid var(--cv-accent); }
.cv-proy-taller p { font-size: 0.92rem; line-height: 1.6; }

/* ---- Anteproyecto en grupo: participación e historial de versiones ---- */
.cv-doc-grupo-paneles { display: grid; grid-template-columns: 1fr 1fr; gap: 0.9rem; margin-bottom: 1rem; }
@media (max-width: 800px) { .cv-doc-grupo-paneles { grid-template-columns: 1fr; } }
.cv-doc-plan-chip {
    display: inline-block; margin-left: 0.5rem; padding: 0.1rem 0.55rem; border-radius: 999px;
    background: var(--cv-surface); border: 1px solid var(--cv-border); font-size: 0.78rem; font-weight: 600;
}
.cv-doc-aviso-sync { font-size: 0.8rem; color: var(--cv-primary-dark); margin-top: 0.25rem; }
.cv-doc-part, .cv-doc-hist { background: var(--cv-surface-2); margin: 0; }
.cv-doc-part-cab { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; margin-bottom: 0.6rem; }
.cv-doc-part-ayuda { font-size: 0.75rem; color: var(--cv-text-dim); cursor: help; text-decoration: underline dotted; }
.cv-doc-part-fila {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "nombre pct" "barra barra" "det det";
    gap: 0.15rem 0.6rem; padding: 0.45rem 0; border-top: 1px solid var(--cv-border);
}
.cv-doc-part-fila:first-child { border-top: 0; }
.cv-doc-part-yo .cv-doc-part-nombre { color: var(--cv-primary-dark); }
.cv-doc-part-nombre { grid-area: nombre; font-weight: 600; font-size: 0.9rem; }
.cv-doc-part-nombre small { font-weight: 400; color: var(--cv-text-dim); }
.cv-doc-part-pct { grid-area: pct; font-weight: 700; font-size: 0.95rem; }
.cv-doc-part-barra { grid-area: barra; height: 8px; border-radius: 999px; background: var(--cv-border); overflow: hidden; }
.cv-doc-part-relleno { height: 100%; background: var(--cv-primary); border-radius: 999px; transition: width .4s; }
.cv-doc-part-det { grid-area: det; font-size: 0.76rem; color: var(--cv-text-dim); }
.cv-doc-part-vacio { margin: 0; font-size: 0.85rem; color: var(--cv-text-dim); }
.cv-doc-mas { color: var(--cv-success); font-weight: 600; }
.cv-doc-menos { color: var(--cv-danger, #c0392b); font-weight: 600; }
.cv-doc-hist summary { cursor: pointer; }
.cv-doc-hist-n { font-size: 0.8rem; color: var(--cv-text-dim); }
.cv-doc-hist-ayuda { font-size: 0.8rem; color: var(--cv-text-dim); margin: 0.4rem 0 0.5rem; }
.cv-doc-hist-lista { max-height: 260px; overflow-y: auto; }
.cv-doc-hist-fila {
    display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; flex-wrap: wrap;
    padding: 0.4rem 0; border-top: 1px solid var(--cv-border); font-size: 0.85rem;
}
.cv-doc-hist-num { font-family: ui-monospace, monospace; color: var(--cv-text-dim); }
.cv-doc-hist-fecha { color: var(--cv-text-dim); font-size: 0.78rem; }
.cv-doc-hist-rest { color: var(--cv-primary-dark); font-size: 0.78rem; }
.cv-doc-hist-acciones { display: flex; gap: 0.35rem; }
.cv-doc-hist-btn { padding: 0.2rem 0.55rem; font-size: 0.78rem; }
.cv-doc-diff { margin-top: 0.6rem; border: 1px solid var(--cv-border); border-radius: 10px; background: var(--cv-surface); padding: 0.7rem 0.9rem; }
.cv-doc-diff-cab { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; flex-wrap: wrap; font-size: 0.85rem; margin-bottom: 0.4rem; }
.cv-doc-diff-texto { font-size: 0.88rem; line-height: 1.55; white-space: pre-wrap; max-height: 320px; overflow-y: auto; }
.cv-doc-diff-texto del { background: #fde2e1; color: #8f1d1d; text-decoration: line-through; }
.cv-doc-diff-texto ins { background: #dcf5e3; color: #14532d; text-decoration: none; }

/* ---- Espacio de trabajo: panel «Mi MySQL» (Proyecto ISUM) ---- */
.cv-ws-mysql { margin-top: .7rem; border: 1px solid var(--cv-border); border-radius: 10px; background: var(--cv-surface-2); padding: .5rem .8rem; font-size: .88rem; }
.cv-ws-mysql summary { cursor: pointer; display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.cv-ws-mysql summary span { color: var(--cv-text-dim); flex: 1; }
.cv-ws-mysql-cuerpo { margin-top: .6rem; }
.cv-ws-mysql-tabla { border-collapse: collapse; margin: .5rem 0; }
.cv-ws-mysql-tabla th, .cv-ws-mysql-tabla td { text-align: left; padding: .25rem .6rem .25rem 0; vertical-align: top; }
.cv-ws-mysql-tabla th { color: var(--cv-text-dim); font-weight: 600; white-space: nowrap; }
.cv-ws-mysql-ver { padding: .1rem .5rem; font-size: .75rem; margin-left: .3rem; }

/* ---- Consola MySQL del espacio de trabajo (Proyecto ISUM) ---- */
.cv-ws-sql { margin-top: 1.2rem; }
.cv-ws-sql-atajos { display: flex; gap: .35rem; flex-wrap: wrap; margin-bottom: .4rem; }
.cv-ws-sql-atajos .cv-btn { padding: .2rem .6rem; font-size: .76rem; font-family: var(--cv-codigo-fuente, ui-monospace, Menlo, monospace); }
.cv-ws-sql-historial {
    max-height: 26rem; overflow: auto;
    background: #0f172a; color: #e2e8f0;
    border-radius: 10px 10px 0 0; padding: 0.7rem 0.8rem;
    font-family: var(--cv-codigo-fuente, ui-monospace, Menlo, monospace); font-size: 0.82rem;
}
.cv-ws-sql-entrada {
    display: flex; align-items: flex-start; gap: 0.5rem;
    background: #1e293b; border-radius: 0 0 10px 10px; padding: 0.5rem 0.6rem;
}
.cv-ws-sql-tabla-env { margin: .35rem 0 .2rem; overflow-x: auto; }
.cv-ws-sql-tabla { border-collapse: collapse; font-size: .78rem; background: #111c33; }
.cv-ws-sql-tabla th, .cv-ws-sql-tabla td { border: 1px solid #334155; padding: .2rem .55rem; text-align: left; white-space: pre; max-width: 28rem; overflow: hidden; text-overflow: ellipsis; }
.cv-ws-sql-tabla th { background: #1e293b; color: #7dd3fc; font-weight: 600; }
.cv-ws-sql-null { color: #64748b; font-style: italic; }
.cv-ws-sql-vacio { color: #64748b; text-align: center; }
.cv-ws-sql-pie { color: #64748b; font-size: .72rem; margin-top: .2rem; }

/* ---- Tablero: varios responsables por tarea ---- */
.cv-kb-resp { display: flex; flex-direction: column; gap: .25rem; padding: .35rem .5rem; border: 1.5px solid var(--cv-border); border-radius: 9px; background: var(--cv-surface); max-height: 9rem; overflow-y: auto; }
.cv-kb-resp-item { display: flex; align-items: center; gap: .4rem; font-weight: 400; font-size: .85rem; cursor: pointer; margin: 0; }
.cv-kb-resp-item input { width: auto; margin: 0; }
.cv-kb-chip-yo { background: var(--cv-primary); color: #fff; }

/* ---- Tablero: detalle plegable de cada tarjeta ---- */
.cv-kb-card-detalle { margin: 0.3rem 0 0; }
.cv-kb-card-detalle-tit { cursor: pointer; font-size: 0.78rem; font-weight: 600; color: var(--cv-primary); }
.cv-kb-card-detalle[open] .cv-kb-card-detalle-tit { margin-bottom: 0.2rem; }
.cv-kb-card-detalle .cv-kb-card-desc { line-height: 1.5; }

/* ---- Anteproyecto: choque de una sección entre dos integrantes ---- */
.cv-doc-choque { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; margin: 0 0 .6rem; font-size: .82rem; }
@media (max-width: 700px) { .cv-doc-choque { grid-template-columns: 1fr; } }
.cv-doc-choque pre { margin: .25rem 0 0; max-height: 9rem; overflow: auto; white-space: pre-wrap; word-break: break-word; font-size: .78rem; }

/* ---- Pruebas lanzadas por la institución ---- */
.cv-pruebas-pendientes { border: 2px solid var(--cv-primary); }
.cv-pruebas-pendiente { display: flex; justify-content: space-between; align-items: center; gap: .8rem; flex-wrap: wrap; padding: .55rem 0; border-top: 1px solid var(--cv-border); }
.cv-pruebas-pendiente:first-of-type { border-top: 0; }
.cv-pruebas-pendiente small { display: block; color: var(--cv-text-dim); font-size: .82rem; margin-top: .15rem; }
.cv-pruebas-sin-pendientes { color: var(--cv-text-dim); }

/* ---- Escuela: secciones del escritorio como tarjetas (Mi grado · Mis logros · Pruebas) ---- */
.cv-dash-tarjetas {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 1rem;
    margin: 0 0 1.6rem;
}
.cv-dash-tarjeta {
    border-left: 5px solid var(--area, var(--cv-primary));
    display: flex; flex-direction: column; gap: 0.5rem;
    text-decoration: none; color: var(--cv-text);
    transition: transform var(--cv-dur-base) var(--cv-ease-out), box-shadow var(--cv-dur-base) var(--cv-ease-out);
}
.cv-dash-tarjeta:hover { transform: translateY(-2px); box-shadow: 0 10px 24px rgba(15, 23, 42, .10); text-decoration: none; }
.cv-dash-tarjeta-cab { display: flex; align-items: center; justify-content: space-between; gap: .5rem; flex-wrap: wrap; }
.cv-dash-tarjeta-cab h3 { margin: 0; font-size: 1.05rem; display: flex; align-items: center; gap: .35rem; }
.cv-dash-tarjeta-icono { font-size: 1.15rem; }
.cv-dash-tarjeta p { font-size: .85rem; color: var(--cv-text-dim); margin: 0; flex: 1; }
.cv-dash-tarjeta .cv-btn { align-self: flex-start; }
.cv-dash-tarjeta--activa { box-shadow: 0 0 0 3px color-mix(in srgb, var(--area) 28%, transparent); }
.cv-dash-tarjeta--activa .cv-btn { background: var(--area); border-color: var(--area); }

/* ---- Iconos propios (GIF/PNG/SVG) en las secciones del estudiante ---- */
.cv-dash-tarjeta-icono img { width: 2rem; height: 2rem; object-fit: contain; vertical-align: middle; border-radius: 6px; }
.cv-dash-seccion-img { width: 1.35rem; height: 1.35rem; object-fit: contain; flex: none; }

/* ── editor del taller: panel de versiones ── */
.cv-editor-versiones{border:1px solid var(--cv-border);border-radius:8px;padding:.6rem .8rem;margin:.4rem 0;background:var(--cv-surface-2);max-height:40vh;overflow:auto;font-size:.85rem}
.cv-editor-versiones-cab{display:flex;justify-content:space-between;align-items:center;margin-bottom:.4rem}
.cv-editor-version{display:flex;gap:.5rem;align-items:center;flex-wrap:wrap;padding:.25rem 0;border-top:1px solid var(--cv-border)}
.cv-editor-version span{flex:1;min-width:12rem}
.cv-editor-version-texto{flex-basis:100%;white-space:pre-wrap;font-family:'Courier New',Consolas,monospace;font-size:.78rem;max-height:14rem;overflow:auto;margin:.3rem 0;padding:.4rem;background:var(--cv-surface);border-radius:6px}
.cv-editor-versiones-vacio{color:var(--cv-text-dim);margin:.3rem 0}
.cv-editor-papelera{margin-top:.5rem}

/* ── recomendaciones de la IA (panel docente) ── */
.cv-ia-texto{font-size:.92rem;line-height:1.55;padding:.6rem .9rem;border-left:3px solid var(--cv-primary);background:var(--cv-surface-2);border-radius:6px}
.cv-ia-texto h3,.cv-ia-texto h4{margin:.8rem 0 .3rem;font-size:1rem}
.cv-ia-texto ul,.cv-ia-texto ol{margin:.2rem 0 .6rem 1.2rem}

/* ── comentarios de la IA sobre el anteproyecto (estilo Google Docs) ── */
.cv-doc-ia{border-left:4px solid #7c3aed;background:linear-gradient(135deg,#f5f3ff,var(--cv-surface));margin-bottom:1rem}
.cv-doc-ia-cab{display:flex;justify-content:space-between;gap:.6rem;flex-wrap:wrap;align-items:baseline}
.cv-doc-ia-meta{font-size:.8rem;color:var(--cv-text-dim)}
.cv-doc-ia-ayuda{font-size:.85rem;color:var(--cv-text-dim);margin:.3rem 0 .5rem}
.cv-doc-ia-n{margin-left:auto;font-size:.72rem;font-weight:700;color:#6d28d9;background:#ede9fe;border-radius:999px;padding:.05rem .45rem;white-space:nowrap}
.cv-doc-ia-seccion{margin-top:.8rem;display:grid;gap:.5rem}
.cv-doc-ia-seccion-cab{font-size:.9rem}
.cv-ia-card{border:1px solid #ddd6fe;border-left:4px solid #8b5cf6;background:#fff;border-radius:10px;padding:.55rem .75rem;font-size:.86rem;line-height:1.45;box-shadow:0 1px 2px rgba(0,0,0,.05);cursor:pointer;transition:box-shadow .15s}
.cv-ia-card:hover{box-shadow:var(--cv-shadow-md)}
.cv-ia-card.cv-ia-activo{border-color:#7c3aed;box-shadow:0 0 0 3px #ddd6fe}
.cv-ia-card-cab{display:flex;justify-content:space-between;gap:.5rem;align-items:center;margin-bottom:.25rem}
.cv-ia-tipo{font-size:.68rem;font-weight:800;text-transform:uppercase;letter-spacing:.05em;color:#6d28d9;background:#ede9fe;border-radius:999px;padding:.05rem .5rem}
.cv-ia-card-apa .cv-ia-tipo{color:#b45309;background:#fef3c7}
.cv-ia-card-falta .cv-ia-tipo{color:#b91c1c;background:#fee2e2}
.cv-ia-card-coherencia .cv-ia-tipo{color:#0f766e;background:#ccfbf1}
.cv-ia-card-redaccion .cv-ia-tipo{color:#1d4ed8;background:#dbeafe}
.cv-ia-resuelto{font-size:.72rem;color:var(--cv-success);font-weight:700}
.cv-ia-card-resuelta{opacity:.7;border-left-color:var(--cv-success)}
.cv-ia-card-resuelta .cv-ia-comentario{text-decoration:line-through;text-decoration-color:rgba(0,0,0,.25)}
.cv-ia-cita{margin:.2rem 0 .35rem;padding:.15rem .5rem;border-left:3px solid #e9d5ff;color:var(--cv-text-dim);font-style:italic;font-size:.8rem}
.cv-ia-comentario{margin:0}
.cv-ia-card-acciones{display:flex;gap:.4rem;flex-wrap:wrap;margin-top:.35rem}
.cv-ia-btn{font:inherit;font-size:.74rem;font-weight:700;color:#6d28d9;background:#f5f3ff;border:1px solid #ddd6fe;border-radius:999px;padding:.12rem .6rem;cursor:pointer}
.cv-ia-btn:hover{background:#ede9fe}
.cv-ia-card-seccion{font-size:.72rem;font-weight:700;color:var(--cv-text-dim);margin-bottom:.2rem}
/* marcas en la vista APA */
.cv-apa-marca{background:#fde68a;border-bottom:2px solid #f59e0b;cursor:pointer;color:inherit;border-radius:2px}
.cv-apa-marca.cv-ia-activo{background:#fbbf24}
.cv-apa-marca-resuelta{background:#d1fae5;border-bottom-color:#10b981}
.cv-apa-ancla{font-size:.75em;margin-left:.3rem;background:#ede9fe;border-bottom:none;border-radius:999px;padding:0 .3rem;vertical-align:middle}
.cv-doc-preview{position:relative}
.cv-doc-preview-con-ia{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:1rem;align-items:start}
.cv-doc-apa-comentarios{position:relative;min-width:0}
.cv-ia-card-flotante{position:absolute;left:0;right:0}
.cv-doc-apa-comentarios-lista{display:grid;gap:.5rem;height:auto!important}
.cv-doc-apa-comentarios-lista .cv-ia-card{position:static}
@media (max-width:1099px){.cv-doc-preview-con-ia{grid-template-columns:1fr}}
@media print{body.cv-imprimiendo-doc .cv-apa-marca{background:none;border-bottom:none}body.cv-imprimiendo-doc .cv-apa-ancla{display:none}body.cv-imprimiendo-doc .cv-doc-apa-comentarios{display:none}}
