(function(){
// ✅ Title Case: chỉ viết hoa chữ cái đầu mỗi từ (giữ nguyên tiếng Việt có dấu)
function toTitleCase(str){
return String(str)
.trim()
.split(/\s+/g)
.map(w => w ? (w[0].toUpperCase() + w.slice(1).toLowerCase()) : w)
.join(" ");
}
const I18N = {
vi: { items:[
{ text:"Menu", href:"/menu-sau-16h/", bg:"https://nexusvietnam.beer/wp-content/uploads/2026/01/Menu-scaled.jpg" },
{ text:"Về Nexus", href:"/ve-nexus", bg:"https://nexusvietnam.beer/wp-content/uploads/2026/01/Ve-Nexus-scaled.jpg" },
{ text:"Đặt Bàn", href:"/lien-he/", bg:"https://nexusvietnam.beer/wp-content/uploads/2026/02/72a26ef44dc9c3979ad8.jpg" },
{ text:"Tư Vấn Tiệc", href:"/lien-he/", bg:"https://nexusvietnam.beer/wp-content/uploads/2026/01/45b6f600404bce15975a.jpg" },
{ text:"Liên Hệ", href:"/lien-he", bg:"https://nexusvietnam.beer/wp-content/uploads/2026/01/Lien-He-scaled.jpg" }
]},
en: { items:[
{ text:"Menu", href:"/menu-sau-16h/", bg:"https://nexusvietnam.beer/wp-content/uploads/2026/01/Menu-scaled.jpg" },
{ text:"About Nexus", href:"/ve-nexus", bg:"https://nexusvietnam.beer/wp-content/uploads/2026/01/Ve-Nexus-scaled.jpg" },
{ text:"Reservation", href:"/lien-he/", bg:"https://nexusvietnam.beer/wp-content/uploads/2026/02/72a26ef44dc9c3979ad8.jpg" },
{ text:"Event Consult", href:"/lien-he/", bg:"https://nexusvietnam.beer/wp-content/uploads/2026/01/45b6f600404bce15975a.jpg" },
{ text:"Contact", href:"/lien-he", bg:"https://nexusvietnam.beer/wp-content/uploads/2026/01/Lien-He-scaled.jpg" }
]},
ko: { items:[
{ text:"메뉴", href:"/menu-sau-16h/", bg:"https://nexusvietnam.beer/wp-content/uploads/2026/01/Menu-scaled.jpg" },
{ text:"넥서스 소개", href:"/ve-nexus", bg:"https://nexusvietnam.beer/wp-content/uploads/2026/01/Ve-Nexus-scaled.jpg" },
{ text:"예약", href:"/lien-he/", bg:"https://nexusvietnam.beer/wp-content/uploads/2026/02/72a26ef44dc9c3979ad8.jpg" },
{ text:"파티 상담", href:"/lien-he/", bg:"https://nexusvietnam.beer/wp-content/uploads/2026/01/45b6f600404bce15975a.jpg" },
{ text:"연락처", href:"/lien-he", bg:"https://nexusvietnam.beer/wp-content/uploads/2026/01/Lien-He-scaled.jpg" }
]}
};
const CLONES = 14;
const AUTOPLAY_MS = 2300;
const AUTOPLAY_RESUME_MS = 1800;
// ✅ mặc định active thẻ thứ 3 khi load (0-based => 2)
const DEFAULT_REAL_INDEX = 2;
const hero = document.getElementById("nexusHomeHero");
const stage = document.getElementById("stage");
const rail = document.getElementById("rail");
const track = document.getElementById("track");
if(!hero || !stage || !rail || !track) return;
const bg = document.createElement("div");
bg.className = "bg";
hero.prepend(bg);
let currentLang = window.NEXUS_LANG || "vi";
let ITEMS = (I18N[currentLang] || I18N.vi).items;
let baseCount = ITEMS.length;
let itemsAll = [];
let bgLayers = [];
let startIndex = 0;
let activeVirtual = 0;
let autoplayTimer = null;
let resumeTimer = null;
function isMobileNow(){ return matchMedia("(max-width: 980px)").matches; }
function getTranslateX(el){
const t = getComputedStyle(el).transform;
if (!t || t === "none") return 0;
return (new DOMMatrixReadOnly(t)).m41;
}
function setTranslateX(el, x){
el.style.transform = `translate3d(${x}px,0,0)`;
}
function centerVirtual(virtualEl, animate=true){
const stageRect = stage.getBoundingClientRect();
const vRect = virtualEl.getBoundingClientRect();
const stageCenter = stageRect.left + stageRect.width / 2;
const itemCenter = vRect.left + vRect.width / 2;
const currentX = getTranslateX(track);
const nextX = currentX + (stageCenter - itemCenter);
track.style.transition = animate ? "transform 0.85s cubic-bezier(.2,.8,.2,1)" : "none";
setTranslateX(track, nextX);
}
function buildBgLayers(){
bg.innerHTML = "";
for (let i = 0; i < baseCount; i++){
const layer = document.createElement("div");
layer.className = "bg-layer" + (i === 0 ? " is-active" : "");
layer.style.backgroundImage = `url('${ITEMS[i].bg}')`;
bg.appendChild(layer);
}
bgLayers = Array.from(bg.querySelectorAll(".bg-layer"));
}
function renderBaseHTML(){
return ITEMS.map((it, i) => {
const raw = String(it.text);
const text = (currentLang === "ko") ? raw : toTitleCase(raw);
return `
${text}_
`;
}).join("");
}
function setActiveBg(realIndex){
bgLayers.forEach((el,i)=> el.classList.toggle("is-active", i===realIndex));
}
function stopAutoplay(){
if (autoplayTimer) clearInterval(autoplayTimer);
autoplayTimer = null;
}
function startAutoplay(){
stopAutoplay();
if (baseCount <= 1) return;
autoplayTimer = setInterval(()=> goToVirtual(activeVirtual + 1, true, true), AUTOPLAY_MS);
}
function pauseAutoplayTemporarily(){
stopAutoplay();
if (resumeTimer) clearTimeout(resumeTimer);
resumeTimer = setTimeout(()=> startAutoplay(), AUTOPLAY_RESUME_MS);
}
function normalizeIfNeeded(){
const v = startIndex + activeVirtual;
const leftEdge = baseCount * 2;
const rightEdge = itemsAll.length - baseCount * 2;
if (v < leftEdge || v > rightEdge){
const real = ((activeVirtual % baseCount) + baseCount) % baseCount;
startIndex = CLONES * baseCount;
activeVirtual = real;
const midEl = itemsAll[startIndex + activeVirtual];
if (midEl){
itemsAll.forEach(el => el.classList.remove("is-active"));
midEl.classList.add("is-active");
centerVirtual(midEl, false);
}
}
}
function goToVirtual(nextVirtual, animate=true, fromAutoplay=false){
activeVirtual = nextVirtual;
const realIndex = ((activeVirtual % baseCount) + baseCount) % baseCount;
setActiveBg(realIndex);
const vPos = startIndex + activeVirtual;
const targetEl = itemsAll[vPos];
itemsAll.forEach(el => el.classList.remove("is-active"));
if (targetEl) targetEl.classList.add("is-active");
if (!isMobileNow() && targetEl) centerVirtual(targetEl, animate);
if (isMobileNow() && targetEl){
targetEl.scrollIntoView({behavior: animate ? "smooth" : "auto", inline:"center", block:"nearest"});
}
if (!isMobileNow()){
setTimeout(()=> normalizeIfNeeded(), animate ? 900 : 0);
}
if (!fromAutoplay) pauseAutoplayTemporarily();
}
function rebuild(){
ITEMS = (I18N[currentLang] || I18N.vi).items;
baseCount = ITEMS.length;
buildBgLayers();
const baseHTML = renderBaseHTML();
if (baseCount <= 1){
track.innerHTML = baseHTML;
} else {
let left="", right="";
for (let i=0;i
1) ? (CLONES * baseCount) : 0;
itemsAll.forEach((el)=>{
const real = Number(el.dataset.index);
el.onclick = (e)=>{
e.preventDefault();
const curReal = ((activeVirtual % baseCount) + baseCount) % baseCount;
if (real === curReal) {
window.location.href = el.getAttribute("href");
return;
}
const forwardSteps = (real - curReal + baseCount) % baseCount;
goToVirtual(activeVirtual + forwardSteps, true, false);
};
});
const safeDefault = Math.min(Math.max(DEFAULT_REAL_INDEX, 0), baseCount - 1);
activeVirtual = safeDefault;
goToVirtual(activeVirtual, false, true);
startAutoplay();
}
(function bindWheelDesktop(){
let wheelLocked = false;
rail.addEventListener("wheel", (e)=>{
if (isMobileNow()) return;
e.preventDefault();
if (wheelLocked) return;
wheelLocked = true;
goToVirtual(activeVirtual + (e.deltaY > 0 ? 1 : -1), true, false);
setTimeout(()=> wheelLocked = false, 260);
}, {passive:false});
})();
rail.addEventListener("mouseenter", ()=> stopAutoplay());
rail.addEventListener("mouseleave", ()=> startAutoplay());
document.addEventListener("visibilitychange", ()=>{
if (document.hidden) stopAutoplay();
else startAutoplay();
});
window.addEventListener("nexus:lang", (e)=>{
currentLang = e.detail?.lang || "vi";
window.NEXUS_LANG = currentLang;
rebuild();
});
rebuild();
})();