/* http://meyerweb.com/eric/tools/css/reset/
   v2.0 | 20110126
   License: none (public domain) */

html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}

/* HTML5 display-role reset for older browsers */
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
	display: block;
}
body {
	line-height: 1;
}
ol,
ul {
	list-style: none;
}
blockquote,
q {
	quotes: none;
}
blockquote {
	&:before,
	&:after {
		content: '';
		content: none;
	}
}
q {
	&:before,
	&:after {
		content: '';
		content: none;
	}
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}

:root {
	--padding: 10px;
	--key-size: 60px;
	--selector-size: calc(var(--key-size) + 4px);
	--selector-border-size: 5px;
	--real-selector-size: calc(var(--selector-size) + 2 * var(--selector-border-size));
	--size: calc(var(--key-size) * 6 + var(--padding) * 2 + var(--selector-border-size) * 2);
	--orbit-size: calc(var(--key-size) * 5);
	--muted-color: #8c8c8c;
	--background-color: #181818;
	--text-color: #e1e1e1;
	--board-color: black;
	--left-color: #48ff3b;
	--up-color: #ff5252;
	--right-color: #00b2ff;
	--down-color: #ffff00;
	--life-color: white;
	--life-track-color: #2a2a2a;
	--life-chunk-color: #e5393f;
	--body-font: 'DM Mono', monospace;
	--display-font: 'Rubik Mono One', sans-serif;
}

@keyframes reversedfadein {
	0% {
		opacity: 0;
	}
	50% {
		opacity: 1;
	}
	100% {
		transform: scale(calc(1.2 * var(--scale-factor)));
		opacity: 0;
	}
}

@keyframes orbit {
	0% {
		opacity: 0;
		transform: translateY(250%) rotate(0deg) translateY(-250%) rotate(0deg) scale(1);
	}
	7% {
		opacity: 0;
		transform: translateY(250%) rotate(-25.2deg) translateY(-250%) rotate(25.2deg) scale(1);
	}
	10% {
		opacity: 1;
		transform: translateY(250%) rotate(-36deg) translateY(-250%) rotate(36deg) scale(1);
	}
	100% {
		opacity: 1;
		transform: translateY(250%) rotate(-360deg) translateY(-250%) rotate(360deg) scale(1);
	}
}

/* the mobile ring is 60% of the desktop one */
@keyframes mobile-orbit {
	0% {
		opacity: 0;
		transform: translateY(150%) rotate(0deg) translateY(-150%) rotate(0deg) scale(0.1);
	}
	10% {
		opacity: 0;
	}
	13% {
		opacity: 1;
	}
	20% {
		transform: translateY(150%) rotate(-72deg) translateY(-150%) rotate(72deg) scale(1);
	}
	100% {
		opacity: 1;
		transform: translateY(150%) rotate(-360deg) translateY(-150%) rotate(360deg) scale(1);
	}
}

@keyframes selector-bad {
	0% {
		background-color: rgba(255, 0, 0, 0);
	}
	50% {
		background-color: rgba(255, 0, 0, 0.3);
		transform: scale(0.95);
	}

	100% {
		background-color: rgba(255, 0, 0, 0);
		transform: scale(1);
	}
}

@keyframes selector-core-bad {
	50% {
		fill: rgba(255, 40, 40, 0.35);
	}
}

@keyframes mobile-selector-bad {
	0% {
		background-color: rgba(255, 0, 0, 0);
	}

	50% {
		background-color: rgba(255, 0, 0, 0.3);
	}

	100% {
		background-color: rgba(255, 0, 0, 0);
	}
}

@keyframes ding {
	0% {
		opacity: 1;
	}
	60% {
		opacity: 1;
	}
	100% {
		opacity: 0;
		transform: translateY(-30px);
	}
}

/* Punch: a hard push out that eases straight back, with no settle tail */
@keyframes selector-punch {
	0% {
		transform: scale(1);
	}
	20% {
		transform: scale(1.08);
		animation-timing-function: ease-out;
	}
	100% {
		transform: scale(1);
	}
}

@keyframes selector-frame-flash {
	from,
	to {
		stroke: currentColor;
	}
}

