Feature section with vertical scroll stack cards
Category: Features
Below is the component for your context <!DOCTYPE html><html lang="en"><head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>How it works - Lunera</title>
<link href="https://fonts.googleapis.com" rel="preconnect">
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
<style>
.animate-on-scroll-hidden {
opacity: 0;
transform: translateY(20px);
transition: opacity 0.8s ease-out, transform 0.8s ease-out;
}
.animate-on-scroll-visible {
opacity: 1;
transform: translateY(0);
}
</style>
<style type="text/tailwindcss">@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
body {
@apply font-secondary;
}
}
.sticky-container {
height: fit-content;
}</style><script src="https://cdn.tailwindcss.com"></script><script>tailwind.config = {
important: '#app-root',
theme: {
extend: {
colors: {
'brand-primary': 'rgb(101, 155, 255)',
'neutral-background': 'rgb(255, 255, 255)',
'text-primary': 'rgb(61, 61, 61)',
'text-secondary': 'rgb(109, 109, 109)',
'border-light': 'rgb(238, 238, 238)',
},
fontFamily: {
'primary': ['Inter Display', 'Inter', 'sans-serif'],
'secondary': ['Inter', 'sans-serif'],
},
borderRadius: {
'xl': '24px',
'full': '40px',
},
boxShadow: {
'card': 'rgba(0, 0, 0, 0.08) 0px 8px 30px 0px',
'tag': 'rgba(0, 0, 0, 0.1) 0px 4px 12px 0px',
}
}
}
}</script></head>
<body id="app-root" class="bg-white overflow-x-hidden">
<main><div class="max-w-[1300px] mx-auto px-10 md:px-20 py-16 flex flex-col lg:flex-row justify-between items-start gap-12 relative">
<!-- Left Column (Sticky) -->
<div class="lg:sticky lg:top-[120px] w-full lg:w-[456px] flex flex-col items-start gap-4 sticky-container">
<div class="bg-white border border-[#e6e6e6] rounded-full px-3 py-1.5 shadow-tag flex items-center justify-center gap-1" data-animation-on-scroll="">
<span class="text-[14px] font-primary text-text-secondary capitalize tracking-[-0.42px]">How it works</span>
</div>
<div data-animation-on-scroll="">
<h2 class="text-text-primary font-primary font-medium text-[48px] leading-[1.2] tracking-[-1.44px] max-w-[456px]">
From setup to insight—just three simple steps.
</h2>
</div>
</div>
<!-- Right Column (Cards) -->
<div class="w-full lg:w-[684px] lg:pl-16 flex flex-col gap-10">
<!-- Card 01 -->
<div class="lg:sticky lg:top-[120px] w-full max-w-[600px] h-auto min-h-[381px] bg-gradient-to-br from-[#fafafa] to-[#f4f4f4] rounded-xl border border-border-light shadow-card p-8 flex flex-col justify-center items-center relative overflow-hidden group">
<!-- Step Badge -->
<div class="absolute bottom-6 right-6 w-8 h-8 rounded-full bg-border-light flex items-center justify-center text-[14px] text-text-secondary font-primary tracking-[-0.42px] z-10">
01
</div>
<div class="flex flex-col md:flex-row items-start gap-5 w-full">
<div class="flex-shrink-0 w-9 h-9 bg-brand-primary rounded-full p-2 flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="white" class="w-5 h-5">
<path d="M88.57,35A8,8,0,0,1,103.43,29l8,20A8,8,0,0,1,96.57,55ZM29,103.43l20,8A8,8,0,1,0,55,96.57l-20-8A8,8,0,0,0,29,103.43ZM227,152.57l-20-8A8,8,0,1,0,201,159.43l20,8A8,8,0,0,0,227,152.57ZM159.43,201A8,8,0,0,0,144.57,207l8,20A8,8,0,1,0,167.43,221ZM237.91,18.52a8,8,0,0,0-11.5-.18L174,70.75l-5.38-5.38a32,32,0,0,0-45.28,0L106.14,82.54a4,4,0,0,0,0,5.66l61.7,61.66a4,4,0,0,0,5.66,0l16.74-16.74a32.76,32.76,0,0,0,9.81-22.52,31.82,31.82,0,0,0-9.37-23.17l-5.38-5.37,52.2-52.17A8.22,8.22,0,0,0,237.91,18.52ZM85.64,90.34a8,8,0,0,0-11.49.18,8.22,8.22,0,0,0,.41,11.37L80.67,108,65.34,123.31A31.82,31.82,0,0,0,56,146.47,32.75,32.75,0,0,0,65.77,169l5,4.94L18.49,226.13a8.21,8.21,0,0,0-.61,11.1,8,8,0,0,0,11.72.43L82,185.25l5.37,5.38a32.1,32.1,0,0,0,45.29,0L148,175.31l6.34,6.35a8,8,0,0,0,11.32-11.32Z"></path>
</svg>
</div>
<div class="flex-grow flex flex-col gap-6">
<div class="flex flex-col gap-1">
<h4 class="text-text-primary font-primary font-medium text-[26px] tracking-[-0.78px]">Connect Accounts</h4>
<p class="text-text-secondary font-primary text-[16px] tracking-[-0.48px]">Securely link your bank and business tools in minutes.</p>
</div>
<img src="https://framerusercontent.com/images/UlOABIv2wZ6Fm8g2WA1IT9BBpVU.svg" alt="Connect" class="w-[400px] h-[232px] object-cover rounded-lg">
</div>
</div>
</div>
<!-- Card 02 -->
<div class="lg:sticky lg:top-[150px] w-full max-w-[600px] h-auto min-h-[381px] bg-gradient-to-br from-[#fafafa] to-[#f4f4f4] rounded-xl border border-border-light shadow-card p-8 flex flex-col justify-center items-center relative overflow-hidden group">
<div class="absolute bottom-6 right-6 w-8 h-8 rounded-full bg-border-light flex items-center justify-center text-[14px] text-text-secondary font-primary z-10">
02
</div>
<div class="flex flex-col md:flex-row items-start gap-5 w-full">
<div class="flex-shrink-0 w-9 h-9 bg-brand-primary rounded-full p-2 flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="white" class="w-5 h-5">
<path d="M128,40a96,96,0,1,0,96,96A96.11,96.11,0,0,0,128,40Zm45.66,61.66-40,40a8,8,0,0,1-11.32-11.32l40-40a8,8,0,0,1,11.32,11.32ZM96,16a8,8,0,0,1,8-8h48a8,8,0,0,1,0,16H104A8,8,0,0,1,96,16Z"></path>
</svg>
</div>
<div class="flex-grow flex flex-col gap-6">
<div class="flex flex-col gap-1">
<h4 class="text-text-primary font-primary font-medium text-[26px] tracking-[-0.78px]">Track in Real-Time</h4>
<p class="text-text-secondary font-primary text-[16px] tracking-[-0.48px]">View all your financial data live on one clean dashboard.</p>
</div>
<img src="https://framerusercontent.com/images/fxRd3uX74bf4rx17yNVXQwUiVc.svg" alt="Track" class="w-[400px] h-[232px] object-cover rounded-lg">
</div>
</div>
</div>
<!-- Card 03 -->
<div class="lg:sticky lg:top-[180px] w-full max-w-[600px] h-auto min-h-[381px] bg-gradient-to-br from-[#fafafa] to-[#f4f4f4] rounded-xl border border-border-light shadow-card p-8 flex flex-col justify-center items-center relative overflow-hidden group">
<div class="absolute bottom-6 right-6 w-8 h-8 rounded-full bg-border-light flex items-center justify-center text-[14px] text-text-secondary font-primary z-10">
03
</div>
<div class="flex flex-col md:flex-row items-start gap-5 w-full">
<div class="flex-shrink-0 w-9 h-9 bg-brand-primary rounded-full p-2 flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="white" class="w-5 h-5">
<path d="M240,56v64a8,8,0,0,1-13.66,5.66L200,99.31l-58.34,58.35a8,8,0,0,1-11.32,0L96,123.31,29.66,189.66a8,8,0,0,1-11.32-11.32l72-72a8,8,0,0,1,11.32,0L136,140.69,188.69,88,162.34,61.66A8,8,0,0,1,168,48h64A8,8,0,0,1,240,56Z"></path>
</svg>
</div>
<div class="flex-grow flex flex-col gap-6">
<div class="flex flex-col gap-1">
<h4 class="text-text-primary font-primary font-medium text-[26px] tracking-[-0.78px]">Grow Smarter, Faster</h4>
<p class="text-text-secondary font-primary text-[16px] tracking-[-0.48px]">Use insights and reports to guide better business decisions.</p>
</div>
<img src="https://framerusercontent.com/images/UtpNRdAnmSCcUHRDJqfzTribMOA.svg" alt="Grow" class="w-[400px] h-[232px] object-cover rounded-lg">
</div>
</div>
</div>
</div>
</div></main>
<script>
document.addEventListener('DOMContentLoaded', () => {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('animate-on-scroll-visible');
}
});
}, { threshold: 0.1 });
document.querySelectorAll('[data-animation-on-scroll]').forEach(el => {
el.classList.add('animate-on-scroll-hidden');
observer.observe(el);
});
});
</script>
</body></html> change the content
Created by: LandingHero
