# Introduction > Motion-rich, niche components for shadcn/ui projects. Accessible, customizable, and open source. Source: https://www.cult-ui.com/docs Cult UI is a shadcn/ui registry of animated, niche components: AI prompt inputs, Halo form controls, shader heroes, device mockups, illustrations, and more. Every component is plain React and Tailwind CSS source that you add to your project with the shadcn CLI, then own and edit like the rest of your code. ## How it works Cult UI is not an npm package. It is a [registry](https://ui.shadcn.com/docs/registry) that the shadcn CLI already knows about under the `@cult-ui` namespace. When you run `npx shadcn@latest add @cult-ui/halo-button`, the CLI: 1. Copies `halo-button.tsx` into your `components/ui` folder. 2. Installs the npm packages it needs, such as `motion` and `@base-ui/react`. 3. Adds any shadcn/ui components it builds on, such as `button` or `badge`. There is no Cult UI runtime and nothing to keep in sync. Components use your shadcn theme tokens (`bg-card`, `text-muted-foreground`, `ring-ring`), so they pick up your colors, radius, and dark mode. ## Quick start In a React project that already uses shadcn/ui: ```bash npx shadcn@latest add @cult-ui/halo-button ``` ```tsx import { HaloButton } from "@/components/ui/halo-button" export default function Page() { return Get started } ``` New project, or not using shadcn/ui yet? Start with [Installation](/docs/installation). ## Where to go next

Installation

Set up a project and add your first component

Theming

Which tokens components read and how to restyle them

MCP Server

Let Cursor or Claude Code search and install components

LLMs & Agents

llms.txt, markdown docs, and agent rules

## FAQ ### Do I need shadcn/ui to use Cult UI? You need the shadcn CLI setup, which is a `components.json` file, a `cn` helper, and shadcn theme tokens in your CSS. Running `npx shadcn@latest init` creates all three. You do not need to use any other shadcn/ui components, although some Cult UI components build on them and the CLI adds those for you. ### Which frameworks are supported? Any React framework that shadcn/ui supports, including Next.js, Vite, React Router, Astro, and TanStack Start. A few components import `next/image` or `next/link`. They work best in Next.js and need a small swap elsewhere, which the [Vite guide](/docs/installation/vite) lists. ### Which versions of React and Tailwind CSS do the components target? React 19 and Tailwind CSS v4, matching a fresh `shadcn init`. Most components also run on React 18. Animated components use [Motion](https://motion.dev) and respect `prefers-reduced-motion`. ### Why copy source instead of installing a package? Owning the source lets you change anything, from markup to animation timing, without fighting a package API or waiting for a release. The tradeoff is that updates are manual. Re-run `shadcn add` with `--overwrite` to pull the latest version of a component, then review the diff. ### Can I use Cult UI in commercial projects? Yes. Cult UI is [MIT licensed](https://github.com/nolly-studio/cult-ui/blob/main/LICENSE.md) and free for personal and commercial use, with no attribution required. --- # Changelog > Release notes for Cult UI, covering new shadcn/ui components, API changes, fixes, and registry updates, newest first. Source: https://www.cult-ui.com/docs/changelog ## September 2026 - 58 new components ### Renames The gradient-rim / frosted kit is now named **Halo**. Old `animated-*` doc URLs redirect, and registry install names still resolve via aliases. | Old | New | | --- | --- | | Animated Badge, Button, Card, Dropzone, Field, Input, Notification, Progress, Search, Segmented, Select, Switch, Tabs, Toast, Toggle Group | Halo * | | Animated Composer | Prompt Composer | | Animated Number | Rolling Number | Docs sidebar is regrouped by product job: AI (Inputs + Generative UI), App & Workspace, Form Controls, Feedback & Status, Navigation & Overlays, Onboarding & Flows, Buttons, Cards, Landing Pages, Illustrations, Media & Mockups, Backgrounds & Effects, and Typography. ### New components - [Gateway Endpoint Illustration](/docs/components/gateway-endpoint-illustration) - [Gateway Route Illustration](/docs/components/gateway-route-illustration) - [Gateway SVG Illustration](/docs/components/gateway-svg-illustration) - [Illustration Card Grid](/docs/components/illustration-card-grid) - [Illustration Cursor](/docs/components/illustration-cursor) - [Illustration Comment Bubble](/docs/components/illustration-comment-bubble) - [Illustration Fluid Rendering](/docs/components/illustration-fluid-rendering) - [Illustration Globe Vercel](/docs/components/illustration-globe-vercel) - [Illustration Graph](/docs/components/illustration-graph) - [Tabs Illustration Vercel](/docs/components/tabs-illustration-vercel) - [Circuit Board](/docs/components/circuit-board) - [Fluid AI Workloads](/docs/components/fluid-ai-workloads) - [Security Checkpoint](/docs/components/security-checkpoint) - [Merging Bubbles](/docs/components/merging-bubbles) - [AI Blob Warp](/docs/components/ai-blob-warp) - [Folded Card](/docs/components/folded-card) - [Shadow Card](/docs/components/shadow-card) - [Organic Card](/docs/components/organic-card) - [Organic Card Small](/docs/components/organic-card-small) - [Organic Button](/docs/components/organic-button) - [Fluted Glass](/docs/components/fluted-glass) - [Speech Bubble](/docs/components/speech-bubble) - [Apple iPhone 17 Pro Max](/docs/components/apple-iphone-17-pro) - [Apple Keyboard](/docs/components/apple-keyboard) - [Apple Watch Ultra](/docs/components/apple-watch-ultra) - [Mac Screen](/docs/components/mac-screen) - [Apple Pro Display XDR](/docs/components/apple-pro-display-xdr) - [Marketing Hero Analytics](/docs/components/marketing-hero-analytics) - [Marketing Feature Code](/docs/components/marketing-feature-code) - [Feature Sticky Section](/docs/components/feature-sticky-section) - [Analytics Chart](/docs/components/analytics-chart) - [Kanban Board](/docs/components/kanban-board) - [Agent Suggest Card Stack](/docs/components/agent-suggest-card-stack) - [Collab Avatar](/docs/components/collab-avatar) - [Collab Toolbar](/docs/components/collab-toolbar) - [Halo Dropzone](/docs/components/halo-dropzone) - [Halo Search](/docs/components/halo-search) - [Globe (COBE)](/docs/components/globe) - [File Icons](/docs/components/file-icons) - [Halo Button](/docs/components/halo-button) - [Copy Button](/docs/components/copy-button) - [Halo Card](/docs/components/halo-card) - [Border Beam Card](/docs/components/border-beam-card) - [Halo Tabs](/docs/components/halo-tabs) - [Halo Segmented](/docs/components/halo-segmented) - [Halo Toggle Group](/docs/components/halo-toggle-group) - [Halo Notification](/docs/components/halo-notification) - [Halo Toast](/docs/components/halo-toast) - [Halo Switch](/docs/components/halo-switch) - [Halo Input](/docs/components/halo-input) - [Halo Field](/docs/components/halo-field) - [Halo Progress](/docs/components/halo-progress) - [Border Beam Input](/docs/components/border-beam-input) - [Halo Badge](/docs/components/halo-badge) - [Halo Select](/docs/components/halo-select) - [Prompt Composer](/docs/components/prompt-composer) - [Wizard Expandable](/docs/components/wizard-expandable) ### Updated components - [Border Beam Button](/docs/components/border-beam-button) ## May 2026 - Metal, dither, and component refreshes ### New components - [Metal Button](/docs/components/metal-button) - Animated liquid metal ring around the shadcn Button with text and icon variants powered by MetalFx. - [Dither Image](/docs/components/dither-image) - Compound figure built on next/image with CSS-only Bayer dither via dither-plugin — full-frame dither, partial masked reveals, and typed props for every plugin CSS variable. ### Updated components - [Loading Carousel](/docs/components/loading-carousel) - [Hover Video Player](/docs/components/hover-video-player) - [Expandable Screen](/docs/components/expandable-screen) - [Code Block](/docs/components/code-block) - [Direction Aware Tabs](/docs/components/direction-aware-tabs) ## March 2026 - New components and major refreshes ### New components - [Border Beam Button](/docs/components/border-beam-button) - Animated border beam around the shadcn Button with text and icon variants. - [Cutout Card](/docs/components/cutout-card) - Image card with cutout corner accents, hover motion, inset labels, pins, and reveal-on-hover actions. - [Grid Beam](/docs/components/grid-beam) - Animated canvas beams on a grid with palette presets, optional SVG dividers, and a headless `useGridBeam` hook. - [Cosmic Button](/docs/components/cosmic-button) - New animated button style with registry and demo support. - [Gradient Button Group](/docs/components/gradient-button-group) - New premium layered button group with animated active state and gradient ring accents. - [Onboarding](/docs/components/onboarding) - New guided onboarding flow component with complete docs and examples. - [Terminal Animation](/docs/components/terminal-animation) - New composable terminal animation primitives with typed command playback and tabbed scenarios. - [Feature Poll](/docs/components/feature-poll) - Poll / feature-vote component with single or multiple selection, optional results, and keyboard navigation. - [Feature Voting](/docs/components/feature-voting) - List of features with up-vote support, optional sorting by vote count, and controlled or uncontrolled state. - [Hero Dithering](/docs/components/hero-dithering) - Split-layout hero section with responsive dithering shader visuals, CTA content, and tech stack badges. - [Hero Color Panels](/docs/components/hero-color-panels) - Split-layout hero section with responsive ColorPanels shader visuals, CTA content, and tech stack badges. - [Hero Heatmap](/docs/components/hero-heatmap) - Split-layout hero section with responsive Heatmap shader visuals, CTA content, and tech stack badges. - [Hero Liquid Metal](/docs/components/hero-liquid-metal) - Split-layout hero section with responsive LiquidMetal shader visuals, CTA content, and tech stack badges. - [Hero Static Radial Gradient](/docs/components/hero-static-radial-gradient) - Split-layout hero section with responsive StaticRadialGradient shader visuals, CTA content, and tech stack badges. ### Updated components - [Dynamic Island](/docs/components/dynamic-island) - [Texture Button](/docs/components/texture-button) - [Shift Card](/docs/components/shift-card) - [Morph Surface](/docs/components/morph-surface) - [Intro Disclosure](/docs/components/intro-disclosure) - [Choice Poll](/docs/components/choice-poll) - [Shader Lens Blur](/docs/components/shader-lens-blur) ### Recent components - [Toolbar Expandable](/docs/components/toolbar-expandable) - [Vote Tally](/docs/components/vote-tally) - [Poll Widget](/docs/components/poll-widget) - [Pixel Heading (Char)](/docs/components/pixel-heading-character) - [Pixel Heading (Word)](/docs/components/pixel-heading-word) - [Pixel Paragraph](/docs/components/pixel-paragraph-words) - [Pixel Paragraph Inverse](/docs/components/pixel-paragraph-words-inverse) - [Edge Blur](/docs/components/edge-blur) - Stacked backdrop-blur layers with a linear gradient mask for a soft fade at the top or bottom of the viewport. - [SVG Shapes](/docs/components/svg-shapes) - Wide viewBox SVG panels — polygons, architectural forms, sacred geometry, and Platonic wire projections styled with currentColor. - [SVG Shapes Animated](/docs/components/svg-shapes-animated) - Wide viewBox SVG shapes with scroll-triggered stroke drawing via Motion, plus extra primitives beyond the static set. - [SVG Bands](/docs/components/svg-bands) - Wide 2400-grid SVG section trims — battlements, zigzags, steep hero bands, wavy footers, and dual-notch frames for landing pages. ## May 2024 - Introducing Cult Templates --- # Installation > Install Cult UI components with the shadcn CLI in Next.js, Vite, or any React project using Tailwind CSS and shadcn/ui. Source: https://www.cult-ui.com/docs/installation Cult UI components install with the shadcn CLI from the `@cult-ui` registry. If your project already runs shadcn/ui, skip to [step 2](#add-a-component). ### Set up shadcn/ui Cult UI needs what `shadcn init` creates: a `components.json`, the `cn` helper in `lib/utils.ts`, an `@/` import alias, and theme tokens in your global CSS. ```bash npx shadcn@latest init ``` Starting from scratch? `init` can scaffold the project too. Pass `-t` with `next`, `vite`, `start`, `react-router`, or `astro`, or open a framework guide:

Next.js

Vite

Without the CLI