/* sin(90t) * 6px, fading out over 0.25s. It uses translate so it adds to the miss's scale. */
@keyframes selector-shake {
	0% {
		translate: 0 0;
	}
	7% {
		translate: 5.568px 0;
	}
	14% {
		translate: -0.374px 0;
	}
	21% {
		translate: -4.686px 0;
	}
	29% {
		translate: 0.621px 0;
	}
	36% {
		translate: 3.794px 0;
	}
	43% {
		translate: -0.742px 0;
	}
	50% {
		translate: -2.903px 0;
	}
	57% {
		translate: 0.737px 0;
	}
	64% {
		translate: 2.029px 0;
	}
	71% {
		translate: -0.609px 0;
	}
	79% {
		translate: -1.184px 0;
	}
	86% {
		translate: 0.362px 0;
	}
	93% {
		translate: 0.382px 0;
	}
	100% {
		translate: 0 0;
	}
}

/* two beats 0.14s apart, the second softer: each one thickens the band at once, then eases back */
@keyframes life-heartbeat {
	0% {
		stroke-width: 7;
	}
	15% {
		stroke-width: 5.44;
	}
	30% {
		stroke-width: 4.45;
	}
	48%,
	51% {
		stroke-width: 4;
	}
	52% {
		stroke-width: 5.5;
	}
	67% {
		stroke-width: 4.72;
	}
	85% {
		stroke-width: 4.15;
	}
	100% {
		stroke-width: 4;
	}
}

/* the counter jumps up on a point and settles straight back */
@keyframes points-bump {
	from {
		transform: scale(1.35);
	}
	to {
		transform: scale(1);
	}
}

@keyframes shutter-cover {
	from {
		transform: translateX(-100%);
	}
	to {
		transform: translateX(0);
	}
}

@keyframes shutter-uncover {
	from {
		transform: translateX(0);
	}
	to {
		transform: translateX(100%);
	}
}

/* the catch: pressed in at once, back out as 1 - 0.05 * exp(-25t) */
@keyframes selector-seat {
	0% {
		transform: scale(0.95);
	}
	20% {
		transform: scale(0.976);
	}
	40% {
		transform: scale(0.989);
	}
	67% {
		transform: scale(0.996);
	}
	100% {
		transform: scale(1);
	}
}

@keyframes selector-seat-flash {
	from,
	to {
		stroke: white;
	}
}

/* start screen: all four arrows breathe together, swelling and nudging out, easing back, then resting a beat */
@keyframes start-breathe {
	0% {
		scale: 1;
		translate: 0 0;
	}
	45% {
		scale: 1.08;
		translate: 0 -2px;
	}
	90%,
	100% {
		scale: 1;
		translate: 0 0;
	}
}

/* a steady arcade blink: full for two thirds of the beat, dimmed for the rest */
@keyframes start-blink {
	0%,
	100% {
		opacity: 1;
	}
	67% {
		opacity: 0.5;
	}
}

@media (prefers-reduced-motion: reduce) {
	@keyframes selector-bad {
		0%,
		100% {
			background-color: rgba(255, 0, 0, 0);
		}
		50% {
			background-color: rgba(255, 0, 0, 0.3);
		}
	}

	@keyframes selector-shake {
		from,
		to {
			transform: none;
		}
	}

	@keyframes selector-punch {
		from,
		to {
			transform: none;
		}
	}

	@keyframes selector-seat {
		from,
		to {
			transform: none;
		}
	}

	@keyframes points-bump {
		from,
		to {
			transform: none;
		}
	}

	@keyframes ding {
		0%,
		60% {
			opacity: 1;
		}
		100% {
			opacity: 0;
		}
	}

	@keyframes reversedfadein {
		0%,
		100% {
			opacity: 0;
		}
		50% {
			opacity: 1;
		}
	}

	@keyframes shutter-cover {
		from {
			transform: translateX(0);
			opacity: 0;
		}
		to {
			transform: translateX(0);
			opacity: 1;
		}
	}

	@keyframes shutter-uncover {
		from {
			transform: translateX(0);
			opacity: 1;
		}
		to {
			transform: translateX(0);
			opacity: 0;
		}
	}
}

