/* ================================================================
   1. COLORES, MEDIDAS Y AJUSTES GENERALES
   Cambiá estos valores para modificar el fondo, los colores globales,
   los bordes redondeados y el ancho máximo del contenido.
   ================================================================ */
:root {
    --container: 1280px;
    /* Montserrat 800. La familia ya se descarga con ese peso incluido (ver el
       <link> de Google Fonts), así que no cuesta un byte extra. Antes acá decía
       "Sifonn Pro", que no está en el proyecto ni en Google Fonts: los títulos
       caían a Montserrat normal y la jerarquía título/cuerpo no existía. */
    --font-title: Montserrat, sans-serif;
    --peso-title: 800;
    --font-detail: Montserrat, sans-serif;
    --font-text: Montserrat, sans-serif;
    /* Progreso de scroll del header (0 = arriba del todo, 1 = header ya achicado).
       Lo actualiza app.js en cada cuadro mientras se hace scroll. */
    --scroll-progress: 0;
    /* Mismo progreso para el desenfoque, escalonado para cuidar el scroll móvil. */
    --blur-progress: 0;
    --blur-max: 34px;

    /* ---- Escalas ----------------------------------------------------------
       Todo el CSS sale de acá. Antes había 27 tamaños de fuente, 46 paddings y
       11 radios distintos: valores que no eran decisiones sino acumulación.
       Si algo necesita un valor intermedio, casi siempre conviene elegir el
       paso de al lado antes que inventar uno nuevo. */
    --space-1: .25rem;  --space-2: .375rem; --space-3: .5rem;
    --space-4: .75rem;  --space-5: 1rem;    --space-6: 1.25rem;
    --space-7: 1.5rem;  --space-8: 2rem;    --space-9: 2.5rem;

    --radius-xs: 6px;   --radius-sm: 8px;   --radius-md: 12px;
    --radius-lg: 16px;  --radius-pill: 999px; --radius-round: 50%;

    /* Escalera de elevación. Referencian var(--shadow), que cambia por tema:
       las custom properties se resuelven al usarse, así que siguen al tema. */
    --elev-1: 0 1px 2px var(--shadow);
    --elev-2: 0 6px 18px var(--shadow);
    --elev-3: 0 12px 30px var(--shadow);
    --elev-4: 0 22px 60px var(--shadow);

    --dur-fast: 120ms;  --dur-base: 180ms;  --dur-slow: 260ms;

    --font-scale: 1;
    --fs-2xs: calc(.75rem * var(--font-scale, 1));
    --fs-xs: calc(.8125rem * var(--font-scale, 1));
    --fs-sm: calc(.875rem * var(--font-scale, 1));
    --fs-base: calc(.9375rem * var(--font-scale, 1));
    --fs-md: calc(1rem * var(--font-scale, 1));
    --fs-lg: calc(1.125rem * var(--font-scale, 1));
    --fs-xl: calc(1.375rem * var(--font-scale, 1));
    --fs-2xl: calc(1.75rem * var(--font-scale, 1));

    /* ---- Paleta orgánica (Fase A del rediseño neumórfico) -------------------
       El tema lo fija un script inline en el <head>. Si ese script no llega a
       correr (JS desactivado, error, CSP), sin estos valores acá var(--bg) y
       var(--text) quedaban inválidos y la página entera perdía color. Esta es
       la paleta clara, que oficia de red de contención.

       Familia cromática: EdTech de tres colores. Índigo para lo formal e
       institucional, naranja para plataformas y categorías, verde jade para
       la acción (CTAs, chat, foco de inputs).

       Los NOMBRES de las variables funcionales (--orange, --blue, --purple…)
       se mantienen a propósito aunque el matiz
       haya cambiado de familia: los usan ~40 reglas y el rol de cada una
       (naranja = plataformas, --blue = formal, violeta = alternativas…) sigue
       siendo el mismo. Renombrarlas sería una segunda refactorización sin
       ganancia. Lo que sí cambió es el color que hay detrás del nombre. */
    --bg: #F7F5FF;
    --surface: #FFFFFF;
    --surface-soft: #EEECFB;
    --line: rgba(27, 24, 48, .14);
    --text: #1B1830;
    --muted: #5C5680;
    --orange: #F97316;   /* naranja: plataformas / categorías */
    --green: #16A34A;    /* verde */
    --blue: #4F46E5;     /* índigo: formal / institucional */
    --purple: #9333EA;   /* violeta */
    --teal: #0D9488;     /* verde azulado */
    --accent: #059669;   /* verde jade: acción (CTAs, chat) */
    /* Corazón de "Me interesa" marcado: es la única señal roja del sitio, a
       propósito, porque un corazón guardado se lee rojo en todos lados. */
    --fav-rojo: #E11D48;
    --shadow: rgba(40, 34, 90, .14);

    /* Tinta de los badges. El color puro sobre su propio tinte al 16% daba ~2.5:1
       (ilegible al sol); estos son el mismo matiz con la luminancia corregida
       para pasar 4.5:1. El fondo sigue siendo el color puro tinteado. */
    --orange-ink: #B23A0B;
    --green-ink: #0F6B33;
    --blue-ink: #4F46E5;
    --purple-ink: #8D31E1;
    --teal-ink: #0A766D;
    --accent-ink: #047854;
    /* Texto sobre relleno saturado claro. */
    --on-accent: #1B1830;
    /* El relleno violeta usa el índigo, que es oscuro: lleva texto claro. */
    --purple-fill: #4F46E5;
    --on-purple: #FFFFFF;
    /* Borde de controles de formulario: --line queda en ~1.3:1 y la norma pide 3:1. */
    --line-strong: rgba(27, 24, 48, .48);
    /* WCAG 2.1 - 1.4.11 Contraste de elementos no textuales: frontera de los
       campos de formulario (>=3:1 contra el fondo donde se apoyan). Token aparte
       de --line-strong porque ese se usa además en adornos (subrayados,
       separadores) que no tienen requisito de contraste. */
    --control-line: rgba(27, 24, 48, .52);
    /* WCAG 2.1 - 1.4.3 Contraste mínimo: tinta oscura para rellenos vivos
       (verde, naranja, teal). Con blanco encima daban 2.8-3.8:1. */
    --on-vivid: #14121F;
    /* Acción sólida (chip activo, botones primarios, skip link, contadores): par
       relleno/tinta con >=4.5:1 en cada tema. --accent a secas daba 4.47:1 en
       claro y 2.98:1 en oscuro. */
    --accion-fill: #4F46E5;
    --accion-ink: #FFFFFF;
    /* Texto sobre --muted (badge de compatibilidad baja). */
    --on-muted: #FFFFFF;
}

