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.
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.
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.
perspectivenumber720–1640 pxDepth of the 3D scene wrapping the button.rotXnumber4°–18°Hover X-axis rotation.rotYnumber-4°–-18°Hover Y-axis rotation.znumber10–40 pxHover translateZ (comes toward viewer).scalenumber1.02–1.12Hover uniform scale.pressZnumber-2 to -8 pxActive-state Z push (sink).durationnumber320–800 msTransition duration for tilt, lift, and shadow.easestring6 curvesCubic-bezier easing chosen per button.originX / originYnumber% of tiletransform-origin for the tilt pivot.haloMixnumber18–56 %Accent-color tint applied to the hover halo.haloBlurnumber40–100 pxHalo bloom radius.shadowSpreadnumber40–88 pxDrop-shadow blur radius under the tile.shadowYnumber18–34 pxDrop-shadow vertical offset.liftYnumber2–10 pxIdle → hover translateY.
// src/data/button-variants.tsexport 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-yMechanic 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.
- 1Name the verbThe 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.
- 2Add the styleAppend a
StyleDeftosrc/data/buttons.tsx. Populaterender(h)using the hue, and provide the paste-readycode(h)string. - 3Register the mechanicAdd an entry to
src/data/button-mechanics.tswith a matchingkey, category, mechanic verb, triggers, GPU cost, usage, and avoid guidance. This page renders from that file — omit it and your button ships undocumented. - 4Respect reduced motionAll hover transforms and loop animations must live inside
.nova-btn-tile-stageso the global reduced-motion rules insrc/styles.csscan freeze them. Loops must use anova-btn-*keyframe name to be auto-paused. - 5Verify uniquenessLoad
/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, andnova-btn-bounceare 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
animationwithout a namespaced keyframe - ✗ Contrast under WCAG AA on any of the 4 hues