KQ-1426 · LOUVER/LIGHT

Louver Light

An architectural louvre wall as a background, drawn in one WebGL2 pass with the content in front: rows of fine slats, cut into blades by thin mullions, each turning rigidly on its long axis as a rolling wave crosses the wall, so a blade's face brightens and glints as it turns toward a soft light above and bands of light travel across, while blades turned edge-on open onto a shadowed recess. The pointer bends the wave around itself, its place on springs.glide and its pull on springs.drift, and a press flips the slats over in a ring that runs out from it, each blade landing its half turn on the recoil spring. It never takes focus; keyboard focus on a control inside bends the wave there and flips a small ring from it.

KQ-1426 · LOUVER/LIGHT

Fernworks Architects

A library lit by its own facade

1,200 cedar louvres turn with the sun

at rest · 40 slats at 20°, dawn light

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/louver-light

Props

children
React.ReactNode
default —
The content in front of the wall: a hero line, a heading, a call to action.
slats
number
default 40
Rows of slats down the wall, 8 to 160: fine louvres or broad blades.
tilt
number
default 20
The angle the slats rest at, in degrees from flat-on (−80 to 80); it decides where the light lands.
light
"dawn" | "noon" | "dusk" | "moon" | string
default "dawn"
The light's colour: a named light, or any CSS colour.
swing
number
default 55
How far the rolling wave turns each slat either side of its rest, in degrees (0 to 90).
speed
number
default 1
How fast the wave rolls, 0 (held) to 3.
wavelength
number
default 420
Distance between bands of light, in px.
angle
number
default 35
The direction the bands travel, in degrees; 0 runs left to right.
segment
number
default 12
Each slat's length between mullions, in slat pitches (2 to 40).
finish
string
default "color-mix(in oklab, var(--background) 84%, var(--foreground))"
The slats' paint, any CSS colour.
glint
number
default 0.6
How bright the glint is where a slat mirrors the light, 0 to 1.
interactive
boolean
default true
The pointer and keyboard focus bend the wave.
pointerStrength
number
default 0.6
How far the pointer bends the wave, 0 to 1.
pulse
boolean
default true
A press on the wall (not on a control) flips the slats over in a ring from it.
intro
boolean
default true
The slats open out of a closed wall the first time it comes into view.
paused
boolean
default false
Hold the wave still; the pointer can still bend it.
seed
number
default 1
Seeds the wave's phase and the slats' small irregularities.
dpr
number
default 2
Cap on the canvas's device pixel ratio, at most 2.
onActiveChange
(active: boolean) => void
default —
Fires when the pointer or keyboard focus starts (true) or stops (false) bending the wave.
className
string
default —
Sizes and shapes the box; it fills its parent by default (h-full w-full).