# Step sequencer checkboxes

> Eight drum machine pads, each a real checkbox, with a running step light that flashes the pads you switched on.

- Category: [Checkboxes](https://library.aimran.es/components/checkboxes)
- Built with: HTML + CSS
- Live editor: https://library.aimran.es/blocks/uv-chk-stepseq
- Library: AIMRAN Library (https://library.aimran.es), free, no sign-up, by Aimran Oukham

## Where to use it

Inspired by classic drum machines, this block turns eight checkboxes into the step pads of a sequencer. Each pad latches down and lights its red LED when active, while a running light sweeps across the row and makes the active steps flash in time. It works with keyboard and screen readers, and fits music apps, creative tools and playful settings panels.

The main color paints the first four pads and the secondary the last four, like the colour groups on real hardware. Rename the legend for each instrument and stack several rows to build a full pattern editor.

## Code

### HTML

```html
<fieldset class="uvq02-seq"><legend>Kick</legend><div class="pd"><label style="--i:0"><input type="checkbox" aria-label="Step 1"><i></i></label><label style="--i:1"><input type="checkbox" aria-label="Step 2"><i></i></label><label style="--i:2"><input type="checkbox" aria-label="Step 3"><i></i></label><label style="--i:3"><input type="checkbox" aria-label="Step 4"><i></i></label><label style="--i:4"><input type="checkbox" aria-label="Step 5"><i></i></label><label style="--i:5"><input type="checkbox" aria-label="Step 6"><i></i></label><label style="--i:6"><input type="checkbox" aria-label="Step 7"><i></i></label><label style="--i:7"><input type="checkbox" aria-label="Step 8"><i></i></label></div></fieldset>
```

### CSS

```css
.uvq02-seq {
  --c1: #ff5a1f;
  --c2: #f2cf3d;
  --s: 16px;
  /* tamaño */
  --k: 1;
  /* velocidad */
  --fg: #1d1d1f;
  /* texto */
  --bg: #f5f5f7;
  /* fondo */
}

.uvq02-seq {
  font-family: -apple-system,BlinkMacSystemFont,"SF Pro Text","Inter",system-ui,sans-serif;
  font-size: var(--s);
  color: var(--fg);
  -webkit-tap-highlight-color: transparent;
  margin: 0;
  padding: .9em 1em 1.1em;
  border: 0;
  min-inline-size: 0;
  border-radius: .7em;
  background: linear-gradient(#36322c,#24211d);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.09),0 1em 2em -1.2em rgba(0,0,0,.7);
  color: #e9dfc8;
}

.uvq02-seq legend {
  float: left;
  width: 100%;
  padding: 0;
  margin: 0 0 .8em;
  font-family: ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  font-size: .7em;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: #d9cdb2;
}

.uvq02-seq .pd {
  clear: both;
  display: grid;
  grid-template-columns: repeat(8,1.7em);
  gap: .45em;
}

.uvq02-seq label {
  --pc: var(--c1);
  position: relative;
  display: grid;
  justify-items: center;
  gap: .45em;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.uvq02-seq label:nth-child(n+5) {
  --pc: var(--c2);
}

.uvq02-seq input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  pointer-events: none;
}

.uvq02-seq label::before,.uvq02-seq label::after {
  content: "";
  grid-area: 1/1;
  width: .42em;
  height: .42em;
  border-radius: 50%;
}

.uvq02-seq label::before {
  background: #4d1a12;
  box-shadow: inset 0 .05em .1em rgba(0,0,0,.6);
  transition: background calc(0.15s / var(--k)) cubic-bezier(.25,.1,.25,1),box-shadow calc(0.15s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq02-seq label::after {
  background: #ffe1d6;
  box-shadow: 0 0 .4em #ff8a66;
  opacity: 0;
  animation: uvq02-seq calc(2s / var(--k)) linear calc(var(--i) * calc(0.25s / var(--k))) infinite;
}

.uvq02-seq i {
  grid-area: 2/1;
  position: relative;
  width: 1.7em;
  height: 2.3em;
  border-radius: .3em;
  background: linear-gradient(180deg,rgba(255,255,255,.3),transparent 45%),var(--pc);
  box-shadow: inset 0 -.2em 0 rgba(0,0,0,.22),0 .22em 0 color-mix(in srgb,var(--pc) 55%,#000),0 .4em .5em rgba(0,0,0,.45);
  transition: transform calc(0.1s / var(--k)) cubic-bezier(.25,.1,.25,1),box-shadow calc(0.1s / var(--k)) cubic-bezier(.25,.1,.25,1),filter calc(0.2s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq02-seq i::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: rgba(255,255,255,.6);
  opacity: 0;
  visibility: hidden;
  animation: uvq02-seq calc(2s / var(--k)) linear calc(var(--i) * calc(0.25s / var(--k))) infinite;
}

.uvq02-seq label:hover i {
  filter: brightness(1.1);
}

.uvq02-seq label:active i {
  transform: translateY(.2em);
  box-shadow: inset 0 -.1em 0 rgba(0,0,0,.22),0 .02em 0 color-mix(in srgb,var(--pc) 55%,#000),0 .1em .2em rgba(0,0,0,.45);
}

.uvq02-seq input:checked + i {
  transform: translateY(.12em);
  box-shadow: inset 0 -.12em 0 rgba(0,0,0,.22),0 .1em 0 color-mix(in srgb,var(--pc) 55%,#000),0 .2em .3em rgba(0,0,0,.45);
}

.uvq02-seq input:checked + i::after {
  visibility: visible;
}

.uvq02-seq label:has(input:checked)::before {
  background: #ff3b1f;
  box-shadow: 0 0 .5em #ff3b1f;
}

.uvq02-seq input:focus-visible + i {
  outline: 2px solid #f6e7c8;
  outline-offset: 3px;
}

@keyframes uvq02-seq {
  0%,11% {
    opacity: 1;
  }
  12.5%,100% {
    opacity: 0;
  }
}

@media (prefers-reduced-motion:reduce) {
  .uvq02-seq,.uvq02-seq *,.uvq02-seq *::before,.uvq02-seq *::after {
    animation-duration: .01ms!important;
    animation-iteration-count: 1!important;
    transition-duration: .01ms!important;
  }
}
```

### React

```tsx
import type { CSSProperties } from "react";

const css = `
.uvq02-seq {
  font-family: -apple-system,BlinkMacSystemFont,"SF Pro Text","Inter",system-ui,sans-serif;
  font-size: var(--s);
  color: var(--fg);
  -webkit-tap-highlight-color: transparent;
  margin: 0;
  padding: .9em 1em 1.1em;
  border: 0;
  min-inline-size: 0;
  border-radius: .7em;
  background: linear-gradient(#36322c,#24211d);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.09),0 1em 2em -1.2em rgba(0,0,0,.7);
  color: #e9dfc8;
}

.uvq02-seq legend {
  float: left;
  width: 100%;
  padding: 0;
  margin: 0 0 .8em;
  font-family: ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  font-size: .7em;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: #d9cdb2;
}

.uvq02-seq .pd {
  clear: both;
  display: grid;
  grid-template-columns: repeat(8,1.7em);
  gap: .45em;
}

.uvq02-seq label {
  --pc: var(--c1);
  position: relative;
  display: grid;
  justify-items: center;
  gap: .45em;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.uvq02-seq label:nth-child(n+5) {
  --pc: var(--c2);
}

.uvq02-seq input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  pointer-events: none;
}

.uvq02-seq label::before,.uvq02-seq label::after {
  content: "";
  grid-area: 1/1;
  width: .42em;
  height: .42em;
  border-radius: 50%;
}

.uvq02-seq label::before {
  background: #4d1a12;
  box-shadow: inset 0 .05em .1em rgba(0,0,0,.6);
  transition: background calc(0.15s / var(--k)) cubic-bezier(.25,.1,.25,1),box-shadow calc(0.15s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq02-seq label::after {
  background: #ffe1d6;
  box-shadow: 0 0 .4em #ff8a66;
  opacity: 0;
  animation: uvq02-seq calc(2s / var(--k)) linear calc(var(--i) * calc(0.25s / var(--k))) infinite;
}

.uvq02-seq i {
  grid-area: 2/1;
  position: relative;
  width: 1.7em;
  height: 2.3em;
  border-radius: .3em;
  background: linear-gradient(180deg,rgba(255,255,255,.3),transparent 45%),var(--pc);
  box-shadow: inset 0 -.2em 0 rgba(0,0,0,.22),0 .22em 0 color-mix(in srgb,var(--pc) 55%,#000),0 .4em .5em rgba(0,0,0,.45);
  transition: transform calc(0.1s / var(--k)) cubic-bezier(.25,.1,.25,1),box-shadow calc(0.1s / var(--k)) cubic-bezier(.25,.1,.25,1),filter calc(0.2s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq02-seq i::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: rgba(255,255,255,.6);
  opacity: 0;
  visibility: hidden;
  animation: uvq02-seq calc(2s / var(--k)) linear calc(var(--i) * calc(0.25s / var(--k))) infinite;
}

.uvq02-seq label:hover i {
  filter: brightness(1.1);
}

.uvq02-seq label:active i {
  transform: translateY(.2em);
  box-shadow: inset 0 -.1em 0 rgba(0,0,0,.22),0 .02em 0 color-mix(in srgb,var(--pc) 55%,#000),0 .1em .2em rgba(0,0,0,.45);
}

.uvq02-seq input:checked + i {
  transform: translateY(.12em);
  box-shadow: inset 0 -.12em 0 rgba(0,0,0,.22),0 .1em 0 color-mix(in srgb,var(--pc) 55%,#000),0 .2em .3em rgba(0,0,0,.45);
}

.uvq02-seq input:checked + i::after {
  visibility: visible;
}

.uvq02-seq label:has(input:checked)::before {
  background: #ff3b1f;
  box-shadow: 0 0 .5em #ff3b1f;
}

.uvq02-seq input:focus-visible + i {
  outline: 2px solid #f6e7c8;
  outline-offset: 3px;
}

@keyframes uvq02-seq {
  0%,11% {
    opacity: 1;
  }
  12.5%,100% {
    opacity: 0;
  }
}

@media (prefers-reduced-motion:reduce) {
  .uvq02-seq,.uvq02-seq *,.uvq02-seq *::before,.uvq02-seq *::after {
    animation-duration: .01ms!important;
    animation-iteration-count: 1!important;
    transition-duration: .01ms!important;
  }
}
`;

export default function ChkStepseq() {
  return (
    <>
      <style>{css}</style>
      <div
        style={{
          "--c1": "#ff5a1f",
          "--c2": "#f2cf3d",
          "--s": "16px",
          "--k": "1",
          "--fg": "#1d1d1f",
          "--bg": "#f5f5f7",
        } as CSSProperties}
      >
        <fieldset className="uvq02-seq"><legend>Kick</legend><div className="pd"><label style={{ "--i": "0" } as CSSProperties}><input type="checkbox" aria-label="Step 1" /><i></i></label><label style={{ "--i": "1" } as CSSProperties}><input type="checkbox" aria-label="Step 2" /><i></i></label><label style={{ "--i": "2" } as CSSProperties}><input type="checkbox" aria-label="Step 3" /><i></i></label><label style={{ "--i": "3" } as CSSProperties}><input type="checkbox" aria-label="Step 4" /><i></i></label><label style={{ "--i": "4" } as CSSProperties}><input type="checkbox" aria-label="Step 5" /><i></i></label><label style={{ "--i": "5" } as CSSProperties}><input type="checkbox" aria-label="Step 6" /><i></i></label><label style={{ "--i": "6" } as CSSProperties}><input type="checkbox" aria-label="Step 7" /><i></i></label><label style={{ "--i": "7" } as CSSProperties}><input type="checkbox" aria-label="Step 8" /><i></i></label></div></fieldset>
      </div>
    </>
  );
}
```

## Prompt for AI assistants

Paste this into ChatGPT, Claude, Cursor, v0 or Lovable to adapt the block to your stack (Tailwind, Vue, Svelte…):

````text
I want to add the “Step sequencer checkboxes” block (Checkboxes) from AIMRAN Library to my project.

## What it is
Eight drum machine pads, each a real checkbox, with a running step light that flashes the pads you switched on.

## Chosen settings
- Main color: #ff5a1f
- Secondary color: #f2cf3d
- Size: 16px (from 12 to 24px)
- Speed: 1x (from 0.5 to 2x)
- Text: "Bombo"

## What I need
1. Add it to my project with the same look and animation as the reference code: same sizes, colours, radii, shadows, timings and easing.
2. It is built with plain HTML and CSS (the reference wraps it in a React component with its CSS). If my project uses something else (Vue, Svelte, Astro, plain HTML…), translate it without losing any behaviour. If I use Tailwind, turn the styles into classes; if not, keep the CSS in its own file.
3. Expose the settings above as props (or CSS variables) with those values as defaults.
4. Make it work well on phones: nothing that depends only on hover, touch targets of at least 44 px and no overflow on 320 px screens.
5. Make it look right in light and dark mode.
6. Keep it accessible: semantic HTML, roles and aria-* where needed, visible focus and keyboard support.
7. Respect prefers-reduced-motion: with reduced motion, no big animations but the same end result.

## Reference code
```tsx
import type { CSSProperties } from "react";

const css = `
.uvq02-seq {
  font-family: -apple-system,BlinkMacSystemFont,"SF Pro Text","Inter",system-ui,sans-serif;
  font-size: var(--s);
  color: var(--fg);
  -webkit-tap-highlight-color: transparent;
  margin: 0;
  padding: .9em 1em 1.1em;
  border: 0;
  min-inline-size: 0;
  border-radius: .7em;
  background: linear-gradient(#36322c,#24211d);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.09),0 1em 2em -1.2em rgba(0,0,0,.7);
  color: #e9dfc8;
}

.uvq02-seq legend {
  float: left;
  width: 100%;
  padding: 0;
  margin: 0 0 .8em;
  font-family: ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  font-size: .7em;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: #d9cdb2;
}

.uvq02-seq .pd {
  clear: both;
  display: grid;
  grid-template-columns: repeat(8,1.7em);
  gap: .45em;
}

.uvq02-seq label {
  --pc: var(--c1);
  position: relative;
  display: grid;
  justify-items: center;
  gap: .45em;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.uvq02-seq label:nth-child(n+5) {
  --pc: var(--c2);
}

.uvq02-seq input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  pointer-events: none;
}

.uvq02-seq label::before,.uvq02-seq label::after {
  content: "";
  grid-area: 1/1;
  width: .42em;
  height: .42em;
  border-radius: 50%;
}

.uvq02-seq label::before {
  background: #4d1a12;
  box-shadow: inset 0 .05em .1em rgba(0,0,0,.6);
  transition: background calc(0.15s / var(--k)) cubic-bezier(.25,.1,.25,1),box-shadow calc(0.15s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq02-seq label::after {
  background: #ffe1d6;
  box-shadow: 0 0 .4em #ff8a66;
  opacity: 0;
  animation: uvq02-seq calc(2s / var(--k)) linear calc(var(--i) * calc(0.25s / var(--k))) infinite;
}

.uvq02-seq i {
  grid-area: 2/1;
  position: relative;
  width: 1.7em;
  height: 2.3em;
  border-radius: .3em;
  background: linear-gradient(180deg,rgba(255,255,255,.3),transparent 45%),var(--pc);
  box-shadow: inset 0 -.2em 0 rgba(0,0,0,.22),0 .22em 0 color-mix(in srgb,var(--pc) 55%,#000),0 .4em .5em rgba(0,0,0,.45);
  transition: transform calc(0.1s / var(--k)) cubic-bezier(.25,.1,.25,1),box-shadow calc(0.1s / var(--k)) cubic-bezier(.25,.1,.25,1),filter calc(0.2s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq02-seq i::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: rgba(255,255,255,.6);
  opacity: 0;
  visibility: hidden;
  animation: uvq02-seq calc(2s / var(--k)) linear calc(var(--i) * calc(0.25s / var(--k))) infinite;
}

.uvq02-seq label:hover i {
  filter: brightness(1.1);
}

.uvq02-seq label:active i {
  transform: translateY(.2em);
  box-shadow: inset 0 -.1em 0 rgba(0,0,0,.22),0 .02em 0 color-mix(in srgb,var(--pc) 55%,#000),0 .1em .2em rgba(0,0,0,.45);
}

.uvq02-seq input:checked + i {
  transform: translateY(.12em);
  box-shadow: inset 0 -.12em 0 rgba(0,0,0,.22),0 .1em 0 color-mix(in srgb,var(--pc) 55%,#000),0 .2em .3em rgba(0,0,0,.45);
}

.uvq02-seq input:checked + i::after {
  visibility: visible;
}

.uvq02-seq label:has(input:checked)::before {
  background: #ff3b1f;
  box-shadow: 0 0 .5em #ff3b1f;
}

.uvq02-seq input:focus-visible + i {
  outline: 2px solid #f6e7c8;
  outline-offset: 3px;
}

@keyframes uvq02-seq {
  0%,11% {
    opacity: 1;
  }
  12.5%,100% {
    opacity: 0;
  }
}

@media (prefers-reduced-motion:reduce) {
  .uvq02-seq,.uvq02-seq *,.uvq02-seq *::before,.uvq02-seq *::after {
    animation-duration: .01ms!important;
    animation-iteration-count: 1!important;
    transition-duration: .01ms!important;
  }
}
`;

export default function ChkStepseq() {
  return (
    <>
      <style>{css}</style>
      <div
        style={{
          "--c1": "#ff5a1f",
          "--c2": "#f2cf3d",
          "--s": "16px",
          "--k": "1",
          "--fg": "#1d1d1f",
          "--bg": "#f5f5f7",
        } as CSSProperties}
      >
        <fieldset className="uvq02-seq"><legend>Kick</legend><div className="pd"><label style={{ "--i": "0" } as CSSProperties}><input type="checkbox" aria-label="Step 1" /><i></i></label><label style={{ "--i": "1" } as CSSProperties}><input type="checkbox" aria-label="Step 2" /><i></i></label><label style={{ "--i": "2" } as CSSProperties}><input type="checkbox" aria-label="Step 3" /><i></i></label><label style={{ "--i": "3" } as CSSProperties}><input type="checkbox" aria-label="Step 4" /><i></i></label><label style={{ "--i": "4" } as CSSProperties}><input type="checkbox" aria-label="Step 5" /><i></i></label><label style={{ "--i": "5" } as CSSProperties}><input type="checkbox" aria-label="Step 6" /><i></i></label><label style={{ "--i": "6" } as CSSProperties}><input type="checkbox" aria-label="Step 7" /><i></i></label><label style={{ "--i": "7" } as CSSProperties}><input type="checkbox" aria-label="Step 8" /><i></i></label></div></fieldset>
      </div>
    </>
  );
}
```

Give me the complete final code, ready to paste, and tell me in one line where to put it in my project.
````
