Library / Buttons

Arcade capsule

Price: Free

For a call to action. It stretches to fit its label and works as a link or a button. Add pale for white plastic and jet for black.

Insert coin
Two playersContinue

Send to Studio

Copy the CSS once and the markup wherever you need it. Set --c to change the color and --ink for the label; all the shading follows from those. It uses system fonts, so it needs nothing from us; set --btn-font to use your own. Covered by the Atomic Socket License.

React
<a className="arcade" href="/start" style={{ "--c": "#ee6a1e" } as React.CSSProperties}>
  <span className="arcade-dome">
    <span className="arcade-label">Insert coin</span>
  </span>
</a>
HTML
<a class="arcade" href="/start" style="--c:#ee6a1e">
  <span class="arcade-dome">
    <span class="arcade-label">Insert coin</span>
  </span>
</a>
CSS
/* Buttons by EELUMA: eeluma.com/library/buttons */
.keycap, .keycap *, .rocker, .rocker *, .arcade, .arcade * { box-sizing: border-box; }

/* Arcade button: a call to action, as a link or a button */
.arcade {
  --c: #e8431f; --ink: #fff;
  --c-hi: color-mix(in oklab, var(--c), white 22%);
  --c-lo: color-mix(in oklab, var(--c), black 24%);
  --c-wall: color-mix(in oklab, var(--c), black 38%);
  --c-groove: color-mix(in oklab, var(--c), black 62%);
  /* The collar: one glossy molded ring, the same plastic as the plunger, which sits high in it */
  position: relative; display: inline-block; padding: 10px 12px 16px; border: 0; border-radius: 999px;
  cursor: pointer; text-decoration: none; font: inherit; -webkit-tap-highlight-color: transparent;
  background: linear-gradient(155deg, var(--c-hi), var(--c) 34%, var(--c) 64%, var(--c-lo));
  box-shadow: inset 0 -2px 3px var(--c-wall), inset 0 1px 1px rgba(255,255,255,.4), 0 2px 2px rgba(0,0,0,.35), 0 9px 14px -5px rgba(0,0,0,.55);
}
.arcade::before { /* the sharp glint round the collar's upper left, a softer one lower right */
  content: ""; position: absolute; inset: 2px; border-radius: inherit; pointer-events: none;
  box-shadow: inset 2px 3px 2px -1px rgba(255,255,255,.72), inset -2px -3px 3px -2px rgba(255,255,255,.3);
}
.arcade-dome {
  position: relative; display: flex; align-items: center; justify-content: center; gap: .55em;
  min-height: 48px; padding: .8em 1.8em; overflow: hidden; border-radius: 999px;
  /* Satin, not gloss: light falls off softly across the top */
  background: radial-gradient(95% 120% at 36% 22%, var(--c-hi), var(--c) 62%, color-mix(in oklab, var(--c), black 10%));
  box-shadow: 0 0 0 1px var(--c-groove), 0 5px 0 0 var(--c-wall), 0 5px 0 1px var(--c-groove), 0 8px 6px rgba(0,0,0,.28), inset 0 1px 1px rgba(255,255,255,.5), inset 0 -2px 3px color-mix(in oklab, var(--c), black 18%);
  transition: transform 240ms cubic-bezier(.3,1.7,.5,1), box-shadow 240ms cubic-bezier(.3,1.7,.5,1), filter 150ms ease;
}
.arcade-dome::before { /* a blurry window in the satin */
  content: ""; position: absolute; left: 14%; top: 9%; width: 44%; height: 40%; border-radius: 999px; pointer-events: none;
  background: radial-gradient(closest-side, rgba(255,255,255,.26), rgba(255,255,255,0));
}
.arcade-label { position: relative; z-index: 1; color: var(--ink); font: 700 15px/1 var(--btn-font, system-ui, -apple-system, "Segoe UI", sans-serif); letter-spacing: .09em; text-transform: uppercase; white-space: nowrap; }
.arcade:hover .arcade-dome { filter: brightness(1.05); }
.arcade:active .arcade-dome {
  transform: translateY(4px);
  box-shadow: 0 0 0 1px var(--c-groove), 0 1px 0 0 var(--c-wall), 0 1px 0 1px var(--c-groove), 0 2px 2px rgba(0,0,0,.3), inset 0 1px 1px rgba(255,255,255,.3), inset 0 -2px 3px color-mix(in oklab, var(--c), black 18%);
  transition-duration: 45ms; transition-timing-function: ease-out;
}
.arcade:focus-visible { outline: 2px solid var(--btn-focus, #2d6cdf); outline-offset: 4px; }
/* Pale plastic needs its shadows pulled back, or it looks dirty */
.arcade.pale { --c-hi: #fff; --c-lo: color-mix(in oklab, var(--c), black 13%); --c-wall: color-mix(in oklab, var(--c), black 24%); --c-groove: color-mix(in oklab, var(--c), black 42%); }
/* Black plastic only shows its shape through the highlights */
.arcade.jet { --c-hi: color-mix(in oklab, var(--c), white 16%); --c-lo: #000; --c-wall: #000; --c-groove: #000; }
@media (prefers-reduced-motion: reduce) { .arcade-dome { transition: none; } }