JSFiddle - React, Tailwind, and code Playground

by johnmu

HTML

<h1>30 Sekunden Mathe</h1>
		<p class="instructions">
			Fange mit der Zahl in der ersten Box an, und führe die Rechnungen durch. Gebe die Antwort in der lezten Box ein und drücke Enter.
		</p>
		<p><label><input type="checkbox" id="focus_toggle"> Fokus auf die Startzahl statt der Eingabebox?</label></p>


<ul id="challenges">
</ul>		
<button class="another" data-difficulty="easy">Einfache Aufgabe</button>
<button class="another" data-difficulty="medium">Mittel</button>
<button class="another" data-difficulty="hard">Schwer</button>

CSS

html {
	font-size: 20px;
	font-family: sans-serif;
}

body {
	width: 60rem;
	margin: 0 auto;
}

.instructions {
	font-size: 16px;
}

#challenges {
	padding: 0;
	list-style: none;
}

.challenge {
    list-style: none;
    padding: 0;
}
.challenge, .summary {
	margin-bottom: 2rem;
}

.challenge.finished {
	opacity: 0.3;
}

.challenge li {
	box-sizing: border-box;
    display: inline-block;
    padding: 1rem;
    width: 5rem;
    height: 5rem;
    border-right: 1px solid black;
    border-bottom: 1px solid black;
    border-top: 1px solid black;
    vertical-align: middle;
    text-align: center;
    line-height: 3em;
}

.challenge .difficulty {
	border-radius: 0.3rem 0 0 0;
}

.challenge li:first-child {
	border-radius: 0.3rem 0 0 0.3rem;
}

.challenge li:last-child {
	border-radius: 0 0.3rem 0.3rem 0;
}

.challenge li.start {
    border-left: 1px solid black;
}
.challenge li .text {
    line-height: 1rem;
    display: inline-block;
    vertical-align: middle;
}
.challenge .move .text {
	text-transform: uppercase;
}

.challenge .result input {
    width: 3rem;
    height: 2rem;
    border: none;
    border-bottom: 1px solid gray;
    /* margin-top: 1rem; */
	font-size: 1em;
	background: transparent;
}

.challenge .result::before, .challenge .difficulty {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    padding: 1px;
    background: black;
    color: white;
    line-height: 1.2em;
}
.challenge .result::before {
    content: 'Answer';
}

.challenge .result, .challenge .start {
    position: relative;
}

.challenge.difficulty-easy .difficulty {
	background: green;
}

.challenge.difficulty-medium .difficulty {
	background: #ffc200 /*amber*/;
}

.challenge.difficulty-hard .difficulty {
	background: red;
}

.challenge .move.double_it .text, .challenge .move.halve_it .text, .challenge .move.square_it .text, .challenge .move.cube_it .text {
    font-size: 0.7em;
}

.challenge .start .text {
    font-size: 2em;
}

.challenge.correct .result...

JavaScript

function randrange(a,b) {
	return Math.floor(Math.random()*(b-a)+a);
}

function show_time(t) {
	var tenths = Math.floor(t*10) % 10;
	var seconds = Math.floor(t);
	return seconds+'.'+tenths+'s'
}

var superscripts = "⁰¹²³⁴⁵⁶⁷⁸⁹";
var subscripts = "₀₁₂₃₄₅₆₇₈₉";

function show_script(n,scripts) {
	if(n==0) {
		return scripts[0];
	}
	var s = '';
	while(n) {
		var m = n%10;
		s = scripts[m]+s;
		n=(n-m)/10;
	}
	return s;
}

function show_fraction(n,d) {
	return show_script(n,superscripts)+'/'+show_script(d,subscripts);
}

function coin() {
	return Math.random()>0.5;
}

function gcd(a,b) {
	if(a>b){return gcd(b,a);}
	while(a>0) {
		var m = b%a;
		b=a;
		a=m;
	}
	return b;
}

function choice(l) {
	var i = Math.floor(Math.random()*l.length);
	return l[i];
}

function weighted_choice(l) {
	var t = 0;
	var keep = null;
	for(var i=0;i<l.length;i++) {
		var o = l[i][0];
		var w = l[i][1];
		var p = w/(t+w);
		if(keep===null || Math.random()<p) {
			keep = o;
		}
		t += w;
	}
	return keep;
}


var square_it = {
	test: function(n){ return n>1 && n<20 },
	fn: function(n) {
		return [{kind: 'square_it',text:'mal sich selber',n:n*n}];
	}
}
var cube_it = {
	test: function(n){ return n>1 && n<10 },
	fn: function(n) {
		return [{kind: 'cube_it',text:'mal sich selber zweimal',n: n*n*n}];
	}
}

var halve_it = {
	test: function(n,steps,last_move){return n%2==0 && last_move!=double_it},
	fn: function(n) {
		return [{kind: 'halve_it', text: 'hälfte', n:n/2}];
	}
}

var double_it = {
	test: function(n,steps,last_move){return last_move!=halve_it},
	fn: function(n) {
		return [{kind: 'double_it', text: 'doppelt', n:n*2}];
	}
}

var add = {
	test: function(n,steps,last_move){return last_move!=subtract && last_move!=add},
	fn: function(n) {
		var i = randrange(1,20);
		return [{kind: 'add', text: '+ '+i, n:n+i}]
	}
}

var subtract = {
	test: function(n,steps,last_move){return n>5 && last_move!=add && last_move!=subtract},
	fn: function(n) {
		var i = randrange(1,Math.min(20,n-5));
		return...