Neumorphic Clay + Neon GlowTactile Micro-Interactions

Neumorphic Glow Tactile CTA Button

Multi-tier soft neumorphic clay button featuring dual convex lighting shadows, glowing neon arrow badge, and spring depth feedback.

preview.tsx
Interactions:0
Hover or click to interact

Customizer

PRESETS & VARIATIONS

All Variants Preview

Hover over buttons to trigger specular clay elevation & neon badge bloom

Neon Emerald PillneonPreset="emerald"
1:1 Figma Master design with glowing emerald arrow badge
UI Pirate SquircleneonPreset="uipirate"
Signature magma orange neumorphic clay squircle
Electric Cyan PillneonPreset="cyan"
Cyan optical underglow badge with specular bevel lip
Neon Magenta SquircleneonPreset="magenta"
Vivid magenta bloom badge with clay squircle chassis
Cyber Amber PillneonPreset="amber"
Warm golden amber indicator badge depth glow
Neon Violet SquircleneonPreset="violet"
Ultraviolet neon arrow badge with 3D drop shadows

Installation & Setup

Install required peer dependencies for Framer Motion spring physics:

npm install framer-motion clsx

Code & Integration

NeumorphicGlowCTA.tsx• Production Ready
"use client";

import React, { useState } from "react";
import { motion } from "framer-motion";

export type NeumorphicGlowShape = "pill" | "squircle";
export type NeumorphicGlowTheme = "default" | "dark" | "uipirate" | "orange" | "cyberpunk";
export type NeumorphicGlowSize = "xs" | "sm" | "md" | "lg" | "xl";

export interface NeumorphicGlowCTAProps {
  label?: string;
  shape?: NeumorphicGlowShape;
  theme?: NeumorphicGlowTheme;
  size?: NeumorphicGlowSize;
  onClick?: () => void;
  className?: string;
}

export function NeumorphicGlowCTA({
  label = "Learn more",
  shape = "pill",
  theme = "default",
  size = "md",
  onClick,
  className = "",
}: NeumorphicGlowCTAProps) {
  const [isHovered, setIsHovered] = useState(false);
  const [isPressed, setIsPressed] = useState(false);

  const themeConfig = {
    default: {
      bg: "bg-[#E6E8ED]",
      border: "border-white/80",
      text: "text-[#3D4450]",
      badgeBg: "bg-[#CBF0CD]",
      arrowColor: "#49C33E",
      badgeGlow: "rgba(73, 195, 62, 0.4)",
    },
    uipirate: {
      bg: "bg-[#181614]",
      border: "border-orange-500/20",
      text: "text-[#FAF5F0]",
      badgeBg: "bg-[#FFEDD5]",
      arrowColor: "#FF5B04",
      badgeGlow: "rgba(255, 91, 4, 0.5)",
    },
    dark: {
      bg: "bg-[#16181F]",
      border: "border-cyan-500/20",
      text: "text-[#E0F2FE]",
      badgeBg: "bg-[#C7F5F8]",
      arrowColor: "#06B6D4",
      badgeGlow: "rgba(6, 182, 212, 0.4)",
    },
  }[theme as "default" | "uipirate" | "dark"] || {
    bg: "bg-[#E6E8ED]",
    border: "border-white/80",
    text: "text-[#3D4450]",
    badgeBg: "bg-[#CBF0CD]",
    arrowColor: "#49C33E",
    badgeGlow: "rgba(73, 195, 62, 0.4)",
  };

  const rounded = shape === "pill" ? "rounded-full" : "rounded-2xl";

  return (
    <motion.button
      type="button"
      onClick={onClick}
      onMouseEnter={() => setIsHovered(true)}
      onMouseLeave={() => {
        setIsHovered(false);
        setIsPressed(false);
      }}
      onMouseDown={() => setIsPressed(true)}
      onMouseUp={() => setIsPressed(false)}
      animate={{
        y: isPressed ? 2 : isHovered ? -3 : 0,
        scale: isPressed ? 0.98 : 1,
      }}
      transition={{ type: "spring", stiffness: 450, damping: 25 }}
      className={`relative flex items-center justify-between gap-4 px-6 py-3.5 ${rounded} ${themeConfig.bg} ${themeConfig.border} border shadow-lg ${themeConfig.text} font-bold text-sm cursor-pointer select-none focus:outline-none ${className}`}
    >
      <span>{label}</span>

      {/* Radiant Glowing Neon Arrow Knob */}
      <div
        className={`relative w-8 h-8 rounded-full ${themeConfig.badgeBg} flex items-center justify-center`}
        style={{
          boxShadow: `0 0 12px ${themeConfig.badgeGlow}`,
        }}
      >
        <svg
          className="w-4 h-4 transition-transform duration-300"
          style={{ color: themeConfig.arrowColor }}
          fill="none"
          stroke="currentColor"
          viewBox="0 0 24 24"
        >
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M9 5l7 7-7 7" />
        </svg>
      </div>
    </motion.button>
  );
}

Component API Reference

PropTypeDefaultDescription
labelstring"Learn more"Text displayed on the button cap
shape"pill" | "squircle""pill"Physical rounded contour geometry
themeNeumorphicGlowTheme"default"Color scheme theme preset
size"xs" | "sm" | "md" | "lg" | "xl""md"Scale multiplier
onClick() => voidundefinedClick callback event handler

Personalized Help

Struggling with neumorphic buttons or modern clay UI components? Let's talk about your product.

UI Pirate is a product design & development agency trusted by 50+ SaaS founders and enterprise teams across the US, UK & beyond. Tell us what you need.