${escapeHtml(card.membership)}
${escapeHtml(card.appointments)}
${escapeHtml(card.servicesCount)}
Services Included:
$${escapeHtml(card.price)}
${escapeHtml(card.save)}
`;
}
function paint() {
leftSlot.innerHTML = cardHtml(cards[visual[0]]);
centerSlot.innerHTML = cardHtml(cards[visual[1]]);
rightSlot.innerHTML = cardHtml(cards[visual[2]]);
dots.forEach(function (dot, i) {
dot.classList.toggle('is-active', i === visual[1]);
});
}
function freezeReset(fn) {
slots.forEach(function (s) { s.style.transition = 'none'; });
fn();
void leftSlot.offsetHeight;
slots.forEach(function (s) { s.style.transition = ''; });
}
function rotate(dir) {
if (animating) return;
animating = true;
if (dir === 'next') {
leftSlot.style.zIndex = 1;
centerSlot.style.zIndex = 2;
rightSlot.style.zIndex = 4;
leftSlot.dataset.pos = 'right';
centerSlot.dataset.pos = 'left';
rightSlot.dataset.pos = 'center';
} else {
leftSlot.style.zIndex = 4;
centerSlot.style.zIndex = 2;
rightSlot.style.zIndex = 1;
leftSlot.dataset.pos = 'center';
centerSlot.dataset.pos = 'right';
rightSlot.dataset.pos = 'left';
}
setTimeout(function () {
visual = dir === 'next'
? [visual[1], visual[2], visual[0]]
: [visual[2], visual[0], visual[1]];
freezeReset(function () {
leftSlot.dataset.pos = 'left';
centerSlot.dataset.pos = 'center';
rightSlot.dataset.pos = 'right';
slots.forEach(function (s) { s.style.zIndex = ''; });
paint();
});
animating = false;
}, duration);
}
nextBtn.addEventListener('click', function () { rotate('next'); });
prevBtn.addEventListener('click', function () { rotate('prev'); });
var startX = 0;
var deltaX = 0;
stage.addEventListener('touchstart', function (e) {
startX = e.changedTouches[0].clientX;
deltaX = 0;
}, { passive: true });
stage.addEventListener('touchmove', function (e) {
deltaX = e.changedTouches[0].clientX - startX;
}, { passive: true });
stage.addEventListener('touchend', function () {
if (Math.abs(deltaX)