Open demo

CSS code

HTML
<div class="duo c3">
  <div><span class="lbl">Product box with a spin switch</span>
  <div class="bx-wrap">
    <input class="bx-toggle" type="checkbox" role="switch" id="bx-spin">
    <label class="bx-btn" for="bx-spin"><i aria-hidden="true"></i>Spin the box</label>
    <div class="bx-scene">
      <div class="bx" role="img" aria-label="Kettle and Leaf Smoked Lapsang tea, a green 100 gram box">
        <div class="bx-front"><span class="bx-brand">Kettle & Leaf</span>
          <svg class="bx-leaf" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 38C8 20 20 8 40 8c0 20-12 32-30 30z"/><path d="M10 38L28 20"/></svg>
          <div><p class="bx-name">Smoked Lapsang</p><p class="bx-sub">Black tea · 100 g loose leaf</p></div></div>
        <div class="bx-back"><strong>Brewing</strong><p>One heaped teaspoon per cup. Water at 95 °C. Steep for four minutes, then taste.</p><p>Pine-smoked in the Wuyi mountains. Packed in Leith.</p></div>
        <div class="bx-right">Brew 95 °C · 4 min</div>
        <div class="bx-left">Kettle & Leaf, Leith</div>
        <div class="bx-top">K & L</div>
        <div class="bx-bottom">Lot 26-114</div>
      </div>
    </div>
  </div></div>

  <div><span class="lbl">Cube navigation, one button per face</span>
  <fieldset class="cbn">
    <legend class="sr-only">Show a step of the project</legend>
    <input type="radio" name="cbn" id="cbn-1" checked><input type="radio" name="cbn" id="cbn-2"><input type="radio" name="cbn" id="cbn-3"><input type="radio" name="cbn" id="cbn-4"><input type="radio" name="cbn" id="cbn-5"><input type="radio" name="cbn" id="cbn-6">
    <div class="cbn-scene">
      <div class="cbn-cube">
        <div><span class="cbn-n">01</span><h3>Plan</h3><p>Two workshops to agree the goals and the budget.</p></div>
        <div><span class="cbn-n">02</span><h3>Design</h3><p>Clickable prototypes, tested with five real users.</p></div>
        <div><span class="cbn-n">03</span><h3>Build</h3><p>Two-week sprints with a demo every other Friday.</p></div>
        <div><span class="cbn-n">04</span><h3>Test</h3><p>Accessibility and load testing before anything ships.</p></div>
        <div><span class="cbn-n">05</span><h3>Launch</h3><p>A staged roll-out, 5 per cent of traffic first.</p></div>
        <div><span class="cbn-n">06</span><h3>Support</h3><p>Ninety days of fixes and a monthly report.</p></div>
      </div>
    </div>
    <div class="cbn-tabs"><label for="cbn-1">Plan</label><label for="cbn-2">Design</label><label for="cbn-3">Build</label><label for="cbn-4">Test</label><label for="cbn-5">Launch</label><label for="cbn-6">Support</label></div>
  </fieldset></div>
</div>

<div class="c3"><span class="lbl">Box size picker</span>
<fieldset class="bxs-grid">
  <legend class="sr-only">Choose a shipping box</legend>
  <label class="bxs"><input type="radio" name="bxs" value="small"><span class="bxs-card"><span class="bxs-scene" aria-hidden="true"><span class="cb3" style="--w:66px;--h:46px;--d:52px"><span class="cb3-f"></span><span class="cb3-r"></span><span class="cb3-t"></span></span></span>
    <span class="bxs-name">Small</span><span class="bxs-dim">20 × 15 × 10 cm, up to 2 kg</span><span class="bxs-price">€3.90</span></span></label>
  <label class="bxs"><input type="radio" name="bxs" value="medium" checked><span class="bxs-card"><span class="bxs-scene" aria-hidden="true"><span class="cb3"><span class="cb3-f"></span><span class="cb3-r"></span><span class="cb3-t"></span></span></span>
    <span class="bxs-name">Medium</span><span class="bxs-dim">30 × 22 × 16 cm, up to 5 kg</span><span class="bxs-price">€5.40</span></span></label>
  <label class="bxs"><input type="radio" name="bxs" value="large"><span class="bxs-card"><span class="bxs-scene" aria-hidden="true"><span class="cb3" style="--w:112px;--h:80px;--d:86px"><span class="cb3-f"></span><span class="cb3-r"></span><span class="cb3-t"></span></span></span>
    <span class="bxs-name">Large</span><span class="bxs-dim">40 × 30 × 24 cm, up to 10 kg</span><span class="bxs-price">€7.90</span></span></label>
</fieldset></div>
CSS
/* 3D cubes and boxes, CSS only. Every solid is a preserve-3d element with absolutely positioned faces, each turned
   (rotateX / rotateY) and pushed out by half the solid's depth (translateZ). Sizes are custom properties. */