### Add a component Use the `@cult-ui/` prefix with any component name from these docs: ```bash npx shadcn@latest add @cult-ui/halo-button ``` The `@cult-ui` namespace is listed in the shadcn registry directory, so this works without editing `components.json`. The CLI writes the component to `components/ui/halo-button.tsx`, installs its npm dependencies, and adds any shadcn/ui components it builds on. Add several at once: ```bash npx shadcn@latest add @cult-ui/halo-card @cult-ui/halo-input @cult-ui/halo-switch ``` ### Use it Import from the path the CLI printed: ```tsx title="app/page.tsx" import { HaloButton } from "@/components/ui/halo-button" export default function Page() { return Get started } ``` Every component page shows its props, examples, and the source you now own. ## Find components from the terminal Search the registry and preview a component before adding it: ```bash npx shadcn@latest search @cult-ui --query card npx shadcn@latest view @cult-ui/prompt-composer ``` To let an AI agent do this for you, set up the [MCP Server](/docs/mcp-server). ## Pin the registry in components.json You only need this if you use a shadcn CLI older than 3.0, run in an environment that cannot reach the shadcn registry directory, or want the registry URL to be explicit for your team: ```json title="components.json" { "registries": { "@cult-ui": "https://www.cult-ui.com/r/{name}.json" } } ``` You can also add a single component by URL with any CLI version: ```bash npx shadcn@latest add https://www.cult-ui.com/r/halo-button.json ``` ## Update a component Components are your code, so updates are opt-in. Re-add a component with `--overwrite` to replace it with the latest version, then review the diff for any local changes you want to keep: ```bash npx shadcn@latest add @cult-ui/halo-button --overwrite ``` ## Troubleshooting ### The CLI says the @cult-ui registry is unknown Run the latest CLI with `npx shadcn@latest`, not a globally installed or pinned older version. If it still fails, add the `registries` entry shown above to `components.json`. ### Cannot find module @/lib/utils The project has not been initialized with shadcn/ui. Run `npx shadcn@latest init`, or follow the [manual setup](/docs/installation/manual) to add the `cn` helper and `@/` alias yourself. ### The component renders but looks unstyled or has the wrong colors Components read shadcn theme tokens such as `--card`, `--border`, and `--muted-foreground`. Check that your global CSS defines them for both `:root` and `.dark`, and that Tailwind scans the `components` folder. See [Theming](/docs/theming). ### Cannot resolve next/image or next/link outside Next.js A few components use Next.js image and link components. Replace them with `` and `` or your router's link component. The [Vite guide](/docs/installation/vite#nextjs-specific-components) lists which components are affected. --- # Manual Installation > Set up Cult UI without the shadcn CLI by installing the dependencies, cn utility, and Tailwind CSS config yourself. Source: https://www.cult-ui.com/docs/installation/manual Use this when you cannot run the shadcn CLI, or want to see exactly what a component adds before it lands in your project. Your project needs the same four things `shadcn init` would set up, and then each component is a file you copy. ## One-time setup ### Tailwind CSS v4 Follow the [Tailwind CSS installation guide](https://tailwindcss.com/docs/installation) for your framework. Components use Tailwind v4 utilities and arbitrary values, and a few use enter and exit classes such as `animate-in` from `tw-animate-css`: ```bash npm install tw-animate-css ``` ```css title="globals.css" @import "tailwindcss"; @import "tw-animate-css"; @custom-variant dark (&:is(.dark *)); ``` ### Theme tokens Components read the standard shadcn tokens: `--background`, `--foreground`, `--card`, `--muted`, `--muted-foreground`, `--border`, `--input`, `--ring`, `--accent`, `--destructive`, `--chart-1` to `--chart-5`, and `--radius`. Copy a complete token set for `:root` and `.dark` from the [shadcn manual installation guide](https://ui.shadcn.com/docs/installation/manual) or the [Cult UI themes](/themes), and map them in `@theme inline`. [Theming](/docs/theming) explains what each token controls. ### The cn helper ```bash npm install clsx tailwind-merge ``` ```ts title="lib/utils.ts" import { clsx, type ClassValue } from "clsx" import { twMerge } from "tailwind-merge" export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) } ``` ### The @/ import alias Components import from `@/lib/utils` and `@/components/ui/*`. Point `@/*` at your source root in `tsconfig.json`, and in your bundler config if it does not read `tsconfig` paths: ```json title="tsconfig.json" { "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["./src/*"] } } } ``` Use `["./*"]` instead if you do not have a `src` folder. ## Add a component Every component page has a **Manual** tab under Installation with its source. Adding a component by hand takes three steps: 1. **Install its npm dependencies.** Most animated components need `motion`. The Halo kit and newer form controls also use `@base-ui/react`. 2. **Add any shadcn/ui or Cult UI components it builds on**, such as `button` or `badge`. 3. **Copy the source** into `components/ui/.tsx` and fix the import paths if your alias differs. The component's registry file is the complete list for steps 1 and 2. It shows `dependencies` (npm packages), `registryDependencies` (components it builds on), and the full source: ```txt https://www.cult-ui.com/r/halo-select.json ``` --- # Next.js > Set up a Next.js App Router project with shadcn/ui and Tailwind CSS, then add Cult UI components with the shadcn CLI. Source: https://www.cult-ui.com/docs/installation/next Next.js is the best-supported framework for Cult UI. Every component works in the App Router, including the ones that use `next/image` and `next/link`. ### Create a project with shadcn/ui This scaffolds a Next.js app with Tailwind CSS v4, the `@/` alias, `components.json`, and theme tokens: ```bash npx shadcn@latest init -t next ``` When it asks for a component library, any choice works. Cult UI components that build on shadcn/ui components use the version you pick. Already have a Next.js app? Run `npx shadcn@latest init` inside it. The [shadcn Next.js guide](https://ui.shadcn.com/docs/installation/next) covers the prompts in detail. ### Add a Cult UI component ```bash npx shadcn@latest add @cult-ui/prompt-composer ``` ### Use it from any page Cult UI components that need the browser already start with `"use client"`, so you can import them directly into Server Components: ```tsx title="app/page.tsx" import { PromptComposer } from "@/components/ui/prompt-composer" export default function Page() { return (
) } ``` ## Next.js notes ### Dark mode Components style dark mode through the `.dark` class that shadcn uses. Add [next-themes](https://ui.shadcn.com/docs/dark-mode/next) with `attribute="class"` to toggle it. Globe, Gradient Button Group, and Shader Lens Blur also read the active theme from `next-themes`, so they need its `ThemeProvider` in your root layout. ### Remote images Components that render `next/image`, such as Cutout Card, Dither Image, and Minimal Card, follow the usual Next.js rule for remote images. Add the image host to `images.remotePatterns` in `next.config.ts`, or use local files from `public/`. ### Fonts Components inherit your font tokens, so `next/font` works as usual. The Pixel Heading and Pixel Paragraph components use the Geist pixel fonts from the `geist` package. Their pages show the layout and `@theme` setup. ## Next steps - Browse components in the sidebar and copy the install command from any page. - Adjust colors and radius in [Theming](/docs/theming). - Let your editor's agent install components through the [MCP Server](/docs/mcp-server). --- # Vite > Set up a Vite React project with shadcn/ui, Tailwind CSS, and path aliases, then add Cult UI components with the shadcn CLI. Source: https://www.cult-ui.com/docs/installation/vite Most Cult UI components run in a Vite React app without changes. A handful import Next.js modules and need a one-line swap, listed [below](#nextjs-specific-components). ### Set up Vite with shadcn/ui This scaffolds a Vite, React, and TypeScript app with Tailwind CSS v4, the `@/` alias, `components.json`, and theme tokens: ```bash npx shadcn@latest init -t vite ``` Adding Cult UI to an existing Vite app? Follow the [shadcn Vite guide](https://ui.shadcn.com/docs/installation/vite) to add Tailwind CSS and the alias, then run `npx shadcn@latest init`. ### Add a Cult UI component ```bash npx shadcn@latest add @cult-ui/halo-segmented ``` ### Use it ```tsx title="src/App.tsx" import { HaloSegmented } from "@/components/ui/halo-segmented" export default function App() { return ( ) } ``` The `"use client"` line at the top of some components is a Next.js directive. Vite ignores it, so leave it in place. ## Next.js-specific components These components import `next/image` or `next/link`. After adding one, replace `Image` from `next/image` with a plain `` (drop the `fill`, `priority`, and `sizes` props) and `Link` from `next/link` with `
` or your router's link: - Apple Pro Display XDR - Cutout Card - Dither Image - Feature Carousel - Feature Sticky Section - Folded Card - Hover Video Player - Intro Disclosure - Kanban Board - Loading Carousel - Minimal Card - Organic Card - Organic Card Small - Text Gif Globe, Gradient Button Group, and Shader Lens Blur read the active theme with `useTheme` from `next-themes`. The package works in Vite too. Wrap your app in its `ThemeProvider` with `attribute="class"`, or replace `useTheme` with your own theme state. ## Next steps - Browse components in the sidebar and copy the install command from any page. - Adjust colors and radius in [Theming](/docs/theming). --- # LLMs & Agents > Give AI coding agents up-to-date Cult UI docs with llms.txt, markdown pages, the shadcn MCP server, and copy-paste agent rules. Source: https://www.cult-ui.com/docs/llms Cult UI publishes its docs in formats that AI coding agents can read directly. Point your agent at one of the sources below so it installs real components instead of guessing at APIs. ## Machine-readable docs | Resource | URL | Use it for | | --- | --- | --- | | `llms.txt` | [`/llms.txt`](https://www.cult-ui.com/llms.txt) | Index of every docs page and component, with install instructions | | `llms-full.txt` | [`/llms-full.txt`](https://www.cult-ui.com/llms-full.txt) | Every docs page, including component source, in one file | | Markdown pages | Append `.md` to any docs URL, e.g. [`/docs/components/halo-button.md`](https://www.cult-ui.com/docs/components/halo-button.md) | One component's docs, demo, and source | | Registry | [`/r/registry.json`](https://www.cult-ui.com/r/registry.json) and `/r/{name}.json` | Installing components with the shadcn CLI | Every docs page also has a **Copy page** button that copies its markdown, plus shortcuts to open the page in ChatGPT, Claude, or v0. ## Install components from an agent Any agent with terminal access can add components by name. The `@cult-ui` namespace is built into the shadcn CLI, so no config is needed: ```bash npx shadcn@latest add @cult-ui/halo-button ``` To let agents browse and search the registry with natural language, set up the [MCP Server](/docs/mcp-server). ## Agent rules Paste this into `AGENTS.md`, `CLAUDE.md`, or a `.cursor/rules` file so your agent knows how to use Cult UI: ```md title="AGENTS.md" ## Cult UI - Cult UI components are shadcn/ui registry items. Install them with `npx shadcn@latest add @cult-ui/`; never recreate them by hand. - Find component names and docs in https://www.cult-ui.com/llms.txt. Read a component's docs at https://www.cult-ui.com/docs/components/.md before using it. - Installed source lives in `components/ui/`. Edit it there; it is owned code, not a dependency. - Components use Tailwind CSS v4 and shadcn theme tokens (`bg-background`, `text-foreground`, `ring-ring`). Style with tokens, not hardcoded colors. - Animated components use `motion`. Respect `prefers-reduced-motion`. ``` --- # MCP Server > Connect the shadcn MCP server to Cursor, Claude Code, or VS Code so AI agents can search and install Cult UI components. Source: https://www.cult-ui.com/docs/mcp-server The [shadcn MCP server](https://ui.shadcn.com/docs/mcp) lets your editor's AI agent search the Cult UI registry, read component examples, and install components into your project. You ask in plain language, such as "add a prompt input from cult-ui to the chat page", and the agent runs the right `shadcn add` command. ### List Cult UI in components.json The MCP server only searches the registries listed in your project's `components.json`. The CLI adds Cult UI there the first time you run `npx shadcn@latest add @cult-ui/`. If you have not added a component yet, add the entry yourself: ```json title="components.json" { "registries": { "@cult-ui": "https://www.cult-ui.com/r/{name}.json" } } ``` The default `@shadcn` registry is always available and does not need an entry. ### Connect your editor Run the init command for your client from the project root: ### Cursor ```bash npx shadcn@latest mcp init --client cursor ``` This writes `.cursor/mcp.json`. Open **Cursor Settings**, then **MCP**, and enable the shadcn server. A green dot means it is connected. ### Claude Code ```bash npx shadcn@latest mcp init --client claude ``` This writes `.mcp.json`. Restart Claude Code and run `/mcp`. The shadcn server should show as connected. ### VS Code ```bash npx shadcn@latest mcp init --client vscode ``` This writes `.vscode/mcp.json`. Open the file and click **Start** next to the shadcn server, then use GitHub Copilot in agent mode. To configure it by hand, add this server to your client's MCP config file: ```json { "mcpServers": { "shadcn": { "command": "npx", "args": ["shadcn@latest", "mcp"] } } } ``` ### Ask for components Mention Cult UI by name so the agent searches the right registry: - Show me the form controls in the cult-ui registry - Add the Halo Select and Halo Switch from cult-ui to the settings page - Build a pricing section using Halo Card and Border Beam Button from cult-ui - Replace the chat input with Prompt Composer from cult-ui ## Give the agent more context The MCP server returns component source and examples, which is enough for most installs. For larger tasks, also point the agent at the docs written for LLMs, and add the Cult UI rules to your `AGENTS.md`. Both are on the [LLMs & Agents](/docs/llms) page. ## Troubleshooting ### The agent only finds shadcn components, not Cult UI Check that `components.json` has the `@cult-ui` entry above and that you mentioned "cult-ui" in the prompt. Restart the MCP server after changing `components.json`. ### The client shows "No tools or prompts" Clear the npx cache with `npx clear-npx-cache`, then disable and re-enable the server. In Cursor, check the logs under **View**, then **Output**, and pick `MCP: project-*` from the dropdown. ### Installs fail or write files to the wrong folder The MCP server uses the same CLI and `components.json` as a manual install. Run `npx shadcn@latest add @cult-ui/halo-button` in the terminal to see the full error, and check the `aliases` in `components.json`. --- # Theming > Theme Cult UI components with shadcn/ui CSS variables and Tailwind CSS v4 tokens, including dark mode and custom brand colors. Source: https://www.cult-ui.com/docs/theming Cult UI components use the same CSS variables as shadcn/ui, so the theme you already have applies to them. Change a token in your global CSS and every component that reads it updates, in light and dark mode. ## The tokens components read A fresh `shadcn init` defines all of these. If you write your own theme, these are the ones that change how Cult UI looks: | Token | What it controls in Cult UI | | --- | --- | | `--card` | Surfaces of cards, Halo controls, and the frosted fills mixed from it | | `--border`, `--input` | Hairline borders, input outlines, and control tracks | | `--muted`, `--muted-foreground` | Secondary surfaces, placeholders, captions, and icons | | `--foreground`, `--background` | Body text and page-level backgrounds | | `--ring` | Focus rings on every interactive component | | `--accent`, `--destructive` | Hover states and error states | | `--chart-1` to `--chart-5` | Globe marker and arc colors | | `--radius` | Corner radius for components that follow your theme's rounding | ## Change your theme Edit the values in your global CSS. shadcn uses OKLCH colors with Tailwind CSS v4: ```css title="app/globals.css" :root { --card: oklch(1 0 0); --border: oklch(0.92 0 0); --ring: oklch(0.55 0.2 260); --radius: 0.75rem; } .dark { --card: oklch(0.2 0 0); --border: oklch(1 0 0 / 10%); --ring: oklch(0.65 0.18 260); } ``` For a complete palette, copy one of the [Cult UI themes](/themes) or generate one with the [shadcn theme editor](https://ui.shadcn.com/themes). ## Dark mode Components switch to their dark styles when an ancestor has the `.dark` class, which matches shadcn's `@custom-variant dark (&:is(.dark *))`. Use [next-themes](https://ui.shadcn.com/docs/dark-mode) or any toggle that sets that class. Globe, Gradient Button Group, and Shader Lens Blur also read the theme from `next-themes` to pick their canvas colors. ## Style one instance Every component accepts `className`, merged last with `cn`, so your classes win over the defaults: ```tsx ``` Some components expose their own CSS variables for colors that tokens do not cover. Set them through `className` or `style`: | Component | Variables | | --- | --- | | Organic Button | `--organic-surface`, `--organic-fg`, `--organic-duration` | | Illustration Globe Vercel | `--globe-bg`, `--globe-dot`, `--globe-wire`, `--globe-icon`, `--globe-error` | | Tabs Illustration Vercel | `--ga-bg`, `--ga-fg`, `--ga-surface`, `--ga-border`, and related `--ga-*` values | ```tsx Get started ``` ## Brand gradients The animated rims on the Halo kit and Prompt Composer use fixed multicolor gradients so they look the same in any theme. To match your brand, edit the `linear-gradient(...)` values in the component file. The file lives in your project, so the change is yours to keep. Border Beam components get their colors from the `border-beam` package, so change them with the `colorVariant` and `theme` props. ## Add a token To add a color that your own components can share, define it for both modes and expose it to Tailwind with `@theme inline`: ```css title="app/globals.css" :root { --warning: oklch(0.84 0.16 84); --warning-foreground: oklch(0.28 0.07 46); } .dark { --warning: oklch(0.41 0.11 46); --warning-foreground: oklch(0.99 0.02 95); } @theme inline { --color-warning: var(--warning); --color-warning-foreground: var(--warning-foreground); } ``` You can then use `bg-warning` and `text-warning-foreground` anywhere. --- # Agent Suggest Card Stack > Stacked AI agent suggestion cards for React and shadcn/ui, with progress bars, success and error states, and a commit button. Source: https://www.cult-ui.com/docs/components/agent-suggest-card-stack ## Example ```tsx title="agent-suggest-card-stack-demo.tsx" "use client" import { AgentSuggestCardStack } from "@/components/ui/agent-suggest-card-stack" import type { SuggestionItem } from "@/components/ui/agent-suggest-card-stack" const sampleSuggestions: SuggestionItem[] = [ { id: "1", title: "Update auth config", progress: 100, status: "success", }, { id: "2", title: "Fix type errors", progress: 65, status: "mixed", mixedProgress: { success: 2, error: 1 }, }, { id: "3", title: "Add tests", progress: 0, status: "error", }, ] function AgentSuggestCardStackDemo() { return (
) } export default AgentSuggestCardStackDemo ``` Agent Suggest Card Stack is an SVG illustration component for React and shadcn/ui. Use it on landing pages or product tours to illustrate an AI code review or agent workflow. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/agent-suggest-card-stack ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/agent-suggest-card-stack.json **Update the import paths to match your project setup.** --- # AI Blob Warp > Animated AI assistant avatar for React and shadcn/ui, a circle filled with a Paper Design Warp shader that pauses for reduced motion. Source: https://www.cult-ui.com/docs/components/ai-blob-warp ## Example ```tsx title="ai-blob-warp-demo.tsx" "use client" import type { ReactNode } from "react" import { AiBlobWarpAvatar } from "@/components/ui/ai-blob-warp" function SampleCard({ label, description, children, }: { label: string description: string children: ReactNode }) { return (
{children}

{label}

{description}

) } export default function AiBlobWarpDemo() { return (

AI blob warp

Circular avatar with Paper's{" "} Warp shader. Size via{" "} className, tuning via{" "} warpProps.

) } ``` AI Blob Warp is a React avatar component for shadcn/ui built on @paper-design/shaders-react. Use it as the avatar for an AI assistant in chat interfaces or voice agents, and the shader pauses off-screen or when reduced motion is preferred. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/ai-blob-warp ``` ### Manual **Install the required dependencies:** ```bash npm install @paper-design/shaders-react motion ``` **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/ai-blob-warp.json **Update the import paths to match your project setup.** --- # AI Instructions > Composable React components for shadcn/ui to search, toggle, and create custom AI instructions from a popover command list. Source: https://www.cult-ui.com/docs/components/ai-instructions ## Example ```tsx title="ai-instructions-demo.tsx" "use client" import { useState } from "react" import { Instruction, Instructions, InstructionsContent, InstructionsCreateDialog, InstructionsCreateTrigger, InstructionsEmpty, InstructionsFooter, InstructionsGroup, InstructionsItem, InstructionsList, InstructionsSearch, InstructionsTrigger, } from "../ui/ai-instructions" const SAMPLE_INSTRUCTIONS: Instruction[] = [ { id: "concise", title: "Be Concise", description: "Keep responses short and to the point", content: "Provide brief, focused responses. Avoid unnecessary elaboration unless specifically requested. Get to the point quickly.", }, { id: "code-examples", title: "Include Code Examples", description: "Always include relevant code snippets", content: "When explaining technical concepts, always include working code examples that demonstrate the concept. Use appropriate syntax highlighting.", }, { id: "explain-reasoning", title: "Explain Your Reasoning", description: "Walk through your thought process step by step", content: "Before providing a solution, explain the reasoning behind your approach. Break down complex problems into smaller steps.", }, { id: "typescript", title: "Prefer TypeScript", description: "Use TypeScript over JavaScript when possible", content: "Write all code examples in TypeScript with proper type annotations. Include interfaces and type definitions.", }, { id: "accessibility", title: "Consider Accessibility", description: "Ensure solutions are accessible to all users", content: "Include ARIA attributes, semantic HTML, keyboard navigation support, and screen reader considerations in all UI-related code.", }, ] export default function AiInstructionsDemo() { const [activeInstructions, setActiveInstructions] = useState([ "concise", ]) const [instructions, setInstructions] = useState(SAMPLE_INSTRUCTIONS) return (

