Client

CAVE 13/70

Timeline

2 WEEKS

Service

REDESIGN
STRATEGY

WEbsite

BOLD

MODERN

DISTINCT.

Challenge

Caves are everywhere in the countryside, so standing out is literally make-or-break. The real challenge? No clear target audience meant the messaging was speaking to everyone and no one at the same time. We needed to get specific about who this experience was for before we could make it pop.

Solution

Defining the target user gave us the clarity needed to position the brand effectively and create messaging that resonates. Research revealed the ideal audience was younger and more experience-driven than initially anticipated. Adventurous drinkers looking to discover natural wines and unique spirits rather than traditional wine collectors. We evolved the branding to feel approachable and contemporary, updated the design aesthetic to appeal to a younger, less traditional palate, and tailored the messaging to emphasize curiosity.

Outcome

A modern landing page design the client was very happy with, unfortunately the accreditation organization they were working with already had a brand guideline the client was unaware of.

Hit your targets!

CTA

Pull me

KPI
CRM
Your CEO

All targets hit!

It took you X seconds.

Try again

Ready when you are, player 1

Party up with a designer that turns ideas into a radiant experience.

Send a flattering email

Grab a coffee and fill out a form.
It's 100% free & non-binding.
(More money for your Minecraft skins)

gsap.registerPlugin(Observer,CustomEase) CustomEase.create("slideshow-wipe", "0.6, 0.08, 0.02, 0.99"); function initSlideShow(el) { // Save all elements in an object for easy reference const ui = { el, slides: Array.from(el.querySelectorAll('[data-slideshow="slide"]')), inner: Array.from(el.querySelectorAll('[data-slideshow="parallax"]')), thumbs: Array.from(el.querySelectorAll('[data-slideshow="thumb"]')) }; let current = 0; const length = ui.slides.length; let animating = false; let observer; let animationDuration = 0.9 // Define the duration of your 'slide' here ui.slides.forEach((slide, index) => { slide.setAttribute('data-index', index); }); ui.thumbs.forEach((thumb, index) => { thumb.setAttribute('data-index', index); }); ui.slides[current].classList.add('is--current'); ui.thumbs[current].classList.add('is--current'); function navigate(direction, targetIndex = null) { if (animating) return; animating = true; observer.disable(); const previous = current; current = targetIndex !== null && targetIndex !== undefined ? targetIndex : direction === 1 ? current < length - 1 ? current + 1 : 0 : current > 0 ? current - 1 : length - 1; const currentSlide = ui.slides[previous]; const currentInner = ui.inner[previous]; const upcomingSlide = ui.slides[current]; const upcomingInner = ui.inner[current]; gsap.timeline({ defaults: { duration: animationDuration, ease: 'slideshow-wipe' }, onStart: function() { upcomingSlide.classList.add('is--current'); ui.thumbs[previous].classList.remove('is--current'); ui.thumbs[current].classList.add('is--current'); }, onComplete: function() { currentSlide.classList.remove('is--current'); animating = false; // Re-enable observer after a short delay setTimeout(() => observer.enable(), animationDuration); } }) .to(currentSlide, { xPercent: -direction * 100 },0) .to(currentInner, { xPercent: direction * 50 }, 0) .fromTo(upcomingSlide, { xPercent: direction * 100 }, { xPercent: 0 }, 0) .fromTo(upcomingInner, { xPercent: -direction * 50 }, { xPercent: 0 }, 0); } function onClick(event) { const targetIndex = parseInt(event.currentTarget.getAttribute('data-index'), 10); if (targetIndex === current || animating) return; const direction = targetIndex > current ? 1 : -1; navigate(direction, targetIndex); } ui.thumbs.forEach(thumb => { thumb.addEventListener('click', onClick); }); observer = Observer.create({ target: el, type: 'wheel,touch,pointer', // Drag events to go left/right onLeft: () => { if (!animating) navigate(1); }, onRight: () => {if (!animating) navigate(-1); }, // For wheel events, check horizontal movement onWheel: (event) => { if (animating) return; if (Math.abs(event.deltaX) > Math.abs(event.deltaY)) { if (event.deltaX > 50) { navigate(1); } else if (event.deltaX < -50) { navigate(-1); } } }, wheelSpeed: -1, tolerance: 10 }); // Cleanup function if you need it return { destroy: function() { if (observer) observer.kill(); ui.thumbs.forEach(thumb => { thumb.removeEventListener('click', onClick); }); } }; } function initParallaxImageGalleryThumbnails() { let wrappers = document.querySelectorAll('[data-slideshow="wrap"]'); wrappers.forEach(wrap => initSlideShow(wrap)); } // Initialize Parallax Image Gallery with Thumbnails document.addEventListener('DOMContentLoaded', () => { initParallaxImageGalleryThumbnails(); });