Button
The action element. Follows the shadcn Button contract (default / destructive / outline / secondary / ghost / link) with one BTNG addition: an accent variant for the lime contrast-CTA.
Configurator
Every axis of the Button component in one view. Switch variant, size, state, and icon layout. The code block updates live.
<Button>
Button CTA
</Button>Default
Forest fill. The main action on any surface. All five sizes: xs (32) · sm (36) · default=md (40) · lg (44) · xl (48).
Accent
Lime fill. BTNG's contrast-CTA — pops against dark surfaces and against Forest siblings.
Secondary
Muted fill. Low-emphasis action that still needs a button affordance.
Outline
Bordered. Low-stakes actions on content-heavy surfaces.
Ghost
No border, no fill. For actions inside cards, toolbars, dense UI.
Destructive
Red. Only for actions that remove, cancel, or delete.
Link
Type-styled action with an underline on hover. Use when a button is needed semantically but visually sits inside prose.
Icon
Square button for icon-only actions. Pair with aria-label. Icons auto-size to 16px.
Loading
Pass the loading prop. The spinner replaces the leading slot, aria-busy flips on, and the button becomes non-interactive.
Disabled
Pointer events off, opacity 50% (shadcn convention).
Reasoning
BTNG has two brand colours. Forest is the primary. Lime is the contrast accent I reach for on hero CTAs, checkout buttons, and any action that needs to cut through a busy layout. Keeping both as first-class variants (default and accent) means the team doesn't have to reach for custom className overrides every time the design calls for a lime button.
Depth is a three-layer recipe ported from the Untitled UI reference: a whisper of outer drop, a 1px top highlight rim, and a 1px inner darker ring. Together they plant the button on the surface without pretending to be skeuomorphic.
Active state nudges 1px down. That tiny movement plants the button into the press and makes the click feel registered on touch devices while a network request is in flight.