@font-face {
	font-family: "Kode Mono";
	src: url("/fonts/KodeMono.woff2") format("woff2");
	font-weight: 400 700;
	font-display: swap;
}

/* The flashlight's position, animatable so the beam can glide */
@property --fx {
	syntax: "<percentage>";
	inherits: true;
	initial-value: 50%;
}

@property --fy {
	syntax: "<percentage>";
	inherits: true;
	initial-value: 42%;
}

:root {
	color-scheme: dark;
	interpolate-size: allow-keywords;
	--bg: #07080b;
	--bg-raised: #0d0f14;
	--panel: rgba(18, 20, 27, 0.78);
	--line: #232733;
	--line-strong: #353a49;
	--text: #ece9e2;
	--muted: #9b978e;
	--faint: #6b6860;
	--demon: #e5303f;
	--demon-glow: rgba(229, 48, 63, 0.35);
	--cyan: #19e3ff;
	--magenta: #ff2bd6;
	--good: #6fd08c;
	--warn: #f0b44c;
	--bad: #ff6a5e;
	--twitch: #9146ff;
	--twitch-hot: #a970ff;
	--steam: #1b2838;
	--steam-hot: #66c0f4;
	--mono: "Kode Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
	--sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
	--radius: 10px;
	--content: 1120px;
	--ease-out: cubic-bezier(0.2, 0.7, 0.2, 1);
	--ease-spring: cubic-bezier(0.3, 1.6, 0.5, 1);
}

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	scroll-behavior: smooth;
}

body {
	margin: 0;
	min-height: 100vh;
	background: var(--bg);
	color: var(--text);
	font: 16px/1.6 var(--sans);
	-webkit-font-smoothing: antialiased;
	overflow-x: hidden;
}

/* A faint CRT scanline over everything, like the game's monitor warp */
body::after {
	content: "";
	position: fixed;
	inset: 0;
	pointer-events: none;
	background: repeating-linear-gradient(to bottom, rgba(255, 255, 255, 0.025) 0 1px, transparent 1px 3px);
	mix-blend-mode: overlay;
	z-index: 50;
}

/* The bright band a CRT's refresh rolls down the screen */
body::before {
	content: "";
	position: fixed;
	left: 0;
	right: 0;
	top: -25vh;
	height: 25vh;
	pointer-events: none;
	background: linear-gradient(to bottom, transparent, rgba(255, 255, 255, 0.022) 50%, transparent);
	z-index: 51;
	animation: roll 11s linear infinite;
}

img {
	max-width: 100%;
	display: block;
}

a {
	color: var(--steam-hot);
}

h1,
h2,
h3 {
	margin: 0;
	font-family: var(--mono);
	font-weight: 700;
	line-height: 1.15;
}

p {
	margin: 0;
}

:focus-visible {
	outline: 2px solid var(--cyan);
	outline-offset: 3px;
	border-radius: 4px;
}

.skip {
	position: absolute;
	left: 16px;
	top: -60px;
	z-index: 60;
	padding: 8px 14px;
	background: var(--text);
	color: var(--bg);
	font-family: var(--mono);
	border-radius: 6px;
}

.skip:focus {
	top: 16px;
}

.sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/* Kode Mono has no Arabic, Hebrew or East Asian letters, and monospace fallbacks stretch them, so those scripts fall
   back to the system's own font while Latin words such as Twitch keep Kode Mono */
