Build Apps Without Code

Verified against v0 · 2026-07-31

Build a documented button, badge, and card variant system

A v0 brief for a Button, Badge, and Card variant system sharing one prop name and one semantic color union, with a real stated contrast ratio checked per variant instead of a general accessibility assurance.

v05 fillable variables

The prompt

Ready to copy — highlighted parts are example details you can swap.

Build a small, documented component variant system — Button, Badge, and Card — for a Next.js design system, using class-variance-authority (cva) with Tailwind CSS, so every variant is type-safe and the whole set reads as one consistent system rather than three components that each invented their own variant naming.

VARIANT SPEC
- Button variants: default, secondary, outline, ghost, destructive. Sizes: sm, default, lg, icon. Every Button must support a disabled state and a loading state (showing a spinner in place of, not alongside, the label) for each variant/size combination.
- Badge variants: default, secondary, destructive, outline — these should reuse the same semantic color names as the Button variants where they overlap (a "destructive" Button and a "destructive" Badge should be visually related, not coincidentally similar).
- Card variants: default (bordered), elevated (shadow, no border), flat (no border or shadow, for use inside another card), plus a consistent internal padding scale that Button and Badge components dropped inside a Card don't have to fight against with extra margin overrides.

CONSISTENCY RULES
Use the same prop name, variant, across all three components — never variant on Button and type or kind on Badge — so a developer who's learned one component's API can guess the others' correctly. Define the variant options as a single shared const array or union type where the semantic names overlap (destructive, for instance) rather than three separate, independently-typed unions that happen to contain the same strings today and can silently drift apart from each other during a future edit to just one of them.

ACCESSIBILITY PER VARIANT
For every variant/state combination — including disabled and each color variant — verify (state the actual contrast ratio, don't just assert it passes) that text stays at or above 4.5:1 contrast against its own background, and that a visible focus ring exists on every interactive variant, not just the default one. If a specific variant/state combination genuinely can't meet 4.5:1 with the given brand colors, name that combination explicitly rather than shipping it silently.

DOCUMENTATION
Alongside the components, generate a single documentation page rendering every variant of all three components side by side with its variant name labeled underneath, organized as one visual reference sheet — the equivalent of a Storybook page, but as one static route in this app, since not every project maintaining a small design system also runs Storybook.

CONSTRAINTS
Primary #4F46E5, Destructive #DC2626, Secondary #64748B — defined as CSS variables in globals.css, referenced through Tailwind, not hardcoded hex in component files Export each component's variant type so consuming code gets autocomplete and a compile error on an invalid variant name, not a silent fallback to some default style. Keep every variant's default export tree-shakeable, so a project using only the Button doesn't pull the Badge and Card source into its bundle as well.

Customize

Optional — swap in your own details for the highlighted parts above.

Why this works

The shared variant prop-name and shared semantic-union-type rule targets the actual, well-documented failure mode of design systems that grow component by component instead of as one coordinated pass. cva makes it trivially easy to define a fresh, locally-sensible variant union per component, and without an explicit cross-component consistency rule, a Button's variant type and a Badge's independently-defined type will start out matching by coincidence and drift the moment either one is edited later, since nothing actually links them together. Naming a single shared union closes that drift at the type level, not just by a naming convention someone has to remember to follow by hand. Requiring an actual stated contrast ratio per variant/state combination, rather than a general accessibility assurance, forces the check to happen at the level where color-contrast bugs actually live. A design system's "destructive" red might pass contrast comfortably as text on a white card background and fail badly as a Badge's own background color with white text sitting on top of it — contrast is a per-combination property of a specific foreground against a specific background, and a system-wide "make sure it's accessible" instruction tends to get checked once against the most obvious case and implicitly assumed to generalize to every other combination, when it simply doesn't. Generating one documentation route that renders every variant side by side addresses a specific and common cost of a variant system that only exists in code. Without a single visual reference, every consumer of this design system has to either read the source to discover what variants exist or guess from partial usage elsewhere in the app, and inconsistencies — a "ghost" Button that looks nothing like anyone would expect a ghost variant to look — go unnoticed until a designer happens to spot it in an already-shipped screen, rather than being immediately visible on one reference page a reviewer can check the whole system against in a single glance.

Verified against

v0 v0 by Vercel (Next.js + shadcn/ui default stack) · 2026-07-31

Changelog

  • 2026-07-31 Initial publish, verified against v0 with a shared cva variant union across Button, Badge, and Card and a per-variant contrast check.
Pairs with our free Colour Palette Generator — no signup, runs in your browser.

Need this built into your business?

If a prompt isn't enough — custom software, built and maintained for you — that's Scult's day job.

EXPLORE CUSTOM SOFTWARE
All Build Apps Without Code prompts

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY