@import "tokens.css?v=8";

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--font-body);
  background: var(--funprotec-bg);
  color: var(--funprotec-text);
  line-height: 1.5;
}
img { max-width: 100%; display: block; }
a { color: inherit; }

.skip-link {
  position: absolute; left: -9999px; top: 0; background: var(--funprotec-navy);
  color: #fff; padding: 0.75rem 1rem; z-index: 100;
}
.skip-link:focus { left: 0; }

/* Foco visible en todo elemento interactivo: sin esto, quien navega con teclado
   no sabe dónde está parado (WCAG 2.4.7). Se usa :focus-visible para no molestar
   a quien navega con mouse. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--funprotec-aqua);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Quien activa "reducir movimiento" en su sistema no debe recibir animaciones. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Barra de utilidad — accesibilidad y cumplimiento, patrón UNAD.
   Fondo claro institucional (--funprotec-navy-bg, 2026-08-18) con texto en
   --funprotec-navy-dark: 9.4:1 de contraste, de sobra para WCAG AA. */
.utility-bar {
  background: var(--funprotec-navy-bg);
  color: var(--funprotec-navy-dark);
  font-size: 0.8rem;
}
.utility-bar .inner {
  max-width: 1200px; margin: 0 auto; padding: 0.4rem 1.5rem;
  display: flex; gap: 1.25rem; flex-wrap: wrap; align-items: center;
}
.utility-bar a { text-decoration: none; opacity: 0.9; }
.utility-bar a:hover { text-decoration: underline; }
.utility-bar button {
  background: transparent; border: 1px solid rgba(10,30,56,0.35); color: var(--funprotec-navy-dark);
  border-radius: 6px; padding: 0.15rem 0.6rem; cursor: pointer; font-size: 0.75rem;
}

/* Nav principal — navy oscuro institucional (2026-08-18, a pedido del usuario: quería
   que "el menú horizontal" destacara con un color distinto). Antes compartía el mismo
   celeste claro que la barra de utilidad y el footer, y se perdía entre ambos — ahora
   crea contraste fuerte justo en la barra que importa (logo + menú + CTA), y sigue
   usando un tono ya presente en la paleta (el mismo de la superposición del hero y del
   footer), no un color nuevo. Utility-bar y footer se dejan igual, en el celeste claro. */
.main-nav {
  background: var(--funprotec-navy-dark);
  color: #fff;
  position: sticky; top: 0; z-index: 50;
  box-shadow: var(--funprotec-shadow);
}
.main-nav .inner {
  max-width: 1200px; margin: 0 auto; padding: 0.75rem 1.5rem;
  display: flex; align-items: center; gap: 2rem; flex-wrap: wrap;
}
/* La marca es un enlace: hay que anular el subrayado por defecto del navegador,
   tanto en reposo como en hover, para que el nombre institucional se lea limpio. */
