html {
	height: 100%;
}
body {
	min-height: 100%;
	margin: 0;
	font-family: sans-serif;
	background-color: white;
	color: black;
}

/*
 * Workaround for Chrome, which for some reason sets the background colour of
 * whatever element is fullscreened to black
 */
:fullscreen {
	background-color: white;
}

/*
 * Add some space before the roll button
 */
#roll {
	margin-top: 1em;
}

/*
 * The full-height area for the 3D scene to be centred within
 */
#sceneArea {
	display: flex;
	height: 100vh;
}

/*
 * The 3D area
 */
#scene {
	perspective: max(100vw, 100vh);
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	user-select: none;
	pointer-events: none;
	margin: auto;

	/* Padding on each side of a die, as a fraction of the --dieEdge */
	--diePad: 0.3;

	/* Helpers */
	--minAxis: min(100vw, 100vh);
	--maxAxis: max(100vw, 100vh);

	/* Space available including padding for each die */
	--maxDieSpace: var(--minAxis);
	--idealDieSpace: calc(30vw + 30vh);
	--dieSpace: min(var(--maxDieSpace), var(--idealDieSpace));

	/* Side length of die edges */
	--dieEdge: calc(var(--dieSpace) / (1 + 2 * var(--diePad)));

	/* Transforms to either push or pull by half an edge length */
	--pullToSurface: translateZ(calc(var(--dieEdge) / 2));
	--pushToFloor: translateZ(calc(-1 * var(--dieEdge) / 2));
}
#scene[data-dice-num="1"] { --idealDieSpace: max(100vw, 100vh); }
#scene[data-dice-num="2"] { --idealDieSpace: calc(var(--maxAxis) / 2); }
#scene[data-dice-num="3"] { --idealDieSpace: calc(var(--minAxis) / 2); }
#scene[data-dice-num="4"] { --idealDieSpace: calc(var(--minAxis) / 2); }
#scene[data-dice-num="5"] { --idealDieSpace: calc(var(--maxAxis) / 3); }
#scene[data-dice-num="6"] { --idealDieSpace: calc(var(--maxAxis) / 3); }

@media (min-aspect-ratio: 3 / 2), (max-aspect-ratio: 2 / 3) {
	#scene[data-dice-num="3"] { --idealDieSpace: calc(var(--maxAxis) / 3); }
	#scene[data-dice-num="5"] { --idealDieSpace: calc(var(--minAxis) / 2); }
	#scene[data-dice-num="6"] { --idealDieSpace: calc(var(--minAxis) / 2); }
}
@media (min-aspect-ratio: 5 / 2), (max-aspect-ratio: 2 / 5) {
	#scene[data-dice-num="5"] { --idealDieSpace: calc(var(--maxAxis) / 5); }
}
@media (min-aspect-ratio: 2), (max-aspect-ratio: 1 / 2) {
	#scene[data-dice-num="4"] { --idealDieSpace: calc(var(--maxAxis) / 4); }
}
@media (min-aspect-ratio: 3), (max-aspect-ratio: 1 / 3) {
	#scene[data-dice-num="6"] { --idealDieSpace: calc(var(--maxAxis) / 6); }
}

/*
 * Some space around the die, so that no two dice are right up against each
 * other (which would make them intersect while rotating)
 */
.diePad {
	padding: calc(var(--dieEdge) * var(--diePad));
	transform-style: preserve-3d;
	display: flex;
}

/*
 * On each successive roll, the dice are rotated a pseudo-random number of full
 * turns so it looks more like they're tumbling randomly rather than just going
 * directly to their target face
 *
 * This was generated with the script util/spins.js
 */
