Components · v0.1 · Contributor reference

3D Button mechanics

The 100-button gallery is built from 25 base mechanics × 4 hues. Each mechanic owns a distinct 3D verb — this page documents every one, the variation engine that keeps duplicates out, and the guidelines contributors follow when adding a new style.

Overview

Every button in /elements?category=Buttons composes two independent layers: a base mechanic (the visual verb — cube, aurora, ripple…) and a variation signature (perspective, timing, lighting, press feel). The mechanic gives the button its identity; the signature guarantees no two tiles animate identically.

Base mechanics
25
Hues per mechanic
4
Total buttons
100

Variation engine

The variation engine is a deterministic function of (styleKey, hueKey). It seeds an xmur3 hash and picks a discrete step across 15 axes. Combined space is on the order of 10¹² signatures — collisions are astronomically unlikely, and the runtime registry salts the input until unique if one ever occurs. That is the guarantee: duplicate button behavior is structurally impossible.

duration: 620ms · ease: cubic-bezier(0.16, 1, 0.3, 1)
rotX/Y: 18° / -14° · Z: 18px · scale: 1.06
halo: mix 48% · blur 52px · shadow 52/30px

Engine API

Every axis emitted as a CSS custom property. Consumers read them via arbitrary Tailwind values or plain var() — no JS on the hot path.

Prop
Type
Default
Description
  • perspective
    number
    720–1640 px
    Depth of the 3D scene wrapping the button.
  • rotX
    number
    4°–18°
    Hover X-axis rotation.
  • rotY
    number
    -4°–-18°
    Hover Y-axis rotation.
  • z
    number
    10–40 px
    Hover translateZ (comes toward viewer).
  • scale
    number
    1.02–1.12
    Hover uniform scale.
  • pressZ
    number
    -2 to -8 px
    Active-state Z push (sink).
  • duration
    number
    320–800 ms
    Transition duration for tilt, lift, and shadow.
  • ease
    string
    6 curves
    Cubic-bezier easing chosen per button.
  • originX / originY
    number
    % of tile
    transform-origin for the tilt pivot.
  • haloMix
    number
    18–56 %
    Accent-color tint applied to the hover halo.
  • haloBlur
    number
    40–100 px
    Halo bloom radius.
  • shadowSpread
    number
    40–88 px
    Drop-shadow blur radius under the tile.
  • shadowY
    number
    18–34 px
    Drop-shadow vertical offset.
  • liftY
    number
    2–10 px
    Idle → hover translateY.
tsx
// src/data/button-variants.ts
export function getVariant(id: string, styleKey: string, hueKey: string): Variant;
export function variantToCssVars(v: Variant): React.CSSProperties;
 
// Emits: --nova-perspective, --nova-rotx, --nova-roty, --nova-z,
// --nova-scale, --nova-press-z, --nova-duration, --nova-ease,
// --nova-origin, --nova-halo-mix, --nova-halo-blur,
// --nova-shadow-spread, --nova-shadow-y, --nova-lift-y

Mechanic catalog

Each mechanic below lists its distinct 3D verb, the triggers that drive it, GPU cost, and when to use / avoid it. Contributors adding a new mechanic must own a verb that no listed mechanic already owns.

Lift & Press

Solid Lift

lift

cheap GPU4 tiles

Hard stacked-plate shadow lifts on hover, sinks on press.

Mechanic
translateY + hard drop shadow shift
Triggers
hoveractive
Use for
Primary CTAs where tactile weight matters.
Avoid
Dense toolbars — the shadow footprint crowds neighbors.

Soft Press

press

cheap GPU4 tiles

Light neumorphic surface; active scale-down.

Mechanic
inset shadows + active scale(.97)
Triggers
active
Use for
Settings, preference toggles.
Avoid
Dark themes — neumorphism relies on light surfaces.

Depth Panel

depth

cheap GPU4 tiles

Dark inset panel with colored inner light.

Mechanic
inset colored highlight + drop shadow
Triggers
hover
Use for
'Deploy', 'Ship' — infra affordances.
Avoid
Light themes — inset light gets lost.

Glow & Halo

Neon Glow

neon

moderate GPU4 tiles

