Files
ide_maqueta_b/scripts.js
T
2026-08-28 15:31:15 -03:00

179 lines
6.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ============================================================
IDE CONSULTORES – SCRIPTS GLOBALES
============================================================ */
/* ── THEME TOGGLE ──────────────────────────────────────────── */
(function () {
const stored = localStorage.getItem('ide-theme') || 'light';
document.documentElement.setAttribute('data-theme', stored);
})();
function initThemeToggle() {
const btn = document.querySelector('.theme-toggle');
if (!btn) return;
function updateBtn() {
const isDark = document.documentElement.getAttribute('data-theme') === 'dark';
btn.textContent = isDark ? '☀ Claro' : '☾ Oscuro';
}
updateBtn();
btn.addEventListener('click', () => {
const current = document.documentElement.getAttribute('data-theme');
const next = current === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next);
localStorage.setItem('ide-theme', next);
updateBtn();
});
}
/* ── HAMBURGER MENU ─────────────────────────────────────────── */
function initHamburger() {
const btn = document.querySelector('.hamburger');
const menu = document.querySelector('.mobile-menu');
if (!btn || !menu) return;
btn.addEventListener('click', () => {
menu.classList.toggle('open');
});
document.addEventListener('click', (e) => {
if (!btn.contains(e.target) && !menu.contains(e.target)) {
menu.classList.remove('open');
}
});
}
/* ── ACTIVE NAV LINK ─────────────────────────────────────────── */
function initActiveNav() {
const path = window.location.pathname.split('/').pop() || 'index.html';
document.querySelectorAll('.navbar__links a, .mobile-menu a').forEach(a => {
const href = a.getAttribute('href');
if (href === path) a.classList.add('active');
});
}
/* ── SCROLL FADE-IN ─────────────────────────────────────────── */
function initFadeIn() {
const els = document.querySelectorAll('.fade-in');
if (!els.length) return;
const obs = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) { e.target.classList.add('visible'); obs.unobserve(e.target); }
});
}, { threshold: 0.12 });
els.forEach(el => obs.observe(el));
}
/* ── MODAL ────────────────────────────────────────────────────── */
function openModal(id) {
const overlay = document.getElementById(id);
if (!overlay) return;
overlay.classList.add('open');
document.body.style.overflow = 'hidden';
}
function closeModal(id) {
const overlay = document.getElementById(id);
if (!overlay) return;
overlay.classList.remove('open');
document.body.style.overflow = '';
}
function initModals() {
// Close on overlay click
document.querySelectorAll('.modal-overlay').forEach(overlay => {
overlay.addEventListener('click', (e) => {
if (e.target === overlay) closeModal(overlay.id);
});
});
// Close buttons
document.querySelectorAll('.modal__close').forEach(btn => {
btn.addEventListener('click', () => {
const overlay = btn.closest('.modal-overlay');
if (overlay) closeModal(overlay.id);
});
});
// Escape key
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
document.querySelectorAll('.modal-overlay.open').forEach(o => closeModal(o.id));
}
});
}
/* ── CONTACT FORM ─────────────────────────────────────────────── */
function initContactForm() {
const form = document.querySelector('.contact-form');
if (!form) return;
form.addEventListener('submit', (e) => {
e.preventDefault();
const btn = form.querySelector('[type="submit"]');
const original = btn.textContent;
btn.textContent = '✓ ¡Enviado!';
btn.disabled = true;
btn.style.background = '#1E9A7F';
setTimeout(() => {
btn.textContent = original;
btn.disabled = false;
btn.style.background = '';
form.reset();
}, 3000);
});
}
/* ── ACCORDION / DESAFÍOS ─────────────────────────────────────── */
function initAccordion() {
document.querySelectorAll('.accordion-trigger').forEach(trigger => {
trigger.addEventListener('click', () => {
const panel = trigger.nextElementSibling;
const isOpen = panel.classList.contains('open');
// Close all
document.querySelectorAll('.accordion-panel').forEach(p => p.classList.remove('open'));
document.querySelectorAll('.accordion-trigger').forEach(t => t.classList.remove('open'));
if (!isOpen) {
panel.classList.add('open');
trigger.classList.add('open');
}
});
});
}
/* ── FILTER TABS ──────────────────────────────────────────────── */
function initFilterTabs() {
document.querySelectorAll('.filter-tab').forEach(tab => {
tab.addEventListener('click', () => {
const group = tab.closest('.filter-tabs');
group.querySelectorAll('.filter-tab').forEach(t => t.classList.remove('active'));
tab.classList.add('active');
const filter = tab.dataset.filter;
document.querySelectorAll('.filterable').forEach(item => {
if (filter === 'all' || item.dataset.cat === filter) {
item.style.display = '';
} else {
item.style.display = 'none';
}
});
});
});
}
/* ── INIT ─────────────────────────────────────────────────────── */
document.addEventListener('DOMContentLoaded', () => {
initThemeToggle();
initHamburger();
initActiveNav();
initFadeIn();
initModals();
initContactForm();
initAccordion();
initFilterTabs();
});