<section class="demo">
<article class="demo__card"><span class="demo__num">01 / STRATEGY</span><h3>Define the<br>intent</h3></article>
<article class="demo__card"><span class="demo__num">02 / CRAFT</span><h3>Shape the<br>motion</h3></article>
<article class="demo__card"><span class="demo__num">03 / SYSTEM</span><h3>Scale the<br>language</h3></article>
<article class="demo__card"><span class="demo__num">04 / SHIP</span><h3>Make it<br>real</h3></article>
</section>.demo {
background: #08080a;
color: #f4f4f2;
font-family: "Helvetica Neue", Inter, system-ui, sans-serif;
padding-bottom: 30vh;
}
.demo__card {
position: sticky;
top: 12vh;
height: 62vh;
margin: 0 20px 14vh;
padding: 28px;
display: flex;
flex-direction: column;
justify-content: space-between;
border-radius: 24px;
border: 1px solid rgba(255, 255, 255, 0.08);
transform-origin: center top;
will-change: transform;
}
.demo__card:nth-child(1) { background: linear-gradient(150deg, #1d1d24, #101014); }
.demo__card:nth-child(2) { background: linear-gradient(150deg, #23202c, #121016); }
.demo__card:nth-child(3) { background: linear-gradient(150deg, #1a2430, #0d1116); }
.demo__card:nth-child(4) { background: linear-gradient(150deg, #2a2018, #14100c); }
.demo__num {
font-size: 11px;
letter-spacing: 0.2em;
color: rgba(244, 244, 242, 0.45);
}
.demo__card h3 {
margin: 0;
font-size: clamp(24px, 6vw, 40px);
font-weight: 500;
letter-spacing: -0.03em;
line-height: 1.1;
}gsap.registerPlugin(ScrollTrigger);
const cards = gsap.utils.toArray(".demo__card");
cards.forEach((card, index) => {
// 마지막 카드는 뒤로 밀릴 일이 없으므로 제외합니다.
if (index === cards.length - 1) return;
gsap.to(card, {
scale: 0.9,
opacity: 0.55,
ease: "none",
scrollTrigger: {
trigger: cards[index + 1],
start: "top 85%",
end: "top 12%",
scrub: true,
},
});
});