html[data-theme="dark"] {
    --bg: #09101c;
    --surface: #121c2f;
    --surface-soft: #1e293b;
    --line: rgba(255, 255, 255, 0.08);
    --text: #f1f5f9;
    --muted: #94a3b8;

    --accent: #818cf8; 
    --accent-ink: #818cf8;
    --fav-rojo: #FB7185;
    --on-accent: #09101c;
    --shadow: rgba(0, 0, 0, 0.4);

    --purple: #a855f7;
    --orange: #fb923c;
    --green:  #4ade80;
    --blue:   #818cf8;
    --teal:   #2dd4bf;

    --orange-ink: #fdba74;
    --green-ink:  #86efac;
    --blue-ink:   #93c5fd;
    --purple-ink: #e9d5ff;
    --teal-ink:   #5eead4;
    
    --badge-orange: color-mix(in srgb, #fb923c 24%, transparent);
    --badge-green:  color-mix(in srgb, #22c55e 24%, transparent);
    --badge-blue:   color-mix(in srgb, #3b82f6 24%, transparent);
    --badge-purple: color-mix(in srgb, #a855f7 24%, transparent);
    --badge-teal:   color-mix(in srgb, #14b8a6 24%, transparent);
    
    --purple-fill: #d8b4fe;
    --on-purple: #09101c;
    --line-strong: rgba(255, 255, 255, 0.2);
    --control-line: rgba(255, 255, 255, .36);
    --accion-fill: #818cf8;
    --accion-ink: #09101c;
    --on-vivid: #14121F;
    --on-muted: #09101c;
}

html[data-theme="light"] {
    --bg: #fdfaf5;
    --surface: #ffffff;
    --surface-soft: #f3f0ea;
    --line: rgba(0, 0, 0, 0.08);
    --text: #1f1d1a;
    --muted: #6b6863;

    --accent: #6366f1;
    --accent-ink: #4338ca;
    --on-accent: #ffffff;
    --shadow: rgba(0, 0, 0, 0.04);

    --orange-ink: #b23a0b;
    --green-ink:  #0f6b33;
    --blue-ink:   #1d4ed8;
    --purple-ink: #6d28d9;
    --teal-ink:   #0f766e;
    
    --badge-orange: #ffedd5;
    --badge-green:  #dcfce7;
    --badge-blue:   #dbeafe;
    --badge-purple: #f3e8ff;
    --badge-teal:   #ccfbf1;
    
    --purple-fill: #5b21b6;
    --on-purple: #ffffff;
    --line-strong: rgba(0, 0, 0, 0.15);
    --control-line: rgba(27, 24, 48, .52);
    --accion-fill: #4F46E5;
    --accion-ink: #ffffff;
    --on-vivid: #14121F;
    --on-muted: #ffffff;
}

/* 2. BASE DE LA PÁGINA: tipografía, fondo y comportamiento global. */
* { box-sizing: border-box; }
/* El canal de la barra de scroll se reserva siempre. Así, cuando la bienvenida
   bloquea el scroll (abajo), esconder la barra no corre el contenido ~15px y
   vuelve a correrlo al soltarlo. */
html { scrollbar-gutter: stable; }
/* Mientras la bienvenida cubre la pantalla no hay nada que scrollear: es un
   overlay fijo. Sin esto la rueda seguía moviendo el catálogo por detrás y, al
   tocar "Ver carreras", el usuario aterrizaba a mitad de la grilla con el
   header todavía expandido, como si el sitio hubiera saltado solo. */
html.bienvenida-abierta, html.bienvenida-abierta body { overflow: hidden; }
body {
    margin: 0;
    min-width: 320px;
    /* Reserva el alto del header expandido (lo mide app.js). El valor de reserva
       es solo por si el JS no llega a correr. */
    padding-top: var(--hero-alto, 130px);
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-text);
    line-height: 1.5;
    transition: background-color var(--dur-slow) ease, color var(--dur-slow) ease;
}
button, input, select { font: inherit; }
button { cursor: pointer; }
[hidden] { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

/* Con el header fijo y 35 filtros antes de los resultados en el orden del DOM,
   sin esto no había forma de saltearlos con el teclado. Solo se ve al enfocarlo. */
.skip-link {
    position: absolute; left: .5rem; top: -100px; z-index: 100;
    padding: .7rem 1rem; border-radius: var(--radius-sm);
    color: var(--accion-ink); background: var(--accion-fill);
    font-weight: 700; text-decoration: none;
}
.skip-link:focus { top: .5rem; }

/* #7 Accesibilidad de foco: anillo visible y de alto contraste para todo elemento
   navegable por teclado. Usa la variable de acento del tema, así respeta claro/oscuro. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }


/* ================================================================
   2b. SUPERFICIES (plano)
   El sitio no usa relieve. Una pieza se distingue del fondo por su
   color de superficie (--surface contra --bg) y por el borde de 1px
   de --line, no por sombras. Los estados (hover, activo, elegido) se
   dicen con fondo y con color de tinta, nunca con volumen ni con la
   pieza levantándose.

   La única sombra que queda en el sitio es la escalera --elev-*, y va
   solo en lo que de verdad flota por encima de la página: la ventana
   del chat y su burbuja. Ahí la
   sombra no es decoración — es lo que separa la capa flotante del
   contenido que quedó abajo.

   Acá había un par de clases utilitarias, .neu-raised y .neu-pressed,
   que aplicaban el relieve. No las usaba ningún elemento del HTML, así
   que se fueron junto con el efecto.
   ================================================================ */
/* ================================================================
   3. ENCABEZADO / PORTADA
   Incluye el degradado superior, el título principal y el texto.
   ================================================================ */
.hero {
    /* Fijo arriba siempre. Una sola fila: logo a la izquierda, buscador al medio
       y el toggle de tema a la derecha. Al hacer scroll la fila no se reordena,
       solo se achica un poco (--scroll-progress, lo actualiza js/main.js) y el
       fondo pasa a vidrio esmerilado (blur) con borde inferior. */
    /* Fijo (no sticky): al achicarse, su alto ya no empuja al contenido, así que
       no se reflota la página entera en cada cuadro. El espacio que ocuparía
       expandido lo reserva el padding-top del body (--hero-alto, lo mide main.js). */
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 40;
    contain: layout;
    /* Header bajo a propósito: al abrir la página tiene que verse el catálogo.
       Con la fila única (logo + buscador + toggle) alcanza con ~123px. */
    --hero-pad-top: 1.75rem;
    --hero-pad-bottom: 1.75rem;
    --hero-pad-compacto: 1rem;
    /* Ancho del logo y del buscador: se achican con el scroll. Se anima el ANCHO
       (no un transform) para que el alto del header baje de verdad: el alto de la
       imagen sigue al ancho por su proporción. */
    --logo-w-expandido: 250px;
    --logo-w-compacto: 190px;
    --logo-w: min(100%, calc(var(--logo-w-expandido) - var(--scroll-progress) * (var(--logo-w-expandido) - var(--logo-w-compacto))));
    --bar-gap: 1.5rem;
    --search-w-expandido: 640px;
    --search-w-compacto: 480px;
    --search-w: calc(var(--search-w-expandido) - var(--scroll-progress) * (var(--search-w-expandido) - var(--search-w-compacto)));
    /* El padding incorpora env(safe-area-inset-top) para no chocar con el notch/status bar en iOS */
    padding:
        calc(var(--hero-pad-top) + env(safe-area-inset-top, 0px) - var(--scroll-progress) * (var(--hero-pad-top) - var(--hero-pad-compacto)))
        1.5rem
        calc(var(--hero-pad-bottom) - var(--scroll-progress) * (var(--hero-pad-bottom) - var(--hero-pad-compacto)));
    text-align: center;
    /* El fondo se vuelve TRANSLÚCIDO al achicarse: si quedara opaco, el
       backdrop-filter no tendría nada para desenfocar y no se vería el efecto. */
    background:
        linear-gradient(180deg,
            color-mix(in srgb, var(--surface) calc((1 - var(--scroll-progress)) * 100%), transparent),
            color-mix(in srgb, var(--bg) calc((1 - var(--scroll-progress)) * 100%), transparent)),
        color-mix(in srgb, var(--surface) calc(var(--scroll-progress) * 55%), transparent);
    /* Blur + saturate emula el "vidrio esmerilado" de iOS en vez de un blur plano.
       Va sobre --blur-progress, que sigue al scroll sin escalones. */
    backdrop-filter: blur(calc(var(--blur-progress) * var(--blur-max))) saturate(calc(1 + var(--blur-progress) * .8));
    -webkit-backdrop-filter: blur(calc(var(--blur-progress) * var(--blur-max))) saturate(calc(1 + var(--blur-progress) * .8));
    border-bottom: 1px solid color-mix(in srgb, var(--line) calc(var(--scroll-progress) * 100%), transparent);
}
/* La fila del header: tres columnas con las laterales iguales (1fr) para que el
   buscador quede centrado de verdad y no corrido por el ancho del logo, como
   pasaría con flex. El max-width de las laterales en 0 deja que se achiquen sin
   desbordar: el logo se reduce con su max-width:100% antes que pisar el buscador. */
.hero-content {
    width: min(100%, var(--container));
    margin: auto;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, var(--search-w)) minmax(0, 1fr);
    align-items: center;
    gap: var(--bar-gap);
}
.brand-link {
    position: relative; display: block; border: 0; background: transparent; outline-offset: 7px;
    text-decoration: none;
    justify-self: start;
    width: var(--logo-w);
    max-width: 100%;
}
.brand-link:focus-visible { outline: 2px solid var(--accent); }
/* El width/height del HTML reserva la proporción antes de que cargue la imagen
   (evita que la página salte); acá se lo deja fluido dentro del botón. */
.brand-logo { display: block; width: 100%; max-width: 100%; height: auto; border-radius: var(--radius-sm); }

/* Botón para alternar modo claro / oscuro: tercera columna de la fila, siempre
   centrado verticalmente (antes era absoluto y perseguía el borde del header). */
.btn-theme-toggle {
    justify-self: end;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    margin: 0;
    line-height: 1;
    width: 40px;
    height: 40px;
    border-radius: var(--radius-round);
    border: 1px solid var(--line);
    background: var(--surface);
    color: var(--text);
    cursor: pointer;
    box-shadow: var(--elev-1);
    transition: background-color var(--dur-fast), border-color var(--dur-fast), transform var(--dur-fast), box-shadow var(--dur-fast);
}
@media (max-width: 600px) {
    .btn-theme-toggle { width: 38px; height: 38px; }
}
.btn-theme-toggle:hover {
    background: var(--surface-soft);
    border-color: var(--line-strong);
    transform: scale(1.06);
}
.btn-theme-toggle:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.btn-theme-toggle svg {
    width: 20px;
    height: 20px;
    display: block;
    flex-shrink: 0;
    margin: auto;
}
html[data-theme="dark"] .theme-icon-sun { display: block; color: #facc15; }
html[data-theme="dark"] .theme-icon-moon { display: none; }
html[data-theme="light"] .theme-icon-sun { display: none; }
html[data-theme="light"] .theme-icon-moon { display: block; color: #6366f1; }

/* (Se fueron .hero-bajada y .theme-hint: la bajada ahora vive solo en la
   portada de bienvenida y .theme-hint no la usaba ningún elemento.) */
/* Montserrat 800 en tamaños de título: el tracking negativo evita que se vea
   suelta y apelmazada, que es lo que pasa con las geométricas pesadas. */
h1, h2, .section-tab-texto strong {
    font-family: var(--font-title); font-weight: var(--peso-title); letter-spacing: -.015em;
}
.card-title, .curso-title, .platform-name {
    font-family: var(--font-title); font-weight: 700; letter-spacing: -.01em;
}

/* 4. BUSCADOR Y BOTONES DEL ENCABEZADO. */
.search-container {
    /* Ocupa la columna del medio del header (su ancho lo capa la grilla con
       --search-w). Fila: el buscador se estira y el botón de filtros (solo en
       celular) va al lado. */
    width: 100%;
    display: flex; align-items: center; gap: .5rem;
    /* Ancla la lupa (ver ::before). */
    position: relative;
}
/* Lupa SIN tocar el HTML: un <input> no admite pseudo-elementos, así que el ícono
   lo pone el contenedor y el input le hace lugar con el padding izquierdo.
   Va como MÁSCARA y no como background-image porque el color de un SVG embebido
   en un data-URI queda incrustado ahí adentro: con mask el color sale de una
   variable del tema y sigue a claro/oscuro y al foco sin duplicar el ícono. */
.search-container::before {
    content: '';
    position: absolute; left: 1.05rem; top: 50%; z-index: 1;
    width: 18px; height: 18px; margin-top: -9px;
    background: var(--muted);
    --icono-lupa: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.8-3.8'/%3E%3C/svg%3E");
    -webkit-mask: var(--icono-lupa) center / contain no-repeat;
    mask: var(--icono-lupa) center / contain no-repeat;
    /* Si no, el click sobre la lupa no enfoca el input que hay debajo. */
    pointer-events: none;
    transition: background var(--dur-base) ease;
}
.search-container:has(.search-input:focus)::before { background: var(--accent); }

/* El buscador es el caso de manual del hundido: parece un pozo tallado en la
   superficie, que es exactamente lo que es un campo donde se escribe. */
.search-input {
    flex: 1; min-width: 0;
    /* El padding izquierdo le deja lugar a la lupa. El text-align explícito
       evita que herede el center del header y centre el placeholder. */
    width: 100%; padding: .9rem 1.2rem .9rem 2.9rem; color: var(--text); background: var(--surface);
    text-align: left;
    /* WCAG 2.1 - 1.4.11: la frontera del campo es lo que lo identifica. */
    border: 1px solid var(--control-line);
    /* Se redondea hasta quedar en forma de píldora al achicarse. */
    border-radius: calc(12px + var(--scroll-progress) * 987px);
    /* Sin sombra: ni la proyectada que crecía con el scroll ni el hundido que la
       reemplazó. El campo se lee por su borde de --line-strong, que es además lo
       que cumple el 3:1 que pide la norma para controles. */
    box-shadow: none;
    transition: box-shadow var(--dur-base) ease, border-color var(--dur-base) ease;
}
/* En foco, borde de acento más un halo. El halo es un anillo plano, no una
   sombra de profundidad: no desplaza ni difumina, solo rodea. El anillo de
   teclado lo sigue poniendo :focus-visible. */
.search-input:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}

/* ---- Dropdown de autocompletado en vivo ---- */
.search-dropdown {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    max-height: min(380px, 60vh);
    overflow-y: auto;
    background: var(--surface);
    /* WCAG 2.1 - 1.4.11: frontera del panel de sugerencias. */
    border: 1px solid var(--control-line);
    border-radius: var(--radius-md);
    box-shadow: var(--elev-3);
    z-index: 60;
    padding: var(--space-2) 0;
    -webkit-overflow-scrolling: touch;
}
.search-dropdown[hidden] {
    display: none !important;
}
.search-dropdown-group-title {
    padding: var(--space-2) var(--space-4);
    font-size: var(--fs-2xs);
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--muted);
    background: var(--surface-soft);
    margin: 0;
}
.search-dropdown-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    min-height: 44px;
    color: var(--text);
    text-decoration: none;
    cursor: pointer;
    font-size: var(--fs-sm);
    line-height: 1.3;
    transition: background var(--dur-fast) ease, color var(--dur-fast) ease;
}
.search-dropdown-item:hover,
.search-dropdown-item.is-selected {
    background: color-mix(in srgb, var(--accent) 12%, var(--surface));
    color: var(--accent-ink);
}
.search-dropdown-item-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.search-dropdown-item-title {
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.search-dropdown-item-sub {
    font-size: var(--fs-2xs);
    color: var(--muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* (Se quitó .search-dropdown-ficha-link: el enlace "Ficha ↗" dentro de las
   sugerencias no era válido para un role="option" —interacción anidada— y la
   ficha se alcanza desde la tarjeta del resultado.) */

.mobile-filter-button {
    min-height: 42px; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .62rem .85rem;
    color: var(--text); background: var(--surface-soft); font-family: var(--font-detail); font-size: var(--fs-base); letter-spacing: .035em;
}
.mobile-filter-button:hover { border-color: var(--accent); color: var(--accent-ink); }
/* Solo aparece en celular (ver breakpoints). No se encoge: es el único acceso
   a los filtros y tiene que sobrevivir a que el buscador se angoste. */
.mobile-filter-button { display: none; flex-shrink: 0; align-items: center; gap: .35rem; white-space: nowrap; }
/* El texto se oculta por opacidad (no display): ocultarlo durante el scroll
   reflotaba el layout del botón en el mismo frame y contribuía a que el header
   se viera bugueado al bajar rápido. Al desvanecer, el botón conserva su ancho. */
.mobile-filter-texto { display: inline; transition: opacity var(--dur-base) ease; }

/* ================================================================
   5. ESTRUCTURA DEL CATÁLOGO
   En computadora: columna izquierda con los filtros y los resultados a la
   derecha. El Copiloto ya no vive en esta columna: es una burbuja flotante
   (ver §10).
   ================================================================ */
.catalog-layout {
    display: grid; 
    grid-template-columns: 280px minmax(0, 1fr); 
    grid-template-areas: 
        "tabs tabs"
        "sidebar results";
    gap: 2.25rem;
    width: min(100% - 3rem, var(--container)); margin: 0 auto; padding: 1.5rem 0 5rem;
}
/* Sin position:sticky a propósito: la columna de filtros es más alta que la
   ventana, y un sticky sobre un bloque más alto que el viewport deja su parte
   de abajo —los filtros— fuera de alcance para siempre. */
.catalog-side { grid-area: sidebar; display: flex; flex-direction: column; gap: var(--space-7); min-width: 0; align-self: start; }
/* En las secciones que no usan filtros (plataformas, formaciones, oficios,
   secundario) la columna izquierda quedaría vacía: se colapsa para que los
   resultados usen todo el ancho. */
.catalog-side:has(#filtersSidebar[hidden]) { display: none; }
.catalog-layout:has(#filtersSidebar[hidden]) { grid-template-columns: 1fr; grid-template-areas: "tabs" "results"; }
.results-area { grid-area: results; min-width: 0; }
/* El header queda fijo arriba (~117px ya compactado), así que cualquier salto a
   la grilla —el skip link y el "Ver mis resultados" del copiloto— tiene que
   frenar antes o las primeras tarjetas quedan tapadas. */
#cardContainer { scroll-margin-top: 110px; }

/* ================================================================
   6. PANEL DE FILTROS
   Estilos de los filtros laterales y de sus opciones.
   ================================================================ */
/* El panel es plano, como todo lo demás: fondo de --surface y borde de --line. */
.filters-sidebar { align-self: start; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; }
.filters-heading { display: flex; align-items: center; justify-content: space-between; padding: 1rem 1rem .8rem; border-bottom: 1px solid var(--line); }
.filters-heading h2 { margin: 0; font-size: var(--fs-md); }
.close-filters-button { display: none; padding: 0; color: var(--muted); background: none; border: 0; font-size: var(--fs-xl); line-height: 1; }
.filter-group { padding: 1rem; border-bottom: 1px solid var(--line); }
.filter-group h3 { margin: 0 0 .55rem; color: var(--text); font-family: var(--font-detail); font-size: var(--fs-md); font-weight: 400; letter-spacing: .045em; }
.filter-options { display: flex; flex-direction: column; align-items: flex-start; gap: .25rem; }
.filter-options-inline { gap: .12rem; }
/* El padding horizontal va en TODAS las opciones, no solo en la activa: si se lo
   pusiera únicamente a la elegida, la lista entera se correría cada vez que
   cambiás de filtro. */
.filter-option {
    width: 100%; min-height: 30px; padding: .28rem .5rem; border: 0; border-radius: var(--radius-sm);
    color: var(--muted); background: transparent;
    text-align: left; font-size: var(--fs-sm);
    /* Los nombres largos (sectores, sobre todo) envuelven en dos líneas. El
       line-height y el display van explícitos porque algunos navegadores no
       heredan el line-height del body a través de `button { font: inherit }`,
       y las líneas terminaban pisándose. */
    display: block; height: auto; line-height: 1.35; overflow-wrap: anywhere;
    transition: color var(--dur-base) ease, background-color var(--dur-base) ease;
}
.filter-option:hover { color: var(--accent-ink); background: color-mix(in srgb, var(--accent) 9%, transparent); }
/* El elegido se tiñe. El fondo y la tinta de acento sostienen solos el estado;
   antes los acompañaba un hundido suave que se fue con el resto del relieve. */
.filter-option.active {
    color: var(--accent-ink); font-weight: 700;
    background: color-mix(in srgb, var(--accent) 14%, var(--surface));
}
/* La marca usa --accent-ink y no --accent a propósito: --accent puro sobre este
   fondo teñido da 2.5:1 en modo claro. --accent-ink es el MISMO verde con la
   luminancia corregida, así que la marca ya es verde (antes era celeste) y además
   se ve. */
/* WCAG 2.1 - 1.4.1 Uso del color: el elegido no se distingue SOLO por el tinte;
   el tilde es una señal de forma además del color y la negrita. */
.filter-option.active::before { content: '✓'; display: inline-block; width: .8rem; font-weight: 700; color: var(--accent-ink); }
.filter-option:not(.active)::before { content: ''; display: inline-block; width: .8rem; }
.filter-options-compact { max-height: 186px; overflow-y: auto; scrollbar-width: thin; }
.duration-range { display: grid; grid-template-columns: 1fr auto 1fr 30px; align-items: center; gap: .35rem; margin-top: .8rem; color: var(--muted); }
.duration-range input { min-width: 0; width: 100%; min-height: 34px; padding: .42rem .35rem; /* WCAG 2.1 - 1.4.11 */ border: 1px solid var(--control-line); border-radius: var(--radius-xs); color: var(--text); background: var(--bg); font-size: var(--fs-2xs); }
.duration-range input:focus { border-color: var(--accent); }
.duration-range button { height: 34px; border: 0; border-radius: var(--radius-xs); color: var(--on-accent); background: var(--blue); font-weight: 800; }
.clear-filters-button { width: calc(100% - 2rem); min-height: 38px; margin: 1rem; padding: .55rem; border: 1px solid var(--line); border-radius: var(--radius-xs); color: var(--muted); background: transparent; font-size: var(--fs-xs); }
.clear-filters-button:hover { border-color: var(--accent); color: var(--accent-ink); }

/* 7. BARRA SOBRE LOS RESULTADOS: cantidad encontrada, selector de orden y las
      tres formas de explorar el catálogo (Carreras / Instituciones / Por área). */
/* Banner hacia la guía de títulos (/titulos/): es el acceso llamativo a las
   diferencias entre licenciatura, tecnicatura, profesorado y posgrado. Solo se
   muestra en Educación Formal: las otras secciones tienen su propio encabezado
   y el banner no aplica. */
.banner-titulos {
    display: none;
    align-items: center; gap: .85rem;
    margin: 0 0 1.1rem;
    padding: .85rem 1rem;
    border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--line));
    border-radius: var(--radius-md);
    background: color-mix(in srgb, var(--accent) 10%, var(--surface));
    color: var(--text); text-decoration: none;
    transition: background-color var(--dur-base) ease, border-color var(--dur-base) ease;
}
body[data-seccion="formal"] .banner-titulos { display: flex; }
.banner-titulos:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 16%, var(--surface)); }
.banner-titulos-icono { display: inline-flex; flex: none; width: 40px; height: 40px; align-items: center; justify-content: center; border-radius: 50%; background: var(--surface); color: var(--accent-ink); }
.banner-titulos-icono svg { width: 22px; height: 22px; }
.banner-titulos-texto { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.banner-titulos-texto strong { font-family: var(--font-title); font-size: var(--fs-base); }
.banner-titulos-texto > span { color: var(--muted); font-size: var(--fs-sm); line-height: 1.35; }
.banner-titulos-corto { display: none; }
.banner-titulos-cta { margin-left: auto; flex: none; color: var(--accent-ink); font-weight: 700; font-size: var(--fs-sm); white-space: nowrap; }
/* En celular la franja se vuelve una píldora compacta: sin ícono ni bajada, con
   el título corto y el CTA reducido a la flecha. Sigue siendo llamativa pero no
   ocupa media pantalla. */
@media (max-width: 600px) {
    body[data-seccion="formal"] .banner-titulos {
        display: inline-flex;
        gap: .35rem;
        padding: .5rem .9rem;
        border-radius: var(--radius-pill);
        margin: 0 0 .85rem;
    }
    .banner-titulos-icono { display: none; }
    .banner-titulos-texto { flex-direction: row; align-items: center; }
    .banner-titulos-texto strong { font-size: var(--fs-sm); }
    .banner-titulos-texto > span { display: none; }
    .banner-titulos-largo { display: none; }
    .banner-titulos-corto { display: inline; }
    .banner-titulos-cta { margin-left: 0; font-size: var(--fs-sm); }
    .banner-titulos-cta-texto { display: none; }
}
.results-toolbar { display: flex; flex-direction: column; gap: .75rem; margin-bottom: 1.25rem; }
.results-toolbar-top { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.results-toolbar-bottom { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
.results-count { margin: 0; color: var(--muted); font-size: var(--fs-base); font-weight: 600; }
/* El ícono recuerda en qué sección está parado el usuario (la barra solo se ve
   en Educación Formal; las plataformas tienen su propio encabezado). Se dibuja
   con una máscara para que herede el color del texto, igual que el resto de los
   íconos SVG de línea del sitio. */
.results-count::before {
    content: '';
    display: inline-block;
    width: 1.05em;
    height: 1.05em;
    margin-right: .4em;
    vertical-align: -.14em;
    background-color: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 10v6M2 10l10-5 10 5-10 5z'/%3E%3Cpath d='M6 12v5c3 3 9 3 12 0v-5'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 10v6M2 10l10-5 10 5-10 5z'/%3E%3Cpath d='M6 12v5c3 3 9 3 12 0v-5'/%3E%3C/svg%3E") center / contain no-repeat;
}
/* Selector persistente de vista: se queda en el medio y el "Ordenar por" se
   pega a la derecha. Al activar "Por área" o "Instituciones" el sort se oculta
   (no hay carreras que ordenar), pero el selector sigue siempre visible. */
.vistas-switcher {
    margin-inline: auto;
    display: inline-flex;
    align-items: center;
    gap: .2rem;
    padding: .25rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--surface-soft);
}
.vistas-switcher-btn {
    border: 0;
    background: transparent;
    color: var(--muted);
    font: inherit;
    font-size: var(--fs-2xs);
    font-weight: 700;
    line-height: 1;
    padding: .5rem .85rem;
    border-radius: 999px;
    cursor: pointer;
    white-space: nowrap;
    transition: background var(--dur-base) ease, color var(--dur-base) ease;
}
.vistas-switcher-btn:hover, .vistas-switcher-btn:focus-visible { color: var(--accent-ink); }
.vistas-switcher-btn.is-active, .vistas-switcher-btn[aria-pressed="true"] {
    /* WCAG 2.1 - 1.4.3: blanco sobre --accent daba 4.47:1 en claro y 2.98:1 en
       oscuro. El par --accion-* mantiene el índigo y pasa en los dos temas. */
    background: var(--accion-fill);
    color: var(--accion-ink);
}
/* WCAG 2.1 - 1.4.1 Uso del color: el estado activo no queda solo en el tinte. */
.vistas-switcher-btn.is-active::before { content: '✓'; margin-right: .3rem; font-weight: 700; }
.sort-control { display: flex; align-items: center; gap: .5rem; color: var(--muted); font-size: var(--fs-xs); white-space: nowrap; }
/* El borde fuerte y la flecha nativa del navegador se quedan intactos: son lo
   que dice "esto se abre", y eso no se negocia por estética. */
.sort-control select {
    min-height: 38px; padding: .5rem .6rem; /* WCAG 2.1 - 1.4.11 */ border: 1px solid var(--control-line);
    border-radius: var(--radius-sm); color: var(--text); background: var(--surface);
    transition: border-color var(--dur-base) ease;
}
.sort-control select:hover { border-color: color-mix(in srgb, var(--accent) 55%, var(--line-strong)); }
.sort-control select:focus { border-color: var(--accent); }

/* ================================================================
   8. TARJETAS DE CARRERAS Y CURSOS
   Cambiá aquí el tamaño, color, bordes y distribución de cada tarjeta.
   ================================================================ */
.results-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(255px, 1fr)); gap: 1rem; }
/* Borde izquierdo azul: marca que la tarjeta es de Educación Formal, en paralelo
   al borde naranja de las tarjetas de plataformas. */
/* Sin min-height: forzaba aire muerto en las tarjetas de título corto y
   desalineaba la grilla. Ahora cada una mide lo que su contenido pide. */
/* --- Familia de cards ---------------------------------------------------------
   .card, .platform-card y .curso-card son la MISMA pieza en distintas
   secciones. Se tratan juntas a propósito: si solo una cambiara de tratamiento,
   cambiar de pestaña mostraría media interfaz rediseñada.

   Planas: fondo de --surface, borde de 1px y nada más. El color de categoría no
   va en un borde grueso a la izquierda sino en la marca chica de --card-tono
   (ver ::before más abajo). */
.card, .platform-card, .curso-card {
    position: relative;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface);
    transition: border-color var(--dur-base) ease;
}
/* La marca de categoría: una barrita corta pegada al borde izquierdo, a la altura
   de la primera línea de contenido. Dice lo mismo que decía el borde de 4px
   (a qué sección pertenece esta card) ocupando una fracción del peso visual. */
.card::before, .platform-card::before, .curso-card::before {
    content: '';
    position: absolute; left: 0; top: var(--space-6);
    width: 3px; height: 26px;
    border-radius: 0 var(--radius-pill) var(--radius-pill) 0;
    background: var(--card-tono, var(--accent));
}
/* En hover la card no se levanta: se le enciende el borde con el color de su
   categoría, que es la misma señal sin movimiento. */
.card:hover, .platform-card:hover, .curso-card:hover {
    border-color: color-mix(in srgb, var(--card-tono, var(--accent)) 45%, var(--line));
}

.card { display: flex; flex-direction: column; padding: var(--space-6); --card-tono: var(--seccion, var(--blue)); }
.card-badges { display: flex; flex-wrap: wrap; gap: var(--space-2); }
/* Los badges se quedan SIN relieve, y es una decisión, no un olvido. Dos razones:
   (1) las sombras neumórficas se derivan de --surface, pero un badge no es
   --surface sino un tinte del color funcional; ponerle sombras de otro material
   encima rompe justo la ilusión que el efecto busca — deja de parecer extruído y
   parece pegoteado. (2) Son seis pastillas de 20px dentro de una card que YA
   tiene relieve: sumarles otro par de sombras a cada una convierte el interior de
   la card en ruido y compite con la jerarquía. El color funcional ya los separa
   del fondo con 4.6:1 o más, que es lo que importa. */
.badge {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .28rem .65rem;
    border-radius: var(--radius-pill);
    color: var(--text);
    background: var(--surface-soft);
    border: 1px solid var(--line);
    font-family: var(--font-text);
    font-size: var(--fs-2xs);
    font-weight: 700;
    letter-spacing: .03em;
    text-transform: uppercase;
    line-height: 1.2;
}
.badge-categoria {
    color: var(--blue-ink);
    background: var(--badge-blue);
    border-color: color-mix(in srgb, var(--blue-ink) 35%, transparent);
}
.badge-publica {
    color: var(--green-ink);
    background: var(--badge-green);
    border-color: color-mix(in srgb, var(--green-ink) 35%, transparent);
}
.badge-privada {
    color: var(--purple-ink);
    background: var(--badge-purple);
    border-color: color-mix(in srgb, var(--purple-ink) 35%, transparent);
}
.badge-modalidad {
    color: var(--teal-ink);
    background: var(--badge-teal);
    border-color: color-mix(in srgb, var(--teal-ink) 35%, transparent);
}
.badge-arancelada {
    color: var(--orange-ink);
    background: var(--badge-orange);
    border-color: color-mix(in srgb, var(--orange-ink) 35%, transparent);
}
.badge-fuente {
    color: var(--purple-ink);
    background: var(--badge-purple);
    border-color: color-mix(in srgb, var(--purple-ink) 35%, transparent);
}
.badge-match {
    /* WCAG 2.1 - 1.4.3: con blanco encima el degradado daba 3.77:1; con tinta
       oscura queda 4.91:1 en el extremo más claro y 7.29:1 en el más oscuro. */
    color: var(--on-vivid);
    background: linear-gradient(135deg, #059669, #10b981);
    border-color: rgba(52, 211, 153, 0.6);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
}
.card-title {
    margin: var(--space-3) 0 var(--space-2);
    font-size: 1.0625rem;
    line-height: 1.35;
    overflow-wrap: anywhere;
}
.card-info {
    color: var(--muted);
    font-size: var(--fs-xs);
    display: flex;
    flex-direction: column;
    gap: .35rem;
    margin-bottom: auto;
}
.card-institucion-row {
    margin: 0;
    font-size: var(--fs-sm);
    color: var(--text);
    display: inline-flex;
    align-items: center;
    gap: .45rem;
}
.card-institucion-row .meta-svg {
    color: var(--accent-ink);
    width: 16px;
    height: 16px;
}
.card-facultad-row {
    margin: 0;
    font-size: var(--fs-2xs);
    color: var(--muted);
    display: inline-flex;
    align-items: center;
    gap: .4rem;
}
.card-facultad-row .meta-svg {
    color: var(--muted);
    width: 14px;
    height: 14px;
}
.card-meta-row {
    margin: .25rem 0 0;
    font-size: var(--fs-xs);
    color: var(--muted);
    display: flex;
    align-items: center;
    gap: .45rem;
    flex-wrap: wrap;
}
.card-meta-row span {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
}
.card-meta-row .meta-svg {
    color: var(--muted);
    width: 14px;
    height: 14px;
}
.card-meta-sep {
    color: var(--line-strong);
    font-weight: 700;
    opacity: .5;
}

/* Iconos vectoriales en tarjetas y botones */
.meta-svg {
    width: 14px;
    height: 14px;
    max-width: 14px;
    max-height: 14px;
    display: inline-block;
    flex-shrink: 0;
    vertical-align: -2px;
}
.badge .meta-svg {
    width: 13px;
    height: 13px;
    max-width: 13px;
    max-height: 13px;
    color: currentColor;
    vertical-align: -1px;
}
.btn-svg {
    width: 14px;
    height: 14px;
    display: inline-block;
    flex-shrink: 0;
    vertical-align: -1px;
    transition: transform var(--dur-fast) ease, fill var(--dur-fast) ease, stroke var(--dur-fast) ease;
}
.card-cta-group {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: var(--space-4);
    padding-top: var(--space-3);
    border-top: 1px solid var(--line);
}
.card-cta-group .card-link-ben {
    margin-top: 0;
}
.card-link-oficial {
    font-size: var(--fs-2xs);
    color: var(--muted);
    text-decoration: none;
    font-weight: 600;
    padding: .35rem .6rem;
    border-radius: var(--radius-xs);
    background: var(--surface-soft);
    transition: color var(--dur-fast), background var(--dur-fast);
}
.card-link-oficial:hover {
    color: var(--text);
    background: color-mix(in srgb, var(--accent) 15%, var(--surface));
}
.card-link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: var(--space-2) 0;
    margin-top: auto;
    color: var(--accent-ink);
    font-size: var(--fs-xs);
    font-weight: 700;
    text-decoration: none;
    line-height: 1.3;
}
.card-link:hover { color: var(--purple-ink); }
.card-info a.link-institucion { color: inherit; text-decoration: none; }
.card-info a.link-institucion:hover { text-decoration: underline; color: var(--accent-ink); }
.instituciones-list a.link-institucion { color: var(--accent-ink); text-decoration: none; }
.instituciones-list a.link-institucion:hover { text-decoration: underline; }
.card-link-muted { color: var(--muted); min-height: 32px; display: inline-flex; align-items: center; }
.card-link-ben {
    color: var(--purple-ink);
    margin-top: auto;
}
.card-link-ben:hover { color: var(--accent-ink); }
.empty-state {
    grid-column: 1 / -1; padding: 3rem 1rem; color: var(--muted);
    text-align: center; font-size: var(--fs-base);
}
/* Ilustración de los estados vacíos. Va por mask-image y no background-image:
   dentro de un data-URI, currentColor no tiene de quién heredar y se resolvía a
   negro, así que en tema oscuro el ícono era invisible. Con máscara, el color lo
   aporta background-color y sí acompaña al tema. */
.empty-state::before {
    content: ""; display: block; width: 72px; height: 72px; margin: 0 auto 1.1rem;
    background-color: currentColor;
    mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%222.5%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Ccircle%20cx%3D%2224%22%20cy%3D%2224%22%20r%3D%229%22%2F%3E%3Cline%20x1%3D%2236%22%20y1%3D%2236%22%20x2%3D%2254%22%20y2%3D%2254%22%2F%3E%3Cline%20x1%3D%222%22%20y1%3D%2238%22%20x2%3D%2214%22%20y2%3D%2238%22%2F%3E%3Cline%20x1%3D%222%22%20y1%3D%2244%22%20x2%3D%2220%22%20y2%3D%2244%22%2F%3E%3Cline%20x1%3D%222%22%20y1%3D%2250%22%20x2%3D%2212%22%20y2%3D%2250%22%2F%3E%3C%2Fsvg%3E");
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%20fill%3D%22none%22%20stroke%3D%22currentColor%22%20stroke-width%3D%222.5%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Ccircle%20cx%3D%2224%22%20cy%3D%2224%22%20r%3D%229%22%2F%3E%3Cline%20x1%3D%2236%22%20y1%3D%2236%22%20x2%3D%2254%22%20y2%3D%2254%22%2F%3E%3Cline%20x1%3D%222%22%20y1%3D%2238%22%20x2%3D%2214%22%20y2%3D%2238%22%2F%3E%3Cline%20x1%3D%222%22%20y1%3D%2244%22%20x2%3D%2220%22%20y2%3D%2244%22%2F%3E%3Cline%20x1%3D%222%22%20y1%3D%2250%22%20x2%3D%2212%22%20y2%3D%2250%22%2F%3E%3C%2Fsvg%3E");
    mask-size: contain; mask-repeat: no-repeat; mask-position: center;
    -webkit-mask-size: contain; -webkit-mask-repeat: no-repeat; -webkit-mask-position: center;
    opacity: .85;
}
.results-suggest {
    grid-column: 1 / -1; margin: 0 0 .25rem; padding: 1rem 1.1rem;
    border: 1px solid var(--line); border-left: 4px solid var(--orange);
    border-radius: var(--radius-lg); background: var(--surface);
    color: var(--text); font-size: var(--fs-base);
}
.results-suggest strong { color: var(--orange-ink); }

.cargar-mas {
    display: block; margin: 1.5rem auto 0; min-height: 44px; padding: .7rem 1.6rem;
    border: 1px solid var(--line); border-radius: var(--radius-pill); background: var(--surface);
    color: var(--accent-ink); font-family: var(--font-text); font-size: var(--fs-base); font-weight: 700;
    cursor: pointer; transition: border-color var(--dur-base) ease, color var(--dur-base) ease, background-color var(--dur-base) ease;
}
.cargar-mas:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, var(--surface)); }

/* ================================================================
   8b. SECCIONES PRINCIPALES: EDUCACIÓN FORMAL vs PLATAFORMAS ONLINE
   Es la primera decisión del usuario. Cada sección tiene su color e ícono,
   y --seccion tiñe todo lo que depende de dónde está parado.
   ================================================================ */
/* --seccion es el relleno/borde; --seccion-ink es su tinta legible. Van siempre
   en pareja, igual que los badges. */
body[data-seccion="formal"]                    { --seccion: var(--blue);   --seccion-ink: var(--blue-ink); }
body[data-seccion="plataformas"]               { --seccion: var(--orange); --seccion-ink: var(--orange-ink); }
body[data-seccion="formaciones-alternativas"]  { --seccion: var(--purple); --seccion-ink: var(--purple-ink); }
body[data-seccion="oficios-tecnicos"]          { --seccion: var(--green);  --seccion-ink: var(--green-ink); }
body[data-seccion="secundario"]                { --seccion: var(--teal);   --seccion-ink: var(--teal-ink); }

.section-tabs {
    grid-area: tabs;
    display: flex; flex-wrap: wrap; gap: .6rem; width: 100%;
    margin: 0 0 var(--space-7);
}
/* Ícono arriba y texto abajo (antes iban lado a lado): en la columna de
   resultados cada pestaña tiene ~165px y compartir el ancho con el ícono le
   dejaba al texto unos 110px, con "Formaciones Alternativas" partida y saliéndose
   de la tarjeta. Apiladas entran las cinco en una sola fila y sin cortes. */
.section-tab {
    display: flex; flex-direction: column; align-items: flex-start; gap: .35rem;
    padding: .75rem .85rem; text-align: left;
    /* Plano: ni borde ni relieve. La pestaña se despega del fondo por su propia
       superficie (--surface contra --bg) y nada más. El borde sigue declarado en
       1px pero transparente para que la geometría no salte cuando la activa sí
       lo pinta. */
    border: 1px solid transparent; border-radius: var(--radius-lg);
    background: var(--surface); color: var(--muted);
    box-shadow: none;
    transition: border-color var(--dur-base) ease, color var(--dur-base) ease,
                background-color var(--dur-base) ease;
}
/* Hover SOLO en las que no están elegidas. Sin relieve que aumentar, el hover
   se nota por la superficie: un escalón de fondo, sin movimiento. */
.section-tab:not(.is-active):hover { background: var(--surface-soft); }
.section-tab-icon { display: inline-flex; line-height: 1; color: var(--muted); transition: color var(--dur-base) ease; }
.section-tab-icon .tab-svg { width: 26px; height: 26px; display: block; }
.section-tab-texto { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.section-tab-texto strong { font-family: var(--font-title); font-size: var(--fs-base); line-height: 1.2; color: var(--text); }
.section-tab-texto small { font-size: var(--fs-2xs); line-height: 1.3; overflow-wrap: anywhere; }

/* INERTES por ahora: la pestaña activa pasó a pintarse con --accent (pedido de
   Fase B), no con el color de su sección. Se dejan porque son el camino de vuelta
   de una línea si preferís recuperar el código de color por sección: alcanza con
   cambiar --accent-ink por --tono-ink y --accent por --tono en .section-tab.is-active.
   El color por sección SIGUE vivo en el resto de la interfaz (--seccion en body). */
.section-tab-formal.is-active       { --tono: var(--blue);   --tono-ink: var(--blue-ink); }
.section-tab-plataformas.is-active  { --tono: var(--orange); --tono-ink: var(--orange-ink); }
.section-tab-formaciones.is-active  { --tono: var(--purple); --tono-ink: var(--purple-ink); }
.section-tab-oficios.is-active      { --tono: var(--green);  --tono-ink: var(--green-ink); }
.section-tab-secundario.is-active   { --tono: var(--teal);   --tono-ink: var(--teal-ink); }
/* Sin relieve, el estado activo lo sostienen el fondo teñido y la tinta de
   acento del título y el ícono. El borde de acento se queda — es el único
   contorno que pinta alguna pestaña, así que no compite con nada. El tiñe sube
   de 10% a 14%: era el relieve lo que hacía de piso del estado y ya no está. */
.section-tab.is-active {
    border-color: var(--tono);
    background: color-mix(in srgb, var(--tono) 14%, var(--surface));
    box-shadow: none;
    transform: none;
}
.section-tab.is-active .section-tab-texto strong { color: var(--tono-ink); }
.section-tab.is-active .section-tab-icon { color: var(--tono-ink); }
.section-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ================================================================
   8c. TARJETAS DE PLATAFORMAS ONLINE
   Una tarjeta por plataforma (no por curso): quién es, qué enseña y
   un botón que lleva a su sitio oficial a ver el catálogo completo.
   ================================================================ */
.platforms-section h2 { margin: 0 0 .4rem; font-size: var(--fs-xl); color: var(--orange-ink); }
.platforms-intro { margin: 0 0 1.4rem; color: var(--muted); font-size: var(--fs-base); }
/* WCAG 2.1 - 1.3.1: los contenedores de tarjetas son <ul>/<li> reales (antes
   eran divs sueltos). Se les quita bullet, margen y padding para que la grilla
   quede exactamente igual. El role="list" va en el HTML porque Safari pierde la
   semántica de lista al apagar el bullet. */
.results-grid, .career-group-grid, .platforms-grid, .cursos-grid,
.results-aviso, #cardContainer { list-style: none; margin: 0; padding: 0; }
.platforms-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); gap: 1rem; }
.platform-card { display: flex; flex-direction: column; padding: 1.15rem; --card-tono: var(--orange); }
.platform-head { display: flex; align-items: center; gap: .7rem; margin-bottom: .7rem; }
/* Espacio del logo: si se agrega la imagen, ocupa este mismo lugar (ver app.js). */
.platform-logo {
    flex: 0 0 auto; width: 44px; height: 44px; border-radius: var(--radius-sm);
    object-fit: contain; background: var(--surface-soft);
}
.platform-logo-vacio {
    display: grid; place-items: center;
    color: var(--orange-ink); font-family: var(--font-title); font-size: var(--fs-xl);
    border: 1px dashed color-mix(in srgb, var(--orange) 45%, transparent);
}
.platform-name { margin: 0; font-size: 1.0625rem; line-height: 1.35; overflow-wrap: anywhere; }
.platform-summary { margin: 0 0 .85rem; color: var(--muted); font-size: var(--fs-sm); line-height: 1.45; }
.platform-meta { display: flex; flex-wrap: wrap; gap: .35rem; margin-bottom: 1rem; }
.platform-link {
    margin-top: auto; padding: .6rem .8rem; border-radius: var(--radius-sm); text-align: center;
    /* WCAG 2.1 - 1.4.3: blanco sobre el naranja daba 2.80:1 en claro. */
    color: var(--on-vivid); background: var(--orange);
    font-size: var(--fs-sm); font-weight: 700; text-decoration: none;
}
.platform-link:hover { background: color-mix(in srgb, var(--orange) 82%, var(--text)); }
.platform-link-muted { color: var(--muted); background: var(--surface-soft); }

