/* ======= LAYOUT BASE ======= */
.nv-carousel {
--gap: 24px;
--slides-desktop: 3;
--slides-tablet: 2;
--slides-mobile: 1;
position: relative;
max-width: 1200px;
margin: 0 auto;
padding: 8px 0;
}
.nv-viewport { overflow: hidden; }
.nv-track {
display: flex;
align-items: stretch;
gap: var(--gap);
will-change: transform;
}
.nv-slide { flex: 0 0 auto; }
/* CARTÃO VERTICAL 9:16, com fallback pra browsers sem aspect-ratio */
.nv-frame {
position: relative;
width: 100%;
background: #000;
border-radius: 14px;
overflow: hidden;
aspect-ratio: 9 / 16;
}
@supports not (aspect-ratio: 9 / 16) {
.nv-frame::before { content:""; display:block; padding-top:177.78%; }
}
.nv-frame > video {
position: absolute; inset: 0;
width: 100%; height: 100%;
object-fit: contain; /* mostra o vídeo inteiro como no print */
display: block;
}
/* NAVEGAÇÃO (opcional) */
/* Botões de navegação com SVG */
.nv-nav {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 42px;
height: 42px;
border: 0;
border-radius: 50%;
background: rgba(0,0,0,.5);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 3;
transition: background .2s;
}
.nv-nav:hover {
background: rgba(0,0,0,.75);
}
.nv-nav svg {
width: 18px;
height: 18px;
fill: #fff;
}
.nv-prev { left: 6px; }
.nv-next { right: 6px; }
(() => {
const root = document.getElementById('nvPortraitCarousel');
if (!root) return;
const viewport = root.querySelector('.nv-viewport');
const track = root.querySelector('.nv-track');
const prevBtn = root.querySelector('.nv-prev');
const nextBtn = root.querySelector('.nv-next');
const pauseOnHover = root.dataset.pauseOnHover === 'true';
const delay = parseInt(root.dataset.delay || '5000', 10); // 5s por padrão
// Responsivo: 3/2/1 por vez
function slidesPerView() {
const w = root.clientWidth || window.innerWidth;
if (w >= 1024) return 3;
if (w >= 768) return 2;
return 1;
}
function layout() {
const n = slidesPerView();
const gap = parseFloat(getComputedStyle(root).getPropertyValue('--gap')) || 24;
const vw = viewport.clientWidth;
const slideW = (vw - gap * (n - 1)) / n;
track.querySelectorAll('.nv-slide').forEach(s => s.style.width = slideW + 'px');
}
// Clona para loop infinito
function ensureClones() {
if (track.dataset.cloned === '1') return;
const originals = Array.from(track.children);
const frag = document.createDocumentFragment();
originals.forEach(slide => frag.appendChild(slide.cloneNode(true)));
track.appendChild(frag);
track.dataset.cloned = '1';
}
// Medidas utilitárias
function slideSize() {
const slide = track.querySelector('.nv-slide');
const gap = parseFloat(getComputedStyle(root).getPropertyValue('--gap')) || 24;
const w = slide ? slide.getBoundingClientRect().width : 0;
return { w, gap, step: w + gap };
}
// Avança/volta 1 slide por vez (suave) e faz loop na metade
function step(dir = 1) {
const { step } = slideSize();
const half = Math.floor(track.scrollWidth / 2);
// normaliza antes de mover (mantém dentro da 1ª metade)
if (viewport.scrollLeft >= half) viewport.scrollLeft -= half;
if (viewport.scrollLeft {
if (viewport.scrollLeft >= half) viewport.scrollLeft -= half;
}, 400);
}
// Timer de autoplay em passos
let timer = null, paused = false;
function start() { stop(); timer = setInterval(() => { if (!paused) step(+1); }, delay); }
function stop() { if (timer) { clearInterval(timer); timer = null; } }
// Pause no hover
if (pauseOnHover) {
root.addEventListener('mouseenter', () => { paused = true; }, { passive:true });
root.addEventListener('mouseleave', () => { paused = false; }, { passive:true });
}
// Botões
nextBtn.addEventListener('click', () => { step(+1); restart(); });
prevBtn.addEventListener('click', () => { step(-1); restart(); });
function restart(){ stop(); start(); }
// Tocar só vídeos visíveis (≥60%)
const io = new IntersectionObserver((entries) => {
entries.forEach(e => {
const video = e.target.querySelector('video');
if (!video) return;
if (e.isIntersecting && e.intersectionRatio >= 0.6) {
const p = video.play(); if (p && p.catch) p.catch(()=>{});
} else {
video.pause();
}
});
}, { root: viewport, threshold: [0, 0.6, 1] });
function observeSlides() {
io.disconnect();
track.querySelectorAll('.nv-slide').forEach(slide => io.observe(slide));
}
// Init
layout();
ensureClones();
observeSlides();
start();
window.addEventListener('resize', () => { layout(); }, { passive:true });
})();