StealThis .dev

Card Stack Cascade

Stacked cards fan out and rearrange into a grid as you scroll, driven by GSAP ScrollTrigger scrub.

Open in Lab
gsapscrolltriggerperspective
Targets: JS HTML

Code

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  --bg: #070a12;
  --text: #f0f4fb;
  --muted: #8a95a8;
  --accent: #86e8ff;
  --neon-purple: #ae52ff;
}

html { background: var(--bg); color: var(--text); font-family: 'Inter', 'SF Pro Display', system-ui, sans-serif; }
body { overflow-x: hidden; }

.intro {
  min-height: 70vh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 2rem;
}

.eyebrow { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.18em; color: var(--accent); margin-bottom: 1rem; }

h1 {
  font-size: clamp(2.2rem, 6vw, 4rem); font-weight: 700; letter-spacing: -0.03em;
  background: linear-gradient(135deg, #fff, var(--accent), var(--neon-purple));
  background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;
}

.subtitle { font-size: clamp(0.9rem, 2vw, 1.05rem); color: var(--muted); max-width: 460px; margin-top: 0.75rem; line-height: 1.6; }

/* Stack section */
.stack-section { position: relative; min-height: 250vh; }

.perspective-container {
  position: sticky; top: 0; height: 100vh;
  display: flex; align-items: center; justify-content: center;
  perspective: 1200px;
}

.card-stack {
  position: relative;
  width: 380px; height: 460px;
}

/* Cards */
.stack-card {
  position: absolute; inset: 0;
  will-change: transform, opacity;
}

.card-glass {
  width: 100%; height: 100%;
  background: linear-gradient(135deg,
    hsla(var(--hue,200), 30%, 15%, 0.6),
    hsla(var(--hue,200), 20%, 10%, 0.8)
  );
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  border: 1px solid hsla(var(--hue,200), 40%, 40%, 0.2);
  border-radius: 20px;
  padding: 2.5rem;
  display: flex; flex-direction: column; justify-content: center;
  box-shadow: 0 8px 32px rgba(0,0,0,0.3), inset 0 1px 0 hsla(var(--hue,200), 50%, 70%, 0.08);
}

.card-num {
  font-size: 3rem; font-weight: 700; line-height: 1; margin-bottom: 1rem;
  color: hsla(var(--hue,200), 60%, 60%, 0.2);
}

.card-glass h3 {
  font-size: 1.3rem; font-weight: 600; margin-bottom: 0.6rem;
  color: hsl(var(--hue,200) 70% 80%);
}

.card-glass p { font-size: 0.88rem; color: var(--muted); line-height: 1.55; margin-bottom: 1.2rem; }

.card-tags { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.card-tags span {
  padding: 0.18rem 0.55rem; border-radius: 4px;
  font-size: 0.65rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
  background: hsla(var(--hue,200), 40%, 30%, 0.25);
  color: hsl(var(--hue,200) 60% 70%);
}

/* Outro */
.outro {
  min-height: 50vh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center; padding: 2rem;
}

.outro h2 { font-size: clamp(1.8rem, 4vw, 3rem); font-weight: 700; letter-spacing: -0.02em; margin-bottom: 1.5rem; }

.btn-back {
  display: inline-block; padding: 0.7rem 2rem; border-radius: 999px;
  border: 1px solid rgba(134,232,255,0.3); color: var(--accent); text-decoration: none;
  font: 600 0.85rem/1 'Inter', system-ui, sans-serif; transition: all 0.25s ease;
}
.btn-back:hover { background: rgba(134,232,255,0.08); border-color: var(--accent); }

/* Reduced motion */
.reduced-motion .stack-card { opacity: 1 !important; transform: none !important; }

@media (max-width: 640px) {
  .card-stack { width: 300px; height: 400px; }
  .card-glass { padding: 1.8rem; }
}

Card Stack Cascade

Stacked cards fan out and rearrange into a grid as you scroll, driven by GSAP ScrollTrigger scrub.

Source

  • Repository: libs-genclaude
  • Original demo id: 05-card-stack

Notes

Stacked cards fan out and rearrange into a grid as you scroll, driven by GSAP ScrollTrigger scrub.