:root:lang(ar),
:root:lang(he),
:root:lang(ja),
:root:lang(ko),
:root:lang(zh) {
	--mono: "Kode Mono", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* Spaced out letters break up joined Arabic script and read oddly in Hebrew and East Asian scripts */
:lang(ar) *,
:lang(he) *,
:lang(ja) *,
:lang(ko) *,
:lang(zh) * {
	letter-spacing: normal !important;
}

/* Held back until the chosen language's words arrive, so the page never flashes up in English first */
.translating body {
	visibility: hidden;
}

/* --------------------------------------------------------------- language ---- */

.language {
	position: absolute;
	top: 18px;
	inset-inline-end: 18px;
	z-index: 5;
}

.language select {
	appearance: none;
	padding-block: 8px;
	padding-inline: 12px 34px;
	border: 1px solid var(--line-strong);
	border-radius: 8px;
	background:
		linear-gradient(45deg, transparent 50%, var(--muted) 50%) calc(100% - 18px) 52% / 5px 5px no-repeat,
		linear-gradient(135deg, var(--muted) 50%, transparent 50%) calc(100% - 13px) 52% / 5px 5px no-repeat,
		rgba(7, 8, 11, 0.72);
	color: var(--text);
	font: 600 13px/1.2 var(--mono);
	cursor: pointer;
	backdrop-filter: blur(6px);
	transition: border-color 0.2s ease;
}

[dir="rtl"] .language select {
	background-position:
		13px 52%,
		18px 52%,
		0 0;
}

.language select:hover,
.language select:focus-visible {
	border-color: var(--demon);
	outline: none;
}

.language option {
	background: var(--bg-raised);
	color: var(--text);
}

/* ------------------------------------------------------------------ hero ---- */

.hero {
	position: relative;
	overflow: hidden;
	min-height: min(92vh, 860px);
	display: grid;
	place-items: center;
	padding: 96px 20px 120px;
	text-align: center;
	isolation: isolate;
}

.hero-art {
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image: image-set(url("/img/hero-small.webp") 1x, url("/img/hero.webp") 2x);
	background-size: cover;
	background-position: 55% 40%;
	filter: saturate(0.9);
	transform: scale(1.06);
	animation:
		lamp 9s steps(1) infinite,
		drift 26s ease-in-out infinite alternate;
}

/* Darkens the aisle towards the edges */
.hero-art::after {
	content: "";
	position: absolute;
	inset: 0;
	background: radial-gradient(ellipse 70% 60% at 50% 45%, rgba(7, 8, 11, 0.25), rgba(7, 8, 11, 0.85) 75%);
}

/* Fades the art and the torch into the page. It sits still over the drifting art, so the fade always reaches the
   page colour by the hero's bottom edge. */
.hero::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	background:
		linear-gradient(to bottom, rgba(7, 8, 11, 0.35) 0%, rgba(7, 8, 11, 0) 22%),
		linear-gradient(to bottom, rgba(7, 8, 11, 0) 45%, rgba(7, 8, 11, 0.55) 70%, rgba(7, 8, 11, 0.9) 88%, var(--bg) 100%);
}

/* A torch over the aisle, following the pointer and wandering when left alone. The darkness is one flat layer with
   the beam's pattern masked out of it, so nothing stacks into a ring at the beam's edge, and the light is the same
   pattern screened on top. The script places the mask in pixels, centred until it runs. */
.hero-light {
	--beam: min(64vw, 640px);
	position: absolute;
	inset: 0;
	z-index: -1;
	overflow: hidden;
	pointer-events: none;
	animation: fade-in 1.6s ease 0.4s backwards;
}