/* ================================================================
   8d. CATÁLOGOS APARTE: FORMACIONES ALTERNATIVAS Y OFICIOS TÉCNICOS
   Vista propia por sección, sin los filtros de carreras. El color sale
   de --seccion, que cambia según la pestaña activa.
   ================================================================ */
.catalog-aparte h2 { margin: 0 0 .4rem; font-size: var(--fs-xl); color: var(--seccion-ink); }
.catalog-aparte-intro { margin: 0 0 1.4rem; color: var(--muted); font-size: var(--fs-base); }
.cursos-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(265px, 1fr)); gap: 1rem; }
/* Cuando el catálogo viene agrupado por rubro, el contenedor deja de ser una
   grilla y pasa a ser una columna de grupos: cada grupo trae su encabezado y su
   propia .cursos-grid adentro. Mismo patrón que la vista Instituciones. */
.cursos-grid-agrupado { display: block; }
.rubro-header { display: flex; flex-direction: column; gap: .35rem; align-items: flex-start; margin-bottom: 1rem; }
.rubro-header-title { margin: 0; font-size: var(--fs-lg); color: var(--seccion-ink); }
.rubro-count { font-size: var(--fs-sm); color: var(--muted); }
.grupo-rubro-separado { margin-top: 2.5rem; }
.curso-card { display: flex; flex-direction: column; padding: 1.15rem; --card-tono: var(--seccion); }
.curso-title { margin: var(--space-3) 0 var(--space-2); font-size: 1.0625rem; line-height: 1.35; overflow-wrap: anywhere; }