#scene[data-roll-count-mod5="0"] > :nth-child(6n+1) { --spin: rotateX(0turn) rotateY(0turn) rotateZ(0turn); }
#scene[data-roll-count-mod5="1"] > :nth-child(6n+1) { --spin: rotateX(2turn) rotateY(1turn) rotateZ(-2turn); }
#scene[data-roll-count-mod5="2"] > :nth-child(6n+1) { --spin: rotateX(-1turn) rotateY(2turn) rotateZ(-3turn); }
#scene[data-roll-count-mod5="3"] > :nth-child(6n+1) { --spin: rotateX(-3turn) rotateY(1turn) rotateZ(-1turn); }
#scene[data-roll-count-mod5="4"] > :nth-child(6n+1) { --spin: rotateX(-1turn) rotateY(-1turn) rotateZ(-2turn); }
#scene[data-roll-count-mod5="0"] > :nth-child(6n+2) { --spin: rotateX(0turn) rotateY(0turn) rotateZ(0turn); }
#scene[data-roll-count-mod5="1"] > :nth-child(6n+2) { --spin: rotateX(-2turn) rotateY(2turn) rotateZ(-1turn); }
#scene[data-roll-count-mod5="2"] > :nth-child(6n+2) { --spin: rotateX(0turn) rotateY(3turn) rotateZ(0turn); }
#scene[data-roll-count-mod5="3"] > :nth-child(6n+2) { --spin: rotateX(2turn) rotateY(2turn) rotateZ(1turn); }
#scene[data-roll-count-mod5="4"] > :nth-child(6n+2) { --spin: rotateX(-1turn) rotateY(1turn) rotateZ(2turn); }
#scene[data-roll-count-mod5="0"] > :nth-child(6n+3) { --spin: rotateX(0turn) rotateY(0turn) rotateZ(0turn); }
#scene[data-roll-count-mod5="1"] > :nth-child(6n+3) { --spin: rotateX(3turn) rotateY(1turn) rotateZ(-1turn); }
#scene[data-roll-count-mod5="2"] > :nth-child(6n+3) { --spin: rotateX(0turn) rotateY(2turn) rotateZ(0turn); }
#scene[data-roll-count-mod5="3"] > :nth-child(6n+3) { --spin: rotateX(2turn) rotateY(3turn) rotateZ(-2turn); }
#scene[data-roll-count-mod5="4"] > :nth-child(6n+3) { --spin: rotateX(0turn) rotateY(1turn) rotateZ(-3turn); }
#scene[data-roll-count-mod5="0"] > :nth-child(6n+4) { --spin: rotateX(0turn) rotateY(0turn) rotateZ(0turn); }
#scene[data-roll-count-mod5="1"] > :nth-child(6n+4) { --spin: rotateX(2turn) rotateY(-1turn) rotateZ(1turn); }
#scene[data-roll-count-mod5="2"] > :nth-child(6n+4) { --spin: rotateX(5turn) rotateY(0turn) rotateZ(0turn); }
#scene[data-roll-count-mod5="3"] > :nth-child(6n+4) { --spin: rotateX(2turn) rotateY(-1turn) rotateZ(1turn); }
#scene[data-roll-count-mod5="4"] > :nth-child(6n+4) { --spin: rotateX(0turn) rotateY(0turn) rotateZ(2turn); }
#scene[data-roll-count-mod5="0"] > :nth-child(6n+5) { --spin: rotateX(0turn) rotateY(0turn) rotateZ(0turn); }
#scene[data-roll-count-mod5="1"] > :nth-child(6n+5) { --spin: rotateX(2turn) rotateY(1turn) rotateZ(-2turn); }
#scene[data-roll-count-mod5="2"] > :nth-child(6n+5) { --spin: rotateX(0turn) rotateY(3turn) rotateZ(-1turn); }
#scene[data-roll-count-mod5="3"] > :nth-child(6n+5) { --spin: rotateX(-2turn) rotateY(1turn) rotateZ(0turn); }
#scene[data-roll-count-mod5="4"] > :nth-child(6n+5) { --spin: rotateX(0turn) rotateY(2turn) rotateZ(2turn); }
#scene[data-roll-count-mod5="0"] > :nth-child(6n+6) { --spin: rotateX(0turn) rotateY(0turn) rotateZ(0turn); }
#scene[data-roll-count-mod5="1"] > :nth-child(6n+6) { --spin: rotateX(-2turn) rotateY(2turn) rotateZ(1turn); }
#scene[data-roll-count-mod5="2"] > :nth-child(6n+6) { --spin: rotateX(1turn) rotateY(1turn) rotateZ(0turn); }
#scene[data-roll-count-mod5="3"] > :nth-child(6n+6) { --spin: rotateX(-1turn) rotateY(0turn) rotateZ(2turn); }
#scene[data-roll-count-mod5="4"] > :nth-child(6n+6) { --spin: rotateX(2turn) rotateY(1turn) rotateZ(1turn); }

