Memory Puzzle

A memory puzzle in just over 100 lines of js.

by TrySpace

HTML

<aside><h3>moves: <span id="moves"></span></h3><h3 id="win"> You won! <button id="reset">reset</button></h3></aside>
<main>  
</main>

CSS

body { 
    background: #efefef;
    font-size: 16px;
    color: #666;
}

aside {
    text-align: center;
}

h3 {
    font-weight: normal;
    display: inline-block;
    margin: 0.5rem 1rem;
}

#reset {
    margin: 0 1rem; 
}

main {
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select:none;
    user-select:none;
    margin: 0 auto;
    width: 57.3rem;
    font: 4rem serif;
}

figure {
    box-shadow: 0 0 15px rgba(0, 0, 0, 0.3);
    border-radius: 0.25rem;
    float: left;
    border: 1px solid #666;
    margin: 0.5rem;
    height: 9rem;
    width: 6rem;
    padding: 0;
    -webkit-perspective: 1000;
    -moz-perspective: 1000;
    perspective: 1000;
    position: relative;
}

div input {
  display: none;
}

div [type="radio"]:checked + .animate {
    -webkit-transform: rotateY(180deg);
    -moz-transform: rotateY(180deg);
    transform: rotateY(180deg);
}

.animate {
   -webkit-transform-style: preserve-3d;
   -moz-transform-style: preserve-3d;
   transform-style: preserve-3d;
   transition: all 0.5s ease-out;
}

label {
    text-align: center;
    border-radius: 0.25rem;
    border: 0.5rem solid #fff;
    display: inline-block;
    width: 5rem;
    height: 8rem;
    line-height: 8rem;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    -webkit-backface-visibility: hidden;
    -moz-backface-visibility: hidden;
    backface-visibility: hidden;
}
 
.back {
    -webkit-transform: rotateY(180deg);
    -moz-transform: rotateY(180deg);
    transform: rotateY(180deg);
    background: #fcfcfc;
}

.front {
   z-index: 1;
}

.front:before {
    content:'\272A';
    text-shadow: 0 0 15px rgba(0, 0, 0, 0.25);
    color: #fff;
    background: firebrick;
    height: 100%;
    width: 100%;
    displey: block;
    border: 1.75rem solid firebrick;
    border-left-width: 0.5rem;
    border-right-width: 0.5rem;
}

JavaScript

var main = document.querySelector('main');
var moves = document.getElementById('moves');
var win = document.getElementById('win');
var last, done;

function newGame() {
    win.style.display = 'none';
    moves.textContent = '0';
    while (main.children.length) main.removeChild(main.children[main.children.length - 1]);
    done = 0;
    var childs = [];
    var frag = document.createDocumentFragment();
    for (var j = 0; j < 20; j += 1) {
        var color = strToHSL(Math.random().toString(36).substring(2));
        for (var d = 0; d < 2; d += 1) {
            var el = createCard(9707 + j + (j * 3), j, d, color);
            childs.push(el);
        }
    }
    var newA = [];
    while (childs.length) frag.appendChild(childs.splice(Math.floor(Math.random() * childs.length), 1)[0]);
    main.appendChild(frag);
}

function createAnimationRadio(i, d, c, ord) {
    var radio = document.createElement('input');
    radio.type = 'radio';
    radio.name = 'radio-' + ord;
    radio.id = 'radio-' + ord + '-' + ((c) ? '2' : '1');
    if (!c) radio.checked = true;
    return radio;
}

function createLabel(i, d, ord, color, codes) {
    var el = document.createElement('label');
    el.className = codes ? 'back' : 'front';
    el.dataset.card = i;
    el.htmlFor = 'radio-' + ord + '-' + (codes ? 1 : 2);
    if (codes) {
        el.textContent = String.fromCharCode(codes);
        el.style['color'] = color;
        el.style['-webkit-text-fill-color'] = color;
        el.style['-webkit-text-stroke'] =  '1px ' + color.replace(',32%', ',46%');
    }
    el.addEventListener('click', play);
    return el;
}

function createCard(codes, i, d, color) {
    var div = document.createElement('div');
    var el = document.createElement('figure');
    el.className = 'animate';
    var ord = i + '-' + d;
    var radio1 = createAnimationRadio(i, d, 0, ord);
    var radio2 = createAnimationRadio(i, d, 1, ord);
    var front = createLabel(i, d, ord);
    var back = createLabel(i, d, ord,...