/* Tarjeta simple (Terminar el Secundario): sin badges arriba, así que el título
   no necesita el margen superior que lo separaba de ellos. */
.curso-card-simple .curso-title { margin-top: 0; margin-bottom: var(--space-1); }
.curso-subtitulo { margin: 0 0 var(--space-3); color: var(--seccion-ink); font-family: var(--font-detail); font-size: var(--fs-base); letter-spacing: .03em; }
.curso-descripcion { margin: 0 0 var(--space-5); color: var(--muted); font-size: var(--fs-sm); line-height: 1.5; }
.badge-seccion { color: var(--seccion-ink); background: color-mix(in srgb, var(--seccion) 22%, transparent); border-color: color-mix(in srgb, var(--seccion-ink) 35%, transparent); }

/* Plataformas que aparecen al buscar dentro de Educación Formal. */
.platform-matches {
    margin-top: 2.25rem; padding-top: 1.35rem;
    border-top: 2px dashed color-mix(in srgb, var(--orange) 45%, transparent);
}
.platform-matches h3 { margin: 0 0 1rem; font-size: var(--fs-lg); color: var(--orange-ink); }

/* 9. SECCIÓN DE NOTICIAS Y SUS TARJETAS. */
/* Borde izquierdo como el resto de las tarjetas: era la única sin acento. */
/* ================================================================
   10. COPILOTO VOCACIONAL (burbuja flotante) Y FONDO DE FILTROS EN CELULAR.
   El copiloto es una burbuja fija en la esquina inferior derecha que abre una
   ventana de chat; en el test guiado (desde la bienvenida) el panel se vuelve
   un fondo oscuro con la página desenfocada y la ventana queda centrada.
   Los filtros en celular siguen siendo un cajón lateral.
   ================================================================ */
.filters-overlay { display: none; }

.copiloto-panel {
    position: fixed; right: 1.25rem; bottom: 1.25rem; z-index: 70;
    display: flex; flex-direction: column; align-items: flex-end; gap: .75rem;
}
.btn-chat-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 60px;
    height: 60px;
    padding: 0;
    overflow: hidden;
    border: 2px solid var(--purple);
    border-radius: var(--radius-round);
    background: var(--surface);
    box-shadow: var(--elev-3);
    cursor: pointer;
    transition: transform var(--dur-base) ease, filter var(--dur-base) ease, box-shadow var(--dur-base) ease;
}
.btn-chat-toggle:hover {
    transform: translateY(-2px) scale(1.06);
    filter: brightness(1.04);
    box-shadow: var(--elev-4);
}
.btn-chat-toggle:focus-visible {
    outline: 2px solid var(--purple);
    outline-offset: 3px;
}
.copiloto-panel.is-abierto .btn-chat-toggle { display: none; }

/* Ventana de chat flotante: la tarjeta que aparece sobre la burbuja. */
.ventana-chat {
    display: flex; flex-direction: column;
    width: min(380px, calc(100vw - 2.5rem));
    height: min(560px, 70vh);
    border: 1px solid var(--line); border-radius: var(--radius-lg);
    background: var(--surface); box-shadow: var(--elev-4); overflow: hidden;
    animation: chat-abrir var(--dur-slow) ease;
}
@keyframes chat-abrir {
    from { opacity: 0; transform: translateY(10px) scale(.98); }
    to   { opacity: 1; transform: none; }
}
/* Test guiado: el panel se vuelve un fondo a pantalla completa con la página
   principal desenfocada atrás, y la ventana de chat queda centrada y acotada
   (antes se llevaba casi toda la pantalla y era demasiado). */
.copiloto-panel.is-test-pantalla-completa {
    inset: 0; z-index: 90; align-items: center; justify-content: center;
    background: rgba(2, 6, 23, .55);
    backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
    transition: opacity var(--dur-slow) ease;
}
.copiloto-panel.is-test-pantalla-completa .btn-chat-toggle { display: none; }
.copiloto-panel.is-test-pantalla-completa .ventana-chat {
    width: min(680px, calc(100vw - 2.5rem));
    height: min(520px, 70vh);
}
/* Test guiado: la ventana es más ancha que un chat común y las preguntas (con
   opciones largas) quedaban pegadas a los bordes y muy justas. El hilo se
   centra, se acota el ancho de lectura y se le da aire arriba y a los costados. */
.copiloto-panel.is-test-pantalla-completa .chat-cuerpo {
    align-items: center;
    padding: 1.15rem 1.25rem 1.35rem;
    gap: .7rem;
}
.copiloto-panel.is-test-pantalla-completa .chat-cuerpo > .mensaje-bot {
    width: 100%;
    max-width: 620px;
    padding: .95rem 1.15rem;
}
.copiloto-panel.is-test-pantalla-completa .chat-cuerpo > .mensaje-usuario {
    max-width: 80%;
}
/* Fade-out al salir del test (lo agrega app.js en salirDelTest). */
.copiloto-panel.is-saliendo-test { opacity: 0; }

.chat-header { display: flex; align-items: center; justify-content: space-between; padding: .8rem .95rem; border-bottom: 1px solid var(--line); font-size: var(--fs-base); font-weight: 700; }
.chat-header button { display: inline-flex; align-items: center; justify-content: center;
    min-width: 44px; min-height: 44px; margin: -.35rem -.5rem -.35rem 0;
    border: 0; border-radius: var(--radius-sm); color: var(--muted); background: none; font-size: var(--fs-md); }
.chat-cuerpo { flex: 1; min-height: 0; padding: .9rem; overflow-y: auto; color: var(--muted); font-size: var(--fs-sm); display: flex; flex-direction: column; gap: .55rem; }

/* Barra de progreso fija del test vocacional (arriba, fuera del scroll) */

/* Burbuja del usuario: a la derecha y con el acento de la sección */
.mensaje-usuario { align-self: flex-end; max-width: 88%; padding: .7rem .85rem; border-radius: var(--radius-md) 12px 3px 12px; background: var(--accent); color: var(--on-accent); line-height: 1.4; }
.mensaje-usuario p { margin: 0; }

/* Sugerencias rápidas que el bot propone como botones */
.chat-sugerencias { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .55rem; }
.btn-chat-sugerencia { min-height: 36px; padding: .4rem .65rem; border: 1px dashed var(--line); border-radius: var(--radius-pill); color: var(--muted); background: transparent; font-size: var(--fs-2xs); transition: border-color var(--dur-base) ease, color var(--dur-base) ease; }
.btn-chat-sugerencia:hover, .btn-chat-sugerencia:focus-visible { border-color: var(--accent); color: var(--accent-ink); }

/* Tarjetas compactas de resultado que el copiloto muestra en el chat, con sus
   acciones operativas (funcionan por delegación). */
.chat-resultados { display: flex; flex-direction: column; gap: .5rem; margin-top: .55rem; }
.chat-resultado-card {
    display: flex; flex-direction: column; gap: .4rem;
    padding: .6rem .75rem; border: 1px solid var(--line); border-radius: var(--radius-md);
    background: var(--surface);
}
.chat-resultado-head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.chat-resultado-nombre { font-weight: 700; color: var(--text); font-size: var(--fs-sm); }
.chat-resultado-card .compatibilidad-badge { font-size: var(--fs-2xs); padding: .1rem .5rem; }
.chat-resultado-acciones { display: flex; flex-wrap: wrap; gap: .4rem; }
.chat-resultado-acciones .tipo-badges { margin: 0; }

/* Barra de progreso del test vocacional */

/* Burbujas de mensaje del bot */
.mensaje-bot { padding: .7rem .85rem; border-radius: var(--radius-md) 12px 12px 3px; background: var(--surface-soft); color: var(--text); }
.mensaje-bot p { margin: 0; line-height: 1.45; }
.mensaje-bot ul { margin: .4rem 0 0; padding-left: 1.15rem; display: flex; flex-direction: column; gap: .3rem; }
.mensaje-bot li { line-height: 1.4; }
.mensaje-bot strong { color: var(--accent-ink); }
.mensaje-bot.final { display: flex; flex-direction: column; gap: .55rem; }
.mensaje-bot-nota { margin: 0; color: var(--muted); font-size: var(--fs-2xs); }

/* Indicador de "escribiendo…" mientras se procesa la respuesta */
.mensaje-escribiendo { display: flex; align-items: center; gap: 4px; width: fit-content; padding: .85rem 1rem; }
.mensaje-escribiendo span { width: 6px; height: 6px; border-radius: var(--radius-round); background: var(--muted); animation: chat-typing 1s infinite ease-in-out; }
.mensaje-escribiendo span:nth-child(2) { animation-delay: .15s; }
.mensaje-escribiendo span:nth-child(3) { animation-delay: .3s; }
@keyframes chat-typing { 0%, 60%, 100% { transform: translateY(0); opacity: .4; } 30% { transform: translateY(-4px); opacity: 1; } }

/* Opciones de respuesta y navegación del test */
.opciones-usuario { display: flex; flex-direction: column; gap: .5rem; margin-top: .75rem; }
.btn-chat-opcion { min-height: 44px; padding: .6rem .75rem; border: 1px solid var(--line); border-radius: var(--radius-sm); color: var(--text); background: var(--surface); font-size: var(--fs-xs); line-height: 1.35; text-align: left; transition: border-color var(--dur-base) ease, background var(--dur-base) ease; }
.btn-chat-opcion:hover, .btn-chat-opcion:focus-visible { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
.btn-chat-atras { display: block; width: 100%; margin-top: .75rem; padding: .4rem; border: 0; color: var(--muted); background: none; font-size: var(--fs-2xs); text-decoration: underline; }
.btn-chat-atras:hover { color: var(--text); }
/* Preguntas ya contestadas: quedan en el chat como transcripcion de lo que
   paso, no como controles. Se apagan (js/copiloto.js las pone disabled) y se
   ven apagadas, para que nadie vuelva a tocarlas esperando que hagan algo. */
.btn-chat-opcion:disabled, .btn-chat-atras:disabled { opacity: .55; cursor: default; }
.btn-chat-opcion:disabled:hover { border-color: var(--line); background: var(--surface); }
.btn-chat-atras:disabled:hover { color: var(--muted); }
/* En el mensaje de bienvenida el botón queda entre párrafos (.mensaje-bot p
   tiene margin: 0), así que necesita su propio aire. */
/* Espaciado del mensaje de resultados del test (notas + tarjetas + reset). */
.mensaje-bot > p + .mensaje-bot-nota,
.mensaje-bot > .mensaje-bot-nota + .chat-resultados,
.mensaje-bot > .chat-resultados + .mensaje-bot-nota,
.mensaje-bot > .mensaje-bot-nota + .btn-chat-reset,
.mensaje-bot > p + .btn-chat-reset { margin-top: var(--space-4); }
.btn-chat-reset { width: 100%; min-height: 40px; padding: .55rem; border: 1px solid var(--line); border-radius: var(--radius-sm); color: var(--text); background: transparent; font-size: var(--fs-xs); }

/* ---- 10b. Portada del copiloto -----------------------------------------
   La bienvenida del chat es la primera pantalla del test, no un mensaje mas:
   ocupa la ventana entera y muestra el proceso en tres pasos en vez de
   explicarlo con un parrafo. Vive dentro de una .mensaje-bot, asi que lo
   primero es sacarle el disfraz de burbuja. */
.mensaje-bot:has(.copiloto-bienvenida) {
    padding: 0; background: none; border-radius: 0;
    /* El contenedor de consulta es el wrapper, no la portada: un elemento no
       puede consultar su propio tamano. La portada se acomoda al ancho REAL
       del modal, no al del viewport, porque la misma pantalla se usa a
       pantalla completa (680px) y en la burbuja flotante (380px). */
    container-type: inline-size;
    container-name: portada-copiloto;
}
/* Con la portada puesta el header queda como cromo minimo: solo la X. El
   titulo se esconde sin salir del arbol de accesibilidad, porque es el que
   nombra la region (aria-labelledby). */
.ventana-chat:has(.copiloto-bienvenida) .chat-header { border-bottom: 0; padding-bottom: 0; }
.ventana-chat:has(.copiloto-bienvenida) #chat-titulo {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap;
}
/* Profundidad: un degradado muy suave de --surface a --surface-soft en vez de
   un plano. */
.ventana-chat:has(.copiloto-bienvenida) {
    background: linear-gradient(163deg, var(--surface) 0%, var(--surface-soft) 100%);
}

.copiloto-bienvenida {
    display: flex; flex-direction: column;
    gap: var(--space-6);
    padding: var(--space-3) var(--space-4) var(--space-4);
    color: var(--text);
}
.cb-svg { width: 100%; height: 100%; display: block; }

