←
Neumorphic Glow CTA

Neumorphic Glow CTA

Clay / Neumorphic

Authentic claymorphic and neumorphic elevated CTA button pair with glowing neon green badge depth, multi-tier elevation drop shadows, and plus-lighter bloom.

Interactive Playground & Studio

Live Controls
neumorphic-glow-cta.tsx
Hover or click to interact
Customizer
PRESETS & VARIATIONS

All Variants & Themes

Click to test interactive spring physics on every theme

Default Emerald Pillvariant="pill" neonPreset="emerald"

1:1 reference design with glowing emerald arrow badge and clay drop shadows.

UI Pirate Squirclevariant="squircle" neonPreset="uipirate"

Signature brand magma orange neumorphic clay squircle with neon glow badge.

Electric Cyan Pillvariant="pill" neonPreset="cyan"

Cyan optical underglow badge with specular bevel lip and obsidian chassis.

Neon Magenta Squirclevariant="squircle" neonPreset="magenta"

Vivid magenta bloom badge with dark cyberpunk clay squircle chassis.

Cyber Amber Pillvariant="pill" neonPreset="amber"

Warm golden amber indicator badge depth glow with dark slate body.

Neon Violet Squirclevariant="squircle" neonPreset="violet"

Ultraviolet neon arrow badge with 3D drop shadows and squircle frame.

Features & Physics

✓Authentic claymorphic multi-tier drop shadow stacks
✓Radiant glowing neon arrow indicator badge depth
✓Pill (Spec Node 14:642) & Squircle (Node 14:669) geometry
✓Interactive 60fps spring press micro-interactions

Code & Integration

Customized live with your active playground prop settings:

"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>
  );
}

Peer Dependencies

Requires Framer Motion and Tailwind CSS for spring physics and layout tokens:

npm install framer-motion clsx lucide-react tailwind-merge

API & Props Reference

PropTypeDefaultDescription
labelstring"Learn more"Primary button call-to-action text displayed on the cap.
variant"pill" | "squircle""pill"Physical rounded contour geometry (Node 14:642 vs 14:669).
theme"default" | "uipirate" | "dark" | "orange" | "cyberpunk" | "minimal""default"Color palette and clay surface lighting theme preset.
size"xs" | "sm" | "md" | "lg" | "xl""md"Controls button padding, font scale, and indicator dimensions.
neonPreset"emerald" | "uipirate" | "cyan" | "magenta" | "amber" | "violet" | "crimson""emerald"Neon glow preset for glowing indicator arrow circle.
onClick() => voidundefinedInteractive click callback event handler.