Hardware Button
A realistic physical button — a gunmetal bezel housing a recessed, illuminated glass panel with embossed text and a colored light bloom. Pure CSS; presses into its housing.
press it — the glass sinks into the housing
Usage
import { HardwareButton } from "~/components/buttons/hardware-button";<HardwareButton color="#FFD400" onClick={start}>LETS VENTURE.</HardwareButton>
How the hardware look works
It's three nested layers. The outer button is the chrome bezel: a steep gray gradient with inset bevels — a bright top edge, a dark bottom and right — so it reads as polished metal lit from above. Its padding is the bezel thickness.
Inside sits a black recessed well with its own deep inset shadow — that's the dark margin the glass appears to float in. Then the glass lens: a dark→bright→dark vertical gradient so it reads as a convex tube catching light through its middle. Two pseudo-elements sell the glass — a curved top sheen and a soft waterline reflection across the lower third — and an outer box-shadow bloom spills its color onto the surface. Press it and the whole thing drops 2px while the glass shadow deepens, sinking into the housing. Everything derives from one --hw-color.
/* 1. Chrome bezel — metal gradient, beveled insets, outer bloom */.hw-btn {--hw-color: #ffd400;padding: 12px; /* the bezel thickness */border-radius: 30px;background: linear-gradient(156deg, #cfcfd6, #8c8c93 8%, #4a4a50 28%, #232327 60%, #101013);box-shadow:0 30px 55px -16px rgba(0,0,0,.9),0 16px 70px -6px color-mix(in srgb, var(--hw-color) 45%, transparent), /* glow */inset 0 2px 1px rgba(255,255,255,.7), /* bright top edge */inset -2px 0 3px rgba(0,0,0,.6),inset 0 -4px 6px rgba(0,0,0,.75);}/* 2. Black recessed well — the dark margin the glass floats in */.hw-btn__well {padding: 13px;border-radius: 20px;background: linear-gradient(180deg, #050506, #121214);box-shadow: inset 0 4px 9px rgba(0,0,0,.9), inset 0 0 0 1px rgba(0,0,0,.9);}/* 3. Convex glass — dark→bright→dark = a lit tube */.hw-btn__glass {border-radius: 13px;padding: 20px 40px;background: linear-gradient(180deg,color-mix(in srgb,var(--hw-color) 72%,#000) 0%, var(--hw-color) 26%,color-mix(in srgb,var(--hw-color) 52%,#fff) 52%, var(--hw-color) 74%,color-mix(in srgb,var(--hw-color) 72%,#000) 100%);box-shadow: 0 0 26px color-mix(in srgb,var(--hw-color) 70%,transparent),inset 0 1px 0 rgba(255,255,255,.55);}.hw-btn__glass::before { /* curved top sheen */content:""; position:absolute; inset:1px 1px auto 1px; height:50%;border-radius: 12px 12px 50% 50% / 12px 12px 26px 26px;background: linear-gradient(180deg, rgba(255,255,255,.6), rgba(255,255,255,.05));}.hw-btn__glass::after { /* convex waterline reflection */content:""; position:absolute; left:7%; right:7%; bottom:13%; height:18%;border-radius:100%; filter:blur(1.5px);background: linear-gradient(180deg, rgba(255,255,255,.5), transparent);}/* 4. Press it into the housing */.hw-btn:active { transform: translateY(2px); }.hw-btn:active .hw-btn__glass { box-shadow: inset 0 6px 12px rgba(0,0,0,.6); }
Props
| prop | type | default | description |
|---|---|---|---|
| color | string | "#FFD400" | Glass + glow color; the whole panel derives from it. |
| arrow | boolean | true | Show the trailing ↗ arrow. |
| children | ReactNode | "LETS VENTURE." | Button label. |
| labelColor | string | "#171200" | Label / arrow color. |
| disabled | boolean | false | Dims and desaturates; cancels press. |
| …props | ButtonHTMLAttributes | — | Any native button prop (onClick, type, aria-*). |