/* ---- Header: icono en placa + titulo con subtitulo ---- */
.cb-header { display: flex; align-items: center; gap: var(--space-4); }
.cb-icono {
    flex: none; display: grid; place-items: center;
    width: 48px; height: 48px; padding: 11px;
    border-radius: var(--radius-md);
    color: var(--accent);
    background: color-mix(in srgb, var(--accent) 14%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 26%, transparent);
}
.cb-titulos { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.cb-titulo {
    margin: 0;
    font-family: var(--font-title); font-weight: var(--peso-title);
    font-size: var(--fs-xl); line-height: 1.15; color: var(--text);
    letter-spacing: -.01em;
}
.cb-subtitulo { margin: 0; color: var(--muted); font-size: var(--fs-sm); line-height: 1.3; }

/* ---- Los tres pasos ---- */
.cb-pasos {
    display: grid; gap: var(--space-3);
    margin: 0; padding: 0; list-style: none;
}
.cb-paso {
    display: flex; align-items: flex-start; gap: var(--space-4);
    padding: var(--space-4);
    border: 1px solid var(--line); border-radius: var(--radius-md);
    background: color-mix(in srgb, var(--surface) 55%, transparent);
}
.cb-paso-icono {
    flex: none; display: grid; place-items: center;
    width: 32px; height: 32px; padding: 6px;
    border-radius: var(--radius-sm);
    color: var(--accent);
    background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.cb-paso-cuerpo { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.cb-paso-num {
    font-family: var(--font-detail); font-size: var(--fs-2xs);
    letter-spacing: .09em; text-transform: uppercase; color: var(--muted);
}
.cb-paso-texto { color: var(--text); font-size: var(--fs-sm); line-height: 1.35; }


/* ---- Badge de tiempo: baja la friccion de arrancar ---- */
.cb-tiempo {
    display: inline-flex; align-items: center; align-self: center; gap: var(--space-2);
    margin: 0; padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-pill);
    color: var(--muted); background: color-mix(in srgb, var(--text) 6%, transparent);
    font-size: var(--fs-2xs);
}
.cb-tiempo .cb-svg { width: 14px; height: 14px; flex: none; }

/* ---- Boton principal ---- */
.cb-cta {
    display: flex; align-items: center; justify-content: center; gap: var(--space-3);
    width: 100%; min-height: 52px; padding: var(--space-4) var(--space-5);
    border: 0; border-radius: var(--radius-md);
    /* WCAG 2.1 - 1.4.3: el CTA del copiloto iba en --accent con --on-accent, que
       en claro queda en 4.47:1 (y el degradado lo empeoraba). */
    color: var(--accion-ink);
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--accion-fill) 92%, #fff) 0%, var(--accion-fill) 100%);
    font-family: var(--font-title); font-weight: 700; font-size: var(--fs-md);
    cursor: pointer;
    transition: filter var(--dur-base) ease;
}
.cb-cta .cb-svg { width: 20px; height: 20px; flex: none; transition: transform var(--dur-base) ease; }
/* El botón no se levanta ni proyecta sombra: aclara, y la flecha se corre. El
   movimiento se lo queda la flecha, que es la que indica hacia dónde lleva. */
.cb-cta:hover { filter: brightness(1.04); }
.cb-cta:hover .cb-svg { transform: translateX(3px); }
.cb-cta:active { filter: brightness(.96); }

/* ---- Salida discreta ---- */
.cb-salida {
    align-self: center; min-height: 36px; padding: var(--space-2) var(--space-3);
    border: 0; border-radius: var(--radius-sm);
    color: var(--muted); background: none;
    font-size: var(--fs-xs); text-decoration: underline;
    text-underline-offset: 3px; text-decoration-color: var(--line-strong);
    cursor: pointer;
    transition: color var(--dur-base) ease;
}
.cb-salida:hover, .cb-salida:focus-visible { color: var(--text); }

.cb-aviso-legal {
    margin: var(--space-2) 0 0;
    font-size: var(--fs-2xs);
    color: var(--muted);
    text-align: center;
    line-height: 1.35;
    opacity: 0.85;
}

/* La X del header pasa a tener estado hover propio, en vez de ser un icono
   suelto. Aplica a todo el chat, no solo a la portada. */
.chat-header button {
    border-radius: var(--radius-round);
    transition: color var(--dur-base) ease, background var(--dur-base) ease;
}
.chat-header button:hover, .chat-header button:focus-visible {
    color: var(--text); background: color-mix(in srgb, var(--text) 9%, transparent);
}

/* Modal ancho: los tres pasos pasan a fila, cada uno en columna. Por debajo de
   este ancho quedan apilados, que es el valor por defecto. */
@container portada-copiloto (min-width: 440px) {
    .cb-pasos { grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }
    .cb-paso { flex-direction: column; align-items: flex-start; gap: var(--space-3); }
}

/* Modal angosto (burbuja flotante y celular): se aprieta el aire para que el
   boton principal siga entrando sin scroll. Una pantalla que promete "menos de
   2 minutos" no puede pedir que scrollees para encontrar el boton. */
@container portada-copiloto (max-width: 439px) {
    .copiloto-bienvenida { gap: var(--space-3); padding-bottom: var(--space-3); }
    .cb-icono { width: 44px; height: 44px; padding: 10px; }
    .cb-titulo { font-size: var(--fs-lg); }
    .cb-pasos { gap: var(--space-2); }
    .cb-paso { padding: var(--space-3); gap: var(--space-3); }
    .cb-tiempo { padding: var(--space-1) var(--space-3); }
    .cb-cta { min-height: 48px; padding: var(--space-3) var(--space-4); }
    .cb-salida { min-height: 32px; }
}

@media (prefers-reduced-motion: reduce) {
    .cb-cta, .cb-cta .cb-svg { transition: none; }
    .cb-cta:hover .cb-svg { transform: none; }
}

/* ================================================================
   10b. NOTEBOOKS (hasta 1100px).
   La fila única del header necesita que logo y buscador entren juntos: a partir
   de acá se achican los dos para que el buscador no se coma la columna del logo.
   ================================================================ */
@media (max-width: 1100px) {
    body { padding-top: var(--hero-alto, 110px); }
    .hero {
        --hero-pad-top: 1.5rem;
        --hero-pad-bottom: 1.5rem;
        --logo-w-expandido: 190px;
        --logo-w-compacto: 150px;
        --search-w-expandido: 420px;
        --search-w-compacto: 340px;
        --bar-gap: 1rem;
    }
}

/* ================================================================
   11. DISEÑO PARA TABLETS Y CELULARES (hasta 820px).
   Convierte el filtro lateral en un panel deslizante y deja una tarjeta
   por fila para facilitar la lectura y los toques.
   ================================================================ */
@media (max-width: 820px) {
    body { padding-top: var(--hero-alto, 100px); }
    /* Una sola fila también acá: las laterales pasan a auto y el buscador se
       queda con todo el resto. Desenfoque más chico: en celulares es la
       operación más cara del scroll. */
    .hero {
        --hero-pad-top: 1.25rem;
        --hero-pad-bottom: 1.25rem;
        --hero-pad-compacto: .75rem;
        --logo-w-expandido: 130px;
        --logo-w-compacto: 105px;
        --bar-gap: .5rem;
        --blur-max: 20px;
        padding-inline: 1rem;
    }
    /* El ancho del logo va explícito y no como track `auto`: con `auto`, su
       max-content (que arrastra el max-width:100% de la imagen) se resuelve
       contra el espacio disponible y se come la fila entera. */
    .hero-content { grid-template-columns: var(--logo-w) minmax(0, 1fr) auto; }
    .mobile-filter-button { display: inline-flex; justify-content: center; min-width: 44px; min-height: 44px; }
    /* Compactado queda poco ancho al lado del logo: se deja solo el ícono. El
       texto se desvanece (opacity) sin tocar el layout, para no reflotar el
       botón en el mismo frame del encogido. */
    .hero--compacto .mobile-filter-texto { opacity: 0; }
    
    .catalog-layout {
        display: grid;
        grid-template-columns: 1fr;
        grid-template-areas:
            "tabs"
            "results";
        gap: 1.5rem;
        width: min(100% - 2rem, var(--container));
        margin: 0 auto;
        padding: 1rem 0 4rem;
    }
    .catalog-side {
        display: contents;
    }
    /* z-index por encima del header fijo (.hero, z-index 40): si se scrollea y se abre
       el panel de filtros, tiene que taparlo, no quedar debajo. */
    .filters-sidebar { position: fixed; z-index: 45; top: 0; bottom: 0; left: 0; width: min(320px, 85vw); height: 100dvh; max-height: 100dvh; padding-bottom: calc(1rem + env(safe-area-inset-bottom)); overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; touch-action: pan-y; border-radius: 0 var(--radius-lg) var(--radius-lg) 0; transform: translateX(-105%); transition: transform var(--dur-slow) ease; scrollbar-color: var(--accent) var(--surface); scrollbar-width: thin; }
    .filters-heading { position: sticky; z-index: 2; top: 0; background: color-mix(in srgb, var(--surface) 94%, transparent); backdrop-filter: blur(10px); }
    .filters-open .filters-sidebar { transform: translateX(0); }
    .filters-overlay { position: fixed; z-index: 42; inset: 0; background: rgba(2, 6, 23, .72); opacity: 0; transition: opacity var(--dur-slow) ease; pointer-events: none; }
    .filters-open .filters-overlay { display: block; opacity: 1; pointer-events: auto; }
    .filters-open { overflow: hidden; }
    .close-filters-button { display: block; min-width: 44px; min-height: 44px; }
    .results-grid, .platforms-grid, .cursos-grid, .career-group-grid { grid-template-columns: 1fr; }
    .card { min-height: 0; }
    /* Optimización móvil agresiva: touch targets mínimos de 44px garantizados en móvil */
    .filter-option {
        min-height: 44px;
        display: flex;
        align-items: center;
        padding: .5rem .85rem;
    }
    .duration-range button, .duration-range input,
    .btn-escuchar-card, .clear-filters-button,
    .btn-chat-sugerencia, .sort-control select,
    .card-link, .platform-link {
        min-height: 44px;
    }
    .card-actions button {
        min-height: 44px;
        padding: .5rem .75rem;
    }
    .duration-range {
        grid-template-columns: 1fr auto 1fr 44px;
    }
    .card-link-ben + .card-link,
    .card-link-ben + span.card-link {
        margin-top: var(--space-2);
    }
    .section-tabs {
        display: flex;
        flex-wrap: nowrap;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        padding: 0.25rem 0.25rem 0.75rem;
        margin-bottom: var(--space-4);
        scrollbar-width: none;
        -ms-overflow-style: none;
        -webkit-overflow-scrolling: touch;
        gap: 0.6rem;
        width: 100%;
    }
    .section-tabs::-webkit-scrollbar { display: none; }
    .section-tabs .section-tab {
        flex: 0 0 210px;
        scroll-snap-align: start;
    }
    /* La burbuja y la ventana del copiloto se acercan al borde y la ventana
       pierde un poco de alto en pantallas chicas. */
    .copiloto-panel { right: .9rem; bottom: .9rem; }
    .ventana-chat { height: min(500px, 62vh); }
}

/* ================================================================
   11b. DESKTOP (desde 821px): el copiloto vocacional es un poco más
   grande. En tablets y celulares (hasta 820px) se mantienen los
   tamaños acotados de arriba.
   ================================================================ */
@media (min-width: 821px) {
    .ventana-chat { width: min(420px, calc(100vw - 2.5rem)); height: min(600px, 76vh); }
    .copiloto-panel.is-test-pantalla-completa .ventana-chat {
        width: min(820px, calc(100vw - 2.5rem));
        height: min(620px, 80vh);
    }
}

/* ================================================================
   12. DISEÑO PARA CELULARES PEQUEÑOS (hasta 480px).
   Ajusta espacios, botones y controles para pantallas angostas.
   ================================================================ */
@media (max-width: 480px) {
    body { padding-top: var(--hero-alto, 90px); }
    .hero {
        --hero-pad-top: 1rem;
        --hero-pad-bottom: 1rem;
        --hero-pad-compacto: .65rem;
        --logo-w-expandido: 100px;
        --logo-w-compacto: 85px;
        --bar-gap: .4rem;
        --blur-max: 16px;
        padding-inline: 1rem;
    }
    /* El botón de filtros se queda solo con el ícono: en 360px cada píxel de la
       fila cuenta y ese ancho se lo lleva el buscador. */
    .mobile-filter-texto { display: none; }
    /* El padding izquierdo NO baja a 1rem: la lupa sigue estando y el texto le
       quedaba encima. Solo se ajusta lo demás. */
    .search-input { min-height: 44px; padding: .75rem 1rem .75rem 2.6rem; font-size: var(--fs-sm); }
    .search-container::before { left: .85rem; width: 16px; height: 16px; margin-top: -8px; }
    /* El de filtros vive en la fila del buscador y conserva su ancho propio. */
    .mobile-filter-button { padding-inline: .6rem; font-size: var(--fs-xs); }
    
    .catalog-layout {
        width: min(100% - 1.5rem, var(--container));
        gap: 1rem;
        padding: 0.75rem 0 3.5rem;
    }
    
    .section-tabs .section-tab {
        flex: 0 0 185px;
        padding: .7rem .8rem;
    }
    .section-tab-texto strong { font-size: var(--fs-sm); }
    .section-tab-icon .tab-svg { width: 22px; height: 22px; }

    .results-toolbar {
        align-items: stretch;
        flex-direction: column;
        gap: .65rem;
        margin-bottom: 1rem;
    }
    .results-count {
        font-size: var(--fs-sm);
        line-height: 1.35;
    }
    .results-toolbar-top, .results-toolbar-bottom { width: 100%; }
    .vistas-switcher { width: 100%; justify-content: center; }
    .toolbar-actions {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: .5rem;
        width: 100%;
    }
    /* El reparto de esta fila lo manda el <select>: entre el rótulo "Ordenar
       por" y el selector, en ~88px la opción activa se leía cortada
       ("Predeterm…") y en celular no había forma de saber cómo estaba ordenada
       la grilla. Ahora el select reserva lo suyo. */
    /* En 375px no entran "Ordenar por" + el selector: se esconde el rótulo, que
       es el más prescindible de los dos —las propias opciones dicen que eso
       ordena—, pero se esconde VISUALMENTE: sigue en el árbol de accesibilidad
       como nombre del <select>. */
    .sort-control-label {
        position: absolute;
        width: 1px; height: 1px;
        margin: -1px; padding: 0; border: 0;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }
    .sort-control {
        flex: 0 1 auto;
        min-width: 0;
        justify-content: flex-end;
        white-space: nowrap;
        font-size: var(--fs-2xs);
    }
    .sort-control select {
        flex: 0 0 auto;
        min-width: 8.5rem;
        max-width: 11rem;
        font-size: var(--fs-xs);
        padding: .4rem .5rem;
    }
    .card { padding: var(--space-4); }
    .card-title { font-size: var(--fs-md); }
    .filter-group { padding: .9rem 1rem; }
    .copiloto-panel { right: .75rem; bottom: .75rem; }
    .btn-chat-toggle { width: 52px; height: 52px; font-size: 1.25rem; }
    .chat-header { padding: .6rem .75rem; font-size: var(--fs-xs); }
    .chat-cuerpo { padding: .6rem; font-size: var(--fs-2xs); gap: .4rem; }
}

/* 13. CELULARES MUY ANGOSTOS (hasta 360px): evita que los botones se corten. */
@media (max-width: 360px) {
    .toolbar-actions { flex-direction: column; align-items: stretch; }
    .sort-control { width: 100%; justify-content: space-between; }
    .sort-control select { max-width: none; width: 60%; }
}

/* ================================================================
   14. BOTONES DE TARJETA
   El botón "Escuchar" nace oculto y solo se muestra cuando el usuario
   activa la lectura en voz alta desde accesibilidad.js.
   ================================================================ */
.toolbar-actions { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.results-toolbar .toolbar-actions[hidden] { display: none; }

.card-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .45rem;
    margin-top: auto;
    padding-top: var(--space-4);
    width: 100%;
}
.btn-escuchar-card {
    flex: 1 1 calc(50% - .25rem);
    min-width: 0;
    display: inline-flex; align-items: center; justify-content: center; gap: .35rem;
    min-height: 36px; padding: .4rem .5rem; border: 1px solid var(--line);
    border-radius: var(--radius-sm); color: var(--muted); background: var(--surface-soft);
    font-family: var(--font-text); font-size: var(--fs-2xs); font-weight: 700; cursor: pointer;
    white-space: nowrap; text-overflow: ellipsis; overflow: hidden;
    transition: border-color var(--dur-base) ease, color var(--dur-base) ease, background var(--dur-base) ease;
}
.btn-escuchar-card:hover { border-color: var(--accent); color: var(--accent-ink); }

.btn-escuchar-card { display: none; }
html[data-tts="true"] .btn-escuchar-card {
    display: inline-flex;
    flex: 1 1 100%;
}


/* ================================================================
   15. PREFERENCIAS DEL SISTEMA
   Van al final a propósito: las media queries no suman especificidad, así que
   para ganarle a reglas como `.filter-option { min-height: 30px }` tienen que
   venir después en el archivo.
   ================================================================ */
/* Movimiento reducido. Lo que más se mueve en la página es el header, que se
   achica y gana un blur de hasta 34px en cada cuadro del scroll. Con esta
   preferencia activa se congela en su estado compacto: --scroll-progress queda
   fijo en 1 y no hay nada que animar (el header ya es una sola fila estable). */
@media (prefers-reduced-motion: reduce) {
    :root { --scroll-progress: 1; --blur-progress: 0; }
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
    /* Las cards, las pestañas y los botones ya no se levantan en hover — el
       relieve se sacó de todo el sitio, así que no queda transform que anular.
       El único que sobrevive es la burbuja del chat, que sí flota. */
    .btn-chat-toggle:hover { transform: none; }
}

/* Área táctil mínima de 44px donde se toca con el dedo. Se decide por tipo de
   puntero y no por ancho: un tablet grande también se toca, y en escritorio con
   mouse llevar todo a 44px estiraría de más la lista de filtros. */
@media (pointer: coarse) {
    .filter-option { min-height: 44px; }
    .duration-range button, .duration-range input,
    .btn-escuchar-card, .clear-filters-button,
    .btn-chat-sugerencia, .sort-control select,
    .card-link, .platform-link { min-height: 44px; }
    .duration-range { grid-template-columns: 1fr auto 1fr 44px; }
}
/* ================================================================
   ORIENTADOR VOCACIONAL - Estilos para tarjetas de compatibilidad
   ================================================================ */

.carrera-card {
    position: relative;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--surface);
    padding: var(--space-5);
    transition: border-color var(--dur-base);
}
.carrera-card:hover {
    border-color: color-mix(in srgb, var(--accent) 45%, var(--line));
}

/* Badge de compatibilidad */
.compatibilidad-badge {
    font-size: var(--fs-sm);
    font-weight: 700;
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-pill);
    display: inline-block;
}
/* WCAG 2.1 - 1.4.3: blanco sobre el verde daba 3.77:1 y sobre el naranja 2.80:1
   en tema claro; --on-vivid (tinta oscura) deja 4.91:1 / 6.59:1 y también pasa en
   oscuro. El badge "bajo" usa --on-muted porque --text sobre --muted daba 3.03:1
   en claro y 2.34:1 en oscuro. */
.carrera-card.match-alto .compatibilidad-badge, .chat-resultado-card.match-alto .compatibilidad-badge { background: var(--green); color: var(--on-vivid); }
.carrera-card.match-medio .compatibilidad-badge, .chat-resultado-card.match-medio .compatibilidad-badge { background: var(--orange); color: var(--on-vivid); }
.carrera-card.match-bajo .compatibilidad-badge, .chat-resultado-card.match-bajo .compatibilidad-badge { background: var(--muted); color: var(--on-muted); }

/* Badges de tipo de formación */
.tipo-badge {
    font-size: var(--fs-2xs);
    font-weight: 700;
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-xs);
    display: inline-block;
    margin-right: var(--space-2);
    margin-bottom: var(--space-2);
}
.tipo-badge.grado { background: var(--blue); color: var(--on-accent); }
.tipo-badge.tecnica { background: var(--purple); color: var(--on-purple); }
/* WCAG 2.1 - 1.4.3: blanco sobre el teal daba 3.74:1 en claro. */
.tipo-badge.curso { background: var(--teal); color: var(--on-vivid); }

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: var(--space-3);
    gap: var(--space-3);
}
.card-header h3 {
    margin: 0;
    font-size: var(--fs-lg);
    line-height: 1.3;
    flex: 1;
}

.card-match-motivos {
    margin-bottom: var(--space-3);
    font-size: var(--fs-sm);
}
.card-match-motivos strong {
    display: block;
    margin-bottom: var(--space-2);
    color: var(--text);
}
.motivos-list {
    margin: 0;
    padding-left: var(--space-5);
    color: var(--muted);
}
.motivos-list li {
    margin-bottom: var(--space-1);
    line-height: 1.4;
}

.card-alertas {
    background: rgba(255, 84, 0, 0.1);
    border: 1px solid var(--orange);
    border-radius: var(--radius-sm);
    padding: var(--space-3);
    margin-bottom: var(--space-3);
    font-size: var(--fs-sm);
}
.card-alertas strong {
    color: var(--orange);
    display: block;
    margin-bottom: var(--space-2);
}
.alertas-list {
    margin: 0;
    padding-left: var(--space-5);
    color: var(--muted);
}
.alertas-list li {
    margin-bottom: var(--space-1);
    line-height: 1.4;
}

.card-instituciones {
    margin-bottom: var(--space-3);
    font-size: var(--fs-sm);
}
.card-instituciones strong {
    display: block;
    margin-bottom: var(--space-2);
    color: var(--text);
}
.instituciones-list {
    margin: 0;
    padding-left: var(--space-5);
    color: var(--muted);
}
.instituciones-list li {
    margin-bottom: var(--space-1);
    line-height: 1.4;
}

.card-actions {
    display: flex;
    gap: var(--space-2);
    justify-content: flex-end;
    padding-top: var(--space-3);
    border-top: 1px solid var(--line);
}
.card-actions button {
    background: none;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: var(--space-2) var(--space-3);
    font-size: var(--fs-sm);
    cursor: pointer;
    color: var(--text);
    transition: background var(--dur-fast), border-color var(--dur-fast);
}
.card-actions button:hover {
    background: var(--surface-soft);
    border-color: var(--accent);
}

/* Progreso del test */
/* Chat mejoras */
.mensaje-bot-nota {
    font-size: var(--fs-xs);
    color: var(--muted);
    font-style: italic;
    margin-top: var(--space-2);
}
.opciones-usuario {
    display: flex;
    flex-direction: column;
    gap: .55rem;
    margin: var(--space-3) 0 0;
}
.btn-chat-opcion {
    min-height: 44px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    padding: .7rem .9rem;
    font-size: var(--fs-sm);
    line-height: 1.4;
    text-align: left;
    cursor: pointer;
    transition: border-color var(--dur-base) ease, background var(--dur-base) ease;
    color: var(--text);
}
.btn-chat-opcion:hover {
    border-color: var(--accent);
    background: var(--surface-soft);
}
.btn-chat-atras {
    background: none;
    border: none;
    color: var(--muted);
    font-size: var(--fs-sm);
    cursor: pointer;
    padding: var(--space-2) 0;
    margin-top: var(--space-2);
}
.btn-chat-atras:hover {
    color: var(--text);
}
.btn-chat-reset {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    padding: var(--space-2) var(--space-4);
    font-size: var(--fs-sm);
    cursor: pointer;
    margin-right: var(--space-2);
    margin-top: var(--space-2);
    transition: all var(--dur-fast);
}
.btn-chat-reset:hover {
    border-color: var(--accent);
    background: var(--surface-soft);
}