body {
	font-family: var(--body-font);
	text-align: center;
	background-color: var(--background-color);
	padding-top: 20px;
	color: var(--text-color);
	margin: 0;
	overflow-x: hidden;

	h1,
	h2,
	h3 {
		font-family: var(--display-font);
		font-weight: normal;
	}

	h1 {
		display: inline-block;
		padding: 6px 10px 4px;
		border: 2px solid white;
		color: white;
		font-size: 11pt;
		margin-top: 10px;
		margin-bottom: 14px;
	}

	h2 {
		font-size: 12pt;
		margin-top: 23px;
		margin-bottom: 13px;
	}

	h3 {
		font-size: 10pt;
		margin-top: 6px;
		margin-bottom: 11px;
	}

	em {
		color: var(--up-color);
	}

	a,
	.link {
		text-decoration: none;
		font-weight: 500;
		color: var(--right-color);
	}

	.link {
		padding: 0;
		border: 0;
		background: none;
		font: inherit;
		font-weight: 500;
		cursor: pointer;
	}

	:focus-visible {
		outline: 2px solid var(--text-color);
		outline-offset: 2px;
	}

	strong {
		font-weight: 500;
	}

	hr {
		border: none;
		border-top: 1px solid #8b8b8b;
		margin-top: 40px;
	}
}

/* read by screen readers, not shown */
.sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* the page can be zoomed, but a double tap while playing shouldn't zoom it! */
.fullscreen-container {
	touch-action: manipulation;
}

.fullscreen-container.is-fullscreen {
	.container {
		height: calc(100vh - 150px);
		width: calc(100vh - 150px);
		max-width: 100vw;

		@media (any-pointer: coarse) {
			height: calc(100vh - 350px);
		}
	}

	/* scale sub containers to fit the parent, using some magic calculations */
	.keys-container,
	.key-selector-container,
	.level-message {
		transform: scale(var(--scale-factor));
	}
}