/*
 * A cube
 */
.die {
	position: relative;
	width: var(--dieEdge);
	height: var(--dieEdge);
	transform: var(--pushToFloor);
	transform-style: preserve-3d;
	transition: transform 1s;
	pointer-events: auto;
	margin: auto;
}

/*
 * A face of a cube
 */
.face {
	position: absolute;
	width: 100%;
	height: 100%;
	color: white;
	font-size: calc(var(--dieEdge) / 2);
	display: flex;
}

/*
 * Each specific numbered face of a cube
 */
.face-1 { transform: rotateY(0turn) var(--pullToSurface); background-color: #07d; }
.face-2 { transform: rotateY(0.25turn) var(--pullToSurface); background-color: #08c; }
.face-3 { transform: rotateX(0.25turn) var(--pullToSurface); background-color: #09c; }
.face-4 { transform: rotateX(-0.25turn) var(--pullToSurface); background-color: #09c; }
.face-5 { transform: rotateY(-0.25turn) var(--pullToSurface); background-color: #08c; }
.face-6 { transform: rotateY(0.5turn) var(--pullToSurface); background-color: #06d; }

/*
 * Rotations to make a die show a particular face
 */
.die[data-result="1"] { transform: var(--pushToFloor) rotateY(0turn) var(--spin); }
.die[data-result="2"] { transform: var(--pushToFloor) rotateY(-0.25turn) var(--spin); }
.die[data-result="3"] { transform: var(--pushToFloor) rotateX(-0.25turn) var(--spin); }
.die[data-result="4"] { transform: var(--pushToFloor) rotateX(0.25turn) var(--spin); }
.die[data-result="5"] { transform: var(--pushToFloor) rotateY(0.25turn) var(--spin); }
.die[data-result="6"] { transform: var(--pushToFloor) rotateY(-0.5turn) var(--spin); }

/*
 * Centre the number within the die face
 */
.die span, .die svg {
	margin: auto;
}

/*
 * Choose between number styles based on user preference
 */
#scene[data-number-style="dots"] .die span {
	display: none;
}
#scene[data-number-style="numbers"] .die svg {
	display: none;
}

/*
 * Set the "dots" version's size and styling
 */
.die svg {
	width: 90%;
	height: 90%;
}
circle {
	fill: white;
}

/*
 * Roll history list
 */
#history {
	position: absolute;
	max-width: 100%;
	bottom: 0;
	overflow: auto;
	white-space: nowrap;
}
#history ol {
	display: flex;
	list-style-position: inside;
	align-items: baseline;
	padding: 0;
}
#history strong {
	font-size: 150%;
	transition: font-size 0.3s;
}
#history li {
	opacity: 0.4;
	transition: opacity 1s;
	padding-left: 0.5em;
	padding-right: 0.5em;
}
#history li + li {
	margin-left: 1em;
}
#history li:last-child {
	opacity: 1;
}
#history li:last-child strong {
	font-size: 450%;
}

/*
 * Title, instructions and configuration area
 */
header {
	position: absolute;
	padding: 0.5em;
	z-index: 3; /* 1 and 2 are not enough for Safari for some reason */
	background-color: rgba(255, 255, 255, 0.8);
}
header ul {
	list-style-type: none;
	padding: 0;
}
header li + li {
	margin-top: 0.5em;
}

#header-fullscreen-fallback {
	display: none;
}

/*
 * Link to source code
 */
footer {
	position: absolute;
	right: 0;
	top: 0;
	padding: 0.5em;
}

/*
 * Style overrides for dark mode
 */
@media (prefers-color-scheme: dark) {
	body {
		background-color: black;
		color: white;
	}
	a {
		color: cornflowerblue;
	}
	a:visited {
		color: violet;
	}
	:fullscreen {
		background-color: black;
	}
	header {
		background-color: rgba(0, 0, 0, 0.8);
	}
}