.brand {
  display: flex; align-items: center; gap: 1rem;
  font-weight: 700; font-size: 1.625rem; /* +2px sobre el 1.5rem original, a pedido del usuario */
  text-decoration: none; color: #fff;
  margin-left: -0.75rem; /* corrido a la izquierda para compensar el nav más cargado (logo/texto más grandes + "La Fundación") */
}
.brand:hover, .brand:focus { text-decoration: none; }
.brand img { height: 78px; width: 78px; border-radius: 50%; background: #fff; } /* +2px sobre 76px original */
.brand__text { display: flex; flex-direction: column; line-height: 1.15; }
.brand__text small {
  font-weight: 400; font-size: 0.975rem; opacity: 0.85; margin-top: 0.15rem; /* +2px sobre 0.85rem original */
}
.nav-collapsible { display: flex; align-items: center; gap: 2rem; flex: 1; flex-wrap: wrap; }
.main-nav ul { list-style: none; display: flex; gap: 1.25rem; margin: 0; padding: 0; flex-wrap: wrap; }
.main-nav ul a {
  text-decoration: none; color: #dfe6f0; font-size: 1.12rem;
  display: inline-flex; align-items: center; min-height: 44px;
}
.main-nav ul a:hover { color: var(--funprotec-gold); }
.nav-cta { margin-left: auto; display: flex; gap: 0.6rem; }
.nav-toggle {
  display: none; margin-left: auto; background: transparent; border: 1px solid rgba(255,255,255,0.35);
  color: #fff; font-size: 1.3rem; border-radius: 8px; padding: 0.3rem 0.65rem; cursor: pointer;
}

/* Menú desplegable "La Fundación" — se abre con hover, foco de teclado o clic
   (nav-dropdown.js). El toggle es un <button> real (no un <a>) porque no navega a
   ningún lado por sí mismo, solo abre/cierra la lista.
   OJO: `.nav-dropdown__menu` es un <ul> DENTRO de `.main-nav`, así que el selector
   general `.main-nav ul` (arriba) también lo alcanza y —por ser más específico que
   un `:not([hidden])` sin más contexto— le ganaba en cascada: el menú se veía
   siempre (ignorando `hidden`) y sus links salían con el estilo grande del nav en
   vez del suyo propio (bug real, 2026-08-18, mismo patrón que ya pasó con el popup
   de noticias y el callout institucional). Por eso aquí todo va con el prefijo
   `.main-nav` repetido, para tener más especificidad que `.main-nav ul` / `.main-nav ul a`. */
.nav-dropdown { position: relative; }
.nav-dropdown__toggle {
  background: transparent; border: none; cursor: pointer; font-family: inherit; color: inherit;
  font-size: 1.12rem; /* mismo tamaño que .main-nav ul a — "font: inherit" no alcanzaba: heredaba
    del <li>/<ul> contenedor, no del tamaño explícito que sí tienen los demás <a> del nav, y quedaba
    más chico que el resto — bug real reportado por el usuario, 2026-08-18. */
  display: inline-flex; align-items: center; gap: 0.3rem; padding: 0; min-height: 44px;
}
.nav-dropdown__arrow { font-size: 0.75em; transition: transform 0.15s ease; }
.nav-dropdown__toggle[aria-expanded="true"] .nav-dropdown__arrow { transform: rotate(180deg); }
.main-nav .nav-dropdown__menu[hidden] { display: none; }
.main-nav .nav-dropdown__menu:not([hidden]) {
  display: block; position: absolute; top: 100%; left: 0; margin-top: 0.5rem;
  background: #fff; min-width: 240px; border-radius: 8px; box-shadow: var(--funprotec-shadow);
  padding: 0.5rem; list-style: none; z-index: 60;
}
.main-nav .nav-dropdown__menu a {
  display: flex; align-items: center; min-height: 44px; padding: 0 0.85rem; border-radius: 6px;
  color: var(--card-text); text-decoration: none; font-size: 0.95rem; font-weight: 500;
}
.main-nav .nav-dropdown__menu a:hover { background: #f2f4f8; color: var(--funprotec-orange-ink); }

/* Menú hamburguesa — por debajo de tablet el nav colapsa para no invadir el contenido
   (antes se apilaba en 3-4 líneas y empujaba el hero fuera de la pantalla en celular). */
@media (max-width: 860px) {
  .nav-toggle { display: block; }
  .nav-collapsible {
    display: none; width: 100%; flex-direction: column; align-items: stretch; gap: 1rem;
    padding-top: 0.75rem;
  }
  .main-nav.nav-open .nav-collapsible { display: flex; }
  .main-nav ul { flex-direction: column; gap: 0.75rem; }
  .nav-cta { margin-left: 0; flex-direction: column; }
  /* En el menú colapsado de móvil el submenú se abre inline (no flotando encima),
     mucho más natural cuando todo el nav ya está apilado en una columna. */
  .main-nav .nav-dropdown__menu:not([hidden]) { position: static; box-shadow: none; margin-top: 0.35rem; background: #f7f8fa; }
}
/* min-height 44px: mínimo de área táctil accesible (WCAG 2.5.5 / Apple HIG). */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0.6rem 1.2rem; border-radius: var(--funprotec-radius);
  font-weight: 600; text-decoration: none; font-size: 1.06rem; border: none; cursor: pointer;
  transition: transform 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease;
}
/* Retroalimentación táctil: el botón "cede" ligeramente al presionarlo (150ms,
   dentro del rango recomendado para micro-interacciones — ni instantáneo ni lento). */
.btn:active { transform: scale(0.96); }
.btn-gold { background: var(--funprotec-orange); color: var(--funprotec-on-brand); }
.btn-gold:hover { background: var(--funprotec-orange-dark); }
.btn-outline { background: transparent; color: #fff; border: 1.5px solid #fff; }
.btn-whatsapp { background: var(--funprotec-green-wa); color: #fff; }

/* Verde fosforescente — CTA principal de matrícula, debe saltar a la vista sobre
   cualquier fondo de marca (naranja del hero de programa, navy del hero de home). */
.btn-neon {
  background: #ccff00; color: #0a1e38; font-weight: 800;
  box-shadow: 0 0 12px rgba(204,255,0,0.75), 0 0 2px rgba(204,255,0,0.9);
}
.btn-neon:hover { background: #b8e600; box-shadow: 0 0 16px rgba(204,255,0,0.9); }

/* Hero — foto real de fondo. Reemplazada 2026-08-18 (hero-fondo-v6.jpg, imagen nueva
   entregada por el usuario en "Imagenes paginas web/cargar imagen nueva.jpg"): un
   diorama isométrico de los 6 perfiles técnicos sobre una "isla" flotante, ~2.36:1 de
   proporción — muy cercana a la del propio recuadro del hero en la mayoría de anchos
   (evita el recorte/zoom excesivo que sufría la foto anterior). El archivo original
   traía fondo de estudio gris claro alrededor del diorama; se reemplazó ese gris con
   Python/Pillow+scipy (detección por componentes conectados desde los bordes, ver
   historial) por la referencia exacta pedida por el usuario — primero #798C8C, luego
   ensayada también con #D7D9D2 (probada en vivo, es la que quedó). Ese mismo tono es
   también el background-color de respaldo de .hero, para que se vea igual en el
   pequeño margen que pueda quedar fuera de la imagen con "contain".
   #D7D9D2 es casi blanco: NO alcanza ni de cerca el contraste ≥4.5:1 que necesita el
   texto blanco si se usa tal cual detrás de él, así que el degradado de abajo
   (.hero::after) sigue siendo imprescindible ahí — usa un gris cálido oscuro de la
   MISMA familia (#222221, mismo matiz que #D7D9D2 pero oscurecido) en vez de un tono
   ajeno, para que sea una progresión clara→oscuro de una sola paleta y no dos colores
   distintos peleando. En escritorio el texto vive solo en la franja izquierda así que
   el degradado puede aclarar hacia la derecha (ahí se ve el #D7D9D2 real, sobre todo en
   los márgenes de la foto); en móvil el texto ocupa casi todo el ancho de la caja (ver
   media query más abajo), así que ahí la franja oscura se extiende casi completa — si
   no, el texto de la derecha quedaría sobre el tono claro y perdería contraste. */
.hero {
  position: relative;
  color: #fff; padding: 4rem 1.5rem 3rem;
  min-height: clamp(560px, 42vw, 720px); display: flex; align-items: center;
  background-color: #D7D9D2;
  overflow: hidden;
}
/* La foto vive en su propio ::before (en vez de venir directo en background-image de .hero)
   para poder aplicarle filter sin afectar el texto, si hiciera falta más adelante. */
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background-image: url("../../public/img/hero-fondo-v6.jpg");
  background-repeat: no-repeat; background-position: center; background-size: contain;
}
/* WebP del hero (2026-09-11, ver auditoría de rendimiento: 253KB vs 368KB del .jpg, -31%).
   Envuelto en @supports en vez de reemplazar el url() de arriba sin más: así un navegador
   que no entienda image-set() (rarísimo hoy, pero el resto del sitio ya sigue este criterio
   de "degradar sin romper" — ver .htaccess) simplemente no entra a este bloque y se queda
   con el .jpg de siempre. Los que sí la soportan usan la que corresponda: -webkit-image-set
   primero por compatibilidad con Safari, image-set sin prefijo después (gana por ser la
   última declaración, ambas hacen lo mismo). */
@supports (background-image: -webkit-image-set(url("../../public/img/hero-fondo-v6.webp") 1x)) or (background-image: image-set(url("../../public/img/hero-fondo-v6.webp") 1x)) {
  .hero::before {
    background-image: -webkit-image-set(url("../../public/img/hero-fondo-v6.webp") type("image/webp") 1x);
    background-image: image-set(url("../../public/img/hero-fondo-v6.webp") type("image/webp") 1x);
  }
}
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background-image:
    linear-gradient(100deg, rgba(34,34,33,0.85) 0%, rgba(34,34,33,0.68) 55%, rgba(34,34,33,0.16) 100%),
    radial-gradient(circle at 90% 75%, rgba(244,121,32,0.3) 0%, transparent 35%);
}
@media (max-width: 700px) {
  /* El texto del hero ocupa casi todo el ancho de la caja en celular (no solo la franja
     izquierda de escritorio) — la franja clara del degradado quedaría detrás de texto y
     bajaría el contraste. Se extiende la zona oscura casi hasta el borde. */
  .hero::after {
    background-image:
      linear-gradient(100deg, rgba(34,34,33,0.9) 0%, rgba(34,34,33,0.87) 85%, rgba(34,34,33,0.8) 100%),
      radial-gradient(circle at 90% 75%, rgba(244,121,32,0.3) 0%, transparent 35%);
  }
}
.hero .inner { max-width: 1200px; margin: 0 auto; position: relative; z-index: 1; }
.hero .badge {
  display: inline-block; background: var(--funprotec-orange); color: var(--funprotec-on-brand);
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.03em;
  padding: 0.4rem 0.9rem; border-radius: 6px; margin-bottom: 1.25rem;
}
.hero h1 { font-size: clamp(2rem, 4.5vw, 3.1rem); line-height: 1.15; margin: 0 0 1rem; max-width: 640px; text-shadow: 0 2px 12px rgba(0,0,0,0.6); }
.hero h1 .accent { color: var(--funprotec-orange); }
.hero p.lead { color: #d7deea; max-width: 520px; margin: 0 0 1.75rem; font-size: 1.02rem; text-shadow: 0 1px 8px rgba(0,0,0,0.6); }
.hero .hero-ctas { display: flex; gap: 0.85rem; flex-wrap: wrap; margin-bottom: 2.5rem; }

.hero-stats {
  display: flex; gap: 2.5rem; flex-wrap: wrap;
}
.hero-stats .stat strong { display: block; font-size: 1.9rem; color: #fff; text-shadow: 0 1px 8px rgba(0,0,0,0.6); }
.hero-stats .stat span { font-size: 0.8rem; color: #b9c4d8; text-shadow: 0 1px 6px rgba(0,0,0,0.6); }

/* "¿Qué quieres estudiar?" — patrón UNAD: chips de nivel + select + accesos directos al lado.
   Margen superior subido ~1cm (2.35rem) respecto al solape original con el hero, para
   dejar más foto de fondo visible antes de que empiece este recuadro blanco. */
.finder-wrap {
  max-width: 1200px; margin: -0.4rem auto 0; padding: 0 1.5rem;
  position: relative; z-index: 2;
  display: grid; grid-template-columns: 2fr 1fr; gap: 1.25rem;
}
@media (max-width: 860px) { .finder-wrap { grid-template-columns: 1fr; } }

/* Variante para páginas donde el buscador va solo, sin los "Accesos Directos" al
   lado (hoy: oferta-academica.html) — bug real reportado por el usuario, 2026-08-18:
   heredaba el grid de 2 columnas (2fr 1fr) pensado para el home, y como solo había
   un hijo, quedaba metido en la columna izquierda con un hueco vacío a la derecha —
   se veía "justificado a la izquierda" en vez de centrado. La página de inicio no se
   toca: sigue con su grid de 2 columnas de siempre. */
.finder-wrap--standalone { grid-template-columns: 1fr; max-width: 760px; }

.program-finder {
  background: #fff; color: var(--card-text);
  border-radius: var(--funprotec-radius); box-shadow: var(--funprotec-shadow);
  padding: 1.5rem;
}
.program-finder h2 { font-size: 1.15rem; margin: 0 0 1rem; color: var(--card-text); }
.finder-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1rem; }
.finder-chips label {
  display: flex; align-items: center; gap: 0.45rem; font-size: 0.9rem; font-weight: 600;
  background: #f2f4f8; border: 1px solid #e1e5ec; border-radius: 22px; padding: 0.5rem 1rem;
  min-height: 44px; cursor: pointer; color: var(--card-text);
}
.finder-chips input[type="radio"] { width: 18px; height: 18px; cursor: pointer; }
.finder-chips input { accent-color: var(--funprotec-orange); }
.finder-row { display: flex; gap: 0.75rem; flex-wrap: wrap; align-items: flex-start; }
.finder-row select, .finder-row input[type="search"] {
  min-height: 44px; padding: 0.65rem 0.85rem; border: 1px solid #d5d9e1; border-radius: 8px;
  font-size: 1rem; width: 100%; color: var(--card-text); background: #fff;
}
.search-wrap { position: relative; flex: 1; min-width: 180px; }

/* Dropdown de sugerencias — se despliega al enfocar/escribir en el buscador */
.search-suggestions {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0;
  background: #fff; border: 1px solid #e1e5ec; border-radius: 10px;
  box-shadow: var(--funprotec-shadow); list-style: none; margin: 0; padding: 0.4rem;
  max-height: 280px; overflow-y: auto; z-index: 20;
}
.search-suggestions[hidden] { display: none; }
.search-suggestions li { margin: 0; }
.search-suggestions .sugg-group {
  font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--card-text-muted); padding: 0.5rem 0.6rem 0.2rem;
}
.search-suggestions button {
  display: block; width: 100%; text-align: left; background: none; border: none;
  padding: 0.55rem 0.6rem; border-radius: 6px; font-size: 0.88rem; color: var(--card-text);
  cursor: pointer;
}
.search-suggestions button:hover, .search-suggestions button.active { background: #fdeee1; color: var(--funprotec-orange-ink); }
.search-suggestions .sugg-empty { padding: 0.6rem; font-size: 0.85rem; color: var(--card-text-muted); }

/* ---- Selector de vista (escritorio / tablet / móvil) ----
   La detección es automática por ancho real del dispositivo (ver media queries del
   sitio). Este control permite además FORZAR una vista concreta: útil para que la
   Dirección revise cómo se ve el sitio en celular sin tener que abrirlo en uno.
   Al forzar, se simula el ancho con un contenedor y se activan las mismas reglas. */
/* 2026-09-23, a pedido del usuario: el selector va como barra vertical en el costado izquierdo
   (antes centrado abajo, tapaba los datos del pie de página). Botones apilados, icono sobre texto
   para que la barra sea angosta. */
.view-switch {
  position: fixed; top: 50%; left: 0.1rem; transform: translateY(-50%);
  z-index: 210; display: flex; flex-direction: column; gap: 0.2rem;
  background: var(--funprotec-navy-bg); padding: 0.25rem; border-radius: 18px;
  box-shadow: 0 6px 18px rgba(0,0,0,0.3);
}
.view-switch button {
  min-height: 44px; min-width: 44px; padding: 0.3rem 0.2rem; border: none; cursor: pointer;
  background: transparent; color: var(--funprotec-navy-dark); border-radius: 14px;
  font-size: 0.62rem; font-weight: 600; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.1rem;
}
.view-switch button[aria-pressed="true"] {
  background: var(--funprotec-orange); color: var(--funprotec-on-brand);
}
/* Cuando se fuerza una vista, el sitio se encuadra al ancho simulado. */
body.vista-forzada { background: #23282f; }
body.vista-forzada > *:not(.view-switch) {
  max-width: var(--ancho-simulado);
  margin-left: auto; margin-right: auto;
}
body.vista-forzada .main-nav,
body.vista-forzada .prog-nav { position: static; }
body.vista-forzada .fab-stack,
body.vista-forzada .a11y-float { position: absolute; }
@media (max-width: 700px) {
  /* En un celular real el selector estorbaría: se oculta y manda la detección automática. */
  .view-switch { display: none; }
}

/* Botones flotantes (FAB), esquina inferior derecha: Formulario CRM y, encima, el de WhatsApp que dibuja Kommo */
.fab-stack {
  position: fixed; bottom: 1.25rem; right: 1.25rem; z-index: 200;
  display: flex; flex-direction: column; gap: 0.75rem; align-items: flex-end;
  opacity: 0; pointer-events: none; transition: opacity 0.2s ease;
}
.fab-stack.is-visible { opacity: 1; pointer-events: auto; }
.a11y-float { opacity: 0; pointer-events: none; transition: opacity 0.2s ease; }
.a11y-float.is-visible { opacity: 1; pointer-events: auto; }
@media (min-width: 861px) {
  /* En escritorio el hero es lo bastante ancho para que no choquen con los CTA — visibles siempre. */
  .fab-stack, .a11y-float { opacity: 1; pointer-events: auto; }
}
.fab {
  width: 52px; height: 52px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  font-size: 1.3rem; text-decoration: none; color: #fff; box-shadow: 0 6px 18px rgba(0,0,0,0.28);
  transition: transform 0.15s ease;
}
.fab:hover { transform: scale(1.06); }
.fab-crm { background: var(--funprotec-navy); width: 46px; height: 46px; font-size: 1.1rem; }

/* Botón de WhatsApp de Kommo (kommo-boton.js). Kommo lo inserta al final del <body> y le pone
   posición y tamaño con atributos style="..."; el tamaño lo bloquea la CSP (sin 'unsafe-inline'),
   así que se fija aquí. La posición sí llega (la pone por JavaScript), por eso lleva !important:
   va en la esquina inferior derecha, encima del botón 🗂️ y centrado con él. El contenedor de
   Kommo trae 7px de margen interno alrededor del botón de 60px.
   Kommo le pone z-index 311 o 401: flotaba encima del aviso de cookies (310), del menú lateral
   (301) y del popup de noticias (300). Se deja en la misma capa que .fab-stack. */
.amo-button-holder {
  right: calc(1.25rem + 23px - 37px) !important;
  bottom: calc(1.25rem + 46px + 0.75rem - 7px) !important;
  z-index: 200 !important;
  transition: opacity 0.2s ease;
}
.amo-button-holder .amo-button { width: 60px; height: 60px; border-radius: 30px; }
/* Etiqueta de marca de Kommo: es invisible, pero quedaba encima del borde superior del botón 🗂️ y le robaba el clic. */
.amo-button-holder .amo-brand { pointer-events: none; }
@media (max-width: 860px) {
  /* En móvil aparece y desaparece junto con .fab-stack (que va antes en el <body>). */
  .fab-stack:not(.is-visible) ~ .amo-button-holder { opacity: 0; pointer-events: none; }
}

/* Formulario CRM (piloto, sin conectar) */
.crm-form {
  background: #fff; border-radius: var(--funprotec-radius); box-shadow: var(--funprotec-shadow);
  padding: 1.5rem; max-width: 720px;
}
.crm-form .form-row { display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem; }
.crm-form label { flex: 1; min-width: 220px; font-size: 0.85rem; font-weight: 600; color: var(--card-text); }
.crm-form input, .crm-form select {
  display: block; width: 100%; margin-top: 0.35rem; min-height: 44px; padding: 0.6rem 0.75rem;
  border: 1px solid #d5d9e1; border-radius: 8px; font-size: 1rem; font-weight: 400;
  color: var(--card-text); background: #fff;
}
/* Mensaje de confirmación tras enviar el formulario de demostración (2026-08-20):
   antes usaba alert() nativo del navegador, que en una demo frente a stakeholders
   se ve como un error/bug sin manejar, no como una confirmación. Este mensaje inline
   deja claro (con el mismo tono honesto que el resto del sitio) que el envío es
   simulado hasta que se conecte un CRM real. */
.crm-form__msg {
  margin-top: 1rem; padding: 0.85rem 1rem; border-radius: 8px;
  background: #eafaf0; color: #0f5132; border: 1px solid #b7e4c7;
  font-size: 0.9rem; font-weight: 600;
}

.quick-links {
  background: #fff; border-radius: var(--funprotec-radius); box-shadow: var(--funprotec-shadow);
  padding: 1.5rem;
}
.quick-links h2 { font-size: 1.15rem; margin: 0 0 1rem; color: var(--card-text); }
.quick-links ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.6rem; }
.quick-links a {
  text-decoration: none; color: var(--card-text); font-weight: 600; font-size: 0.87rem;
  display: flex; align-items: center; gap: 0.5rem;
}
.quick-links a:hover { color: var(--funprotec-orange-ink); }

/* Botón flotante de accesibilidad, patrón UNAD */
.a11y-float {
  position: fixed; bottom: 1.25rem; left: 1.25rem; z-index: 200;
  width: 48px; height: 48px; border-radius: 50%; background: var(--funprotec-navy);
  color: #fff; border: none; display: flex; align-items: center; justify-content: center;
  font-size: 1.2rem; box-shadow: 0 4px 14px rgba(0,0,0,0.25); cursor: pointer;
}

/* Secciones genéricas */
section.block { max-width: 1200px; margin: 3.5rem auto; padding: 0 1.5rem; }
section.block h2 { font-size: 1.6rem; margin-bottom: 0.4rem; }
section.block p.section-lead { color: var(--funprotec-text-muted); max-width: 680px; margin-bottom: 1.75rem; }

.grid-programs {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.25rem;
}
.program-card {
  background: #fff; border-radius: var(--funprotec-radius); overflow: hidden;
  box-shadow: 0 2px 10px rgba(20,40,80,0.08); display: flex; flex-direction: column;
  outline: 3px solid transparent;
  transition: outline-color 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease;
}
/* La tarjeta "flota" un poco al pasar el mouse — solo transform/box-shadow (rendimiento: no
   dispara reflow) y únicamente en dispositivos con hover real, para no dejarla "pegada" al tacto. */
@media (hover: hover) {
  .program-card:hover { transform: translateY(-6px); box-shadow: 0 10px 24px rgba(20,40,80,0.16); }
}
.program-card--highlight { outline-color: var(--funprotec-orange); }

/* ---- Revelado al hacer scroll ----
   Estado inicial oculto/desplazado; `.is-visible` lo activa un IntersectionObserver
   (ver src/scripts/animaciones.js). Con "reducir movimiento" activado, la media query
   global ya lleva las transiciones a ~0ms, así que el contenido aparece igual, sin salto. */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity 0.5s ease, transform 0.5s ease; }
.reveal.is-visible { opacity: 1; transform: translateY(0); }
/* Efecto escalonado: las tarjetas de una misma cuadrícula no aparecen todas a la vez. */
.grid-programs .reveal:nth-child(2), .plan-grid .reveal:nth-child(2) { transition-delay: 0.05s; }
.grid-programs .reveal:nth-child(3), .plan-grid .reveal:nth-child(3) { transition-delay: 0.1s; }
.grid-programs .reveal:nth-child(4), .plan-grid .reveal:nth-child(4) { transition-delay: 0.15s; }
.grid-programs .reveal:nth-child(n+5), .plan-grid .reveal:nth-child(n+5) { transition-delay: 0.2s; }
.program-card .thumb {
  aspect-ratio: 4 / 3; flex-shrink: 0; background: linear-gradient(135deg, var(--funprotec-navy), var(--funprotec-orange));
  display: flex; align-items: center; justify-content: center; color: #fff; font-size: 0.75rem;
  text-align: center; padding: 0.5rem;
}
/* Foto real: cada archivo ya se generó en proporción 4:3 exacta (con relleno de fondo
   desenfocado de sí misma cuando el original no calzaba), así que "cover" llena el 100%
   del recuadro sin recortar nada real — la caja y la imagen tienen la misma proporción.
   FIX 2026-09-01: se retiró "height: 100%" de acá — combinado con aspect-ratio dentro de
   una tarjeta flex-column estirada por la cuadrícula (grid stretch), hacía que la altura
   real del recuadro NO respetara el 4:3 (variaba tarjeta por tarjeta, 200-360px con el
   mismo ancho), recortando por los lados imágenes con texto pegado al borde izquierdo
   (ej. Excel Empresarial, Ofimática Básica) y dejando el título ilegible. Con "width: 100%"
   y sin "height", aspect-ratio (heredado de .thumb) calcula la altura de forma consistente
   siempre; flex-shrink:0 en .thumb evita que la fila estirada la comprima por debajo de eso. */
.program-card .thumb--foto {
  padding: 0; object-fit: cover; width: 100%;
}
.program-card .body { padding: 1rem; flex: 1; display: flex; flex-direction: column; }
.program-card h3 { margin: 0 0 0.4rem; font-size: 1.05rem; color: var(--card-text); }
.program-card p { font-size: 0.88rem; color: var(--card-text-muted); flex: 1; }
.program-card .price { font-weight: 700; color: var(--funprotec-navy); margin: 0.5rem 0; }
.program-card .price small { display: block; font-weight: 400; color: var(--card-text-muted); font-size: 0.75rem; }

.badge-pendiente {
  display: inline-block; background: #fff3cd; color: #7a5c00; font-size: 0.7rem;
  padding: 0.15rem 0.5rem; border-radius: 6px; margin-bottom: 0.5rem; font-weight: 600;
}
/* Bug real (2026-08-25, mismo patrón que .modal-overlay[hidden] en blog.css): el
   `display: inline-block` de arriba, al ser regla de autor, le gana en la cascada al
   `display: none` del atributo `hidden` cuando programa.js oculta este badge (malla
   curricular ya confirmada) — sin esto, el badge seguía visible con datos que ya no
   son "propuesta pendiente". Detectado al confirmar Investigación Judicial. */
.badge-pendiente[hidden] { display: none; }

/* Barra "Volver a la página de inicio" — nació en programa.css (el logo y el enlace del pie
   no eran lo bastante visibles), y ahora vive aquí (2026-08-25) para que las 6 páginas del
   sitio puedan usarla sin cargar programa.css completo — a pedido del usuario, todas deben
   tener una forma clara y visible de volver al inicio, no solo el logo o un enlace en el pie. */
/* 2026-10-01, a pedido del usuario: el enlace pasa de texto azul a botón naranja de marca (mismo color
   que "Ir a la página de inicio" del pie), para que se vea de inmediato. El relleno lateral de la barra
   alinea el botón con el contenido centrado a 1200px. Aplica también a "Volver al blog" (blog-post.html). */
.volver-inicio-bar {
  background: #f2f4f8; border-bottom: 1px solid #e5e8ee;
  padding: 0.5rem max(1.5rem, calc((100% - 1200px) / 2 + 1.5rem));
}
.volver-inicio-bar .volver-inicio {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0.4rem 1.1rem;
  border-radius: var(--funprotec-radius); background: var(--funprotec-orange); color: var(--funprotec-on-brand);
  font-weight: 700; font-size: 0.95rem; text-decoration: none; box-shadow: 0 2px 8px rgba(244,121,32,0.4);
  transition: transform 0.15s ease, background-color 0.15s ease;
}
.volver-inicio-bar .volver-inicio:hover { background: var(--funprotec-orange-dark); }
.volver-inicio-bar .volver-inicio:active { transform: scale(0.96); }

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 1.5rem; text-align: center; }
/* Verde fosforescente (mismo tono que .btn-neon) para que las cifras "salten a la
   vista" sobre el fondo blanco de la sección — a pedido del usuario, 2026-08-18.
   #ccff00 sobre blanco no cumple contraste de texto normal (WCAG AA), por eso se
   usa aquí en tamaño grande/negrita (1.8rem ⁠— pasa el umbral de "texto grande",
   3:1) y con un borde de texto oscuro que refuerza la legibilidad sin apagar el brillo. */
/* 2026-09-23, a pedido del usuario: cifras 3 pt más grandes (1.8rem → ~2.05rem) y más gruesas, y texto
   de abajo en blanco. El blanco necesita fondo oscuro para leerse, así que cada cifra va en una
   tarjeta navy; sobre ese fondo el verde fosforescente contrasta de sobra (se quita el contorno). */
.stats .stat {
  padding: 1.4rem 1rem; border-radius: 16px; box-shadow: var(--funprotec-shadow);
  background: linear-gradient(160deg, var(--funprotec-navy-dark) 0%, var(--funprotec-navy) 100%);
}
.stats .stat strong {
  display: block; font-size: calc(1.8rem + 3pt); font-weight: 900; color: #ccff00; line-height: 1.1;
  text-shadow: 0 0 12px rgba(204,255,0,0.55);
}
.stats .stat span { display: block; margin-top: 0.35rem; color: #fff; font-size: 0.9rem; font-weight: 600; }

/* Footer de cumplimiento, patrón UNAD — mismo fondo claro institucional que el nav. */
footer {
  background: var(--funprotec-navy-bg); color: var(--funprotec-navy-dark); padding: 3rem 1.5rem 1.5rem; margin-top: 4rem;
}
footer .inner { max-width: 1200px; margin: 0 auto; display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 2rem; }
footer h4 { color: var(--funprotec-navy-dark); font-size: 0.9rem; margin-bottom: 0.75rem; }
/* Títulos del pie: párrafo en vez de <h4> (2026-09-21, auditoría SEO): el h4 saltaba niveles
   de encabezado en las 9 páginas (h2 → h4, o h1 → h4). Mismo aspecto que tenía el h4. */
.footer-heading { color: var(--funprotec-navy-dark); font-size: 0.9rem; font-weight: 700; margin: 1.2rem 0 0.75rem; }
footer ul { list-style: none; padding: 0; margin: 0; }
footer li { margin-bottom: 0.4rem; font-size: 0.82rem; }
footer a { text-decoration: none; color: var(--funprotec-navy-dark); }
footer a:hover { color: var(--funprotec-orange-ink); }
/* Botones del pie (2026-10-01, observación del rector): al terminar de leer una página había que
   desplazarse con el mouse hasta arriba para volver. "Subir" lleva al comienzo de la misma página
   (href="#", sin recargar) e "Ir a la página de inicio" a index.html (no va en la propia portada). */
.footer-acciones { max-width: 1200px; margin: 2rem auto 0; display: flex; flex-wrap: wrap; justify-content: center; gap: 0.75rem; }
footer .footer-acciones .btn-gold:hover { color: var(--funprotec-on-brand); }
/* "Subir" en verde fosforescente (.btn-neon, 2026-10-01, a pedido del usuario: color vibrante de la paleta). */
footer .footer-acciones .btn-neon:hover { color: #0a1e38; }
.footer-bottom {
  max-width: 1200px; margin: 2rem auto 0; padding-top: 1.25rem; border-top: 1px solid rgba(10,30,56,0.2);
  font-size: 0.75rem; color: var(--funprotec-navy); text-align: center;
}

/* ---- Utilidades para eliminar style="" inline (2026-09-08) ----
   Necesario para poder quitar 'unsafe-inline' de style-src en la CSP del .htaccess,
   a pedido del usuario ("cerremos el hueco de unsafe-inline"). Cada una reemplaza
   un style="" puntual que había directo en el HTML o en las plantillas de tarjetas
   armadas por JS (home-teasers.js, oferta-academica.js, blog.js) — mismo resultado
   visual, sin cambiar nada más. */
.u-push-right { margin-left: auto; }
.u-text-small { font-size: 0.85rem; }
.u-full-width { width: 100%; }
/* Variante de .btn-outline con navy en vez de blanco — para usarla sobre fondo claro
   (tarjetas, secciones blancas), a diferencia de .btn-outline "normal" (blanco),
   pensado para ir sobre el hero oscuro. */
.btn-outline-navy { color: var(--funprotec-navy); border-color: var(--funprotec-navy); }
/* .badge-pendiente trae margin-bottom por defecto (pensado para uso en bloque); esta
   variante lo quita para los casos en que va inline dentro de un <li> de texto
   corrido (footer, "Cumplimiento"). */
.badge-pendiente--inline { margin: 0; }

/* Tabla de la política de cookies (2026-09-08) — envuelta en .tabla-scroll para que
   una tabla ancha en pantallas angostas desborde con su propio scroll horizontal en
   vez de romper el layout de la página (regla general del sitio: nada scrollea el
   body completo hacia los lados). */
.tabla-scroll { overflow-x: auto; margin: 1rem 0; }
.tabla-cookies { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.tabla-cookies th { text-align: left; padding: 0.5rem 0.75rem; border-bottom: 2px solid #e5e8ee; }
.tabla-cookies td { padding: 0.5rem 0.75rem; border-bottom: 1px solid #eee; vertical-align: top; }
.tabla-cookies tbody tr:last-child td { border-bottom: none; }

/* Auditoría web-design-guidelines (2026-09-21) ---------------------------------------
   - scroll-padding-top: las barras de navegación son sticky; sin esto, los enlaces a
     #sedes, #crm-form, #plan-estudios, etc. dejaban el título tapado bajo la barra.
   - text-wrap: balance evita títulos con una palabra suelta en la última línea.
   - touch-action: manipulation quita el retraso de doble toque en móviles.
   - overscroll-behavior en el popup evita que el fondo se desplace al llegar al final. */
html { scroll-padding-top: 6rem; }
h1, h2, h3 { text-wrap: balance; }
a, button, input, select, summary, label { touch-action: manipulation; }
.modal-overlay, .modal-card { overscroll-behavior: contain; }

/* Botón de preinscripción estilo "sala de juegos" (2026-09-22, a pedido del usuario). Abre el
   formulario de Q10. Cara dorada + halo magenta que respira + bombillos parpadeantes + brillo
   que barre el botón. Texto navy sobre dorado: contraste ~11:1 (AA). Todo se anima con
   transform/opacity; parpadeo a ~1,7 Hz (bajo el umbral de 3 Hz de WCAG 2.3.1) y se apaga con
   prefers-reduced-motion. Colores propios del botón: es un CTA de excepción, no un token de marca. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.preinscripcion {
  max-width: 720px; margin: 1.5rem auto 0; padding: 2.25rem 1.25rem 1.75rem; text-align: center;
  border-radius: 16px; color: #fff;
  background: radial-gradient(ellipse at 50% 0%, #2a4f86 0%, var(--funprotec-navy) 45%, #0a1e38 100%);
  box-shadow: var(--funprotec-shadow);
}
.prog-form .preinscripcion { background: none; box-shadow: none; padding: 1.25rem 0 0.25rem; margin-top: 0; }
.preinscripcion__kicker {
  display: block; width: fit-content; margin: 0 auto 1.4rem; padding: 0.3rem 0.9rem; border-radius: 999px;
  background: #ff1f6b; color: #fff; font-weight: 800; font-size: 0.85rem; letter-spacing: 0.12em;
  text-transform: uppercase;
}
.preinscripcion__nota { margin: 1.4rem 0 0; font-size: 0.9rem; color: #dbe4f3; }
.btn-preinscripcion {
  position: relative; isolation: isolate; overflow: visible;
  display: inline-flex; align-items: center; justify-content: center; gap: 0.75rem;
  min-height: 68px; padding: 0.9rem 2.1rem; max-width: 100%;
  border-radius: 999px; border: 4px solid #fff; text-decoration: none; cursor: pointer;
  background: linear-gradient(180deg, #fff27a 0%, #ffd60a 45%, #ffb000 100%);
  color: #0a1e38; font-weight: 900; font-size: clamp(1.15rem, 4.6vw, 1.6rem);
  letter-spacing: 0.06em; text-transform: uppercase; line-height: 1.15;
  box-shadow: 0 6px 0 #b86e00, 0 0 0 5px #ff1f6b;
  animation: preinsc-pulso 1.6s ease-in-out infinite;
  transition: filter 0.15s ease;
}
.btn-preinscripcion__texto { position: relative; z-index: 1; }
.btn-preinscripcion__icono { flex-shrink: 0; position: relative; z-index: 1; }
/* Halo de neón: capa aparte que solo cambia de opacidad (más barato que animar box-shadow). */
.btn-preinscripcion::before {
  content: ""; position: absolute; inset: -12px; z-index: -1; border-radius: inherit;
  box-shadow: 0 0 28px 8px rgba(255,31,107,0.85), 0 0 70px 22px rgba(255,176,0,0.55);
  animation: preinsc-halo 1.6s ease-in-out infinite;
}
/* Bombillos de marquesina: anillo punteado que alterna de color. */
.btn-preinscripcion::after {
  content: ""; position: absolute; inset: -17px; z-index: -1; border-radius: inherit; pointer-events: none;
  border: 5px dotted #fff; animation: preinsc-bombillos 0.6s steps(1, end) infinite;
}
.btn-preinscripcion:hover { filter: brightness(1.08) saturate(1.15); }
.btn-preinscripcion:active { translate: 0 4px; box-shadow: 0 2px 0 #b86e00, 0 0 0 5px #ff1f6b; }
.btn-preinscripcion:focus-visible { outline: 4px solid #fff; outline-offset: 10px; border-radius: 999px; }
@keyframes preinsc-pulso { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } }
@keyframes preinsc-halo { 0%, 100% { opacity: 0.45; } 50% { opacity: 1; } }
@keyframes preinsc-bombillos { 0% { border-color: #fff; } 50% { border-color: #ffd60a; } }
@media (max-width: 480px) {
  .btn-preinscripcion { width: 100%; padding: 0.9rem 1.1rem; gap: 0.5rem; letter-spacing: 0.03em; }
  .btn-preinscripcion__icono { width: 22px; height: 22px; }
  .btn-preinscripcion__flecha { width: 32px; height: 32px; }
}
/* Flecha llamativa (2026-09-23, a pedido del usuario): va sobre una pastilla navy para que los
   colores vibrantes resalten sobre el dorado. Cambia de color cada 0,4 s (5 colores en 2 s),
   titila en opacidad y se desplaza hacia el botón. Sin destellos de alto contraste: los cambios
   son de matiz sobre fondo oscuro, a ~2,5 Hz. Se detiene con prefers-reduced-motion. */
.btn-preinscripcion__flecha {
  flex-shrink: 0; position: relative; z-index: 1; box-sizing: border-box; width: 40px; height: 40px; padding: 7px;
  border-radius: 50%; background: #0a1e38; color: #ff1f6b;
  animation: preinsc-flecha-mov 0.8s ease-in-out infinite alternate,
             preinsc-flecha-color 2s steps(1, end) infinite,
             preinsc-flecha-titilar 1.2s ease-in-out infinite;
}
@keyframes preinsc-flecha-mov { from { transform: translateX(-2px); } to { transform: translateX(5px); } }
@keyframes preinsc-flecha-titilar { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
@keyframes preinsc-flecha-color {
  0% { color: #ff1f6b; } 20% { color: #00e5ff; } 40% { color: #7cff00; } 60% { color: #ffd60a; } 80% { color: #d264ff; }
}
/* Versión compacta para la barra de navegación (sin aro de bombillos: no cabe). */
.btn-preinscripcion--nav {
  min-height: 48px; padding: 0.35rem 0.5rem 0.35rem 1.1rem; gap: 0.55rem; border-width: 3px;
  font-size: 1rem; letter-spacing: 0.04em; box-shadow: 0 4px 0 #b86e00, 0 0 0 3px #ff1f6b;
}
.btn-preinscripcion--nav::before { inset: -8px; box-shadow: 0 0 18px 4px rgba(255,31,107,0.8), 0 0 40px 10px rgba(255,176,0,0.5); }
.btn-preinscripcion--nav::after { display: none; }
.btn-preinscripcion--nav .btn-preinscripcion__flecha { width: 34px; height: 34px; padding: 6px; }
@media (max-width: 860px) { .btn-preinscripcion--nav { width: 100%; } }
@media (prefers-reduced-motion: reduce) {
  .btn-preinscripcion, .btn-preinscripcion::before, .btn-preinscripcion::after,
  .btn-preinscripcion::before { opacity: 0.8; }
}

/* Marquesina de bombillos (preinscripcion.js): 3 anillos de luces (blanco, dorado, cian) que se
   encienden por turnos y "corren" alrededor del botón. Cada bombillo apagado queda tenue (no
   desaparece) para que se lea como un letrero real. Un bombillo cambia ~1 vez por segundo. */
.btn-preinscripcion.tiene-marquesina::after { display: none; }
.marquesina {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  z-index: -1; pointer-events: none; overflow: visible;
}
.marquesina rect { stroke: currentColor; opacity: 0.12; animation: preinsc-luz 1s steps(1, end) infinite; }
.marquesina__a { color: #ffffff; filter: drop-shadow(0 0 5px #ffffff); }
.marquesina rect.marquesina__b { color: #ffd60a; filter: drop-shadow(0 0 5px #ffb000); animation-delay: -0.667s; }
.marquesina rect.marquesina__c { color: #22e6ff; filter: drop-shadow(0 0 5px #22e6ff); animation-delay: -0.333s; }
@keyframes preinsc-luz { 0% { opacity: 1; } 33.3% { opacity: 0.12; } 100% { opacity: 0.12; } }
@media (prefers-reduced-motion: reduce) {
  .marquesina rect { animation: preinsc-luz-suave 2.4s ease-in-out infinite !important; }
  .marquesina rect.marquesina__b { animation-delay: -1.6s !important; }
  .marquesina rect.marquesina__c { animation-delay: -0.8s !important; }
}
@keyframes preinsc-luz-suave { 0%, 100% { opacity: 0.12; } 33% { opacity: 1; } 66% { opacity: 0.12; } }

/* ===== Selector de aspecto: Claro / Oscuro / Dispositivo (2026-09-23) =====
   Botón flotante (izquierda, sobre el de accesibilidad) que abre un menú de 3 opciones. Colores
   propios (navy + blanco) para que se lea igual en cualquier aspecto. */
.tema-float { position: fixed; left: 1.25rem; bottom: 5.4rem; z-index: 205; }
.tema-float__boton {
  width: 48px; height: 48px; border-radius: 50%; border: 2px solid #fff; cursor: pointer;
  background: var(--funprotec-navy); color: #ffd166; display: grid; place-items: center;
  box-shadow: 0 4px 14px rgba(0,0,0,0.3); transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.tema-float__boton:hover { transform: scale(1.08); box-shadow: 0 0 0 3px rgba(255,209,102,0.5), 0 6px 18px rgba(0,0,0,0.35); }
.tema-float__menu {
  position: absolute; left: 58px; bottom: 0; min-width: 190px; padding: 0.5rem; border-radius: 14px;
  background: #0a1e38; color: #fff; box-shadow: 0 10px 30px rgba(0,0,0,0.4); border: 1px solid rgba(255,255,255,0.2);
}
.tema-float__menu[hidden] { display: none; }
.tema-float__titulo { margin: 0.2rem 0.6rem 0.4rem; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: #ffd166; }
.tema-float__opcion {
  display: flex; align-items: center; gap: 0.65rem; width: 100%; min-height: 44px; padding: 0.4rem 0.7rem; border: 0; border-radius: 10px;
  background: transparent; color: #fff; font: inherit; font-weight: 600; cursor: pointer; text-align: left;
  transition: background-color 0.15s ease;
}
.tema-float__opcion:hover { background: rgba(255,255,255,0.14); }
.tema-float__opcion[aria-checked="true"] { background: #ffd166; color: #0a1e38; }
body.vista-forzada .tema-float { position: absolute; }

/* ===== Tarjetas de programas técnicos con su color (oferta académica, 2026-09-23) =====
   A pedido de la Rectoría: colores más llamativos para aspirantes jóvenes, en lugar del naranja y el
   blanco uniformes. Cada tarjeta lleva data-programa=<id> (oferta-academica.js) y toma la paleta de
   programas-color.css. Botón invertido (fondo = color del texto) para que resalte en cualquier color. */
.program-card[data-programa] {
  background: linear-gradient(165deg, var(--prog-bg), var(--prog-bg-2)); color: var(--prog-ink);
  box-shadow: 0 8px 22px rgba(0,0,0,0.22);
}
.program-card[data-programa] h3 { color: var(--prog-ink); font-size: 1.2rem; font-weight: 800; }
.program-card[data-programa] p { color: var(--prog-ink); opacity: 0.94; }
.program-card[data-programa] .price { color: var(--prog-ink); }
.program-card[data-programa] .price small { color: var(--prog-ink); opacity: 0.85; }
.program-card[data-programa] .btn {
  background: var(--prog-ink); color: var(--prog-bg); font-weight: 800;
  box-shadow: 0 4px 0 rgba(0,0,0,0.25);
}
.program-card[data-programa] .btn:hover { filter: brightness(1.08); }
.program-card[data-programa] .thumb--foto { border-bottom: 5px solid var(--prog-ink); }
@media (hover: hover) {
  .program-card[data-programa]:hover { box-shadow: 0 0 0 3px var(--prog-ink), 0 16px 36px rgba(0,0,0,0.35); }
}

/* ===== Menú lateral derecho (botón de 3 líneas), en todas las páginas (2026-09-23) =====
   Lo arma menu-lateral.js. Cada entrada tiene su propio color (--c) para distinguirse; al pasar el
   cursor se ilumina con halo y al presionar/enfocar se rellena. Panel oscuro para que los colores
   vibrantes resalten en cualquier aspecto (claro u oscuro). */
html.menu-abierto { overflow: hidden; }
.menu-float__boton {
  position: fixed; right: 0.7rem; top: 0.7rem; z-index: 300; width: 54px; height: 54px; border-radius: 16px; cursor: pointer;
  border: 2px solid #fff; background: linear-gradient(135deg, #ff1f6b, #ff9a3d); display: grid; place-items: center;
  box-shadow: 0 6px 18px rgba(0,0,0,0.35), 0 0 22px rgba(255,31,107,0.55); transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.menu-float__boton:hover { transform: scale(1.08); box-shadow: 0 6px 18px rgba(0,0,0,0.35), 0 0 30px rgba(255,154,61,0.8); }
.menu-float__boton:focus-visible { outline: 3px solid #ffd166; outline-offset: 3px; }
.menu-float__barras { display: grid; gap: 5px; }
.menu-float__barras i { display: block; width: 26px; height: 3px; border-radius: 3px; background: #fff; transition: transform 0.25s ease, opacity 0.2s ease; }
.menu-float--abierto .menu-float__barras i:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.menu-float--abierto .menu-float__barras i:nth-child(2) { opacity: 0; }
.menu-float--abierto .menu-float__barras i:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }
.menu-float__velo { position: fixed; inset: 0; z-index: 299; background: rgba(6,16,31,0.62); }
.menu-float__velo[hidden] { display: none; }
.menu-float__panel {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 301; width: min(390px, 92vw); overflow-y: auto; overscroll-behavior: contain;
  color: #fff; padding: 1rem 1rem 1.5rem; visibility: hidden; transform: translateX(105%);
  background:
    radial-gradient(circle at 15% 6%, rgba(56,189,248,0.22), transparent 40%),
    radial-gradient(circle at 90% 95%, rgba(255,31,107,0.20), transparent 42%),
    linear-gradient(170deg, #0a1e38 0%, #14345c 100%);
  box-shadow: -12px 0 40px rgba(0,0,0,0.45); transition: transform 0.3s ease, visibility 0.3s;
}
.menu-float--abierto .menu-float__panel { transform: none; visibility: visible; }
.menu-float__cabecera { position: relative; display: grid; gap: 0.15rem; padding: 0.4rem 3rem 1rem 0.4rem; }
.menu-float__cabecera strong { font-size: 1.5rem; letter-spacing: 0.04em; }
.menu-float__cabecera span { color: #ffd166; font-weight: 700; font-size: 0.9rem; }
.menu-float__cerrar {
  position: absolute; right: 0; top: 0.2rem; width: 44px; height: 44px; border-radius: 50%; border: 0; cursor: pointer;
  background: rgba(255,255,255,0.14); color: #fff; display: grid; place-items: center;
}
.menu-float__cerrar:hover { background: #ff1f6b; }
.menu-float__lista { display: grid; gap: 0.55rem; }
.menu-float__pre { margin: 0.9rem 1.2rem 1.3rem 0.5rem; }
.menu-float__item {
  --c: #38bdf8; display: flex; align-items: center; gap: 0.75rem; min-height: 52px; padding: 0.55rem 0.8rem; border-radius: 14px;
  background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.16); border-left: 6px solid var(--c);
  color: #fff; font-weight: 700; font-size: 1rem; text-decoration: none; cursor: pointer; list-style: none;
  transition: transform 0.18s ease, background-color 0.18s ease, box-shadow 0.18s ease, color 0.18s ease;
}
.menu-float__item::-webkit-details-marker { display: none; }
.menu-float__chip { flex: none; width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center; background: var(--c); color: #0a1e38; }
.menu-float__txt { flex: 1; line-height: 1.2; }
.menu-float__ir { flex: none; opacity: 0.85; display: grid; }
.menu-float__item:hover, .menu-float__item:focus-visible { background: rgba(255,255,255,0.18); transform: translateX(-4px); box-shadow: 0 0 0 2px var(--c), 0 0 20px var(--c); }
.menu-float__item:focus-visible { outline: 3px solid #ffd166; outline-offset: 2px; }
.menu-float__item:active { background: var(--c); color: #0a1e38; }
.menu-float__grupo[open] > summary .menu-float__mas { transform: rotate(180deg); }
.menu-float__grupo > summary { margin-bottom: 0; }
.menu-float__grupo { --c: #38bdf8; }
.menu-float__grupo .menu-float__item { --c: inherit; }
.menu-float__subs { display: grid; gap: 0.2rem; padding: 0.4rem 0 0.2rem 1.1rem; margin-left: 1.4rem; border-left: 2px dashed rgba(255,255,255,0.3); }
.menu-float__sub {
  display: flex; align-items: center; gap: 0.6rem; padding: 0.5rem 0.8rem; border-radius: 10px; color: #e6eefb; text-decoration: none;
  font-size: 0.93rem; font-weight: 600; transition: background-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.menu-float__sub:hover, .menu-float__sub:focus-visible { background: var(--c, #38bdf8); color: #0a1e38; transform: translateX(-3px); }
.menu-float__prog i { flex: none; width: 12px; height: 12px; border-radius: 50%; background: var(--pc, #fff); box-shadow: 0 0 0 2px #fff; }
.menu-float__prog:hover { background: var(--pc); color: #fff; }
.menu-float__prog:hover i { box-shadow: 0 0 0 2px #0a1e38; }
.menu-float__c-inicio { --c: #60a5fa; }
.menu-float__c-fundacion { --c: #a78bfa; }
.menu-float__c-oferta { --c: #ff9a3d; }
.menu-float__c-blog { --c: #22d3ee; }
.menu-float__c-sedes { --c: #f472b6; }
.menu-float__c-pqrsf { --c: #fbbf24; }
.menu-float__c-wa { --c: #25d366; }
.menu-float__pie { margin: 1.2rem 0 0; text-align: center; font-size: 0.8rem; color: #c6d4ea; }
.menu-float__pie a { color: #fff; }
@media (max-width: 480px) { .menu-float__boton { width: 48px; height: 48px; right: 0.5rem; top: 0.6rem; } }
.menu-float__p-clinica-veterinaria { --pc: #9b1b47; }
.menu-float__p-desarrollo-software { --pc: #7c3aed; }
.menu-float__p-primera-infancia { --pc: #db2777; }
.menu-float__p-investigacion-judicial { --pc: #2b3038; }
.menu-float__p-auxiliar-archivo { --pc: #38bdf8; }
.menu-float__p-ingles-practico { --pc: #047857; }

/* El botón del menú va DENTRO de la barra superior, en la misma fila y alineado con los botones
   "Preinscríbete" y "WhatsApp" (2026-09-23): menu-lateral.js lo mueve allí. Al ser parte de la barra
   fija, se desplaza con ella. Además se retira el ☰ propio de la barra principal (móvil): este menú
   ya incluye todas sus rutas. */
.menu-float__boton.menu-float__boton--barra { position: static; flex: none; width: 50px; height: 50px; margin-left: auto; align-self: center; }
html.con-menu-lateral .main-nav .nav-toggle { display: none; }

/* Acceso directo a PQRSF en el menú horizontal (2026-09-23): "píldora" ámbar para que la ciudadanía la
   encuentre de inmediato. Para que la barra siga cabiendo en una fila con el botón del menú se
   compactan un poco los espacios. */
.main-nav ul a.nav-pqrsf {
  padding: 0 1rem; border-radius: 999px; border: 2px solid #fbbf24; color: #fbbf24; font-weight: 800; letter-spacing: 0.03em;
  transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
.main-nav ul a.nav-pqrsf:hover, .main-nav ul a.nav-pqrsf[aria-current="page"] { background: #fbbf24; color: #0a1e38; box-shadow: 0 0 16px rgba(251,191,36,0.7); }
@media (min-width: 861px) {
  html.con-menu-lateral .main-nav .inner { max-width: 1440px; gap: 0.9rem; padding-left: 1rem; padding-right: 1rem; }
  html.con-menu-lateral .main-nav ul { gap: 0.8rem; }
  html.con-menu-lateral .main-nav ul a { font-size: 1rem; }
  html.con-menu-lateral .brand img { height: 66px; width: 66px; }
  html.con-menu-lateral .nav-cta { gap: 0.5rem; }
  /* Lema de la marca en dos líneas para liberar ancho y que todo quepa en una sola fila. */
  html.con-menu-lateral .brand__text small { max-width: 11.5rem; white-space: normal; line-height: 1.15; }
}

/* Opciones del menú horizontal con su propio color (2026-09-23), como la píldora de PQRSF: La Fundación
   (violeta), Oferta Académica (naranja), Blog (cian) y PQRSF (ámbar). Los colores coinciden con los del
   menú lateral. Al pasar el cursor, al abrir el submenú o en la página actual se rellenan. */
.main-nav .nav-collapsible > ul > li:nth-child(-n+3) > a,
.main-nav .nav-collapsible > ul > li:nth-child(-n+3) > .nav-dropdown__toggle {
  --c: #a78bfa; padding: 0 0.85rem; border-radius: 999px; border: 2px solid var(--c); color: var(--c); font-weight: 800;
  transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
.main-nav .nav-collapsible > ul > li:nth-child(2) > .nav-dropdown__toggle { --c: #ff9a3d; }
.main-nav .nav-collapsible > ul > li:nth-child(3) > a { --c: #22d3ee; }
.main-nav .nav-collapsible > ul > li:nth-child(-n+3) > a:hover,
.main-nav .nav-collapsible > ul > li:nth-child(-n+3) > a[aria-current="page"],
.main-nav .nav-collapsible > ul > li:nth-child(-n+3) > .nav-dropdown__toggle:hover,
.main-nav .nav-collapsible > ul > li:nth-child(-n+3) > .nav-dropdown__toggle[aria-expanded="true"] {
  background: var(--c); color: #0a1e38; box-shadow: 0 0 16px var(--c);
}
@media (min-width: 861px) {
  html.con-menu-lateral .main-nav ul { gap: 0.5rem; }
  html.con-menu-lateral .main-nav .nav-collapsible > ul > li:nth-child(-n+3) > a,
  html.con-menu-lateral .main-nav .nav-collapsible > ul > li:nth-child(-n+3) > .nav-dropdown__toggle { padding: 0 0.7rem; }
}

/* Compactación de la barra con las opciones de color (cabe en una fila desde ~1280 px). */
@media (min-width: 861px) {
  html.con-menu-lateral .main-nav .inner { gap: 0.6rem; }
  html.con-menu-lateral .main-nav ul a, html.con-menu-lateral .nav-dropdown__toggle { font-size: 0.95rem; }
  html.con-menu-lateral .main-nav .nav-collapsible > ul > li:nth-child(-n+3) > a,
  html.con-menu-lateral .main-nav .nav-collapsible > ul > li:nth-child(-n+3) > .nav-dropdown__toggle { padding: 0 0.6rem; }
  html.con-menu-lateral .main-nav ul a.nav-pqrsf { padding: 0 0.7rem; }
  html.con-menu-lateral .main-nav ul { gap: 0.4rem; }
  html.con-menu-lateral .brand img { height: 58px; width: 58px; }
  html.con-menu-lateral .brand__text small { max-width: 10rem; font-size: 0.72rem; }
}
.program-card[data-programa] .btn-outline { border: 0; }

/* Botón "Ver todos los eventos" de la portada (2026-09-23): llamativo, en degradado vibrante magenta→violeta con halo que
   respira, ícono de calendario y flecha que avanza. Texto blanco sobre colores oscuros de cada extremo (contraste AA). */
.btn-eventos {
  position: relative; isolation: isolate; display: inline-flex; align-items: center; justify-content: center; gap: 0.7rem;
  min-height: 56px; padding: 0.8rem 1.6rem; border-radius: 999px; border: 3px solid #fff; text-decoration: none; cursor: pointer;
  background: linear-gradient(100deg, #c2185b 0%, #a21caf 55%, #6d28d9 100%); color: #fff; font-weight: 900; font-size: 1.1rem;
  letter-spacing: 0.03em; overflow: hidden; box-shadow: 0 5px 0 #4a044e, 0 0 26px 6px rgba(255, 31, 107, 0.75), 0 0 54px 12px rgba(168, 85, 247, 0.55);
  animation: eventos-halo 1.6s ease-in-out infinite;
  transition: transform 0.15s ease, filter 0.15s ease;
}
.btn-eventos::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: -40%; width: 30%; z-index: 1; pointer-events: none;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.55), transparent); transform: skewX(-20deg); animation: eventos-brillo 3.2s ease-in-out infinite;
}
.btn-eventos:hover { filter: brightness(1.12); transform: translateY(-2px); }
.btn-eventos:active { transform: translateY(3px); }
.btn-eventos:focus-visible { outline: 4px solid #ffd166; outline-offset: 4px; }
.btn-eventos__flecha { animation: eventos-flecha 0.8s ease-in-out infinite alternate; }
@keyframes eventos-halo {
  0%, 100% { box-shadow: 0 5px 0 #4a044e, 0 0 14px 2px rgba(255, 31, 107, 0.45), 0 0 30px 6px rgba(168, 85, 247, 0.3); }
  50% { box-shadow: 0 5px 0 #4a044e, 0 0 30px 8px rgba(255, 31, 107, 0.85), 0 0 62px 16px rgba(168, 85, 247, 0.6); }
}
@keyframes eventos-brillo { 0%, 55% { left: -40%; } 100% { left: 130%; } }
@keyframes eventos-flecha { from { transform: translateX(-2px); } to { transform: translateX(5px); } }
@media (prefers-reduced-motion: reduce) { .btn-eventos, .btn-eventos::after, .btn-eventos__flecha { animation: none !important; } }

/* "Ver más noticias": misma familia que "Ver todos los eventos" pero en cian → azul → violeta, con halo cian. */
.btn-eventos--noticias {
  background: linear-gradient(100deg, #0e7490 0%, #1d4ed8 55%, #6d28d9 100%); box-shadow: 0 5px 0 #172554, 0 0 26px 6px rgba(34, 211, 238, 0.75), 0 0 54px 12px rgba(96, 165, 250, 0.55);
  animation-name: noticias-halo; margin-top: 1.4rem;
}
.btn-eventos--noticias:active { box-shadow: 0 2px 0 #172554; }
@keyframes noticias-halo {
  0%, 100% { box-shadow: 0 5px 0 #172554, 0 0 14px 2px rgba(34, 211, 238, 0.45), 0 0 30px 6px rgba(96, 165, 250, 0.3); }
  50% { box-shadow: 0 5px 0 #172554, 0 0 30px 8px rgba(34, 211, 238, 0.85), 0 0 62px 16px rgba(96, 165, 250, 0.6); }
}

/* Aviso de cookies (2026-10-02, aviso-cookies.js): barra fija abajo hasta que el visitante decide.
   Va por encima de todo, incluida la ventana emergente de noticias de la portada (z-index 300), que si no taparía los botones.
   Fondo azul oscuro fijo en ambos temas, así el texto blanco cumple AA sin depender del tema.
   Los dos botones son iguales a propósito: rechazar debe ser tan fácil como aceptar. */
.aviso-cookies {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 310;
  display: flex; align-items: center; justify-content: center; gap: 1rem 1.5rem; flex-wrap: wrap;
  padding: 0.9rem 1.25rem; background: var(--funprotec-navy-dark); color: #fff;
  box-shadow: 0 -6px 18px rgba(0,0,0,0.3);
}
.aviso-cookies__texto { margin: 0; max-width: 62ch; font-size: 1rem; line-height: 1.45; }
.aviso-cookies__texto a { color: #fff; text-decoration: underline; white-space: nowrap; }
.aviso-cookies__acciones { display: flex; gap: 0.75rem; }
.aviso-cookies__btn { min-width: 8.5rem; background: #fff; color: var(--funprotec-navy-dark); }
.aviso-cookies__btn:hover { background: var(--funprotec-navy-bg); }
.aviso-cookies__btn:focus-visible, .aviso-cookies__texto a:focus-visible { outline: 3px solid var(--funprotec-orange); outline-offset: 3px; }
@media (max-width: 700px) {
  .aviso-cookies__acciones { width: 100%; }
  .aviso-cookies__btn { flex: 1; min-width: 0; }
}