.container {
	max-width: var(--size);
	background-color: var(--board-color);
	border-radius: 5px;
	height: var(--size);
	position: relative;
	border-radius: 0;
	margin: 0 auto 10px auto;
	padding: 0;
	user-select: text;

	.keys-container {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
	}

	.key-selector-container {
		position: relative;
		z-index: 1;
		padding: var(--padding);

		&.hide {
			opacity: 0;
		}

		&.show {
			opacity: 1;
		}

		.key-selector {
			position: absolute;
			margin: 0 auto;
			left: 0;
			right: 0;
			width: var(--selector-size);
			height: var(--selector-size);
			opacity: 0;

			border: var(--selector-border-size) solid transparent;

			&.show {
				opacity: 1;
			}

			&.bad {
				animation:
					selector-bad 0.15s 1 ease-out,
					selector-shake 0.25s 1 linear;
			}

			> svg {
				position: absolute;
				top: calc(-1 * var(--selector-border-size));
				left: calc(-1 * var(--selector-border-size));
				width: var(--real-selector-size);
				height: var(--real-selector-size);
				overflow: visible;
			}

			/* The frame is the life band. It runs clockwise from the top middle, and a miss eats into it from the end. */
			.sel-life-track,
			.sel-life-chunk,
			.sel-life-band {
				fill: none;
				stroke-width: 4;
			}

			.sel-life-track {
				stroke: var(--life-track-color);
			}

			.sel-life-chunk {
				stroke: var(--life-chunk-color);
				stroke-dasharray: 0 100;
			}

			.sel-life-band {
				stroke: var(--life-color);
				stroke-dasharray: 100 100;
			}

			&.heal .sel-life-band {
				animation: life-heartbeat 0.27s 1 linear;
			}

			/* the flash comes last so it wins the stroke while both run */
			&.heal.punch .sel-life-band {
				animation:
					life-heartbeat 0.27s 1 linear,
					selector-frame-flash 0.1s 1 step-end;
			}

			.sel-body,
			.sel-plate {
				transform-box: fill-box;
				transform-origin: center;
			}

			/* a catch seats the arrow: the selector presses in and the glyph flashes white */
			&.seat {
				.sel-body {
					animation: selector-seat 0.15s 1 linear;
				}

				.sel-glyph-shape {
					animation: selector-seat-flash 0.07s 1 step-end;
				}
			}

			.sel-core {
				fill: transparent;
			}

			.sel-glyph {
				visibility: hidden;
				transform: rotate(var(--sel-angle));
			}

			/* a stance change snaps at once: the glyph turns and the plate punches out */
			&.punch {
				.sel-plate {
					animation: selector-punch 0.15s 1 linear;
				}

				.sel-life-band {
					animation: selector-frame-flash 0.1s 1 step-end;
				}
			}

			.sel-glyph-base,
			.sel-glyph-shape {
				fill: none;
				stroke-miterlimit: 10;
			}

			.sel-glyph-base {
				stroke: black;
				stroke-width: 19;
			}

			.sel-glyph-shape {
				stroke: currentColor;
				stroke-width: 11;
			}

			&.s-key-up {
				color: var(--up-color);
				--sel-angle: 0deg;
			}

			&.s-key-right {
				color: var(--right-color);
				--sel-angle: 90deg;
			}

			&.s-key-down {
				color: var(--down-color);
				--sel-angle: 180deg;
			}

			&.s-key-left {
				color: var(--left-color);
				--sel-angle: -90deg;
			}

			&:is(.s-key-up, .s-key-right, .s-key-down, .s-key-left) .sel-glyph {
				visibility: visible;
			}

			&.bad .sel-core {
				animation: selector-core-bad 0.15s 1 ease-out;
			}

			.ding {
				position: absolute;
				top: 0;
				left: 0;
				right: 0;
				margin: 0 auto;
				font-family: var(--display-font);
				font-size: 13pt;
				animation: ding 0.5s 1 ease-out;
				opacity: 0;
				color: var(--text-color);
			}
		}
	}

	.emblem {
		display: block;
		width: 96px;
		height: 96px;
		margin: 0 auto 28px auto;

		rect {
			fill: black;
		}

		.emblem-block {
			fill: white;
		}
	}

	.track {
		position: absolute;
		left: 0;
		right: 0;
		top: calc(var(--padding) + var(--selector-border-size) + var(--selector-size) * 0.5);
		width: var(--orbit-size);
		height: var(--orbit-size);
		margin: 0 auto;
		overflow: visible;
		opacity: 0;

		/* Leaves a gap in the ring where the selector sits, plus 10px of air on each side. The ring is drawn with
		   pathLength 360, so dash lengths are in degrees: the gap is asin((37px + 10px) / 150px) = 18.2602 on each
		   side of the 300px ring. CSS can't turn an angle into a plain number in the browsers we target, so the
		   values are precomputed (the mobile ring has its own in responsive.css). */
		circle {
			fill: none;
			stroke: #202020;
			stroke-dasharray: 323.4795441342 36.5204558658;
			/* the viewBox is 300 wide, so scale the stroke back to 2px on screen */
			stroke-width: 2px;
			transform-origin: center;
			transform: rotate(-71.7397720671deg);
		}

		&.show {
			opacity: 1;
		}
	}

	.key {
		position: absolute;
		margin: calc((var(--selector-size) - var(--key-size)) * 0.5) auto;
		left: 0;
		right: 0;
		width: var(--key-size);
		height: var(--key-size);
		animation: orbit 2s 1 linear;
		top: calc(var(--padding) + var(--selector-border-size));

		&.paused {
			animation-play-state: paused;
		}

		&.idle {
			animation: none;
			display: none;
		}

		&.hide svg {
			opacity: 0;
		}

		&.key-left {
			color: var(--left-color);

			svg {
				transform: rotate(-90deg);
			}
		}

		&.key-up {
			color: var(--up-color);

			svg {
				transform: rotate(0deg);
			}
		}

		&.key-right {
			color: var(--right-color);

			svg {
				transform: rotate(90deg);
			}
		}

		&.key-down {
			color: var(--down-color);

			svg {
				transform: rotate(180deg);
			}
		}
	}

	.level-message {
		display: none;
		position: absolute;
		left: 0;
		top: 0;
		line-height: calc(var(--size) * var(--scale-factor));
		width: 100%;
		height: 100%;
		font-size: 17px;

		&.show {
			display: block;
			animation: reversedfadein 1s;
		}
	}

	.helper-container {
		position: absolute;
		width: 100%;
		height: 100%;
		top: 0;
		left: 0;
		bottom: 0;

		&.hide {
			opacity: 0;
			visibility: hidden;
		}

		.start-screen {
			display: block;
			width: 100%;
			height: 100%;
		}

		text {
			font-family: var(--body-font);
			fill: white;
		}

		.cta {
			font-family: var(--display-font);
			font-size: 17px;
			text-anchor: middle;
		}

		.sub {
			font-size: 14px;
			font-weight: 500;
			fill: var(--muted-color);
			text-anchor: middle;
		}

		.key-base,
		.key-shape {
			fill: none;
			stroke-miterlimit: 10;
		}

		.key-base {
			stroke: black;
			stroke-width: 17;
		}

		.key-shape {
			stroke: currentColor;
			stroke-width: 11;
		}

		.up {
			color: var(--up-color);
		}

		.right {
			color: var(--right-color);
		}

		.down {
			color: var(--down-color);
		}

		.left {
			color: var(--left-color);
		}

		/* The arrows breathe together: a 3.6s breath of 1.6s in, 1.6s out and 0.4s rest, three blinks of the prompt long. */
		@media (prefers-reduced-motion: no-preference) {
			.cap {
				transform-box: fill-box;
				transform-origin: center;
				animation: start-breathe 3.6s ease-in-out infinite;
			}

			.prompt {
				animation: start-blink 1.2s step-end infinite;
			}
		}
	}

	/* One panel slides over the whole board, the screens swap under it, then it slides off. It is split into four
	   stripes of the stance colors that lag each other, so it reaches 18% past the board's right side for the most
	   lagging stripe to still cover it. */
	/* the board lets things like the "+x" rise past its edge, so the shutter clips itself */
	.shutter-frame {
		position: absolute;
		z-index: 10;
		inset: 0;
		overflow: hidden;
		pointer-events: none;
	}

	.shutter {
		position: absolute;
		top: 0;
		bottom: 0;
		left: 0;
		right: -18%;
		transform: translateX(-100%);
		pointer-events: none;

		/* the stripes lag each other, so the moving edges zigzag */
		> div {
			position: absolute;
			/* 1px taller, so no seam between stripes lets the board show through */
			height: calc(25% + 1px);
			left: 0;
			right: 0;
		}

		> div:nth-child(1) {
			top: 0;
			background-color: var(--left-color);
			transform: translateX(0);
		}

		> div:nth-child(2) {
			top: 25%;
			background-color: var(--up-color);
			transform: translateX(-5%);
		}

		> div:nth-child(3) {
			top: 50%;
			background-color: var(--right-color);
			transform: translateX(-10%);
		}

		> div:nth-child(4) {
			top: 75%;
			background-color: var(--down-color);
			transform: translateX(-15%);
		}

		&.cover {
			animation: shutter-cover 0.24s cubic-bezier(0.7, 0, 0.3, 1) both;
		}

		&.uncover {
			animation: shutter-uncover 0.24s cubic-bezier(0.7, 0, 0.3, 1) both;
		}
	}

	.results {
		position: absolute;
		z-index: 2;
		display: none;
		top: 0;
		left: 0;
		margin: 0;
		padding: 0;
		width: 100%;
		height: 100%;
		background-color: var(--board-color);
		border-radius: 5px;
		opacity: 0;

		&.show {
			display: table;
			opacity: 1;
		}

		&.hide {
			display: table;
			opacity: 0;
			visibility: hidden;
		}

		.results-container {
			display: table-cell;
			vertical-align: middle;

			.results-content {
				margin-left: auto;
				margin-right: auto;

				h2,
				p {
					margin: 0;
					color: white;
					font-size: 16px;
					font-weight: 500;
				}

				.results-label {
					font-family: var(--display-font);
					color: var(--muted-color);
				}

				h2 {
					margin: 6px 0 20px;
					font-size: 34px;
				}
			}
		}
	}

	.pause {
		position: absolute;
		z-index: 2;
		display: none;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background-color: var(--board-color);
		border-radius: 5px;
		overflow: hidden;

		&.show {
			display: table;
		}

		.pause-container {
			display: table-cell;
			vertical-align: middle;

			.pause-content {
				margin-left: auto;
				margin-right: auto;

				h2,
				p {
					margin: 0;
					color: white;
					font-size: 16px;
					font-weight: 500;
				}

				h2 {
					margin-bottom: 10px;
					font-size: 34px;
					text-transform: uppercase;
				}
			}
		}
	}
}

