/* =====================================================================
   VEL - Sistema de diseno de ROBOTSchool
   Se carga despues de bootstrap.min.css.

   CONVENCIONES QUE NO SE PUEDEN ROMPER
   -----------------------------------
   1. Ningun color se escribe suelto en un componente: todo sale de un
      token semantico. Cambiar la marca debe ser cambiar esta seccion.
   2. No se usan atributos style="" en el HTML. La politica de seguridad
      de contenido los bloquea. Los valores dinamicos viajan en atributos
      data-* y assets/js/vel.js los aplica.
   3. Los dos temas (claro y oscuro) se definen juntos. Un color que solo
      existe dentro de un @media queda sin valor en el otro tema.
   4. Todo par de texto y fondo supera 4.5:1. Los bordes de controles
      superan 3:1 (WCAG 1.4.11). Verificado, no estimado.

   COLOR DE MARCA Y COLOR DE INTERFAZ SON COSAS DISTINTAS
   -----------------------------------------------------
   La marca es teal #219BAC y rojo #ED1F24. Ese rojo NO se usa como color
   de interfaz: en un sistema de UI el rojo esta reservado para error y
   para accion destructiva, y usar el mismo tono para "marca" y "peligro"
   entrena al usuario a ignorar las alertas. El rojo de marca vive solo
   dentro del logo. El teal, aclarado o profundizado segun haga falta para
   el contraste, es el color primario de la interfaz.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1. Tokens - tema claro (definicion completa, base de todo)
   --------------------------------------------------------------------- */
:root {
    /* Marca: valores oficiales. Solo para el logo y acentos de identidad. */
    --marca-teal: #219BAC;
    --marca-rojo: #ED1F24;

    /* Primario de interfaz: el teal de marca llevado a contraste usable.
       #219BAC sobre blanco da 3.31:1, insuficiente para texto. */
    --vel-primario: #12707E;          /* 5.76:1 sobre blanco */
    --vel-primario-fuerte: #0B4A54;   /* 9.90:1 sobre blanco */

    /* Fondo de la barra de navegacion. Token propio, no reutiliza
       --vel-primario-fuerte: ese token existe para escribir texto
       sobre superficies claras y por eso en el tema oscuro se
       aclara. La barra necesita lo contrario, un fondo oscuro en
       los dos temas. Compartirlos dejaba la barra en cian claro
       con letras blancas: 1.63:1, ilegible. */
    --vel-nav: #0B4A54;               /* 9.90:1 con blanco */
    --vel-primario-suave: #E4F2F4;    /* fondos de realce */
    --vel-primario-contraste: #FFFFFF;

    /* Semanticos: independientes de la marca. */
    --vel-peligro: #B3261E;
    --vel-peligro-suave: #FCEBE9;
    --vel-exito: #15704A;
    --vel-exito-suave: #E6F5EE;
    --vel-aviso: #8A5200;
    --vel-aviso-suave: #FBF0DF;
    --vel-info: #12707E;
    --vel-info-suave: #E4F2F4;

    /* Superficies y texto. Neutros con sesgo teal: un gris puro al lado
       de este primario se ve sucio. */
    --vel-fondo: #F2F6F7;
    --vel-superficie: #FFFFFF;
    --vel-superficie-2: #F7FAFB;      /* filas alternas, encabezados */
    --vel-tinta: #12232A;             /* 16.16:1 */
    --vel-apagado: #54686F;           /* 5.86:1  */
    --vel-borde: #DCE5E8;             /* separadores decorativos */
    --vel-borde-control: #748A91;     /* 3.63:1, bordes de campos */

    /* Escala de elevacion. Tres niveles, no uno por componente. */
    --vel-elev-0: none;
    --vel-elev-1: 0 1px 2px rgba(18, 35, 42, .06);
    --vel-elev-2: 0 1px 2px rgba(18, 35, 42, .06), 0 8px 20px rgba(18, 35, 42, .07);
    --vel-elev-3: 0 12px 32px rgba(18, 35, 42, .16);

    /* Radios: tres valores, por rol. */
    --vel-radio-sm: 8px;
    --vel-radio: 12px;
    --vel-radio-lg: 18px;

    /* Ritmo de espaciado de 4 px. */
    --vel-e1: .25rem; --vel-e2: .5rem;  --vel-e3: .75rem; --vel-e4: 1rem;
    --vel-e5: 1.5rem; --vel-e6: 2rem;   --vel-e7: 3rem;

    /* Movimiento. */
    --vel-mov-rapido: 140ms;
    --vel-mov: 220ms;
    --vel-mov-salida: 150ms;          /* la salida es mas corta que la entrada */
    --vel-curva: cubic-bezier(.2, .8, .3, 1);

    /* Capas. */
    --vel-z-barra: 1030;
    --vel-z-flotante: 1040;

    color-scheme: light;
}

/* ---------------------------------------------------------------------
   2. Tokens - tema oscuro
   Se redefinen SOLO los tokens. Ningun componente se estiliza aqui.
   Guardado con :not([data-theme="light"]) para que una eleccion explicita
   del usuario gane sobre la preferencia del sistema.
   --------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --vel-primario: #4FC3D2;          /* 8.06:1 sobre la superficie oscura */
        --vel-primario-fuerte: #7FD8E4;
        --vel-nav: #08343B;               /* 13.42:1 con blanco */
        --vel-primario-suave: #10333A;
        --vel-primario-contraste: #06232A;

        --vel-peligro: #F2857E;
        --vel-peligro-suave: #3A1714;
        --vel-exito: #5FD3A0;
        --vel-exito-suave: #0F2E22;
        --vel-aviso: #F0B357;
        --vel-aviso-suave: #33260F;
        --vel-info: #4FC3D2;
        --vel-info-suave: #10333A;

        --vel-fondo: #0C1417;
        --vel-superficie: #141F23;
        --vel-superficie-2: #1A272C;
        --vel-tinta: #E8F0F2;             /* 14.54:1 */
        --vel-apagado: #9BB0B7;           /* 7.43:1  */
        --vel-borde: #26363C;
        --vel-borde-control: #6F8A94;     /* 4.59:1  */

        --vel-elev-1: 0 1px 2px rgba(0, 0, 0, .45);
        --vel-elev-2: 0 1px 2px rgba(0, 0, 0, .45), 0 8px 20px rgba(0, 0, 0, .40);
        --vel-elev-3: 0 12px 32px rgba(0, 0, 0, .55);

        color-scheme: dark;
    }
}

:root[data-theme="dark"] {
    --vel-primario: #4FC3D2;
    --vel-primario-fuerte: #7FD8E4;
    --vel-nav: #08343B;
    --vel-primario-suave: #10333A;
    --vel-primario-contraste: #06232A;
    --vel-peligro: #F2857E;
    --vel-peligro-suave: #3A1714;
    --vel-exito: #5FD3A0;
    --vel-exito-suave: #0F2E22;
    --vel-aviso: #F0B357;
    --vel-aviso-suave: #33260F;
    --vel-info: #4FC3D2;
    --vel-info-suave: #10333A;
    --vel-fondo: #0C1417;
    --vel-superficie: #141F23;
    --vel-superficie-2: #1A272C;
    --vel-tinta: #E8F0F2;
    --vel-apagado: #9BB0B7;
    --vel-borde: #26363C;
    --vel-borde-control: #6F8A94;
    --vel-elev-1: 0 1px 2px rgba(0, 0, 0, .45);
    --vel-elev-2: 0 1px 2px rgba(0, 0, 0, .45), 0 8px 20px rgba(0, 0, 0, .40);
    --vel-elev-3: 0 12px 32px rgba(0, 0, 0, .55);
    color-scheme: dark;
}

/* ---------------------------------------------------------------------
   3. Base y tipografia

   Se usa la pila del sistema en vez de una fuente web a proposito: la
   plataforma se usa en colegios con conexion irregular, y una fuente
   remota que no carga deja el texto invisible o descolocado. La pila del
   sistema se ve bien, pesa cero y no depende de la red.
   Escala: 12 / 14 / 16 / 18 / 22 / 28 / 36.
   --------------------------------------------------------------------- */
:root {
    --vel-tipo: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
                "Helvetica Neue", Arial, "Noto Sans", sans-serif;
    --vel-mono: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas,
                "Liberation Mono", monospace;

    --vel-t-xs: .75rem;    /* 12 - solo etiquetas, nunca texto corrido */
    --vel-t-sm: .875rem;   /* 14 */
    --vel-t-base: 1rem;    /* 16 - minimo de texto corrido */
    --vel-t-lg: 1.125rem;  /* 18 */
    --vel-t-xl: 1.375rem;  /* 22 */
    --vel-t-2xl: 1.75rem;  /* 28 */
    --vel-t-3xl: 2.25rem;  /* 36 */
}

