CulletCollecting cullet
000
CulletGet the kit
GlassHero

Broken glass,melted intocomponents.

Cullet is the glass a studio breaks down to melt into the next piece. This is thirty-two scroll-driven components cut out of this very page, built with GSAP and three.js. Scroll, and copy whichever one you are looking at, CSS included.

Rendered for your local light.
One file each, CSS included. No lock-in.

Scroll to take it apart
disassembly 0% · 80 facets · one uniform · 0 draw calls
06:12one object, one day, four light temperatures

Dawn

Cool from the window, warm from the core. A pinned section with a scrubbed timeline; the key light lerps between two colours.

key #ffd6a8 rim #9db7d5 2 700 K

Noon

Flat daylight. The environment panels go white, the transmission goes near-clear, and the ember almost disappears.

key #fff6e8 rim #efe7db 6 500 K

Dusk

The hour it was made for. Chromatic aberration ramps up and the facets throw colour on the wall.

key #ff9a5e rim #d9755a 2 200 K

Night

Dimmed to a small blue planet. Enough to find the door by.

key #8ea7d4 rim #a9bfdd 9 000 K

Thirty-two components. Twenty-five of them are on this page.

Scroll sideways. Open any card for its source, props and a copy button. The ones marked kit only are patterns every motion site ends up needing (a route curtain, a menu, cursor previews, scrambled text) that this page has no use for. Same deal: one file each, CSS included.

0components, each one a single file with its CSS, readable in a sitting
0libraries the kit needs: gsap and three. Lenis and Framer Motion are optional
0 kbgzipped for this whole page, fonts excluded
0images. Every surface here is CSS, SVG noise or WebGL
plate 1 of 3

Stacked plates scale back as the next one lands.

Each panel is pinned, then shrinks and dims by two percent as its successor slides up. The eye reads depth from three transforms.

plate 2 of 3

Use them for case studies, chapters, or anything with a sequence.

The component takes any children. Backgrounds here are gradients with a noise overlay; swap in images or video.

plate 3 of 3

The last plate stays put so the page can continue.

ScrollTrigger ends exactly on the final plate; there is no dead scroll afterwards.

Cullet is the broken glass a studio keeps to melt into the next piece. Nothing here was designed as a component. Every one was cut out of this page, which was built as a site first and a kit second, then ground down until only the part worth keeping was left. Most motion libraries hand you a tween and leave the choreography to you. The hard part was never the easing. It was deciding what pins, what scrubs, what reveals once, and how a page can take itself apart and go back together without anyone seeing the seams. 

Glow
300wght
0SOFT
9opsz
0WONK

Draw the ease, take the string.

Drag the two handles. The dot on the right runs the curve on a loop, and the outputs update as CSS and as a GSAP CustomEase path. The eases this page uses are presets. Set a Framer Motion spring and fit it: CSS has no springs, so this is the closest bezier.

loop 1.2 s · dashed line is the spring–
cubic-bezier(0.16, 1, 0.3, 1)
CustomEase.create("cullet", "M0,0 C0.16,1 0.3,1 1,1")

Tune the piece, then take the config with you.

Three steps to a page like this one.

Each component is a single file. Install the two libraries it needs, drop the file in, and tune the props.

  1. Every component is written against gsap (with ScrollTrigger) and, for the WebGL ones, three. Nothing else. Lenis for smooth scroll and Framer Motion for the React variants are optional.

    npm i gsap three