.points-container {
	max-width: calc(var(--size) + 2 * var(--padding));
	text-align: center;
	font-family: var(--display-font);
	font-size: 18px;
	color: white;
	margin: 0 auto 20px auto;
	opacity: 0;
	visibility: hidden;

	.points {
		display: inline-block;

		&.bump {
			animation: points-bump 0.17s 1 linear;
		}
	}

	&.hide {
		opacity: 0;
		visibility: hidden;
	}

	&.show {
		opacity: 1;
		visibility: visible;
	}
}

.best {
	max-width: var(--size);
	margin: 0 auto;
	text-align: right;
	padding-right: 5px;
	font-size: 16px;

	.best-points {
		font-weight: 500;
	}
}

.fullscreen-btn {
	max-width: var(--size);
	margin: 5px auto 0;
	text-align: right;
	padding-right: 5px;
	font-size: 16px;
}

.about {
	max-width: calc(var(--size) - 20px);
	margin: 0 auto;
	text-align: justify;
	font-size: 16px;
	padding-top: 20px;

	p {
		padding-top: 10px;
		padding-bottom: 10px;
	}

	.prim {
		color: var(--text-color);
		font-weight: 500;
	}

	.sec {
		color: var(--text-color);
		font-weight: 500;
	}

	.third {
		color: var(--up-color);
		font-weight: 500;
	}

	.key-up {
		display: inline-block;
		width: 16px;
		height: 16px;
		vertical-align: top;
		color: var(--up-color);

		svg {
			display: block;
			width: 100%;
			height: 100%;
		}
	}

	a,
	.link {
		text-decoration: underline;
	}

	.footer {
		text-align: right;
	}

	/* the heading icons, sized like Font Awesome's inline SVGs */
	.icon {
		box-sizing: content-box;
		display: inline-block;
		width: 1.25em;
		height: 1em;
		overflow: visible;
		vertical-align: -0.125em;
	}

	.icon-left {
		color: var(--left-color);
	}

	.icon-up {
		color: var(--up-color);
	}

	.icon-right {
		color: var(--right-color);
	}

	.icon-down {
		color: var(--down-color);
	}
}