.torch-dark {
	position: absolute;
	inset: 0;
	background: rgba(4, 5, 8, 0.42);
	-webkit-mask-image: url("/img/torch-mask.webp"), linear-gradient(#000, #000);
	mask-image: url("/img/torch-mask.webp"), linear-gradient(#000, #000);
	-webkit-mask-size: var(--beam) var(--beam), 100% 100%;
	mask-size: var(--beam) var(--beam), 100% 100%;
	-webkit-mask-position: var(--tx, 50%) var(--ty, 42%), 0 0;
	mask-position: var(--tx, 50%) var(--ty, 42%), 0 0;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-composite: xor;
	mask-composite: exclude;
}

.torch-glow {
	position: absolute;
	left: var(--fx);
	top: var(--fy);
	translate: -50% -50%;
	width: var(--beam);
	height: var(--beam);
	background: url("/img/torch-light.webp") center / 100% 100% no-repeat;
	mix-blend-mode: screen;
	animation: torch-flicker 6s steps(1) infinite;
}

.hero-inner {
	max-width: 760px;
	display: grid;
	justify-items: center;
	gap: 18px;
}

.hero-inner > * {
	animation: rise 0.9s var(--ease-out) backwards;
}

.logo {
	width: min(520px, 86vw);
	margin: 6px 0 2px;
	animation: none !important;
}

.logo img {
	width: 100%;
	height: auto;
	filter: drop-shadow(0 10px 40px rgba(0, 0, 0, 0.6));
	animation:
		power-on 1.3s var(--ease-out) 0.15s backwards,
		glitch 7s 3s infinite;
}

.tagline {
	font: 700 clamp(20px, 3.4vw, 30px) / 1.25 var(--mono);
	letter-spacing: 0.01em;
	text-shadow:
		-1px 0 rgba(25, 227, 255, 0.45),
		1px 0 rgba(255, 43, 214, 0.45);
	animation-delay: 0.7s;
}

.tagline-hot {
	display: block;
	color: var(--demon);
	text-shadow: 0 0 22px var(--demon-glow);
	animation: flicker-in 1.5s linear 1.15s backwards;
}

.lead {
	max-width: 600px;
	color: #c9c5bc;
	font-size: 17px;
	animation-delay: 0.9s !important;
}

.hero-actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 12px;
	margin-top: 8px;
	animation-delay: 1.05s !important;
}

.scroll-cue {
	position: absolute;
	left: 50%;
	bottom: 56px;
	width: 26px;
	height: 40px;
	margin-left: -13px;
	border: 1px solid rgba(236, 233, 226, 0.25);
	border-radius: 14px;
	animation: fade-in 1s ease 1.8s backwards;
}

.scroll-cue::after {
	content: "";
	position: absolute;
	left: 50%;
	top: 8px;
	width: 3px;
	height: 8px;
	margin-left: -1.5px;
	border-radius: 2px;
	background: var(--demon);
	animation: cue 1.8s var(--ease-out) infinite;
}

/* ---------------------------------------------------------------- buttons ---- */

.button {
	position: relative;
	overflow: hidden;
	isolation: isolate;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	min-height: 46px;
	padding: 0 22px;
	border: 1px solid transparent;
	border-radius: 8px;
	color: #fff;
	font: 700 14px/1 var(--mono);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	text-decoration: none;
	white-space: nowrap;
	cursor: pointer;
	transition:
		transform 0.2s var(--ease-out),
		background-color 0.2s ease,
		border-color 0.2s ease,
		box-shadow 0.2s ease,
		color 0.2s ease;
}

/* A sheen that sweeps across on hover */
.button::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: linear-gradient(110deg, transparent 30%, rgba(255, 255, 255, 0.22) 50%, transparent 70%);
	transform: translateX(-120%);
	transition: transform 0.7s var(--ease-out);
	pointer-events: none;
}

.button:hover {
	transform: translateY(-2px);
}

.button:hover::after {
	transform: translateX(120%);
}

.button:active {
	transform: translateY(0) scale(0.97);
	transition-duration: 0.08s;
}

.button.primary {
	background: var(--demon);
	box-shadow:
		0 0 0 1px rgba(255, 255, 255, 0.08) inset,
		0 8px 30px var(--demon-glow);
	animation: breathe 3.4s ease-in-out 2.4s infinite;
}

.button.primary:hover {
	background: #f23f4e;
}

.button.ghost {
	border-color: var(--line-strong);
	background: rgba(7, 8, 11, 0.5);
	color: var(--text);
	backdrop-filter: blur(4px);
}

.button.ghost:hover {
	border-color: #555b6d;
}

.button.twitch {
	background: var(--twitch);
}

.button.twitch:hover {
	background: var(--twitch-hot);
	box-shadow: 0 6px 24px rgba(145, 70, 255, 0.35);
}