Configure AI behavior with custom instructions. Click the button below to manage your active instructions.

{instructions.map((instruction) => ( ))}
{activeInstructions.length > 0 && (

Active ({activeInstructions.length}):

{activeInstructions.map((id) => { const instruction = instructions.find((i) => i.id === id) return instruction ? ( {instruction.title} ) : null })}
)}
) } ``` AI Instructions is a set of composable React components for shadcn/ui built on Popover, Command, and Dialog. Use it in AI chat inputs or agent settings to manage system prompts and rules. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/ai-instructions ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/ai-instructions.json **Update the import paths to match your project setup.** ## Usage Use `Instructions` with `instructions`, `onInstructionsChange`, `value`, and `onValueChange`. Compose `InstructionsTrigger`, `InstructionsContent` (with `InstructionsSearch`, `InstructionsList`, `InstructionsEmpty`, `InstructionsGroup`, `InstructionsItem`), `InstructionsFooter`, `InstructionsCreateTrigger`, and `InstructionsCreateDialog` for the full experience. ### Basic example ```tsx import { useState } from "react"; import { Instruction, Instructions, InstructionsTrigger, InstructionsContent, InstructionsSearch, InstructionsList, InstructionsEmpty, InstructionsGroup, InstructionsItem, InstructionsFooter, InstructionsCreateTrigger, InstructionsCreateDialog, } from "@/registry/default/ui/ai-instructions"; const instructions: Instruction[] = [ { id: "concise", title: "Be Concise", description: "Keep responses short and to the point", content: "Provide brief, focused responses. Get to the point quickly.", }, ]; export default function Example() { const [activeIds, setActiveIds] = useState(["concise"]); const [instructionsState, setInstructionsState] = useState(instructions); return ( {instructionsState.map((instruction) => ( ))} ); } ``` ## Features - **Toggle active instructions**: Control which instructions are active via `value` and `onValueChange` - **Search**: `InstructionsSearch` filters the list - **Custom instructions**: Add custom instructions via `onInstructionsChange`, `InstructionsCreateTrigger`, and `InstructionsCreateDialog` - **Hover preview**: Optional hover card for full instruction content (when using `InstructionsItem` with content) - **Compound API**: Instructions, InstructionsTrigger, InstructionsContent, InstructionsSearch, InstructionsList, InstructionsEmpty, InstructionsGroup, InstructionsItem, InstructionsFooter, InstructionsCreateTrigger, InstructionsCreateDialog --- # Analytics Chart > Vercel-style SVG line chart for React and shadcn/ui with a gradient stroke and floating tooltip cards for analytics dashboards. Source: https://www.cult-ui.com/docs/components/analytics-chart ## Example ```tsx title="analytics-chart-demo.tsx" "use client" import { useState } from "react" import { AnalyticsLineChart, DEFAULT_DATA, DEFAULT_GRADIENT, EASE_OUT, type AnalyticsDataPoint, type AnalyticsGradientStop, } from "@/components/ui/analytics-chart" const ANALYTICS_DEMO_SETS = { ecommerce: { title: "Clicks", sub: "Conversion analytics", data: DEFAULT_DATA, valueLabel: "clicks", }, signups: { title: "Signups", sub: "Organic acquisition", data: [ { date: "2024-01-07", label: "organic", value: 340 }, { date: "2024-01-14", label: "organic", value: 520 }, { date: "2024-01-21", label: "organic", value: 480 }, { date: "2024-01-28", label: "organic", value: 710 }, { date: "2024-02-04", label: "organic", value: 890 }, { date: "2024-02-11", label: "organic", value: 1250 }, ], valueLabel: "signups", }, revenue: { title: "Revenue", sub: "SaaS MRR growth", data: [ { date: "2023-07-01", label: "saas-mrr", value: 14_200 }, { date: "2023-08-01", label: "saas-mrr", value: 16_800 }, { date: "2023-09-01", label: "saas-mrr", value: 15_900 }, { date: "2023-10-01", label: "saas-mrr", value: 21_300 }, { date: "2023-11-01", label: "saas-mrr", value: 24_700 }, { date: "2023-12-01", label: "saas-mrr", value: 28_100 }, { date: "2024-01-01", label: "saas-mrr", value: 31_500 }, { date: "2024-02-01", label: "saas-mrr", value: 35_800 }, ], valueLabel: "USD", gradient: [ { offset: "0%", color: "#c084fc" }, { offset: "50%", color: "#818cf8" }, { offset: "100%", color: "#6366f1" }, ], }, } as const satisfies Record< string, { title: string sub: string data: AnalyticsDataPoint[] valueLabel: string gradient?: AnalyticsGradientStop[] } > type AnalyticsDemoKey = keyof typeof ANALYTICS_DEMO_SETS function AnalyticsChartDemo() { const [tab, setTab] = useState("ecommerce") const [epoch, setEpoch] = useState(0) const demo = ANALYTICS_DEMO_SETS[tab] function pick(k: AnalyticsDemoKey) { setTab(k) setEpoch((e) => e + 1) } return (
{/* Tabs */}
{( Object.entries(ANALYTICS_DEMO_SETS) as [ AnalyticsDemoKey, (typeof ANALYTICS_DEMO_SETS)[AnalyticsDemoKey], ][] ).map(([k, v]) => { const on = tab === k return ( ) })}
{/* Card */}

{demo.title}

{demo.sub}

{demo.data.length} points

Hover points for details

{/* Props */}

Component API

{[ ["data", "chart data points"], ["gradientStops", "line color stops"], ["dotColors", "per-dot overrides"], ["gridLines", "grid line count"], ["pinnedIndices", "pinned tooltips"], ["valueLabel", "unit label"], ].map(([p, d]) => ( {p} {" — "} {d} ))}
) } export default AnalyticsChartDemo ``` Analytics Chart is an SVG line chart component for React and shadcn/ui. Use it for analytics dashboards, usage reports, or traffic overviews where a time series metric needs per-point details. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/analytics-chart ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/analytics-chart.json **Update the import paths to match your project setup.** --- # Apple iPhone 17 Pro Max > iPhone 17 Pro device mockup for React and shadcn/ui with Dynamic Island, status bar, and four frame colors for app screenshots. Source: https://www.cult-ui.com/docs/components/apple-iphone-17-pro ## Example ```tsx title="apple-iphone-17-pro-demo.tsx" "use client" import { useState } from "react" import { IPhone17ProMax, type DynamicIslandSize, } from "@/components/ui/apple-iphone-17-pro" const FRAME_SWATCH: Record<"graphite" | "gold" | "blue", string> = { graphite: "#363839", gold: "#E96A45", blue: "#0066F7", } export default function AppleIPhone17ProDemo() { const [dynamicIslandSize, setDynamicIslandSize] = useState("default") const [frameColor, setFrameColor] = useState< "graphite" | "silver" | "gold" | "blue" >("graphite") const cycleDynamicIsland = () => { const sizes: DynamicIslandSize[] = ["default", "expanded", "large", "ultra"] const currentIndex = sizes.indexOf(dynamicIslandSize) const nextIndex = (currentIndex + 1) % sizes.length setDynamicIslandSize(sizes[nextIndex]) } return ( {/* Demo screen content */}

iPhone 17 Pro Max

Tap the Screen to cycle
through dynamic island sizes

Current: {dynamicIslandSize}
{/* Frame color selector */}
{(["graphite", "gold", "blue"] as const).map((color) => (

Select frame color

) } ``` Apple iPhone 17 Pro Max is a React device mockup component for shadcn/ui. Use it to present mobile app screens on landing pages, product launches, or portfolio case studies. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/apple-iphone-17-pro ``` ### Manual **Install the required dependencies:** ```bash npm install lucide-react motion ``` **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/apple-iphone-17-pro.json **Update the import paths to match your project setup.** ## Usage `IPhone17ProMax` is a client component. Pass `children` for the screen body, and use `dynamicIslandSize`, `frameColor`, and optional callbacks to match your layout. ```tsx import { IPhone17ProMax } from "@/components/apple-iphone-17-pro"; export function Hero() { return (
Your UI
); } ``` --- # Apple Keyboard > Apple Magic Keyboard illustration for React and shadcn/ui with labeled, pressable keys and a media row for shortcut guides. Source: https://www.cult-ui.com/docs/components/apple-keyboard ## Example ```tsx title="apple-keyboard-demo.tsx" "use client" import { AppleKeyboard } from "@/components/ui/apple-keyboard" export default function AppleKeyboardDemo() { return (
) } ``` Apple Keyboard is a React illustration component for shadcn/ui with Tabler icons on the media row. Use it as an illustration for keyboard shortcut guides, productivity apps, or developer tool landing pages. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/apple-keyboard ``` ### Manual **Install the required dependencies:** ```bash npm install @tabler/icons-react ``` **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/apple-keyboard.json **Update the import paths to match your project setup.** ## Usage `AppleKeyboard` renders a static, presentational compact keyboard layout for marketing or device mockups. ```tsx import { AppleKeyboard } from "@/components/apple-keyboard"; export function Showcase() { return (
); } ``` --- # Apple Pro Display XDR > Apple Pro Display XDR mockup for React and shadcn/ui with an aluminum frame, screen modes, and an animated macOS dock. Source: https://www.cult-ui.com/docs/components/apple-pro-display-xdr ## Example ```tsx title="apple-pro-display-xdr-demo.tsx" "use client" import { AppleProDisplayXDR } from "@/components/ui/apple-pro-display-xdr" export default function AppleProDisplayXDRDemo() { return (
) } ``` Apple Pro Display XDR is a React display mockup component for shadcn/ui, animated with Motion. Use it to showcase desktop apps on landing pages, or pass your own screen content. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/apple-pro-display-xdr ``` ### Manual **Install the required dependencies:** ```bash npm install @tabler/icons-react motion ``` **Install the tooltip component from shadcn/ui:** ```bash npx shadcn@latest add tooltip ``` **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/apple-pro-display-xdr.json **Update the import paths to match your project setup.** **The built-in wallpaper demo loads `next/image` from `public/images/apple-wallpaper.jpg`. Add that asset or pass `screenContent` / adjust the source in the component.** ## Usage `AppleProDisplayXDR` is a client component. Optionally pass `screenContent` to fully control the display area; otherwise the default cycling demos and dock run on click. ```tsx import { AppleProDisplayXDR } from "@/components/apple-pro-display-xdr"; export function Hero() { return ( ); } ``` --- # Apple Watch Ultra > Apple Watch Ultra mockup for React and shadcn/ui with tappable complications, a rotating crown compass, and Motion animation. Source: https://www.cult-ui.com/docs/components/apple-watch-ultra ## Example ```tsx title="apple-watch-ultra-demo.tsx" "use client" import { AppleWatchUltra } from "@/components/ui/apple-watch-ultra" export default function AppleWatchUltraDemo() { return (
) } ``` Apple Watch Ultra is a React smartwatch mockup component for shadcn/ui, animated with Motion. Use it for fitness, outdoor, or wearable app landing pages. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/apple-watch-ultra ``` ### Manual **Install the required dependencies:** ```bash npm install lucide-react ``` **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/apple-watch-ultra.json **Update the import paths to match your project setup.** ## Usage `AppleWatchUltra` is a self-contained client component with interactive crown, action button, and complication regions. ```tsx import { AppleWatchUltra } from "@/components/apple-watch-ultra"; export function Showcase() { return ; } ``` --- # Background Animate Button > Animated gradient button for React and shadcn/ui with a rotating conic background, preset gradients, CVA variants, and asChild. Source: https://www.cult-ui.com/docs/components/bg-animate-button ## Example ```tsx title="bg-animate-button-demo.tsx" import { BgAnimateButton } from "../ui/bg-animate-button" type Gradients = | "sunrise" | "ocean" | "candy" | "default" | "forest" | "sunset" | "nebula" type Radius = "full" | "xl" | "2xl" | "3xl" | "sm" type Animations = "spin" | "pulse" | "spin-slow" | "spin-fast" const gradients: Gradients[] = [ "sunrise", "ocean", "candy", "forest", "sunset", "default", "nebula", ] const roundings: Radius[] = ["full", "xl", "2xl", "3xl", "sm"] const animations: Animations[] = ["spin", "pulse", "spin-slow", "spin-fast"] export const BgAnimateButtonsDemo = () => { return (
{/* Roundings Grid */}
{roundings.slice(0, 2).map((rounding, i) => ( {rounding} ))}
{roundings.slice(2, 5).map((rounding, i) => ( {rounding} ))}
{/* animations Grid */}
{animations.map((animations, i) => ( {animations} ))}
) } export default BgAnimateButtonsDemo ``` BgAnimateButton is a React button component for shadcn/ui built with class-variance-authority and Radix Slot. Use it for call to action buttons on landing pages, pricing sections, or signup forms. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/bg-animate-button ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/bg-animate-button.json **Update the import paths to match your project setup.** ## Usage ```tsx const roundings = ["full", "xl", "2xl", "3xl", "sm"]; const gradients = [ "sunrise", "ocean", "candy", "default", "forest", "sunset", "nebula", ]; const animations = ["spin", "pulse", "spin-slow", "spin-fast"]; export const BgAnimateDemo = () => { return (
{/* Roundings Grid */}
{roundings.slice(0, 2).map((rounding, i) => ( {rounding} ))}
{roundings.slice(2, 5).map((rounding, i) => ( {rounding} ))}
{/* animations Grid */}
{animations.map((animations, i) => ( {animations} ))}
); }; export default BgAnimateDemo; ``` --- # Fractal Dot Grid > Interactive canvas dot grid background for React and shadcn/ui with a hover wave, optional noise, and a mouse-following glow. Source: https://www.cult-ui.com/docs/components/bg-animated-fractal-grid ## Example ```tsx title="bg-animated-fractal-dot-grid-demo.tsx" "use client" import React, { useState } from "react" import { Check, Copy } from "lucide-react" import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, } from "@/components/ui/accordion" import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { Slider } from "@/components/ui/slider" import { Switch } from "@/components/ui/switch" import { useToast } from "@/components/ui/use-toast" import { FractalDotGrid } from "../ui/bg-animated-fractal-dot-grid" const initialConfig = { dotSize: 5.5, dotSpacing: 13, dotOpacity: 0.7, waveIntensity: 99, waveRadius: 200, dotColor: "rgba(100, 100, 255, 1)", glowColor: "rgba(100, 100, 255, 1)", enableNoise: false, noiseOpacity: 0.03, enableMouseGlow: false, initialPerformance: "medium" as const, } export function ConfigurableFractalDotGridDemo() { const [config, setConfig] = useState(initialConfig) const [isCopied, setIsCopied] = useState(false) const { toast } = useToast() const updateConfig = (key: string, value: any) => { setConfig((prev) => ({ ...prev, [key]: value })) } const copyConfigToClipboard = () => { const configString = ` "use client" import { FractalDotGrid } from "./fractal-dot-grid" export function FractalDotGridExample() { return (
) } ` navigator.clipboard.writeText(configString).then(() => { setIsCopied(true) toast({ title: "Configuration Copied", description: "The current configuration has been copied to your clipboard.", }) setTimeout(() => setIsCopied(false), 2000) }) } return (
Configuration ### Dots
updateConfig("dotSize", value) } />
updateConfig("dotSpacing", value) } />
updateConfig("dotOpacity", value) } />
updateConfig("dotColor", e.target.value) } className="h-10 px-3 py-2" />
### Waves
updateConfig("waveIntensity", value) } />
updateConfig("waveRadius", value) } />
### Effects
updateConfig("glowColor", e.target.value) } className="h-10 px-3 py-2" />
updateConfig("enableNoise", checked) } />
{config.enableNoise && (
updateConfig("noiseOpacity", value) } />
)}
updateConfig("enableMouseGlow", checked) } />
### Performance
) } export default ConfigurableFractalDotGridDemo ``` FractalDotGrid is a canvas-rendered React background component for shadcn/ui. Use it behind landing page heroes or feature sections to add motion without loading images or video. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/bg-animated-fractal-dot-grid ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/bg-animated-fractal-dot-grid.json **Update the import paths to match your project setup.** ## Usage ```tsx function FractalDotGridExample() { return (
); } export default FractalDotGridExample; ``` --- # Background Image Texture > Texture background wrapper for React and shadcn/ui that layers fabric, grid-noise, or paper textures behind content at any opacity. Source: https://www.cult-ui.com/docs/components/bg-image-texture ## Example ```tsx title="bg-image-texture-demo.tsx" "use client" import { useState } from "react" import { Download } from "lucide-react" import { Button } from "@/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card" import { Label } from "@/components/ui/label" import { Slider } from "@/components/ui/slider" import { BackgroundImageTexture } from "@/components/ui/bg-image-texture" import type { TextureVariant } from "@/components/ui/bg-image-texture" const textureVariants: TextureVariant[] = [ "fabric-of-squares", "grid-noise", "inflicted", "debut-light", "groovepaper", "none", ] const textureMap: Record, string> = { "fabric-of-squares": "/textures/fabric-of-squares.png", "grid-noise": "/textures/grid-noise.png", inflicted: "/textures/inflicted.png", "debut-light": "/textures/debut-light.png", groovepaper: "/textures/groovepaper.png", } async function downloadTexture(variant: Exclude) { const url = textureMap[variant] try { const response = await fetch(url) const blob = await response.blob() const blobUrl = window.URL.createObjectURL(blob) const link = document.createElement("a") link.href = blobUrl link.download = `${variant}.png` document.body.appendChild(link) link.click() document.body.removeChild(link) window.URL.revokeObjectURL(blobUrl) } catch { // Fallback to direct link if fetch fails const link = document.createElement("a") link.href = url link.download = `${variant}.png` document.body.appendChild(link) link.click() document.body.removeChild(link) } } export default function BackgroundImageTextureDemo() { const [selectedVariant, setSelectedVariant] = useState("fabric-of-squares") const [opacity, setOpacity] = useState([0.5]) return (
{/* Controls */} Texture Controls Select a texture variant and adjust the opacity
{textureVariants.map((variant) => ( ))}
{/* Preview with Content */}
Preview with Content See how the texture looks with content on top
{selectedVariant !== "none" && ( )}

Texture Background

This content sits on top of the texture layer. Adjust the opacity slider to see how the texture affects the background. The texture is fully interactive and customizable.

Feature 1

Content with texture background

Feature 2

More content examples

{/* All Variants Showcase */}

All Texture Variants

{textureVariants .filter((v) => v !== "none") .map((variant) => (
{variant.replace(/-/g, " ")}

{variant}

Opacity: 0.5

))}
{/* Opacity Variations */}

Opacity Variations

{[0.2, 0.5, 0.8].map((opacityValue) => ( Opacity: {opacityValue}

grid-noise texture

Opacity: {opacityValue}

))}
{/* Use Case Examples */}

Use Case Examples

{/* Card with Texture */} Card with Texture

Beautiful Card

Cards look great with subtle texture backgrounds

{/* Hero Section */} Hero Section

Hero Title

Perfect for hero sections and banners

) } ``` BackgroundImageTexture is a React wrapper component for shadcn/ui. Use it to add subtle surface texture to hero sections, cards, or pricing blocks. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/bg-image-texture ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/bg-image-texture.json **Update the import paths to match your project setup.** ## Usage ```tsx import { BackgroundImageTexture } from "@/components/ui/bg-image-texture"; ``` ### Basic Usage Apply a texture background to any container: ```tsx

