Skip to content
← components

Hardware Button

new

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.

color
arrow

press it — the glass sinks into the housing

Usage

example.tsx
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.

hardware-button.css
/* 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

proptypedefaultdescription
colorstring"#FFD400"Glass + glow color; the whole panel derives from it.
arrowbooleantrueShow the trailing ↗ arrow.
childrenReactNode"LETS VENTURE."Button label.
labelColorstring"#171200"Label / arrow color.
disabledbooleanfalseDims and desaturates; cancels press.
…propsButtonHTMLAttributesAny native button prop (onClick, type, aria-*).