.button.steam {
	background: linear-gradient(180deg, #2a475e, var(--steam));
	border-color: #3d6c8d;
}

.button.steam:hover {
	border-color: var(--steam-hot);
	box-shadow: 0 6px 24px rgba(102, 192, 244, 0.2);
}

.button.secondary {
	background: transparent;
	border-color: var(--line-strong);
	color: var(--muted);
	box-shadow: none;
}

.button.secondary:hover {
	border-color: #555b6d;
	color: var(--text);
}

.link-button {
	padding: 0;
	border: 0;
	background: none;
	color: var(--steam-hot);
	font: inherit;
	text-decoration: underline;
	cursor: pointer;
}

/* --------------------------------------------------------------- sections ---- */

main {
	display: grid;
	gap: 112px;
	max-width: var(--content);
	margin: -40px auto 0;
	padding: 0 20px 96px;
	position: relative;
}

.section-head {
	display: grid;
	gap: 10px;
	margin-bottom: 32px;
	max-width: 640px;
}

.kicker {
	color: var(--demon);
	font: 700 12px/1 var(--mono);
	letter-spacing: 0.24em;
	text-transform: uppercase;
}

.section-head h2 {
	font-size: clamp(28px, 4vw, 40px);
}

.section-lead {
	color: var(--muted);
}

/* ----------------------------------------------------------------- linking ---- */

.link {
	max-width: 760px;
	width: 100%;
	justify-self: center;
	padding: 36px;
	border: 1px solid var(--line);
	border-radius: 16px;
	background:
		linear-gradient(180deg, rgba(229, 48, 63, 0.06), transparent 40%),
		var(--panel);
	backdrop-filter: blur(10px);
	box-shadow: 0 30px 80px rgba(0, 0, 0, 0.55);
}

.link .section-head {
	margin-bottom: 24px;
}

.steps {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 12px;
}

.step {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: center;
	gap: 18px;
	padding: 18px 20px;
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: var(--bg-raised);
	transition:
		border-color 0.3s ease,
		background-color 0.3s ease;
}

.step:hover {
	background: #10131a;
}

.step-number {
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	border: 1px solid var(--line-strong);
	border-radius: 8px;
	color: var(--muted);
	font: 700 15px/1 var(--mono);
	transition:
		background-color 0.3s ease,
		border-color 0.3s ease;
}

.step h3 {
	font-size: 17px;
}

.step-text p {
	color: var(--muted);
	font-size: 14px;
	transition: color 0.3s ease;
}

.step.done {
	border-color: rgba(111, 208, 140, 0.35);
	animation: done-ring 1.1s var(--ease-out);
}

.step.done .step-number {
	position: relative;
	border-color: transparent;
	background: rgba(111, 208, 140, 0.14);
	color: transparent;
}

/* Drawn rather than typed, so it sits in the middle of the box whatever the font does with the glyph */
.step.done .step-number::after {
	content: "";
	position: absolute;
	left: 50%;
	top: 50%;
	width: 7px;
	height: 14px;
	border: solid var(--good);
	border-width: 0 2.5px 2.5px 0;
	translate: -50% -62%;
	rotate: 45deg;
	animation: pop 0.6s var(--ease-spring) 0.1s backwards;
}

.step.done .step-text p {
	color: var(--good);
}

.notice {
	margin: 0 0 16px;
	padding: 14px 18px;
	border-radius: var(--radius);
}

.notice.error {
	border: 1px solid rgba(255, 106, 94, 0.5);
	background: rgba(255, 106, 94, 0.08);
	color: var(--bad);
	animation: shake 0.5s ease 0.2s backwards;
}

.notice.linked {
	display: flex;
	gap: 16px;
	align-items: center;
	margin: 16px 0 0;
	border: 1px solid rgba(111, 208, 140, 0.35);
	background: rgba(111, 208, 140, 0.07);
	animation: slide-in 0.7s var(--ease-out) backwards;
}

.notice.linked[hidden] {
	display: none;
}

.notice.linked h3 {
	font-size: 17px;
	color: var(--good);
}

.notice.linked p {
	color: #bfe6cb;
	font-size: 14px;
}

.linked-mark {
	position: relative;
	flex: none;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: var(--good);
	color: transparent;
	animation:
		pop 0.6s var(--ease-spring) 0.3s backwards,
		halo 2.4s ease-out 1s 2;
}

/* The same drawn tick as a finished step, in the page's dark colour */
.linked-mark::after {
	content: "";
	position: absolute;
	left: 50%;
	top: 50%;
	width: 7px;
	height: 14px;
	border: solid var(--bg);
	border-width: 0 3px 3px 0;
	translate: -50% -62%;
	rotate: 45deg;
}

/* ------------------------------------------------------------------ skins ---- */

.skins {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	gap: 14px;
}

.skins > li {
	display: grid;
}

/* The card leans towards the pointer. The script sets the angles, the glare spot and the image's drift. */
.skin {
	--rx: 0deg;
	--ry: 0deg;
	--lift: 0px;
	position: relative;
	display: grid;
	/* The column never grows to fit a long word, or the picture above it would grow with it */
	grid-template-columns: minmax(0, 1fr);
	grid-template-rows: auto 1fr;
	overflow: hidden;
	border: 1px solid var(--line);
	border-radius: 12px;
	background:
		radial-gradient(ellipse 80% 40% at 50% 92%, rgba(229, 48, 63, 0.22), transparent 70%),
		linear-gradient(180deg, #0f1117, #0a0b0f);
	transform: perspective(900px) rotateX(var(--rx)) rotateY(var(--ry)) translateY(var(--lift));
	transition:
		transform 0.45s var(--ease-out),
		border-color 0.3s ease,
		box-shadow 0.3s ease;
}

.skin.tilting {
	transition:
		transform 0.1s linear,
		border-color 0.3s ease,
		box-shadow 0.3s ease;
}

.skin:hover {
	--lift: -6px;
	border-color: rgba(229, 48, 63, 0.55);
	box-shadow: 0 22px 60px rgba(229, 48, 63, 0.2);
}

/* Glare where the pointer is */
.skin::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 3;
	pointer-events: none;
	background: radial-gradient(circle at var(--gx, 50%) var(--gy, 0%), rgba(255, 255, 255, 0.1), transparent 55%);
	opacity: 0;
	transition: opacity 0.35s ease;
}

.skin:hover::after {
	opacity: 1;
}

/* A sweep of light across a skin once it's in the inventory */
.skin::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 2;
	pointer-events: none;
	background: linear-gradient(115deg, transparent 35%, rgba(111, 208, 140, 0.28) 50%, transparent 65%);
	transform: translateX(-110%);
}