Content with texture background

Your content goes here

``` ### Texture Variants Choose from five different texture patterns: ```tsx // Fabric of squares pattern
Content
// Grid noise pattern
Content
// Inflicted pattern
Content
// Debut light pattern
Content
// Groovepaper pattern
Content
// No texture (transparent)
Content
``` ### Opacity Control Adjust the opacity to control how visible the texture is: ```tsx // Subtle texture (low opacity)
Content
// Medium texture (default)
Content
// Bold texture (high opacity)
Content
``` ### Without Children The component can be used without children for a pure background texture: ```tsx ``` ## API Reference ### BackgroundImageTexture Props | Prop | Type | Default | Description | | --- | --- | --- | --- | | `variant` | `TextureVariant` | `"fabric-of-squares"` | Texture pattern variant | | `opacity` | `number` | `0.5` | Opacity of the texture (0 to 1) | | `className` | `string` | - | Additional CSS classes for the container | | `children` | `React.ReactNode` | - | Content to display on top of the texture | ### TextureVariant Type ```tsx type TextureVariant = | "fabric-of-squares" | "grid-noise" | "inflicted" | "debut-light" | "groovepaper" | "none"; ``` ## Features - **Multiple Texture Variants**: Choose from 5 different texture patterns - **Customizable Opacity**: Control texture visibility from 0 to 1 - **Flexible Usage**: Use with or without children content - **Accessible**: Texture layer is marked with `aria-hidden="true"` - **Non-Interactive**: Texture layer has `pointer-events-none` to allow interaction with content - **Responsive**: Works seamlessly across all screen sizes ## Examples ### Card with Texture Add texture to card components: ```tsx Card Title