@media (max-width: 600px) {
    .card-header {
        flex-direction: column;
        align-items: flex-start;
    }
    .card-actions {
        flex-wrap: wrap;
    }
}

/* ================================================================
   16. PANTALLA DE BIENVENIDA
   Overlay fijo a pantalla completa: la puerta de entrada al sitio.
   El logo y las dos opciones entran con fade + slide escalonado
   (cada elemento con su propio delay, todo CSS puro). El
   ocultamiento lo maneja app.js: agrega .is-saliendo y, al
   terminar la transición, el atributo hidden.
   ================================================================ */
.pantalla-bienvenida {
    position: fixed;
    inset: 0;
    z-index: 80;
    display: grid;
    place-items: center;
    padding: 2rem;
    background:
        radial-gradient(circle at 50% -35%, color-mix(in srgb, var(--purple) 24%, transparent) 0, transparent 58%),
        linear-gradient(180deg, var(--surface) 0%, var(--bg) 100%);
    animation: bienvenida-entrar var(--dur-slow) ease;
}
@keyframes bienvenida-entrar {
    from { opacity: 0; }
    to   { opacity: 1; }
}
/* Salida: fade + subida leve. El fade de entrada no usa fill-mode,
   así que al terminar la animación la opacidad vuelve a la normal
   (1) y la transición de salida no queda bloqueada. */
.pantalla-bienvenida.is-saliendo {
    opacity: 0;
    transform: translateY(-12px);
    transition: opacity var(--dur-slow) ease, transform var(--dur-slow) ease;
}

.bienvenida-contenido {
    width: min(100%, 720px);
    text-align: center;
}
.bienvenida-logo {
    display: block;
    width: min(100%, 480px);
    height: auto;
    margin: 0 auto var(--space-6);
    border-radius: var(--radius-sm);
    animation: bienvenida-deslizar var(--dur-slow) ease backwards;
}
.bienvenida-bajada {
    margin: 0 0 var(--space-7);
    color: var(--muted);
    font-family: var(--font-detail);
    font-size: var(--fs-sm);
    letter-spacing: .08em;
    text-transform: uppercase;
    animation: bienvenida-deslizar var(--dur-slow) ease backwards;
    animation-delay: .06s;
}
/* Dos tarjetas, un camino cada una: el orientador (violeta, con el ícono del
   copiloto) y el catálogo completo (neutra). Entran con delay respecto al logo
   y se asientan con un slide corto. */
.bienvenida-opciones {
    display: flex;
    align-items: stretch;
    justify-content: center;
    gap: var(--space-5);
    flex-wrap: wrap;
}
.bienvenida-card {
    flex: 1 1 42%;
    /* Con min-width, si las dos tarjetas no entran lado a lado (tablet chica),
       envuelven solas sin media query. */
    min-width: min(100%, 300px);
    display: flex;
    align-items: center;
    gap: var(--space-5);
    min-height: 132px;
    padding: var(--space-6);
    border: 2px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface);
    color: var(--text);
    text-align: left;
    cursor: pointer;
    animation: bienvenida-deslizar var(--dur-slow) ease backwards;
    animation-delay: .12s;
    transition: background-color var(--dur-base) ease, border-color var(--dur-base) ease;
}
.bienvenida-card-primaria {
    border-color: var(--purple);
    background: color-mix(in srgb, var(--purple) 12%, var(--surface));
}
/* Sin levantarse: en hover se profundiza el tinte violeta que ya tiene. */
.bienvenida-card-primaria:hover {
    background: color-mix(in srgb, var(--purple) 20%, var(--surface));
}
.bienvenida-card-secundaria { animation-delay: .2s; }
.bienvenida-card-secundaria:hover { border-color: var(--accent); background: var(--surface-soft); }

/* Ícono de la tarjeta del catálogo: mismo círculo, sin la sombra del ícono del
   copiloto (que es una imagen con volumen propio). */
.bienvenida-icono-catalogo {
    background: var(--surface-soft);
    border: 1px solid var(--line);
    box-shadow: none;
    color: var(--accent-ink);
}
.bienvenida-icono-catalogo svg { width: 34px; height: 34px; }
.bienvenida-icono {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 66px;
    height: 66px;
    border-radius: var(--radius-round);
    background: transparent;
    overflow: hidden;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.bienvenida-copiloto-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.chat-titulo-img {
    width: 24px;
    height: 24px;
    object-fit: cover;
    border-radius: 50%;
    vertical-align: middle;
    margin-right: 0.4rem;
}
/* Chapa "Beta" del Copiloto Vocacional: avisa que la función está en prueba. */
.badge-beta {
    display: inline-block;
    margin-left: .45rem;
    padding: .1rem .45rem;
    border-radius: var(--radius-pill);
    vertical-align: middle;
    font-family: var(--font-text);
    font-size: var(--fs-2xs);
    font-weight: 700;
    line-height: 1.4;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--accent-ink);
    background: color-mix(in srgb, var(--accent) 16%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 42%, transparent);
}
.chat-bot-icon {
    width: 18px;
    height: 18px;
    object-fit: cover;
    border-radius: 50%;
    vertical-align: -3px;
    margin-right: 5px;
    display: inline-block;
}
.btn-chat-icono-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 50%;
    display: block;
}
.bienvenida-card-texto { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.bienvenida-card strong { font-family: var(--font-title); font-size: var(--fs-xl); line-height: 1.2; letter-spacing: -.015em; color: var(--text); }
.bienvenida-card-desc { color: var(--muted); font-size: var(--fs-sm); line-height: 1.5; }
.bienvenida-cta { color: var(--purple-ink); font-size: var(--fs-xs); font-weight: 700; }
.bienvenida-card-secundaria .bienvenida-cta { color: var(--accent-ink); }
/* En pantallas angostas las dos opciones se apilan. */
@media (max-width: 480px) {
    .pantalla-bienvenida { padding: 1.5rem; }
    .bienvenida-logo { width: min(100%, 320px); }
    .bienvenida-opciones { flex-direction: column; align-items: stretch; }
    .bienvenida-card { flex-direction: column; text-align: center; }
}

/* ================================================================
   16b. TUTORIAL DE PRIMERA VISITA
   Un foco sobre el elemento real (el resto se oscurece con el box-shadow) y una
   tarjeta que lo explica. El contenido lo pinta js/tutorial.js; acá vive el
   aspecto. z-index 82: arriba de la portada (80) y debajo del botón de
   accesibilidad (85), que tiene que seguir alcanzable.
   ================================================================ */
/* Mismo bloqueo de scroll que la portada: el tour centra cada objetivo solo. */
html.tutorial-abierto, html.tutorial-abierto body { overflow: hidden; }
.tutorial { position: fixed; inset: 0; z-index: 82; }
/* El "agujero" iluminado: la caja no tiene fondo y su sombra enorme oscurece
   todo lo demás. Sin clip-path ni capas extra. */
.tutorial-foco {
    position: fixed;
    border-radius: 14px;
    box-shadow: 0 0 0 100vmax rgba(2, 6, 23, .62);
    pointer-events: none;
    transition: top var(--dur-base) ease, left var(--dur-base) ease,
                width var(--dur-base) ease, height var(--dur-base) ease;
}
.tutorial-card {
    position: fixed;
    z-index: 1;
    width: min(400px, calc(100vw - 2rem));
    max-height: min(70vh, 420px);
    overflow-y: auto;
    padding: var(--space-6);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--elev-3);
}
.tutorial-paso {
    margin: 0 0 var(--space-2);
    color: var(--accent-ink);
    font-family: var(--font-detail);
    font-size: var(--fs-2xs);
    letter-spacing: .08em;
    text-transform: uppercase;
}
.tutorial-titulo {
    margin: 0 0 var(--space-3);
    font-size: var(--fs-lg);
    color: var(--text);
    outline: none;
}
.tutorial-texto { margin: 0; color: var(--muted); font-size: var(--fs-base); line-height: 1.55; }
/* Paso de cierre (sin objetivo): la tarjeta va centrada. En celular se queda
   abajo como el resto, que es donde el pulgar la espera. */
@media (min-width: 821px) {
    .tutorial-card-centrada { left: 50%; top: 50%; transform: translate(-50%, -50%); }
}
.tutorial-acciones { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-top: var(--space-5); }
.tutorial-acciones-fin { display: flex; gap: var(--space-3); }
.tutorial-btn {
    min-height: 40px;
    padding: .5rem 1rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: var(--fs-xs);
    font-weight: 600;
    cursor: pointer;
}
.tutorial-btn:hover { border-color: var(--line-strong); background: var(--surface-soft); }
.tutorial-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tutorial-btn-primario { border-color: transparent; background: var(--accion-fill); color: var(--accion-ink); }
.tutorial-btn-primario:hover { background: var(--accion-fill); filter: brightness(1.08); }
/* En celular la tarjeta se fija abajo a lo ancho: anclarla al objetivo dejaría
   el texto peleando con el teclado y con el borde de la pantalla. Cuando el
   objetivo está en la mitad de abajo (las tarjetas del catálogo, el botón del
   copiloto) el mensaje sube: js/tutorial.js agrega .tutorial-card-arriba y acá
   se lo deja debajo del header fijo, que si no lo taparía. */
@media (max-width: 820px) {
    .tutorial-card {
        left: 1rem; right: 1rem; bottom: 1rem;
        width: auto;
        top: auto !important;
        max-height: 45vh;
    }
    .tutorial-card-arriba {
        top: calc(var(--hero-alto, 90px) + .5rem) !important;
        bottom: auto;
    }
}

/* ================================================================
   17. ACCESIBILIDAD (A11Y) - WCAG 2.1 AA/AAA
   Botón flotante, panel de configuración, alto contraste,
   resaltado de enlaces y lector de voz.
   ================================================================ */

/* Botón flotante de accesibilidad (Esquina inferior izquierda) */
.a11y-widget {
    position: fixed;
    bottom: 1rem;
    left: 1rem;
    /* WCAG 2.1 - 1.4.4 / 2.1.1: con z-index 70 la portada (80) tapaba el botón:
       con mouse o touch no había forma de abrir el panel en la primera pantalla
       (solo con Alt+A, porque el panel tiene z-index 95). Queda por encima de la
       portada y por debajo de los diálogos del test (100) y Mi lista (110). */
    z-index: 85;
}
.btn-a11y-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    border: 2px solid var(--accent);
    border-radius: var(--radius-round);
    background: var(--surface);
    color: var(--accent);
    cursor: pointer;
    box-shadow: var(--elev-3);
    transition: transform var(--dur-base) ease, background var(--dur-base) ease, color var(--dur-base) ease;
}
.a11y-btn-svg {
    width: 34px;
    height: 34px;
    display: block;
    color: currentColor;
    transition: transform var(--dur-base) ease;
}
.a11y-title-svg {
    width: 26px;
    height: 26px;
    display: block;
    color: var(--accent);
    flex-shrink: 0;
}
.btn-a11y-toggle:hover {
    transform: scale(1.08);
    background: var(--accent);
    color: var(--on-accent);
}
.btn-a11y-toggle:hover .a11y-btn-svg {
    transform: scale(1.05);
}
.btn-a11y-toggle:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 3px;
}

/* Panel Modal de Accesibilidad */
.a11y-panel {
    position: fixed;
    inset: 0;
    z-index: 95;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}
.a11y-panel[hidden] {
    display: none !important;
}
.a11y-overlay {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.65);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}
.a11y-panel-card {
    position: relative;
    z-index: 2;
    width: min(100%, 460px);
    max-height: 90vh;
    overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--elev-4);
    display: flex;
    flex-direction: column;
}
.a11y-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1.25rem 1.5rem;
    border-bottom: 1px solid var(--line);
}
.a11y-titulo {
    margin: 0;
    font-size: var(--fs-lg);
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.a11y-close-btn {
    /* WCAG 2.5.8: el ✕ del panel tiene que llegar a 24x24 de área táctil. */
    min-width: 24px; min-height: 24px;
    padding: 0.25rem 0.5rem;
    background: transparent;
    border: 0;
    color: var(--muted);
    font-size: var(--fs-xl);
    line-height: 1;
    border-radius: var(--radius-xs);
    cursor: pointer;
}
.a11y-close-btn:hover {
    color: var(--text);
    background: var(--surface-soft);
}
.a11y-body {
    padding: 1.25rem 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}
.a11y-grupo {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.a11y-label {
    font-size: var(--fs-xs);
    font-weight: 700;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.a11y-opciones-fuente {
    display: flex;
    gap: 0.5rem;
}
.a11y-btn-font {
    flex: 1;
    padding: 0.6rem 0.5rem;
    background: var(--surface-soft);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    color: var(--text);
    font-weight: 700;
    font-size: var(--fs-md);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    cursor: pointer;
    transition: all var(--dur-base) ease;
}
.a11y-btn-font span {
    font-size: var(--fs-2xs);
    font-weight: 400;
    color: var(--muted);
}
.a11y-btn-font:hover {
    border-color: var(--accent);
}
.a11y-btn-font.is-active {
    background: color-mix(in srgb, var(--accent) 15%, var(--surface));
    border-color: var(--accent);
    color: var(--accent-ink);
}
.a11y-btn-font.is-active span {
    color: var(--accent-ink);
    font-weight: 600;
}

/* Switch toggles */
.a11y-switch-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 0.9rem;
    background: var(--surface-soft);
    border-radius: var(--radius-md);
    cursor: pointer;
    user-select: none;
    gap: 1rem;
}
.a11y-switch-text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}
.a11y-switch-text strong {
    font-size: var(--fs-sm);
    color: var(--text);
}
.a11y-switch-text small {
    font-size: var(--fs-2xs);
    color: var(--muted);
}
.a11y-switch-input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}
.a11y-switch-slider {
    position: relative;
    flex: 0 0 46px;
    height: 26px;
    background-color: color-mix(in srgb, var(--muted) 35%, transparent);
    border-radius: 999px;
    transition: background-color var(--dur-base) ease;
}
.a11y-switch-slider::before {
    content: '';
    position: absolute;
    height: 20px;
    width: 20px;
    left: 3px;
    bottom: 3px;
    background-color: #ffffff;
    border-radius: 50%;
    /* WCAG 2.1 - 1.4.11: sin esta frontera el knob blanco se perdía sobre la
       pista apagada (1.66:1) y no se leía la posición del switch. */
    border: 1px solid var(--control-line);
    transition: transform var(--dur-base) ease;
    box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
.a11y-switch-input:checked + .a11y-switch-slider {
    background-color: var(--accent);
}
.a11y-switch-input:checked + .a11y-switch-slider::before {
    transform: translateX(20px);
}
.a11y-switch-input:focus-visible + .a11y-switch-slider {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.a11y-footer {
    margin-top: 0.5rem;
    text-align: center;
}
.a11y-reset-btn {
    width: 100%;
    padding: 0.6rem;
    background: transparent;
    border: 1px dashed var(--line);
    border-radius: var(--radius-md);
    color: var(--muted);
    font-size: var(--fs-xs);
    cursor: pointer;
    transition: all var(--dur-base) ease;
}
.a11y-reset-btn:hover {
    color: var(--orange-ink);
    border-color: var(--orange);
    background: color-mix(in srgb, var(--orange) 10%, transparent);
}

/* ================================================================
   MODO ALTO CONTRASTE (WCAG AAA - Ratio > 7:1)
   ================================================================ */
html[data-contrast="high"] {
    --line: rgba(255, 255, 255, 0.45);
    --line-strong: #ffffff;
    --control-line: #ffffff;
}
html[data-theme="dark"][data-contrast="high"] {
    --bg: #000000;
    --surface: #0a0a0a;
    --surface-soft: #141414;
    --text: #ffffff;
    --muted: #e2e8f0;
    --accent: #38bdf8;
    --accent-ink: #38bdf8;
    --orange-ink: #fb923c;
    --blue-ink: #60a5fa;
    --green-ink: #4ade80;
    --purple-ink: #c084fc;
    --accion-fill: #38bdf8;
    --accion-ink: #09101c;
}
html[data-theme="light"][data-contrast="high"] {
    --bg: #ffffff;
    --surface: #ffffff;
    --surface-soft: #f1f5f9;
    --text: #000000;
    --muted: #1e293b;
    --line: rgba(0, 0, 0, 0.45);
    --line-strong: #000000;
    --accent: #1d4ed8;
    --accent-ink: #1d4ed8;
    --control-line: #000000;
    --accion-fill: #1d4ed8;
    --accion-ink: #ffffff;
}
html[data-contrast="high"] .card,
html[data-contrast="high"] .platform-card,
html[data-contrast="high"] .curso-card,
html[data-contrast="high"] .filters-sidebar,
html[data-contrast="high"] .search-input,
html[data-contrast="high"] .section-tab {
    border: 2px solid var(--line-strong) !important;
}

/* ================================================================
   MODO LECTURA FÁCIL / DISLEXIA
   ================================================================ */
html[data-dyslexia="true"] {
    line-height: 1.8 !important;
    letter-spacing: 0.05em !important;
    word-spacing: 0.12em !important;
}
html[data-dyslexia="true"] p,
html[data-dyslexia="true"] span,
html[data-dyslexia="true"] button,
html[data-dyslexia="true"] input,
html[data-dyslexia="true"] strong,
html[data-dyslexia="true"] a,
/* Los títulos también. Faltaban en esta lista y, como los de tarjeta llevan un
   tracking negativo propio (-.015em, que es lindo pero apretado), en modo
   lectura fácil quedaban MÁS juntos que el resto del texto: exactamente lo
   contrario de lo que la opción promete. */
html[data-dyslexia="true"] h1,
html[data-dyslexia="true"] h2,
html[data-dyslexia="true"] h3,
html[data-dyslexia="true"] h4 {
    letter-spacing: 0.04em !important;
    word-spacing: 0.08em !important;
}

/* ================================================================
   DESTACAR ENLACES Y ELEMENTOS INTERACTIVOS
   ================================================================ */
html[data-highlight="true"] a {
    text-decoration: underline 2px solid var(--accent) !important;
    text-underline-offset: 3px !important;
}
html[data-highlight="true"] button:not(.a11y-btn-font):not(.btn-a11y-toggle) {
    outline: 2px solid var(--accent) !important;
    outline-offset: 1px !important;
}

/* ================================================================
   BOTÓN ESCUCHAR CARRERA (TTS)
   ================================================================ */
.btn-escuchar-card {
    display: none;
}
html[data-tts="true"] .btn-escuchar-card {
    display: inline-flex;
}
.btn-escuchar-card.is-playing {
    /* WCAG 2.1 - 1.4.3: blanco sobre el verde daba 3.30:1 (claro) y 1.74:1 (oscuro). */
    color: var(--on-vivid) !important;
    background: var(--green) !important;
    border-color: var(--green) !important;
    animation: a11y-pulse 1.4s infinite;
}
@keyframes a11y-pulse {
    0% { transform: scale(1); }
    50% { transform: scale(1.03); }
    100% { transform: scale(1); }
}

@media (max-width: 480px) {
    .a11y-widget {
        bottom: 0.75rem;
        left: 0.75rem;
    }
    .btn-a11y-toggle {
        width: 48px;
        height: 48px;
        font-size: 1.25rem;
    }
    .a11y-panel-card {
        max-height: 85vh;
    }
}

/* ================================================================
   PIE DE PÁGINA (FOOTER) Y FEEDBACK / REPORTE DE FALLOS
   ================================================================ */
.site-footer {
    width: 100%;
    margin-top: 3rem;
    padding: 2.5rem 1.5rem 6rem;
    border-top: 1px solid var(--line);
    background: var(--surface);
    color: var(--muted);
    font-size: var(--fs-sm);
}

.footer-container {
    max-width: var(--container);
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1.25rem;
}

.footer-copy {
    margin: 0;
    line-height: 1.5;
}

.footer-copy strong {
    color: var(--text);
    font-weight: 700;
}

.footer-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.enlace-footer { color: var(--muted); font-size: var(--fs-sm); text-decoration: underline; text-decoration-style: dotted; text-underline-offset: 2px; }
.enlace-footer:hover { color: var(--text); text-decoration-style: solid; }
/* "¿Cómo funciona?" es un botón con la ropa del enlace: se le saca el aspecto
   nativo para que la fila del pie no tenga dos lenguajes visuales. */
button.enlace-footer { padding: 0; border: 0; background: none; font: inherit; font-size: var(--fs-sm); cursor: pointer; }
button.enlace-footer:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.btn-footer-feedback {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 1.15rem;
    border-radius: var(--radius-pill);
    border: 1px solid var(--line);
    background: var(--surface-soft);
    color: var(--text);
    font-family: var(--font-text);
    font-size: var(--fs-xs);
    font-weight: 600;
    cursor: pointer;
    transition: transform var(--dur-fast), border-color var(--dur-fast), background-color var(--dur-fast), box-shadow var(--dur-fast);
}

.btn-footer-feedback:hover {
    border-color: var(--accent);
    background: var(--surface);
    color: var(--accent-ink);
    transform: translateY(-1px);
    box-shadow: var(--elev-1);
}

.btn-footer-feedback:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.footer-legal {
    max-width: var(--container);
    margin: 1.5rem auto 0;
    padding-top: 1.25rem;
    border-top: 1px solid var(--line);
    font-size: var(--fs-2xs);
    line-height: 1.6;
    color: var(--muted);
}

.footer-legal p {
    margin: 0;
}

.footer-legal strong {
    color: var(--text);
    font-weight: 600;
}

/* Modal de Feedback */
.modal-feedback {
    position: fixed;
    inset: 0;
    z-index: 105;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}

.modal-feedback[hidden] {
    display: none;
}

.modal-feedback-overlay {
    position: absolute;
    inset: 0;
    background: rgba(15, 12, 30, 0.55);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    animation: fadeInFeedback var(--dur-fast) ease-out;
}

.modal-feedback-dialog {
    position: relative;
    width: min(100%, 460px);
    max-height: 90vh;
    overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--elev-4);
    animation: scaleUpFeedback var(--dur-fast) cubic-bezier(0.16, 1, 0.3, 1);
    display: flex;
    flex-direction: column;
}

@keyframes fadeInFeedback {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes scaleUpFeedback {
    from { transform: scale(0.95); opacity: 0; }
    to { transform: scale(1); opacity: 1; }
}

.modal-feedback-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1.15rem 1.25rem;
    border-bottom: 1px solid var(--line);
    position: sticky;
    top: 0;
    background: var(--surface);
    z-index: 2;
}

.modal-feedback-header h2 {
    margin: 0;
    font-family: var(--font-title);
    font-size: var(--fs-md);
    font-weight: 700;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.modal-feedback-cerrar {
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface-soft);
    color: var(--muted);
    font-size: 1rem;
    cursor: pointer;
    transition: color var(--dur-fast), background-color var(--dur-fast);
}

.modal-feedback-cerrar:hover {
    color: var(--text);
    background: var(--surface);
    border-color: var(--line-strong);
}

.modal-feedback-cerrar:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.modal-feedback-body {
    padding: 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 1.15rem;
}

/* Selector de tipo (Pills) */
.feedback-tipo-selector {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;
    background: var(--surface-soft);
    padding: 0.35rem;
    border-radius: var(--radius-md);
    border: 1px solid var(--line);
}

.btn-tipo-feedback {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.6rem 0.75rem;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--muted);
    font-family: var(--font-text);
    font-size: var(--fs-xs);
    font-weight: 600;
    cursor: pointer;
    transition: all var(--dur-fast);
}

