CSS
.btn-punch {
position: relative;
padding: 28px 32px 18px;
border: 1.5px solid #8a7d4a;
background: #e3d4a8;
color: #2a1d0e;
font-family: ui-monospace, monospace;
font-size: 14px; font-weight: 800;
letter-spacing: 0.28em;
cursor: pointer;
/* Iconic clipped top-right corner */
clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 0 100%);
box-shadow: 0 4px 12px rgba(58,36,16,0.3);
transition: transform 0.25s cubic-bezier(.3,1,.5,1);
text-align: center;
display: block;
--px: 0px; --py: 0px;
}
.btn-punch-header {
position: absolute;
top: 6px; left: 14px;
font-family: ui-monospace, monospace;
font-size: 8px; font-weight: 700;
color: #5a4520;
letter-spacing: 0.22em;
border-bottom: 1px solid #8a7d4a;
padding-bottom: 2px;
width: calc(100% - 36px);
text-align: left;
}
/* The hole grid: a single repeating background that draws columns of
1.5×4 mm rectangular holes — the visual signature of an 80-column card.
Two rows of perforations, evenly spaced, with ink-black holes. */
.btn-punch-grid {
position: absolute;
top: 22px; bottom: 4px;
left: 8px; right: 8px;
background-image:
radial-gradient(2px 4px at 50% 50%, #1a1a1a 99%, transparent 100%),
radial-gradient(2px 4px at 50% 50%, rgba(0,0,0,0.18) 99%, transparent 100%);
background-size: 14px 22px, 14px 22px;
background-position: 0 0, 0 11px;
background-repeat: repeat-x, repeat-x;
pointer-events: none;
opacity: 0.85;
-webkit-mask: linear-gradient(180deg,
#000 0 30%, transparent 30% 60%, #000 60% 100%);
mask: linear-gradient(180deg,
#000 0 30%, transparent 30% 60%, #000 60% 100%);
}
.btn-punch-text {
position: relative;
z-index: 1;
display: inline-block;
background: #e3d4a8;
padding: 2px 12px;
}
.btn-punch:hover { transform: translate(var(--px), var(--py)); } JS
document.querySelectorAll('.btn-punch').forEach(function(btn) {
btn.addEventListener('mousemove', function(e) {
var rect = btn.getBoundingClientRect();
var x = (e.clientX - rect.left - rect.width / 2) * 0.18;
var y = (e.clientY - rect.top - rect.height / 2) * 0.18;
btn.style.setProperty('--px', x + 'px');
btn.style.setProperty('--py', y + 'px');
});
btn.addEventListener('mouseleave', function() {
btn.style.setProperty('--px', '0px');
btn.style.setProperty('--py', '0px');
});
});