Card Content

Cards look great with subtle texture backgrounds

``` ### Hero Section Use texture in hero sections: ```tsx

Hero Title

Perfect for hero sections and banners

``` ### All Variants Showcase Display all texture variants: ```tsx const variants = [ "fabric-of-squares", "grid-noise", "inflicted", "debut-light", "groovepaper", ] as const
{variants.map((variant) => (

{variant}

))}
``` ### Opacity Variations Compare different opacity levels: ```tsx const opacities = [0.2, 0.5, 0.8]
{opacities.map((opacity) => (

Opacity: {opacity}

))}
``` ### Dynamic Opacity Control Use state to control opacity dynamically: ```tsx import { useState } from "react"; import { BackgroundImageTexture } from "@/components/ui/bg-image-texture"; import { Slider } from "@/components/ui/slider"; function DynamicTextureExample() { const [opacity, setOpacity] = useState([0.5]); return (

Dynamic Texture

Adjust the slider to change texture opacity

); } ``` ### Custom Styling Apply custom styles to the container: ```tsx
Custom styled content
``` ### Section Dividers Use texture as decorative section dividers: ```tsx
``` --- # Background Media > Full screen image or video background for React and shadcn/ui with a light or dark overlay and a play and pause control. Source: https://www.cult-ui.com/docs/components/bg-media ## Example ```tsx title="bg-media-demo.tsx" import BackgroundMedia from "../ui/bg-media" export default function BgMediaDemo() { return (
) } ``` BgMedia is a React background component for shadcn/ui. Use it for landing page heroes, event pages, or portfolio intros that lead with photography or footage. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/bg-media ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/bg-media.json **Update the import paths to match your project setup.** ## Usage ```tsx import BackgroundMedia from "@/components/ui/bg-media"; export default function BgMediaDemo() { return (
); } ``` --- # Border Beam Button > shadcn/ui Button with an animated border beam, in text and icon variants, for primary calls to action in React apps. Source: https://www.cult-ui.com/docs/components/border-beam-button ## Example ```tsx title="border-beam-button-demo.tsx" "use client" import { useEffect, useId, useState, type ReactNode } from "react" import type { BorderBeamColorVariant } from "border-beam" import { ArrowRight, Pause, Play, Sparkles, Wand2, Zap } from "lucide-react" import { cn } from "@/lib/utils" import { BorderBeamButton, BorderBeamIconButton, } from "@/components/ui/border-beam-button" const COLOR_ROW: { key: BorderBeamColorVariant; label: string }[] = [ { key: "colorful", label: "Colorful" }, { key: "ocean", label: "Ocean" }, { key: "sunset", label: "Sunset" }, { key: "mono", label: "Mono" }, ] const BEAM_SIZES = ["sm", "md", "line"] as const function Section({ title, description, children, }: { title: string description?: string children: ReactNode }) { return (

{title}

{description ? (

{description}

) : null}
{children}
) } export default function BorderBeamButtonDemo() { const id = useId() const [beamActive, setBeamActive] = useState(true) const [respectsReducedMotion, setRespectsReducedMotion] = useState(false) useEffect(() => { const mq = window.matchMedia("(prefers-reduced-motion: reduce)") const sync = () => setRespectsReducedMotion(mq.matches) sync() mq.addEventListener("change", sync) return () => mq.removeEventListener("change", sync) }, []) const effectiveActive = beamActive && !respectsReducedMotion return (

Border beam

Button + traveling glow

className targets the shadcn Button;{" "} borderBeamClassName styles the beam wrapper. Use{" "} colorVariant,{" "} beamSize, and{" "} active to tune the effect.

Continue Outline Secondary Ghost
{COLOR_ROW.map(({ key, label }) => ( {label} ))}
{BEAM_SIZES.map((size) => ( {size} ))}
Get started setBeamActive((v) => !v)} title={effectiveActive ? "Pause beam" : "Play beam"} type="button" variant="secondary" > {effectiveActive ? ( ) : ( )}

{respectsReducedMotion ? "Reduced motion is on — beam animation stays off." : "Tip: pause leaves the button fully clickable; the glow stops."}

) } ``` BorderBeamButton is a React button component for shadcn/ui built on the border-beam package. Use it for the primary call to action in AI prompt bars, onboarding flows, or upgrade prompts. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/border-beam-button ``` ### Manual **Install the [Border Beam](https://www.npmjs.com/package/border-beam) package.** ```bash pnpm add border-beam ``` **Add the [shadcn/ui Button](https://ui.shadcn.com/docs/components/button) if you do not already have it.** **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/border-beam-button.json **Update the import paths to match your project setup.** ## Usage `BorderBeamButton` wraps the standard `Button` with [`BorderBeam`](https://www.npmjs.com/package/border-beam) from the [`border-beam`](https://www.npmjs.com/package/border-beam) package. Pass any `Button` props as usual. Use `className` for the button surface and `borderBeamClassName` (or `borderBeamStyle`) for the beam wrapper. - **BorderBeamButton** — default `beamSize="sm"` for a tight glow on controls. - **BorderBeamIconButton** — same API, with `size` defaulting to `icon-sm` for icon-only actions. ```tsx import { BorderBeamButton, BorderBeamIconButton, } from "@/components/ui/border-beam-button"; import { Sparkles } from "lucide-react"; ``` ```tsx Outline ``` ### Beam options The component forwards the main [`BorderBeam`](https://www.npmjs.com/package/border-beam) controls: `beamSize`, `theme`, `colorVariant`, `staticColors`, `duration`, `active`, `borderRadius`, `brightness`, `saturation`, `hueRange`, `strength`, `onActivate`, and `onDeactivate`. See the [Border Beam documentation](https://beam.jakubantalik.com/) for behavior and examples. ## Credits The animated border effect comes from **Border Beam** by Jakub Antalík. Documentation, demos, and the underlying React package are available at [beam.jakubantalik.com](https://beam.jakubantalik.com/). --- # Border Beam Card > React card for shadcn/ui with an animated border-beam glow on the compound Card API, for featured plans and active AI tasks. Source: https://www.cult-ui.com/docs/components/border-beam-card ## Example ```tsx title="border-beam-card-demo.tsx" "use client" import { useId, useState } from "react" import { BorderBeamCard, BorderBeamCardContent, BorderBeamCardDescription, BorderBeamCardHeader, BorderBeamCardTitle, } from "@/components/ui/border-beam-card" export default function BorderBeamCardDemo() { const [strength, setStrength] = useState(1) const [active, setActive] = useState(true) const strengthId = useId() const activeId = useId() return (

Border beam card

BorderBeamCard wraps{" "} Card {" "} with the same header / content slots. Effect layers use{" "} pointer-events: none.

Composable card

Same slots as Card — header, title, description, content.

Border beam card Uses Card layout tokens; beamSize{" "} controls the glow preset,{" "} size matches card density (sm / default).

Body content sits in{" "} CardContent, with padding aligned to the root{" "} size.

Color variants

colorful

mono

ocean

sunset

) } ``` Border Beam Card is a React card component for shadcn/ui built on the border-beam package. Use it to highlight a featured pricing plan, an active AI task, or an announcement on dashboards and landing pages. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/border-beam-card ``` ### Manual **Install the required dependencies:** ```bash npm install border-beam ``` **Add the shadcn `card` component if you do not already have it.** **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/border-beam-card.json **Update the import paths to match your project setup.** --- # Border Beam Input > React input for shadcn/ui built on Base UI with an animated border-beam glow along the bottom edge or the full border. Source: https://www.cult-ui.com/docs/components/border-beam-input ## Example ```tsx title="border-beam-input-demo.tsx" "use client" import { useId } from "react" import { Search } from "lucide-react" import { BorderBeamInput, BorderBeamInputGroup, BorderBeamInputGroupAddon, BorderBeamInputGroupInput, } from "@/components/ui/border-beam-input" export default function BorderBeamInputDemo() { const searchId = useId() return (