body {
    background: var(--vel-fondo);
    color: var(--vel-tinta);
    font-family: var(--vel-tipo);
    font-size: var(--vel-t-base);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
    color: var(--vel-tinta);
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -.011em;
    text-wrap: balance;
}
h1 { font-size: var(--vel-t-2xl); }
h2 { font-size: var(--vel-t-xl); }
h3 { font-size: var(--vel-t-lg); }
h4, h5, h6 { font-size: var(--vel-t-base); }

a { color: var(--vel-primario); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--vel-primario-fuerte); }

/* Cifras alineadas en columnas: sin esto las tablas de notas bailan. */
table, .vel-cifra, .vel-metrica .valor, .vel-progreso-texto { font-variant-numeric: tabular-nums; }

hr { border-color: var(--vel-borde); opacity: 1; }

/* Foco visible SIEMPRE. Quitar el anillo de foco deja la plataforma
   inutilizable con teclado, que es como la usa quien no puede usar raton. */
:focus-visible {
    outline: 3px solid var(--vel-primario);
    outline-offset: 2px;
    border-radius: var(--vel-radio-sm);
}
.vel-nav :focus-visible { outline-color: #FFFFFF; }

/* Enlace de salto: invisible hasta que se navega con teclado. */
.vel-salto {
    position: absolute;
    left: var(--vel-e4);
    top: -100px;
    z-index: var(--vel-z-flotante);
    background: var(--vel-superficie);
    color: var(--vel-primario);
    padding: var(--vel-e3) var(--vel-e4);
    border-radius: var(--vel-radio-sm);
    box-shadow: var(--vel-elev-3);
    font-weight: 600;
    transition: top var(--vel-mov-rapido) var(--vel-curva);
}
.vel-salto:focus { top: var(--vel-e4); }

/* ---------------------------------------------------------------------
   4. Barra de navegacion
   --------------------------------------------------------------------- */
.vel-nav {
    background: var(--vel-nav);
    box-shadow: var(--vel-elev-1);
    padding-block: var(--vel-e2);
}
/* La marca en la barra es el buho mas el nombre en texto, no el logotipo
   completo. El logotipo de ROBOTSchool es apilado (buho arriba, palabra
   abajo, proporcion 1.28:1): metido en una barra de 34 px dejaria la
   palabra en 10 px de alto, que es ilegible. El logotipo completo se usa
   donde hay espacio vertical: portada, acceso y certificado. */
.vel-nav .navbar-brand { display: flex; align-items: center; gap: var(--vel-e3); padding-block: var(--vel-e1); }
.vel-logo { height: 34px; width: auto; display: block; }
.vel-logo-buho { height: 30px; width: auto; display: block; }
.vel-marca-texto {
    font-size: var(--vel-t-xl);
    font-weight: 700;
    letter-spacing: .02em;
    line-height: 1;
    color: #FFFFFF;
}
.vel-marca-org {
    font-size: var(--vel-t-base);
    font-weight: 400;
    line-height: 1;
    color: rgba(255, 255, 255, .82);
    /* Separador en lugar de un punto suelto: no depende de una fuente de
       iconos y se lee igual en cualquier tema. */
    padding-left: var(--vel-e3);
    border-left: 1px solid rgba(255, 255, 255, .32);
}

.vel-nav .nav-link {
    color: rgba(255, 255, 255, .85);
    font-weight: 500;
    padding: var(--vel-e2) var(--vel-e3);
    border-radius: var(--vel-radio-sm);
    /* Area tactil de 44 px sin agrandar la caja visual. */
    min-height: 44px;
    display: flex;
    align-items: center;
    transition: background var(--vel-mov-rapido) var(--vel-curva),
                color var(--vel-mov-rapido) var(--vel-curva);
}
.vel-nav .nav-link:hover { color: #FFFFFF; background: rgba(255, 255, 255, .10); }

/* La pagina actual se marca con color Y con una barra: el color solo no
   basta para quien no distingue tonos. El atributo aria-current lo dice
   ademas al lector de pantalla. */
.vel-nav .nav-link.activo,
.vel-nav .nav-link[aria-current="page"] {
    color: #FFFFFF;
    background: rgba(255, 255, 255, .14);
    position: relative;
}
.vel-nav .nav-link.activo::after,
.vel-nav .nav-link[aria-current="page"]::after {
    content: "";
    position: absolute;
    left: var(--vel-e3); right: var(--vel-e3); bottom: 2px;
    height: 2px;
    background: var(--marca-teal);
    border-radius: 2px;
}
.vel-nav .navbar-toggler { border-color: rgba(255, 255, 255, .3); min-width: 44px; min-height: 44px; }

/* Selector de tema. Vive en la barra, se pinta con el boton nativo para
   que el teclado y el lector de pantalla lo traten como lo que es. El
   estado real lo lleva aria-pressed, no el color. */
.vel-tema {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--vel-e2);
    min-width: 44px;
    min-height: 44px;
    padding: var(--vel-e2) var(--vel-e3);
    background: transparent;
    border: 1px solid rgba(255, 255, 255, .3);
    border-radius: var(--vel-radio-sm);
    color: rgba(255, 255, 255, .9);
    font-size: var(--vel-t-sm);
    font-weight: 500;
    cursor: pointer;
    transition: background var(--vel-mov-rapido) var(--vel-curva),
                border-color var(--vel-mov-rapido) var(--vel-curva);
}
.vel-tema:hover { background: rgba(255, 255, 255, .12); border-color: rgba(255, 255, 255, .55); color: #FFFFFF; }
.vel-tema svg { width: 18px; height: 18px; flex: 0 0 auto; }

/* El control anuncia el tema al que se va a cambiar, no el actual. Las dos
   variantes se escriben en el HTML y decide el CSS: asi el boton dice la
   verdad tambien antes de que corra el JavaScript. Mismo patron de los
   tokens: claro en :root, oscuro en la consulta y en [data-theme]. */
.vel-tema .vel-si-oscuro { display: none; }
.vel-tema .vel-si-claro  { display: inline; }
.vel-tema svg.vel-si-claro { display: block; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .vel-tema .vel-si-claro,
    :root:not([data-theme="light"]) .vel-tema svg.vel-si-claro { display: none; }
    :root:not([data-theme="light"]) .vel-tema .vel-si-oscuro { display: inline; }
    :root:not([data-theme="light"]) .vel-tema svg.vel-si-oscuro { display: block; }
}
:root[data-theme="dark"] .vel-tema .vel-si-claro,
:root[data-theme="dark"] .vel-tema svg.vel-si-claro { display: none; }
:root[data-theme="dark"] .vel-tema .vel-si-oscuro { display: inline; }
:root[data-theme="dark"] .vel-tema svg.vel-si-oscuro { display: block; }

/* ---------------------------------------------------------------------
   5. Superficies

   No todo es una tarjeta. El borde, el relleno, el radio y la sombra
   dicen "objeto separado"; gastarlos en cada bloque aplana la jerarquia.
   --------------------------------------------------------------------- */
.vel-tarjeta {
    background: var(--vel-superficie);
    border: 1px solid var(--vel-borde);
    border-radius: var(--vel-radio);
    box-shadow: var(--vel-elev-1);
}
/* Columna lateral que acompana al lector en lecciones largas. Solo desde
   lg: pegar algo en una pantalla de movil roba alto util. */
@media (min-width: 992px) {
    .vel-lateral { position: sticky; top: var(--vel-e4); }
}

.vel-tarjeta-plana { background: var(--vel-superficie); border: 1px solid var(--vel-borde); border-radius: var(--vel-radio); box-shadow: var(--vel-elev-0); }

.vel-tarjeta-curso {
    overflow: hidden;
    height: 100%;
    transition: transform var(--vel-mov) var(--vel-curva),
                box-shadow var(--vel-mov) var(--vel-curva);
}
.vel-tarjeta-curso:hover,
.vel-tarjeta-curso:focus-within { transform: translateY(-2px); box-shadow: var(--vel-elev-2); }

.vel-cinta { height: 5px; background: var(--vel-primario); }

.vel-emblema {
    width: 48px; height: 48px;
    border-radius: var(--vel-radio-sm);
    display: flex; align-items: center; justify-content: center;
    font-size: var(--vel-t-lg); font-weight: 800;
    color: #FFFFFF;                   /* solo respaldo: ver abajo */
    background: var(--vel-primario);
    flex: 0 0 auto;
    /* El color del emblema lo pone el curso y puede ser cualquiera, asi
       que la tinta no se decide aqui: el servidor calcula blanco o negro
       contra ese color (helpers.php, tintaSobre) y vel.js lo aplica. Antes
       habia una sombra de texto para "despegar" el blanco del fondo; era
       un parche que dejaba emblemas medidos en 3.08:1. */
}

/* ---------------------------------------------------------------------
   6. Metricas
   --------------------------------------------------------------------- */
.vel-metrica {
    background: var(--vel-superficie);
    border: 1px solid var(--vel-borde);
    border-radius: var(--vel-radio);
    padding: var(--vel-e4);
    display: flex; flex-direction: column; gap: var(--vel-e1);
}
.vel-metrica .valor {
    font-size: var(--vel-t-2xl); font-weight: 800; line-height: 1.1;
    color: var(--vel-tinta);   /* explicito: dentro de la portada hereda blanco */
}
.vel-metrica .etiqueta {
    color: var(--vel-apagado);
    font-size: var(--vel-t-xs);
    text-transform: uppercase;
    letter-spacing: .06em;
    font-weight: 600;
}

/* ---------------------------------------------------------------------
   7. Progreso
   El porcentaje va SIEMPRE escrito al lado: una barra sin cifra obliga a
   estimar, y en un tema oscuro o con daltonismo puede no leerse.
   --------------------------------------------------------------------- */
.vel-progreso {
    height: 8px;
    background: var(--vel-borde);
    border-radius: 99px;
    overflow: hidden;
}
.vel-progreso > span {
    display: block; height: 100%; width: 0;
    border-radius: 99px;
    background: var(--vel-primario);
    transition: width var(--vel-mov) var(--vel-curva);
}
.vel-progreso.alto > span { background: var(--vel-exito); }
.vel-progreso-texto { font-size: var(--vel-t-sm); font-weight: 600; color: var(--vel-apagado); }

/* ---------------------------------------------------------------------
   8. Habilidades
   --------------------------------------------------------------------- */
.vel-habilidad {
    border: 1px solid var(--vel-borde);
    border-radius: var(--vel-radio-sm);
    padding: var(--vel-e3) var(--vel-e4);
    background: var(--vel-superficie);
    display: flex; flex-direction: column; gap: var(--vel-e2);
}
.vel-habilidad .nombre { font-weight: 600; font-size: var(--vel-t-sm); color: var(--vel-tinta); }

.vel-nivel { display: inline-flex; gap: 3px; }
.vel-nivel i { width: 18px; height: 6px; border-radius: 3px; background: var(--vel-borde); display: block; }
.vel-nivel i.on { background: var(--vel-primario); }

.vel-etiqueta-hab {
    display: inline-block;
    font-size: var(--vel-t-xs); font-weight: 600;
    padding: var(--vel-e1) var(--vel-e2);
    border-radius: 99px;
    background: var(--vel-primario-suave);
    color: var(--vel-primario);
    border: 1px solid var(--vel-borde);
}

/* ---------------------------------------------------------------------
   9. Insignias
   --------------------------------------------------------------------- */
.vel-insignia {
    text-align: center;
    padding: var(--vel-e4) var(--vel-e2);
    border-radius: var(--vel-radio);
    border: 1px dashed var(--vel-borde-control);
    background: var(--vel-superficie);
    display: flex; flex-direction: column; gap: var(--vel-e2);
    align-items: center;
}
/* Obtenida frente a pendiente: cambia el borde, el fondo y el icono, no
   solo el color. */
.vel-insignia.obtenida { border-style: solid; border-color: var(--vel-primario); background: var(--vel-primario-suave); }
.vel-insignia .icono {
    width: 44px; height: 44px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--vel-borde); color: var(--vel-apagado);
    font-size: var(--vel-t-lg); font-weight: 800;
}
.vel-insignia.obtenida .icono { background: var(--vel-primario); color: var(--vel-primario-contraste); }

/* ---------------------------------------------------------------------
   10. Contenido de leccion
   Medida de linea controlada: 65-75 caracteres. Un parrafo que cruza
   1200 px obliga al ojo a saltar de renglon y se pierde la lectura.
   --------------------------------------------------------------------- */
.vel-contenido { font-size: var(--vel-t-lg); line-height: 1.7; color: var(--vel-tinta); max-width: 68ch; }
.vel-contenido > * + * { margin-top: var(--vel-e4); }
.vel-contenido h2 { font-size: var(--vel-t-xl); margin-top: var(--vel-e6); }
.vel-contenido h3 { font-size: var(--vel-t-lg); margin-top: var(--vel-e5); }
.vel-contenido ul, .vel-contenido ol { padding-left: var(--vel-e5); }
.vel-contenido li + li { margin-top: var(--vel-e2); }
.vel-contenido strong { font-weight: 700; }
.vel-contenido code {
    font-family: var(--vel-mono); font-size: .9em;
    background: var(--vel-superficie-2);
    border: 1px solid var(--vel-borde);
    border-radius: 5px; padding: .1em .35em;
    color: var(--vel-tinta);
}
.vel-contenido blockquote {
    border-left: 4px solid var(--vel-primario);
    padding: var(--vel-e3) var(--vel-e4);
    background: var(--vel-primario-suave);
    border-radius: 0 var(--vel-radio-sm) var(--vel-radio-sm) 0;
    margin-inline: 0;
}
/* Las tablas anchas se desplazan dentro de su caja, nunca empujan la pagina. */
.vel-contenido table { width: 100%; border-collapse: collapse; display: block; overflow-x: auto; }
.vel-contenido th, .vel-contenido td { border: 1px solid var(--vel-borde); padding: var(--vel-e2) var(--vel-e3); text-align: left; }
.vel-contenido th { background: var(--vel-superficie-2); font-weight: 600; }

/* ---------------------------------------------------------------------
   11. Codigo
   Fondo propio, constante en los dos temas: el resaltado de sintaxis
   pierde sentido si el fondo cambia de claro a oscuro.
   --------------------------------------------------------------------- */
.vel-codigo-cab {
    background: #16262D; color: #A8C0C7;
    border-radius: var(--vel-radio-sm) var(--vel-radio-sm) 0 0;
    padding: var(--vel-e2) var(--vel-e4);
    font-size: var(--vel-t-xs); letter-spacing: .06em; text-transform: uppercase;
    display: flex; justify-content: space-between; align-items: center; gap: var(--vel-e3);
    font-weight: 600;
}
.vel-codigo {
    background: #0F1C22; color: #E6EDF3;
    border-radius: 0 0 var(--vel-radio-sm) var(--vel-radio-sm);
    padding: var(--vel-e4);
    font-size: var(--vel-t-sm); line-height: 1.65;
    overflow-x: auto; white-space: pre;
    font-family: var(--vel-mono);
    margin: 0;
    tab-size: 2;
}
.vel-codigo-cab .btn-link { color: #A8C0C7; min-height: 44px; }
.vel-codigo-cab .btn-link:hover { color: #FFFFFF; }

/* Errores comunes: es un aviso, no un error del sistema. Va en el tono
   de aviso, no en el de peligro. */
.vel-errores {
    border-left: 4px solid var(--vel-aviso);
    background: var(--vel-aviso-suave);
    border-radius: 0 var(--vel-radio-sm) var(--vel-radio-sm) 0;
    padding: var(--vel-e4);
    color: var(--vel-tinta);
}

/* ---------------------------------------------------------------------
   12. Evaluaciones
   --------------------------------------------------------------------- */
.vel-pregunta {
    border: 1px solid var(--vel-borde);
    border-radius: var(--vel-radio);
    background: var(--vel-superficie);
    padding: var(--vel-e5);
    margin-bottom: var(--vel-e4);
}
.vel-opcion {
    display: flex; align-items: flex-start; gap: var(--vel-e3);
    border: 1px solid var(--vel-borde-control);
    border-radius: var(--vel-radio-sm);
    padding: var(--vel-e3) var(--vel-e4);
    margin-bottom: var(--vel-e2);
    cursor: pointer;
    min-height: 48px;                 /* area tactil comoda */
    background: var(--vel-superficie);
    transition: background var(--vel-mov-rapido) var(--vel-curva),
                border-color var(--vel-mov-rapido) var(--vel-curva);
}
.vel-opcion:hover { background: var(--vel-superficie-2); border-color: var(--vel-primario); }
.vel-opcion:focus-within { outline: 3px solid var(--vel-primario); outline-offset: 2px; }
.vel-opcion input { margin-top: .3em; flex: 0 0 auto; width: 20px; height: 20px; accent-color: var(--vel-primario); }

/* En la revision, el estado no se codifica solo con color: la vista
   antepone un simbolo de acierto o error a cada opcion. */
.vel-opcion.correcta { border-color: var(--vel-exito); background: var(--vel-exito-suave); }
.vel-opcion.incorrecta { border-color: var(--vel-peligro); background: var(--vel-peligro-suave); }
.vel-marca-opcion {
    flex: 0 0 auto;
    width: 1.5em;
    font-weight: 700;
    line-height: 1.4;
    color: var(--vel-apagado);
}
.vel-opcion-cuerpo { flex: 1 1 auto; min-width: 0; }
.vel-opcion.correcta .vel-marca-opcion { color: var(--vel-exito); }
.vel-opcion.incorrecta .vel-marca-opcion { color: var(--vel-peligro); }
.vel-explicacion { font-size: var(--vel-t-sm); color: var(--vel-apagado); margin-top: var(--vel-e2); }

/* ---------------------------------------------------------------------
   13. Portada
   --------------------------------------------------------------------- */
.vel-portada {
    background:
        radial-gradient(1200px 400px at 15% -10%, rgba(33, 155, 172, .35), transparent 60%),
        linear-gradient(160deg, var(--vel-nav) 0%, #072F37 100%);
    color: #FFFFFF;
    border-radius: 0 0 var(--vel-radio-lg) var(--vel-radio-lg);
}
.vel-portada h1 { color: #FFFFFF; font-size: clamp(1.75rem, 3.2vw, var(--vel-t-3xl)); }
.vel-portada .lead { color: rgba(255, 255, 255, .88); font-size: var(--vel-t-lg); max-width: 56ch; }
.vel-portada .vel-chip { background: rgba(255, 255, 255, .16); color: #FFFFFF; border-color: rgba(255, 255, 255, .28); }
.vel-logo-portada { height: 76px; width: auto; }

/* ---------------------------------------------------------------------
   14. Certificado
   --------------------------------------------------------------------- */
.vel-certificado {
    background: #FFFFFF;
    color: #12232A;
    border: 2px solid var(--marca-teal);
    border-radius: var(--vel-radio);
    padding: var(--vel-e7) clamp(var(--vel-e5), 6vw, 4rem);
    max-width: 920px;
    margin: var(--vel-e6) auto;
    text-align: center;
    box-shadow: var(--vel-elev-2);
    position: relative;
}
.vel-certificado::before {
    content: "";
    position: absolute; inset: 10px;
    border: 1px solid var(--vel-borde);
    border-radius: var(--vel-radio-sm);
    pointer-events: none;
}
.vel-certificado .vel-logo-cert { height: 84px; width: auto; margin-bottom: var(--vel-e4); }
.vel-certificado .nombre {
    font-size: clamp(1.5rem, 4vw, 2.1rem); font-weight: 800;
    color: #0B4A54;
    border-bottom: 2px solid var(--vel-borde);
    display: inline-block; padding: 0 var(--vel-e6) var(--vel-e2);
    margin: var(--vel-e3) 0 var(--vel-e4);
}
.vel-certificado .sello {
    width: 92px; height: 92px; border-radius: 50%;
    border: 3px solid var(--marca-teal);
    display: flex; align-items: center; justify-content: center;
    margin: var(--vel-e5) auto 0;
    font-weight: 800; color: #0B4A54;
    letter-spacing: .04em;
}
/* El certificado se imprime: mantiene fondo blanco y tinta oscura en los
   dos temas, por eso los colores van escritos y no salen de un token. */
.vel-certificado .vel-mini { color: #546870; }

/* ---------------------------------------------------------------------
   15. Utilidades
   --------------------------------------------------------------------- */
.vel-mini { font-size: var(--vel-t-sm); color: var(--vel-apagado); }

.vel-chip {
    display: inline-flex; align-items: center; gap: var(--vel-e1);
    font-size: var(--vel-t-xs); font-weight: 600;
    padding: var(--vel-e1) var(--vel-e2);
    border-radius: 99px;
    background: var(--vel-primario-suave);
    color: var(--vel-primario);
    border: 1px solid var(--vel-borde);
    white-space: nowrap;
}
.vel-chip.verde   { background: var(--vel-exito-suave);   color: var(--vel-exito); }
.vel-chip.naranja { background: var(--vel-aviso-suave);   color: var(--vel-aviso); }
.vel-chip.roja    { background: var(--vel-peligro-suave); color: var(--vel-peligro); }

.vel-tabla-limpia { color: var(--vel-tinta); }
.vel-tabla-limpia th {
    font-size: var(--vel-t-xs); text-transform: uppercase; letter-spacing: .05em;
    color: var(--vel-apagado); font-weight: 700;
    border-bottom-color: var(--vel-borde);
}
.vel-tabla-limpia td { border-bottom-color: var(--vel-borde); }
.vel-tabla-limpia tbody tr:hover { background: var(--vel-superficie-2); }

.vel-vacio {
    text-align: center; padding: var(--vel-e7) var(--vel-e4);
    color: var(--vel-apagado);
    display: flex; flex-direction: column; align-items: center; gap: var(--vel-e3);
}

/* Indice lateral de leccion */
.vel-indice { position: sticky; top: var(--vel-e4); max-height: calc(100vh - 2rem); overflow-y: auto; }
.vel-indice .modulo {
    font-size: var(--vel-t-xs); text-transform: uppercase; letter-spacing: .06em;
    color: var(--vel-apagado); font-weight: 700;
    margin: var(--vel-e4) 0 var(--vel-e1);
}
.vel-indice a {
    display: block; padding: var(--vel-e2) var(--vel-e3);
    border-radius: var(--vel-radio-sm);
    color: var(--vel-tinta); text-decoration: none;
    font-size: var(--vel-t-sm);
    border-left: 3px solid transparent;
    min-height: 44px;
}
.vel-indice a:hover { background: var(--vel-superficie-2); }
.vel-indice a.activa { background: var(--vel-primario-suave); border-left-color: var(--vel-primario); font-weight: 600; }

/* ---------------------------------------------------------------------
   16. Ajustes sobre Bootstrap
   Bootstrap trae su propio azul y sus propios grises. Se reencaminan a
   los tokens para que no convivan dos paletas.
   --------------------------------------------------------------------- */
.btn { min-height: 44px; border-radius: var(--vel-radio-sm); font-weight: 600; }
.btn-sm { min-height: 38px; font-size: var(--vel-t-sm); }
.btn-lg { min-height: 52px; }

.btn-primary {
    background: var(--vel-primario); border-color: var(--vel-primario);
    color: var(--vel-primario-contraste);
}
.btn-primary:hover, .btn-primary:focus {
    background: var(--vel-primario-fuerte); border-color: var(--vel-primario-fuerte);
    color: var(--vel-primario-contraste);
}
.btn-outline-primary { color: var(--vel-primario); border-color: var(--vel-primario); }
.btn-outline-primary:hover, .btn-outline-primary:focus {
    background: var(--vel-primario); border-color: var(--vel-primario);
    color: var(--vel-primario-contraste);
}
.btn-success { background: var(--vel-exito); border-color: var(--vel-exito); color: #FFFFFF; }
.btn-success:hover { background: var(--vel-exito); border-color: var(--vel-exito); filter: brightness(.9); color: #FFFFFF; }
.btn-danger, .btn-outline-danger:hover { background: var(--vel-peligro); border-color: var(--vel-peligro); color: #FFFFFF; }
.btn-outline-danger { color: var(--vel-peligro); border-color: var(--vel-peligro); }
.btn-outline-secondary { color: var(--vel-tinta); border-color: var(--vel-borde-control); }
.btn-outline-secondary:hover { background: var(--vel-superficie-2); color: var(--vel-tinta); border-color: var(--vel-borde-control); }
.btn-warning { background: var(--vel-aviso); border-color: var(--vel-aviso); color: #FFFFFF; }
.btn-warning:hover { background: var(--vel-aviso); border-color: var(--vel-aviso); filter: brightness(.9); color: #FFFFFF; }

/* El amarillo de Bootstrap (#ffc107) sobre blanco da 1.63:1: es un color
   pensado para fondos, no para letra. Las variantes de contorno se llevan
   al tono semantico, que si esta calculado para texto. */
.btn-outline-warning { color: var(--vel-aviso); border-color: var(--vel-aviso); }
.btn-outline-warning:hover, .btn-outline-warning:focus {
    background: var(--vel-aviso); border-color: var(--vel-aviso); color: #FFFFFF;
}
.btn-outline-success { color: var(--vel-exito); border-color: var(--vel-exito); }
.btn-outline-success:hover, .btn-outline-success:focus {
    background: var(--vel-exito); border-color: var(--vel-exito); color: #FFFFFF;
}
.btn-link { color: var(--vel-primario); }

/* Llamada a la accion sobre fondo oscuro (barra y portada). Antes era
   btn-warning, es decir el amarillo de aviso: usar el color de "cuidado"
   para invitar a crear una cuenta ensena a ignorarlo. Aqui la accion
   principal se destaca invirtiendo, no cambiando de significado. */
.btn-vel-marca {
    /* Fondo y tinta escritos, no tomados de tokens: este boton solo
       aparece sobre la barra y la portada, que son oscuras en los dos
       temas. Si tomara --vel-primario-fuerte, en tema oscuro quedaria
       cian claro sobre blanco (1.9:1). */
    background: #FFFFFF;
    border: 1px solid #FFFFFF;
    color: #0B4A54;                   /* 9.90:1 sobre blanco */
}
.btn-vel-marca:hover,
.btn-vel-marca:focus { background: #E4F2F4; border-color: #E4F2F4; color: #0B4A54; }
.vel-nav .btn-vel-marca:focus-visible,
.vel-portada .btn-vel-marca:focus-visible { outline: 3px solid #FFFFFF; outline-offset: 3px; }

/* Estado deshabilitado: se ve deshabilitado y el cursor lo confirma. */
.btn:disabled, .btn.disabled { opacity: .45; cursor: not-allowed; }

.form-control, .form-select {
    min-height: 44px;
    border-color: var(--vel-borde-control);
    background: var(--vel-superficie);
    color: var(--vel-tinta);
    border-radius: var(--vel-radio-sm);
    font-size: var(--vel-t-base);     /* 16 px evita el zoom automatico de iOS */
}
.form-control:focus, .form-select:focus {
    border-color: var(--vel-primario);
    box-shadow: 0 0 0 3px var(--vel-primario-suave);
    background: var(--vel-superficie);
    color: var(--vel-tinta);
}
.form-control::placeholder { color: var(--vel-apagado); opacity: 1; }
.form-control:disabled, .form-control[readonly] { background: var(--vel-superficie-2); color: var(--vel-apagado); }
.form-label { font-weight: 600; font-size: var(--vel-t-sm); color: var(--vel-tinta); margin-bottom: var(--vel-e1); }
.form-text { color: var(--vel-apagado); font-size: var(--vel-t-sm); }
/* Los controles pequenos recuperan su tamano de letra: heredar los 16 px
   de .form-control dejaba los <select> de rol y estado cortados
   ("estudi..."), sin forma de leer el valor puesto. Solo se usan en las
   tablas densas de administracion, que son de escritorio; el minimo de
   16 px que evita el zoom de iOS sigue vigente en todo lo demas. */
.form-select-sm, .form-control-sm { min-height: 38px; font-size: var(--vel-t-sm); }
/* Ancho suficiente para el valor mas largo ("coordinador"). */
.table .form-select-sm { min-width: 11ch; }

.alert { border-radius: var(--vel-radio-sm); border-width: 1px; }
.alert-success { background: var(--vel-exito-suave);   border-color: var(--vel-exito);   color: var(--vel-tinta); }
.alert-danger  { background: var(--vel-peligro-suave); border-color: var(--vel-peligro); color: var(--vel-tinta); }
.alert-warning { background: var(--vel-aviso-suave);   border-color: var(--vel-aviso);   color: var(--vel-tinta); }
.alert-info    { background: var(--vel-info-suave);    border-color: var(--vel-info);    color: var(--vel-tinta); }

.dropdown-menu {
    background: var(--vel-superficie);
    border-color: var(--vel-borde);
    border-radius: var(--vel-radio);
    box-shadow: var(--vel-elev-3);
}
.dropdown-item { color: var(--vel-tinta); min-height: 44px; display: flex; align-items: center; }
.dropdown-item:hover, .dropdown-item:focus { background: var(--vel-superficie-2); color: var(--vel-tinta); }
.dropdown-divider { border-color: var(--vel-borde); }

.accordion-item { background: var(--vel-superficie); border-color: var(--vel-borde); }
.accordion-button { background: var(--vel-superficie); color: var(--vel-tinta); min-height: 52px; }
.accordion-button:not(.collapsed) { background: var(--vel-primario-suave); color: var(--vel-primario); box-shadow: none; }
.accordion-button:focus { box-shadow: 0 0 0 3px var(--vel-primario-suave); border-color: var(--vel-primario); }

.list-group-item { background: var(--vel-superficie); color: var(--vel-tinta); border-color: var(--vel-borde); }
.list-group-item-action:hover, .list-group-item-action:focus { background: var(--vel-superficie-2); color: var(--vel-tinta); }

.breadcrumb { margin-bottom: 0; }
.breadcrumb-item, .breadcrumb-item a { color: var(--vel-apagado); }
.breadcrumb-item.active { color: var(--vel-tinta); }
.breadcrumb-item + .breadcrumb-item::before { color: var(--vel-apagado); }

.page-link { color: var(--vel-primario); background: var(--vel-superficie); border-color: var(--vel-borde); min-width: 44px; min-height: 44px; display: flex; align-items: center; justify-content: center; }
.page-item.active .page-link { background: var(--vel-primario); border-color: var(--vel-primario); color: var(--vel-primario-contraste); }

/* Las tablas de Bootstrap pintan cada celda con sus propias variables y
   con un selector mas especifico que .table, de modo que no basta con
   fijar el color aqui: hay que reencaminar las variables. */
.table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--vel-tinta);
    --bs-table-striped-color: var(--vel-tinta);
    --bs-table-striped-bg: var(--vel-superficie-2);
    --bs-table-hover-color: var(--vel-tinta);
    --bs-table-hover-bg: var(--vel-superficie-2);
    --bs-table-border-color: var(--vel-borde);
    color: var(--vel-tinta);
}
.card { background: var(--vel-superficie); border-color: var(--vel-borde); }
.text-muted { color: var(--vel-apagado) !important; }

/* El rosa de Bootstrap para <code> (#d63384) da 4.14:1 sobre blanco, por
   debajo del minimo. Se usa en toda la administracion para los codigos de
   pedido, que es justo texto que hay que leer y dictar por telefono. */
code { color: var(--vel-primario-fuerte); word-wrap: break-word; }

/* Columna de estado en la tabla de requisitos del instalador. */
.vel-col-estado { width: 44px; }
:not(pre) > code {
    background: var(--vel-superficie-2);
    border: 1px solid var(--vel-borde);
    border-radius: 5px;
    padding: .1em .35em;
}
.border-top, .border-bottom { border-color: var(--vel-borde) !important; }

/* ---------------------------------------------------------------------
   17. Landing publica

   La landing tiene que atraer a dos publicos con lenguajes distintos:
   docentes que deciden una compra institucional y ninos que quieren
   construir algo. La solucion no es un termino medio, que no le habla a
   ninguno de los dos: es una promesa comun arriba y DOS caminos
   declarados justo debajo, cada uno con su tono.
   --------------------------------------------------------------------- */
.vel-heroe {
    position: relative;
    overflow: hidden;
    color: #FFFFFF;
    background:
        radial-gradient(1100px 520px at 78% -12%, rgba(33, 155, 172, .55) 0%, rgba(33, 155, 172, 0) 62%),
        radial-gradient(720px 420px at 8% 108%, rgba(237, 31, 36, .22) 0%, rgba(237, 31, 36, 0) 60%),
        linear-gradient(158deg, var(--vel-nav) 0%, #062429 100%);
    padding-block: clamp(var(--vel-e6), 8vw, 5.5rem);
}
/* Trama de circuito. Va como fondo SVG en linea y no como imagen aparte:
   una peticion menos en conexiones de colegio, y escala sin pixelarse. */
.vel-heroe::before {
    content: "";
    position: absolute;
    inset: 0;
    opacity: .16;
    pointer-events: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='72' height='72' viewBox='0 0 72 72'%3E%3Cg fill='none' stroke='%23ffffff' stroke-width='1'%3E%3Cpath d='M0 36h20M52 36h20M36 0v20M36 52v20'/%3E%3Ccircle cx='36' cy='36' r='6'/%3E%3Ccircle cx='0' cy='36' r='2'/%3E%3Ccircle cx='72' cy='36' r='2'/%3E%3Ccircle cx='36' cy='0' r='2'/%3E%3Ccircle cx='36' cy='72' r='2'/%3E%3C/g%3E%3C/svg%3E");
}
.vel-heroe > * { position: relative; }
.vel-heroe h1 {
    color: #FFFFFF;
    font-size: clamp(2rem, 5.2vw, 3.4rem);
    line-height: 1.1;
    letter-spacing: -.02em;
    max-width: 18ch;
}
.vel-heroe .lead {
    color: rgba(255, 255, 255, .90);
    font-size: clamp(var(--vel-t-base), 2.2vw, var(--vel-t-xl));
    max-width: 52ch;
}
.vel-heroe .vel-chip {
    background: rgba(255, 255, 255, .16);
    color: #FFFFFF;
    border-color: rgba(255, 255, 255, .30);
}

/* Los dos caminos. Son tarjetas grandes y pulsables enteras, no dos
   enlaces de texto: en movil el visitante decide aqui y tiene que poder
   hacerlo con el pulgar. */
.vel-caminos { display: grid; gap: var(--vel-e4); grid-template-columns: 1fr; }
@media (min-width: 768px) {
    .vel-caminos { grid-template-columns: 1fr 1fr; }
}
.vel-camino {
    display: block;
    padding: var(--vel-e5);
    border-radius: var(--vel-radio-lg);
    border: 1px solid rgba(255, 255, 255, .22);
    background: rgba(255, 255, 255, .08);
    color: #FFFFFF;
    text-decoration: none;
    transition: transform var(--vel-mov) var(--vel-curva),
                background var(--vel-mov) var(--vel-curva),
                border-color var(--vel-mov) var(--vel-curva);
}
.vel-camino:hover,
.vel-camino:focus-visible {
    background: rgba(255, 255, 255, .15);
    border-color: rgba(255, 255, 255, .48);
    color: #FFFFFF;
    transform: translateY(-3px);
}
.vel-camino .titulo { font-size: var(--vel-t-xl); font-weight: 700; display: block; }
.vel-camino .detalle { color: rgba(255, 255, 255, .84); font-size: var(--vel-t-sm); display: block; margin-top: var(--vel-e2); }
.vel-camino .flecha { font-weight: 700; margin-top: var(--vel-e3); display: inline-block; }

/* Franja de cifras. Se separa del heroe para que no compita con el
   titular: primero la promesa, despues la prueba. */
.vel-cifras {
    display: grid;
    gap: var(--vel-e4);
    grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 768px) {
    .vel-cifras { grid-template-columns: repeat(4, 1fr); }
}
.vel-cifra-caja { text-align: center; padding: var(--vel-e4) var(--vel-e3); }
.vel-cifra-caja .valor {
    display: block;
    font-size: clamp(var(--vel-t-2xl), 5vw, var(--vel-t-3xl));
    font-weight: 800;
    line-height: 1;
    color: var(--vel-primario);
    font-variant-numeric: tabular-nums;
}
.vel-cifra-caja .etiqueta {
    display: block;
    margin-top: var(--vel-e2);
    font-size: var(--vel-t-sm);
    color: var(--vel-apagado);
    text-transform: uppercase;
    letter-spacing: .06em;
}

.vel-seccion { padding-block: clamp(var(--vel-e6), 6vw, 4.5rem); }
.vel-seccion-alt { background: var(--vel-superficie-2); }
.vel-titulo-seccion { font-size: clamp(1.5rem, 3.4vw, var(--vel-t-2xl)); letter-spacing: -.01em; }

/* ---------------------------------------------------------------------
   18. Tarjeta de curso con imagen

   La portada es 16:9 fijo. Sin aspect-ratio la tarjeta salta de alto
   mientras cargan las imagenes y la rejilla entera baila (CLS).
   --------------------------------------------------------------------- */
.vel-curso {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
    /* Imprescindible: el titulo de la tarjeta usa .stretched-link para que
       toda la tarjeta sea pulsable, y ese enlace se estira hasta el ancestro
       POSICIONADO mas cercano. Sin esta linea se estiraba hasta el bloque
       contenedor inicial y la ultima tarjeta del catalogo tapaba la pagina
       entera con una capa invisible: la barra de navegacion dejaba de
       responder. Lo detecto la prueba de navegador, no la revision a ojo. */
    position: relative;
    background: var(--vel-superficie);
    /* La tinta se fija aqui y no se hereda: esta tarjeta tambien se usa
       DENTRO del heroe oscuro, que pinta su texto en blanco. Heredarlo
       dejaba el titulo blanco sobre la tarjeta blanca, medido en 1.00:1.
       Todo componente de superficie que pueda caer sobre una seccion oscura
       tiene que declarar su color. */
    color: var(--vel-tinta);
    border: 1px solid var(--vel-borde);
    border-radius: var(--vel-radio-lg);
    box-shadow: var(--vel-elev-1);
    transition: transform var(--vel-mov) var(--vel-curva),
                box-shadow var(--vel-mov) var(--vel-curva);
}
/* :not(.btn) es necesario: sin el, esta regla le gana en especificidad a
   .btn-primary y pintaba la letra del boton en tinta oscura sobre el teal
   (2.80:1). Un ajuste de color que arregla un contraste y rompe otro es el
   modo tipico de perseguirse la cola. */
.vel-curso a:not(.btn) { color: var(--vel-tinta); }
.vel-curso a:not(.btn):hover { color: var(--vel-primario); }
.vel-curso .vel-mini { color: var(--vel-apagado); }
.vel-curso:hover,
.vel-curso:focus-within { transform: translateY(-4px); box-shadow: var(--vel-elev-2); }

.vel-curso-portada {
    position: relative;
    aspect-ratio: 16 / 9;
    max-width: 100%;
    background: var(--vel-superficie-2);
    overflow: hidden;
}
.vel-curso-portada img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Sin portada no se deja un hueco gris: se pinta el color del curso con su
   inicial, que sigue siendo reconocible en el catalogo. */
.vel-curso-portada .sin-imagen {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    font-size: 3rem; font-weight: 800;
}
.vel-curso-cinta {
    position: absolute; left: 0; right: 0; bottom: 0; height: 5px;
    background: var(--vel-primario);
}
.vel-curso-cuerpo { display: flex; flex-direction: column; flex: 1 1 auto; padding: var(--vel-e5); gap: var(--vel-e3); }
.vel-curso-cuerpo h3 { font-size: var(--vel-t-lg); margin: 0; }
.vel-curso-pie {
    display: flex; align-items: center; justify-content: space-between; gap: var(--vel-e3);
    margin-top: auto; padding-top: var(--vel-e3); border-top: 1px solid var(--vel-borde);
}

/* Precio. El gratis se marca en verde de exito y el precio anunciado va
   tachado al lado: la urgencia real es una fecha, no un color chillon. */
.vel-precio { display: flex; align-items: baseline; gap: var(--vel-e2); flex-wrap: wrap; }
.vel-precio .valor { font-size: var(--vel-t-xl); font-weight: 800; color: var(--vel-tinta); font-variant-numeric: tabular-nums; }
.vel-precio .gratis { font-size: var(--vel-t-xl); font-weight: 800; color: var(--vel-exito); }
.vel-precio .antes { font-size: var(--vel-t-sm); color: var(--vel-apagado); text-decoration: line-through; }
.vel-precio .moneda { font-size: var(--vel-t-sm); color: var(--vel-apagado); }
.vel-promo {
    display: inline-flex; align-items: center; gap: var(--vel-e2);
    background: var(--vel-exito-suave); color: var(--vel-exito);
    border: 1px solid var(--vel-exito);
    border-radius: 999px; padding: var(--vel-e1) var(--vel-e3);
    font-size: var(--vel-t-sm); font-weight: 600;
}

/* Encabezado de la pagina de curso. La imagen va de fondo con un velo
   oscuro encima: sin el velo, el texto blanco sobre una foto clara es
   ilegible y no hay forma de saber de antemano como es la foto que suba
   un coordinador. */
.vel-curso-heroe {
    position: relative;
    color: #FFFFFF;
    background: var(--vel-nav);
    padding-block: clamp(var(--vel-e6), 7vw, 4.5rem);
    overflow: hidden;
}
/* Es un <img> y no un background-image porque la politica de contenido
   prohibe el atributo style y la imagen es distinta en cada curso. Necesita
   width/height al 100% con object-fit: sin eso conserva su ancho natural de
   1920 px y desborda la pagina en movil. */
.vel-curso-heroe .fondo {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    opacity: .30;
}
.vel-curso-heroe .velo {
    position: absolute; inset: 0;
    background: linear-gradient(180deg, rgba(6, 36, 41, .55) 0%, rgba(6, 36, 41, .88) 100%);
}
.vel-curso-heroe > .container-xl { position: relative; }
.vel-curso-heroe h1 { color: #FFFFFF; font-size: clamp(1.8rem, 4.4vw, 2.8rem); line-height: 1.15; }
.vel-curso-heroe .lead { color: rgba(255, 255, 255, .92); max-width: 60ch; }
.vel-curso-heroe .vel-chip { background: rgba(255, 255, 255, .16); color: #FFFFFF; border-color: rgba(255, 255, 255, .30); }
/* Las migas heredan el gris apagado, pensado para fondo claro: sobre el
   heroe oscuro daban 1.69:1. */
.vel-curso-heroe .vel-migas,
.vel-curso-heroe .vel-migas a { color: rgba(255, 255, 255, .82); }
.vel-curso-heroe .vel-migas a:hover { color: #FFFFFF; }

/* Tarjeta flotante de inscripcion. Se pega al hacer scroll solo en
   escritorio: en movil roba la mitad de la pantalla. */
.vel-compra {
    background: var(--vel-superficie);
    border: 1px solid var(--vel-borde);
    border-radius: var(--vel-radio-lg);
    box-shadow: var(--vel-elev-3);
    padding: var(--vel-e5);
}
@media (min-width: 992px) {
    .vel-compra-fija { position: sticky; top: var(--vel-e4); }
}

/* Temario publico: acordeon de modulos */
.vel-temario-modulo {
    border: 1px solid var(--vel-borde);
    border-radius: var(--vel-radio);
    background: var(--vel-superficie);
    margin-bottom: var(--vel-e3);
    overflow: hidden;
}
.vel-temario-cab {
    display: flex; align-items: center; gap: var(--vel-e3);
    width: 100%; text-align: left;
    padding: var(--vel-e4);
    background: transparent; border: 0; color: var(--vel-tinta);
    font-weight: 600; min-height: 56px; cursor: pointer;
}
.vel-temario-cab:hover { background: var(--vel-superficie-2); }
.vel-temario-num {
    flex: 0 0 auto; width: 32px; height: 32px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--vel-primario-suave); color: var(--vel-primario-fuerte);
    font-size: var(--vel-t-sm); font-weight: 700;
}
.vel-temario-lista { list-style: none; margin: 0; padding: 0 var(--vel-e4) var(--vel-e4) calc(var(--vel-e4) + 44px); }
.vel-temario-lista li {
    display: flex; align-items: center; justify-content: space-between; gap: var(--vel-e3);
    padding: var(--vel-e2) 0; border-top: 1px solid var(--vel-borde);
    font-size: var(--vel-t-sm);
}

/* ---------------------------------------------------------------------
   19. Bloques de contenido

   Un bloque es la unidad con la que un coordinador arma una leccion. Cada
   tipo tiene su forma; lo que comparten es el ritmo vertical, para que la
   leccion se lea como un texto y no como una lista de cajas.
   --------------------------------------------------------------------- */
.vel-bloques > * + * { margin-top: var(--vel-e5); }
.vel-bloque-titulo { font-size: var(--vel-t-xl); margin-bottom: var(--vel-e3); }

.vel-b-imagen figure { margin: 0; }
.vel-b-imagen img { max-width: 100%; height: auto; border-radius: var(--vel-radio); display: block; }
.vel-b-imagen figcaption { font-size: var(--vel-t-sm); color: var(--vel-apagado); margin-top: var(--vel-e2); }
.vel-b-imagen.medio img   { max-width: 60%; }
.vel-b-imagen.pequeno img { max-width: 38%; }
@media (max-width: 767px) {
    .vel-b-imagen.medio img, .vel-b-imagen.pequeno img { max-width: 100%; }
}

/* Los marcos de video, simulador y HTML aislado conservan su proporcion
   con aspect-ratio y no con relleno porcentual: el truco del padding
   obliga a recalcular el alto a mano cada vez que cambia el contenido. */
.vel-marco {
    position: relative;
    width: 100%;
    border: 1px solid var(--vel-borde);
    border-radius: var(--vel-radio);
    overflow: hidden;
    background: var(--vel-superficie-2);
}
.vel-marco iframe { display: block; width: 100%; border: 0; }
.vel-marco-video { aspect-ratio: 16 / 9; max-width: 100%; }
.vel-marco-video iframe { position: absolute; inset: 0; width: 100%; height: 100%; }
.vel-marco-pie {
    display: flex; align-items: center; justify-content: space-between; gap: var(--vel-e3);
    padding: var(--vel-e2) var(--vel-e3);
    background: var(--vel-superficie-2);
    border-top: 1px solid var(--vel-borde);
    font-size: var(--vel-t-xs); color: var(--vel-apagado);
}

.vel-b-pdf .visor { width: 100%; height: 640px; border: 0; }
@media (max-width: 767px) {
    /* En movil el visor incrustado de PDF es inutilizable en casi todos los
       navegadores. Se muestra la ficha y el boton de abrir, y ya. */
    .vel-b-pdf .visor { display: none; }
}
.vel-archivo {
    display: flex; align-items: center; gap: var(--vel-e4);
    padding: var(--vel-e4);
    border: 1px solid var(--vel-borde);
    border-radius: var(--vel-radio);
    background: var(--vel-superficie);
}
.vel-archivo .icono {
    flex: 0 0 auto; width: 44px; height: 44px; border-radius: var(--vel-radio-sm);
    display: flex; align-items: center; justify-content: center;
    background: var(--vel-primario-suave); color: var(--vel-primario-fuerte);
    font-weight: 700; font-size: var(--vel-t-xs); letter-spacing: .04em;
}
.vel-archivo .datos { flex: 1 1 auto; min-width: 0; }
.vel-archivo .datos .nombre { font-weight: 600; word-break: break-word; }

/* Avisos. Cada variante lleva su color Y su etiqueta escrita: el color
   solo no comunica a quien no lo distingue. */
.vel-b-aviso {
    border-left: 4px solid var(--vel-primario);
    background: var(--vel-primario-suave);
    border-radius: 0 var(--vel-radio) var(--vel-radio) 0;
    padding: var(--vel-e4) var(--vel-e5);
}
.vel-b-aviso .rotulo {
    display: block; font-weight: 700; font-size: var(--vel-t-sm);
    text-transform: uppercase; letter-spacing: .05em;
    margin-bottom: var(--vel-e2); color: var(--vel-primario-fuerte);
}
.vel-b-aviso.consejo { border-left-color: var(--vel-exito); background: var(--vel-exito-suave); }
.vel-b-aviso.consejo .rotulo { color: var(--vel-exito); }
.vel-b-aviso.cuidado { border-left-color: var(--vel-aviso); background: var(--vel-aviso-suave); }
.vel-b-aviso.cuidado .rotulo { color: var(--vel-aviso); }
.vel-b-aviso.error   { border-left-color: var(--vel-peligro); background: var(--vel-peligro-suave); }
.vel-b-aviso.error .rotulo { color: var(--vel-peligro); }

.vel-b-separador { border: 0; border-top: 1px solid var(--vel-borde); margin-block: var(--vel-e6); }

/* Actividades interactivas */
.vel-actividad {
    border: 2px solid var(--vel-primario);
    border-radius: var(--vel-radio-lg);
    background: var(--vel-superficie);
    padding: var(--vel-e5);
}
.vel-actividad-cab { display: flex; align-items: center; justify-content: space-between; gap: var(--vel-e3); flex-wrap: wrap; }
.vel-par { display: grid; gap: var(--vel-e3); grid-template-columns: 1fr; align-items: center; }
@media (min-width: 640px) {
    .vel-par { grid-template-columns: 1fr auto; }
}
.vel-par-fila {
    display: grid; gap: var(--vel-e3); align-items: center;
    grid-template-columns: 1fr;
    padding: var(--vel-e3);
    border: 1px solid var(--vel-borde);
    border-radius: var(--vel-radio-sm);
    background: var(--vel-superficie-2);
}
@media (min-width: 640px) {
    .vel-par-fila { grid-template-columns: 1fr 220px; }
}
.vel-par-fila.acierto { border-color: var(--vel-exito); background: var(--vel-exito-suave); }
.vel-par-fila.fallo   { border-color: var(--vel-peligro); background: var(--vel-peligro-suave); }

/* ---------------------------------------------------------------------
   20. Editor de autoria

   Regla de la seccion: el autor siempre tiene que ver DONDE esta y QUE le
   falta. Un editor que solo muestra formularios obliga a recordar el
   estado del curso de memoria.
   --------------------------------------------------------------------- */
.vel-editor-cab {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: var(--vel-e4); flex-wrap: wrap;
    padding-bottom: var(--vel-e4);
    border-bottom: 1px solid var(--vel-borde);
    margin-bottom: var(--vel-e5);
}
.vel-migas { font-size: var(--vel-t-sm); color: var(--vel-apagado); }
.vel-migas a { color: var(--vel-apagado); }
.vel-migas a:hover { color: var(--vel-primario); }

/* Lista de comprobacion para publicar. Se muestra siempre, tambien cuando
   esta completa: saber que no falta nada es informacion. */
.vel-checklist { list-style: none; margin: 0; padding: 0; }
.vel-checklist li {
    display: flex; gap: var(--vel-e3); align-items: flex-start;
    padding: var(--vel-e2) 0; font-size: var(--vel-t-sm);
}
.vel-checklist .marca { flex: 0 0 auto; font-weight: 700; width: 1.4em; }
.vel-checklist .falta .marca { color: var(--vel-aviso); }
.vel-checklist .listo .marca { color: var(--vel-exito); }

/* Estructura del curso: modulos y lecciones anidadas */
.vel-arbol { list-style: none; margin: 0; padding: 0; }
.vel-arbol-modulo {
    border: 1px solid var(--vel-borde);
    border-radius: var(--vel-radio);
    background: var(--vel-superficie);
    margin-bottom: var(--vel-e4);
    overflow: hidden;
}
.vel-arbol-cab {
    display: flex; align-items: center; gap: var(--vel-e3);
    padding: var(--vel-e4);
    background: var(--vel-superficie-2);
    border-bottom: 1px solid var(--vel-borde);
    flex-wrap: wrap;
}
.vel-arbol-cab .titulo { font-weight: 700; flex: 1 1 220px; min-width: 0; }
.vel-arbol-lecciones { list-style: none; margin: 0; padding: 0; }
.vel-arbol-lecciones li {
    display: flex; align-items: center; gap: var(--vel-e3);
    padding: var(--vel-e3) var(--vel-e4);
    border-bottom: 1px solid var(--vel-borde);
    flex-wrap: wrap;
}
.vel-arbol-lecciones li:last-child { border-bottom: 0; }
.vel-arbol-lecciones .nombre { flex: 1 1 200px; min-width: 0; }
.vel-arbol-vacio { padding: var(--vel-e5); text-align: center; color: var(--vel-apagado); font-size: var(--vel-t-sm); }

/* Paleta de tipos de bloque. Cada tipo se presenta con su nombre y su
   ayuda: si hay que explicar el boton en una capacitacion, el boton esta
   mal escrito. */
.vel-paleta { display: grid; gap: var(--vel-e3); grid-template-columns: 1fr; }
@media (min-width: 576px) { .vel-paleta { grid-template-columns: 1fr 1fr; } }
@media (min-width: 992px) { .vel-paleta { grid-template-columns: repeat(3, 1fr); } }
.vel-paleta button {
    display: block; width: 100%; text-align: left;
    padding: var(--vel-e4);
    border: 1px solid var(--vel-borde-control);
    border-radius: var(--vel-radio);
    background: var(--vel-superficie);
    color: var(--vel-tinta);
    min-height: 44px; cursor: pointer;
    transition: border-color var(--vel-mov-rapido) var(--vel-curva),
                background var(--vel-mov-rapido) var(--vel-curva);
}
.vel-paleta button:hover { border-color: var(--vel-primario); background: var(--vel-primario-suave); }
.vel-paleta .nombre { display: block; font-weight: 700; }
.vel-paleta .ayuda { display: block; font-size: var(--vel-t-sm); color: var(--vel-apagado); margin-top: var(--vel-e1); }

/* Bloque dentro del editor */
.vel-bloque-editor {
    border: 1px solid var(--vel-borde);
    border-radius: var(--vel-radio);
    background: var(--vel-superficie);
    margin-bottom: var(--vel-e4);
}
.vel-bloque-editor > summary {
    display: flex; align-items: center; gap: var(--vel-e3);
    padding: var(--vel-e3) var(--vel-e4);
    cursor: pointer; min-height: 48px;
    background: var(--vel-superficie-2);
    border-radius: var(--vel-radio) var(--vel-radio) 0 0;
    flex-wrap: wrap;
}
.vel-bloque-editor > summary:hover { background: var(--vel-primario-suave); }
.vel-bloque-editor[open] > summary { border-bottom: 1px solid var(--vel-borde); }
.vel-bloque-editor .cuerpo { padding: var(--vel-e4); }
.vel-etiqueta-tipo {
    flex: 0 0 auto;
    font-size: var(--vel-t-xs); font-weight: 700;
    text-transform: uppercase; letter-spacing: .05em;
    background: var(--vel-primario-suave); color: var(--vel-primario-fuerte);
    border-radius: 999px; padding: 2px var(--vel-e3);
}
.vel-bloque-editor .resumen { flex: 1 1 200px; min-width: 0; color: var(--vel-apagado); font-size: var(--vel-t-sm); }

/* Vista previa de la imagen que el curso ya tiene puesta.
   aspect-ratio fijo para que la tarjeta no salte al cambiar de imagen. */
.vel-miniatura {
  display: block;
  width: 100%;
  max-width: 260px;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--vel-radio-sm);
  border: 1px solid var(--vel-borde);
}

/* Selector visual de imagen de la biblioteca */
.vel-galeria { display: grid; gap: var(--vel-e3); grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
.vel-galeria label {
    display: block; cursor: pointer;
    border: 2px solid var(--vel-borde);
    border-radius: var(--vel-radio-sm);
    overflow: hidden; background: var(--vel-superficie-2);
}
.vel-galeria label:hover { border-color: var(--vel-primario); }
.vel-galeria input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.vel-galeria input:checked + img,
.vel-galeria input:checked ~ .pie { outline: 0; }
.vel-galeria input:focus-visible + img { outline: 3px solid var(--vel-primario); outline-offset: 2px; }
.vel-galeria .marco { aspect-ratio: 16 / 9; max-width: 100%; }
.vel-galeria img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vel-galeria .pie { padding: var(--vel-e2); font-size: var(--vel-t-xs); color: var(--vel-apagado); word-break: break-word; }
.vel-galeria .elegida { border-color: var(--vel-primario); box-shadow: 0 0 0 3px var(--vel-primario-suave); }

/* Rubrica: tabla de criterios por niveles */
.vel-rubrica { width: 100%; border-collapse: collapse; }
.vel-rubrica th, .vel-rubrica td {
    border: 1px solid var(--vel-borde);
    padding: var(--vel-e3);
    vertical-align: top;
    font-size: var(--vel-t-sm);
}
.vel-rubrica thead th { background: var(--vel-superficie-2); text-align: left; }
.vel-rubrica .criterio { font-weight: 700; background: var(--vel-superficie-2); }

/* ---------------------------------------------------------------------
   21. Movimiento reducido
   Quien activa esta preferencia suele hacerlo por mareo o migrana. No es
   opcional respetarla.
   --------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
    .vel-tarjeta-curso:hover { transform: none; }
}

/* ---------------------------------------------------------------------
   22. Impresion
   --------------------------------------------------------------------- */
@media print {
    .vel-nav, .vel-sin-imprimir, footer, .vel-salto { display: none !important; }
    body { background: #FFFFFF; color: #000000; }
    .vel-certificado { border-width: 2px; margin: 0; box-shadow: none; max-width: none; }
    a[href]::after { content: ""; }
}

/* ---------------------------------------------------------------------
   23. Pantallas pequenas
   --------------------------------------------------------------------- */
@media (max-width: 575.98px) {
    /* Una .row con separacion g-5 lleva margenes negativos de 24 px por
       lado, pero .container-xl solo pone 12 px de relleno: sobran 12 px que
       en movil se convierten en desplazamiento horizontal de toda la
       pagina. Se recorta la separacion en pantallas pequenas, donde de todos
       modos las columnas se apilan y esa separacion no aporta nada. */
    .row.g-5, .row.gx-5 { --bs-gutter-x: 1.5rem; }

    .vel-contenido { font-size: var(--vel-t-base); }
    .vel-certificado { padding: var(--vel-e5) var(--vel-e4); }
    .vel-metrica .valor { font-size: var(--vel-t-xl); }
    .vel-logo { height: 28px; }
    .vel-portada { border-radius: 0 0 var(--vel-radio) var(--vel-radio); }
}
