GradientBall
A ball of the brand's colours in motion: mostly lilac and leaf, with a few accents blooming, drifting as soft gradients over a slowly turning sphere, under film grain.
Playground
import { GradientBall } from "@/components/shared/gradient-ball";
<GradientBall className="size-80" />Sizes
Size it with Tailwind; the ball fills the box's shorter side. The grain stays a CSS pixel at every size, so a small ball reads grainier.
import { GradientBall } from "@/components/shared/gradient-ball";
<GradientBall className="size-16" />
<GradientBall className="size-32" />
<GradientBall className="size-56" />Colours
Mostly the brand: lilac and leaf in broad regions, meeting through pearl the way the hero's washes do. Here and there an accent blooms — the secondary palette's sky over the lilac, butter over the leaf — and drifts on. All four follow their tokens.
lilac
#e4e1fb
--mix-ball-b
leaf
#c8f0b8
--mix-ball-a
sky
#bcdafb
--mix-bloom-1
butter
#f6e795
--mix-bloom-2
States
Moving — on screen
Still — reduced motion
Smooth — grain 0
Field
The same colours laid flat over a whole box, edge to edge: no sphere, no rim, the colours running into each other. wash pales them toward white so words read on it — the hero's left half wears it at 0.1, drifting through the mixes. Drawn at half a CSS pixel; nothing stands in before it draws, so give the box a tint.
import { GradientBall } from "@/components/shared/gradient-ball";
<div className="relative h-64 overflow-hidden rounded-3xl">
<GradientBall shape="field" wash={0.1} grain={0} className="absolute inset-0" />
</div>API reference
| Prop | Type | Default | Description |
|---|---|---|---|
| speed | number | 1 | Scales the motion — the sphere's turn, the gradients' drift. 0 holds it still. |
| grain | number | 1 | The film grain's strength: 0 smooth, 1 the house grain. It moves at 24 frames a second. |
| seed | number | 0 | Another ball: where its regions and accents fall on the sphere. Give neighbours different seeds. |
| drift | boolean | false | Drifting through mixes: a change of mix takes 2.5s (five --duration-very-slow), eased in and out, so a ball cycled through mixes is always moving. Without it a change eases over in --duration-very-slow. |
| shape | "ball" | "field" | "ball" | field: the colours laid flat over the whole box, no sphere and no rim — a surface's wash. Nothing stands in before it draws. |
| wash | number | 0 | How far toward white, 0 (the colours) to 1. A field under words wants a touch; below 0 it goes deeper, past the colours: the hero's is −0.125. |
| cloth | boolean | false | A field hung as fabric, §6's cloth: moved by the wind, stirred by the cursor, its folds lit in colour (a touch deeper and richer turned from the light, never grey). Only a field; still under reduced motion. The hero's wash wears it. |
| label | string | — | Names it for screen readers (role img); left out, it's decorative. |
| className | string | — | Size it here (size-56); the ball fills the shorter side, a field the whole box. |
Guidelines
- A brand moment, one at a time: a hero, an empty state, a moment of waiting. Never as chrome, never repeated down a list.
- On white or porcelain: its colours are light, made for a light page.
- Moves only on screen; still under
prefers-reduced-motion. Without WebGL a still circle of the same colours stands in.