Border beam input

BorderBeamInput and{" "} BorderBeamInputGroup{" "} default to{" "} beamSize="line" {" "} (bottom-travel glow). Use{" "} pill on the group for a rounded search bar. Addons match{" "} InputGroup {" "} composition.

Single input & pill group

Line beam (InputGroup)

Same pattern as a compact toolbar search — icon + control inside{" "} BorderBeamInputGroup.

) } ``` Border Beam Input is a React input component for shadcn/ui built on Base UI and the border-beam package. Use it for AI prompt fields, search bars, or newsletter signup forms. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/border-beam-input ``` ### Manual **Install the required dependencies:** ```bash npm install border-beam @base-ui/react ``` **Add the shadcn `input-group` component if you do not already have it.** **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/border-beam-input.json **Update the import paths to match your project setup.** --- # Canvas Fractal Grid > Interactive canvas dot grid hero background for React and shadcn/ui with animated gradients, noise, glow, and performance presets. Source: https://www.cult-ui.com/docs/components/canvas-fractal-grid ## Example ```tsx title="canvas-fractal-grid-demo.tsx" "use client" import React, { useState } from "react" import { Check, Copy, Minus, Plus, Trash2 } from "lucide-react" import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, } from "@/components/ui/accordion" import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select" import { Slider } from "@/components/ui/slider" import { Switch } from "@/components/ui/switch" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { useToast } from "@/components/ui/use-toast" import { CanvasFractalGrid } from "../ui/canvas-fractal-grid" type GradientStop = { color: string position: number } type Gradient = { stops: GradientStop[] centerX: number centerY: number } const initialConfig = { dotSize: 5, dotSpacing: 25, dotOpacity: 0.8, gradientAnimationDuration: 5, waveIntensity: 40, waveRadius: 250, dotColor: "rgba(100, 200, 255, 0.2)", glowColor: "rgba(100, 200, 255, 1)", enableNoise: true, noiseOpacity: 0.05, enableMouseGlow: false, initialPerformance: "high" as const, gradients: [ { stops: [ { color: "#3498DB", position: 0 }, { color: "#2980B9", position: 25 }, { color: "#1ABC9C", position: 50 }, { color: "transparent", position: 75 }, ], centerX: 30, centerY: 70, }, { stops: [ { color: "#16A085", position: 0 }, { color: "#2980B9", position: 25 }, { color: "#3498DB", position: 50 }, { color: "transparent", position: 75 }, ], centerX: 70, centerY: 30, }, ], } export function ConfigurableCanvasFractalGrid() { const [config, setConfig] = useState(initialConfig) const [isCopied, setIsCopied] = useState(false) const { toast } = useToast() const updateConfig = (key: string, value: any) => { setConfig((prev) => ({ ...prev, [key]: value })) } const updateGradient = (index: number, updatedGradient: Gradient) => { const newGradients = [...config.gradients] newGradients[index] = updatedGradient updateConfig("gradients", newGradients) } const addGradient = () => { const newGradient: Gradient = { stops: [ { color: "#000000", position: 0 }, { color: "#FFFFFF", position: 100 }, ], centerX: 50, centerY: 50, } updateConfig("gradients", [...config.gradients, newGradient]) } const removeGradient = (index: number) => { const newGradients = config.gradients.filter((_, i) => i !== index) updateConfig("gradients", newGradients) } const copyConfigToClipboard = () => { const configString = ` "use client" import { CanvasFractalGrid } from "../ui/canvas-fractal-grid" export function CanvasFractalGridExample() { return (
) } ` navigator.clipboard.writeText(configString).then(() => { setIsCopied(true) toast({ title: "Configuration Copied", description: "The current configuration has been copied to your clipboard.", }) setTimeout(() => setIsCopied(false), 2000) }) } return (

Configurable CanvasFractalGrid

Configuration ### General ### Dots
updateConfig("dotSize", value) } />
updateConfig("dotSpacing", value) } />
updateConfig("dotOpacity", value) } />
updateConfig("dotColor", e.target.value) } className="h-10 px-3 py-2" />
### Waves
updateConfig("waveIntensity", value) } />
updateConfig("waveRadius", value) } />
### Effects
updateConfig("gradientAnimationDuration", value) } />
updateConfig("glowColor", e.target.value) } className="h-10 px-3 py-2" />
updateConfig("enableNoise", checked) } />
updateConfig("enableMouseGlow", checked) } />
### Performance
### Gradients
{config.gradients.map((gradient, index) => ( Gradient {index + 1}
updateGradient(index, { ...gradient, centerX: value, }) } />
updateGradient(index, { ...gradient, centerY: value, }) } />
{gradient.stops.map((stop, stopIndex) => (
{ const newStops = [...gradient.stops] newStops[stopIndex] = { ...stop, color: e.target.value, } updateGradient(index, { ...gradient, stops: newStops, }) }} className="h-10 w-16" /> { const newStops = [...gradient.stops] newStops[stopIndex] = { ...stop, position: value, } updateGradient(index, { ...gradient, stops: newStops, }) }} className="flex-grow" />
))}
))}
) } export default ConfigurableCanvasFractalGrid ``` CanvasFractalGrid is a canvas-rendered React background component for shadcn/ui, animated with Motion. Use it as a hero or section background on landing pages and product sites. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/canvas-fractal-grid ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/canvas-fractal-grid.json **Update the import paths to match your project setup.** ## Usage ```tsx function CanvasFractalGridExample() { return (
); } export default CanvasFractalGridExample; ``` --- # Choice Poll > Composable React poll for shadcn/ui with single or multiple choice, result bars with percentages, and keyboard navigation. Source: https://www.cult-ui.com/docs/components/choice-poll ## Example ```tsx title="choice-poll-demo.tsx" "use client" import { useState } from "react" import { Database01Icon, DropboxIcon, Github01Icon, GoogleIcon, NotionIcon, SlackIcon, } from "@hugeicons/core-free-icons" import { HugeiconsIcon } from "@hugeicons/react" import { Button } from "@/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card" import { ChoicePoll } from "../ui/choice-poll" /* ----------------------------------------------------------------------------- * Integration options data * -------------------------------------------------------------------------- */ const integrations = [ { id: "slack", label: "Slack", description: "Team communication and notifications", icon: SlackIcon, }, { id: "notion", label: "Notion", description: "Documentation and knowledge base", icon: NotionIcon, }, { id: "github", label: "GitHub", description: "Code repositories and CI/CD", icon: Github01Icon, }, { id: "google-drive", label: "Google Drive", description: "File storage and collaboration", icon: GoogleIcon, }, { id: "dropbox", label: "Dropbox", description: "Cloud file storage", icon: DropboxIcon, }, { id: "supabase", label: "Supabase", description: "Database and authentication", icon: Database01Icon, }, ] /* ----------------------------------------------------------------------------- * Basic Example - Single Selection * -------------------------------------------------------------------------- */ function ChoicePollBasicExample() { const [selected, setSelected] = useState("") const [hasVoted, setHasVoted] = useState(false) const votes = { slack: 234, notion: 189, github: 156, "google-drive": 98, } const handleVote = () => { setHasVoted(true) } return ( Vote for Next Integration Help us prioritize which integration to build next setSelected(Array.isArray(v) ? (v[0] ?? "") : v) } showResults value={selected} votes={votes} > {integrations.slice(0, 4).map((integration) => (
{integration.label}
))}
{!hasVoted && (
)}
) } /* ----------------------------------------------------------------------------- * With Results Example * -------------------------------------------------------------------------- */ function ChoicePollWithResultsExample() { const [selected, setSelected] = useState("") const [hasVoted, setHasVoted] = useState(false) const votes = { slack: 100, notion: 189, github: 256, "google-drive": 98, } const handleVote = () => { setHasVoted(true) } return ( Vote for Next Integration Help us prioritize which integration to build next setSelected(Array.isArray(v) ? (v[0] ?? "") : v) } showResults value={selected} votes={votes} > {integrations.slice(0, 4).map((integration) => (
{integration.label}
))}
{!hasVoted && (
)}
) } /* ----------------------------------------------------------------------------- * Multiple Selection Example * -------------------------------------------------------------------------- */ function ChoicePollMultipleExample() { const [selected, setSelected] = useState([]) const [hasVoted, setHasVoted] = useState(false) const votes = { slack: 100, notion: 189, github: 256, "google-drive": 198, dropbox: 98, supabase: 156, } const handleVote = () => { setHasVoted(true) } return ( Choose Your Top Integrations Select up to 3 integrations you'd like us to prioritize setSelected(val as string[])} showResults value={selected} votes={votes} > {integrations.map((integration) => ( = 3 && !selected.includes(integration.id) } key={integration.id} value={integration.id} >
{integration.label} {integration.description}
))}
{!hasVoted && (
)}
) } /* ----------------------------------------------------------------------------- * Compact Inline Example * -------------------------------------------------------------------------- */ function ChoicePollCompactExample() { const [selected, setSelected] = useState("") return (
setSelected(Array.isArray(v) ? (v[0] ?? "") : v)} value={selected} > Quick Poll Which feature would you like next? Dark Mode Mobile App API Access
) } /* ----------------------------------------------------------------------------- * Combined Demo * -------------------------------------------------------------------------- */ export default function ChoicePollDemo() { return (

Single Selection

With Results

Multiple Selection

Compact

) } ``` Choice Poll is a composable React poll component for shadcn/ui with controlled or uncontrolled state. Use it for feedback widgets, community votes, or in-app surveys. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/choice-poll ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/choice-poll.json **Update the import paths to match your project setup.** ## Usage Use `ChoicePoll.Root` with Header, Title, Description, Options (each Option with Indicator and Label), and Footer. Supports single or multiple selection, controlled or uncontrolled value, and optional results after voting. ### Basic poll ```tsx import { ChoicePoll } from "@/registry/default/ui/choice-poll"; export default function Example() { return ( Which feature matters most? Pick one option. Results are shown after you vote. Faster builds Better DX Clearer docs ); } ``` ### Poll with results (controlled) Wire `value` / `onValueChange` and set `showResults`, `hasVoted`, and `votes` when the user submits to show results and "You voted". ```tsx import { useState } from "react"; import { ChoicePoll } from "@/registry/default/ui/choice-poll"; export default function Example() { const [value, setValue] = useState(); const [hasVoted, setHasVoted] = useState(false); const votes = { speed: 42, dx: 28, docs: 30 }; return ( Which feature matters most? Pick one, then submit. Faster builds Better DX Clearer docs {/* In real usage, a submit button would set hasVoted to true */} ); } ``` ## Features - Single or multiple selection via `multiple` - Controlled or uncontrolled value via `value` / `defaultValue` and `onValueChange` - Optional results: `showResults`, `votes`, `hasVoted` for progress bars and "You voted" - Keyboard navigation (Arrow keys, Home, End) in the options list - Compound API: Root, Header, Title, Description, Options, Option, Indicator, Label, Progress, Percentage, Footer --- # Circuit Board > Animated SVG circuit board illustration for React and shadcn/ui with glowing traces around a central chip, for AI and dev tools. Source: https://www.cult-ui.com/docs/components/circuit-board ## Example ```tsx title="circuit-board-demo.tsx" "use client" import { CircuitBoard } from "@/components/ui/circuit-board" function CircuitBoardDemo() { return (
) } export default CircuitBoardDemo ``` Circuit Board is a React SVG illustration component for shadcn/ui, animated with Motion and CSS keyframes. Use it in hero sections or feature grids for AI, hardware, infrastructure, or developer tool products. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/circuit-board ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/circuit-board.json **Install dependencies if needed: `motion` and `lucide-react`.** **Update the import paths to match your project setup.** ## Usage Import and render `CircuitBoard` inside a full-width container. The SVG scales with its parent (`max-w-[891px]` inside the component). Pair it with dark backgrounds so the orange pulse and card treatments read clearly. --- # Code Block > Code block for React and shadcn/ui with tabs for npm, pnpm, and yarn snippets, a copy button, and animated tab switching. Source: https://www.cult-ui.com/docs/components/code-block ## Example ```tsx title="code-block-demo.tsx" import { CodeBlock } from "@/components/ui/code-block" function CodeBlockDemo() { return (
{/* Multi-tab example */}

Package Manager Installation

{/* Single code block example */}

Single Code Block

) }`} language="tsx" />
{/* API example */}

API Configuration

) } export default CodeBlockDemo ``` CodeBlock is a React code display component for shadcn/ui, animated with Motion. Use it in documentation, installation instructions, or landing pages that show the same command for npm, pnpm, and yarn. ## References Inspiration Kibo UI Code Block ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/code-block ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/code-block.json **Update the import paths to match your project setup.** ## Usage ```tsx import { CodeBlock } from "@/components/ui/code-block"; ``` ### Single Code Block Display a single code snippet: ```tsx ``` ### Multi-Tab Code Block Display multiple code snippets with tabs: ```tsx ``` ### Package Manager Installation Common use case for showing different package manager commands: ```tsx ``` ### Multi-Language Code Examples Show code examples in different languages: ```tsx ``` ## API Reference ### CodeBlock Props | Prop | Type | Default | Description | | --- | --- | --- | --- | | `tabs` | `CodeTab[]` | - | Array of code tabs for multi-tab display | | `code` | `string` | - | Single code string (when not using tabs) | | `language` | `string` | `"bash"` | Language identifier for syntax highlighting | | `className` | `string` | - | Additional CSS classes | ### CodeTab Interface | Property | Type | Description | | ---------- | -------- | ---------------------------------- | | `label` | `string` | Tab label displayed in the tab bar | | `code` | `string` | Code content for this tab | | `language` | `string` | Optional language identifier | ## Features - **Single & Multi-Tab Support**: Use either a single code block or multiple tabs - **Copy Functionality**: Built-in copy button with smooth animations - **Direction-Aware Animations**: Smooth transitions when switching tabs - **Dark Mode**: Automatically adapts to light and dark themes - **Accessible**: Proper ARIA labels and keyboard navigation support - **Responsive**: Scrollable tabs for mobile devices ## Examples ### Basic JavaScript ```tsx ``` ### React Component ```tsx ) }`} language="tsx" /> ``` ### Configuration Files ```tsx ``` ### API Examples ```tsx ``` ### Custom Styling ```tsx ``` --- # Collab Avatar > Presence avatar for React and shadcn/ui showing initials on a color-tinted gradient, for collaborative editors and whiteboards. Source: https://www.cult-ui.com/docs/components/collab-avatar ## Example ```tsx title="collab-avatar-demo.tsx" "use client" import { CollabAvatar } from "@/components/ui/collab-avatar" const avatars = [ { name: "Jordan Gilliam", color: "#0070F3" }, { name: "Alex Kim", color: "#7928CA" }, { name: "Sam Taylor", color: "#EB3672" }, { name: "Jo", color: "#00C2A8" }, ] function CollabAvatarDemo() { return (
{avatars.map(({ name, color }) => ( ))}
) } export default CollabAvatarDemo ``` Collab Avatar is a React avatar component for shadcn/ui with a Motion entrance that respects reduced motion. Use it for presence indicators in collaborative editors, whiteboards, or shared documents. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/collab-avatar ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/collab-avatar.json **Update the import paths to match your project setup.** --- # Collab Toolbar > Collaborative editor toolbar for React and shadcn/ui that groups icon buttons and collaborator avatars into divided sections. Source: https://www.cult-ui.com/docs/components/collab-toolbar ## Example ```tsx title="collab-toolbar-demo.tsx" "use client" import { CollabToolbar } from "@/components/ui/collab-toolbar" const avatars = [ { name: "Jane Doe", imageUrl: "https://i.pravatar.cc/100?img=12" }, { name: "Alex Kim", imageUrl: "https://i.pravatar.cc/100?img=32" }, { name: "Sam Taylor", imageUrl: "https://i.pravatar.cc/100?img=68" }, ] function CollabToolbarDemo() { return (
) } export default CollabToolbarDemo ``` Collab Toolbar is a React toolbar component for shadcn/ui with data-slot attributes for styling. Use it as the top bar of collaborative editors, design canvases, or shared whiteboards. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/collab-toolbar ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/collab-toolbar.json **Update the import paths to match your project setup.** --- # Color Picker > Color picker for React and shadcn/ui with hue, saturation, and lightness sliders, hex or HSL input, and preset swatches. Source: https://www.cult-ui.com/docs/components/color-picker ## Example ```tsx title="color-picker-demo.tsx" "use client" import React, { useCallback, useState } from "react" import { Check, Copy, Lock, LockOpen, Palette, RefreshCw } from "lucide-react" import { motion } from "motion/react" import { Poline, positionFunctions } from "poline" import { Button } from "@/components/ui/button" import { Card, CardContent } from "@/components/ui/card" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip" import ColorPicker from "../ui/color-picker" type ColorScheme = { [key: string]: string } export default function ColorPickerDemo() { const [colorScheme, setColorScheme] = useState({ background: "0 0% 100%", foreground: "240 10% 3.9%", card: "0 0% 100%", "card-foreground": "240 10% 3.9%", popover: "0 0% 100%", "popover-foreground": "240 10% 3.9%", primary: "240 5.9% 10%", "primary-foreground": "0 0% 98%", secondary: "240 4.8% 95.9%", "secondary-foreground": "240 5.9% 10%", muted: "240 4.8% 95.9%", "muted-foreground": "240 3.8% 46.1%", accent: "240 4.8% 95.9%", "accent-foreground": "240 5.9% 10%", destructive: "0 84.2% 60.2%", "destructive-foreground": "0 0% 98%", border: "240 5.9% 90%", input: "240 5.9% 90%", ring: "240 5.9% 10%", }) const [lockedColor, setLockedColor] = useState(null) const [copied, setCopied] = useState(false) const generateHarmoniousColors = useCallback(() => { let anchorColors: [number, number, number][] = [] if (lockedColor) { const [h, s, l] = colorScheme[lockedColor].split(" ").map(parseFloat) anchorColors.push([h, s / 100, l / 100]) } while (anchorColors.length < 3) { anchorColors.push([Math.random() * 360, 0.7, 0.5]) } const poline = new Poline({ numPoints: 20, anchorColors, positionFunctionX: positionFunctions.sinusoidalPosition, positionFunctionY: positionFunctions.quadraticPosition, positionFunctionZ: positionFunctions.linearPosition, }) const newColorScheme = { ...colorScheme } const colors = poline.colorsCSS Object.keys(newColorScheme).forEach((key, index) => { if (key !== lockedColor) { const color = colors[index % colors.length] const [h, s, l] = color.match(/\d+(\.\d+)?/g)?.map(Number) || [0, 0, 0] let adjustedLightness = l if (key.includes("foreground")) { adjustedLightness = Math.min(l - 30, 20) } else if (key === "background") { adjustedLightness = Math.max(l + 30, 90) } else if (key === "border" || key === "input") { adjustedLightness = Math.min(Math.max(l, 70), 90) } newColorScheme[key] = `${h.toFixed(1)} ${s.toFixed( 1 )}% ${adjustedLightness.toFixed(1)}%` } }) setColorScheme(newColorScheme) }, [colorScheme, lockedColor]) const resetColors = useCallback(() => { setColorScheme({ background: "0 0% 100%", foreground: "240 10% 3.9%", card: "0 0% 100%", "card-foreground": "240 10% 3.9%", popover: "0 0% 100%", "popover-foreground": "240 10% 3.9%", primary: "240 5.9% 10%", "primary-foreground": "0 0% 98%", secondary: "240 4.8% 95.9%", "secondary-foreground": "240 5.9% 10%", muted: "240 4.8% 95.9%", "muted-foreground": "240 3.8% 46.1%", accent: "240 4.8% 95.9%", "accent-foreground": "240 5.9% 10%", destructive: "0 84.2% 60.2%", "destructive-foreground": "0 0% 98%", border: "240 5.9% 90%", input: "240 5.9% 90%", ring: "240 5.9% 10%", }) setLockedColor(null) }, []) const copyColorScheme = useCallback(() => { const cssVariables = Object.entries(colorScheme) .map(([key, value]) => `--${key}: ${value};`) .join("\n ") const fullCss = `@layer base { :root { ${cssVariables} } }` navigator.clipboard.writeText(fullCss) setCopied(true) setTimeout(() => setCopied(false), 2000) }, [colorScheme]) const getContrastColor = useCallback((color: string) => { const [, , lightness] = color.split(" ").map(parseFloat) return lightness > 50 ? "0 0% 0%" : "0 0% 100%" }, []) const toggleLock = useCallback((key: string) => { setLockedColor((prev) => (prev === key ? null : key)) }, []) return (
{Object.entries(colorScheme).map(([key, value]) => (
{ const [h, s, l] = newColor .match(/\d+(\.\d+)?/g) ?.map(Number) || [0, 0, 0] setColorScheme({ ...colorScheme, [key]: `${h.toFixed(1)} ${s.toFixed(1)}% ${l.toFixed( 1 )}%`, }) }} />
))}

