| name | cinematic-web |
| description | Build cinematic, motion-rich, scroll-driven websites — award-style pages with smooth inertia scrolling, scrollytelling, pinned/parallax sections, WebGL/Three.js heroes, page-transition wipes, animated text, custom cursors, and stacked cards. Use WHENEVER the user wants any of: GSAP, ScrollTrigger, ScrollSmoother, Lenis, Locomotive Scroll, smooth/inertia scrolling, parallax, horizontal scroll sections, scrollytelling, pinned sections, scroll reveals, WebGL or Three.js, shader/image-distortion effects, real-time rendering, page/route transitions, loading or skeleton screens, hover micro-interactions, custom cursors, stacked/sticky cards, DrawSVG, MotionPath, Flip layout transitions, SplitText, typewriter, or stop-motion/stepped animation. Also trigger when the user asks to make a site feel "cinematic", "premium", "interactive", or "like awwwards", even without naming a library. Consult before writing code so the smooth-scroll/ScrollTrigger wiring, plugin registration, performance, and accessibility are correct.
|
Cinematic Web
Build immersive, motion-led sites that feel directed rather than decorated. This skill is the
orchestration layer over the modern creative-dev stack: a smooth-scroll engine (Lenis / ScrollSmoother /
Locomotive) driving GSAP + ScrollTrigger, optionally with Three.js/WebGL for 3D and shaders,
plus the recurring patterns (scrollytelling, stacked cards, horizontal scroll, page transitions,
animated text, custom cursor, skeleton screens).
This SKILL.md is a lean router. It has everything to start and a decision guide; open the matching
reference file for any specific technique. Each reference is deep, self-contained, and full of
copy-paste recipes — read the one you need rather than guessing API details.
Companion: if a separate gsap skill is installed, use it for exhaustive core GSAP/timeline/easing
API depth. This skill focuses on the integrations and patterns that combine GSAP with smooth scroll,
WebGL, and UI motion.
The first decision: pick ONE smooth-scroll engine
Everything hangs off this. Never run two smooth-scroll libraries at once — they fight over the
scroll position and produce jitter. Choose one and wire ScrollTrigger to it.
| Engine | Pick it when | Notes |
|---|
| Lenis (default) | Almost always. Lightweight, framework-agnostic, the current creative-dev standard | Wire lenis.raf into gsap.ticker; call ScrollTrigger.update on its scroll event |
| ScrollSmoother | You're already all-in on GSAP and want data-speed/data-lag parallax for free | GSAP-native, free since v3.13. Requires a #smooth-wrapper > #smooth-content markup shell. Don't also load Lenis |
| Locomotive Scroll | The user explicitly asks for it, or you're matching an existing Locomotive codebase | v5 is built on Lenis; v4 needs a scrollerProxy. Prefer Lenis for new builds |
| None (native) | Reduced-motion users, or content-first/SEO pages where inertia hurts usability | ScrollTrigger works perfectly on native scroll — smooth scroll is optional polish |
Full setup + the exact integration code for each → references/smooth-scroll.md. Get this wiring right
first; most "ScrollTrigger is janky / triggers fire at the wrong place" bugs are a broken smooth-scroll
hookup or a missing ScrollTrigger.refresh().
Install (single-file HTML default)
Default to a self-contained HTML file using CDNs (renders as an artifact, nothing to build). All GSAP
plugins are 100% free since v3.13 — pin 3.13.0+, never a Club/login CDN.
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.13.0/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.13.0/ScrollTrigger.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.13.0/SplitText.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.13.0/DrawSVGPlugin.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.13.0/MotionPathPlugin.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.13.0/Flip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.13.0/ScrollSmoother.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.13.0/TextPlugin.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lenis@1.1.18/dist/lenis.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lenis@1.1.18/dist/lenis.css">
<script>
gsap.registerPlugin(ScrollTrigger, SplitText, DrawSVGPlugin, MotionPathPlugin, Flip);
</script>
Three.js (when needed) uses an ES-module importmap — see references/webgl-three.md.
For production multi-file projects (a real site, not an artifact): npm i gsap lenis three,
import { gsap } from "gsap", import { ScrollTrigger } from "gsap/ScrollTrigger", register once at
the app root, and in React wrap effects in useGSAP() (@gsap/react) for automatic cleanup. The
patterns are identical; only the imports change.
Reference map — read the file that matches the task
| Task | File |
|---|
| Lenis / ScrollSmoother / Locomotive setup + ScrollTrigger integration, parallax via attributes, lag effects, mobile fixes | references/smooth-scroll.md |
| ScrollTrigger patterns: pinning, scrub vs toggle, parallax, scroll reveals, phased/sequenced triggers, horizontal scroll, scrollytelling, stacked cards, progress, snap | references/scroll-effects.md |
| Three.js scene + render loop, scroll-driven 3D & camera, shader/displacement & image-distortion, hover-warp planes, real-time rendering, perf, WebGL↔ScrollTrigger sync, fallback | references/webgl-three.md |
| Animated text (SplitText reveals, typewriter), DrawSVG line-draw, MotionPath follow-a-curve, Flip layout transitions, stop-motion / stepped animation | references/text-svg-motion.md |
| Page/route transition wipes (overlay, View Transitions API, Barba-style, SPA), loading & skeleton screens, custom cursor, hover micro-interactions | references/transitions-ui.md |
| Full standalone copy-paste templates that combine the above (cinematic page shell, scrollytelling section, stacked cards, horizontal gallery, WebGL hero, preloader) | references/recipes.md |
| Ready-to-extend boilerplate HTML (Lenis + GSAP + ScrollTrigger + cursor + preloader + reduced-motion, all wired) | assets/starter.html |
Direction before effects
A pile of effects reads as "AI-generated demo." A cinematic site reads as directed. Before coding:
- Name the one signature moment — the WebGL hero, the scrollytelling act, the horizontal gallery —
and spend your boldness there. Keep everything around it quiet. (See the
frontend-design skill for
palette/type direction if available.)
- Choreograph a load sequence. Premium sites don't pop in — a preloader resolves into a staged
entrance (mask reveal → heading SplitText → hero settles). One orchestrated moment beats ten
scattered ones.
- Map motion to scroll, not to time, for anything tied to reading position. Use
scrub so the
user controls pacing; reserve self-playing eases for fire-on-enter reveals.
- Pick a restrained motion vocabulary — one or two eases (e.g.
power3.out, expo.out), a
consistent reveal distance, a shared duration scale — and reuse it everywhere. Consistency is what
separates "designed" from "busy."
Non-negotiables (the rules that bite)
These apply to every build; the references repeat the technique-specific ones.
- Register each plugin once before use (
gsap.registerPlugin(...)), or its properties are silently
ignored. The most common GSAP bug, full stop.
- One smooth-scroll engine only. Wire ScrollTrigger to it (see
smooth-scroll.md). Never Lenis +
ScrollSmoother together.
- Respect
prefers-reduced-motion. Gate inertia scroll, scrubbed motion, autoplay, and large
transforms behind gsap.matchMedia(). In the reduced branch: disable smooth scroll, show content in
final state, keep essential meaning. This is a quality floor, not an afterthought — every recipe here
includes it.
ScrollTrigger.refresh() after layout settles — fonts/images load, preloader finishes, content
swaps, WebGL canvas sizes. Stale start/end positions are the usual "fires in the wrong place" cause.
Use invalidateOnRefresh: true on size-dependent tweens.
- Clean up in SPAs/React.
useGSAP() or gsap.context() + .revert(); kill ScrollTriggers and
stop the Three.js RAF/dispose geometries on unmount/route change. Leaks cause compounding jank.
- Use
autoAlpha (opacity+visibility) over opacity, and transform shortcuts (x,y,rotation,
scale) over raw CSS transform. Scrubbed tweens use ease:"none".
- Perf budget: animate only
transform and opacity; add will-change sparingly and remove it
after; cap Three.js pixelRatio at Math.min(devicePixelRatio, 2); throttle pointer/scroll work;
gsap.ticker.lagSmoothing(0) when driving Lenis. Remove all markers:true before shipping.
- Match complexity to vision. Don't bolt a WebGL hero, horizontal gallery, custom cursor, and
typewriter onto one page unless the brief calls for it. Cut one accessory before shipping.