Velocity UI
Loading…
Menu

Midnight Mercury Button

A premium liquid‑metal button with magnetic tilt, gooey mercury shapes, and specular lighting. Built for high‑impact actions and cinematic surfaces.

Installation

Add this component to your project using the CLI:

terminal
npx vui-registry-cli-v1 add midnight-mercury-button

Source Code

midnight-mercury-button.tsx
'use client'

import React, { useState } from 'react'
import { motion } from 'framer-motion'
import { cn } from '@/lib/utils'

type ObsidianCapsuleProps = Omit<
  React.ComponentPropsWithoutRef<typeof motion.button>,
  'children'
> & {
  children?: React.ReactNode
  className?: string
}

export function MidnightMercuryButton({ className, children, ...props }: ObsidianCapsuleProps) {
  const [isHovered, setIsHovered] = useState(false)

  return (
    <motion.button
      onMouseEnter={() => setIsHovered(true)}
      onMouseLeave={() => setIsHovered(false)}
      whileTap={{ scale: 0.97 }}
      className={cn(
        'group relative flex items-center justify-center px-12 py-4',
        'bg-card text-foreground rounded-full select-none cursor-pointer',
        'border border-border transition-all duration-500',
        'hover:border-border hover:shadow-[0_0_30px_-5px_hsl(var(--foreground)/0.15)]',
        className,
      )}
      {...props}
    >
      {/* 1. INTERNAL DOTTED BORDER (Precision detail) */}
      <div className="absolute inset-[3px] rounded-full border border-dashed border-border transition-colors duration-500 pointer-events-none" />

      {/* 2. GRADIENT FILL (Soft top-down lighting) */}
      <div className="absolute inset-0 rounded-full bg-gradient-to-b from-foreground/5 to-transparent pointer-events-none" />

      {/* 3. HOVER SHIMMER (The "Glass" effect) */}
      <div className="absolute inset-0 rounded-full overflow-hidden pointer-events-none">
        <motion.div
          animate={isHovered ? { x: ['-100%', '100%'] } : { x: '-100%' }}
          transition={{ duration: 1, ease: 'easeInOut' }}
          className="absolute inset-0 bg-gradient-to-r from-transparent via-foreground/5 to-transparent skew-x-[-20deg]"
        />
      </div>

      {/* 4. CONTENT */}
      <div className="relative z-10 flex items-center gap-4">
        <span className="text-[11px] font-bold uppercase tracking-[0.4em] text-muted-foreground group-hover:text-foreground transition-all duration-500">
          {children || 'System.Access'}
        </span>

        {/* Minimalist Arrow */}
        <div className="overflow-hidden w-3 h-3 flex items-center justify-center">
          <motion.div
            animate={{ x: isHovered ? [0, 20, -20, 0] : 0 }}
            transition={{ duration: 0.5, times: [0, 0.4, 0.41, 1] }}
          >
            <svg
              width="12"
              height="12"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="3"
            >
              <path d="M5 12h14m-7-7 7 7-7 7" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
          </motion.div>
        </div>
      </div>

      {/* 5. SOFT BLOOM (Glow behind the button) */}
      <div className="absolute inset-0 z-[-1] rounded-full bg-foreground/5 blur-xl opacity-0 group-hover:opacity-100 transition-opacity duration-700" />
    </motion.button>
  )
}

export default MidnightMercuryButton

Dependencies

  • framer-motion: latest

Props

Component property reference.

NameTypeDefaultDescription
classNamestring-Custom classes for the button container.
childrenReactNode-Label text; defaults to 'Initiate Flux'.
Context Worth Keeping In Orbit

Most components here are inspired by outstanding libraries and creators in the ecosystem. I don’t claim to be the original author — this is my space for learning, rebuilding, and understanding great work at a deeper level.

I’m still a student of the craft, constantly studying the best and translating what I learn through my own perspective. Every piece reflects curiosity, respect for the community, and small creative touches that feel true to me.

I’ve done my best to credit inspirations properly. If anything is missing or inaccurate, I truly appreciate a message so it can be corrected with care.