Skip to main content
Skip to footer
Opens in a new tab
/* Aldana Construction — site scripts (no dependencies) */
(function () {
"use strict";
var doc = document.documentElement;
doc.classList.remove("no-js");
var body = document.body;
body.classList.add("al-site"); // needed when pasted into WordPress (theme controls )
/* ---------- Highlight current page in nav (WordPress header has no aria-current) ---------- */
if (!document.querySelector('.al-nav [aria-current="page"]')) {
var here = location.pathname.replace(//+$/, "") || "/";
document.querySelectorAll(".al-nav a, .al-mnav a").forEach(function (a) {
var p = (a.getAttribute("href") || "").replace(//+$/, "") || "/";
if (p === here) {
a.setAttribute("aria-current", "page");
var parent = a.closest(".al-nav__item--has-sub"); if (parent) parent.classList.add("is-current");
var msub = a.closest(".al-mnav__sub");
if (msub) { var b = document.querySelector('[aria-controls="' + msub.id + '"]'); if (b) b.setAttribute("aria-expanded", "true"); }
}
});
}
/* ---------- Mobile / tablet drawer navigation ---------- */
var burger = document.querySelector(".al-burger");
var drawer = document.getElementById("al-drawer");
var overlay = document.querySelector(".al-drawer-overlay");
var closeBtn = document.querySelector(".al-drawer__close");
var lastFocus = null;
function focusables() {
return drawer.querySelectorAll('a[href], button:not([disabled])');
}
function openNav() {
lastFocus = document.activeElement;
body.classList.add("al-nav-open");
burger.setAttribute("aria-expanded", "true");
drawer.setAttribute("aria-hidden", "false");
setTimeout(function () { closeBtn && closeBtn.focus(); }, 50);
}
function closeNav() {
body.classList.remove("al-nav-open");
burger.setAttribute("aria-expanded", "false");
drawer.setAttribute("aria-hidden", "true");
if (lastFocus) lastFocus.focus();
}
if (burger && drawer) {
burger.addEventListener("click", openNav);
closeBtn && closeBtn.addEventListener("click", closeNav);
overlay && overlay.addEventListener("click", closeNav);
document.addEventListener("keydown", function (e) {
if (!body.classList.contains("al-nav-open")) return;
if (e.key === "Escape") closeNav();
if (e.key === "Tab") {
var f = focusables(), first = f[0], last = f[f.length - 1];
if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
}
});
// Close drawer if resized up to desktop
window.addEventListener("resize", function () {
if (window.innerWidth > 1024 && body.classList.contains("al-nav-open")) closeNav();
});
// Accordion submenus
drawer.querySelectorAll(".al-mnav button[aria-controls]").forEach(function (btn) {
var panel = document.getElementById(btn.getAttribute("aria-controls"));
if (btn.getAttribute("aria-expanded") === "true") panel.style.maxHeight = panel.scrollHeight + "px";
btn.addEventListener("click", function () {
var open = btn.getAttribute("aria-expanded") === "true";
btn.setAttribute("aria-expanded", String(!open));
panel.style.maxHeight = open ? "0px" : panel.scrollHeight + "px";
});
});
}
/* ---------- Desktop dropdowns: keyboard + touch support ---------- */
document.querySelectorAll(".al-nav__item--has-sub > .al-nav__link").forEach(function (btn) {
btn.addEventListener("click", function (e) {
var item = btn.parentElement, open = item.classList.toggle("is-open");
btn.setAttribute("aria-expanded", String(open));
document.querySelectorAll(".al-nav__item--has-sub.is-open").forEach(function (o) {
if (o !== item) { o.classList.remove("is-open"); o.firstElementChild.setAttribute("aria-expanded", "false"); }
});
e.stopPropagation();
});
});
document.addEventListener("click", function () {
document.querySelectorAll(".al-nav__item--has-sub.is-open").forEach(function (o) {
o.classList.remove("is-open"); o.firstElementChild.setAttribute("aria-expanded", "false");
});
});
/* ---------- Sticky header shadow + back to top ---------- */
var header = document.querySelector(".al-header");
var toTop = document.querySelector(".al-totop");
function onScroll() {
var y = window.scrollY || window.pageYOffset;
header && header.classList.toggle("is-scrolled", y > 10);
toTop && toTop.classList.toggle("is-visible", y > 600);
}
window.addEventListener("scroll", onScroll, { passive: true });
onScroll();
toTop && toTop.addEventListener("click", function () { window.scrollTo({ top: 0, behavior: "smooth" }); });
/* ---------- Reveal on scroll ---------- */
var reveals = document.querySelectorAll(".al-reveal");
if ("IntersectionObserver" in window) {
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (en) { if (en.isIntersecting) { en.target.classList.add("is-in"); io.unobserve(en.target); } });
}, { threshold: 0.12, rootMargin: "0px 0px -40px 0px" });
reveals.forEach(function (el) { io.observe(el); });
} else {
reveals.forEach(function (el) { el.classList.add("is-in"); });
}
/* ---------- Video play buttons ---------- */
document.querySelectorAll(".al-video").forEach(function (box) {
var btn = box.querySelector(".al-video__play"), vid = box.querySelector("video");
if (!btn || !vid) return;
btn.addEventListener("click", function () {
box.classList.add("is-playing");
vid.controls = true; vid.muted = false;
var p = vid.play(); if (p && p.catch) p.catch(function () {});
});
});
/* ---------- Testimonial slider ---------- */
document.querySelectorAll(".al-slider").forEach(function (slider) {
var track = slider.querySelector(".al-slider__track");
var slides = track.children, dotsWrap = slider.parentElement.querySelector(".al-dots");
var index = 0, timer;
function perView() { return window.innerWidth <= 767 ? 1 : window.innerWidth <= 1024 ? 2 : 3; }
function pages() { return Math.max(1, slides.length - perView() + 1); }
function buildDots() {
if (!dotsWrap) return;
dotsWrap.innerHTML = "";
for (var i = 0; i < pages(); i++) {
var b = document.createElement("button");
b.type = "button"; b.setAttribute("aria-label", "Show review " + (i + 1));
(function (n) { b.addEventListener("click", function () { go(n); restart(); }); })(i);
dotsWrap.appendChild(b);
}
}
function go(n) {
index = (n + pages()) % pages();
track.style.transform = "translateX(-" + (index * (100 / perView())) + "%)";
if (dotsWrap) Array.prototype.forEach.call(dotsWrap.children, function (d, i) { d.classList.toggle("is-active", i === index); });
}
function restart() { clearInterval(timer); timer = setInterval(function () { go(index + 1); }, 6000); }
// swipe
var sx = null;
track.addEventListener("touchstart", function (e) { sx = e.touches[0].clientX; }, { passive: true });
track.addEventListener("touchend", function (e) {
if (sx === null) return; var dx = e.changedTouches[0].clientX - sx;
if (Math.abs(dx) > 40) { go(index + (dx < 0 ? 1 : -1)); restart(); } sx = null;
});
slider.addEventListener("mouseenter", function () { clearInterval(timer); });
slider.addEventListener("mouseleave", restart);
window.addEventListener("resize", function () { buildDots(); go(Math.min(index, pages() - 1)); });
buildDots(); go(0); restart();
});
/* ---------- Forms (demo handler — replace with your WP form plugin) ---------- */
document.querySelectorAll("form.al-form[data-demo]").forEach(function (form) {
form.addEventListener("submit", function (e) {
e.preventDefault();
if (!form.checkValidity()) { form.reportValidity(); return; }
form.classList.add("is-sent");
form.reset();
});
});
/* ---------- Footer year ---------- */
document.querySelectorAll("[data-year]").forEach(function (el) { el.textContent = new Date().getFullYear(); });
})();