footer.about {
	padding-top: 0;
}

.mobile-controls {
	position: relative;
	display: none;
	max-width: var(--size);
	margin: 0 auto;
	user-select: none;
	-webkit-touch-callout: none;
	-webkit-tap-highlight-color: transparent;

	.top,
	.bottom {
		display: flex;
		justify-content: center;
		gap: 10px;
		padding-bottom: 10px;
	}

	.key-up,
	.key-left,
	.key-down,
	.key-right {
		width: calc(var(--key-size) + 15px);
		height: calc(var(--key-size) + 15px);
		box-sizing: border-box;
		padding: 0;
		border: 3px solid white;
		background-color: black;
		cursor: pointer;
		/* a slide that starts on an arrow plays, one that starts beside them still scrolls the page */
		touch-action: none;

		svg {
			display: block;
			width: 100%;
			height: 100%;
		}

		&.pressed {
			background-color: currentColor;

			.key-base {
				display: none;
			}

			.key-shape {
				stroke: black;
			}
		}
	}

	.key-up {
		color: var(--up-color);

		svg {
			transform: rotate(0deg);
		}
	}

	.key-right {
		color: var(--right-color);

		svg {
			transform: rotate(90deg);
		}
	}

	.key-down {
		color: var(--down-color);

		svg {
			transform: rotate(180deg);
		}
	}

	.key-left {
		color: var(--left-color);

		svg {
			transform: rotate(-90deg);
		}
	}

	.pause-btn {
		position: absolute;
		top: 0;
		right: 0;
		margin-right: 7px;
		padding: 12px 14px;
		border: 0;
		background-color: white;
		color: black;
		font: inherit;
		font-family: var(--display-font);
		cursor: pointer;
		letter-spacing: 0.05em;
		text-transform: uppercase;
	}
}

.not-desktop {
	display: none;
}

@media (hover: none) and (pointer: coarse) {
	.desktop-only {
		display: none;
	}
	.not-desktop {
		display: block;
	}
}

@media (any-pointer: coarse) {
	.mobile-controls {
		display: block;
	}
}

/* Tablet */
@media (max-width: 1024px) {
	.container {
		.emblem {
			width: 64px;
			height: 64px;
			margin-bottom: 16px;
		}
	}
}

