<!doctype html>
<title>3D Solvable Rubik's Cube</title> <style> :root{ --size:64px; --gap:6px; } html,body{height:100%;margin:0;background:#0b0b0f;color:#ddd;font-family:Inter,system-ui,Segoe UI,Roboto,"Helvetica Neue",Arial} .wrap{height:100vh;display:flex;align-items:center;justify-content:center;gap:24px;padding:24px;box-sizing:border-box} .stage{width:720px;height:520px;display:flex;gap:20px;align-items:center} .viewer{width:520px;height:520px;perspective:1200px} .controls{width:180px} .cube-scene{width:100%;height:100%;position:relative;transform-style:preserve-3d} .cube-wrap{width:100%;height:100%;position:relative;transform-style:preserve-3d;transition:transform 300ms cubic-bezier(.2,.9,.2,1)} .field{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:calc(var(--size)*3 + var(--gap)*2);height:calc(var(--size)*3 + var(--gap)*2);transform-style:preserve-3d} .cubie{position:absolute;width:var(--size);height:var(--size);transform-style:preserve-3d;box-shadow:0 6px 18px rgba(0,0,0,.6)} .face{position:absolute;inset:0;border-radius:6px;display:flex;align-items:center;justify-content:center;font-weight:700;color:#111;backface-visibility:hidden;overflow:hidden} /* stickers (smaller than face) */ .sticker{position:absolute;left:6px;top:6px;right:6px;bottom:6px;border-radius:4px} .face.front{transform:translateZ(calc(var(--size)/2));} .face.back{transform:rotateY(180deg) translateZ(calc(var(--size)/2));} .face.right{transform:rotateY(90deg) translateZ(calc(var(--size)/2));} .face.left{transform:rotateY(-90deg) translateZ(calc(var(--size)/2));} .face.up{transform:rotateX(90deg) translateZ(calc(var(--size)/2));} .face.down{transform:rotateX(-90deg) translateZ(calc(var(--size)/2));}/* sticker colors */ .cW{background:#ffffff} .cY{background:#ffd500} .cR{background:#ff3b30} .cO{background:#ff9500} .cB{background:#007aff} .cG{background:#34c759} .blank{background:transparent}
/* UI */ .controls{color:#ddd} .controls h2{margin:0 0 12px 0;font-size:16px} .btn{display:inline-block;padding:8px 10px;margin:6px;border-radius:8px;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.04);cursor:pointer} .btn:active{transform:translateY(1px)} .row{display:flex;flex-wrap:wrap} .small{font-size:13px;padding:6px 8px} .info{font-size:13px;margin-top:12px;line-height:1.3;color:#cfcfcf} .actions{margin-top:14px} .scramble{margin-top:12px} .footer{font-size:12px;color:#999;margin-top:14px} </style>
<div class="controls">
<h2>Controls</h2>
<div class="row">
<button class="btn small" data-face="U">U</button>
<button class="btn small" data-face="D">D</button>
<button class="btn small" data-face="L">L</button>
<button class="btn small" data-face="R">R</button>
<button class="btn small" data-face="F">F</button>
<button class="btn small" data-face="B">B</button>
</div>
<div class="row actions">
<button class="btn" id="ccw">↺ CCW</button>
<button class="btn" id="cw">↻ CW</button>
</div>
<div class="row scramble">
<button class="btn" id="scrambleBtn">Scramble</button>
<button class="btn" id="solveBtn">Solve</button>
</div>
<div class="info">
Click face button then choose rotation direction.<br>
Drag the cube to orbit view.<br>
Scramble randomizes; Solve reverses the scramble.
</div>
<div class="footer">Made with HTML/CSS/JS — simple reversible solver (undo the scramble)</div>
</div>