<section class="demo">
<article class="demo__card" id="card">
<p>032 / Physics</p>
<h2>Pull, then let go</h2>
</article>
</section>.demo {
min-height: 100dvh;
display: grid;
place-items: center;
background: #08080a;
color: #f4f4f2;
font-family: "Helvetica Neue", system-ui, sans-serif;
}
.demo__card {
width: min(260px, 78vw);
height: 300px;
padding: 22px;
display: flex;
flex-direction: column;
justify-content: space-between;
border-radius: 16px;
border: 1px solid rgba(255, 255, 255, 0.08);
background: linear-gradient(160deg, #1c1c24, #101014);
cursor: grab;
user-select: none;
will-change: transform;
}
.demo__card:active { cursor: grabbing; }
.demo__card p {
margin: 0;
font-size: 10px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: #5a5a62;
}
.demo__card h2 {
margin: 0;
font-size: 28px;
font-weight: 500;
letter-spacing: -0.04em;
}const card = document.querySelector("#card");
const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
gsap.from(card, { y: 16, opacity: 0, duration: 0.8, ease: "expo.out" });
if (window.Draggable) {
Draggable.create(card, {
type: "x,y",
edgeResistance: 0.65,
onPress: function () {
gsap.killTweensOf(card);
},
onRelease: function () {
gsap.to(card, {
x: 0,
y: 0,
duration: reduce ? 0.2 : 1.15,
ease: "elastic.out(1, 0.42)",
});
},
});
}