Oblivion
Oblivion
Docs
Go back
Component by
OV
Oblivion
Press Start
PWR_ON
TSX
arcade-button
"use client"

import React, { useState } from "react"
import { cn } from "@/lib/utils"

export const componentMeta = {
  name: "Arcade Button",
  description: "An incredibly tactile physical switch with extreme depth. Feels exactly like pressing a heavy mechanical arcade button.",
  props: {
    className: { type: "string", description: "Additional CSS classes", default: '""' }
  }
}

export default function ArcadeButton({ className }: { className?: string }) {
  const [pressed, setPressed] = useState(false)

  return (
    <div className={cn("flex flex-col items-center justify-center p-12 gap-8", className)}>
       
       <div className="text-zinc-500 text-sm font-semibold tracking-[0.2em] uppercase">Press Start</div>

       {/* Bezel / Base of the button */}
       <div className="relative w-52 h-52 rounded-full bg-gradient-to-b from-zinc-700 to-zinc-900 flex items-center justify-center shadow-[0_15px_30px_rgba(0,0,0,0.6),inset_0_2px_3px_rgba(255,255,255,0.2)] border-2 border-zinc-950 select-none">
          
          {/* Inner plastic trench */}
          <div className="relative w-40 h-40 rounded-full bg-zinc-950 flex items-center justify-center shadow-[inset_0_12px_24px_rgba(0,0,0,0.9)] overflow-hidden">
              
              {/* Highlight rim in the trench */}
              <div className="absolute inset-0 rounded-full border-[6px] border-zinc-900 blur-[2px]" />

              {/* Actual Red Button Cap */}
              <button
                onMouseDown={() => setPressed(true)}
                onMouseUp={() => setPressed(false)}
                onMouseLeave={() => setPressed(false)}
                onTouchStart={() => setPressed(true)}
                onTouchEnd={() => setPressed(false)}
                className={cn(
                  "relative w-32 h-32 rounded-full transition-all duration-[50ms] focus:outline-none flex items-center justify-center group overflow-hidden border-2",
                  pressed 
                    ? "bg-red-700 border-red-800 translate-y-3 shadow-[inset_0_20px_30px_rgba(0,0,0,0.7)]" 
                    : "bg-red-500 border-red-400 translate-y-[-8px] shadow-[0_14px_0_#7f1d1d,0_24px_24px_rgba(0,0,0,0.7),inset_0_8px_16px_rgba(255,255,255,0.4)]"
                )}
              >
                  {/* Glassy dome glare - top */}
                  <div className={cn(
                    "absolute top-2 left-1/2 -translate-x-1/2 w-[80%] h-[30%] bg-white/40 rounded-[50%] blur-[2px] transition-opacity",
                    pressed ? "opacity-20" : "opacity-80"
                  )} />

                  {/* Glassy dome glare - side */}
                  <div className="absolute right-3 top-1/2 -translate-y-1/2 w-2 h-[60%] bg-white/20 rounded-[50%] blur-[3px]" />

                  {/* Internal button text/icon (optional, but adds to the vibe) */}
                  <div className={cn(
                      "text-white font-black tracking-widest text-2xl drop-shadow-[0_2px_2px_rgba(0,0,0,0.5)] transition-transform",
                      pressed ? "scale-95 text-red-100" : "scale-100"
                  )}>
                      P1
                  </div>
              </button>
          </div>
       </div>

       {/* Optional status light to visualize the output */}
       <div className="flex items-center gap-3">
          <div className={cn(
            "w-3 h-3 rounded-full transition-colors duration-75 shadow-sm",
            pressed ? "bg-green-500 shadow-[0_0_15px_rgba(34,197,94,0.8)]" : "bg-zinc-800 shadow-[inset_0_2px_4px_rgba(0,0,0,0.5)]"
          )} />
          <span className="text-zinc-600 text-xs font-mono font-bold">PWR_ON</span>
       </div>

    </div>
  )
}
Save to favoritesCopy to Figma
React

Arcade Button

An incredibly tactile physical switch with extreme depth. Feels exactly like pressing a heavy mechanical arcade button.

Installation

$ npx @cosmoo/oblivion add arcade-button
Dependenciesnpm install

Usage Example

tsx
import ArcadeButton from "@/components/oblivion/arcade-button"

export default function Demo() {
  return (
    <div className="p-10 flex justify-center">
      <ArcadeButton />
    </div>
  )
}