Magnetic button
CSS + JSInside its field the button shifts and leans toward the pointer while its label floats higher, so the two slide apart. JS only reports the pointer position; release it and a springy transition takes it home.
A real checkbox underneath: click, tap or press Space. The rocker tips on :checked.
Your edited version
<input type="checkbox"> holds the state, so keyboard, forms and screen readers all work.display: none, which would remove it from the tab order).input:checked + .rocker tips it from rotateX(-22deg) to rotateX(22deg).<label> makes the whole switch clickable with zero JavaScript.--u, tied to the canvas — the rocker, its bezel rings, the gap and the LED — so the switch is the same share of a gallery card, the editor and a recording canvas. The numbers below are those units.input:checked + siblingrotateX rockerlabel makes the whole thing clickable<label class="switch">
<input type="checkbox">
<span class="rocker"><b>I</b><b>O</b></span>
<em></em>
</label>
.switch {
/* one base unit: every length below is a multiple of it, so the switch is the same share of a
card, the editor, a full screen and a recording canvas */
--u: 0.34vmin;
display: grid;
justify-items: center;
gap: calc(22 * var(--u));
perspective: calc(320 * var(--u));
cursor: pointer;
}
/* hidden but still focusable */
.switch input {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
}
.rocker {
box-sizing: content-box; /* its size is its inside, its edge outside it, on any page */
display: grid;
grid-template-rows: 1fr 1fr;
width: calc(90 * var(--u));
height: calc(146 * var(--u));
border-radius: calc(14 * var(--u));
background: linear-gradient(#2b3050, #161a30);
border: calc(1 * var(--u)) solid #4a5280;
color: #8d95b3;
font: 700 calc(25.6 * var(--u)) Inter, system-ui;
text-align: center;
box-shadow: 0 0 0 calc(9 * var(--u)) #05060c, 0 0 0 calc(10 * var(--u)) #4a5280;
transform: rotateX(-22deg); /* OFF */
transition: transform 0.18s cubic-bezier(0.3, 1.6, 0.5, 1);
}
.rocker b { display: grid; place-items: center; }
input:checked + .rocker {
transform: rotateX(22deg); /* ON */
color: #2ee6d6;
}
input:focus-visible + .rocker {
outline: calc(2 * var(--u)) solid #2ee6d6;
outline-offset: calc(14 * var(--u));
}
/* status LED */
.switch em {
width: calc(14 * var(--u));
height: calc(14 * var(--u));
border-radius: 50%;
background: #3a3f5c;
transition: 0.2s;
}
input:checked ~ em {
background: #2ee6d6;
box-shadow: 0 0 calc(14 * var(--u)) #2ee6d6;
}