refactorizacion v4.8 index

This commit is contained in:
2026-10-08 10:04:29 -03:00
parent 4cb4b3d1d7
commit a0bd5d5a02
33 changed files with 2988 additions and 1878 deletions
+114
View File
@@ -0,0 +1,114 @@
/**
* ECOSISTEMA - CARRUSEL
* Auto-play con fade, control por tabs, pausa al interactuar,
* reanudación al salir completamente del viewport.
*/
(function () {
'use strict';
const INTERVAL_MS = 5000;
const FADE_MS = 600; // debe coincidir con --eco-fade-duration
const section = document.querySelector('.ecosystem-section');
if (!section) return;
const tabs = Array.from(section.querySelectorAll('.eco-tab'));
const slides = Array.from(section.querySelectorAll('.eco-slide'));
let currentIndex = 0;
let timer = null;
let userInteracted = false; // true después de un clic manual
// ---------- Utilidades ----------
function goTo(index) {
if (index < 0) index = slides.length - 1;
if (index >= slides.length) index = 0;
// Actualizar slides
slides.forEach((slide, i) => {
if (i === index) {
slide.classList.add('is-active');
slide.removeAttribute('hidden');
} else {
slide.classList.remove('is-active');
// Esperamos la transición para ocultar (accesibilidad + rendimiento)
setTimeout(() => {
if (!slide.classList.contains('is-active')) {
slide.setAttribute('hidden', '');
}
}, FADE_MS);
}
});
// Actualizar tabs
tabs.forEach((tab, i) => {
if (i === index) {
tab.classList.add('is-active');
tab.setAttribute('aria-selected', 'true');
// Color activo específico de la capacidad
tab.style.backgroundColor = tab.dataset.color;
tab.style.borderColor = tab.dataset.color;
} else {
tab.classList.remove('is-active');
tab.setAttribute('aria-selected', 'false');
// Reset a color inactivo estándar
tab.style.backgroundColor = '';
tab.style.borderColor = '';
}
});
currentIndex = index;
}
function next() {
goTo(currentIndex + 1);
}
function startAutoPlay() {
stopAutoPlay();
timer = setInterval(next, INTERVAL_MS);
}
function stopAutoPlay() {
if (timer) {
clearInterval(timer);
timer = null;
}
}
// ---------- Eventos de tabs ----------
tabs.forEach((tab, i) => {
tab.addEventListener('click', () => {
userInteracted = true;
stopAutoPlay();
goTo(i);
});
});
// ---------- IntersectionObserver: reanudar al salir del viewport ----------
// "Salir completamente" = cuando la sección ya no intersecta en absoluto.
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) {
// Salió completamente del viewport
userInteracted = false;
startAutoPlay();
} else {
// Entró al viewport: si el usuario interactuó, mantenemos pausa;
// si no, arrancamos el auto-play.
if (!userInteracted) {
startAutoPlay();
}
}
});
},
{ threshold: 0 } // se dispara cuando la visibilidad cambia de 0 a >0 o viceversa
);
observer.observe(section);
// ---------- Init ----------
goTo(0);
startAutoPlay();
})();
+10 -9
View File
@@ -398,6 +398,15 @@ function closeModal(modalId) {
const el = document.getElementById('step-' + id);
if (el) el.classList.add('active');
const backBtn = document.getElementById('global-quiz-back-btn');
if (backBtn) {
if (id == 1 || id === '1' || id === 'result') {
backBtn.style.display = 'none';
} else {
backBtn.style.display = 'block';
}
}
updateProgress(id);
updateIndicator(id);
}
@@ -415,15 +424,7 @@ function closeModal(modalId) {
}
function updateIndicator(id) {
const label = document.getElementById('quiz-step-indicator');
if (!label) return;
let text = '';
if (id === 'result') text = '¡Orientación lista!';
else if (['2a', '2b', '2c', '2d'].includes(String(id))) text = 'Paso 2 de 4';
else text = 'Paso ' + id + ' de 4';
label.textContent = text;
// El indicador de pasos (Paso X de 4) fue removido del HTML a petición del usuario.
}
function renderResult(ans) {