/* Mobile */
@media (max-width: 480px) {
	body {
		padding-top: 0;

		h1 {
			margin-top: 5px;
		}
	}

	.container {
		height: calc(var(--size) * 0.7);
		margin-top: 0;

		.key-selector-container {
			.key-selector {
				&.bad {
					animation:
						mobile-selector-bad 0.15s 1 ease-out,
						selector-shake 0.25s 1 linear;
				}
			}
		}

		.key {
			backface-visibility: hidden;
			animation: mobile-orbit 2s 1 linear;
			opacity: 1;
		}

		.track {
			width: calc(var(--orbit-size) * 0.6);
			height: calc(var(--orbit-size) * 0.6);

			/* the same gap as in layout.css, for the 180px ring: asin(47px / 90px) = 31.4814 */
			circle {
				stroke-dasharray: 297.0371356817 62.9628643183;
				stroke-width: 3.3333333333px;
				transform: rotate(-58.5185678408deg);
			}
		}

		.pause .pause-container .pause-content h2 {
			font-size: 28px;
		}

		.results .results-container .results-content h2 {
			margin-bottom: 12px;
			font-size: 28px;
		}
	}

	.about {
		padding-left: 15px;
		padding-right: 15px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.container .shutter > div:nth-child(n) {
		background-color: var(--board-color);
	}
}

:root{--background-color:#071318;--board-color:#061016;--text-color:#d9eeed;--body-font:system-ui,sans-serif;--display-font:system-ui,sans-serif;--up-color:#ff948e;--left-color:#85e5ab;--right-color:#62d8fa;--down-color:#ffe397;--muted-color:#88a7ac}body{background:radial-gradient(ellipse at 50% 0,#133b40 0, #071318 65%);min-height:100vh;padding:26px 0}body h1{font-size:38px;font-weight:800;letter-spacing:-1.5px;border:0;margin:0;padding:0}body h2{font-weight:750;letter-spacing:-.4px;font-size:23px}.eyebrow{font-size:10px;letter-spacing:2.4px;color:#87d9c7;margin:10px 0}.tagline{font-size:13px;color:#9bb8bd;margin:8px 0 18px}.container{isolation:isolate;border:1px solid #28535b;border-radius:24px;box-shadow:0 20px 70px #0008;overflow:hidden}.scene{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-1;pointer-events:none;opacity:var(--signal,1);transition:opacity .3s}.track{filter:drop-shadow(0 0 6px #75f2de)}.mobile-controls{display:block;margin-top:16px}.mobile-controls .top,.mobile-controls .bottom{display:inline-flex;gap:8px}.mobile-controls .top{padding:0 4px 0 0}.mobile-controls .key-up,.mobile-controls .key-left,.mobile-controls .key-down,.mobile-controls .key-right{width:52px;height:52px;border:1px solid #46656e;border-radius:12px;background:#0a2028}.mobile-controls .pause-btn{position:static;margin:0 0 0 8px;vertical-align:top;height:52px;border-radius:12px;font-size:10px;padding:0 13px;background:#c9eee7;color:#163c40}.best{font-size:12px;color:#9bb8bd;margin-top:12px}.fullscreen-btn{margin-top:10px;font-size:11px}.about.instructions{max-width:650px;margin:38px auto 0;text-align:left;background:#0b1e25;border:1px solid #224049;border-radius:22px;padding:24px 28px;font-size:14px;line-height:1.65}.instructions h2{margin:5px 0 12px}.rules{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin:22px 0}.rules p{font-size:12px;color:#9bb8bd}.rules strong{color:#a5e8d8;letter-spacing:1px;font-size:10px}.credit{border-top:1px solid #29424b;padding-top:17px;margin-top:24px;font-size:11px;color:#86a4ac}.helper-container .start-screen{filter:drop-shadow(0 2px 5px #000)}.points-container{margin:0 0 12px}.signal-hit{animation:signal-flash .35s}@keyframes signal-flash{50%{box-shadow:inset 0 0 55px #fb6f7388}}@media(max-width:480px){body{padding:14px 0}.about.instructions{margin:25px 12px 0;padding:20px}.container{border-radius:20px}.rules{gap:10px}.mobile-controls .key-up,.mobile-controls .key-left,.mobile-controls .key-down,.mobile-controls .key-right{width:48px;height:48px}.mobile-controls .pause-btn{height:48px}body h1{font-size:32px}.tagline{font-size:12px}}