"use client"; import { useEffect } from "react"; export default function ArticleScripts() { useEffect(() => { // ── Scroll reveal (AOS replacement) ── const revealEls = document.querySelectorAll( ".content-wrapper, .double-image-grid-vertical, .photo-video-grid, " + ".triple-image-grid, .triple-vertical-grid, .two-img-one-video-grid, " + ".iphone-photo-row, .horizontal-vertical-grid, .double-vertical-grid, " + ".single-wide-4x3, .single-wide-16x9, .video-block, .figure-wide" ); const revealObserver = new IntersectionObserver( (entries) => { entries.forEach((e) => { if (e.isIntersecting) { e.target.classList.add("aos-animate"); revealObserver.unobserve(e.target); } }); }, { threshold: 0.1 } ); revealEls.forEach((el) => revealObserver.observe(el)); // ── Drop caps ── const article = document.querySelector(".article-body"); if (article) { const firstWrapper = article.querySelector(".content-wrapper"); if (firstWrapper) { const ps = firstWrapper.querySelectorAll(":scope > p"); const target = ps.length > 1 ? ps[1] : ps[0]; if (target) target.classList.add("has-dropcap"); } article.querySelectorAll(".parallax-section").forEach((px) => { let sibling = px.nextElementSibling; while (sibling && !sibling.classList.contains("content-wrapper")) { sibling = sibling.nextElementSibling; } if (sibling) { const p = sibling.querySelector(":scope > p"); if (p) p.classList.add("has-dropcap"); } }); } // ── Lightbox ── const overlay = document.createElement("div"); overlay.className = "lightbox-overlay"; overlay.innerHTML = ` `; document.body.appendChild(overlay); const imgEl = overlay.querySelector(".lightbox-image") as HTMLImageElement; const closeBtn = overlay.querySelector(".lightbox-close")!; const show = (src: string, alt: string) => { imgEl.src = src; imgEl.alt = alt || ""; overlay.classList.add("is-open"); document.body.style.overflow = "hidden"; }; const hide = () => { overlay.classList.remove("is-open"); document.body.style.overflow = ""; }; overlay.addEventListener("click", (e) => { if (e.target === overlay || e.target === closeBtn) hide(); }); const onKey = (e: KeyboardEvent) => { if (e.key === "Escape" && overlay.classList.contains("is-open")) hide(); }; document.addEventListener("keydown", onKey); document.querySelectorAll(".article-body img").forEach((img) => { (img as HTMLElement).style.cursor = "zoom-in"; img.addEventListener("click", () => show((img as HTMLImageElement).src, (img as HTMLImageElement).alt) ); }); // ── Mobile parallax imitation ── const isMobile = ("ontouchstart" in window || navigator.maxTouchPoints > 0) && window.innerWidth <= 768; if (isMobile) { const sections = document.querySelectorAll(".parallax-section"); sections.forEach((section) => { const bgLayer = document.createElement("div"); bgLayer.className = "parallax-bg-layer"; bgLayer.style.backgroundImage = section.style.backgroundImage; section.style.backgroundImage = "none"; section.classList.add("has-bg-layer"); section.insertBefore(bgLayer, section.firstChild); }); const onScroll = () => { sections.forEach((section) => { const rect = section.getBoundingClientRect(); const viewH = window.innerHeight; if (rect.bottom < 0 || rect.top > viewH) return; const progress = 1 - (rect.top + rect.height) / (viewH + rect.height); const shift = (progress - 0.5) * 40; const bg = section.querySelector(".parallax-bg-layer"); if (bg) bg.style.transform = `translateY(${shift}px)`; }); }; window.addEventListener("scroll", onScroll, { passive: true }); } // ── Auto-play videos on scroll ── document.querySelectorAll(".article-body video").forEach((video) => { video.muted = true; const vidObserver = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { video.play().catch(() => {}); } else { video.pause(); } }); }, { threshold: 0.5 } ); vidObserver.observe(video); }); // ── Open external links in new tab ── document.querySelectorAll(".article-body a[href]").forEach((link) => { const href = link.getAttribute("href"); if (!href || href.startsWith("#")) return; link.setAttribute("target", "_blank"); link.setAttribute("rel", "noopener noreferrer"); }); return () => { revealObserver.disconnect(); document.removeEventListener("keydown", onKey); overlay.remove(); }; }, []); return null; }