Oddball, small-batch sparkling soda
Real fruit, cane sugar and a lot of bubbles, brewed in 400-can batches in Oakland. Pick a flavor and watch it move.
A full-bleed drinks hero over the blob-gradient background component: glowing colored blobs rise, sink and merge like wax in a lava lamp under a fine film grain, and the cursor becomes one more blob that joins them. A list of flavors beside the copy recolors the lamp: picking one fades the blobs and the background to its colors and grows or shrinks the number of blobs, while the copy, a soft veil and the primary Arrow Pill follow the site theme. An oversized headline, an intro and an underline link sit on the left. Every lamp setting passes through the lamp prop, and each flavor carries its own colors, blob count and optional background.
A full-bleed hero over the blob-gradient component: colored blobs rise, sink and merge like wax in a lava lamp while a list of flavors beside the copy recolors the lamp and changes how many blobs float, while the copy follows the site theme.
Upgrade to Pro
Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.
Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.
Radix flavor
npx shadcn add "https://ui.beste.co/r/hero264?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/hero264?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/hero264.tsx plus the blob-gradient background and the button23 and button2 buttons it uses.
The installed file exports hero264Demo alongside the block: the exact props behind the preview above. Spread it to get a working hero in one line.
import { Hero264, hero264Demo } from "@/components/beste/block/hero264";
export default function Page() {
return <Hero264 {...hero264Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Hero264 } from "@/components/beste/block/hero264";
export default function Page() {
return (
<Hero264
eyebrow="Oddball, small-batch sparkling soda"
heading="Soda that refuses to sit still."
description="Real fruit, cane sugar and a lot of bubbles, brewed in 400-can batches in Oakland."
buttons={[
{ label: "Order a mixed case", href: "/shop" },
{ label: "Find a shop", href: "/stockists" },
]}
flavors={[
{ name: "Blood orange & yuzu", note: "Bright, bitter, a little wild", colors: ["#ff5a36", "#ff9d2e", "#ffd166"], count: 7 },
{ name: "Pear & elderflower", note: "Soft, cool and barely sweet", colors: ["#d9f99d", "#fde68a", "#a7f3d0"], count: 5 },
]}
lamp={{ goo: 0.65, glow: 0.55, rise: 0.8, grain: 0.2, transition: 1.4 }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
eyebrow | string | – | Small line above the headline |
heading | string | – | Oversized headline, rendered as the page h1 |
description | string | – | Intro under the headline |
buttons | ActionButton[] | [] | The first renders as a primary Arrow Pill, every later one as a Button2 underline link |
flavors | Flavor[] | [] | Flavors to pick from; the first is shown on load, and the list only appears with two or more |
flavorsLabel | string | "Pick a flavor" | Accessible name for the flavor list |
lamp | Omit<BlobGradientProps, "className" | "children" | "colors" | "backgroundColor" | "count"> | – | Forwarded to the BlobGradient component: size, goo, glow, speed, rise, saturation, grain, grain size, grain motion, transition, seed, interactive, cursor size and paused |
className | string | – | Extra classes for the outer <section> |
type ActionButton = {
label: string;
href: string;
};
type Flavor = {
name: string;
note?: string;
colors: string[]; // 1 to 6 blob colors, any CSS color
backgroundColor?: string; // color behind the blobs, the theme background by default
count?: number; // blobs for this flavor, 1 to 10
};colors, backgroundColor and count to BlobGradient: the blobs and the background crossfade over lamp.transition seconds and blobs grow in or shrink away to the new count. A soft radial veil in the theme background sits behind the copy so it stays readable over any flavor.radiogroup; each row shows a small swatch of the flavor's colors, its name and its note.var(--background) and the copy, pill and links use foreground, muted-foreground and primary, so the hero follows the site theme. The flavor colors stay as given. A custom backgroundColor should read with your theme's foreground.interactive on, the cursor becomes one more blob that merges with the others. Touch pointers are ignored.IntersectionObserver and on hidden tabs and respects prefers-reduced-motion: the copy then renders without its rise and flavors swap without fading.max(640px, 100svh - 78px) with the copy and the list centered vertically; below md the list stacks under the buttons.