.btn-tipo-feedback:hover {
    color: var(--text);
}

.btn-tipo-feedback.is-active {
    background: var(--surface);
    color: var(--text);
    box-shadow: var(--elev-1);
}

.btn-tipo-feedback:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

/* Formulario */
.feedback-form {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.feedback-grupo {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.feedback-grupo label {
    font-size: var(--fs-xs);
    font-weight: 600;
    color: var(--text);
    line-height: 1.4;
}

.feedback-grupo label small {
    color: var(--muted);
    font-weight: 400;
}

.feedback-grupo textarea,
.feedback-grupo input {
    width: 100%;
    padding: 0.65rem 0.85rem;
    border-radius: var(--radius-md);
    /* WCAG 2.1 - 1.4.11: frontera de los campos del formulario. */
    border: 1px solid var(--control-line);
    background: var(--surface-soft);
    color: var(--text);
    font-family: var(--font-text);
    font-size: var(--fs-sm);
    line-height: 1.5;
    transition: border-color var(--dur-fast), box-shadow var(--dur-fast), background-color var(--dur-fast);
}

.feedback-grupo textarea {
    resize: vertical;
    min-height: 95px;
    max-height: 220px;
}

.feedback-grupo textarea:focus,
.feedback-grupo input:focus {
    outline: none;
    border-color: var(--accent);
    background: var(--surface);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}

.feedback-grupo textarea[aria-invalid="true"],
.feedback-grupo input[aria-invalid="true"] {
    border-color: #EF4444;
    box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.15);
}

.feedback-error-texto {
    font-size: var(--fs-2xs);
    color: #EF4444;
    font-weight: 500;
}

.feedback-privacidad-aviso {
    margin: 0.35rem 0 0;
    font-size: var(--fs-2xs);
    color: var(--muted);
    line-height: 1.35;
    opacity: 0.9;
}

.feedback-footer-acciones {
    margin-top: 0.5rem;
}

.btn-feedback-submit {
    width: 100%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.75rem 1.25rem;
    border-radius: var(--radius-md);
    border: none;
    background: var(--accion-fill);
    color: var(--accion-ink);
    font-family: var(--font-text);
    font-size: var(--fs-sm);
    font-weight: 600;
    cursor: pointer;
    transition: opacity var(--dur-fast), transform var(--dur-fast), box-shadow var(--dur-fast);
    box-shadow: var(--elev-1);
}

.btn-feedback-submit:hover:not(:disabled) {
    opacity: 0.94;
    transform: translateY(-1px);
    box-shadow: var(--elev-2);
}

.btn-feedback-submit:disabled {
    opacity: 0.65;
    cursor: not-allowed;
}

.btn-feedback-submit:focus-visible {
    outline: 2px solid var(--text);
    outline-offset: 2px;
}

/* Spinner de carga */
.btn-feedback-spinner {
    width: 16px;
    height: 16px;
    border: 2px solid rgba(255, 255, 255, 0.35);
    border-top-color: #FFFFFF;
    border-radius: 50%;
    animation: feedbackSpin 0.7s linear infinite;
}

@keyframes feedbackSpin {
    to { transform: rotate(360deg); }
}

/* Pantallas de estado (éxito y error) */
.feedback-estado-mensaje {
    padding: 1.5rem 0.5rem 0.5rem;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
}

.feedback-estado-icono {
    font-size: 2.25rem;
    line-height: 1;
}

.feedback-estado-mensaje h3 {
    margin: 0;
    font-family: var(--font-title);
    font-size: var(--fs-md);
    font-weight: 700;
    color: var(--text);
}

.feedback-estado-mensaje p {
    margin: 0 0 1rem;
    font-size: var(--fs-sm);
    color: var(--muted);
    line-height: 1.5;
    max-width: 320px;
}

/* Soporte de Alto Contraste */
html[data-contrast="high"] .site-footer {
    border-top: 2px solid var(--text);
}

html[data-contrast="high"] .btn-footer-feedback,
html[data-contrast="high"] .modal-feedback-dialog,
html[data-contrast="high"] .modal-feedback-cerrar,
html[data-contrast="high"] .feedback-tipo-selector,
html[data-contrast="high"] .feedback-grupo textarea,
html[data-contrast="high"] .feedback-grupo input {
    border: 2px solid var(--text) !important;
}

html[data-contrast="high"] .btn-tipo-feedback.is-active {
    background: var(--text) !important;
    color: var(--surface) !important;
}

@media (max-width: 600px) {
    .footer-container {
        flex-direction: column;
        align-items: flex-start;
    }
    .modal-feedback-dialog {
        width: 100%;
        max-height: 94vh;
    }
}

/* 9c. CHAPITA DE RECOMENDACIONES DEL COPILOTO.
   Avisa que la grilla no es el catálogo completo sino el ranking del test, y da
   la salida de vuelta. Sin ella, filtrar sobre las recomendaciones se sentiría
   como un catálogo roto ("¿por qué solo hay 24 carreras?"). */
.chapa-recomendacion {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    margin: 0;
    padding: .3rem .35rem .3rem .7rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--surface-soft);
    color: var(--text);
    font-size: var(--fs-2xs);
    font-weight: 600;
}
.chapa-recomendacion[hidden] { display: none; }
.chapa-recomendacion button {
    display: grid;
    place-items: center;
    /* WCAG 2.5.8: 24px reales de área interactiva. */
    width: 24px;
    height: 24px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    color: inherit;
    background: transparent;
    font-size: var(--fs-2xs);
    line-height: 1;
    cursor: pointer;
}
.chapa-recomendacion button:hover { background: var(--accion-fill); color: var(--accion-ink); }
.chapa-recomendacion button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.section-title-svg {
    width: 22px;
    height: 22px;
    display: inline-block;
    vertical-align: -4px;
    margin-right: .45rem;
    color: currentColor;
    flex-shrink: 0;
}
.chapa-texto {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
}


/* (El pie ancla al catálogo estático vía sitemap.xml: /carreras/, /instituciones/.
   El enlace "Todas las instituciones" del footer se retiró de index.html.) */

.area-header {
    margin-bottom: 2rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    align-items: flex-start;
}

.area-header-title {
    font-size: 1.75rem;
    margin: 0;
    color: var(--text);
}

.career-group-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1rem;
}

/* Agrupación de instituciones por tipo en la vista "Instituciones": una
   sección por tipo, con su h2 y la grilla de tarjetas. El primer grupo no
   necesita separación (arranca la vista); los siguientes se espacian. */
.grupo-instituciones-separado {
    margin-top: 2.75rem;
}

.grupo-instituciones-count {
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

/* Nuevos estilos para Orientador Asertivo */
.chat-resultado-explicacion {
  font-size: 0.82rem;
  color: var(--texto-secundario);
  margin: 0.3em 0 0;
  line-height: 1.35;
}

.chat-resultado-alerta,
.mensaje-bot-alerta {
  font-size: 0.82rem;
  color: var(--color-alerta, #c0392b);
  margin: 0.3em 0 0;
  line-height: 1.35;
}

.chat-resultados-secundarios .chat-resultado-card {
  opacity: 0.85;
  border-left: 2px solid var(--borde-suave, #ddd);
}

/* ================================================================
   17. TEST VOCACIONAL COMPLETO
   Ventana flotante que desenfoca el sitio de atrás. Adentro vive el
   recorrido intro → preguntas por tandas → resultados. Todo el HTML
   lo arma js/vocacional/test-completo.js.
   ================================================================ */
.test-completo {
    position: fixed; inset: 0; z-index: 100;
    display: flex; align-items: center; justify-content: center;
    padding: var(--space-4);
    background: rgba(2, 6, 23, .55);
    backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
html.test-completo-abierto { overflow: hidden; }

.tc-ventana {
    display: flex; flex-direction: column;
    width: min(860px, 100%);
    height: min(680px, 92vh);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--elev-4);
    overflow: hidden;
    animation: chat-abrir var(--dur-slow) ease;
}
.tc-header { display: flex; align-items: center; justify-content: space-between; padding: .9rem 1.1rem; border-bottom: 1px solid var(--line); }
.tc-header h2 { margin: 0; font-family: var(--font-title); font-size: var(--fs-lg); color: var(--text); letter-spacing: -.01em; }
.tc-header button { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; border: 0; border-radius: var(--radius-sm); background: none; color: var(--muted); font-size: var(--fs-md); cursor: pointer; }
.tc-header button:hover { color: var(--text); background: var(--surface-soft); }

.tc-progreso { padding: .85rem 1.1rem .2rem; }
.tc-progreso-barra { height: 6px; border-radius: var(--radius-pill); background: var(--line); overflow: hidden; }
.tc-progreso-barra span { display: block; height: 100%; width: 0; background: var(--accent); transition: width var(--dur-slow) ease; }
.tc-progreso-texto { margin: .5rem 0 .6rem; color: var(--muted); font-family: var(--font-detail); font-size: var(--fs-2xs); letter-spacing: .06em; text-transform: uppercase; }

.tc-cuerpo { flex: 1; min-height: 0; overflow-y: auto; padding: 1.1rem 1.25rem 1.4rem; color: var(--text); }
.tc-pie { display: flex; align-items: center; justify-content: space-between; gap: .75rem; padding: .9rem 1.1rem; border-top: 1px solid var(--line); background: var(--surface); }

/* Botones del test */
.tc-btn-primario, .tc-btn-secundario, .tc-btn-chico, .tc-btn-texto { font-family: var(--font-text); cursor: pointer; }
.tc-btn-primario { min-height: 44px; padding: .65rem 1.15rem; border: 0; border-radius: var(--radius-pill); background: var(--accion-fill); color: var(--accion-ink); font-weight: 700; font-size: var(--fs-sm); }
.tc-btn-primario:hover { filter: brightness(1.05); }
.tc-btn-secundario { min-height: 44px; padding: .6rem 1rem; border: 1px solid var(--line); border-radius: var(--radius-pill); background: var(--surface); color: var(--muted); font-weight: 700; font-size: var(--fs-sm); }
.tc-btn-secundario:hover { border-color: var(--accent); color: var(--accent-ink); }
.tc-btn-primario:disabled, .tc-btn-secundario:disabled { opacity: .5; cursor: default; }
.tc-btn-texto { border: 0; background: none; color: var(--muted); font-size: var(--fs-xs); text-decoration: underline; padding: .4rem; }
.tc-btn-chico { min-height: 36px; padding: .4rem .8rem; border: 1px dashed var(--line); border-radius: var(--radius-pill); background: transparent; color: var(--muted); font-size: var(--fs-2xs); }
.tc-btn-chico:hover { border-color: var(--accent); color: var(--accent-ink); }
.tc-aviso { color: var(--muted); font-size: var(--fs-2xs); }

/* Intro */
.tc-intro { display: flex; flex-direction: column; gap: 1rem; max-width: 640px; margin: 0 auto; }
.tc-eyebrow { margin: 0; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); font-size: var(--fs-2xs); font-family: var(--font-detail); }
.tc-titulo-grande { margin: 0; font-family: var(--font-title); font-size: var(--fs-xl); line-height: 1.25; color: var(--text); letter-spacing: -.015em; }
.tc-descripcion { margin: 0; color: var(--muted); font-size: var(--fs-sm); line-height: 1.55; }
.tc-pasos { display: flex; flex-direction: column; gap: .6rem; margin: 0; padding: 0; list-style: none; }
.tc-paso { display: flex; gap: .75rem; align-items: flex-start; border: 1px solid var(--line); border-radius: var(--radius-md); padding: .7rem .85rem; color: var(--muted); font-size: var(--fs-sm); line-height: 1.45; }
.tc-paso strong { color: var(--text); }
.tc-paso-num { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 1.6rem; height: 1.6rem; border-radius: 50%; background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent-ink); font-weight: 700; font-size: var(--fs-xs); }
.tc-ultimo { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .75rem; border: 1px solid var(--line); border-radius: var(--radius-md); padding: .85rem .95rem; background: var(--surface-soft); }
.tc-ultimo p { margin: .2rem 0 0; color: var(--muted); font-size: var(--fs-xs); }
.tc-aviso-legal { margin: .4rem 0 0; color: var(--muted); }
.tc-aviso-legal small { line-height: 1.5; }

/* Preguntas */
.tc-pagina { max-width: 720px; margin: 0 auto; }
.tc-instruccion { margin: .1rem 0 .4rem; font-family: var(--font-title); font-size: var(--fs-lg); color: var(--text); }
.tc-escala { display: flex; justify-content: space-between; color: var(--muted); font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .06em; margin-bottom: .75rem; }
.tc-pregunta { border: 1px solid var(--line); border-radius: var(--radius-md); padding: .85rem .95rem; margin: 0 0 .7rem; }
.tc-pregunta-texto { display: flex; gap: .6rem; align-items: flex-start; padding: 0; margin: 0 0 .6rem; color: var(--text); font-size: var(--fs-sm); line-height: 1.45; font-weight: 600; }
.tc-numero { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 1.5rem; height: 1.5rem; border-radius: 50%; background: var(--surface-soft); color: var(--muted); font-size: var(--fs-2xs); font-weight: 700; }
.tc-likert { display: grid; grid-template-columns: repeat(5, 1fr); gap: .4rem; }
.tc-opcion { position: relative; display: flex; }
.tc-opcion input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.tc-opcion span { display: flex; align-items: center; justify-content: center; width: 100%; min-height: 44px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); color: var(--muted); font-weight: 700; font-size: var(--fs-sm); cursor: pointer; transition: border-color var(--dur-base) ease, background var(--dur-base) ease, color var(--dur-base) ease; }
.tc-opcion span:hover { border-color: var(--accent); }
.tc-opcion input:checked + span { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent-ink); }
.tc-opcion input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Cargando */
.tc-cargando { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1rem; min-height: 280px; color: var(--muted); }
.tc-spinner { width: 34px; height: 34px; border-radius: 50%; border: 3px solid var(--line); border-top-color: var(--accent); animation: tc-girar .8s linear infinite; }
@keyframes tc-girar { to { transform: rotate(360deg); } }