Color Preview

Experience your color palette in action. This preview showcases your selected colors.

{Object.entries(colorScheme).map(([key, value]) => (
{key}

Click to copy

))}
) } ``` Color Picker is a popover-based React component for shadcn/ui. Use it in theme editors, design tools, or settings pages where users choose brand or accent colors. ## References ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/color-picker ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/color-picker.json **Update the import paths to match your project setup.** --- # Copy Button > Copy to clipboard button for React and shadcn/ui with a legacy fallback and an animated check icon, for code and API keys. Source: https://www.cult-ui.com/docs/components/copy-button ## Example ```tsx title="copy-button-demo.tsx" "use client" import { CopyButton } from "@/components/ui/copy-button" const sampleCode = "npm install @radix-ui/react-slot" const sampleUrl = "https://github.com/vercel/next.js" function CopyableRow({ value, children, }: { value: string children: React.ReactNode }) { return (
{children}
) } function CopyButtonDemo() { return (
{sampleCode} {sampleUrl}
) } export default CopyButtonDemo ``` Copy Button is a React button component for shadcn/ui, animated with Motion. Use it beside code snippets, API keys, or share links. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/copy-button ``` ### Manual **Install the required dependencies:** ```bash npm install @tabler/icons-react ``` **Install the button component:** ```bash npx shadcn@latest add button ``` **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/copy-button.json **Update the import paths to match your project setup.** --- # Cosmic Button > Animated link or button for React and shadcn/ui with a glowing cosmic gradient border that grows on hover, for landing page CTAs. Source: https://www.cult-ui.com/docs/components/cosmic-button ## Example ```tsx title="cosmic-button-demo.tsx" "use client" import { CosmicButton } from "@/components/ui/cosmic-button" export default function CosmicButtonDemo() { return (
Cosmic button goes brrr
) } ``` CosmicButton is a polymorphic React button and link component for shadcn/ui. Use it for landing page calls to action or launch announcements, rendering an anchor by default or a button through the as prop. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/cosmic-button ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/cosmic-button.json **Add the required keyframes and utilities to your global CSS (e.g. globals.css):** ```css @keyframes cosmic-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @keyframes cosmic-spin-slow { from { transform: rotate(0deg); } to { transform: rotate(-360deg); } } /* If using Tailwind v4 @theme: */ /* --animate-cosmic-spin: cosmic-spin 3s linear infinite; */ /* --animate-cosmic-spin-slow: cosmic-spin-slow 5s linear infinite; */ ``` **Update the import paths to match your project setup.** ## Usage As a link (default): ```tsx About ``` As a button: ```tsx Submit ``` --- # Cutout Card > Composable image card for React and shadcn/ui with cutout corner accents, inset labels, pins, and actions revealed on hover. Source: https://www.cult-ui.com/docs/components/cutout-card ## Example ```tsx title="cutout-card-demo.tsx" "use client" import { motion } from "motion/react" import { CutoutCard, CutoutCardAction, CutoutCardContent, CutoutCardFooter, CutoutCardImage, CutoutCardInsetLabel, CutoutCardMedia, CutoutCardOverlay, CutoutCardPin, cutoutCardSurfaceClassName, CutoutCorner, useCutoutContentStaggerVariants, } from "@/components/ui/cutout-card" // ============================================================================ // Demo — full-page showcase matching the original single-component layout // ============================================================================ function CutoutCardDemo() { const stagger = useCutoutContentStaggerVariants() return (
Featured New Alpine Adventures Discover breathtaking mountain landscapes and experience the serenity of nature at its finest.
Sarah Chen
5 min read
) } export default CutoutCardDemo ``` CutoutCard is a composable React card component for shadcn/ui, animated with Motion. Use it for portfolio grids, product galleries, or template showcases. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/cutout-card ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/cutout-card.json **Update the import paths to match your project setup.** ## Usage `CutoutCard` is a composable layout: wrap content in `CutoutCardMedia`, `CutoutCardContent`, and optional `CutoutCardInsetLabel`, `CutoutCardPin`, and `CutoutCardAction`. Use `CutoutCorner` inside labels or pins for the masked corner shape. `CutoutCardImage` wraps `next/image` with sensible defaults (`fill`, `sizes`). ```tsx import { CutoutCard, CutoutCardAction, CutoutCardContent, CutoutCardFooter, CutoutCardImage, CutoutCardInsetLabel, CutoutCardMedia, CutoutCardOverlay, CutoutCardPin, CutoutCorner, cutoutCardSurfaceClassName, useCutoutCard, useCutoutContentStaggerVariants, } from "@/components/ui/cutout-card"; ``` ```tsx Featured {/* title, body */} {/* e.g. button */} ``` --- # Direction Aware Tabs > Animated tabs for React and shadcn/ui that slide content left or right based on direction and smoothly resize to fit. Source: https://www.cult-ui.com/docs/components/direction-aware-tabs ## Example ```tsx title="direction-aware-tabs-demo.tsx" "use client" import { BgAnimateButton } from "../ui/bg-animate-button" import { DirectionAwareTabs } from "../ui/direction-aware-tabs" const DirectionAwareTabsDemo = ({}) => { const tabs = [ { id: 0, label: "ocean", content: (
Button Button Button
), }, { id: 1, label: "forest", content: (
Button Button Button
), }, { id: 2, label: "default", content: (
Button Button Button
), }, { id: 3, label: "sunset", content: (
Button Button Button
), }, ] return (
) } export default DirectionAwareTabsDemo ``` DirectionAwareTabs is a React tabs component for shadcn/ui built with Motion. Use it for settings panels, pricing toggles, or feature walkthroughs. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/direction-aware-tabs ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/direction-aware-tabs.json **Update the import paths to match your project setup.** ## Usage ```tsx const DirectionAwareTabsDemo = ({}) => { const tabs = [ { id: 0, label: "ocean", content: (
Button Button Button
), }, { id: 1, label: "forest", content: (
Button Button Button
), }, { id: 2, label: "default", content: (
Button Button Button
), }, { id: 3, label: "sunset", content: (
Button Button Button
), }, ]; return (
); }; export default DirectionAwareTabsDemo; ``` --- # Distorted Glass > Frosted glass divider for React and shadcn/ui using an SVG fractal noise displacement filter, for section transitions and headers. Source: https://www.cult-ui.com/docs/components/distorted-glass ## Example ```tsx title="distorted-glass-demo.tsx" "use client" import { useRef } from "react" import { motion, useScroll, useTransform } from "motion/react" import { DistortedGlass } from "@/components/ui/distorted-glass" export default function DistortedGlassDemo() { const containerRef = useRef(null) const { scrollYProgress } = useScroll({ target: containerRef, offset: ["start start", "end end"], }) // Transform values for parallax effects const parallaxY = useTransform(scrollYProgress, [0, 1], [0, -200]) const parallaxYSlow = useTransform(scrollYProgress, [0, 1], [0, -100]) const parallaxYFast = useTransform(scrollYProgress, [0, 1], [0, -300]) return (
{/* Fixed Distorted Glass Header */} {/* Scrollable Content Area - Content scrolls behind the glass */}
{/* Section 1: Large Moving Text - Easy to see distortion */}
DISTORTED GLASS
{/* Section 2: Grid of Moving Squares */}
{Array.from({ length: 64 }).map((_, i) => { const row = Math.floor(i / 8) const col = i % 8 const squareId = `square-${row}-${col}` return ( ) })}
{/* Section 3: Radial Circles */}
{Array.from({ length: 5 }).map((_, i) => { const size = 200 + i * 80 const circleId = `circle-${size}` return ( ) })}
{/* Section 4: Lines Pattern */}
{Array.from({ length: 20 }).map((_, i) => { const lineTop = i * 10 const lineId = `line-${lineTop}` return ( ) })}
{/* Final Info Section */}

About Distorted Glass

The DistortedGlass component uses SVG filters with fractal noise to create a unique glass morphism effect.

) } ``` DistortedGlass is an SVG filter component for React and shadcn/ui. Use it as a divider between landing page sections or under a sticky header to soften the transition. ## Installation ### CLI ```bash npx shadcn@latest add @cult-ui/distorted-glass ``` ### Manual **Copy and paste the following code into your project.** Full source: https://www.cult-ui.com/r/distorted-glass.json **Update the import paths to match your project setup.** ## Usage ```tsx import { DistortedGlass } from "@/components/ui/distorted-glass"; ``` ### Basic Usage ```tsx ``` ### Header Navigation Example Use the distorted glass effect to create a smooth transition between header and content: ```tsx
Logo