Dual inner/outer bloom + text halo.

Mechanic
layered box-shadow + text-shadow bloom
Triggers
hoveridle-loop
Use for
Dark UI accents, sci-fi / gaming.
Avoid
Long-form content — bloom competes with body text.

Halo Ring

halo

moderate GPU4 tiles

Radial blur bloom appears behind on hover.

Mechanic
outer radial-gradient + blur
Triggers
hover
Use for
Primary actions on dark surfaces.
Avoid
Compact grids — glow bleeds into neighbors.

Sweep & Reveal

Sheen

sheen

cheap GPU4 tiles

Diagonal white ribbon sweeps across on hover.

Mechanic
translateX(0 → 100%) gradient ribbon
Triggers
hover
Use for
Premium marketing buttons.
Avoid
High-frequency interactions — sweep feels ceremonial.

Slide Reveal

slide

cheap GPU4 tiles

Skewed color panel slides in, text inverts.

Mechanic
skewX translate + color swap
Triggers
hover
Use for
Editorial / uppercase 'ENTER' style CTAs.
Avoid
Sentence-case labels — feels stylistically off.

Liquid Fill

liquid

cheap GPU4 tiles

Fill height 0 → 100 % rises through the button.

Mechanic
height transition on inner plate
Triggers
hover
Use for
Progress-y CTAs ('Start', 'Fill up').
Avoid
As a destructive action — feels celebratory.

Ripple

ripple

cheap GPU4 tiles

Center-origin circle scales 0 → 224 px.

Mechanic
scale-up on centered circle
Triggers
hoveractive
Use for
Material-flavored surfaces.
Avoid
Cursor-tracked ripples elsewhere in the same view.

Structural

Glass

glass

heavy GPU4 tiles

Backdrop-blur pane with inset top highlight.

Mechanic
backdrop-filter + inset highlight
Triggers
hover
Use for
Over rich imagery or gradients.
Avoid
Flat backgrounds — the blur has nothing to sample.

Gradient Border

border

cheap GPU4 tiles

Conic-tinted 1.5 px frame around a dark plate.

Mechanic
1.5px gradient wrap + inner plate
Triggers
hover
Use for
Secondary actions that still need identity.
Avoid
Very small sizes — the border overwhelms the label.

Magnet Dots

dots

cheap GPU4 tiles

Dot-grid background with pulsing indicator.

Mechanic
radial dot-pattern + scale on dot
Triggers
hover
Use for
Technical / dev-tooling actions.
Avoid
Consumer flows — reads as engineering.

Corner Brackets

brackets

cheap GPU4 tiles

Four L-brackets grow on hover (HUD reticle).

Mechanic
corner pseudo-elements scale on hover
Triggers
hover
Use for
Terminals, technical dashboards.
Avoid
Marketing / editorial — reads as UI, not brand.

Punch Ghost

ghost

cheap GPU4 tiles

Dashed outline; interior fill scales & fades in.

Mechanic
inner fill scale(0.9 → 1) + opacity
Triggers
hover
Use for
Tertiary actions, empty-state CTAs.
Avoid
As the only CTA in a flow — reads as optional.

Command Key

cmd

cheap GPU4 tiles

Label + kbd chips with inset highlight.

Mechanic
border + inset light; kbd caps
Triggers
hover
Use for
Search triggers ('Search ⌘K').
Avoid
Contexts where the shortcut is not real.

True 3D

3D Cube

cube

moderate GPU4 tiles

Rotates on X/Y with hard side-shadow.

Mechanic
perspective + rotateX/rotateY
Triggers
hover
Use for
Playful marketing, empty states.
Avoid
Data-dense dashboards.

Isometric

iso

moderate GPU4 tiles

Persistent tilt with visible right + floor faces.

Mechanic
static rotateX/Y + 3D face polygons
Triggers
hover
Use for
Landing heroes, product tours.
Avoid
Anywhere the tilt breaks a strict grid.

Layered Stack

stack

cheap GPU4 tiles

Two z-stacked panels fan out on hover.

Mechanic
translateX/Y on stacked pseudo-layers
Triggers
hover
Use for
Card actions ('Open in new').
Avoid
Icon-only buttons — layers become invisible.