/* Played once the card is on screen, or straight away when there's no motion script to bring it on */
.is-in > .skin.delivered::before,
html:not(.motion) .skin.delivered::before {
	animation: shine 1.5s var(--ease-out) calc(0.5s + var(--i, 0) * 90ms) both;
}

.skin-art {
	position: relative;
	aspect-ratio: 1 / 2;
	padding: 10px 6px 0;
}

/* Embers under each figure, out of step with their neighbours */
.skin-art::before {
	content: "";
	position: absolute;
	left: 8%;
	right: 8%;
	bottom: -14px;
	height: 38%;
	background: radial-gradient(ellipse at 50% 100%, color-mix(in srgb, var(--rarity-a, #e5303f) 45%, transparent), transparent 70%);
	filter: blur(6px);
	animation: ember 4.2s ease-in-out infinite;
	animation-delay: calc(var(--i, 0) * -0.7s);
}

/* The picture only chooses between the idle loop and the still, the image inside sizes itself */
.skin-art picture {
	display: contents;
}

.skin-art img {
	position: relative;
	width: 100%;
	height: 100%;
	object-fit: contain;
	object-position: bottom;
	filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.7));
	/* --fit grows a figure the render had to shrink to fit its pose's width, so every crew member stands about as tall,
	   with anything that then spills past the card's edges clipped. It grows from the feet, so they stay on the floor. */
	transform: translate3d(calc(var(--mx, 0) * 2px), calc(var(--my, 0) * 1px), 0) scale(calc(var(--zoom, 1) * var(--fit, 1)));
	transform-origin: 50% 96.4%;
	transition:
		transform 0.45s var(--ease-out),
		filter 0.45s ease;
}

.skin:hover .skin-art img {
	--zoom: 1.015;
}

/* Each rarity's colours. The card's bar is a solid gradient of them and its embers take the first. */
.skin[data-rarity="common"] {
	--rarity-a: #5b616e;
	--rarity-b: #2b2f38;
}

.skin[data-rarity="uncommon"] {
	--rarity-a: #3f9a5c;
	--rarity-b: #1c4a2b;
}

.skin[data-rarity="rare"] {
	--rarity-a: #3b7ee0;
	--rarity-b: #173a78;
}

.skin[data-rarity="epic"] {
	--rarity-a: #9a4ae0;
	--rarity-b: #48206f;
}

.skin[data-rarity="legendary"] {
	--rarity-a: #e0a43b;
	--rarity-b: #7a4a12;
}

.skin[data-rarity="exclusive"] {
	--rarity-a: #e5303f;
	--rarity-b: #5e0f18;
}

.skin-info {
	position: relative;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 4px;
	padding: 12px 14px 14px;
	border-top: 1px solid color-mix(in srgb, var(--rarity-a, #5b616e) 70%, #fff);
	background: linear-gradient(160deg, var(--rarity-a, #5b616e), var(--rarity-b, #2b2f38));
	box-shadow: 0 -10px 24px -10px var(--rarity-a, transparent);
}

.skin-rarity {
	color: rgba(255, 255, 255, 0.75);
	font: 700 10px/1 var(--mono);
	letter-spacing: 0.22em;
	text-transform: uppercase;
}

.skin-name {
	font: 700 15px/1.2 var(--mono);
	color: #fff;
	text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
}

.skin-crew {
	color: rgba(255, 255, 255, 0.72);
	font-size: 12px;
}

.badge {
	align-self: flex-start;
	margin-top: auto;
	padding: 4px 7px;
	border: 1px solid rgba(255, 255, 255, 0.2);
	border-radius: 999px;
	background: rgba(7, 8, 11, 0.45);
	color: rgba(255, 255, 255, 0.85);
	max-width: 100%;
	font: 600 10px/1.2 var(--mono);
	letter-spacing: 0.03em;
	text-transform: uppercase;
	/* Some languages need two lines, which beats losing the end of the words */
	overflow-wrap: anywhere;
	transition:
		background-color 0.3s ease,
		color 0.3s ease,
		border-color 0.3s ease;
}

/* The pill on a skin not earned yet opens the game's Twitch category */
a.badge {
	text-decoration: none;
	cursor: pointer;
	transition:
		background-color 0.25s ease,
		border-color 0.25s ease,
		color 0.25s ease,
		translate 0.25s var(--ease-out);
}

a.badge::after {
	content: "↗";
	display: inline-block;
	margin-left: 3px;
	transition: translate 0.25s var(--ease-out);
}

a.badge:hover {
	border-color: var(--twitch-hot);
	background: var(--twitch);
	color: #fff;
}

a.badge:hover::after {
	translate: 2px -2px;
}

.is-in > .skin:not(.none) .badge,
html:not(.motion) .skin:not(.none) .badge {
	animation: pop 0.55s var(--ease-spring) calc(0.4s + var(--i, 0) * 90ms) backwards;
}

.skin.delivered {
	border-color: rgba(111, 208, 140, 0.45);
}

.skin.delivered .badge {
	border-color: rgba(111, 208, 140, 0.5);
	background: rgba(7, 20, 12, 0.7);
	color: var(--good);
}

.skin.sending .badge,
.skin.waiting .badge {
	border-color: rgba(240, 180, 76, 0.5);
	background: rgba(24, 16, 4, 0.7);
	color: var(--warn);
}

/* A beating dot while a skin is still on its way */
.skin.sending .badge::before,
.skin.waiting .badge::before {
	content: "";
	display: inline-block;
	width: 6px;
	height: 6px;
	margin-right: 6px;
	border-radius: 50%;
	background: currentColor;
	vertical-align: 1px;
	animation: blink 1.2s ease-in-out infinite;
}

.skin.problem .badge {
	border-color: rgba(255, 106, 94, 0.5);
	background: rgba(26, 8, 6, 0.7);
	color: var(--bad);
}

/* ------------------------------------------------------------ how it works ---- */

.how-steps {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 14px;
}

.how-steps li {
	display: grid;
	gap: 10px;
	align-content: start;
	padding: 24px;
	border: 1px solid var(--line);
	border-radius: 12px;
	background: var(--bg-raised);
	transition:
		translate 0.35s var(--ease-out),
		border-color 0.35s ease,
		box-shadow 0.35s ease;
}

.how-steps li:hover {
	translate: 0 -4px;
	border-color: rgba(229, 48, 63, 0.4);
	box-shadow: 0 18px 40px rgba(0, 0, 0, 0.4);
}

.how-number {
	color: transparent;
	font: 700 44px/1 var(--mono);
	-webkit-text-stroke: 1px rgba(229, 48, 63, 0.6);
	transition: color 0.35s ease;
}

.how-steps li:hover .how-number {
	color: rgba(229, 48, 63, 0.28);
}

.how-steps h3 {
	font-size: 20px;
}

.how-steps p {
	color: var(--muted);
	font-size: 15px;
}

/* -------------------------------------------------------------------- faq ---- */

.faq-list {
	display: grid;
	gap: 10px;
	max-width: 820px;
}

details {
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: var(--bg-raised);
	transition:
		border-color 0.3s ease,
		background-color 0.3s ease;
}

details:hover {
	border-color: var(--line-strong);
}

details[open] {
	border-color: rgba(229, 48, 63, 0.35);
	background: #10121a;
}

/* Answers slide open where the browser can animate to their height */
details::details-content {
	block-size: 0;
	overflow: hidden;
	transition:
		block-size 0.4s var(--ease-out),
		content-visibility 0.4s allow-discrete;
}

details[open]::details-content {
	block-size: auto;
}

summary {
	position: relative;
	padding: 18px 52px 18px 20px;
	font: 700 15px/1.4 var(--mono);
	cursor: pointer;
	list-style: none;
	transition: color 0.2s ease;
}

summary:hover {
	color: #fff;
}

summary::-webkit-details-marker {
	display: none;
}

summary::after {
	content: "+";
	position: absolute;
	right: 20px;
	top: 50%;
	translate: 0 -50%;
	color: var(--demon);
	font-size: 22px;
	transition: rotate 0.35s var(--ease-spring);
}

details[open] summary::after {
	rotate: 135deg;
}

details p {
	padding: 0 20px 18px;
	color: var(--muted);
	opacity: 0;
	translate: 0 -6px;
	transition:
		opacity 0.35s ease 0.08s,
		translate 0.35s var(--ease-out) 0.08s;
}

details[open] p {
	opacity: 1;
	translate: 0 0;
}

/* ----------------------------------------------------------------- footer ---- */

.footer {
	display: grid;
	gap: 8px;
	padding: 32px 20px 48px;
	border-top: 1px solid var(--line);
	color: var(--faint);
	font-size: 13px;
	text-align: center;
}

.footer p {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 10px;
}

.footer a {
	color: var(--muted);
	transition: color 0.2s ease;
}

.footer a:hover {
	color: var(--text);
}

.footer .fine {
	font-size: 12px;
}

/* -------------------------------------------------------- scroll reveals ---- */

/* Only once the boot script says motion is on, so the page never hides itself without the script to show it */
.motion [data-reveal] {
	--d: calc(var(--i, 0) * 90ms);
	opacity: 0;
	transform: translateY(28px);
	transition:
		opacity 0.8s var(--ease-out) var(--d),
		transform 0.8s var(--ease-out) var(--d),
		translate 0.35s var(--ease-out),
		border-color 0.35s ease,
		box-shadow 0.35s ease;
}

.motion [data-reveal].is-in {
	opacity: 1;
	transform: none;
}

.motion .skins > [data-reveal] {
	transform: translateY(36px) scale(0.96);
}

.motion .skins > [data-reveal].is-in {
	transform: none;
}

/* Section labels type themselves out and headings resolve from an RGB split */
.motion .section-head .kicker {
	clip-path: inset(0 100% 0 0);
	transition: clip-path 0.7s steps(16) 0.25s;
}

.motion .section-head.is-in .kicker {
	clip-path: inset(0 0 0 0);
}

.motion .section-head.is-in h2 {
	animation: heading-in 1s var(--ease-out) 0.1s backwards;
}

.motion .how-steps .is-in .how-number {
	animation: number-in 0.9s var(--ease-out) calc(0.2s + var(--i, 0) * 90ms) backwards;
}

/* ------------------------------------------------------------------ motion ---- */

@keyframes rise {
	from {
		opacity: 0;
		transform: translateY(18px);
		filter: blur(6px);
	}
}

@keyframes fade-in {
	from {
		opacity: 0;
	}
}

/* A CRT tube warming up, a bright line opening into the picture */
@keyframes power-on {
	0% {
		opacity: 0;
		transform: scale(0.3, 0.01);
		filter: brightness(5);
	}
	14% {
		opacity: 1;
		transform: scale(1, 0.015);
		filter: brightness(5);
	}
	32% {
		transform: scale(1, 1.06);
		filter: brightness(2.2);
	}
	44% {
		transform: none;
		filter: brightness(1.4) drop-shadow(0 10px 40px rgba(0, 0, 0, 0.6));
	}
	50% {
		opacity: 0.5;
	}
	56% {
		opacity: 1;
	}
	62% {
		opacity: 0.75;
	}
	70%,
	100% {
		opacity: 1;
		transform: none;
		filter: drop-shadow(0 10px 40px rgba(0, 0, 0, 0.6));
	}
}

@keyframes flicker-in {
	0% {
		opacity: 0;
	}
	8% {
		opacity: 0.9;
	}
	12% {
		opacity: 0.1;
	}
	26% {
		opacity: 1;
	}
	30% {
		opacity: 0.25;
	}
	44%,
	100% {
		opacity: 1;
	}
}

/* An occasional RGB tear across the logo, echoing its split edges */
@keyframes glitch {
	0%,
	91%,
	100% {
		transform: none;
		filter: drop-shadow(0 10px 40px rgba(0, 0, 0, 0.6));
	}
	92% {
		transform: translate(-3px, 1px) skewX(-4deg);
		filter: drop-shadow(-4px 0 0 rgba(25, 227, 255, 0.7)) drop-shadow(4px 0 0 rgba(255, 43, 214, 0.7));
	}
	93% {
		transform: translate(3px, -1px);
		filter: drop-shadow(3px 0 0 rgba(25, 227, 255, 0.6)) drop-shadow(-3px 0 0 rgba(255, 43, 214, 0.6));
	}
	94% {
		transform: none;
	}
}

/* The aisle's lights stutter now and then */
@keyframes lamp {
	0%,
	100% {
		opacity: 1;
	}
	71% {
		opacity: 0.82;
	}
	72% {
		opacity: 1;
	}
	74% {
		opacity: 0.88;
	}
	75% {
		opacity: 1;
	}
}

/* A torch's bulb isn't perfectly steady */
@keyframes torch-flicker {
	0%,
	100% {
		opacity: 1;
	}
	62% {
		opacity: 0.86;
	}
	63% {
		opacity: 1;
	}
	64% {
		opacity: 0.9;
	}
	65% {
		opacity: 1;
	}
}

@keyframes drift {
	to {
		transform: scale(1.12) translate(-1.5%, -1%);
	}
}

@keyframes roll {
	to {
		transform: translateY(150vh);
	}
}

@keyframes cue {
	0% {
		opacity: 0;
		transform: translateY(0);
	}
	30% {
		opacity: 1;
	}
	100% {
		opacity: 0;
		transform: translateY(14px);
	}
}

@keyframes breathe {
	50% {
		box-shadow:
			0 0 0 1px rgba(255, 255, 255, 0.08) inset,
			0 10px 46px rgba(229, 48, 63, 0.6);
	}
}

@keyframes pop {
	from {
		opacity: 0;
		transform: scale(0.3) rotate(-25deg);
	}
}

@keyframes done-ring {
	from {
		box-shadow: 0 0 0 0 rgba(111, 208, 140, 0.45);
	}
	to {
		box-shadow: 0 0 0 14px rgba(111, 208, 140, 0);
	}
}

@keyframes halo {
	from {
		box-shadow: 0 0 0 0 rgba(111, 208, 140, 0.5);
	}
	to {
		box-shadow: 0 0 0 16px rgba(111, 208, 140, 0);
	}
}

@keyframes slide-in {
	from {
		opacity: 0;
		transform: translateY(12px) scale(0.98);
	}
}

@keyframes shake {
	0%,
	100% {
		transform: none;
	}
	20%,
	60% {
		transform: translateX(-6px);
	}
	40%,
	80% {
		transform: translateX(6px);
	}
}

@keyframes shine {
	from {
		transform: translateX(-110%);
	}
	to {
		transform: translateX(110%);
	}
}

@keyframes ember {
	50% {
		opacity: 0.5;
		transform: scaleX(0.85);
	}
}

@keyframes blink {
	50% {
		opacity: 0.25;
	}
}

@keyframes heading-in {
	0% {
		opacity: 0;
		letter-spacing: 0.12em;
		filter: blur(4px);
		text-shadow:
			-8px 0 rgba(25, 227, 255, 0.8),
			8px 0 rgba(255, 43, 214, 0.8);
	}
	60% {
		opacity: 1;
		filter: none;
		text-shadow:
			-2px 0 rgba(25, 227, 255, 0.5),
			2px 0 rgba(255, 43, 214, 0.5);
	}
	100% {
		text-shadow: none;
	}
}

@keyframes number-in {
	from {
		opacity: 0;
		transform: translateX(-14px);
		color: rgba(229, 48, 63, 0.6);
	}
}

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation: none !important;
		transition: none !important;
	}

	body::before,
	.hero-light,
	.scroll-cue {
		display: none;
	}
}

/* ------------------------------------------------------------------ layout ---- */

@media (max-width: 1000px) {
	.skins {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (max-width: 720px) {
	main {
		gap: 80px;
	}

	.hero {
		min-height: 0;
		padding: 72px 18px 96px;
	}

	.scroll-cue {
		display: none;
	}

	.link {
		padding: 22px 16px;
	}

	.step {
		grid-template-columns: auto 1fr;
	}

	.step .button {
		grid-column: 1 / -1;
		width: 100%;
	}

	.skins {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.how-steps {
		grid-template-columns: 1fr;
	}
}