Hero Section

The distorted glass effect creates a beautiful transition between the header and content areas.

``` ### Content Overlay Example Create a frosted glass effect over content: ```tsx

Beautiful Background

Content visible through the glass effect

The distorted glass creates a frosted glass effect that provides visual separation while maintaining the connection to the content below.

``` ### Standalone Example Use as a decorative element between sections: ```tsx

Section Title

This is a content section with the distorted glass effect below it.

``` ## API Reference The `DistortedGlass` component is a presentational component with no props. It creates a glass morphism effect using SVG filters. ## Features - **Glass Morphism Effect**: Uses SVG filters with fractal noise to create a unique glass-like appearance - **Responsive**: Automatically hidden on smaller screens for optimal mobile experience - **Performance Optimized**: Lightweight implementation using CSS and SVG filters - **Visual Transitions**: Perfect for creating smooth transitions between sections - **No Dependencies**: Pure CSS and SVG, no external dependencies required ## How It Works The component uses an SVG filter with fractal noise (`feTurbulence`) combined with a displacement map (`feDisplacementMap`) to create the distorted glass effect. The effect is applied to a repeating radial gradient background to simulate the glass texture. ## Examples ### Between Card Sections ```tsx

Top Section

Content above the glass effect

Bottom Section

Content below the glass effect

``` ### With Gradient Background ```tsx

Background Content

Content section with glass transition

``` ## Notes - The component is hidden on screens smaller than `xl` breakpoint for better mobile experience - Use negative margin (`-mt-[17px]`) to overlap the glass effect with the content above - The effect works best with contrasting backgrounds - Ensure proper z-index layering when using with other elements --- # Dither Image > next/image wrapper for React and shadcn/ui that applies a CSS-only Bayer dither effect, with full-frame and partial masked reveals. Source: https://www.cult-ui.com/docs/components/dither-image ## Example ```tsx title="dither-image-demo.tsx" "use client" import { DitherImage, DitherImageCaption, DitherImageContent, DitherImageFrame, DitherImageOverlay, DitherImageReveal, type DitherRevealDirection, } from "@/components/ui/dither-image" const GHIBLI_STILLS: { alt: string; src: string }[] = Array.from( { length: 9 }, (_, i) => ({ src: `/images/gibli/gibli-${i + 1}.jpg`, alt: `Studio Ghibli-style still ${i + 1}, dithered`, }) ) const FRAME_SIZES = "(min-width: 1024px) 25vw, (min-width: 640px) 50vw, 90vw" /** Fixed box for `DitherImageReveal` + overlay demos (`size-56` → 14rem). */ const REVEAL_SIZES = "224px" const REVEAL_OVERLAY_VARIANTS: { direction: DitherRevealDirection from: number to: number label: string hint: string }[] = [ { direction: "r", from: 0, to: 65, label: "r", hint: "Clean left → dither right", }, { direction: "l", from: 0, to: 65, label: "l", hint: "Clean right → dither left", }, { direction: "t", from: 0, to: 65, label: "t", hint: "Clean top → dither bottom", }, { direction: "b", from: 0, to: 65, label: "b", hint: "Clean bottom → dither top", }, { direction: "tl-br", from: 0, to: 70, label: "tl-br", hint: "Diagonal (clean top-left)", }, { direction: "radial", from: 25, to: 75, label: "radial", hint: "Center clean, edges dither", }, ] export default function DitherImageDemo() { return (

DitherImage

CSS-only Bayer dither via{" "} dither-plugin . Compound:{" "} DitherImage {" "} wraps a{" "} DitherImageFrame {" "} (the dithered surface) containing a{" "} DitherImageContent , with an optional{" "} DitherImageCaption {" "} that stays outside the filter.

xs · 8px cell, defaults sm · 12px cell, defaults md · 16px cell, defaults lg · 20px cell, defaults
Color + soft{" "} · grayscale 0, contrast 80 Faded overlay{" "} · opacity 0.6, brightness 1.15 Circle · invert on dark {" "} · rounded-full, 12px cell, dots flip in dark mode

Reveal · DitherImageOverlay

Partial dither:{" "} DitherImageReveal {" "} stacks a masked{" "} DitherImageOverlay {" "} on the dithered frame.{" "} direction {" "} controls the gradient axis;{" "} from {" "} /{" "} to {" "} set mask stops (see component types for diagonals).

{REVEAL_OVERLAY_VARIANTS.map( ({ direction, from, to, label, hint }, i) => { const img = GHIBLI_STILLS[(7 + i) % GHIBLI_STILLS.length] return ( {label} {" "} · {hint} {" "} — {from}%→{to}% ) } )}
) } ``` Dither Image is a React image component for shadcn/ui built on next/image and the dither-plugin Tailwind utility. Use it for editorial photos, portfolio grids, or landing page heroes, including partial reveals that dither only part of an image. ## Installation The UI layer is a thin React wrapper; the visual effect comes from [`dither-plugin`](https://github.com/flornkm/dither-plugin). Install the package and import it in your Tailwind v4 stylesheet **alongside** `tailwindcss`. ### CLI ```bash npx shadcn@latest add @cult-ui/dither-image ``` After the CLI finishes, ensure `dither-plugin` is installed and `@import "dither-plugin";` is present in your global CSS (see Manual). ### Manual **Install `dither-plugin` and keep `next` available for `next/image`.** ```bash npm install dither-plugin ``` **In your Tailwind v4 entry CSS, register the plugin import.** ```css @import "tailwindcss"; @import "dither-plugin"; ``` **Copy the component into your project.** Full source: https://www.cult-ui.com/r/dither-image.json **Update import paths (`@/lib/utils`, `@/components/ui/...`) to match your app.** ## Usage ```tsx import { DitherImage, DitherImageCaption, DitherImageContent, DitherImageFrame, } from "@/components/ui/dither-image"; ``` ### Full-frame dither Wrap **`DitherImageContent`** in **`DitherImageFrame`**. The frame owns the `dither-*` utilities; captions belong in **`DitherImageCaption`** **outside** the frame so text is not blurred or grayscale-filtered. ```tsx Caption stays crisp outside the filtered surface. ``` ### Partial reveal (clean layer + dither) Use **`DitherImageReveal`** as a `relative overflow-hidden` stage. Stack **`DitherImageFrame`** (dithered) and **`DitherImageOverlay`** (same image, masked) as siblings. The overlay’s `direction`, `from`, and `to` props control the gradient mask. ```tsx import { DitherImageContent, DitherImageFrame, DitherImageOverlay, DitherImageReveal, } from "@/components/ui/dither-image"; export function DitherRevealExample() { return ( ); } ``` ### Dark mode and `invertOnDark` When **`invertOnDark`** is set on **`DitherImageFrame`**, the frame is wrapped so the dither reads correctly in dark mode while photo colors are counter-inverted on **`DitherImageContent`**. ### `next/image` and arbitrary sources For remote URLs, blobs, or data URLs, the image optimizer may need **`unoptimized`** or **`remotePatterns`** in `next.config`. The upload playground below uses the same pattern you can copy into product code. ## API | Export | Role | | --- | --- | | `DitherImage` | `
` wrapper; groups frame + caption without applying dither filters. | | `DitherImageFrame` | Dither surface: `size`, `aspectRatio`, `grayscale`, `contrast`, `brightness`, `blur`, `opacity`, `rounded`, `invertOnDark`, and CSS variables via `style`. | | `DitherImageContent` | `next/image` child; use `fill` + `object-cover` sizing inside the frame. | | `DitherImageReveal` | Relative, overflow-hidden stage for partial dither layouts. | | `DitherImageOverlay` | Absolutely positioned duplicate image with a gradient **`maskImage`**; props `direction`, `from`, `to`, `maskClassName`. | | `DitherImageCaption` | `
` with muted typography defaults. | **Types:** `DitherSize`, `DitherAspectRatio`, `DitherRevealDirection` are exported for props and demos. ## Notes - The dither class must sit on a **wrapper** around the media: the plugin paints with `::after`, which does not apply to raw `` / `