Card Flip

flipcard

moderate GPU4 tiles

Full 3D X-rotation revealing a back face.

Mechanic
rotateX(180°) + backface-visibility
Triggers
hover
Use for
Preview → Play, front / back detail flips.
Avoid
Text-heavy back faces — motion sickness risk.

Loop

Holographic

holo

moderate GPU4 tiles

Conic-gradient iridescence, slow shift.

Mechanic
conic-gradient + background-position drift
Triggers
idle-loop
Use for
Hero CTA, launch announcements.
Avoid
More than one per view — draws all attention.

Aurora

aurora

heavy GPU4 tiles

Spinning conic blur ring behind inset plate.

Mechanic
rotating conic gradient + blur
Triggers
idle-loop
Use for
AI features, generative CTAs.
Avoid
Reduced-motion contexts (auto-disabled).

Radar Ping

radar

moderate GPU4 tiles

Two staggered expanding ring pulses.

Mechanic
box-shadow expanding rings, offset delays
Triggers
idle-loop
Use for
Live status, 'Broadcasting', 'Recording'.
Avoid
Passive labels — pulse implies action needed.

Live Dots

dots3

cheap GPU4 tiles

Three staggered bouncing dots (0.15 s offsets).

Mechanic
translateY bounce with per-dot delay
Triggers
idle-loop
Use for
Streaming, live status, typing indicators.
Avoid
For 'save' actions — implies still working.

Content Swap

Text Flip

flip

cheap GPU4 tiles

Two labels translate on Y, marquee-style swap.

Mechanic
translateY of two stacked labels
Triggers
hover
Use for
Download → Go, Buy → Checkout affordances.
Avoid
When only one message is truthful at a time.

Metal

Bevel Metal

bevel

cheap GPU4 tiles

Vertical bevel gradient with inset highlight/shadow.

Mechanic
inset top-highlight + inset bottom-shade
Triggers
hover
Use for
Game UI, media playback.
Avoid
Minimal / editorial products — reads as skeuomorphic.

Adding a mechanic

Follow this recipe to contribute a 26th base style.

  1. 1Name the verb
    The verb must not overlap with an existing mechanic — audit the catalog above. If your idea is "another gradient button", it will not ship. Distinct motion verbs only.
  2. 2Add the style
    Append a StyleDef to src/data/buttons.tsx. Populate render(h) using the hue, and provide the paste-ready code(h) string.
  3. 3Register the mechanic
    Add an entry to src/data/button-mechanics.ts with a matching key, category, mechanic verb, triggers, GPU cost, usage, and avoid guidance. This page renders from that file — omit it and your button ships undocumented.
  4. 4Respect reduced motion
    All hover transforms and loop animations must live inside .nova-btn-tile-stage so the global reduced-motion rules in src/styles.css can freeze them. Loops must use a nova-btn-* keyframe name to be auto-paused.
  5. 5Verify uniqueness
    Load /elements?category=Buttons. The variation engine will assign a fresh 15-axis signature; the registry will assert it does not collide with the other 100 tiles.

Accessibility

  • • Tiles expose aria-label="Name — view code" and a visible focus-visible ring.
  • • Keyboard activation via Enter / Space mirrors click behavior.
  • • Color is never the sole differentiator — every mechanic has a shape / motion signature independent of hue.
  • • Loops respect reduced motion — nova-btn-holo, nova-btn-spin, nova-btn-ping, and nova-btn-bounce are auto-paused.

Contributor checklist

Before opening a PR

  • ✓ Verb is not already in the catalog
  • ✓ Entry added to button-mechanics.ts
  • ✓ Tile renders under all 4 hues
  • ✓ Reduced-motion path verified
  • ✓ Focus-visible ring intact
  • ✓ No new keyframes outside the nova-btn-* namespace

Automatic rejections

  • ✗ Recolored duplicate of an existing style
  • ✗ Hover transform outside .nova-btn-tile-stage
  • ✗ Motion-only state (color / shape must also change)
  • ✗ Uses inline animation without a namespaced keyframe
  • ✗ Contrast under WCAG AA on any of the 4 hues