.c3 :where(p,h3,ul){margin:0;padding:0}
.c3 .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* A. product box: a cuboid --w × --h × --d that can be set spinning with a switch */
.bx-wrap{position:relative;display:grid;justify-items:center;gap:20px}
.bx-scene{display:grid;place-items:center;width:100%;height:300px;perspective:1100px}
.bx{--w:150px;--h:210px;--d:90px;position:relative;width:var(--w);height:var(--h);transform-style:preserve-3d;transform:rotateX(-14deg) rotateY(-32deg)}
.bx > *{position:absolute;display:flex;flex-direction:column;-webkit-backface-visibility:hidden;backface-visibility:hidden}
.bx-front,.bx-back{width:var(--w);height:var(--h)}
.bx-left,.bx-right{width:var(--d);height:var(--h);left:calc((var(--w) - var(--d)) / 2)}
.bx-top,.bx-bottom{width:var(--w);height:var(--d);top:calc((var(--h) - var(--d)) / 2)}
.bx-front{transform:translateZ(calc(var(--d) / 2))}
.bx-back{transform:rotateY(180deg) translateZ(calc(var(--d) / 2))}
.bx-right{transform:rotateY(90deg) translateZ(calc(var(--w) / 2))}
.bx-left{transform:rotateY(-90deg) translateZ(calc(var(--w) / 2))}
.bx-top{transform:rotateX(90deg) translateZ(calc(var(--h) / 2))}
.bx-bottom{transform:rotateX(-90deg) translateZ(calc(var(--h) / 2))}
.bx-front{justify-content:space-between;padding:18px 16px;background:#14532d;color:#fefce8;
  background-image:linear-gradient(160deg,#166534,#14532d 60%)}
.bx-brand{font-size:.62rem;font-weight:800;letter-spacing:.22em;text-transform:uppercase;color:#fde68a}
.bx-name{font-family:Georgia,"Times New Roman",serif;font-size:1.45rem;line-height:1.05}
.bx-sub{font-size:.7rem;letter-spacing:.06em;color:#dcfce7}
.bx-leaf{width:44px;height:44px;color:#fde68a}
.bx-right,.bx-left{align-items:center;justify-content:center;background:#166534;color:#fefce8;font-size:.6rem;font-weight:800;letter-spacing:.2em;text-transform:uppercase;writing-mode:vertical-rl}
.bx-left{background:#115e2b}
.bx-back{gap:8px;padding:18px 14px;background:#fefce8;color:#14532d;font-size:.66rem;line-height:1.45}
.bx-back strong{font-size:.72rem;letter-spacing:.14em;text-transform:uppercase}
.bx-top,.bx-bottom{align-items:center;justify-content:center;background:#0f3f22;color:#fde68a;font-size:.6rem;font-weight:800;letter-spacing:.24em;text-transform:uppercase}
.bx-bottom{background:#0b301a}
.bx-toggle{position:absolute;opacity:0;width:1px;height:1px}
.bx-btn{display:inline-flex;align-items:center;gap:10px;padding:8px 14px 8px 10px;border-radius:999px;background:#fff;border:1px solid #a8a29e;font-size:.88rem;font-weight:700;color:#1c1917;cursor:pointer}
.bx-btn i{position:relative;width:34px;height:20px;border-radius:999px;background:#78716c;transition:background-color .2s}
.bx-btn i::after{content:"";position:absolute;top:3px;left:3px;width:14px;height:14px;border-radius:50%;background:#fff;transition:transform .2s}
.bx-toggle:checked + .bx-btn i{background:#15803d}
.bx-toggle:checked + .bx-btn i::after{transform:translateX(14px)}
.bx-toggle:focus-visible + .bx-btn{outline:3px solid #1d4ed8;outline-offset:3px}
.bx-toggle:checked ~ .bx-scene .bx{animation:bx-spin 10s linear infinite}
@keyframes bx-spin{from{transform:rotateX(-14deg) rotateY(-32deg)}to{transform:rotateX(-14deg) rotateY(328deg)}}

/* B. cube navigation: six radios, one per face, turn the cube; the labels below are the buttons */
.cbn{position:relative;display:grid;justify-items:center;gap:22px;min-width:0;border:0;margin:0;padding:0}
.cbn > input{position:absolute;opacity:0;width:1px;height:1px}
.cbn-scene{display:grid;place-items:center;width:100%;height:300px;perspective:1000px}
.cbn-cube{--s:190px;position:relative;width:var(--s);height:var(--s);transform-style:preserve-3d;
  transform:translateZ(calc(var(--s) / -2)) rotateX(-12deg) rotateY(16deg) rotateX(var(--fx,0deg)) rotateY(var(--fy,0deg));transition:transform .8s cubic-bezier(.3,.8,.25,1)}
.cbn-cube > *{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;gap:6px;padding:20px;border-radius:6px;-webkit-backface-visibility:hidden;backface-visibility:hidden;
  box-shadow:inset 0 0 0 1px rgba(28,25,23,.12)}
.cbn-cube > :nth-child(1){transform:translateZ(calc(var(--s) / 2));background:#fde68a}
.cbn-cube > :nth-child(2){transform:rotateY(90deg) translateZ(calc(var(--s) / 2));background:#bbf7d0}
.cbn-cube > :nth-child(3){transform:rotateY(180deg) translateZ(calc(var(--s) / 2));background:#bae6fd}
.cbn-cube > :nth-child(4){transform:rotateY(-90deg) translateZ(calc(var(--s) / 2));background:#fbcfe8}
.cbn-cube > :nth-child(5){transform:rotateX(90deg) translateZ(calc(var(--s) / 2));background:#ddd6fe}
.cbn-cube > :nth-child(6){transform:rotateX(-90deg) translateZ(calc(var(--s) / 2));background:#fed7aa}
.cbn-n{font-size:2.4rem;font-weight:800;letter-spacing:-.04em;line-height:1;color:#1c1917}
.cbn-cube h3{font-size:1.05rem;font-weight:800}
.cbn-cube p{font-size:.82rem;line-height:1.4;color:#44403c}
.cbn > input:nth-of-type(2):checked ~ .cbn-scene .cbn-cube{--fy:-90deg}
.cbn > input:nth-of-type(3):checked ~ .cbn-scene .cbn-cube{--fy:-180deg}
.cbn > input:nth-of-type(4):checked ~ .cbn-scene .cbn-cube{--fy:90deg}
.cbn > input:nth-of-type(5):checked ~ .cbn-scene .cbn-cube{--fx:-90deg}
.cbn > input:nth-of-type(6):checked ~ .cbn-scene .cbn-cube{--fx:90deg}
.cbn-tabs{display:flex;flex-wrap:wrap;justify-content:center;gap:8px}
.cbn-tabs label{padding:8px 14px;border-radius:999px;border:1px solid #a8a29e;background:#fff;font-size:.86rem;font-weight:700;color:#44403c;cursor:pointer;transition:background-color .2s,color .2s}
.cbn-tabs label:hover{border-color:#1c1917}
.cbn > input:nth-of-type(1):checked ~ .cbn-tabs label:nth-of-type(1),.cbn > input:nth-of-type(2):checked ~ .cbn-tabs label:nth-of-type(2),
.cbn > input:nth-of-type(3):checked ~ .cbn-tabs label:nth-of-type(3),.cbn > input:nth-of-type(4):checked ~ .cbn-tabs label:nth-of-type(4),
.cbn > input:nth-of-type(5):checked ~ .cbn-tabs label:nth-of-type(5),.cbn > input:nth-of-type(6):checked ~ .cbn-tabs label:nth-of-type(6){background:#1c1917;border-color:#1c1917;color:#fff}
.cbn > input:nth-of-type(1):focus-visible ~ .cbn-tabs label:nth-of-type(1),.cbn > input:nth-of-type(2):focus-visible ~ .cbn-tabs label:nth-of-type(2),
.cbn > input:nth-of-type(3):focus-visible ~ .cbn-tabs label:nth-of-type(3),.cbn > input:nth-of-type(4):focus-visible ~ .cbn-tabs label:nth-of-type(4),
.cbn > input:nth-of-type(5):focus-visible ~ .cbn-tabs label:nth-of-type(5),.cbn > input:nth-of-type(6):focus-visible ~ .cbn-tabs label:nth-of-type(6){outline:3px solid #1d4ed8;outline-offset:3px}

/* C. box size picker: radio cards, each with a small cardboard cuboid that turns when chosen */
.bxs-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,200px),1fr));gap:18px;border:0;margin:0;padding:0;min-width:0}
.bxs{position:relative;display:block;cursor:pointer}
.bxs input{position:absolute;opacity:0;width:1px;height:1px}
.bxs-card{display:grid;justify-items:center;gap:4px;height:100%;padding:18px 18px 20px;border-radius:18px;background:#fff;border:2px solid #d6d3d1;text-align:center;transition:border-color .2s,box-shadow .2s}
.bxs:hover .bxs-card{border-color:#a8a29e}
.bxs input:checked + .bxs-card{border-color:#c2410c;box-shadow:0 18px 30px -22px rgba(194,65,12,.7)}
.bxs input:focus-visible + .bxs-card{outline:3px solid #1d4ed8;outline-offset:3px}
.bxs-scene{display:grid;place-items:center;height:150px;width:100%;perspective:800px}
.cb3{--w:90px;--h:64px;--d:70px;position:relative;display:block;width:var(--w);height:var(--h);transform-style:preserve-3d;transform:rotateX(-22deg) rotateY(-34deg);transition:transform .6s cubic-bezier(.3,.8,.25,1)}
.cb3 > *{position:absolute;top:0;left:0;display:block}
.cb3-f{width:var(--w);height:var(--h);transform:translateZ(calc(var(--d) / 2));background:linear-gradient(180deg,#d9a46c,#c98f55)}
.cb3-r{width:var(--d);height:var(--h);left:calc((var(--w) - var(--d)) / 2);transform:rotateY(90deg) translateZ(calc(var(--w) / 2));background:linear-gradient(180deg,#b57b45,#a46c3a)}
.cb3-t{width:var(--w);height:var(--d);top:calc((var(--h) - var(--d)) / 2);transform:rotateX(90deg) translateZ(calc(var(--h) / 2));
  background:linear-gradient(90deg,transparent calc(50% - 9px),#f3d9b1 calc(50% - 9px) calc(50% + 9px),transparent calc(50% + 9px)),#e8b981;box-shadow:inset 0 0 0 1px rgba(120,72,30,.25)}
.cb3-f::after{content:"";position:absolute;left:calc(50% - 9px);top:0;width:18px;height:22%;background:#f3d9b1}
.bxs input:checked + .bxs-card .cb3{transform:rotateX(-30deg) rotateY(-58deg) translateY(-6px)}
.bxs-name{margin-top:6px;font-size:1rem;font-weight:800}
.bxs-dim{font-size:.84rem;color:#57534e}
.bxs-price{margin-top:6px;font-size:.92rem;font-weight:800;color:#9a3412}

@media (prefers-reduced-motion:reduce){
  .bx-toggle,.bx-btn{display:none}
  .bx-toggle:checked ~ .bx-scene .bx{animation:none}
  .cbn-cube,.cb3,.bxs-card,.cbn-tabs label,.bx-btn i,.bx-btn i::after{transition:none}
}

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<div class="row row-cols-1 row-cols-md-2 duo c3">
  <div class="col"><span class="lbl">Product box with a spin switch</span>
  <div class="bx-wrap">
    <input class="btn-check bx-toggle" type="checkbox" role="switch" id="bx-spin" autocomplete="off">
    <label class="btn bx-btn" for="bx-spin"><i aria-hidden="true"></i>Spin the box</label>
    <div class="bx-scene">
      <div class="bx" role="img" aria-label="Kettle and Leaf Smoked Lapsang tea, a green 100 gram box">
        <div class="bx-front"><span class="bx-brand">Kettle & Leaf</span>
          <svg class="bx-leaf" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 38C8 20 20 8 40 8c0 20-12 32-30 30z"/><path d="M10 38L28 20"/></svg>
          <div><p class="bx-name">Smoked Lapsang</p><p class="bx-sub">Black tea · 100 g loose leaf</p></div></div>
        <div class="bx-back"><strong>Brewing</strong><p>One heaped teaspoon per cup. Water at 95 °C. Steep for four minutes, then taste.</p><p>Pine-smoked in the Wuyi mountains. Packed in Leith.</p></div>
        <div class="bx-right">Brew 95 °C · 4 min</div>
        <div class="bx-left">Kettle & Leaf, Leith</div>
        <div class="bx-top">K & L</div>
        <div class="bx-bottom">Lot 26-114</div>
      </div>
    </div>
  </div></div>

  <div class="col"><span class="lbl">Cube navigation, one button per face</span>
  <fieldset class="cbn">
    <legend class="visually-hidden">Show a step of the project</legend>
    <input type="radio" class="btn-check" name="cbn" id="cbn-1" autocomplete="off" checked><input type="radio" class="btn-check" name="cbn" id="cbn-2" autocomplete="off"><input type="radio" class="btn-check" name="cbn" id="cbn-3" autocomplete="off"><input type="radio" class="btn-check" name="cbn" id="cbn-4" autocomplete="off"><input type="radio" class="btn-check" name="cbn" id="cbn-5" autocomplete="off"><input type="radio" class="btn-check" name="cbn" id="cbn-6" autocomplete="off">
    <div class="cbn-scene">
      <div class="cbn-cube">
        <div><span class="cbn-n">01</span><h3>Plan</h3><p>Two workshops to agree the goals and the budget.</p></div>
        <div><span class="cbn-n">02</span><h3>Design</h3><p>Clickable prototypes, tested with five real users.</p></div>
        <div><span class="cbn-n">03</span><h3>Build</h3><p>Two-week sprints with a demo every other Friday.</p></div>
        <div><span class="cbn-n">04</span><h3>Test</h3><p>Accessibility and load testing before anything ships.</p></div>
        <div><span class="cbn-n">05</span><h3>Launch</h3><p>A staged roll-out, 5 per cent of traffic first.</p></div>
        <div><span class="cbn-n">06</span><h3>Support</h3><p>Ninety days of fixes and a monthly report.</p></div>
      </div>
    </div>
    <div class="cbn-tabs"><label class="btn" for="cbn-1">Plan</label><label class="btn" for="cbn-2">Design</label><label class="btn" for="cbn-3">Build</label><label class="btn" for="cbn-4">Test</label><label class="btn" for="cbn-5">Launch</label><label class="btn" for="cbn-6">Support</label></div>
  </fieldset></div>
</div>

<div class="c3"><span class="lbl">Box size picker</span>
<fieldset class="bxs-grid">
  <legend class="visually-hidden">Choose a shipping box</legend>
  <div class="row row-cols-1 row-cols-sm-3 g-3">
  <div class="col"><input type="radio" class="btn-check" name="bxs" value="small" id="bxs-s" autocomplete="off"><label class="card bxs-card" for="bxs-s"><span class="bxs-scene" aria-hidden="true"><span class="cb3" style="--w:66px;--h:46px;--d:52px"><span class="cb3-f"></span><span class="cb3-r"></span><span class="cb3-t"></span></span></span>
    <span class="bxs-name">Small</span><span class="bxs-dim">20 × 15 × 10 cm, up to 2 kg</span><span class="bxs-price">€3.90</span></label></div>
  <div class="col"><input type="radio" class="btn-check" name="bxs" value="medium" id="bxs-m" autocomplete="off" checked><label class="card bxs-card" for="bxs-m"><span class="bxs-scene" aria-hidden="true"><span class="cb3"><span class="cb3-f"></span><span class="cb3-r"></span><span class="cb3-t"></span></span></span>
    <span class="bxs-name">Medium</span><span class="bxs-dim">30 × 22 × 16 cm, up to 5 kg</span><span class="bxs-price">€5.40</span></label></div>
  <div class="col"><input type="radio" class="btn-check" name="bxs" value="large" id="bxs-l" autocomplete="off"><label class="card bxs-card" for="bxs-l"><span class="bxs-scene" aria-hidden="true"><span class="cb3" style="--w:112px;--h:80px;--d:86px"><span class="cb3-f"></span><span class="cb3-r"></span><span class="cb3-t"></span></span></span>
    <span class="bxs-name">Large</span><span class="bxs-dim">40 × 30 × 24 cm, up to 10 kg</span><span class="bxs-price">€7.90</span></label></div>
  </div>
</fieldset></div>
CSS
/* 3D cubes and boxes on Bootstrap .btn-check, .btn and .card, with no JavaScript. Every solid is a preserve-3d element with absolutely positioned faces, each turned
   (rotateX / rotateY) and pushed out by half the solid's depth (translateZ). Sizes are custom properties. */
.c3 :where(p,h3,ul){margin:0;padding:0}

/* A. product box: a cuboid --w × --h × --d that can be set spinning with a switch */
.bx-wrap{position:relative;display:grid;justify-items:center;gap:20px}
.bx-scene{display:grid;place-items:center;width:100%;height:300px;perspective:1100px}
.bx{--w:150px;--h:210px;--d:90px;position:relative;width:var(--w);height:var(--h);transform-style:preserve-3d;transform:rotateX(-14deg) rotateY(-32deg)}
.bx > *{position:absolute;display:flex;flex-direction:column;-webkit-backface-visibility:hidden;backface-visibility:hidden}
.bx-front,.bx-back{width:var(--w);height:var(--h)}
.bx-left,.bx-right{width:var(--d);height:var(--h);left:calc((var(--w) - var(--d)) / 2)}
.bx-top,.bx-bottom{width:var(--w);height:var(--d);top:calc((var(--h) - var(--d)) / 2)}
.bx-front{transform:translateZ(calc(var(--d) / 2))}
.bx-back{transform:rotateY(180deg) translateZ(calc(var(--d) / 2))}
.bx-right{transform:rotateY(90deg) translateZ(calc(var(--w) / 2))}
.bx-left{transform:rotateY(-90deg) translateZ(calc(var(--w) / 2))}
.bx-top{transform:rotateX(90deg) translateZ(calc(var(--h) / 2))}
.bx-bottom{transform:rotateX(-90deg) translateZ(calc(var(--h) / 2))}
.bx-front{justify-content:space-between;padding:18px 16px;background:#14532d;color:#fefce8;
  background-image:linear-gradient(160deg,#166534,#14532d 60%)}
.bx-brand{font-size:.62rem;font-weight:800;letter-spacing:.22em;text-transform:uppercase;color:#fde68a}
.bx-name{font-family:Georgia,"Times New Roman",serif;font-size:1.45rem;line-height:1.05}
.bx-sub{font-size:.7rem;letter-spacing:.06em;color:#dcfce7}
.bx-leaf{width:44px;height:44px;color:#fde68a}
.bx-right,.bx-left{align-items:center;justify-content:center;background:#166534;color:#fefce8;font-size:.6rem;font-weight:800;letter-spacing:.2em;text-transform:uppercase;writing-mode:vertical-rl}
.bx-left{background:#115e2b}
.bx-back{gap:8px;padding:18px 14px;background:#fefce8;color:#14532d;font-size:.66rem;line-height:1.45}
.bx-back strong{font-size:.72rem;letter-spacing:.14em;text-transform:uppercase}
.bx-top,.bx-bottom{align-items:center;justify-content:center;background:#0f3f22;color:#fde68a;font-size:.6rem;font-weight:800;letter-spacing:.24em;text-transform:uppercase}
.bx-bottom{background:#0b301a}
.bx-btn{--bs-btn-padding-x:14px;--bs-btn-padding-y:8px;--bs-btn-font-size:.88rem;--bs-btn-font-weight:700;--bs-btn-border-radius:999px;--bs-btn-bg:#fff;--bs-btn-color:#1c1917;--bs-btn-border-color:#a8a29e;
  --bs-btn-hover-bg:#fff;--bs-btn-hover-color:#1c1917;--bs-btn-hover-border-color:#1c1917;--bs-btn-active-bg:#fff;--bs-btn-active-color:#1c1917;--bs-btn-active-border-color:#1c1917;
  display:inline-flex;align-items:center;gap:10px;padding-left:10px}
.bx-btn i{position:relative;width:34px;height:20px;border-radius:999px;background:#78716c;transition:background-color .2s}
.bx-btn i::after{content:"";position:absolute;top:3px;left:3px;width:14px;height:14px;border-radius:50%;background:#fff;transition:transform .2s}
.bx-toggle:checked + .bx-btn i{background:#15803d}
.bx-toggle:checked + .bx-btn i::after{transform:translateX(14px)}
.bx-toggle:focus-visible + .bx-btn{outline:3px solid #1d4ed8;outline-offset:3px;box-shadow:none}
.bx-toggle:checked ~ .bx-scene .bx{animation:bx-spin 10s linear infinite}
@keyframes bx-spin{from{transform:rotateX(-14deg) rotateY(-32deg)}to{transform:rotateX(-14deg) rotateY(328deg)}}

/* B. cube navigation: six radios, one per face, turn the cube; the labels below are the buttons */
.cbn{position:relative;display:grid;justify-items:center;gap:22px;min-width:0;border:0;margin:0;padding:0}
.cbn-scene{display:grid;place-items:center;width:100%;height:300px;perspective:1000px}
.cbn-cube{--s:190px;position:relative;width:var(--s);height:var(--s);transform-style:preserve-3d;
  transform:translateZ(calc(var(--s) / -2)) rotateX(-12deg) rotateY(16deg) rotateX(var(--fx,0deg)) rotateY(var(--fy,0deg));transition:transform .8s cubic-bezier(.3,.8,.25,1)}
.cbn-cube > *{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;gap:6px;padding:20px;border-radius:6px;-webkit-backface-visibility:hidden;backface-visibility:hidden;
  box-shadow:inset 0 0 0 1px rgba(28,25,23,.12)}
.cbn-cube > :nth-child(1){transform:translateZ(calc(var(--s) / 2));background:#fde68a}
.cbn-cube > :nth-child(2){transform:rotateY(90deg) translateZ(calc(var(--s) / 2));background:#bbf7d0}
.cbn-cube > :nth-child(3){transform:rotateY(180deg) translateZ(calc(var(--s) / 2));background:#bae6fd}
.cbn-cube > :nth-child(4){transform:rotateY(-90deg) translateZ(calc(var(--s) / 2));background:#fbcfe8}
.cbn-cube > :nth-child(5){transform:rotateX(90deg) translateZ(calc(var(--s) / 2));background:#ddd6fe}
.cbn-cube > :nth-child(6){transform:rotateX(-90deg) translateZ(calc(var(--s) / 2));background:#fed7aa}
.cbn-n{font-size:2.4rem;font-weight:800;letter-spacing:-.04em;line-height:1;color:#1c1917}
.cbn-cube h3{font-size:1.05rem;font-weight:800}
.cbn-cube p{font-size:.82rem;line-height:1.4;color:#44403c}
.cbn > input:nth-of-type(2):checked ~ .cbn-scene .cbn-cube{--fy:-90deg}
.cbn > input:nth-of-type(3):checked ~ .cbn-scene .cbn-cube{--fy:-180deg}
.cbn > input:nth-of-type(4):checked ~ .cbn-scene .cbn-cube{--fy:90deg}
.cbn > input:nth-of-type(5):checked ~ .cbn-scene .cbn-cube{--fx:-90deg}
.cbn > input:nth-of-type(6):checked ~ .cbn-scene .cbn-cube{--fx:90deg}
.cbn-tabs{display:flex;flex-wrap:wrap;justify-content:center;gap:8px}
.cbn-tabs .btn{--bs-btn-padding-x:14px;--bs-btn-padding-y:8px;--bs-btn-font-size:.86rem;--bs-btn-font-weight:700;--bs-btn-border-radius:999px;--bs-btn-bg:#fff;--bs-btn-color:#44403c;--bs-btn-border-color:#a8a29e;
  --bs-btn-hover-bg:#fff;--bs-btn-hover-color:#1c1917;--bs-btn-hover-border-color:#1c1917;--bs-btn-active-bg:#1c1917;--bs-btn-active-color:#fff;--bs-btn-active-border-color:#1c1917;transition:background-color .2s,color .2s}
.cbn > input:nth-of-type(1):checked ~ .cbn-tabs label:nth-of-type(1),.cbn > input:nth-of-type(2):checked ~ .cbn-tabs label:nth-of-type(2),
.cbn > input:nth-of-type(3):checked ~ .cbn-tabs label:nth-of-type(3),.cbn > input:nth-of-type(4):checked ~ .cbn-tabs label:nth-of-type(4),
.cbn > input:nth-of-type(5):checked ~ .cbn-tabs label:nth-of-type(5),.cbn > input:nth-of-type(6):checked ~ .cbn-tabs label:nth-of-type(6){background:#1c1917;border-color:#1c1917;color:#fff}
.cbn > input:nth-of-type(1):focus-visible ~ .cbn-tabs label:nth-of-type(1),.cbn > input:nth-of-type(2):focus-visible ~ .cbn-tabs label:nth-of-type(2),
.cbn > input:nth-of-type(3):focus-visible ~ .cbn-tabs label:nth-of-type(3),.cbn > input:nth-of-type(4):focus-visible ~ .cbn-tabs label:nth-of-type(4),
.cbn > input:nth-of-type(5):focus-visible ~ .cbn-tabs label:nth-of-type(5),.cbn > input:nth-of-type(6):focus-visible ~ .cbn-tabs label:nth-of-type(6){outline:3px solid #1d4ed8;outline-offset:3px}

/* C. box size picker: radio cards, each with a small cardboard cuboid that turns when chosen */
.bxs-grid{border:0;margin:0;padding:0;min-width:0}
.bxs-grid .col{position:relative}
.bxs-card{--bs-card-border-width:2px;--bs-card-border-color:#d6d3d1;--bs-card-border-radius:18px;display:grid;justify-items:center;gap:4px;height:100%;padding:18px 18px 20px;text-align:center;cursor:pointer;transition:border-color .2s,box-shadow .2s}
.bxs-card:hover{border-color:#a8a29e}
.btn-check:checked + .bxs-card{border-color:#c2410c;box-shadow:0 18px 30px -22px rgba(194,65,12,.7)}
.btn-check:focus-visible + .bxs-card{outline:3px solid #1d4ed8;outline-offset:3px}
.bxs-scene{display:grid;place-items:center;height:150px;width:100%;perspective:800px}
.cb3{--w:90px;--h:64px;--d:70px;position:relative;display:block;width:var(--w);height:var(--h);transform-style:preserve-3d;transform:rotateX(-22deg) rotateY(-34deg);transition:transform .6s cubic-bezier(.3,.8,.25,1)}
.cb3 > *{position:absolute;top:0;left:0;display:block}
.cb3-f{width:var(--w);height:var(--h);transform:translateZ(calc(var(--d) / 2));background:linear-gradient(180deg,#d9a46c,#c98f55)}
.cb3-r{width:var(--d);height:var(--h);left:calc((var(--w) - var(--d)) / 2);transform:rotateY(90deg) translateZ(calc(var(--w) / 2));background:linear-gradient(180deg,#b57b45,#a46c3a)}
.cb3-t{width:var(--w);height:var(--d);top:calc((var(--h) - var(--d)) / 2);transform:rotateX(90deg) translateZ(calc(var(--h) / 2));
  background:linear-gradient(90deg,transparent calc(50% - 9px),#f3d9b1 calc(50% - 9px) calc(50% + 9px),transparent calc(50% + 9px)),#e8b981;box-shadow:inset 0 0 0 1px rgba(120,72,30,.25)}
.cb3-f::after{content:"";position:absolute;left:calc(50% - 9px);top:0;width:18px;height:22%;background:#f3d9b1}
.btn-check:checked + .bxs-card .cb3{transform:rotateX(-30deg) rotateY(-58deg) translateY(-6px)}
.bxs-name{margin-top:6px;font-size:1rem;font-weight:800}
.bxs-dim{font-size:.84rem;color:#57534e}
.bxs-price{margin-top:6px;font-size:.92rem;font-weight:800;color:#9a3412}

@media (prefers-reduced-motion:reduce){
  .bx-toggle,.bx-btn{display:none}
  .bx-toggle:checked ~ .bx-scene .bx{animation:none}
  .cbn-cube,.cb3,.bxs-card,.cbn-tabs label,.bx-btn i,.bx-btn i::after{transition:none}
}

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<div class="grid grid-cols-[repeat(auto-fit,minmax(min(100%,320px),1fr))] gap-12">
  <div><span class="mb-[18px] block text-[.72rem] tracking-[.12em] text-[#57534e] uppercase">Product box with a spin switch</span>
  <div class="relative grid justify-items-center gap-5">
    <input class="peer absolute size-px opacity-0 motion-reduce:hidden" type="checkbox" role="switch" id="bxw-spin">
    <label class="group inline-flex cursor-pointer items-center gap-2.5 rounded-full border border-[#a8a29e] bg-white py-2 pr-3.5 pl-2.5 text-[.88rem] font-bold text-[#1c1917] peer-focus-visible:outline-3 peer-focus-visible:outline-offset-3 peer-focus-visible:outline-[#1d4ed8] motion-reduce:hidden" for="bxw-spin"><i class="relative h-5 w-[34px] rounded-full bg-[#78716c] transition-colors duration-200 group-[.peer:checked~&]:bg-[#15803d] after:absolute after:top-[3px] after:left-[3px] after:size-3.5 after:rounded-full after:bg-white after:transition-transform after:duration-200 after:content-[''] group-[.peer:checked~&]:after:translate-x-3.5" aria-hidden="true"></i>Spin the box</label>
    <div class="grid h-[300px] w-full place-items-center perspective-[1100px] motion-safe:peer-checked:*:animate-[bx-spin_10s_linear_infinite]">
      <div class="relative h-(--h) w-(--w) transform-3d [--d:90px] [--h:210px] [--w:150px] [transform:rotateX(-14deg)_rotateY(-32deg)]" role="img" aria-label="Kettle and Leaf Smoked Lapsang tea, a green 100 gram box">
        <div class="absolute flex flex-col backface-hidden h-(--h) w-(--w) justify-between bg-[#14532d] bg-[linear-gradient(160deg,#166534,#14532d_60%)] px-4 py-[18px] text-[#fefce8] [transform:translateZ(calc(var(--d)/2))]"><span class="text-[.62rem] font-extrabold tracking-[.22em] text-[#fde68a] uppercase">Kettle & Leaf</span>
          <svg class="size-11 text-[#fde68a]" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10 38C8 20 20 8 40 8c0 20-12 32-30 30z"/><path d="M10 38L28 20"/></svg>
          <div><p class="font-[Georgia,'Times_New_Roman',serif] text-[1.45rem] leading-[1.05]">Smoked Lapsang</p><p class="text-[.7rem] tracking-[.06em] text-[#dcfce7]">Black tea · 100 g loose leaf</p></div></div>
        <div class="absolute flex flex-col backface-hidden h-(--h) w-(--w) gap-2 bg-[#fefce8] px-3.5 py-[18px] text-[.66rem] leading-[1.45] text-[#14532d] [transform:rotateY(180deg)_translateZ(calc(var(--d)/2))]"><strong class="text-[.72rem] tracking-[.14em] uppercase">Brewing</strong><p>One heaped teaspoon per cup. Water at 95 °C. Steep for four minutes, then taste.</p><p>Pine-smoked in the Wuyi mountains. Packed in Leith.</p></div>
        <div class="absolute flex flex-col backface-hidden left-[calc((var(--w)_-_var(--d))/2)] h-(--h) w-(--d) items-center justify-center bg-[#166534] text-[.6rem] font-extrabold tracking-[.2em] text-[#fefce8] uppercase [writing-mode:vertical-rl] [transform:rotateY(90deg)_translateZ(calc(var(--w)/2))]">Brew 95 °C · 4 min</div>
        <div class="absolute flex flex-col backface-hidden left-[calc((var(--w)_-_var(--d))/2)] h-(--h) w-(--d) items-center justify-center bg-[#115e2b] text-[.6rem] font-extrabold tracking-[.2em] text-[#fefce8] uppercase [writing-mode:vertical-rl] [transform:rotateY(-90deg)_translateZ(calc(var(--w)/2))]">Kettle & Leaf, Leith</div>
        <div class="absolute flex flex-col backface-hidden top-[calc((var(--h)_-_var(--d))/2)] h-(--d) w-(--w) items-center justify-center bg-[#0f3f22] text-[.6rem] font-extrabold tracking-[.24em] text-[#fde68a] uppercase [transform:rotateX(90deg)_translateZ(calc(var(--h)/2))]">K & L</div>
        <div class="absolute flex flex-col backface-hidden top-[calc((var(--h)_-_var(--d))/2)] h-(--d) w-(--w) items-center justify-center bg-[#0b301a] text-[.6rem] font-extrabold tracking-[.24em] text-[#fde68a] uppercase [transform:rotateX(-90deg)_translateZ(calc(var(--h)/2))]">Lot 26-114</div>
      </div>
    </div>
  </div></div>

  <div><span class="mb-[18px] block text-[.72rem] tracking-[.12em] text-[#57534e] uppercase">Cube navigation, one button per face</span>
  <fieldset class="relative flex min-w-0 flex-wrap justify-center gap-2">
    <legend class="sr-only">Show a step of the project</legend>
    <input type="radio" name="cbn" id="cbnw-1" class="peer/c1 absolute size-px opacity-0" checked><input type="radio" name="cbn" id="cbnw-2" class="peer/c2 absolute size-px opacity-0"><input type="radio" name="cbn" id="cbnw-3" class="peer/c3 absolute size-px opacity-0"><input type="radio" name="cbn" id="cbnw-4" class="peer/c4 absolute size-px opacity-0"><input type="radio" name="cbn" id="cbnw-5" class="peer/c5 absolute size-px opacity-0"><input type="radio" name="cbn" id="cbnw-6" class="peer/c6 absolute size-px opacity-0">
    <div class="mb-3.5 grid h-[300px] basis-full place-items-center perspective-[1000px] peer-checked/c2:[--fy:-90deg] peer-checked/c3:[--fy:-180deg] peer-checked/c4:[--fy:90deg] peer-checked/c5:[--fx:-90deg] peer-checked/c6:[--fx:90deg]">
      <div class="relative size-(--s) transition-transform duration-800 ease-[cubic-bezier(.3,.8,.25,1)] transform-3d [--s:190px] [transform:translateZ(calc(var(--s)/-2))_rotateX(-12deg)_rotateY(16deg)_rotateX(var(--fx,0deg))_rotateY(var(--fy,0deg))] motion-reduce:transition-none">
        <div class="absolute inset-0 flex flex-col justify-end gap-1.5 rounded-md p-5 shadow-[inset_0_0_0_1px_rgba(28,25,23,.12)] backface-hidden bg-[#fde68a] [transform:translateZ(calc(var(--s)/2))]"><span class="text-[2.4rem] leading-none font-extrabold tracking-[-.04em] text-[#1c1917]">01</span><h3 class="text-[1.05rem] font-extrabold">Plan</h3><p class="text-[.82rem] leading-[1.4] text-[#44403c]">Two workshops to agree the goals and the budget.</p></div>
        <div class="absolute inset-0 flex flex-col justify-end gap-1.5 rounded-md p-5 shadow-[inset_0_0_0_1px_rgba(28,25,23,.12)] backface-hidden bg-[#bbf7d0] [transform:rotateY(90deg)_translateZ(calc(var(--s)/2))]"><span class="text-[2.4rem] leading-none font-extrabold tracking-[-.04em] text-[#1c1917]">02</span><h3 class="text-[1.05rem] font-extrabold">Design</h3><p class="text-[.82rem] leading-[1.4] text-[#44403c]">Clickable prototypes, tested with five real users.</p></div>
        <div class="absolute inset-0 flex flex-col justify-end gap-1.5 rounded-md p-5 shadow-[inset_0_0_0_1px_rgba(28,25,23,.12)] backface-hidden bg-[#bae6fd] [transform:rotateY(180deg)_translateZ(calc(var(--s)/2))]"><span class="text-[2.4rem] leading-none font-extrabold tracking-[-.04em] text-[#1c1917]">03</span><h3 class="text-[1.05rem] font-extrabold">Build</h3><p class="text-[.82rem] leading-[1.4] text-[#44403c]">Two-week sprints with a demo every other Friday.</p></div>
        <div class="absolute inset-0 flex flex-col justify-end gap-1.5 rounded-md p-5 shadow-[inset_0_0_0_1px_rgba(28,25,23,.12)] backface-hidden bg-[#fbcfe8] [transform:rotateY(-90deg)_translateZ(calc(var(--s)/2))]"><span class="text-[2.4rem] leading-none font-extrabold tracking-[-.04em] text-[#1c1917]">04</span><h3 class="text-[1.05rem] font-extrabold">Test</h3><p class="text-[.82rem] leading-[1.4] text-[#44403c]">Accessibility and load testing before anything ships.</p></div>
        <div class="absolute inset-0 flex flex-col justify-end gap-1.5 rounded-md p-5 shadow-[inset_0_0_0_1px_rgba(28,25,23,.12)] backface-hidden bg-[#ddd6fe] [transform:rotateX(90deg)_translateZ(calc(var(--s)/2))]"><span class="text-[2.4rem] leading-none font-extrabold tracking-[-.04em] text-[#1c1917]">05</span><h3 class="text-[1.05rem] font-extrabold">Launch</h3><p class="text-[.82rem] leading-[1.4] text-[#44403c]">A staged roll-out, 5 per cent of traffic first.</p></div>
        <div class="absolute inset-0 flex flex-col justify-end gap-1.5 rounded-md p-5 shadow-[inset_0_0_0_1px_rgba(28,25,23,.12)] backface-hidden bg-[#fed7aa] [transform:rotateX(-90deg)_translateZ(calc(var(--s)/2))]"><span class="text-[2.4rem] leading-none font-extrabold tracking-[-.04em] text-[#1c1917]">06</span><h3 class="text-[1.05rem] font-extrabold">Support</h3><p class="text-[.82rem] leading-[1.4] text-[#44403c]">Ninety days of fixes and a monthly report.</p></div>
      </div>
    </div>
    <label for="cbnw-1" class="cursor-pointer rounded-full border border-[#a8a29e] bg-white px-3.5 py-2 text-[.86rem] font-bold text-[#44403c] transition-colors duration-200 hover:border-[#1c1917] motion-reduce:transition-none peer-checked/c1:border-[#1c1917] peer-checked/c1:bg-[#1c1917] peer-checked/c1:text-white peer-focus-visible/c1:outline-3 peer-focus-visible/c1:outline-offset-3 peer-focus-visible/c1:outline-[#1d4ed8]">Plan</label><label for="cbnw-2" class="cursor-pointer rounded-full border border-[#a8a29e] bg-white px-3.5 py-2 text-[.86rem] font-bold text-[#44403c] transition-colors duration-200 hover:border-[#1c1917] motion-reduce:transition-none peer-checked/c2:border-[#1c1917] peer-checked/c2:bg-[#1c1917] peer-checked/c2:text-white peer-focus-visible/c2:outline-3 peer-focus-visible/c2:outline-offset-3 peer-focus-visible/c2:outline-[#1d4ed8]">Design</label><label for="cbnw-3" class="cursor-pointer rounded-full border border-[#a8a29e] bg-white px-3.5 py-2 text-[.86rem] font-bold text-[#44403c] transition-colors duration-200 hover:border-[#1c1917] motion-reduce:transition-none peer-checked/c3:border-[#1c1917] peer-checked/c3:bg-[#1c1917] peer-checked/c3:text-white peer-focus-visible/c3:outline-3 peer-focus-visible/c3:outline-offset-3 peer-focus-visible/c3:outline-[#1d4ed8]">Build</label><label for="cbnw-4" class="cursor-pointer rounded-full border border-[#a8a29e] bg-white px-3.5 py-2 text-[.86rem] font-bold text-[#44403c] transition-colors duration-200 hover:border-[#1c1917] motion-reduce:transition-none peer-checked/c4:border-[#1c1917] peer-checked/c4:bg-[#1c1917] peer-checked/c4:text-white peer-focus-visible/c4:outline-3 peer-focus-visible/c4:outline-offset-3 peer-focus-visible/c4:outline-[#1d4ed8]">Test</label><label for="cbnw-5" class="cursor-pointer rounded-full border border-[#a8a29e] bg-white px-3.5 py-2 text-[.86rem] font-bold text-[#44403c] transition-colors duration-200 hover:border-[#1c1917] motion-reduce:transition-none peer-checked/c5:border-[#1c1917] peer-checked/c5:bg-[#1c1917] peer-checked/c5:text-white peer-focus-visible/c5:outline-3 peer-focus-visible/c5:outline-offset-3 peer-focus-visible/c5:outline-[#1d4ed8]">Launch</label><label for="cbnw-6" class="cursor-pointer rounded-full border border-[#a8a29e] bg-white px-3.5 py-2 text-[.86rem] font-bold text-[#44403c] transition-colors duration-200 hover:border-[#1c1917] motion-reduce:transition-none peer-checked/c6:border-[#1c1917] peer-checked/c6:bg-[#1c1917] peer-checked/c6:text-white peer-focus-visible/c6:outline-3 peer-focus-visible/c6:outline-offset-3 peer-focus-visible/c6:outline-[#1d4ed8]">Support</label>
  </fieldset></div>
</div>

<div><span class="mb-[18px] block text-[.72rem] tracking-[.12em] text-[#57534e] uppercase">Box size picker</span>
<fieldset class="grid min-w-0 grid-cols-[repeat(auto-fit,minmax(min(100%,200px),1fr))] gap-[18px]">
  <legend class="sr-only">Choose a shipping box</legend>
  <label class="group relative block cursor-pointer"><input type="radio" name="bxs" value="small" class="peer absolute size-px opacity-0"><span class="grid h-full justify-items-center gap-1 rounded-[18px] border-2 border-[#d6d3d1] bg-white px-[18px] pt-[18px] pb-5 text-center transition-[border-color,box-shadow] duration-200 group-hover:border-[#a8a29e] peer-checked:border-[#c2410c] peer-checked:shadow-[0_18px_30px_-22px_rgba(194,65,12,.7)] peer-checked:[--bx-x:-30deg] peer-checked:[--bx-y:-58deg] peer-checked:[--bx-lift:-6px] peer-focus-visible:outline-3 peer-focus-visible:outline-offset-3 peer-focus-visible:outline-[#1d4ed8] motion-reduce:transition-none"><span class="grid h-[150px] w-full place-items-center perspective-[800px]" aria-hidden="true"><span class="block relative h-(--h) w-(--w) transition-transform duration-600 ease-[cubic-bezier(.3,.8,.25,1)] transform-3d [transform:rotateX(var(--bx-x,-22deg))_rotateY(var(--bx-y,-34deg))_translateY(var(--bx-lift,0px))] motion-reduce:transition-none [--d:52px] [--h:46px] [--w:66px]"><span class="absolute top-0 left-0 block h-(--h) w-(--w) bg-[linear-gradient(180deg,#d9a46c,#c98f55)] [transform:translateZ(calc(var(--d)/2))] after:absolute after:top-0 after:left-[calc(50%_-_9px)] after:h-[22%] after:w-[18px] after:bg-[#f3d9b1] after:content-['']"></span><span class="absolute top-0 left-[calc((var(--w)_-_var(--d))/2)] block h-(--h) w-(--d) bg-[linear-gradient(180deg,#b57b45,#a46c3a)] [transform:rotateY(90deg)_translateZ(calc(var(--w)/2))]"></span><span class="absolute top-[calc((var(--h)_-_var(--d))/2)] left-0 block h-(--d) w-(--w) bg-[#e8b981] bg-[linear-gradient(90deg,transparent_calc(50%_-_9px),#f3d9b1_calc(50%_-_9px)_calc(50%_+_9px),transparent_calc(50%_+_9px))] shadow-[inset_0_0_0_1px_rgba(120,72,30,.25)] [transform:rotateX(90deg)_translateZ(calc(var(--h)/2))]"></span></span></span>
    <span class="mt-1.5 text-base font-extrabold">Small</span><span class="text-[.84rem] text-[#57534e]">20 × 15 × 10 cm, up to 2 kg</span><span class="mt-1.5 text-[.92rem] font-extrabold text-[#9a3412]">€3.90</span></span></label>
  <label class="group relative block cursor-pointer"><input type="radio" name="bxs" value="medium" class="peer absolute size-px opacity-0" checked><span class="grid h-full justify-items-center gap-1 rounded-[18px] border-2 border-[#d6d3d1] bg-white px-[18px] pt-[18px] pb-5 text-center transition-[border-color,box-shadow] duration-200 group-hover:border-[#a8a29e] peer-checked:border-[#c2410c] peer-checked:shadow-[0_18px_30px_-22px_rgba(194,65,12,.7)] peer-checked:[--bx-x:-30deg] peer-checked:[--bx-y:-58deg] peer-checked:[--bx-lift:-6px] peer-focus-visible:outline-3 peer-focus-visible:outline-offset-3 peer-focus-visible:outline-[#1d4ed8] motion-reduce:transition-none"><span class="grid h-[150px] w-full place-items-center perspective-[800px]" aria-hidden="true"><span class="block relative h-(--h) w-(--w) transition-transform duration-600 ease-[cubic-bezier(.3,.8,.25,1)] transform-3d [transform:rotateX(var(--bx-x,-22deg))_rotateY(var(--bx-y,-34deg))_translateY(var(--bx-lift,0px))] motion-reduce:transition-none [--d:70px] [--h:64px] [--w:90px]"><span class="absolute top-0 left-0 block h-(--h) w-(--w) bg-[linear-gradient(180deg,#d9a46c,#c98f55)] [transform:translateZ(calc(var(--d)/2))] after:absolute after:top-0 after:left-[calc(50%_-_9px)] after:h-[22%] after:w-[18px] after:bg-[#f3d9b1] after:content-['']"></span><span class="absolute top-0 left-[calc((var(--w)_-_var(--d))/2)] block h-(--h) w-(--d) bg-[linear-gradient(180deg,#b57b45,#a46c3a)] [transform:rotateY(90deg)_translateZ(calc(var(--w)/2))]"></span><span class="absolute top-[calc((var(--h)_-_var(--d))/2)] left-0 block h-(--d) w-(--w) bg-[#e8b981] bg-[linear-gradient(90deg,transparent_calc(50%_-_9px),#f3d9b1_calc(50%_-_9px)_calc(50%_+_9px),transparent_calc(50%_+_9px))] shadow-[inset_0_0_0_1px_rgba(120,72,30,.25)] [transform:rotateX(90deg)_translateZ(calc(var(--h)/2))]"></span></span></span>
    <span class="mt-1.5 text-base font-extrabold">Medium</span><span class="text-[.84rem] text-[#57534e]">30 × 22 × 16 cm, up to 5 kg</span><span class="mt-1.5 text-[.92rem] font-extrabold text-[#9a3412]">€5.40</span></span></label>
  <label class="group relative block cursor-pointer"><input type="radio" name="bxs" value="large" class="peer absolute size-px opacity-0"><span class="grid h-full justify-items-center gap-1 rounded-[18px] border-2 border-[#d6d3d1] bg-white px-[18px] pt-[18px] pb-5 text-center transition-[border-color,box-shadow] duration-200 group-hover:border-[#a8a29e] peer-checked:border-[#c2410c] peer-checked:shadow-[0_18px_30px_-22px_rgba(194,65,12,.7)] peer-checked:[--bx-x:-30deg] peer-checked:[--bx-y:-58deg] peer-checked:[--bx-lift:-6px] peer-focus-visible:outline-3 peer-focus-visible:outline-offset-3 peer-focus-visible:outline-[#1d4ed8] motion-reduce:transition-none"><span class="grid h-[150px] w-full place-items-center perspective-[800px]" aria-hidden="true"><span class="block relative h-(--h) w-(--w) transition-transform duration-600 ease-[cubic-bezier(.3,.8,.25,1)] transform-3d [transform:rotateX(var(--bx-x,-22deg))_rotateY(var(--bx-y,-34deg))_translateY(var(--bx-lift,0px))] motion-reduce:transition-none [--d:86px] [--h:80px] [--w:112px]"><span class="absolute top-0 left-0 block h-(--h) w-(--w) bg-[linear-gradient(180deg,#d9a46c,#c98f55)] [transform:translateZ(calc(var(--d)/2))] after:absolute after:top-0 after:left-[calc(50%_-_9px)] after:h-[22%] after:w-[18px] after:bg-[#f3d9b1] after:content-['']"></span><span class="absolute top-0 left-[calc((var(--w)_-_var(--d))/2)] block h-(--h) w-(--d) bg-[linear-gradient(180deg,#b57b45,#a46c3a)] [transform:rotateY(90deg)_translateZ(calc(var(--w)/2))]"></span><span class="absolute top-[calc((var(--h)_-_var(--d))/2)] left-0 block h-(--d) w-(--w) bg-[#e8b981] bg-[linear-gradient(90deg,transparent_calc(50%_-_9px),#f3d9b1_calc(50%_-_9px)_calc(50%_+_9px),transparent_calc(50%_+_9px))] shadow-[inset_0_0_0_1px_rgba(120,72,30,.25)] [transform:rotateX(90deg)_translateZ(calc(var(--h)/2))]"></span></span></span>
    <span class="mt-1.5 text-base font-extrabold">Large</span><span class="text-[.84rem] text-[#57534e]">40 × 30 × 24 cm, up to 10 kg</span><span class="mt-1.5 text-[.92rem] font-extrabold text-[#9a3412]">€7.90</span></span></label>
</fieldset></div>
CSS
/* The spin for the product box. Faces, sizes (--w, --h, --d, --s) and the face-by-face rotations are utilities in the markup. */
@keyframes bx-spin{from{transform:rotateX(-14deg) rotateY(-32deg)}to{transform:rotateX(-14deg) rotateY(328deg)}}

About this set

Solid shapes built from HTML and CSS, in three variants. The product box is a tea packet with six printed faces, shown at an angle, with a Spin the box switch that sets it turning. It only rotates after the visitor turns the switch on, and the switch is hidden under prefers-reduced-motion, so the box stays still. The cube navigation has six faces for the steps of a project, Plan, Design, Build, Test, Launch and Support, and a row of buttons, one per face, that turns the cube to show the chosen step. The box size picker is a set of radio cards, each with a small cardboard box drawn in 3D, and the chosen card turns and lifts its box. Every solid is a preserve-3d element whose faces are absolutely positioned, turned with rotateX or rotateY and pushed out by half the depth with translateZ, so width, height and depth are custom properties. The face buttons are visually hidden radio inputs with their labels styled as buttons, and the spin is a checkbox, so none of it needs JavaScript.

What’s included

  • Cuboids sized by --w, --h and --d custom properties
  • Six-face cube turned by radio buttons, one per face
  • Spin only after the visitor switches it on, never under reduced motion
  • Radio cards with a 3D cardboard box for each size
  • No JavaScript; the Bootstrap version uses .btn-check, .btn and .card

Accessibility

The cube's face buttons are a radio group in a fieldset with a legend, so Tab enters the group and the arrow keys move between faces. The box size cards are labelled radios whose name includes the size, dimensions and price, and the spin control is a checkbox with role="switch". Focus shows a 3px blue outline on the visible button or card, the product box is one image with a text alternative, and all turning is removed or hidden under prefers-reduced-motion.

Customise it

Change --w, --h and --d on .bx and .cb3, or --s on .cbn-cube, to resize the solids; face colours are the backgrounds of each face rule. In Tailwind the same variables are [--w:] style utilities and the faces use [transform:] classes.