<section class="vb-g7p" data-section-name="Галерея проекта" aria-labelledby="vb-g7p-title" data-vibeblock-unique-section="yes">
<style>
.vb-g7p,
.vb-g7p * { box-sizing: border-box; }
.vb-g7p input,
.vb-g7p textarea,
.vb-g7p select { font: inherit; }
.vb-g7p {
--g7p-cream: #f2f0eb;
--g7p-ceramic: #edebe9;
--g7p-green: #006241;
--g7p-accent: #00754A;
--g7p-house: #1E3932;
--g7p-text: rgba(0, 0, 0, 0.87);
--g7p-text-soft: rgba(0, 0, 0, 0.58);
--g7p-text-on-dark: rgba(255, 255, 255, 0.7);
--g7p-radius: 12px;
background: var(--g7p-cream);
padding: 80px 16px;
font-family: var(--t-text-font, "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif);
color: var(--g7p-text);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.vb-g7p__inner {
max-width: 1200px;
margin: 0 auto;
}
/* ---------- Header ---------- */
.vb-g7p__head {
max-width: 760px;
margin: 0 auto 48px;
text-align: left;
}
.vb-g7p__eyebrow {
display: inline-flex;
align-items: center;
gap: 10px;
font-family: var(--t-headline-font, "Inter", sans-serif);
font-size: 13px;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--g7p-green);
margin-bottom: 18px;
}
.vb-g7p__eyebrow::before {
content: '';
width: 28px;
height: 2px;
background: var(--g7p-green);
border-radius: 2px;
}
.vb-g7p__title {
font-family: var(--t-headline-font, "Inter", "Helvetica Neue", sans-serif);
font-size: 36px;
font-weight: 600;
line-height: 1.2;
letter-spacing: -0.01em;
color: var(--g7p-green);
margin: 0 0 16px;
}
.vb-g7p__title-meta {
display: inline-block;
margin-left: 8px;
padding-left: 14px;
border-left: 1px solid var(--g7p-text-soft);
color: var(--g7p-text-soft);
font-weight: 400;
font-size: 24px;
}
.vb-g7p__lead {
font-size: 16px;
line-height: 1.5;
color: var(--g7p-text-soft);
margin: 0;
max-width: 560px;
}
/* ---------- Viewer ---------- */
.vb-g7p__viewer {
position: relative;
}
.vb-g7p__stage {
position: relative;
aspect-ratio: 16 / 9;
background: var(--g7p-house);
border-radius: var(--g7p-radius);
overflow: hidden;
box-shadow:
0 0 0.5px rgba(0, 0, 0, 0.14),
0 1px 1px rgba(0, 0, 0, 0.24),
0 16px 32px -12px rgba(0, 0, 0, 0.18);
}
.vb-g7p__photo {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
display: block;
opacity: 1;
transition: opacity 0.28s ease;
user-select: none;
-webkit-user-drag: none;
}
.vb-g7p__photo--changing {
opacity: 0;
}
@media (prefers-reduced-motion: reduce) {
.vb-g7p__photo { transition: none; }
.vb-g7p__photo--changing { opacity: 1; }
}
/* Arrows on main stage */
.vb-g7p__arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 52px;
height: 52px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.92);
backdrop-filter: blur(10px) saturate(140%);
-webkit-backdrop-filter: blur(10px) saturate(140%);
border: 1px solid rgba(0, 0, 0, 0.06);
color: var(--g7p-text);
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
box-shadow:
0 1px 2px rgba(0, 0, 0, 0.10),
0 6px 14px rgba(0, 0, 0, 0.18);
transition: background 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
z-index: 3;
}
.vb-g7p__arrow:hover {
background: #ffffff;
}
.vb-g7p__arrow:active {
transform: translateY(-50%) scale(0.94);
}
.vb-g7p__arrow:focus-visible {
outline: 2px solid var(--g7p-accent);
outline-offset: 3px;
}
.vb-g7p__arrow svg {
width: 24px;
height: 24px;
display: block;
}
.vb-g7p__arrow--prev { left: 18px; }
.vb-g7p__arrow--next { right: 18px; }
/* Counter pill */
.vb-g7p__counter {
position: absolute;
top: 18px;
right: 18px;
background: rgba(255, 255, 255, 0.92);
backdrop-filter: blur(10px) saturate(140%);
-webkit-backdrop-filter: blur(10px) saturate(140%);
border-radius: 50px;
padding: 7px 14px;
font-family: var(--t-headline-font, "Inter", sans-serif);
font-size: 13px;
font-weight: 600;
letter-spacing: 0.02em;
color: var(--g7p-text);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
z-index: 3;
display: inline-flex;
align-items: baseline;
gap: 6px;
pointer-events: none;
}
.vb-g7p__counter-current {
color: var(--g7p-green);
font-size: 14px;
font-weight: 700;
}
.vb-g7p__counter-sep {
color: var(--g7p-text-soft);
font-weight: 400;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.1em;
}
.vb-g7p__counter-total {
color: var(--g7p-text);
}
/* Caption row */
.vb-g7p__caption {
display: flex;
justify-content: space-between;
align-items: flex-end;
gap: 24px;
margin-top: 22px;
padding: 0 4px;
min-height: 56px;
}
.vb-g7p__caption-body {
display: flex;
flex-direction: column;
gap: 4px;
min-width: 0;
}
.vb-g7p__caption-text {
font-family: var(--t-headline-font, "Inter", sans-serif);
font-size: 19px;
font-weight: 600;
line-height: 1.35;
letter-spacing: -0.01em;
color: var(--g7p-text);
margin: 0;
}
.vb-g7p__caption-meta {
font-size: 14px;
line-height: 1.4;
color: var(--g7p-text-soft);
margin: 0;
white-space: nowrap;
}
.vb-g7p__caption-meta::before {
content: '';
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--g7p-accent);
margin-right: 8px;
vertical-align: middle;
}
/* ---------- Thumbnail strip ---------- */
.vb-g7p__strip-wrap {
position: relative;
margin-top: 22px;
}
.vb-g7p__strip {
display: flex;
gap: 10px;
overflow-x: auto;
overflow-y: hidden;
scroll-behavior: smooth;
scrollbar-width: none;
padding: 10px 24px 14px;
-webkit-overflow-scrolling: touch;
scroll-snap-type: x proximity;
}
.vb-g7p__strip::-webkit-scrollbar {
display: none;
}
.vb-g7p__thumb {
flex: 0 0 auto;
width: 144px;
aspect-ratio: 16 / 9;
border: 0;
background: transparent;
padding: 0;
border-radius: 8px;
cursor: pointer;
overflow: hidden;
position: relative;
opacity: 0.5;
transition: opacity 0.25s ease, transform 0.2s ease, box-shadow 0.25s ease;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.10);
scroll-snap-align: center;
}
.vb-g7p__thumb img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
border-radius: 8px;
}
.vb-g7p__thumb:hover {
opacity: 0.9;
}
.vb-g7p__thumb:active {
transform: scale(0.96);
}
.vb-g7p__thumb:focus-visible {
outline: 2px solid var(--g7p-accent);
outline-offset: 3px;
}
.vb-g7p__thumb--active {
opacity: 1;
box-shadow:
inset 0 0 0 2px var(--g7p-accent),
0 2px 6px rgba(0, 0, 0, 0.18);
}
/* Strip nav arrows */
.vb-g7p__strip-nav {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 40px;
height: 40px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.96);
backdrop-filter: blur(8px) saturate(140%);
-webkit-backdrop-filter: blur(8px) saturate(140%);
border: 1px solid rgba(0, 0, 0, 0.06);
color: var(--g7p-text);
cursor: pointer;
display: none !important;
align-items: center;
justify-content: center;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.14);
transition: transform 0.2s ease, background 0.2s ease;
z-index: 3;
}
.vb-g7p__strip-nav:active {
transform: translateY(-50%) scale(0.94);
}
.vb-g7p__strip-nav:focus-visible {
outline: 2px solid var(--g7p-accent);
outline-offset: 2px;
}
.vb-g7p__strip-nav svg {
width: 18px;
height: 18px;
display: block;
}
.vb-g7p__strip-nav--prev { left: 0; }
.vb-g7p__strip-nav--next { right: 0; }
/* Edge fade hint when strip overflows */
.vb-g7p__strip-wrap::before,
.vb-g7p__strip-wrap::after {
content: '';
position: absolute;
top: 0;
bottom: 14px;
width: 24px;
pointer-events: none;
z-index: 2;
opacity: 0;
transition: opacity 0.2s ease;
}
.vb-g7p__strip-wrap::before {
left: 0;
background: linear-gradient(to right, var(--g7p-cream), rgba(242, 240, 235, 0));
}
.vb-g7p__strip-wrap::after {
right: 0;
background: linear-gradient(to left, var(--g7p-cream), rgba(242, 240, 235, 0));
}
.vb-g7p__strip-wrap--fade-left::before { opacity: 1; }
.vb-g7p__strip-wrap--fade-right::after { opacity: 1; }
/* ---------- Responsive ---------- */
@media (max-width: 960px) {
.vb-g7p { padding: 64px 24px; }
.vb-g7p__title { font-size: 30px; }
.vb-g7p__title-meta { font-size: 20px; }
.vb-g7p__head { margin-bottom: 36px; }
}
@media (max-width: 640px) {
.vb-g7p { padding: 48px 16px; }
.vb-g7p__title { font-size: 26px; }
.vb-g7p__title-meta {
display: block;
margin: 8px 0 0;
padding: 0;
border: 0;
font-size: 18px;
}
.vb-g7p__head { margin-bottom: 28px; }
.vb-g7p__arrow { width: 44px; height: 44px; }
.vb-g7p__arrow svg { width: 22px; height: 22px; }
.vb-g7p__arrow--prev { left: 12px; }
.vb-g7p__arrow--next { right: 12px; }
.vb-g7p__counter { top: 12px; right: 12px; padding: 6px 12px; font-size: 12px; }
.vb-g7p__counter-current { font-size: 13px; }
.vb-g7p__caption {
flex-direction: column;
align-items: flex-start;
gap: 6px;
margin-top: 18px;
}
.vb-g7p__caption-text { font-size: 17px; }
.vb-g7p__caption-meta { white-space: normal; }
.vb-g7p__thumb { width: 112px; }
.vb-g7p__strip { gap: 8px; padding: 10px 16px 14px; }
.vb-g7p__strip-wrap { margin-top: 18px; }
}
@media (max-width: 480px) {
.vb-g7p { padding: 40px 16px; }
.vb-g7p__title { font-size: 22px; }
.vb-g7p__arrow { width: 40px; height: 40px; }
.vb-g7p__arrow svg { width: 20px; height: 20px; }
.vb-g7p__counter { padding: 5px 10px; font-size: 11px; }
.vb-g7p__counter-current { font-size: 12px; }
.vb-g7p__counter-sep { font-size: 10px; }
.vb-g7p__thumb { width: 100px; }
.vb-g7p__caption-text { font-size: 16px; }
}
</style>
<div class="vb-g7p__inner">
<header class="vb-g7p__head">
<span class="vb-g7p__eyebrow">Проект дома</span>
<h2 id="vb-g7p-title" class="vb-g7p__title">
Сосны<span class="vb-g7p__title-meta">180 м²</span>
</h2>
<p class="vb-g7p__lead">Двухэтажный загородный дом из клееного бруса. Рассмотрите проект со всех сторон — фасады, интерьеры и участок.</p>
</header>
<div class="vb-g7p__viewer" role="region" aria-roledescription="gallery" aria-label="Фотографии проекта Сосны">
<div class="vb-g7p__stage" id="vb-g7p-stage">
<img class="vb-g7p__photo" src="https://static.tildacdn.com/tild6539-3464-4539-b363-636539396636/photo-1788429749141-.jpg" alt="Фасад дома Сосны в дневном свете среди сосен" draggable="false">
<button class="vb-g7p__arrow vb-g7p__arrow--prev" type="button" aria-label="Предыдущее фото">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M15 5 L9 12 L15 19"></path>
</svg>
</button>
<button class="vb-g7p__arrow vb-g7p__arrow--next" type="button" aria-label="Следующее фото">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M9 5 L15 12 L9 19"></path>
</svg>
</button>
<div class="vb-g7p__counter" aria-live="polite" aria-atomic="true">
<span class="vb-g7p__counter-current">1</span>
<span class="vb-g7p__counter-sep">из</span>
<span class="vb-g7p__counter-total">9</span>
</div>
</div>
<div class="vb-g7p__caption">
<div class="vb-g7p__caption-body">
<p class="vb-g7p__caption-text" aria-live="polite">Фасад среди сосен в дневном свете</p>
<p class="vb-g7p__caption-meta">180 м² · загородный дом из клееного бруса</p>
</div>
</div>
</div>
<div class="vb-g7p__strip-wrap" id="vb-g7p-strip-wrap">
<button class="vb-g7p__strip-nav vb-g7p__strip-nav--prev" type="button" aria-label="Прокрутить миниатюры влево">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M15 5 L9 12 L15 19"></path>
</svg>
</button>
<div class="vb-g7p__strip" role="tablist" aria-label="Миниатюры фотографий">
<button class="vb-g7p__thumb vb-g7p__thumb--active" type="button" role="tab" aria-selected="true" tabindex="0" data-full="https://static.tildacdn.com/tild6539-3464-4539-b363-636539396636/photo-1788429749141-.jpg" data-caption="Фасад среди сосен в дневном свете" aria-label="Фасад среди сосен в дневном свете, фото 1 из 9">
<img src="https://static.tildacdn.com/tild6539-3464-4539-b363-636539396636/photo-1788429749141-.jpg" alt="">
</button>
<button class="vb-g7p__thumb" type="button" role="tab" aria-selected="false" tabindex="-1" data-full="https://static.tildacdn.com/tild3065-3431-4365-b636-383862346533/photo-1683923389483-.jpg" data-caption="Дом и участок с высоты" aria-label="Дом и участок с высоты, фото 2 из 9">
<img src="https://static.tildacdn.com/tild3065-3431-4365-b636-383862346533/photo-1683923389483-.jpg" alt="">
</button>
<button class="vb-g7p__thumb" type="button" role="tab" aria-selected="false" tabindex="-1" data-full="https://static.tildacdn.com/tild6539-6663-4663-a630-653030373032/photo-1659633882885-.jpg" data-caption="Вечерняя подсветка фасада" aria-label="Вечерняя подсветка фасада, фото 3 из 9">
<img src="https://static.tildacdn.com/tild6539-6663-4663-a630-653030373032/photo-1659633882885-.jpg" alt="">
</button>
<button class="vb-g7p__thumb" type="button" role="tab" aria-selected="false" tabindex="-1" data-full="https://static.tildacdn.com/tild3030-6231-4834-a434-313932313365/photo-1696861080288-.jpg" data-caption="Гостиная с панорамными окнами" aria-label="Гостиная с панорамными окнами, фото 4 из 9">
<img src="https://static.tildacdn.com/tild3030-6231-4834-a434-313932313365/photo-1696861080288-.jpg" alt="">
</button>
<button class="vb-g7p__thumb" type="button" role="tab" aria-selected="false" tabindex="-1" data-full="https://static.tildacdn.com/tild3634-6238-4638-a461-386462343235/photo-1663337048816-.jpg" data-caption="Кухня-гостиная" aria-label="Кухня-гостиная, фото 5 из 9">
<img src="https://static.tildacdn.com/tild3634-6238-4638-a461-386462343235/photo-1663337048816-.jpg" alt="">
</button>
<button class="vb-g7p__thumb" type="button" role="tab" aria-selected="false" tabindex="-1" data-full="https://static.tildacdn.com/tild3663-6564-4838-b931-383330656561/photo-1789132782848-.jpg" data-caption="Мастер-спальня" aria-label="Мастер-спальня, фото 6 из 9">
<img src="https://static.tildacdn.com/tild3663-6564-4838-b931-383330656561/photo-1789132782848-.jpg" alt="">
</button>
<button class="vb-g7p__thumb" type="button" role="tab" aria-selected="false" tabindex="-1" data-full="https://static.tildacdn.com/tild3262-3862-4734-b338-616633386562/photo-1759239355404-.jpg" data-caption="Санузел с панорамным окном" aria-label="Санузел с панорамным окном, фото 7 из 9">
<img src="https://static.tildacdn.com/tild3262-3862-4734-b338-616633386562/photo-1759239355404-.jpg" alt="">
</button>
<button class="vb-g7p__thumb" type="button" role="tab" aria-selected="false" tabindex="-1" data-full="https://static.tildacdn.com/tild3965-3131-4363-b163-373435636539/photo-1760992631346-.jpg" data-caption="Терраса и участок" aria-label="Терраса и участок, фото 8 из 9">
<img src="https://static.tildacdn.com/tild3965-3131-4363-b163-373435636539/photo-1760992631346-.jpg" alt="">
</button>
<button class="vb-g7p__thumb" type="button" role="tab" aria-selected="false" tabindex="-1" data-full="https://static.tildacdn.com/tild3032-3130-4537-b139-656464356162/photo-1759300632629-.jpg" data-caption="Дом зимой" aria-label="Дом зимой, фото 9 из 9">
<img src="https://static.tildacdn.com/tild3032-3130-4537-b139-656464356162/photo-1759300632629-.jpg" alt="">
</button>
</div>
<button class="vb-g7p__strip-nav vb-g7p__strip-nav--next" type="button" aria-label="Прокрутить миниатюры вправо">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M9 5 L15 12 L9 19"></path>
</svg>
</button>
</div>
</div>
<script>
(function () {
var root = document.querySelector('.vb-g7p');
if (!root) return;
var thumbEls = Array.prototype.slice.call(root.querySelectorAll('.vb-g7p__thumb'));
var photoEl = root.querySelector('.vb-g7p__photo');
var prevBtn = root.querySelector('.vb-g7p__arrow--prev');
var nextBtn = root.querySelector('.vb-g7p__arrow--next');
var captionTextEl = root.querySelector('.vb-g7p__caption-text');
var counterCurrentEl = root.querySelector('.vb-g7p__counter-current');
var counterTotalEl = root.querySelector('.vb-g7p__counter-total');
var stripEl = root.querySelector('.vb-g7p__strip');
var stageEl = root.querySelector('.vb-g7p__stage');
var stripWrapEl = root.querySelector('.vb-g7p__strip-wrap');
var stripPrevBtn = root.querySelector('.vb-g7p__strip-nav--prev');
var stripNextBtn = root.querySelector('.vb-g7p__strip-nav--next');
if (!thumbEls.length || !photoEl || !stripEl || !stageEl) return;
var total = thumbEls.length;
var current = 0;
var reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var items = thumbEls.map(function (t) {
return {
full: t.getAttribute('data-full') || '',
caption: t.getAttribute('data-caption') || ''
};
});
// Preload all full-size images for instant swap
items.forEach(function (item) {
if (!item.full) return;
var pre = new Image();
pre.src = item.full;
});
function setCurrent(idx, focusThumb) {
if (idx < 0) idx = total - 1;
if (idx >= total) idx = 0;
current = idx;
var item = items[current];
// Swap main photo
if (photoEl.src !== item.full) {
if (reduceMotion) {
photoEl.src = item.full;
photoEl.alt = item.caption;
} else {
photoEl.classList.add('vb-g7p__photo--changing');
setTimeout(function () {
photoEl.src = item.full;
photoEl.alt = item.caption;
var done = function () {
photoEl.classList.remove('vb-g7p__photo--changing');
photoEl.removeEventListener('load', done);
};
if (photoEl.complete && photoEl.naturalWidth > 0) {
done();
} else {
photoEl.addEventListener('load', done);
// Fallback in case load doesn't fire
setTimeout(done, 600);
}
}, 220);
}
}
// Update thumbs
thumbEls.forEach(function (t, i) {
var active = i === current;
if (active) {
t.classList.add('vb-g7p__thumb--active');
t.setAttribute('aria-selected', 'true');
t.tabIndex = 0;
} else {
t.classList.remove('vb-g7p__thumb--active');
t.setAttribute('aria-selected', 'false');
t.tabIndex = -1;
}
});
// Update caption + counter
if (captionTextEl) captionTextEl.textContent = item.caption;
if (counterCurrentEl) counterCurrentEl.textContent = String(current + 1);
if (counterTotalEl) counterTotalEl.textContent = String(total);
// Keep active thumb in view
var activeThumb = thumbEls[current];
if (activeThumb && typeof activeThumb.scrollIntoView === 'function') {
try {
activeThumb.scrollIntoView({
behavior: reduceMotion ? 'auto' : 'smooth',
inline: 'center',
block: 'nearest'
});
} catch (e) {
// older browsers
var stripRect = stripEl.getBoundingClientRect();
var thumbRect = activeThumb.getBoundingClientRect();
var offset = (thumbRect.left - stripRect.left) - (stripEl.clientWidth / 2) + (thumbRect.width / 2);
stripEl.scrollLeft += offset;
}
}
if (focusThumb && activeThumb) activeThumb.focus({ preventScroll: true });
updateStripState();
}
function updateStripState() {
if (!stripEl) return;
var overflow = stripEl.scrollWidth > stripEl.clientWidth + 1;
var atStart = stripEl.scrollLeft <= 1;
var atEnd = stripEl.scrollLeft + stripEl.clientWidth >= stripEl.scrollWidth - 1;
if (stripPrevBtn) stripPrevBtn.style.display = (overflow && !atStart) ? 'inline-flex' : 'none';
if (stripNextBtn) stripNextBtn.style.display = (overflow && !atEnd) ? 'inline-flex' : 'none';
if (stripWrapEl) {
stripWrapEl.classList.toggle('vb-g7p__strip-wrap--fade-left', overflow && !atStart);
stripWrapEl.classList.toggle('vb-g7p__strip-wrap--fade-right', overflow && !atEnd);
}
}
// Bind events
thumbEls.forEach(function (t, i) {
t.addEventListener('click', function () { setCurrent(i, false); });
});
if (prevBtn) prevBtn.addEventListener('click', function () { setCurrent(current - 1, false); });
if (nextBtn) nextBtn.addEventListener('click', function () { setCurrent(current + 1, false); });
if (stripPrevBtn) stripPrevBtn.addEventListener('click', function () {
var step = Math.max(240, stripEl.clientWidth * 0.8);
stripEl.scrollBy({ left: -step, behavior: reduceMotion ? 'auto' : 'smooth' });
});
if (stripNextBtn) stripNextBtn.addEventListener('click', function () {
var step = Math.max(240, stripEl.clientWidth * 0.8);
stripEl.scrollBy({ left: step, behavior: reduceMotion ? 'auto' : 'smooth' });
});
// Keyboard navigation
root.addEventListener('keydown', function (e) {
var tag = (e.target && e.target.tagName) || '';
if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;
var key = e.key;
var handled = false;
if (key === 'ArrowLeft') {
setCurrent(current - 1, isThumbFocused());
handled = true;
} else if (key === 'ArrowRight') {
setCurrent(current + 1, isThumbFocused());
handled = true;
} else if (key === 'Home') {
setCurrent(0, isThumbFocused());
handled = true;
} else if (key === 'End') {
setCurrent(total - 1, isThumbFocused());
handled = true;
}
if (handled) e.preventDefault();
});
function isThumbFocused() {
var a = document.activeElement;
return !!(a && a.classList && a.classList.contains('vb-g7p__thumb'));
}
// Touch swipe on main stage
var tStartX = 0, tStartY = 0, tDX = 0, tDY = 0, tracking = false;
stageEl.addEventListener('touchstart', function (e) {
if (!e.touches || e.touches.length !== 1) return;
tStartX = e.touches[0].clientX;
tStartY = e.touches[0].clientY;
tDX = 0; tDY = 0; tracking = true;
}, { passive: true });
stageEl.addEventListener('touchmove', function (e) {
if (!tracking || !e.touches || e.touches.length !== 1) return;
tDX = e.touches[0].clientX - tStartX;
tDY = e.touches[0].clientY - tStartY;
}, { passive: true });
stageEl.addEventListener('touchend', function () {
if (!tracking) return;
tracking = false;
var ax = Math.abs(tDX);
var ay = Math.abs(tDY);
if (ax > 48 && ax > ay * 1.4) {
if (tDX < 0) setCurrent(current + 1, false);
else setCurrent(current - 1, false);
}
});
// Listen to strip scroll for edge fade
if (stripEl) stripEl.addEventListener('scroll', updateStripState, { passive: true });
window.addEventListener('resize', updateStripState);
// Init
counterTotalEl.textContent = String(total);
setCurrent(0, false);
updateStripState();
})();
</script>
</section><style data-vb-overrides="true">
.vb-g7p__strip {
padding: 10px 0px 14px;
}
</style>