<section class="demo">
<article class="demo__page" id="page">
<p class="demo__kicker" id="kicker">Index</p>
<h1 id="title">Still rooms</h1>
<button type="button" class="demo__next" id="next">Next scene</button>
</article>
<div class="demo__curtain" id="curtain" aria-hidden="true"></div>
</section>.demo {
position: relative;
min-height: 100dvh;
overflow: hidden;
background: #08080a;
color: #f4f4f2;
font-family: "Helvetica Neue", system-ui, sans-serif;
}
.demo__page {
min-height: 100dvh;
display: flex;
flex-direction: column;
justify-content: center;
padding: 40px 28px;
}
.demo__kicker {
margin: 0 0 12px;
font-size: 11px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: #5a5a62;
}
.demo__page h1 {
margin: 0 0 28px;
font-size: clamp(36px, 8vw, 64px);
font-weight: 500;
letter-spacing: -0.045em;
line-height: 1.02;
}
.demo__next {
align-self: flex-start;
border: 1px solid #2a2a32;
background: transparent;
color: #f4f4f2;
border-radius: 999px;
padding: 10px 16px;
font: 12px/1 "Helvetica Neue", system-ui, sans-serif;
letter-spacing: 0.12em;
text-transform: uppercase;
cursor: pointer;
}
.demo__curtain {
position: absolute;
inset: 0;
background: #f4f4f2;
transform: translateY(101%);
pointer-events: none;
}const pages = [
{ kicker: "Index", title: "Still rooms" },
{ kicker: "Studio", title: "Night shift" },
];
let index = 0;
let locked = false;
const curtain = document.querySelector("#curtain");
const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
function apply() {
document.querySelector("#kicker").textContent = pages[index].kicker;
document.querySelector("#title").textContent = pages[index].title;
}
function go() {
if (locked) return;
locked = true;
const next = (index + 1) % pages.length;
if (reduce) {
index = next;
apply();
locked = false;
return;
}
const tl = gsap.timeline({
onComplete: function () { locked = false; },
});
tl.to(curtain, { yPercent: 0, duration: 0.55, ease: "power3.in" })
.add(function () {
index = next;
apply();
})
.to(curtain, { yPercent: -101, duration: 0.6, ease: "power3.out" })
.set(curtain, { yPercent: 101 });
}
gsap.set(curtain, { yPercent: 101 });
document.querySelector("#next").addEventListener("click", go);
gsap.delayedCall(1.1, go);