let fullpageOn = false; let observer = null; let navRaf = false; const isDesktop = () => window.matchMedia('(min-width:1200px)').matches; const isTouchView = () => !isDesktop(); function toggleDrawer(){ document.getElementById('drawer').classList.toggle('open'); } function toggleLangMenu(e){ e.stopPropagation(); document.getElementById('langMenu').classList.toggle('open'); } function selectLang(v){ document.querySelectorAll('.lang-label').forEach(el => el.textContent = v); document.getElementById('langMenu').classList.remove('open'); const krBtn = document.querySelector('.lang-btn-kr'); const enBtn = document.querySelector('.lang-btn-en'); if (krBtn && enBtn){ krBtn.classList.toggle('active', v === 'KR'); enBtn.classList.toggle('active', v === 'EN'); } applyLang(v); } function applyLang(v){ document.querySelectorAll('[data-en]').forEach(el => { if (!el.dataset.ko) el.dataset.ko = el.innerHTML; el.innerHTML = (v === 'EN') ? el.dataset.en : el.dataset.ko; }); document.documentElement.lang = (v === 'EN') ? 'en' : 'ko'; } function toggleFamilyMenu(e){ e.stopPropagation(); document.getElementById('familyMenu').classList.toggle('open'); } document.addEventListener('click', () => { document.getElementById('langMenu').classList.remove('open'); document.getElementById('familyMenu').classList.remove('open'); }); function scrollToSection(id){ const scroller = document.querySelector('.device-scroll'); const el = document.getElementById(id); if (!el) return; scroller.scrollTo({ top: el.offsetTop, behavior: 'smooth' }); document.getElementById('drawer').classList.remove('open'); } function updateNavTheme(){ const scroller = document.querySelector('.device-scroll'); const sections = Array.from(document.querySelectorAll('.site > section')); const pos = scroller.scrollTop + 2; let current = sections[0]; for (const sec of sections){ if (sec.offsetTop <= pos) current = sec; else break; } const theme = current ? current.dataset.theme : 'dark'; document.getElementById('mainNav').classList.toggle('on-light', theme === 'light'); } function syncSlideHeight(){ const scroller = document.querySelector('.device-scroll'); scroller.style.setProperty('--slide-h', scroller.clientHeight + 'px'); } function setupObserver(){ const scroller = document.querySelector('.device-scroll'); if (observer) observer.disconnect(); observer = new IntersectionObserver((entries) => { entries.forEach(entry => { entry.target.classList.toggle('in-view', entry.isIntersecting && entry.intersectionRatio > 0.5); }); }, { root: scroller, threshold: [0, 0.5, 1] }); document.querySelectorAll('.site > section').forEach(el => observer.observe(el)); } function setFullpage(on){ if (on === fullpageOn) return; fullpageOn = on; const scroller = document.querySelector('.device-scroll'); scroller.classList.toggle('fullpage', fullpageOn); if (fullpageOn){ syncSlideHeight(); setupObserver(); scroller.scrollTo({ top: 0, behavior: 'auto' }); } else if (observer){ observer.disconnect(); document.querySelectorAll('.site > section').forEach(el => el.classList.remove('in-view')); } } // Fullpage scroll-snap is automatic: on for desktop (>=1200px), off for tablet/mobile. // Re-evaluated on load and whenever the viewport crosses the breakpoint (e.g. resizing the browser window). function applyFullpageForViewport(){ setFullpage(isDesktop()); } /* ---- Hero background slideshow ---- */ let heroIdx = 0; let heroTimer = null; function initHeroSlider(){ const slides = document.querySelectorAll('#heroSlides .hero-slide'); const dotsWrap = document.getElementById('heroDots'); dotsWrap.innerHTML = ''; slides.forEach((s, i) => { const d = document.createElement('span'); if (i === 0) d.classList.add('active'); d.addEventListener('click', () => setHeroSlide(i)); dotsWrap.appendChild(d); }); if (heroTimer) clearInterval(heroTimer); heroTimer = setInterval(() => { setHeroSlide((heroIdx + 1) % slides.length); }, 4500); } function setHeroSlide(i){ const slides = document.querySelectorAll('#heroSlides .hero-slide'); const dots = document.querySelectorAll('#heroDots span'); slides.forEach((s, idx) => s.classList.toggle('active', idx === i)); dots.forEach((d, idx) => d.classList.toggle('active', idx === i)); heroIdx = i; } /* ---- Social swiper (autoplay carousel, no manual buttons/dots) ---- */ let autoplayTimer = null; let pauseTimer = null; const AUTOPLAY_MS = 3200; function cardStep(){ const track = document.getElementById('socialTrack'); if (!isDesktop()){ const page = track.querySelector('.swiper-page'); return page ? page.getBoundingClientRect().width + 14 : track.clientWidth; } const card = track.querySelector('.social-card'); return card ? card.getBoundingClientRect().width + 14 : 300; } function swiperStep(dir){ const track = document.getElementById('socialTrack'); const atEnd = track.scrollLeft + track.clientWidth >= track.scrollWidth - 4; const atStart = track.scrollLeft <= 4; if (dir > 0 && atEnd) track.scrollTo({ left: 0, behavior: 'smooth' }); else if (dir < 0 && atStart) track.scrollTo({ left: track.scrollWidth, behavior: 'smooth' }); else track.scrollBy({ left: cardStep() * dir, behavior: 'smooth' }); pauseAutoplay(); } function startAutoplay(){ if (autoplayTimer) clearInterval(autoplayTimer); autoplayTimer = setInterval(() => { const track = document.getElementById('socialTrack'); const atEnd = track.scrollLeft + track.clientWidth >= track.scrollWidth - 4; if (atEnd) track.scrollTo({ left: 0, behavior: 'smooth' }); else track.scrollBy({ left: cardStep(), behavior: 'smooth' }); }, AUTOPLAY_MS); } function pauseAutoplay(){ if (autoplayTimer) clearInterval(autoplayTimer); if (pauseTimer) clearTimeout(pauseTimer); pauseTimer = setTimeout(startAutoplay, AUTOPLAY_MS * 1.6); } document.addEventListener('DOMContentLoaded', () => { const scroller = document.querySelector('.device-scroll'); scroller.addEventListener('scroll', () => { if (!navRaf){ navRaf = true; requestAnimationFrame(() => { updateNavTheme(); navRaf = false; }); } }); const track = document.getElementById('socialTrack'); track.addEventListener('pointerdown', pauseAutoplay); /* clickable cards: click a card to bring it into center focus */ document.querySelectorAll('.social-card').forEach(card => { card.addEventListener('click', () => { card.scrollIntoView({ behavior: 'smooth', inline: 'center', block: 'nearest' }); pauseAutoplay(); }); }); updateNavTheme(); startAutoplay(); initHeroSlider(); applyFullpageForViewport(); document.querySelectorAll('.biz-card').forEach(card => { const video = card.querySelector('.biz-video'); card.addEventListener('mouseenter', () => { if (!isTouchView() && video) video.play().catch(() => {}); }); card.addEventListener('mouseleave', () => { if (!isTouchView() && video) video.pause(); }); card.addEventListener('click', () => { if (!isTouchView()) return; if (video){ if (video.paused) video.play().catch(() => {}); else video.pause(); } const allCards = Array.from(document.querySelectorAll('.biz-card')); const wasExpanded = card.classList.contains('is-expanded'); allCards.forEach(c => c.classList.remove('is-expanded', 'is-collapsed')); if (!wasExpanded){ card.classList.add('is-expanded'); allCards.filter(c => c !== card).forEach(c => c.classList.add('is-collapsed')); } }); }); document.querySelectorAll('.spec-card').forEach(card => { card.addEventListener('click', () => { if (!isTouchView()) return; document.querySelectorAll('.spec-card').forEach(c => { if (c !== card) c.classList.remove('is-active'); }); card.classList.toggle('is-active'); }); }); /* ---- Custom cursor ---- */ const frameEl = document.getElementById('frame'); const cursorEl = document.getElementById('cursor'); frameEl.addEventListener('mousemove', (e) => { const rect = frameEl.getBoundingClientRect(); cursorEl.style.left = (e.clientX - rect.left) + 'px'; cursorEl.style.top = (e.clientY - rect.top) + 'px'; }); frameEl.addEventListener('mouseleave', () => { cursorEl.style.opacity = '0'; }); frameEl.addEventListener('mouseenter', () => { cursorEl.style.opacity = '1'; }); const hoverSelector = 'a, button, .biz-card, .social-card, .spec-card, .hero-dots span, .lang-menu a, .footer-family-menu a'; frameEl.addEventListener('mouseover', (e) => { if (e.target.closest(hoverSelector)) cursorEl.classList.add('hover'); }); frameEl.addEventListener('mouseout', (e) => { if (e.target.closest(hoverSelector) && !e.relatedTarget?.closest(hoverSelector)){ cursorEl.classList.remove('hover'); } }); }); // Re-check the desktop/tablet-mobile breakpoint whenever the browser window is resized, // so fullpage scroll turns itself on/off automatically if the window crosses 1200px. window.matchMedia('(min-width:1200px)').addEventListener('change', applyFullpageForViewport); window.addEventListener('resize', () => { if (fullpageOn) syncSlideHeight(); });