/* Resultados */
.tc-resultado { display: flex; flex-direction: column; gap: .9rem; max-width: 720px; margin: 0 auto; }
.tc-resumen { margin: 0; font-family: var(--font-title); font-size: var(--fs-lg); line-height: 1.45; color: var(--text); }
.tc-codigo { margin: 0; color: var(--muted); font-size: var(--fs-xs); }
.tc-alertas { border: 1px solid var(--line); border-left: 3px solid var(--accent); border-radius: var(--radius-md); padding: .8rem .95rem; background: var(--surface-soft); }
.tc-alertas strong { display: block; margin-bottom: .35rem; font-size: var(--fs-sm); color: var(--text); }
.tc-alertas ul { margin: 0; padding-left: 1.1rem; display: flex; flex-direction: column; gap: .45rem; color: var(--muted); font-size: var(--fs-xs); line-height: 1.5; }
.tc-subtitulo { margin: .4rem 0 0; font-family: var(--font-title); font-size: var(--fs-md); color: var(--text); }
.tc-cards { display: flex; flex-direction: column; gap: .7rem; }
.tc-card { display: flex; flex-direction: column; gap: .5rem; border: 1px solid var(--line); border-radius: var(--radius-md); padding: .85rem .95rem; background: var(--surface); }
.tc-card.match-alto { border-left: 3px solid var(--accent); }
.tc-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: .6rem; }
.tc-card-head h5 { margin: 0; font-size: var(--fs-base); color: var(--text); }
.tc-card-why { margin: 0; color: var(--muted); font-size: var(--fs-sm); line-height: 1.45; }
.tc-card .alertas-list { margin: 0; padding-left: 1.1rem; color: var(--muted); font-size: var(--fs-xs); display: flex; flex-direction: column; gap: .3rem; }
.tc-card-acciones { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; }
.tc-link { color: var(--accent-ink); font-size: var(--fs-xs); font-weight: 700; }
.tc-acciones { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; }

@media (max-width: 600px) {
    .test-completo { padding: 0; }
    .tc-ventana { width: 100%; height: 100%; max-height: none; border: 0; border-radius: 0; }
    .tc-cuerpo { padding: .9rem .85rem 1.2rem; }
    .tc-pie { flex-wrap: wrap; }
    .tc-pie .tc-btn-primario { flex: 1 1 auto; }
    .tc-likert { gap: .3rem; }
    .tc-opcion span { min-height: 42px; font-size: var(--fs-xs); }
}

/* ================================================================
   18. FAVORITOS ("ME INTERESA") Y MI LISTA
   El botón lo pinta js/favoritos.js en cada tarjeta; el apartado con la
   lista y el comparador vive en js/mi-lista.js (overlay #miLista).
   ================================================================ */
.btn-favorito {
    flex: 1 1 100%;
    min-width: 0;
    display: inline-flex; align-items: center; justify-content: center; gap: .35rem;
    min-height: 36px; padding: .4rem .5rem; border: 1px solid var(--line);
    border-radius: var(--radius-sm); color: var(--muted); background: var(--surface-soft);
    font-family: var(--font-text); font-size: var(--fs-2xs); font-weight: 700; cursor: pointer;
    white-space: nowrap; text-overflow: ellipsis; overflow: hidden;
    transition: border-color var(--dur-base) ease, color var(--dur-base) ease, background var(--dur-base) ease;
}
.btn-favorito:hover { border-color: var(--accent); color: var(--accent-ink); }
.btn-favorito .fav-svg { width: 14px; height: 14px; flex: none; }
.btn-favorito.is-favorito { border-color: var(--fav-rojo); color: var(--text); background: var(--surface-soft); }
.btn-favorito.is-favorito .fav-svg { color: var(--fav-rojo); fill: var(--fav-rojo); stroke: var(--fav-rojo); }
/* Con el lector de texto activo, Escuchar ya ocupa la fila entera: el corazón
   comparte el espacio para no empujar la tarjeta a una tercera línea. */
html[data-tts="true"] .btn-favorito { flex: 1 1 calc(50% - .25rem); }

.fav-toast {
    position: fixed;
    left: 50%; bottom: 1.1rem;
    transform: translate(-50%, 1.2rem);
    z-index: 130;
    display: flex; align-items: center; gap: .6rem;
    max-width: min(92vw, 26rem);
    padding: .6rem .9rem;
    border: 1px solid var(--line); border-radius: 999px;
    background: var(--surface);
    color: var(--text);
    box-shadow: var(--elev-3);
    font-family: var(--font-text); font-size: var(--fs-sm);
    opacity: 0; pointer-events: none;
    transition: opacity var(--dur-base) ease, transform var(--dur-base) ease;
}
.fav-toast.is-visible { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.fav-toast-texto { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fav-toast-accion { color: var(--accent-ink); font-weight: 700; flex: none; }

/* --- Botón "Mi lista" de la barra de resultados --- */
.btn-mi-lista {
    display: inline-flex; align-items: center; gap: .4rem;
    min-height: 38px; padding: .4rem .8rem;
    border: 1px solid var(--line); border-radius: 999px;
    background: var(--surface-soft); color: var(--text);
    font-family: var(--font-text); font-size: var(--fs-xs); font-weight: 700; cursor: pointer;
    transition: border-color var(--dur-base) ease, color var(--dur-base) ease;
}
.btn-mi-lista:hover { border-color: var(--accent); color: var(--accent-ink); }
.btn-mi-lista .fav-svg { width: 15px; height: 15px; fill: currentColor; }
.btn-mi-lista[hidden] { display: none; }
.btn-mi-lista .mi-lista-contador {
    min-width: 1.35em; padding: 0 .3em;
    border-radius: 999px; background: var(--accion-fill); color: var(--accion-ink);
    font-size: .85em; text-align: center;
}

/* --- Ventana de Mi lista (misma receta que el test) --- */
.mi-lista {
    position: fixed; inset: 0; z-index: 110;
    display: flex; align-items: center; justify-content: center;
    padding: var(--space-4);
    background: rgba(2, 6, 23, .55);
    backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
html.mi-lista-abierta { overflow: hidden; }

.ml-ventana {
    display: flex; flex-direction: column;
    width: min(940px, 100%);
    height: min(720px, 92vh);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--elev-4);
    overflow: hidden;
    animation: chat-abrir var(--dur-slow) ease;
}
.ml-header { display: flex; align-items: center; justify-content: space-between; padding: .9rem 1.1rem; border-bottom: 1px solid var(--line); }
.ml-header h2 { margin: 0; font-family: var(--font-title); font-size: var(--fs-lg); color: var(--text); letter-spacing: -.01em; }
.ml-header button { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; border: 0; border-radius: var(--radius-sm); background: none; color: var(--muted); font-size: var(--fs-md); cursor: pointer; }
.ml-header button:hover { color: var(--text); background: var(--surface-soft); }
.ml-cuerpo { flex: 1; min-height: 0; overflow-y: auto; padding: 1.1rem 1.25rem 1.4rem; color: var(--text); }
.ml-pie { display: flex; align-items: center; justify-content: space-between; gap: .75rem; padding: .9rem 1.1rem; border-top: 1px solid var(--line); background: var(--surface); flex-wrap: wrap; }
.ml-pie-info { margin: 0; color: var(--muted); font-size: var(--fs-xs); }
.ml-pie-acciones { display: flex; gap: .5rem; flex-wrap: wrap; }
.ml-btn-primario, .ml-btn-secundario { font-family: var(--font-text); cursor: pointer; min-height: 42px; border-radius: var(--radius-pill); font-weight: 700; font-size: var(--fs-sm); padding: .6rem 1.1rem; }
.ml-btn-primario { border: 0; background: var(--accion-fill); color: var(--accion-ink); }
.ml-btn-primario:hover { filter: brightness(1.05); }
.ml-btn-primario:disabled { opacity: .5; cursor: default; }
.ml-btn-secundario { border: 1px solid var(--line); background: var(--surface); color: var(--muted); }
.ml-btn-secundario:hover { border-color: var(--accent); color: var(--accent-ink); }
/* WCAG 2.1 - 1.4.3: blanco sobre naranja daba 2.80:1 (claro) y 2.26:1 (oscuro). */
.ml-btn-peligro { background: var(--orange); color: var(--on-vivid); }
.ml-btn-volver { border: 0; background: none; color: var(--accent-ink); font-weight: 700; font-size: var(--fs-sm); cursor: pointer; padding: .3rem 0; }

/* Lista vacía */
.ml-vacia { max-width: 30rem; margin: 2rem auto; text-align: center; display: flex; flex-direction: column; gap: .7rem; align-items: center; }
.ml-vacia-titulo { margin: 0; font-family: var(--font-title); font-size: var(--fs-md); color: var(--text); }
.ml-vacia-texto { margin: 0; color: var(--muted); font-size: var(--fs-sm); line-height: 1.5; }

/* Grupos y filas */
.ml-grupo { margin-bottom: 1.4rem; }
.ml-grupo-titulo { display: flex; align-items: center; gap: .5rem; margin: 0 0 .6rem; font-family: var(--font-title); font-size: var(--fs-sm); color: var(--text); }
.ml-grupo-titulo span { min-width: 1.5em; padding: 0 .4em; border-radius: 999px; background: var(--surface-soft); color: var(--muted); font-size: var(--fs-2xs); text-align: center; }
.ml-items { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .45rem; }
.ml-item {
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; gap: .7rem; align-items: center;
    border: 1px solid var(--line); border-radius: var(--radius-md);
    padding: .6rem .75rem; background: var(--surface);
}
.ml-item.is-seleccionada { border-color: var(--accent); background: var(--surface-soft); }
.ml-item-huerfana { opacity: .75; }
/* WCAG 2.5.8 (y el pedido explícito de 24x24): el área táctil real es el input,
   así que el cuadradito mide 24px y la fila lo acompaña. */
.ml-item-check { display: inline-flex; align-items: center; justify-content: center; min-width: 24px; min-height: 24px; }
.ml-item-check input { width: 24px; height: 24px; accent-color: var(--accent); cursor: pointer; }
.ml-item-info { min-width: 0; }
.ml-item-nombre { margin: 0; font-weight: 700; font-size: var(--fs-sm); color: var(--text); display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.ml-item-meta { margin: .15rem 0 0; color: var(--muted); font-size: var(--fs-xs); }
.ml-item-afinidad { padding: .1em .5em; border-radius: 999px; background: var(--accion-fill); color: var(--accion-ink); font-size: var(--fs-2xs); }
.ml-item-link { color: var(--accent-ink); font-size: var(--fs-xs); font-weight: 700; white-space: nowrap; }
.ml-item-quitar { min-width: 36px; min-height: 36px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-soft); color: var(--muted); cursor: pointer; }
.ml-item-quitar:hover { border-color: var(--orange); color: var(--orange-ink); }

/* Comparación */
.ml-volver { margin: 0 0 .6rem; }
.ml-tabla-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius-md); }
.ml-tabla { border-collapse: collapse; width: 100%; min-width: 100%; font-size: var(--fs-sm); }
.ml-tabla th, .ml-tabla td { padding: .6rem .7rem; text-align: left; vertical-align: top; border-bottom: 1px solid var(--line); }
.ml-tabla tbody th { position: sticky; left: 0; z-index: 1; background: var(--surface); color: var(--muted); font-weight: 700; font-size: var(--fs-xs); white-space: nowrap; }
.ml-tabla thead th { background: var(--surface-soft); border-bottom: 1px solid var(--line-strong, var(--line)); }
.ml-tabla-esquina { position: sticky; left: 0; z-index: 2; }
.ml-tabla-titulo { display: block; font-family: var(--font-title); font-size: var(--fs-sm); color: var(--text); }
.ml-tabla-sub { display: block; margin-top: .15rem; color: var(--muted); font-size: var(--fs-2xs); font-weight: 400; }
.ml-tabla tbody tr:last-child th, .ml-tabla tbody tr:last-child td { border-bottom: 0; }
.ml-vacio { color: var(--muted); }
.ml-link { color: var(--accent-ink); font-weight: 700; font-size: var(--fs-xs); }
.ml-instituciones, .ml-planes { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .2rem; }
.ml-instituciones a, .ml-planes a { color: var(--accent-ink); font-size: var(--fs-xs); }

.ml-afinidad { display: flex; flex-direction: column; gap: .3rem; min-width: 5.5rem; }
.ml-afinidad-valor { font-weight: 800; font-size: var(--fs-md); }
.ml-afinidad.alta .ml-afinidad-valor { color: var(--accent-ink); }
.ml-afinidad.media .ml-afinidad-valor { color: var(--text); }
.ml-afinidad.baja .ml-afinidad-valor { color: var(--muted); }
.ml-afinidad-barra { height: 6px; border-radius: 999px; background: var(--line); overflow: hidden; }
.ml-afinidad-barra span { display: block; height: 100%; background: var(--accent); }

.ml-riasec { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .25rem; min-width: 8rem; }
.ml-riasec li { display: grid; grid-template-columns: 6.5rem 4rem 1.4rem; align-items: center; gap: .4rem; }
.ml-riasec-nombre { color: var(--muted); font-size: var(--fs-2xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ml-riasec-barra { height: 5px; border-radius: 999px; background: var(--line); overflow: hidden; }
.ml-riasec-barra span { display: block; height: 100%; background: var(--accent); }
.ml-riasec-valor { color: var(--muted); font-size: var(--fs-2xs); text-align: right; }

/* Comparación en celular: una sola lista vertical, un bloque por atributo (con
   las carreras adentro). Misma comparación que la tabla, sin scroll lateral. */
.ml-lista { margin: 0; border: 1px solid var(--line); border-radius: var(--radius-md); overflow: hidden; background: var(--surface); }
.ml-lista-grupo { border-bottom: 1px solid var(--line); }
.ml-lista-grupo:last-child { border-bottom: 0; }
.ml-lista-grupo-nombre {
    padding: .5rem .85rem .4rem;
    background: var(--surface-soft);
    color: var(--muted); font-weight: 700; font-size: var(--fs-2xs);
    letter-spacing: .05em; text-transform: uppercase;
}
.ml-lista-valores { margin: 0; }
.ml-lista-valores ul { list-style: none; margin: 0; padding: .4rem .85rem .65rem; display: flex; flex-direction: column; gap: .5rem; }
.ml-lista-item { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.ml-lista-item-nombre { font-weight: 700; font-size: var(--fs-xs); color: var(--text); }
.ml-lista-item-dato { font-size: var(--fs-sm); color: var(--text); min-width: 0; }

.ml-diferencias { margin-top: 1.2rem; border: 1px solid var(--line); border-radius: var(--radius-md); padding: .85rem .95rem; background: var(--surface-soft); }
.ml-diferencias h3 { margin: 0 0 .5rem; font-family: var(--font-title); font-size: var(--fs-sm); color: var(--text); }
.ml-diferencias-lista { margin: 0; padding-left: 1.1rem; display: flex; flex-direction: column; gap: .4rem; color: var(--text); font-size: var(--fs-sm); line-height: 1.45; }
.ml-diferencias-vacio { margin: 0; color: var(--muted); font-size: var(--fs-sm); }

@media (max-width: 640px) {
    .mi-lista { padding: 0; }
    .ml-ventana { width: 100%; height: 100%; max-height: none; border: 0; border-radius: 0; }
    .ml-item { grid-template-columns: auto minmax(0, 1fr) auto; }
    .ml-item-link { grid-column: 2; }
    .ml-riasec li { grid-template-columns: 5.5rem 3rem 1.3rem; }
}

/* Impresión: solo la comparación, en una hoja legible. Sirve para "Imprimir /
   PDF" y para llevarle la comparación a la familia o al colegio. */
@media print {
    body > *:not(#miLista) { display: none !important; }
    .mi-lista { position: static; background: none; backdrop-filter: none; padding: 0; }
    .ml-ventana { width: 100%; height: auto; max-height: none; border: 0; box-shadow: none; }
    .ml-header button, .ml-pie, .ml-volver { display: none !important; }
    .ml-cuerpo { overflow: visible; padding: 0; }
    .ml-tabla-scroll { overflow: visible; border-color: #999; }
    .ml-tabla th, .ml-tabla td { font-size: 10pt; }
    .ml-tabla tbody th { position: static; }
    .ml-diferencias { break-inside: avoid; }
}
