/* Wonky Racers, the look of the logo on every screen
   Warm paper stickers with painted edges, soft depth and chunky uppercase headings,
   the orange of the logo on the one thing to press, and everything sitting a little crooked */

@font-face {
	font-family: "Lilita One";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("/assets/fonts/LilitaOne-400.woff2") format("woff2");
}

@font-face {
	font-family: "Nunito";
	font-style: normal;
	font-weight: 600 900;
	font-display: swap;
	src: url("/assets/fonts/Nunito-900.woff2") format("woff2");
}

@font-face {
	font-family: "Caveat";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("/assets/fonts/Caveat-600.woff2") format("woff2");
}

:root {
	color-scheme: dark;
	--ink: #2b1d12;
	--ink-soft: #705039;
	--paper: #f6e9cf;
	--paper-bright: #fff3d6;
	--white: #fffdf7;
	--orange: #ff9f1c;
	--orange-light: #ffc457;
	--orange-deep: #ff8a00;
	--accent-ink: #a54c08;
	--green: #3ddc84;
	--red: #d9403a;
	--red-light: #ff7a72;
	--blue: #2f80ed;
	/* The darkness the gate casts, and the page under everything, so the first paint is already the gate's dark and
	   there is no lighter flash before the game mounts */
	--dark: #0b0a12;
	--line: 2px solid color-mix(in srgb, var(--ink) 72%, var(--paper));
	/* Blue paper ruled like a blueprint, and the pale ink of its edge, behind anything that is drawn and not built */
	--blueprint: #2f5fb3;
	--blueprint-rule: linear-gradient(rgba(255, 255, 255, 0.12) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, 0.12) 1px, transparent 1px);
	--blueprint-edge: #dbe9ff;
	--shadow-ink: color-mix(in srgb, var(--ink) 42%, transparent);
	--radius: 18px;
	--menu-width: 1400px;
	--display: "Lilita One", "Impact", "Arial Black", sans-serif;
	--font: "Nunito", "Segoe UI", system-ui, -apple-system, sans-serif;
	/* Cream text sitting straight on the level behind gets an ink outline so it reads on any sky */
	--outline: 3px 3px 0 var(--ink), -2px -2px 0 var(--ink), 2px -2px 0 var(--ink), -2px 2px 0 var(--ink), 2px 2px 0 var(--ink), 0 -2px 0 var(--ink), 0 2px 0 var(--ink), -2px 0 0 var(--ink), 2px 0 0 var(--ink);
	/* The darkness creeping into the corners over whatever the screens are standing on. Eases in from well inside so
	   it never shows an edge, and still ends dark in the corners */
	--vignette: radial-gradient(ellipse at center, transparent 40%, color-mix(in srgb, var(--ink) 12%, transparent) 62%, color-mix(in srgb, var(--ink) 40%, transparent) 82%, color-mix(in srgb, var(--ink) 75%, transparent) 100%);
}

* {
	box-sizing: border-box;
	scrollbar-width: thin;
	scrollbar-color: var(--ink-soft) transparent;
}

html, body {
	margin: 0;
	height: 100%;
	overflow: hidden;
	background: var(--dark);
	color: var(--ink);
	font-family: var(--font);
	font-weight: 700;
	font-size: 16px;
	touch-action: manipulation;
}

/* The world fills the same box as the page over it, the one the browser leaves us. Sized in vh it would be the
   height of the window with the phone's address bar retracted, which is taller than what is on show while the bar is
   there, and the world then painted below the page's own screens: on a phone the credits ended in a bright strip of
   undimmed level */
canvas.world, canvas.overlay {
	position: fixed;
	inset: 0;
	/* A canvas is a picture, so it keeps its own size against insets alone and has to be told, and it is told in the
	   share of the box the page over it gets, never in vh */
	width: 100%;
	height: 100%;
	display: block;
	touch-action: none;
}

/* The editors draw their lines on the overlay, every pointer event goes through it to the world */
canvas.overlay {
	pointer-events: none;
}

.page {
	--corner-inset: 24px;
	--corner-step: min(80px, calc((100vw - 2 * var(--corner-inset) - 64px) / 3));
	position: fixed;
	inset: 0;
	pointer-events: none;
}

.page > * {
	pointer-events: auto;
}

/* A vignette over the world, the same on every screen, painted before the page's own screens so it sits under every one of them */
.page::before {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--vignette);
}

/* While the player is driving, in the level editor or in the workshop the vignette is faint, the world is what matters */
.page:has(> .hud:not(.hidden), > .map-editor:not(.hidden), > .workshop:not(.hidden))::before {
	opacity: 0.3;
}

/* The interface is frozen while anything is on its way in or out, nothing takes a click, a tap or a hover, however
   deep and whatever it set for itself, so no button lifts or sounds. freeze() in dom.ts is the only thing that sets this */
body.busy, body.busy *, body.busy *::before, body.busy *::after {
	pointer-events: none !important;
}

.hidden {
	display: none !important;
}

.screen {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	padding: 32px;
	animation: rise 320ms cubic-bezier(0.2, 0.9, 0.3, 1.2);
}

@keyframes sink {
	to {
		opacity: 0;
		transform: translateY(18px) scale(0.98);
	}
}

@keyframes rise {
	from {
		opacity: 0;
		transform: translateY(18px) scale(0.98);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

/* Type */

h1, h2, h3 {
	font-family: var(--display);
	font-weight: 400;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	margin: 0;
}

.muted {
	color: var(--ink-soft);
}

/* Paper buttons that lift gently and press down */

button {
	font-family: var(--display);
	font-weight: 400;
	font-size: 18px;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	color: var(--ink);
	--face: var(--paper);
	border-radius: 12px;
	--lift: 4px;
	padding: 10px 20px;
	cursor: pointer;
	transition: transform 140ms ease, opacity 140ms ease;
}

button:hover:not(:disabled) {
	transform: translate(-1px, -1px);
	--lift: 5px;
}

button:active:not(:disabled) {
	transform: translate(1px, 2px);
	--lift: 1px;
}

button:disabled {
	opacity: 0.58;
	cursor: not-allowed;
	transform: none;
	--lift: 4px;
}

button.primary {
	--face: linear-gradient(var(--orange-light), var(--orange));
}

button.big {
	font-size: 26px;
	padding: 14px 34px;
	--lift: 6px;
}

button.big:hover {
	--lift: 8px;
}

button.big:active {
	--lift: 2px;
}

button.primary.big {
	font-size: 36px;
	padding: 16px 56px;
}

button.link {
	font-family: var(--font);
	font-weight: 900;
	font-size: 16px;
	text-transform: none;
	letter-spacing: 0;
	--face: transparent;
	--edge: 0px;
	--shade: transparent;
	padding: 6px 10px;
	color: var(--ink-soft);
}

button.link:hover {
	transform: none;
	color: var(--ink);
}

.buttons {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 14px;
	justify-content: center;
	margin-top: 20px;
}

.buttons.left {
	justify-content: flex-start;
	margin: 10px 0;
}

/* Tabs, small round chips, the picked one inked in */

.tabs {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 14px 0 10px;
}

.tab {
	font-family: var(--font);
	font-weight: 900;
	font-size: 14px;
	text-transform: none;
	letter-spacing: 0;
	padding: 6px 14px;
	border-radius: 999px;
	--face: var(--white);
	--shade: transparent;
}

.tab:hover {
	transform: none;
	--face: var(--paper-bright);
}

.tab:active {
	transform: translate(1px, 1px);
}

/* A picked tab is active and pressing it again does nothing, a switch that is on can be pressed again to turn it off */
.tab.active, .tab.on {
	--face: var(--ink);
	color: var(--paper);
}

/* Fields */

input, select, textarea {
	color-scheme: light;
	font: inherit;
	color: var(--ink);
}

.field input, .field select, .field textarea, .chat-input, .editor-name, .editor-field textarea, .editor-field input[type="number"], .level-version, .level-search, .dev-controls select, .dev-controls input[type="text"], .admin-actions select, .admin-fields select, .admin-string-input, .admin-file {
	font-weight: 700;
	background: var(--white);
	border: var(--line);
	border-radius: 10px;
	padding: 8px 12px;
	outline: none;
}

.field select:focus, .level-version:focus, .field input:focus, .field textarea:focus, .chat-input:focus, .editor-name:focus, .editor-field textarea:focus, .editor-field input[type="number"]:focus, .level-search:focus {
	background: #ffffff;
	box-shadow: inset 0 0 0 2px var(--orange);
}

button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible, [tabindex="0"]:focus-visible {
	outline: 3px solid var(--blue);
	outline-offset: 4px;
}

input[type="range"] {
	accent-color: var(--orange-deep);
}

input[type="checkbox"] {
	accent-color: var(--orange-deep);
	width: 18px;
	height: 18px;
}

/* Stickers, every panel is one */

.paper-panel, .menu-card, .leaderboard, .level-list, .map-list, .settings-section, .result-box, .dialog, .sticker, .hud-board, .editor-panel, .editor-menu, .build-notice, .hud-stats {
	--face: linear-gradient(145deg, var(--paper-bright), var(--paper));
	color: var(--ink);
	border-radius: var(--radius);
	--lift: 3px;
}

/* Text straight on the level behind, cream with an ink edge */

.outlined, .screen-heading h1, .map-column h2, .hud-timer, .gate-text, .gate-wait, .menu-hint {
	color: var(--paper);
	text-shadow: var(--outline);
}

/* The way back is a real button, a plain link vanished against the sky */
.screen-heading button.link, .editor-top-bar button.link {
	font-family: var(--display);
	font-weight: 400;
	font-size: 18px;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	color: var(--ink);
	text-shadow: none;
	--face: var(--paper);
	--edge: 2px;
	border-radius: 12px;
	--shade: var(--shadow-ink);
	--lift: 4px;
	padding: 8px 18px;
}

.screen-heading button.link {
	rotate: 1.5deg;
}

.editor-top-bar button.link {
	padding: 6px 12px;
	font-size: 16px;
}

.screen-heading button.link:hover, .editor-top-bar button.link:hover {
	transform: translate(-1px, -1px);
	--lift: 5px;
}

.screen-heading button.link:active, .editor-top-bar button.link:active {
	transform: translate(1px, 2px);
	--lift: 1px;
}

/* The account and guest pills on the backdrop */

.menu-status, .menu-account {
	--face: var(--paper);
	color: var(--ink);
	border-radius: 999px;
	--lift: 4px;
	padding: 6px 16px;
	font-weight: 900;
	font-size: 15px;
	text-shadow: none;
}

/* The title and the menu */

/* One column, the pills, the logo, the buttons and the cards, centred when it fits and scrolling from the top when it does not */
.menu {
	--intro-hint-top: 62%;
	--intro-logo-gap: 32px;
	justify-content: flex-start;
	padding: 16px 32px 32px;
	overflow-y: auto;
}

.menu.intro {
	overflow: hidden;
}

.menu-top {
	width: 100%;
	min-height: 44px;
	display: flex;
	align-items: center;
	justify-content: flex-end;
	flex-shrink: 0;
}

/* The same block carries the logo into the menu */
.menu-middle {
	position: relative;
	width: 100%;
	margin: auto 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2.5vh;
	translate: 0 0;
	transition: translate 900ms cubic-bezier(0.2, 0.9, 0.3, 1);
}

/* The logo sits above the hint regardless of the hidden menu's height */
.menu.intro .menu-middle {
	position: absolute;
	top: var(--intro-hint-top);
	left: 0;
	margin: 0;
	transition: none;
}

.menu.intro .logo {
	position: absolute;
	bottom: calc(100% + var(--intro-logo-gap));
	margin: 0;
	/* Scaling grows from the centre, so lift the bottom edge back above the hint */
	translate: 0 calc((1 - var(--intro-scale)) * 50%);
}

.menu-buttons, .menu-cards, .menu-status, .menu-account {
	transition: opacity 600ms ease 400ms;
}

.menu-account:empty {
	display: none;
}

/* Hidden, not merely see-through: every button and card gives its own shadow pointer events again, so a see-through one
   would still take the pointer and sound under the title hint. Hidden this way nothing under it is hit at all */
.menu.intro .menu-buttons, .menu.intro .menu-cards, .menu.intro .menu-status, .menu.intro .menu-account {
	opacity: 0;
	visibility: hidden;
	transition: none;
}

/* The logo hangs a little above the block and above where its own box would put it, so the buttons under it get more of the screen */
.menu-middle .logo {
	margin: -3vh 0 2vh;
}

/* The shadow uses the picture's silhouette, both spin, swell and rock in step,
   the shadow pushed down in screen space after its turn so it always drops down, and each is a finished picture on its own layer */
.logo {
	position: relative;
}

.logo :is(img, .logo-shadow) {
	display: block;
	width: auto;
	max-width: 80vw;
	max-height: 30vh;
	will-change: transform, scale, rotate;
	transform: translateZ(0);
	backface-visibility: hidden;
	transition: scale 900ms cubic-bezier(0.2, 0.9, 0.3, 1);
	/* A slow rock from side to side, started at its upright middle so it never jumps in */
	animation: breathe 1.6s ease-in-out -0.8s infinite alternate;
}

.logo-shadow {
	position: absolute;
	inset: 0;
	/* The same ink as the buttons, offset a little farther for the larger artwork. */
	translate: 4px 6px;
	background: var(--shadow-ink);
	mask: url("/assets/logo.png") center / contain no-repeat;
	pointer-events: none;
}

/* Behind the darkness the logo waits at four times its title size and shrinks to it while the circle opens */
/* It comes in spinning three full turns, barely slowing, and lands with a snap past the mark and back, the timing must match the menu code */
.menu.intro {
	/* The title logo is bigger than the menu one, and stays that size whatever the menu logo is made */
	--intro-scale: 1.35;
}

.menu.intro .logo :is(img, .logo-shadow) {
	scale: 4;
	rotate: -1080deg;
	animation: swell 2.2s ease-in-out infinite;
}

.menu.intro.opened .logo :is(img, .logo-shadow) {
	scale: var(--intro-scale);
	rotate: 0deg;
	transition: scale 1.9s cubic-bezier(0.3, 0.2, 0.5, 1.25), rotate 1.9s cubic-bezier(0.35, 0.1, 0.7, 1.15);
}

/* The pow, on landing the logo bumps and a cream silhouette of it bursts out and fades */
.logo-pow {
	position: absolute;
	inset: 0;
	opacity: 0;
	pointer-events: none;
	filter: brightness(0) invert(1);
}

.menu.intro.landed .logo-pow {
	animation: pow 650ms cubic-bezier(0.1, 0.7, 0.3, 1) forwards;
}

.menu.intro.opened.landed .logo :is(img, .logo-shadow) {
	transition: none;
}

.menu.intro.landed .logo-picture, .menu.intro.landed .logo-shadow {
	animation: punch 320ms cubic-bezier(0.2, 0.9, 0.3, 1.4), swell 2.2s ease-in-out 320ms infinite;
}

@keyframes pow {
	from {
		scale: var(--intro-scale);
		opacity: 0.9;
	}
	to {
		scale: calc(var(--intro-scale) * 2);
		opacity: 0;
	}
}

@keyframes punch {
	from {
		transform: scale(1.18);
	}
	to {
		transform: scale(1);
	}
}

.menu.sliding .logo :is(img, .logo-shadow) {
	animation: none;
}

@keyframes breathe {
	from {
		transform: rotate(-1.5deg);
	}
	to {
		transform: rotate(1.5deg);
	}
}

/* On the title the logo only swells a little, no tilt */
@keyframes swell {
	0%, 100% {
		transform: scale(1);
	}
	50% {
		transform: scale(1.04);
	}
}

.menu-hint {
	position: absolute;
	top: var(--intro-hint-top);
	left: 50%;
	translate: -50% 0;
	font-family: var(--display);
	font-size: min(34px, 6vw);
	white-space: nowrap;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	/* The ink outline every outlined text has, with a dark glow spread out past it so it reads against the level */
	text-shadow: var(--outline), 0 0 14px rgb(0 0 0 / 0.9), 0 0 32px rgb(0 0 0 / 0.7);
	/* Fades in over a second, then holds for two seconds and dips and comes back over one, over and over */
	animation: hint-in 1s ease-out, hint-blink 3.2s ease-in-out 1s infinite;
	/* A click on it ends the title like a click anywhere, so it shows the hand, but it is no button and makes no sound */
	cursor: pointer;
}

@keyframes hint-in {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}

@keyframes hint-blink {
	0%, 62.5%, 100% {
		opacity: 1;
	}
	81.25% {
		opacity: 0.2;
	}
}

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

.menu-buttons {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: 22px;
	justify-content: center;
}

/* Every button leans its own way, like stickers slapped on */
.menu-buttons > button:nth-child(odd) {
	rotate: -1.5deg;
}

.menu-buttons > button:nth-child(even) {
	rotate: 1.5deg;
}

.menu-buttons > button.primary {
	rotate: -2deg;
}

.menu-cards {
	width: min(var(--menu-width), 100%);
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 28px;
	align-items: start;
}

.menu-card {
	--face: var(--paper-bright);
	padding: 20px 24px;
	display: flex;
	flex-direction: column;
	gap: 8px;
	max-height: 38vh;
	min-width: 0;
	overflow-wrap: anywhere;
}

/* Nothing in a card gives way when the card is capped, only the news list scrolls */
.menu-card > * {
	flex-shrink: 0;
}

.menu-card > .menu-news {
	flex-shrink: 1;
}

.menu-news-card {
	--face: linear-gradient(110deg, #fff4d9, #eddfc1);
	--tilt: 0deg;
}

.menu-daily-card {
	--face: linear-gradient(140deg, #e9f0da, #cedcbe);
	--tilt: .6deg;
	--edge-colour: #7d8e70;
}

.menu-daily-best {
	white-space: pre-line;
}

.menu-events-card {
	--face: linear-gradient(125deg, #fae7b9, #dfc28d);
	--tilt: -.7deg;
	--edge-colour: #9c8054;
}

.menu-bingo {
	--face: linear-gradient(145deg, #efe4ed, #ddd0df);
	--tilt: .6deg;
	--edge-colour: #958398;
}

.menu-card {
	rotate: var(--tilt);
	border-radius: 8px 14px 10px 6px;
}

.menu-card h2 {
	font-size: 25px;
	color: var(--accent-ink);
	padding-bottom: 9px;
	border-bottom: 2px dashed #ac977466;
	letter-spacing: .045em;
}

.menu-daily-card h2 { color: #405c3f; }
.menu-events-card h2 { color: #745128; }
.menu-events-heading { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.menu-cup { object-fit: contain; flex: none; }
.menu-events-card.join-open { --edge-colour:#e3ad37; filter:drop-shadow(0 0 10px #ffc94cab) drop-shadow(0 0 22px #ffb62d55); }
.menu-events-card.join-open .menu-cup { filter:drop-shadow(2px 3px 0 var(--shadow-ink)) drop-shadow(0 0 5px #ffe48a) drop-shadow(0 0 11px #ffca4d); animation:event-bob 4.5s ease-in-out infinite; }
.menu-events-heading .marquee { --event-hop:-4px; }

.menu-cup, .menu-bingo-prize > .figure-box {
	filter: drop-shadow(2px 3px 1px var(--shadow-ink));
}

.menu-bingo h2 { color: #695272; }

.menu-card p {
	margin: 0;
	font-size: 15px;
	font-weight: 600;
	line-height: 1.4;
}

.menu-card .buttons {
	margin: 8px 0 0;
}

.menu-card .level-name {
	font-family: var(--display);
	font-weight: 400;
	font-size: 26px;
	text-transform: uppercase;
	display: flex;
	align-items: center;
	gap: 10px;
}

/* The news scrolls, all of it stays readable. The list reaches out into the card's padding so the bar runs down the card's edge, not through the text */
.menu-news {
	overflow-y: auto;
	min-height: 0;
	margin-right: -24px;
	padding-right: 8px;
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.menu-news-item {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.menu-news-item .muted {
	font-size: 13px;
	font-weight: 800;
}

.menu-news-item + .menu-news-item {
	padding-top: 12px;
	border-top: 4px double rgba(43, 29, 18, 0.18);
}

.menu-news-title {
	font-weight: 900;
	font-size: 18px;
}

.menu-account {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 4px 6px 4px 16px;
	--tilt: 1.5deg;
	rotate: var(--tilt);
}

/* The account pill wears the card, with the same lettering on the name and log out link. */
.menu-account.card-background {
	--face: var(--card-background) center / cover;
}

.menu-account.card-text {
	color: var(--card-text);
}


.menu-status {
	margin: 4px 0;
}

/* Four cards need the width of a desk, two rows of two is the next step down and one column the last */
@media (max-width: 1340px) {
	.menu-cards {
		/* auto-fit and not a plain two, so a card on its own with an odd number of them takes the full width
		   instead of the left one. A track is 460 across, so two of them fit down to about 950 pixels and no
		   more */
		grid-template-columns: repeat(auto-fit, minmax(min(100%, 460px), 1fr));
	}
}

/* A screen too short for the whole card draws it tighter rather than hiding its foot below the fold */
@media (max-height: 780px) {
	.bingo-grid {
		grid-template-rows: auto repeat(var(--bingo-side), minmax(86px, 1fr)) auto;
	}

	.bingo-square-words {
		font-size: 12px;
	}

	.bingo-band {
		padding-bottom: 8px;
	}
}

@media (max-width: 900px), (pointer: coarse) and (max-height: 600px) {
	.menu-cards {
		grid-template-columns: 1fr;
	}
}

/* The credits, the file rolling up over the world with nothing else on the screen, ending on the logo */

/* The world keeps drifting behind, the roll fills the screen and nothing in it is a box */
.credits {
	padding: 0;
	overflow: hidden;
}

/* Nothing else while the credits roll, the corner stickers included */
.page:has(> .credits:not(.hidden)) > .sticker {
	display: none;
}

/* Night falls over the drifting level, deepest at the edges, so cream words carry the screen */
.credits-veil {
	position: absolute;
	inset: 0;
	background: radial-gradient(ellipse at 50% 45%, color-mix(in srgb, var(--dark) 55%, transparent), color-mix(in srgb, var(--dark) 85%, transparent) 65%, var(--dark) 100%);
	animation: appear 2400ms ease both;
}

/* Specks of dust drifting up behind the words, each one given its size, its sway and its pace when the screen is built */
.credits-sky {
	position: absolute;
	inset: 0;
	overflow: hidden;
}

.credits-mote {
	position: absolute;
	bottom: -6vh;
	width: var(--size);
	height: var(--size);
	border-radius: 999px;
	background: var(--paper-bright);
	filter: blur(1px);
	opacity: 0;
	animation-name: mote;
	animation-timing-function: linear;
	animation-iteration-count: infinite;
}

@keyframes mote {
	0% {
		translate: 0 0;
		opacity: 0;
	}
	20% {
		opacity: 0.45;
	}
	75% {
		opacity: 0.3;
	}
	100% {
		translate: var(--sway) -112vh;
		opacity: 0;
	}
}

/* The roll itself is drawn, not laid out: the words are written into one picture and that picture is drawn at the
   height it has climbed to, see the credits screen. Nothing here but the canvas it is drawn on */
.credits-canvas {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
}

/* The card the roll ends on, the logo swelling up out of the dark with the last words under it */
.credits-finale {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 28px;
	opacity: 0;
	scale: 0.92;
	transition: opacity 2600ms ease, scale 4000ms cubic-bezier(0.2, 0.8, 0.3, 1);
}

.credits-finale.shown {
	opacity: 1;
	scale: 1;
}

.credits-ending {
	font-family: var(--display);
	font-weight: 400;
	font-size: clamp(24px, 4vw, 44px);
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: var(--paper-bright);
	text-shadow: var(--outline);
	margin: 0;
}

/* The way out sits quietly in the corner and comes up when the pointer finds it, Escape does the same */
.credits-leave {
	position: absolute;
	left: 22px;
	bottom: 18px;
	opacity: 0.45;
	transition: opacity 300ms ease;
}

.credits-leave:hover {
	opacity: 1;
}

.credits-leave button.link {
	color: var(--paper);
	text-shadow: 2px 2px 0 var(--ink);
}

.credits-leave button.link:hover {
	color: var(--paper-bright);
}

/* Screens with a heading and two columns */

.screen-heading {
	width: min(1200px, 100%);
	display: flex;
	align-items: center;
	justify-content: space-between;
}

.screen-heading h1 {
	font-size: 48px;
	rotate: -1.5deg;
}

.screen-heading-actions {
	display: flex;
	align-items: center;
	gap: 12px;
}

/* Quick Cups use the level picker's columns, cards and inner scrollers. */

/* Quick Cups use the level picker's columns, cards and inner scrollers. */

.quick-cups {
	overflow: hidden;
}

.quick-cups .screen-heading, .quick-cups .columns {
	width: min(1320px, 100%);
}

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

.icon-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
}

.quick-cup-icon {
	width: 20px;
	height: 20px;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
	flex: none;
}

.quick-cup-create {
	width: 100%;
	min-height: 46px;
}

.quick-cup-list, .quick-cup-selected, .quick-cup-picker {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.quick-cup-card {
	grid-template-columns: 44px minmax(0, 1fr) 52px 90px;
	text-align: left;
}

.quick-cup-card-mark {
	width: 40px;
	height: 40px;
	display: grid;
	place-items: center;
	border-radius: 50%;
	background: radial-gradient(circle at 35% 28%, #fffbd0, #ffc451 55%, #cc7720);
	border: var(--line);
	box-shadow: 2px 3px 0 var(--shadow-ink);
}

.quick-cup-card-mark .icon-trophy {
	width: 25px;
	height: 25px;
	margin: 0;
}

.quick-cup-card-levels, .quick-cup-card-rule {
	font-family: var(--display);
	font-size: 18px;
	text-align: center;
}

.quick-cup-card-levels {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 4px;
}

.quick-cup-card-levels .quick-cup-icon {
	width: 17px;
	height: 17px;
}

.quick-cup-card-rule {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 5px;
}

.quick-cup-card-rule .quick-cup-icon {
	width: 18px;
	height: 18px;
}

.quick-cup-public-detail > .scroll {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 22px;
	text-align: center;
}

.quick-cup-public-hero {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 10px;
}

.quick-cup-public-hero h2 {
	margin: 0;
}

.quick-cup-emblem {
	position: relative;
	width: 112px;
	height: 112px;
	display: grid;
	place-items: center;
	border: var(--line);
	border-radius: 50%;
	background: radial-gradient(circle at 35% 28%, #fffbd0, #ffc451 55%, #cc7720);
	box-shadow: 5px 6px 0 var(--shadow-ink);
	rotate: -3deg;
}

.quick-cup-emblem::before, .quick-cup-emblem::after {
	display: none !important;
}

.quick-cup-emblem .icon-trophy {
	width: 64px;
	height: 64px;
	margin: 0;
	stroke-width: 1;
}

.quick-cup-emblem.small {
	width: 58px;
	height: 58px;
	box-shadow: 3px 4px 0 var(--shadow-ink);
}

.quick-cup-emblem.small::before, .quick-cup-emblem.small::after {
	display: none !important;
}

.quick-cup-emblem.small .icon-trophy {
	width: 34px;
	height: 34px;
	stroke-width: 1.2;
}

.quick-cup-facts {
	width: min(480px, 100%);
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 12px;
}

.quick-cup-fact {
	display: grid;
	grid-template-columns: auto 1fr;
	align-items: center;
	gap: 0 8px;
	padding: 12px;
	border-radius: 12px;
	--face: var(--white);
	--edge-colour: var(--ink);
	--shade: var(--shadow-ink);
	--lift: 2px;
	text-align: left;
}

.quick-cup-fact .quick-cup-icon {
	grid-row: 1 / 3;
	width: 28px;
	height: 28px;
	color: var(--orange-deep);
}

.quick-cup-fact strong {
	font-family: var(--display);
	font-size: 25px;
	line-height: 1;
}

.quick-cup-fact span {
	font-size: 11px;
	color: var(--ink-soft);
	text-transform: uppercase;
}

.quick-cup-join {
	margin-top: auto;
}

.quick-cup-lobby-facts {
	width: 100%;
	grid-template-columns: 1fr;
	margin: 16px 0 20px;
}

.quick-cup-room {
	width: min(1320px, 100%);
	height: min(calc(100dvh - 165px), 710px);
	display: grid;
	grid-template-columns: minmax(0, 1.35fr) minmax(280px, .65fr);
	grid-template-rows: minmax(0, .8fr) minmax(220px, 1.2fr);
	gap: 18px;
	margin-top: 16px;
}

.quick-cup-room > .paper-panel {
	padding: 20px;
	min-height: 0;
}

.quick-cup-room h2, .quick-cup-room h3 {
	margin: 0 0 12px;
}

.quick-cup-setup {
	grid-row: 1 / 3;
	display: flex;
	flex-direction: column;
	min-height: 0;
	max-height: 100%;
	overflow: visible;
}

.quick-cup-setup-scroll {
	flex: 1 1 0%;
	min-height: 0;
	overflow-y: auto;
	overflow-x: hidden;
	padding-right: 4px;
}

.quick-cup-setup-title, .quick-cup-room-actions, .quick-cup-player, .quick-cup-level, .quick-cup-select-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
}

.quick-cup-setup-title {
	justify-content: flex-start;
	margin-bottom: 12px;
}

.quick-cup-room-actions {
	justify-content: flex-start;
	flex-wrap: wrap;
}

.quick-cup-public-toggle {
	padding: 6px 14px;
	border-radius: 999px;
	font-family: var(--font);
	font-weight: 900;
	font-size: 14px;
}

.quick-cup-public-toggle.active {
	--face: var(--ink);
	color: var(--paper);
}

.quick-cup-settings {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(180px, .45fr);
	gap: 12px;
	margin: 16px 0 20px;
}

.quick-cup-setting {
	display: flex;
	flex-direction: column;
	gap: 8px;
	padding: 12px 14px;
	border-radius: 13px;
	--face: var(--white);
	--edge-colour: var(--ink);
	--shade: var(--shadow-ink);
	--lift: 2px;
}

.quick-cup-setting-label {
	font-size: 11px;
	font-weight: 900;
	letter-spacing: .05em;
	text-transform: uppercase;
	color: var(--ink-soft);
}

.quick-cup-selected, .quick-cup-picker {
	margin: 10px 0;
}

.quick-cup-rule-tabs {
	margin: 0;
}

.quick-cup-level {
	padding: 8px 12px;
	border-radius: 10px;
	--face: var(--white);
	--edge-colour: var(--ink-soft);
	--shade: transparent;
}

.quick-cup-number {
	width: 2em;
	font-family: var(--display);
	font-size: 20px;
	color: var(--orange-deep);
}

.quick-cup-level > strong, .quick-cup-level > span:not(.quick-cup-number) {
	flex: 1;
}

.quick-cup-people-list {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.quick-cup-player {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 8px 12px;
	border-radius: 10px;
	background: var(--white);
	border: 2px solid color-mix(in srgb, var(--ink) 72%, var(--paper));
}

/* A player's row in a room wears the card they have on, the way a board row does. The name inside it wears the same
   card of its own, so the letters take the card's colours without anything said here */

.quick-cup-player.card-background {
	background: var(--card-background) center / cover;
}

.quick-cup-player-badge {
	font-size: 11px;
	font-weight: 900;
	text-transform: uppercase;
	padding: 3px 8px;
	border-radius: 999px;
	border: var(--line);
}

.quick-cup-player-badge.host {
	background: var(--paper-bright);
	color: var(--ink);
}

.quick-cup-player-badge.done {
	background: var(--green-light, #c8e6c9);
	color: var(--ink);
}

.quick-cup-player-badges {
	display: flex;
	align-items: center;
	gap: 6px;
}

.quick-cup-people-list {
	flex: 1;
	min-height: 0;
	overflow-y: auto;
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.quick-cup-player .quick-cup-kick {
	opacity: 0;
	pointer-events: none;
	transition: opacity 120ms ease;
	font-size: 13px;
	padding: 2px 8px;
}

.quick-cup-player:hover .quick-cup-kick,
.quick-cup-player:focus-within .quick-cup-kick {
	opacity: 1;
	pointer-events: auto;
}

.quick-cup-select-row {
	justify-content: flex-end;
	margin-top: 14px;
}

.quick-cup-level-warning {
	display: flex;
	align-items: center;
	gap: 8px;
	color: var(--red);
	font-size: 15px;
}

.quick-cup-level-warning .quick-cup-icon {
	width: 20px;
	height: 20px;
}

.quick-cup-start-row {
	margin: 12px 0 0;
	padding: 6px 0;
}

.quick-cup-start .icon-trophy {
	width: 27px;
	height: 27px;
	margin: 0;
}

.quick-cup-stepper {
	display: grid;
	grid-template-columns: 38px minmax(72px, 1fr) 38px;
	align-items: center;
	gap: 8px;
}

button.quick-cup-step {
	width: 38px;
	height: 38px;
	padding: 0;
	border-radius: 50%;
}

.quick-cup-step span {
	display: none;
}

.quick-cup-step .quick-cup-icon {
	width: 18px;
	height: 18px;
}

.quick-cup-step-value {
	font-family: var(--display);
	font-size: 22px;
	text-align: center;
	padding: 4px 8px;
	border-radius: 8px;
	--face: var(--paper);
	--edge-colour: var(--ink);
	--shade: transparent;
}

.dialog.quick-cup-level-dialog {
	width: min(860px, calc(100vw - 24px));
	height: min(720px, calc(100dvh - 24px));
	overflow: hidden;
}

.quick-cup-level-dialog .level-list {
	flex: 1;
}

.quick-cup-picker {
	padding: 12px;
}

.quick-cup-picker-count {
	color: var(--ink-soft);
}

.quick-cup-pick-card {
	grid-template-columns: 40px minmax(0, 1fr) auto;
}

button.quick-cup-pick-toggle, button.quick-cup-level-remove {
	width: 44px;
	height: 40px;
	padding: 0;
}

.quick-cup-pick-toggle span, .quick-cup-level-remove span {
	display: none;
}

.quick-cup-chat {
	display: flex;
	flex-direction: column;
}

.quick-cup-chat .chat-lines {
	flex: 1;
	min-height: 100px;
	border: 2px solid var(--ink);
	border-radius: 10px;
	background: var(--white);
	padding: 10px 14px;
	box-sizing: border-box;
	overflow-y: auto;
	overflow-x: hidden;
}

.quick-cup-chat .chat-form {
	border-top: none;
	padding: 10px 0 0 0;
}

.quick-cup-run-result, .quick-cup-final {
	width: min(620px, 100%);
}

.quick-cup-final-board {
	margin-bottom: 22px;
	text-align: left;
}

/* Who took the cup, with the levels that took it for them */
.quick-cup-winner {
	display: flex;
	align-items: center;
	gap: 14px;
	margin-bottom: 20px;
	text-align: left;
}

.quick-cup-winner-names {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 2px;
	min-width: 0;
}

.quick-cup-winner-label {
	font-size: 11px;
	font-weight: 900;
	color: var(--ink-soft);
	text-transform: uppercase;
}

.quick-cup-winner-name {
	font-family: var(--display);
	font-size: 26px;
}

.quick-cup-winner-why {
	margin: 0 0 0 auto;
	font-size: 13px;
	color: var(--ink-soft);
	text-align: right;
}

/* The places a rider took, one a level, and the cup they add up to */
.quick-cup-places {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: flex-end;
	gap: 4px;
}

.quick-cup-place {
	min-width: 20px;
	color: var(--ink-soft);
	font-family: var(--display);
	font-size: 18px;
	text-align: center;
}

/* A level a rider won is one they were fastest on, so it wears the accent a first place wears */
.quick-cup-place.first {
	color: var(--accent-ink);
}

.quick-cup-places-total {
	margin-left: 8px;
	font-family: var(--display);
	font-size: 22px;
}

/* A phone row has no width for a place per level beside the name, so the strip takes the line under it */
@media (max-width: 520px) {
	.quick-cup-final-board .board-row {
		grid-template-columns: 36px minmax(0, 1fr);
		row-gap: 2px;
	}

	.quick-cup-final-board .quick-cup-places {
		grid-column: 2;
		justify-content: flex-start;
	}
}

.quick-cup-final + .arcade-confetti {
	position: fixed;
	inset: 0;
	pointer-events: none;
}

.columns {
	width: min(1200px, 100%);
	height: min(72vh, 680px);
	display: grid;
	grid-template-columns: 1fr 1fr;
	/* One screenful tall whatever is put in them. A row left to size itself grows to the taller of the two cards and
	   drags the other one down with it, and the scroll inside each card is what the overflow is for */
	grid-template-rows: minmax(0, 1fr);
	gap: 40px;
	margin-top: 12px;
}

.levels .screen-heading, .levels .columns {
	width: min(1560px, 100%);
}

.levels .columns {
	grid-template-columns: repeat(2, minmax(0, 1fr));
	/* The list and the board take the height the screen has left over rather than a share of the window, so the cards
	   are as tall as there is room for and can never be taller than the room there is */
	flex: 1;
	min-height: 0;
	height: auto;
	max-height: 760px;
}

/* How many quick cups are waiting to be joined, said right before the button that opens them, with cream lettering
   like the heading it stands beside and an arrow nudging at the button */
.quick-cup-available {
	display: flex;
	align-items: center;
	gap: 8px;
	font-family: var(--display);
	font-size: 20px;
	white-space: nowrap;
}

.quick-cup-available .nudge-arrow {
	width: 26px;
	height: 22px;
	filter: drop-shadow(2px 2px 0 var(--ink));
}

@media (max-width: 800px) {
	.columns, .levels .columns {
		grid-template-columns: 1fr;
		height: 80vh;
	}

	.quick-cup-room {
		height: auto;
		grid-template-columns: 1fr;
		grid-template-rows: auto;
		padding-bottom: 96px;
	}

	.quick-cup-setup {
		grid-row: auto;
	}
}

/* The level list, a timing board of stickers */

.level-column {
	display: flex;
	flex-direction: column;
	gap: 10px;
	min-height: 0;
}

.level-column .tabs {
	margin: 0;
}

/* An input has no pseudo elements, so this one keeps a box-shadow */
.level-search {
	border-radius: 999px;
	padding: 12px 20px;
	box-shadow: 4px 4px 0 var(--shadow-ink);
}

.level-list {
	flex: 1;
	min-height: 0;
	display: flex;
	flex-direction: column;
	--face: var(--paper);
}

.level-list > .scroll {
	padding: 12px;
	display: flex;
	flex-direction: column;
	gap: 8px;
}

/* A shelf's heading on the featured tab, sitting above the cards it names. The first one has no rule over it
   because there is nothing above it to be parted from */
.shelf {
	padding: 18px 14px 4px;
}

.shelf + .level-card {
	margin-top: 0;
}

.shelf:not(:first-child) {
	border-top: 2px dashed color-mix(in srgb, var(--ink) 20%, transparent);
	margin-top: 10px;
}

.shelf h2 {
	margin: 0;
	font-family: var(--display);
	font-size: 20px;
	text-transform: uppercase;
	letter-spacing: 0.03em;
}

.shelf p {
	margin: 2px 0 0;
	font-size: 13px;
}

/* Where the list stops and tells the player to search instead */
.list-end {
	padding: 14px;
	text-align: center;
	font-size: 13px;
}

.level-card {
	display: grid;
	grid-template-columns: 44px 1fr 118px 72px;
	align-items: center;
	gap: 10px;
	padding: 10px 14px;
	border-radius: 12px;
	--edge-colour: transparent;
	--face: var(--white);
	--shade: transparent;
	cursor: pointer;
	transition: transform 140ms ease, opacity 140ms ease;
}

.level-card:hover {
	transform: translateX(4px);
	--edge-colour: var(--ink-soft);
}

.level-card.selected {
	--face: var(--paper-bright);
	--edge-colour: var(--ink);
	--shade: var(--shadow-ink);
	--lift: 4px;
}

.level-card .medal {
	width: 44px;
	height: 44px;
	margin: 0;
}

.level-name {
	font-family: var(--display);
	font-weight: 400;
	font-size: 20px;
	text-transform: uppercase;
	line-height: 1.05;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.level-author, .level-best, .level-description {
	color: var(--ink-soft);
	font-size: 14px;
	font-weight: 800;
}

.level-title {
	min-width: 0;
}

.level-record, .level-yours {
	align-self: start;
	text-align: right;
	line-height: 1.1;
}

.level-label {
	font-size: 11px;
	font-weight: 900;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ink-soft);
}

.level-time {
	font-family: var(--display);
	font-size: 20px;
	font-variant-numeric: tabular-nums;
}

.level-description {
	white-space: pre-line;
	margin: 0;
}

/* The picked level, a bigger sticker standing straight so its chips and times read cleanly */

.leaderboard {
	display: flex;
	flex-direction: column;
	--face: var(--paper-bright);
}

.leaderboard > .scroll {
	padding: 24px 28px;
}

.leaderboard h2 {
	font-size: 36px;
	line-height: 1;
	margin: 0 0 6px;
}

.leaderboard p {
	margin: 4px 0;
}

.level-version {
	padding: 8px 12px;
	font-weight: 800;
	font-size: 14px;
}

.vote-row {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 6px 0;
}

.vote {
	width: 48px;
	height: 44px;
	padding: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

.icon-thumb {
	width: 26px;
	height: 26px;
	fill: var(--white);
	stroke: var(--ink);
	stroke-width: 2;
	stroke-linejoin: round;
}

.icon-trophy {
	width: 16px;
	height: 16px;
	margin-right: 4px;
	fill: var(--medal-colour);
	stroke: var(--ink);
	stroke-width: 1.2;
	stroke-linejoin: round;
	stroke-linecap: round;
}

.vote.on {
	--face: linear-gradient(var(--orange-light), var(--orange));
}

.vote-count {
	position: relative;
	font-weight: 900;
	font-variant-numeric: tabular-nums;
	min-width: 2ch;
	text-align: center;
}

/* The number jumps out a little as it lands, and a ring bursts out of it and fades */

.vote-count.jump {
	animation: jump 360ms cubic-bezier(0.2, 0.9, 0.3, 1.4);
}

@keyframes jump {
	from {
		transform: scale(1.7);
	}
	to {
		transform: scale(1);
	}
}

.pow-ring {
	position: absolute;
	left: 50%;
	top: 50%;
	width: 0;
	height: 0;
	translate: -50% -50%;
	box-sizing: border-box;
	border: 3px solid var(--orange);
	border-radius: 50%;
	pointer-events: none;
	animation: pow-ring 520ms cubic-bezier(0.1, 0.7, 0.3, 1) forwards;
}

@keyframes pow-ring {
	from {
		width: 8px;
		height: 8px;
		opacity: 1;
	}
	to {
		width: 72px;
		height: 72px;
		opacity: 0;
	}
}

/* Medals, the grey coin in assets/medal.png tinted by luminosity over the medal colour, the author medal green like Trackmania's
   A medal is a round box with the same ink edge and hard shadow as every other box, see the ink shadows at the end,
   the colour here is also the trophy's and the stamp face's */

.medal {
	display: inline-block;
	/* Positioned here and not by the shared rule, the medal on the finish stamp positions itself */
	position: relative;
	width: 20px;
	height: 20px;
	vertical-align: -4px;
	margin-right: 4px;
	/* A medal in a row of flex items keeps its size, the text beside it gives way */
	flex-shrink: 0;
	border-radius: 50%;
	--edge: 2px;
	--lift: 2px;
	--face: url("/assets/medal.png") center / cover no-repeat, var(--medal-colour);
}

.medal::after {
	background-blend-mode: luminosity, normal;
}

.medal-author {
	--medal-colour: var(--green);
}

.medal-gold {
	--medal-colour: #ffd54a;
}

.medal-silver {
	--medal-colour: #d8dde6;
}

.medal-bronze {
	--medal-colour: #d29a5a;
}

/* No medal is an empty ring where the coin would stand */
.medal-none {
	--face: none;
	--edge-colour: rgba(43, 29, 18, 0.3);
	--shade: transparent;
}

/* The lines sit as far apart as the last one is from the buttons under it */
.medal-rows {
	display: flex;
	flex-direction: column;
	gap: 14px;
	margin: 8px 0 4px;
}

.medal-row {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.medal-chip {
	display: inline-flex;
	align-items: center;
	height: 28px;
	box-sizing: border-box;
	padding: 0 10px;
	border: var(--line);
	border-radius: 999px;
	background: var(--white);
	font-weight: 900;
	font-size: 13px;
	font-variant-numeric: tabular-nums;
	color: var(--ink-soft);
}

.medal-chip .medal {
	opacity: 0.35;
	/* The chip centres the medal with its shadow, or the coin sits a pixel low */
	margin-bottom: var(--lift);
}

.medal-chip.held {
	color: var(--ink);
}

.medal-chip.held .medal {
	opacity: 1;
}

/* Your own best sits first in the row, on paper, with the medal it earns */

.medal-chip.yours {
	background: var(--paper);
	color: var(--ink);
}

.medal-chip.yours .medal {
	opacity: 1;
}

.medal-chip.rank {
	background: var(--paper);
	color: var(--ink);
}

/* Boards */

.board {
	display: flex;
	flex-direction: column;
	gap: 4px;
	padding: 8px;
	border: var(--line);
	border-radius: 12px;
	background: var(--white);
}

/* Which times a board is showing, for the boards with no tabs of their own, the one over a run and the results one */
.board-title {
	font-family: var(--display);
	font-weight: 400;
	font-size: 16px;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--accent-ink);
	padding: 2px 12px 2px;
}

.board-row {
	display: grid;
	grid-template-columns: 40px 1fr auto;
	align-items: center;
	padding: 8px 12px;
	border-radius: 8px;
	font-variant-numeric: tabular-nums;
	font-weight: 800;
}

.board-row.mine {
	background: #ffe2a8;
}

.board-rank {
	font-family: var(--display);
	font-size: 20px;
	color: var(--ink-soft);
}

.board-row.top1 .board-rank {
	color: var(--accent-ink);
}

.board-row.top2 .board-rank {
	color: #8a94a3;
}

.board-row.top3 .board-rank {
	color: #b5763a;
}

.board-time {
	font-family: var(--display);
	font-size: 20px;
}

.board-gap {
	margin-left: 8px;
	font-family: var(--font);
	font-size: 12px;
	font-weight: 800;
	color: var(--ink-soft);
}

.board-gap-row {
	text-align: center;
	color: var(--ink-soft);
}

/* The results */

.results {
	pointer-events: none;
}

.results > * {
	pointer-events: auto;
}

.result-box {
	flex: none;
	margin-block: auto;
	padding: 32px 48px;
	text-align: center;
	min-width: 420px;
	--face: var(--paper-bright);
	rotate: -0.6deg;
}

.result-box h1 {
	font-size: 28px;
	color: var(--ink-soft);
}

.result-time {
	font-family: var(--display);
	font-size: 84px;
	line-height: 1;
	color: var(--orange-deep);
	text-shadow: var(--outline);
	margin: 6px 0 12px;
}

.result-detail {
	color: var(--ink-soft);
	margin: 14px 0;
}

.result-detail {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: 8px 14px;
}

.result-detail strong {
	flex-basis: 100%;
	color: var(--ink);
	font-weight: 900;
}

.result-medal {
	min-height: 40px;
	font-family: var(--display);
	font-size: 30px;
	text-transform: uppercase;
	margin: 0 0 8px;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
}

.result-medal.muted {
	font-family: var(--font);
	font-size: 15px;
	font-weight: 800;
	text-transform: none;
}

.result-medal .medal {
	width: 1.6em;
	height: 1.6em;
}

.result-medal.pop {
	animation: rise 320ms cubic-bezier(0.2, 0.9, 0.3, 1.2);
}

/* The medal is a rubber stamp in the medal colour that comes down on the box from high up, lands hard and bounces once */

.result-medal.stamp {
	width: max-content;
	margin: 2px auto 24px;
	/* The medal hanging off the left edge reaches 1.6em in, the text starts clear of it and its shadow */
	padding: 4px 22px 6px 2.1em;
	--edge: 5px;
	border-radius: 14px;
	--face: linear-gradient(170deg, color-mix(in srgb, var(--medal-colour) 80%, var(--white)), var(--medal-colour) 45%, color-mix(in srgb, var(--medal-colour) 70%, var(--ink)));
	--lift: 5px;
	font-size: 34px;
	letter-spacing: 0.04em;
	--stamp-tilt: -6deg;
	animation: stamp 460ms both;
}

/* The medal on the stamp is big enough to hang out past its left edge */
.result-medal.stamp .medal {
	position: absolute;
	left: -1.3em;
	top: 50%;
	translate: 0 -50%;
	width: 2.9em;
	height: 2.9em;
	margin: 0;
	--edge: 2px;
	--lift: 5px;
}

/* Whatever is stamped says the angle it comes to rest at in --stamp-tilt, so one drop serves them all */
@keyframes stamp {
	0% {
		transform: scale(3.6) rotate(calc(var(--stamp-tilt) - 16deg));
		opacity: 0;
		animation-timing-function: cubic-bezier(0.6, 0, 1, 0.5);
	}
	30% {
		opacity: 1;
	}
	56% {
		transform: scale(0.94) rotate(var(--stamp-tilt));
		animation-timing-function: ease-out;
	}
	74% {
		transform: scale(1.06) rotate(calc(var(--stamp-tilt) + 1deg));
		animation-timing-function: ease-in-out;
	}
	100% {
		transform: scale(1) rotate(var(--stamp-tilt));
	}
}

/* The box takes the hit when the stamp lands */

.result-box.thud, .arcade-machine.thud {
	animation: thud 360ms ease-out;
}

@keyframes thud {
	0% {
		translate: 0 0;
	}
	20% {
		translate: 0 7px;
	}
	45% {
		translate: -3px -3px;
	}
	70% {
		translate: 2px 2px;
	}
	100% {
		translate: 0 0;
	}
}

.result-line {
	animation: rise 320ms cubic-bezier(0.2, 0.9, 0.3, 1.2) backwards;
}

.result-board {
	max-height: 36vh;
	overflow-y: auto;
	margin-top: 16px;
	text-align: left;
}

/* Over the game */

.hud {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

.hud-back {
	position: absolute;
	top: 20px;
	left: 20px;
	pointer-events: auto;
}

.hud.touch-on .hud-back {
	display: none;
}

.hud-controls { position:absolute; left:12px; bottom:12px; display:grid; grid-template-columns:auto auto; gap:3px 12px; padding:6px 8px; border-radius:6px; background:#24190fc2; color:var(--paper); font:600 11px/1.35 var(--font); }
.hud-controls>span { white-space:nowrap; }
.hud-controls kbd { font:800 11px var(--font); color:var(--orange-light); }
.hud.touch-on .hud-controls { display:none; }
@media(any-pointer:coarse),(hover:none) { .hud-controls { display:none; } }

.hud-timer {
	position: absolute;
	top: 18px;
	left: 50%;
	transform: translateX(-50%);
	font-family: var(--display);
	font-size: 56px;
	line-height: 1;
}

.hud-quick-cup {
	position: absolute;
	top: 84px;
	left: 50%;
	translate: -50% 0;
	display: grid;
	grid-template-columns: 31px 25px minmax(28px, auto);
	align-items: center;
	gap: 7px;
	padding: 7px 13px 7px 8px;
	border: var(--line);
	border-radius: 999px;
	background: linear-gradient(145deg, var(--paper-bright), #f1d690);
	box-shadow: 4px 5px 0 var(--shadow-ink);
	color: var(--ink);
	rotate: -1deg;
}

.hud-quick-cup .icon-trophy {
	width: 27px;
	height: 27px;
	margin: 0;
}

.hud-quick-cup .quick-cup-icon {
	width: 23px;
	height: 23px;
	color: var(--orange-deep);
}

.hud-quick-cup.retries .quick-cup-icon {
	fill: var(--red);
	color: var(--ink);
}

.hud-quick-cup strong {
	font-family: var(--display);
	font-size: 27px;
	font-variant-numeric: tabular-nums;
	line-height: 1;
}

/* Every digit of a counting number stands in a box a 0 wide, the widest digit the display font has,
   so the number does not dance while it counts. The font has no tabular figures to ask for instead */
.digit {
	display: inline-block;
	width: 1ch;
	text-align: center;
}

.hud-countdown {
	position: absolute;
	top: 30%;
	left: 50%;
	transform: translate(-50%, -50%);
	font-family: var(--display);
	font-size: 200px;
	line-height: 1;
	color: var(--orange);
	text-shadow: var(--outline), 0 14px 0 rgba(20, 12, 4, 0.35);
}

.hud-countdown.pop {
	animation: pop 500ms cubic-bezier(0.2, 0.9, 0.3, 1.3);
}

@keyframes pop {
	from {
		transform: translate(-50%, -50%) scale(2.2);
		opacity: 0;
	}
	to {
		transform: translate(-50%, -50%) scale(1);
		opacity: 1;
	}
}

.hud-spectate {
	position: absolute;
	top: 20px;
	left: 50%;
	transform: translateX(-50%);
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
	padding: 8px 18px;
	border: var(--line);
	border-radius: 999px;
	background: linear-gradient(145deg, var(--paper-bright), #f1d690);
	box-shadow: 4px 5px 0 var(--shadow-ink);
	color: var(--ink);
	text-align: center;
	pointer-events: none;
	z-index: 10;
}

.hud-spectate-name {
	font-family: var(--display);
	font-size: 20px;
	color: var(--orange-deep);
	line-height: 1.1;
}

.hud-spectate-hint {
	font-size: 13px;
	font-weight: 700;
	color: var(--ink-soft);
	line-height: 1.1;
}


.hud-board {
	position: absolute;
	top: 20px;
	right: 20px;
	width: 320px;
	padding: 8px;
	font-size: 14px;
	--lift: 4px;
	rotate: 1deg;
	opacity: 0.92;
}

.hud-board.crowded {
	visibility: hidden;
}

/* Nothing to show, no panel */
.hud-board:empty {
	display: none;
}

.hud-board /* Which times a board is showing, for the boards with no tabs of their own, the one over a run and the results one */
.board-title {
	font-family: var(--display);
	font-weight: 400;
	font-size: 16px;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--accent-ink);
	padding: 2px 12px 2px;
}

.board-row {
	padding: 4px 8px;
	grid-template-columns: 28px 1fr auto;
}

.hud-board .board-rank, .hud-board .board-time {
	font-size: 16px;
}

/* The numbers over the game, tucked under the way out rather than over it. F3 needs a keyboard, so the touch
   layout's own pills in that corner only ever meet it on a tablet with one plugged in, and it clears them too */
.hud-stats {
	position: absolute;
	top: 76px;
	left: 20px;
	display: flex;
	flex-direction: column;
	gap: 6px;
	padding: 10px 12px 11px;
	border-radius: 12px;
	--lift: 4px;
	font-family: "JetBrains Mono", ui-monospace, monospace;
	font-size: 12px;
	font-variant-numeric: tabular-nums;
	opacity: 0.94;
}

.hud.touch-on .hud-stats {
	top: 118px;
}

.stats-head {
	display: flex;
	align-items: baseline;
	gap: 6px;
}

.stats-rate {
	font-family: var(--display);
	font-size: 34px;
	line-height: 1;
}

/* The rate is read against the rate the game is wanted at, so a run going as well as it can is plain ink and only
   one that is slipping away from it takes a colour */
.stats-rate.good {
	color: var(--ink);
}

.stats-rate.fair {
	color: var(--orange-deep);
}

.stats-rate.poor {
	color: var(--red);
}

.stats-unit {
	font-family: var(--font);
	font-size: 11px;
	font-weight: 900;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--ink-soft);
}

.stats-graph {
	display: block;
	width: 234px;
	height: 38px;
	border-radius: 6px;
	background: color-mix(in srgb, var(--ink) 9%, transparent);
}

.stats-row {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: baseline;
	gap: 12px;
}

.stats-row > span {
	font-family: var(--font);
	font-size: 10px;
	font-weight: 900;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--ink-soft);
}

.stats-row > b {
	font-weight: 700;
	color: var(--ink);
}

/* Round buttons for touch screens, lean under the left thumb, gas and brake under the right */

.touch {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

.touch-button {
	position: absolute;
	width: 84px;
	height: 84px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	--face: var(--paper);
	opacity: 0.8;
	--lift: 4px;
	color: var(--ink);
	font-family: var(--display);
	font-size: 18px;
	text-transform: uppercase;
	pointer-events: auto;
	touch-action: none;
	user-select: none;
	-webkit-user-select: none;
}

.touch-button.down {
	--face: var(--orange);
	transform: translate(1px, 2px);
	--lift: 1px;
}


/* The corner stickers would sit under the gas button, so they go while the touch buttons are up in a run */
.hud.touch-on:not(.hidden) ~ .sticker {
	display: none;
}

/* A sticker in the corner that folds down to a round button, the chat and the mailbox */

/* Over every screen and all of what is on one, under the gate, the reveal, the popouts and the dialogs */
.sticker, .guide-radio {
	z-index: 10;
}

.sticker {
	position: absolute;
	right: var(--corner-inset);
	bottom: var(--corner-inset);
	width: min(380px, calc(100vw - 48px));
	height: min(440px, calc(100dvh - 48px));
	display: flex;
	flex-direction: column;
	transition: height 260ms cubic-bezier(0.2, 0.9, 0.3, 1.1);
}

/* The open sticker's parts are kept inside it while it folds */
.sticker-body {
	flex: 1;
	min-height: 0;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	border-radius: inherit;
}

.sticker.closed {
	height: 64px;
	width: 64px;
	border-radius: 50%;
	--edge-colour: transparent;
	--face: transparent;
	--shade: transparent;
	overflow: visible;
}

.sticker.closed .sticker-body {
	visibility: hidden;
}

.sticker-icon {
	display: none;
	position: absolute;
	right: 0;
	bottom: 0;
	width: 64px;
	height: 64px;
	padding: 0;
	border-radius: 50%;
	--face: var(--paper);
	--lift: 4px;
}

/* The picture is put in the middle by the button itself, a line height or a margin lands differently in every browser */
.sticker.closed .sticker-icon {
	display: flex;
	align-items: center;
	justify-content: center;
}

/* The picture on the button, the same ink outline on both stickers */
.sticker-picture {
	display: block;
	width: 32px;
	height: 32px;
	overflow: visible;
}

.sticker-shape {
	fill: var(--white);
	stroke: var(--ink);
	stroke-width: 2;
	stroke-linejoin: round;
}

.sticker-line {
	fill: none;
	stroke: var(--ink);
	stroke-width: 2;
	stroke-linejoin: round;
	stroke-linecap: round;
}

.sticker-dot {
	fill: var(--ink);
}

.sticker-heading {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: 12px 18px;
	font-family: var(--display);
	font-size: 20px;
	text-transform: uppercase;
	color: var(--accent-ink);
	cursor: pointer;
	border-bottom: var(--line);
	user-select: none;
}

.sticker-close {
	font-family: var(--font);
	font-weight: 900;
	font-size: 16px;
	color: var(--ink-soft);
}

/* Only actionable, unseen changes mark a corner button. */
.sticker-icon.attention { --face:var(--orange); }
.sticker-icon.urgent { --face:var(--red); color:var(--white); }
.sticker.empty { display:none; }
.page { --mailbox-visible:0; --nook-visible:0; }
.page:has(> .mailbox:not(.empty):not(.hidden)) { --mailbox-visible:1; }
.page:has(> .nook:not(.empty):not(.hidden)) { --nook-visible:1; }
.mailbox { right:calc(var(--corner-inset) + var(--corner-step)); }
.nook { right:calc(var(--corner-inset) + (1 + var(--mailbox-visible)) * var(--corner-step)); }
.expeditions { right:calc(var(--corner-inset) + (1 + var(--mailbox-visible) + var(--nook-visible)) * var(--corner-step)); }

.mail-list {
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: 12px;
	background: var(--white);
}

/* The cross that throws a read letter away, over the envelope's right end where the seal sits on an unread one, only
   seen while the envelope is under the pointer or the cross has the focus */
.mail-bin {
	position: absolute;
	right: 10px;
	top: 50%;
	translate: 0 -50%;
	width: 28px;
	height: 28px;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	border: 2px solid var(--ink);
	background: var(--paper);
	box-shadow: 2px 2px 0 var(--shadow-ink);
	font-family: var(--font);
	font-weight: 900;
	font-size: 14px;
	color: var(--ink-soft);
	opacity: 0;
	transition: opacity 120ms ease;
}

.envelope:hover .mail-bin, .mail-bin:focus-visible {
	opacity: 1;
}

.mail-bin:hover {
	background: var(--paper-bright);
}

/* An envelope in the list, an airmail stripe down its left edge, the stamp, the words and a wax seal while unread */
.envelope {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 8px 12px 8px 16px;
	text-align: left;
	font-family: var(--font);
	font-size: 14px;
	text-transform: none;
	letter-spacing: 0;
	border-radius: 8px;
	--face: var(--paper-bright);
	--lift: 3px;
	--edge: 2px;
	background: repeating-linear-gradient(-45deg, var(--red) 0 6px, transparent 6px 12px, var(--blue) 12px 18px, transparent 18px 24px) left / 6px 100% no-repeat;
}

.envelope.unread {
	--face: var(--white);
}

.envelope-stamp {
	flex-shrink: 0;
	padding: 3px;
	background: var(--white);
	border: 1px dashed var(--ink-soft);
	rotate: -3deg;
}

.envelope-words {
	flex: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 2px;
	line-height: 1.25;
}

.envelope-words strong {
	font-weight: 900;
}

.envelope-seal {
	flex-shrink: 0;
	width: 14px;
	height: 14px;
	border-radius: 50%;
	background: radial-gradient(circle at 35% 35%, var(--red-light), var(--red) 60%);
	box-shadow: 0 0 0 2px var(--paper-bright), 0 0 0 3px var(--red);
	visibility: hidden;
}

.envelope.unread .envelope-seal {
	visibility: visible;
}

/* The open letter, a sheet with an airmail frame, the address, the stamp with the postmark beside it and the words */

.dialog.letter {
	width: 440px;
	max-width: calc(100vw - 24px);
	padding: 36px 36px 28px;
	rotate: 0.6deg;
}

.dialog.letter h2 {
	font-size: 26px;
	line-height: 1.1;
	margin: 0;
}

/* The airmail frame is four ribbons, the top and bottom the full width and the sides between them, each striped on its
   own and cut straight where it meets the next. One pattern round the whole frame would fill a corner square with
   whatever band lands there, a solid triangle, and each ribbon begins with a paper band so its first end is clean */
.letter-edge {
	position: absolute;
	inset: 8px;
	--stripes: repeating-linear-gradient(45deg, var(--paper-bright) 0 12px, var(--red) 12px 24px, var(--paper-bright) 24px 36px, var(--blue) 36px 48px);
	background: var(--stripes) top / 100% 7px no-repeat, var(--stripes) bottom / 100% 7px no-repeat, var(--stripes) left 0 top 7px / 7px calc(100% - 14px) no-repeat, var(--stripes) right 0 top 7px / 7px calc(100% - 14px) no-repeat;
	pointer-events: none;
}

.letter-top {
	display: flex;
	justify-content: space-between;
	align-items: flex-start;
	min-height: 96px;
}

.letter-address {
	display: flex;
	flex-direction: column;
	padding-top: 10px;
	line-height: 1.2;
}

.letter-address strong {
	font-family: var(--display);
	font-size: 22px;
	color: var(--accent-ink);
}

.letter-corner {
	position: relative;
	flex-shrink: 0;
	width: 130px;
	height: 100px;
}

/* A stamp, its edge cut by a row of holes, the picture inside a thin line */
.stamp {
	position: absolute;
	top: 0;
	right: 0;
	width: 90px;
	height: 90px;
	background: radial-gradient(circle, transparent 2.5px, var(--white) 3px) -5px -5px / 10px 10px;
	rotate: 4deg;
}

.stamp-inner {
	position: absolute;
	inset: 8px;
	display: flex;
	align-items: center;
	justify-content: center;
	border: 1px solid var(--ink-soft);
	background: var(--paper-bright);
	overflow: hidden;
}

.stamp-cog {
	width: 48px;
	height: 48px;
	fill: var(--orange-deep);
}

.stamp-question {
	font-family: var(--display);
	font-size: 44px;
	color: var(--ink-soft);
}

/* A double ring of ink struck on paper, with a word inside it. The postmark on a letter and the DONE on a ticked
   bingo square are both one of these, each with its own size, colour and place */
.inked-ring {
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	border-radius: 50%;
	/* How heavy the two rings are struck, so a postmark can be fine and a DONE can be laid on hard */
	--ring: 2px;
	border: var(--ring) solid currentColor;
	outline: var(--ring) solid currentColor;
	outline-offset: 3px;
	font-weight: 900;
	line-height: 1.15;
	text-transform: uppercase;
	opacity: 0.6;
}

/* The postmark, the day the letter came, struck over the stamp's corner */
.postmark {
	position: absolute;
	left: -26px;
	bottom: -4px;
	width: 80px;
	height: 80px;
	padding: 8px;
	font-size: 9px;
	color: var(--ink);
	rotate: -14deg;
	/* Struck over the stamp, not under it */
	z-index: 1;
}

/* A letter read for the first time comes out of its envelope. The sheet is put in a post box with the envelope's pieces
   around it, each an svg drawn in the sheet's pixels by mailbox.ts, and the envelope sits lower than the sheet by a
   share of its height so the sheet has somewhere to come out to. Behind the sheet is the envelope's inside, in front
   of it the pocket with its folds meeting under the seal and a notch where the flap was, and the flap is hinged on
   the top edge with the seal on its tip. The seal breaks, the flap folds up and over onto the back, the sheet slides
   up out of the pocket and the envelope drops away under it. The times match SEAL_MILLISECONDS and
   OPENING_MILLISECONDS in mailbox.ts, and the pieces are taken off when the envelope is gone */
.letter-post {
	position: relative;
	isolation: isolate;
}

.letter-post > .dialog {
	z-index: 1;
	animation: letter-sheet 600ms cubic-bezier(0.2, 0.9, 0.3, 1.15) 900ms both;
}

/* The pieces stand ENVELOPE_MARGIN out from the sheet on every side and ENVELOPE_DROP of its height down */
.letter-inside, .letter-pocket, .letter-flap {
	position: absolute;
	top: calc(45% - 10px);
	left: -10px;
	right: -10px;
	height: calc(100% + 20px);
	overflow: visible;
	rotate: -0.4deg;
	pointer-events: none;
	fill: var(--paper);
	stroke: var(--ink);
	stroke-width: 3;
	stroke-linejoin: round;
	animation: letter-drop 500ms ease-in 1400ms both;
}

.letter-inside {
	fill: var(--paper-bright);
}

.letter-shade {
	fill: var(--shadow-ink);
	stroke: none;
	translate: 4px 4px;
}

.letter-pocket {
	z-index: 2;
}

.letter-fold {
	fill: var(--paper-bright);
	stroke-width: 2;
}

/* Folded flat up over the back it is wholly above the pocket, and at that moment letter-flap-depth drops it under
   the inside, so the sheet comes up in front of it */
.letter-flap {
	z-index: 3;
	transform-origin: top;
	animation: letter-flap 600ms ease-in-out 450ms both, letter-flap-depth 600ms step-end 450ms both, letter-drop 500ms ease-in 1400ms both;
}

/* On the flap's tip, which with the pieces' offsets works out to a pixel under the sheet's own bottom edge:
   45% - 10px down, then 55% of the height plus 20px, is 100% + 1px */
.letter-seal {
	position: absolute;
	left: 50%;
	top: calc(100% + 1px);
	width: 26px;
	height: 26px;
	translate: -50% -50%;
	border-radius: 50%;
	background: radial-gradient(circle at 35% 35%, var(--red-light), var(--red) 60%);
	box-shadow: 0 0 0 3px var(--red);
	z-index: 4;
	pointer-events: none;
	animation: letter-seal 250ms ease-out 350ms both;
}

@keyframes letter-seal {
	from {
		transform: none;
		opacity: 1;
	}
	to {
		transform: scale(1.8);
		opacity: 0;
	}
}

@keyframes letter-flap {
	from {
		transform: perspective(600px) rotateX(0deg);
	}
	to {
		transform: perspective(600px) rotateX(-180deg);
	}
}

@keyframes letter-flap-depth {
	from, 49.9% {
		z-index: 3;
	}
	50%, to {
		z-index: -1;
	}
}

@keyframes letter-sheet {
	from {
		transform: translateY(45%);
	}
	to {
		transform: none;
	}
}

@keyframes letter-drop {
	from {
		translate: 0 0;
		opacity: 1;
	}
	60% {
		opacity: 1;
	}
	to {
		translate: 0 70%;
		opacity: 0;
	}
}

/* An admin's words keep their line breaks */
.letter-text {
	white-space: pre-line;
}

.letter-wish {
	margin: 0;
	font-style: italic;
	color: var(--ink-soft);
}

/* The lines take the room that is left and the input stays at the bottom of whatever panel the chat sits in */
.chat-view {
	display: flex;
	flex-direction: column;
	flex: 1;
	min-height: 0;
}

.chat-lines {
	flex: 1;
	overflow-y: auto;
	padding: 10px 16px;
	font-size: 14px;
	font-weight: 600;
	background: var(--white);
}

.chat-line {
	margin: 3px 0;
	overflow-wrap: anywhere;
}

.chat-name {
	font-weight: 900;
	color: var(--accent-ink);
	margin-right: 6px;
}

.chat-line.system .chat-name {
	color: #1f7ab8;
}

.chat-form {
	display: flex;
	flex-shrink: 0;
	gap: 8px;
	padding: 10px;
	border-top: var(--line);
}

.chat-input {
	flex: 1;
	min-width: 0;
}

.chat-send {
	padding: 8px 16px;
	font-size: 16px;
}

/* Dialogs */

/* A dialog on its way out takes no more clicks, and the darkness goes with it */
.dialog-backdrop.leaving {
	pointer-events: none;
	animation: vanish 280ms ease forwards;
}

.dialog.leaving {
	animation: sink 240ms ease-in forwards;
}

@keyframes dim {
	from {
		opacity: 0;
	}
}

@keyframes vanish {
	to {
		opacity: 0;
	}
}

/* Over every screen and everything on one, the corner stickers too, so a dialog is never half under something.
   The darkness comes on over a moment, a screen that goes dark in one frame is hard on the eyes */
.dialog-backdrop {
	position: fixed;
	inset: 0;
	z-index: 30;
	background: rgba(20, 12, 4, 0.45);
	animation: dim 280ms ease;
	display: flex;
	align-items: safe center;
	justify-content: safe center;
	padding: 12px;
	overflow: auto;
}

.dialog {
	display: flex;
	flex-direction: column;
	gap: 12px;
	width: 360px;
	max-width: calc(100vw - 24px);
	flex-shrink: 0;
	overflow: visible;
	padding: 28px;
	--face: var(--paper-bright);
	rotate: -1deg;
	animation: rise 260ms ease;
}

.dialog h2 {
	font-size: 30px;
}

/* The shortfall box, wide enough for its heading on one line */
.dialog.shortfall {
	width: 480px;
	max-width: calc(100vw - 32px);
}

/* A price asked in a dialog stands in the middle of it, under the words */
.dialog .recipe-row {
	justify-content: center;
}

.field {
	display: flex;
	flex-direction: column;
	gap: 4px;
	font-size: 14px;
	font-weight: 800;
	color: var(--ink-soft);
}

.dialog-message {
	margin: 0;
	min-height: 1.2em;
	color: var(--red);
	font-size: 14px;
}

/* Toasts and the notice for a new build */

.toast {
	position: absolute;
	top: 100px;
	left: 50%;
	translate: -50% 0;
	width: max-content;
	max-width: calc(100vw - 24px);
	white-space: nowrap;
	--face: linear-gradient(var(--orange-light), var(--orange));
	color: var(--ink);
	--lift: 4px;
	padding: 12px 28px;
	border-radius: 999px;
	font-weight: 900;
	rotate: -1deg;
	animation: rise 260ms ease;
}

.build-notice {
	position: absolute;
	z-index: 19;
	bottom: calc(100px + env(safe-area-inset-bottom, 0px));
	left: 50%;
	translate: -50% 0;
	width: max-content;
	max-width: calc(100vw - 24px);
	display: flex;
	gap: 14px;
	align-items: center;
	padding: 10px 12px 10px 20px;
	border-radius: 999px;
	font-weight: 900;
	animation: rise 260ms ease;
}

.build-notice span {
	flex: 1;
	min-width: 0;
	line-height: 1.3;
}

.build-notice button {
	flex-shrink: 0;
}

/* The darkness the page opens in, and the fade between screens */

.gate {
	--gate-duration: 1s;
	position: absolute;
	inset: 0;
	overflow: hidden;
	cursor: pointer;
	/* Over everything on the page, the corner button on the menu too */
	z-index: 20;
}

.gate.level {
	cursor: default;
}

/* The opening is cut by one length and not by a path: a path this size is not painted as it grows, the darkness
   just goes, while a mask follows the number all the way out. Registered so the number can be transitioned */
@property --gate-r {
	syntax: "<length>";
	inherits: false;
	initial-value: 0px;
}

.gate-hole {
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: var(--dark);
	--gate-r: 0px;
	mask-image: radial-gradient(circle at 50% 50%, transparent calc(var(--gate-r) - 1px), #000 var(--gate-r));
	transition: --gate-r var(--gate-duration) cubic-bezier(0.4, 0, 0.6, 1);
}

.gate.open .gate-hole { --gate-r: var(--gate-reach); }

@media (prefers-reduced-motion: reduce) {
	.gate-hole { mask-image: none; transition: opacity var(--gate-duration); }
	.gate.open .gate-hole { opacity: 0; }
}

.gate-text {
	position: absolute;
	top: 50%;
	left: 50%;
	translate: -50% -50%;
	font-family: var(--display);
	font-size: min(34px, 6vw);
	white-space: nowrap;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	animation: pulse 1.6s ease-in-out infinite;
}

/* While the game loads a wheel turns over a please wait, so the darkness is seen to be doing something.
   The box is the whole screen and the wheel is pinned to the middle of it on its own, so the line arriving
   under it later cannot shift it */
.gate-wait {
	position: absolute;
	inset: 0;
	font-family: var(--display);
	font-size: min(22px, 4.5vw);
	white-space: nowrap;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	pointer-events: none;
}

/* Below the wheel, out of the way of it */
.gate-wait-line {
	position: absolute;
	left: 50%;
	top: calc(50% + 62px);
	translate: -50% 0;
}

.gate-tyre {
	position: absolute;
	left: 50%;
	top: 50%;
	translate: -50% -50%;
	width: 96px;
	height: 96px;
	fill: none;
	stroke: var(--paper);
	stroke-width: 2.6;
	stroke-linecap: round;
	animation: spin 1.1s linear infinite;
}

.gate-tyre path {
	stroke-width: 1.5;
}

.gate-tyre .gate-hub {
	fill: var(--paper);
	stroke: none;
}

/* The workshop and the map editor lay their own panels out, the screen only holds them */

.workshop, .map-editor {
	justify-content: flex-start;
	pointer-events: none;
	animation: none;
}

/* The map editor fills the screen from the left, the workshop is a block in the middle like the level picker */
.map-editor {
	display: grid;
	grid-template-columns: 76px minmax(0, 1fr);
	grid-template-rows: auto minmax(0, 1fr) auto;
	align-items: stretch;
}

.workshop > *, .map-editor > * {
	pointer-events: auto;
}

/* The workshop's heading and doors are as wide as its block below, so they line up with it. With the bike on the
   stage the block is wide and leaves its third column empty, without it the block is narrower and stands centred */
.workshop .screen-heading, .workshop-doors, .workshop .workshop {
	width: min(1100px, 100%);
}

.workshop.staged .screen-heading, .workshop.staged .workshop-doors, .workshop.staged .workshop {
	width: min(1500px, 100%);
}

.editor-side {
	width: min(420px, 100%);
	margin-top: 16px;
}

.editor-tabs {
	display: flex;
	gap: 8px;
	margin-bottom: 14px;
}

.editor-panel {
	padding: 18px;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.editor-field {
	display: flex;
	flex-direction: column;
	gap: 4px;
	font-size: 14px;
	font-weight: 800;
	color: var(--ink-soft);
}

.editor-switch {
	display: flex;
	align-items: center;
	gap: 10px;
	font-size: 14px;
	font-weight: 800;
}

.map-editor {
	padding: 0;
}

/* The editor's bars are paper too, straight, with ink edges where they meet the level */

.editor-top-bar, .editor-materials, .editor-side-panel, .editor-status-line {
	background: var(--paper);
	color: var(--ink);
}

.editor-top-bar {
	grid-column: 1 / -1;
	flex-wrap: wrap;
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 8px 10px;
	border-bottom: var(--line);
	max-height: 40dvh;
	overflow-y: auto;
}

.editor-top-group {
	display: flex;
	max-width: 100%;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px;
	flex-shrink: 0;
}

.editor-top-group.right {
	margin-left: auto;
}

.editor-top-bar .tab {
	padding: 6px 12px;
}

.editor-top-bar .primary {
	padding: 6px 16px;
	font-size: 16px;
}

.editor-top-bar .level-version {
	padding: 5px 8px;
}

.editor-name {
	width: 160px;
	padding: 6px 10px;
	font-weight: 900;
}

.editor-materials {
	grid-column: 1;
	grid-row: 2;
	min-height: 0;
	width: 76px;
	display: flex;
	flex-direction: column;
	gap: 6px;
	padding: 8px;
	border-right: var(--line);
	overflow-y: auto;
}

.swatch, .picker-choice {
	flex-shrink: 0;
	padding: 0;
	border-radius: 8px;
	overflow: hidden;
	border: var(--line);
	background: var(--white);
}

.swatch {
	width: 56px;
	height: 56px;
}

.picker-choice {
	width: 44px;
	height: 44px;
}

.picker-choice > .store-backdrop {
	border: 0;
	border-radius: 0;
}

.picker-choice .store-backdrop-layer { image-rendering: auto; }

.picker-choice-flags {
	width: 94px;
}

.picker-choice-flags .figure-flag {
	width: 30%;
	height: auto;
	object-fit: contain;
	image-rendering: auto;
}

.swatch:hover, .picker-choice:hover {
	transform: none;
}

.swatch img, .picker-choice img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	image-rendering: pixelated;
	display: block;
}

.swatch.active, .picker-choice.active {
	outline: 3px solid var(--orange-deep);
	outline-offset: 2px;
}

.editor-side-panel {
	grid-column: 2;
	grid-row: 2;
	justify-self: end;
	min-height: 0;
	width: 340px;
	display: flex;
	flex-direction: column;
	gap: 14px;
	padding: 14px;
	border-left: var(--line);
	overflow-y: auto;
}

.editor-section {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.editor-section + .editor-section {
	padding-top: 12px;
	border-top: 3px solid rgba(43, 29, 18, 0.15);
}

.editor-section h3 {
	font-size: 20px;
	color: var(--accent-ink);
}

.editor-section .buttons {
	margin: 0;
	gap: 8px;
}

.editor-problem {
	margin: 0;
	color: var(--red);
	font-size: 14px;
}

.editor-status-line {
	grid-column: 1 / -1;
	grid-row: 3;
	padding: 8px 14px;
	font-size: 13px;
	font-weight: 800;
	color: var(--ink-soft);
	border-top: var(--line);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.editor-menu {
	position: absolute;
	display: flex;
	flex-direction: column;
	min-width: 200px;
	padding: 6px;
	border-radius: 12px;
	--lift: 4px;
}

.editor-menu-entry {
	font-family: var(--font);
	font-weight: 800;
	font-size: 15px;
	text-transform: none;
	letter-spacing: 0;
	text-align: left;
	--face: transparent;
	--edge: 0px;
	--shade: transparent;
	border-radius: 8px;
	padding: 8px 12px;
}

.editor-menu-entry:hover {
	transform: none;
	--face: var(--white);
}

.picker {
	display: flex;
	flex-direction: column;
	gap: 4px;
	max-height: 320px;
	overflow-y: auto;
}

.picker-group {
	font-size: 12px;
	font-weight: 900;
	color: var(--ink-soft);
	text-transform: capitalize;
}

.picker-row {
	display: flex;
	flex-wrap: wrap;
	gap: 4px;
}

.editor-field textarea {
	resize: vertical;
}

.editor-shape-row {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.editor-shape-name {
	font-weight: 800;
}

.editor-field input[type="color"] {
	width: 64px;
	height: 36px;
	padding: 2px;
	border: var(--line);
	border-radius: 8px;
	background: var(--white);
}

/* The map list */

.map-column {
	display: flex;
	flex-direction: column;
	gap: 10px;
	min-height: 0;
}

.map-column h2 {
	font-size: 28px;
}

.map-column-heading {
	display: flex;
	align-items: center;
	justify-content: space-between;
	min-height: 48px;
}

.map-list {
	flex: 1;
	min-height: 0;
	display: flex;
	flex-direction: column;
}

.map-list > .scroll {
	padding: 12px;
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.map-card {
	padding: 12px 16px;
	border-radius: 12px;
	background: var(--white);
}

.map-card .buttons {
	margin: 8px 0 0;
	gap: 8px;
}

.map-card .level-name {
	white-space: normal;
}

/* The settings, keys on the left, sound and performance on the right */

/* Three cards are taller than a short window, and a column held to the middle there pushes the heading off the top of
   the screen where nothing can reach it, so the screen holds its content at the top and scrolls. The box takes itself
   back to the middle with the auto margin once there is room for it */
.settings {
	justify-content: flex-start;
	overflow-y: auto;
	gap: 12px;
}

.settings-box {
	align-items: start;
	width: min(1200px, 100%);
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 40px;
	margin-block: auto;
}

/* The cards beside the controls, sound over performance */
.settings-stack {
	display: flex;
	flex-direction: column;
	gap: 40px;
}

.settings-section {
	padding: 20px 24px;
	display: flex;
	flex-direction: column;
	gap: 10px;
	rotate: -0.8deg;
}

/* One card in each column leans the other way, so the box does not read as a grid */
.settings-section.tilt-right {
	rotate: 0.8deg;
	background: var(--paper-bright);
}

.settings-section h2 {
	font-size: 28px;
	color: var(--accent-ink);
}

.settings-section p {
	margin: 0;
	font-size: 14px;
	font-weight: 700;
}

.settings-row {
	display: grid;
	grid-template-columns: 1fr auto auto;
	align-items: center;
	gap: 12px;
	font-weight: 900;
}

.settings-choices {
	display: flex;
	gap: 8px;
}

.settings-keys {
	display: flex;
	gap: 8px;
}

.key-slot {
	min-width: 130px;
	padding: 8px 14px;
	font-size: 16px;
	--face: var(--white);
	--lift: 3px;
}

.key-slot.empty {
	color: var(--ink-soft);
}

.key-slot.listening {
	background: linear-gradient(var(--orange-light), var(--orange));
}

.key-slot.locked {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	gap: 6px;
	opacity: 1;
	cursor: default;
	--face: var(--paper);
}

.key-lock {
	width: 16px;
	height: 16px;
	fill: currentColor;
	flex: none;
}

.settings-actions {
	flex-wrap: nowrap;
}

.settings-section .key-cancel {
	color: var(--red);
	margin-left: auto;
	text-align: right;
	visibility: hidden;
}

.key-cancel.visible {
	visibility: visible;
}

.settings-slider {
	width: 220px;
}

.settings-value {
	min-width: 48px;
	text-align: right;
	font-variant-numeric: tabular-nums;
	color: var(--ink-soft);
}

/* A screen too short for the whole card draws it tighter rather than hiding its foot below the fold */
@media (max-height: 780px) {
	.bingo-grid {
		grid-template-rows: auto repeat(var(--bingo-side), minmax(86px, 1fr)) auto;
	}

	.bingo-square-words {
		font-size: 12px;
	}

	.bingo-band {
		padding-bottom: 8px;
	}
}

@media (max-width: 900px), (pointer: coarse) and (max-height: 600px) {
	.settings-box {
		grid-template-columns: 1fr;
	}
}

/* Phones, everything shrinks and the screens scroll instead of overflowing */

@media (max-width: 900px), (pointer: coarse) and (max-height: 600px) {
	.screen {
		padding: 12px;
		justify-content: flex-start;
		overflow-y: auto;
	}

	.menu {
		padding: 8px 12px 12px;
	}

	.menu-account {
		rotate: 0deg;
		margin: 2px 0;
		font-size: 13px;
		padding: 4px 12px;
	}

	.menu-middle {
		gap: 16px;
	}

	.menu-middle .logo {
		margin: 6px 0 4px;
		order: -2;
	}

	.logo :is(img, .logo-shadow) {
		max-height: 18vh;
	}

	/* The title logo swells less on a phone, the full swell would push it past the edges */
	.menu.intro {
		--intro-scale: 1.12;
	}

	/* The guest line goes under the logo on a phone, nobody scrolls to the bottom for it */
	.menu-status {
		order: -1;
	}

	.menu-buttons {
		gap: 10px;
	}

	button.big {
		font-size: 18px;
		padding: 10px 18px;
		--lift: 4px;
	}

	button.primary.big {
		font-size: 26px;
		padding: 12px 32px;
	}

	.menu-cards {
		width: 100%;
		gap: 22px;
		min-height: 0;
		/* Room to scroll the last card clear of the chat bubble */
		padding-bottom: 96px;
	}

	.menu-card {
		max-height: none;
		padding: 16px 18px;
	}

	.menu-news-card {
		max-height: min(360px, 42svh);
	}

	.menu-card h2 {
		font-size: 22px;
	}

	.menu-hint, .gate-text {
		font-size: min(28px, 7vw);
	}

	.screen-heading {
		width: 100%;
	}

	.screen-heading h1 {
		font-size: 30px;
	}

	.quick-cup-available {
		font-size: 15px;
	}

	.quick-cup-available .nudge-arrow {
		width: 20px;
		height: 17px;
	}

	.screen-heading button.link {
		font-size: 15px;
		padding: 6px 12px;
	}

	.columns {
		width: 100%;
		height: auto;
		gap: 22px;
		padding-bottom: 96px;
	}

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

	.level-list {
		max-height: 50vh;
	}

	.level-card {
		grid-template-columns: 36px minmax(0, 1fr) minmax(0, 1fr);
		gap: 8px;
		padding: 8px 10px;
	}

	.level-card .medal {
		width: 36px;
		height: 36px;
		grid-row: 1 / 3;
	}

	.level-title {
		grid-column: 2 / -1;
	}

	.level-record, .level-yours {
		text-align: left;
	}

	.level-name {
		font-size: 17px;
	}

	.level-author {
		font-size: 12px;
	}

	.level-time {
		font-size: 17px;
	}

	.leaderboard {
		rotate: 0deg;
		padding: 18px 16px;
	}

	.leaderboard h2 {
		font-size: 28px;
	}

	.result-box {
		min-width: 0;
		width: 100%;
		padding: 22px 18px;
		rotate: 0deg;
	}

	.results {
		pointer-events: auto;
	}

	.result-time {
		font-size: 56px;
	}

	.dialog {
		width: 100%;
		padding: 20px;
		rotate: 0deg;
	}

	.settings-box {
		width: 100%;
		gap: 22px;
		padding-bottom: 96px;
	}

	.settings-section, .settings-section.tilt-right {
		rotate: 0deg;
	}

	.settings-row {
		grid-template-columns: 1fr;
		gap: 6px;
		margin-bottom: 6px;
	}

	.settings-slider {
		width: 100%;
	}

	.key-slot {
		min-width: 0;
		flex: 1;
		padding: 8px;
		font-size: 14px;
	}

	.hud-timer {
		font-size: 36px;
		top: 14px;
	}

	.hud-countdown {
		font-size: 120px;
	}

	.hud-board {
		width: 180px;
		font-size: 12px;
		padding: 4px;
		top: 12px;
		right: 12px;
	}

	.hud-board .board-rank, .hud-board .board-time {
		font-size: 13px;
	}

	.page {
		--corner-inset: 12px;
		--corner-step: min(76px, calc((100vw - 2 * var(--corner-inset) - 64px) / 3));
	}

	.sticker {
		width: calc(100vw - 24px);
		height: min(440px, calc(100dvh - 24px));
	}

	.mailbox:not(.closed) {
		right: 12px;
	}

	.editor-side-panel {
		width: min(340px, 80vw);
	}
}

/* The question dialog */

.dialog-question {
	margin: 0;
	font-size: 16px;
	font-weight: 700;
	line-height: 1.4;
}

.dialog .buttons {
	margin-top: 8px;
}

@media (max-width: 700px) {
	.level-label {
		font-size: 10px;
		white-space: nowrap;
	}
}

/* A phone held upright, the touch buttons size from the width so the two clusters never meet, the board goes under the timer */

@media (max-width: 700px) {
	.touch-button {
		--touch-size: min(84px, 18vw);
		width: var(--touch-size);
		height: var(--touch-size);
		font-size: min(18px, 4vw);
	}

	.hud-board {
		top: 96px;
		right: 12px;
		width: 150px;
		font-size: 11px;
	}
}

/* The name tag cuts a long name itself, so nothing here clips the flag's shadow */
.board-name {
	min-width: 0;
	white-space: nowrap;
}

/* Where the touch buttons sit, lean and turn under the left thumb, brake and gas under the right, restart, exit and retry as pills in the top left corner */

.touch-left {
	left: 24px;
	bottom: 36px;
}

.touch-right {
	left: 132px;
	bottom: 36px;
}

.touch-turn {
	left: 24px;
	bottom: 150px;
	width: 64px;
	height: 64px;
	font-size: 14px;
}

.touch-gas {
	right: 24px;
	bottom: 36px;
	width: 100px;
	height: 100px;
}

.touch-brake {
	right: 148px;
	bottom: 36px;
}

.touch-restart, .touch-back, .touch-respawn {
	top: 20px;
	width: 96px;
	height: 42px;
	border-radius: 999px;
	font-size: 14px;
}

.touch-restart {
	left: 20px;
}

.touch-back {
	left: 124px;
}

.touch-respawn {
	top: 70px;
	left: 20px;
}

@media (max-width: 700px) {
	.touch-left {
		left: 12px;
		bottom: 24px;
	}

	.touch-right {
		left: calc(20px + min(84px, 18vw));
		bottom: 24px;
	}

	.touch-turn {
		--touch-size: min(64px, 15vw);
		left: 12px;
		bottom: calc(36px + min(84px, 18vw));
		font-size: min(14px, 3.4vw);
	}

	.touch-gas {
		--touch-size: min(100px, 22vw);
		width: var(--touch-size);
		height: var(--touch-size);
		right: 12px;
		bottom: 24px;
	}

	.touch-brake {
		right: calc(20px + min(100px, 22vw));
		bottom: 24px;
	}

	.touch-restart, .touch-back, .touch-respawn {
		top: 12px;
		width: min(96px, 24vw);
		height: 38px;
		font-size: min(13px, 3.2vw);
	}

	.touch-restart {
		left: 12px;
	}

	.touch-back {
		left: calc(20px + min(96px, 24vw));
	}

	.touch-respawn {
		top: 58px;
		left: 12px;
	}
}

/* On a phone the pills own the top left, so the timer goes top right with the board under it and the ghost line under the pills */
@media (max-width: 700px) {
	.hud-timer {
		left: auto;
		right: 12px;
		top: 10px;
		transform: none;
	}

	.hud-board {
		top: 60px;
	}
}

/* What stopped the game from starting, in the middle of the dark page */
.start-failure {
	position: fixed;
	inset: 0;
	display: grid;
	place-items: center;
	padding: 40px;
	text-align: center;
	color: var(--paper);
	font-size: 20px;
}

/* Ink shadows

   Every paper box with an ink edge and a shadow draws both under its content as two pseudo elements: the shadow first,
   pushed down and right by --lift and coloured --shade, then the face over it, --face for its background and --edge
   for its border. The box itself keeps a transparent border of the same width for layout. A box without a shadow
   sets --shade to transparent, a zero --lift would still leave a faint dark halo at the edges. A see-through box
   sets opacity on itself so the face and the shadow fade together, a see-through face would show the shadow under it.
   The rules are wrapped in :where() so they carry no specificity, any rule above sets --face, --edge, --edge-colour,
   --shade and --lift for its own box.

   A box-shadow stops at the border box and leaves a light seam along the edge of a rotated box, and a drop-shadow
   filter goes through an offscreen surface that in Firefox leaked stray lines into other boxes. The paper and its
   offset shadow therefore keep their own surfaces, with only a soft halo around the shadow.

   A box that scrolls keeps its scrolling on an inner .scroll element, its own overflow would clip the pseudo elements.

   The list of what is left out of the relative below is what puts itself somewhere: every one of those sets its own
   position, and the :not chain is how they say so. It has to be said here rather than overridden further down,
   since the chain gives this rule more weight than a plain class selector has */

:where(button:not(.swatch):not(.picker-choice), .paper-panel, .menu-card, .leaderboard, .level-list, .map-list, .settings-section, .result-box, .dialog, .sticker, .hud-board, .editor-panel, .editor-menu, .build-notice, .hud-stats, .menu-status, .menu-account, .level-card, .result-medal.stamp, .medal, .touch-button, .toast, .event-step, .stock-chip, .resource-chip, .bingo-prize-sheet, .hint-popout, .profile-name-row, .quick-cup-setting) {
	--face: var(--paper);
	--edge: 2px;
	--edge-colour: color-mix(in srgb, var(--ink) 72%, var(--paper));
	--lift: 3px;
	--shade: var(--shadow-ink);
	isolation: isolate;
	background: none;
	border: var(--edge) solid transparent;
}

:where(button:not(.swatch):not(.picker-choice), .paper-panel, .menu-card, .leaderboard, .level-list, .map-list, .settings-section, .result-box, .dialog, .sticker, .hud-board, .editor-panel, .editor-menu, .build-notice, .hud-stats, .menu-status, .menu-account, .level-card, .result-medal.stamp, .medal, .touch-button, .toast, .event-step, .stock-chip, .resource-chip, .bingo-prize-sheet, .hint-popout, .profile-name-row, .quick-cup-setting):not(.sticker):not(.hud-board):not(.hud-stats):not(.toast):not(.sticker-icon):not(.touch-button):not(.editor-menu):not(.build-notice):not(.medal):not(.bingo-swap):not(.hint-popout):not(.nook-furniture):not(.nook-poop):not(.nook-close):not(.journey-close):not(.guide-nav) {
	position: relative;
}

:where(button:not(.swatch):not(.picker-choice), .paper-panel, .menu-card, .leaderboard, .level-list, .map-list, .settings-section, .result-box, .dialog, .sticker, .hud-board, .editor-panel, .editor-menu, .build-notice, .hud-stats, .menu-status, .menu-account, .level-card, .result-medal.stamp, .medal, .touch-button, .toast, .event-step, .stock-chip, .resource-chip, .bingo-prize-sheet, .hint-popout, .profile-name-row, .quick-cup-setting)::before,
:where(button:not(.swatch):not(.picker-choice), .paper-panel, .menu-card, .leaderboard, .level-list, .map-list, .settings-section, .result-box, .dialog, .sticker, .hud-board, .editor-panel, .editor-menu, .build-notice, .hud-stats, .menu-status, .menu-account, .level-card, .result-medal.stamp, .medal, .touch-button, .toast, .event-step, .stock-chip, .resource-chip, .bingo-prize-sheet, .hint-popout, .profile-name-row, .quick-cup-setting)::after {
	content: "";
	position: absolute;
	inset: calc(-1 * var(--edge));
	border-radius: inherit;
	pointer-events: none;
}

:where(button:not(.swatch):not(.picker-choice), .paper-panel, .menu-card, .leaderboard, .level-list, .map-list, .settings-section, .result-box, .dialog, .sticker, .hud-board, .editor-panel, .editor-menu, .build-notice, .hud-stats, .menu-status, .menu-account, .level-card, .result-medal.stamp, .medal, .touch-button, .toast, .event-step, .stock-chip, .resource-chip, .bingo-prize-sheet, .hint-popout, .profile-name-row, .quick-cup-setting)::before {
	z-index: -2;
	background: var(--shade);
	box-shadow: 0 3px 9px color-mix(in srgb, var(--shade) 40%, transparent);
	translate: var(--lift) var(--lift);
	transition: translate 140ms ease;
	/* The shadow counts as part of the box under the pointer, so a button that lifts on hover keeps the pointer on it and does not flicker at its lower edge */
	pointer-events: auto;
}

:where(button:not(.swatch):not(.picker-choice), .paper-panel, .menu-card, .leaderboard, .level-list, .map-list, .settings-section, .result-box, .dialog, .sticker, .hud-board, .editor-panel, .editor-menu, .build-notice, .hud-stats, .menu-status, .menu-account, .level-card, .result-medal.stamp, .medal, .touch-button, .toast, .event-step, .stock-chip, .resource-chip, .bingo-prize-sheet, .hint-popout, .profile-name-row, .quick-cup-setting)::after {
	z-index: -1;
	background: var(--face);
	/* A gradient face spans the whole box, or it would start over under the border */
	background-origin: border-box;
	border: var(--edge) solid var(--edge-colour);
}

.scroll {
	flex: 1;
	min-height: 0;
	overflow-y: auto;
	border-radius: inherit;
}

/* A click on a button must never leave a word or a picture selected, only what is typed or read may be */
body {
	user-select: none;
}

input, textarea, .chat-lines, .level-description {
	user-select: text;
}

/* Country flags, a small picture with an ink outline and a hard shadow, left of a player's name */

.flag {
	position: relative;
	isolation: isolate;
	display: inline-block;
	width: 24px;
	height: 18px;
	margin-right: 6px;
	vertical-align: -3px;
	/* Square, a rounded corner on the right would be filled in by the shadow behind it and the two sides would not match */
	border-radius: 0;
}

.flag img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	border: 2px solid var(--ink);
	border-radius: inherit;
	box-sizing: border-box;
}

.flag::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	border-radius: inherit;
	background: var(--name-shadow, var(--shadow-ink));
	translate: 2px 2px;
}

/* Loading, a soft ring that appears after a moment, fades away when what it waited for is in, and the items pop in */

.spinner {
	position: absolute;
	left: 50%;
	top: 40px;
	translate: -50% 0;
	width: 32px;
	height: 32px;
	box-sizing: border-box;
	border: 4px solid color-mix(in srgb, var(--ink) 15%, transparent);
	border-top-color: var(--orange);
	border-radius: 50%;
	animation: spin 0.9s linear infinite, appear 200ms 150ms both;
	transition: opacity 200ms ease;
	pointer-events: none;
}

.spinner.gone {
	animation-name: spin;
	opacity: 0;
}

/* Under a list, in place of the button that asked for more */
.spinner.inline {
	position: static;
	translate: none;
	margin: 8px auto;
}

/* The spinner sits inside these, the board over the game keeps its own place */
.scroll, .level-board, .result-board {
	position: relative;
}

@keyframes spin {
	to {
		transform: rotate(360deg);
	}
}

@keyframes appear {
	from {
		opacity: 0;
	}
}

.plop {
	animation: plop 260ms cubic-bezier(0.2, 0.9, 0.3, 1.3) backwards;
}

@keyframes plop {
	from {
		opacity: 0;
		transform: scale(0.9);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

/* The workshop, the doors across the top, the room's panels on the left and the bike on the stage behind the empty column */

/* The panels never grow past the screen, only the lists inside them scroll. A panel never hides its own overflow, that
   would clip the ink edge and the shadow it draws around itself */
/* The floor sits in the middle of the screen like the level picker's columns, never spread across the whole width.
   Its third column is left empty and the bike stands on the stage behind it, so the look is never behind a panel. */

.workshop .workshop {
	display: grid;
	grid-template-columns: minmax(280px, 1fr) minmax(0, 1fr);
	grid-template-rows: minmax(0, 1fr);
	gap: 20px;
	height: min(78vh, 860px);
	margin-top: 10px;
	box-sizing: border-box;
}

.workshop.staged .workshop {
	grid-template-columns: minmax(280px, 1fr) minmax(0, 1fr) minmax(0, 0.9fr);
}

.workshop-floor {
	display: contents;
}

.workshop-panel {
	max-height: 100%;
	min-height: 0;
}

/* The drawing board wants the width of two panels */
.workshop-panel.wide {
	grid-column: 1 / 3;
}

/* Too narrow for a column of its own, so the bike stands behind the panels and the floor keeps its two */
@media (max-width: 1000px) {
	.workshop.staged .workshop {
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	}

	.store-stage {
		display: none;
	}
}

/* A list that scrolls inside its panel. The padding leaves room for the shadows and the stickers that stick out of
   its rows, and a row that runs past the bottom fades out there rather than being sliced through */
.store-scroll,
.pick-list {
	display: flex;
	flex-direction: column;
	flex: 1;
	min-height: 0;
	overflow-y: auto;
	scrollbar-gutter: stable;
	mask-image: linear-gradient(to bottom, #000 calc(100% - 34px), transparent calc(100% - 4px));
}

.store-scroll {
	gap: 12px;
	padding: 10px 16px 20px 10px;
	margin: -10px -16px -20px -10px;
}

.workshop-panel .editor-tabs {
	flex-wrap: wrap;
	margin-bottom: 4px;
}

.workshop h2 {
	font-family: var(--display);
	font-size: 20px;
	margin: 4px 0 0;
}

.store-list {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 10px;
}

.store-card {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
	padding: 8px 8px 6px;
	--face: var(--paper-bright);
}

.figure-bike {
	position: relative;
	opacity: 0;
	/* One layer for body and wheels, so a hovered card moves them as one */
	will-change: transform;
}

.figure-bike.ready {
	opacity: 1;
	transition: opacity 120ms ease-out;
}

.figure-bike-body {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
}

.figure-bike-wheel {
	position: absolute;
}

/* A suspension leg and its bolt, laid out from the same numbers the game draws them with */

.figure-bike-fork {
	position: absolute;
}

/* A rider standing, his pieces laid out around his joints */

/* The bike's column, always the third one. Without saying so it would slide over into the preview's column
   whenever nothing is picked and the preview is not there, taking the bike with it. */

.store-stage {
	grid-column: 3;
}

.figure-rider {
	display: block;
}

.store-card-name {
	font-weight: 800;
	font-size: 13px;
}

.store-new {
	position: absolute;
	z-index: 2;
	top: -8px;
	left: -8px;
	padding: 2px 9px;
	background: var(--orange);
	color: var(--ink);
	border: var(--line);
	border-radius: 8px;
	font-family: var(--display);
	font-size: 13px;
	rotate: -12deg;
}

.store-preview-pictures {
	display: flex;
	align-items: flex-end;
	justify-content: center;
	gap: 12px;
	/* The big picture sits in a box like the small ones on the cards */
	padding: 16px;
	border-radius: 12px;
	background: var(--paper-bright);
	border: var(--line);
	box-shadow: 4px 4px 0 var(--shadow-ink);
}


.store-part {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	font-weight: 800;
}

.store-part > span:last-of-type {
	margin-left: auto;
}

.store-bolts {
	font-family: var(--display);
	font-size: 22px;
	margin: 0 16px 0 auto;
}

.store-card-by {
	font-size: 11px;
	color: var(--ink-soft);
}

/* The notice hangs from the top edge until it is clicked */

.store-error {
	color: var(--red);
	font-weight: 800;
}

.store-made {
	font-size: 13px;
}

/* A decoration on its own in a box */

.figure-box {
	display: flex;
	align-items: center;
	justify-content: center;
}

.figure-box-picture {
	max-width: 100%;
	max-height: 100%;
}

/* A material's tile, repeated so a seam would show */

.figure-tile {
	border: var(--line);
	border-radius: 10px;
	background-repeat: repeat;
	image-rendering: auto;
}

/* A backdrop's three layers stacked over the sky, as they stand behind a level.
   The layers are grey on white and the sky colour multiplies over the lot at the end,
   which is the same sum the game's shader does when it tints each layer. */

.store-backdrop {
	position: relative;
	overflow: hidden;
	isolation: isolate;
	border: var(--line);
	border-radius: 10px;
	background: #fff;
}

.store-backdrop-layer {
	position: absolute;
	left: 0;
	bottom: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: bottom;
}

.store-backdrop::after {
	content: "";
	position: absolute;
	inset: 0;
	/* A backdrop shown outside a level has no sky of its own to take, so it is tinted as the stock one */
	background: var(--backdrop-sky, #a5aeff);
	mix-blend-mode: multiply;
}

/* A backdrop filling a screen is one square hung low over it, the size and the drop the game draws it at, so what
   is seen here is what is seen in a level. The square is measured against the screen, this is only ever a screen's own */
.backdrop-filling .store-backdrop-layer {
	left: 50%;
	top: calc((100% - var(--backdrop-side)) * var(--backdrop-low));
	bottom: auto;
	width: var(--backdrop-side);
	height: var(--backdrop-side);
	translate: -50% 0;
	object-fit: fill;
}

/* The one still backdrop the menus stand on in performance mode, in place of a level drifting by behind them. It is
   the first child of the page so it covers the world and sits under every screen. It carries the corner darkness
   itself because the page's own vignette is painted under it rather than over it */
.menu-backdrop {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

.menu-backdrop::after {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--vignette);
}

.menu-backdrop .store-backdrop {
	position: absolute;
	inset: 0;
	border: 0;
	border-radius: 0;
}

/* The arcade games, the machine in a panel on the left and the cog bank beside it */

.arcade-box {
	width: min(1000px, 100%);
	display: grid;
	grid-template-columns: auto 1fr;
	gap: 40px;
	align-items: start;
	margin-top: 12px;
}

/* A game stands in the same room as the cabinets: the machine in a cabinet of its own neon, the board a dark screen
   with light lines on it, and the bank sign and the note beside it */

.arcade {
	--neon: #ff4fb0;
}

/* The room and a game are drawn in one go, nothing rises in, or the last picture of the world would show through */
.arcade-place {
	animation: none;
}

.arcade.gearfall {
	--neon: #7dff5a;
}

.arcade.juggle {
	--neon: #ffb03a;
}

.arcade.skittles {
	--neon: #b8ff3a;
}

.arcade.flipper {
	--neon: #5adfff;
}

.arcade-machine {
	--face: linear-gradient(90deg, #2a2150, #3a2d6e 30%, #3a2d6e 70%, #241b48);
	--edge-colour: #0b0820;
	--shade: #06041a;
	--lift: 8px;
	padding: 16px;
	border-radius: 14px;
	rotate: -0.6deg;
	box-shadow: 0 0 40px 6px color-mix(in srgb, var(--neon) 45%, transparent);
	animation: neon-breathe 2.6s ease-in-out infinite;
}

/* The board is sized from the screen, never from its own bitmap, or it would jump to size on the first frame it is drawn */
/* The board's own colours, read by the game for its canvas */
.arcade-board {
	--ink: #efe9ff;
	--paper: #0b0820;
	--paper-bright: #0b0820;
	--orange-light: #ffd23a;
	display: block;
	width: min(440px, calc(100vw - 64px), 48vh);
	aspect-ratio: 1 / 1.5;
	border: 4px solid #1a1236;
	border-radius: 8px;
	background: #050311;
	box-shadow: inset 0 0 24px color-mix(in srgb, var(--neon) 40%, transparent);
	cursor: pointer;
	touch-action: none;
}

.arcade-side {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 16px;
	padding-top: 10px;
}

.arcade-side .arcade-plaque {
	margin: 0;
	rotate: -0.6deg;
}

.arcade-side .arcade-no-cogs {
	margin: 0;
	font-weight: 900;
	color: #ff6a6a;
	text-shadow: 0 0 8px rgba(255, 60, 60, 0.6);
}

.arcade-board.empty {
	cursor: default;
}

/* The gear tally and the alley seen from above stand taller than the pachinko, each as tall as its board says */
.arcade-board.gearfall, .arcade-board.skittles {
	width: min(440px, calc(100vw - 64px), 46vh);
	aspect-ratio: 1 / 1.62;
}

.arcade-board.skittles {
	aspect-ratio: 1 / 1.74;
}

.arcade-cheer.miss .cheer-word {
	color: var(--red);
}

/* A screen too short for the whole card draws it tighter rather than hiding its foot below the fold */
@media (max-height: 780px) {
	.bingo-grid {
		grid-template-rows: auto repeat(var(--bingo-side), minmax(86px, 1fr)) auto;
	}

	.bingo-square-words {
		font-size: 12px;
	}

	.bingo-band {
		padding-bottom: 8px;
	}
}

@media (max-width: 900px), (pointer: coarse) and (max-height: 600px) {
	.arcade-box {
		grid-template-columns: 1fr;
	}

	.arcade-machine {
		justify-self: center;
	}
}

/* The cheer, a big green shout in the middle of the screen that slides in from the left and leaves to the right */

.arcade-confetti {
	position: fixed;
	inset: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
}

.arcade-cheer {
	position: fixed;
	top: 50%;
	left: 50%;
	pointer-events: none;
	text-align: center;
	font-family: var(--display);
	color: var(--green);
	text-shadow: var(--outline);
	line-height: 0.95;
	white-space: nowrap;
	animation: cheer-in 600ms cubic-bezier(0.2, 0.9, 0.3, 1.25) both, cheer-out 400ms cubic-bezier(0.6, 0, 1, 0.6) 2200ms forwards;
}

.arcade-cheer .cheer-word {
	font-size: 0.6em;
	color: var(--paper);
}

.arcade-cheer.small {
	font-size: min(64px, 10vw, 18dvh);
}

.arcade-cheer.big {
	font-size: min(112px, 12vw, 22dvh);
}

.arcade-cheer.huge {
	font-size: min(160px, 14vw, 26dvh);
}

@keyframes cheer-in {
	from {
		translate: calc(-50% - 100vw) -50%;
		rotate: -14deg;
		scale: 0.5;
	}
	to {
		translate: -50% -50%;
		rotate: -4deg;
		scale: 1;
	}
}

@keyframes cheer-out {
	from {
		translate: -50% -50%;
		rotate: -4deg;
		opacity: 1;
	}
	to {
		translate: calc(-50% + 100vw) -50%;
		rotate: 10deg;
		opacity: 0;
	}
}

/* Names, wherever a name is drawn, are one thing at one size whatever the words round them: the flag on the left,
   the name in the middle and the icon on the right, the name in the name colour of the card the player wears with a
   hard drop shadow in the card's outline colour, the same as on the card's figure. Nothing is drawn round a name,
   the thing it sits on wears the card */

.name-tag, .menu-account {
	font-family: var(--font);
	font-size: 18px;
	font-weight: 900;
	line-height: 1.25;
}

.name-tag {
	--name-shadow: var(--card-outline, var(--shadow-ink));
	display: inline-flex;
	align-items: center;
	gap: 8px;
	max-width: 100%;
	vertical-align: middle;

}

.name-tag .flag {
	flex-shrink: 0;
	margin: 0;
	vertical-align: middle;
}

/* In a tag that picks the country the flag is a button, an empty dashed one for a player who has not picked one */
.name-flag, .name-icon-picker {
	padding: 0;
	line-height: 1;
	--edge: 0px;
	--face: transparent;
	--shade: transparent;
}

.name-icon-picker {
	display: flex;
	flex-shrink: 0;
}

.name-flag.empty {
	width: 24px;
	height: 18px;
	border: 2px dashed var(--ink-soft);
	border-radius: 3px;
}

/* In a tag that opens the profile the name is a button drawn like the plain name, underlined under the pointer */
.name-tag-name.link {
	font: inherit;
	text-transform: none;
	letter-spacing: 0;
	padding: 2px 0;
	color: inherit;
	--face: transparent;
	--edge: 0px;
	--shade: transparent;
}

.name-tag-name.link:hover {
	transform: none;
	color: inherit;
	text-decoration: underline;
}

/* A name too long for its place is cut with an ellipsis, the padding is the same above as below so the letters stay
   centred beside the flag */
.name-tag-name {
	min-width: 0;
	padding: 2px 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* A name on a card, in a tag or on the card's figure, is in the card's name colour when the card has one, with a hard
   shadow in its outline colour when it has that, a tenth of the letters wide so it looks the same at every size. A
   card that leaves either out leaves the name as it is drawn without a card */
.card-name .name-tag-name, .card-name .figure-card-name {
	color: var(--card-name);
}

.card-outline {
	--card-letter-edge: -1px -1px 0 var(--card-outline), 1px -1px 0 var(--card-outline), -1px 1px 0 var(--card-outline), 1px 1px 0 var(--card-outline);
}

.card-outline .name-tag-name, .card-outline .figure-card-name {
	text-shadow: var(--card-letter-edge), 0.1em 0.1em 0 var(--card-outline);
}

.card-outline .name-tag-name {
	/* The shadow's width, so it is inside the ellipsis cut and the letters stand as far from the icon as without it */
	padding-right: 0.1em;
}

.name-tag.name-clear {
	--name-shadow: var(--shadow-ink);
}

.name-tag.name-clear .name-tag-name {
	color: inherit;
	text-shadow: none;
}

.name-icon {
	flex-shrink: 0;
	/* The flag's width, scaled down from the 32 pixels the icons are drawn at. A tilt would smear it, a turned bitmap is
	   resampled, so a tilted thing holding a name says its tilt in --tilt and the icon turns back by it */
	width: 24px;
	height: 24px;
	rotate: calc(0deg - var(--tilt, 0deg));
	/* The flag's shadow reaches 2px into its gap and the art starts 1px inside the picture, so the icon comes in by
	   the two to stand as far from the name as the flag does */
	margin-left: -3px;
	/* The same 2px hard shadow as the flag, as a drop shadow since the picture is transparent round its shape, and no edge.
	   The shadow takes no room of its own, so the margin under the picture is its height and the picture with its
	   shadow is what stands centred beside the name */
	filter: drop-shadow(2px 2px 0 var(--name-shadow, var(--shadow-ink)));
	margin-bottom: 2px;
}

/* A board row wears the card, so the rank and the time are in the card's text colour */

.board-row.card-background {
	background: var(--card-background) center / cover;
}

.board-row.card-text, .board-row.card-text .board-rank, .board-row.card-text .board-time, .board-row.card-text .board-gap {
	color: var(--card-text);
}

/* A fine edge keeps words legible across the original card artwork. */
.board-row.card-outline .board-rank, .board-row.card-outline .board-time {
	text-shadow: var(--card-letter-edge);
}

/* Your own row is ringed when the card's background covers the highlight */
.board-row.card-background.mine {
	box-shadow: inset 0 0 0 2px var(--orange-deep);
}

.board-name.link {
	font: inherit;
	text-transform: none;
	letter-spacing: 0;
	padding: 0;
	/* Square, the button rounding would clip the flag standing at the left edge */
	border-radius: 0;
	--face: transparent;
	--edge: 0px;
	--shade: transparent;
	color: inherit;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	text-align: left;
}

.board-name.link:hover {
	transform: none;
	color: var(--accent-ink);
}

/* The doors across the top of the workshop, one per room, the open one inked in */

.workshop-doors {
	display: flex;
	gap: 10px;
	margin-top: 6px;
	flex-wrap: wrap;
}

.door {
	font-size: 20px;
	padding: 8px 22px;
	--face: var(--paper);
}

.door-hook:nth-child(odd) {
	rotate: -1deg;
}

.door-hook:nth-child(even) {
	rotate: 1deg;
}

.door.active {
	--face: var(--ink);
	color: var(--paper);
	transform: none;
}


/* The workshop is a shed open at the front: a corrugated roof along the top with lamps hanging from it, the yard
   at dusk behind, the dark closing in at the edges, the sign and the stock up on the beam and the doors hanging
   from it on chains */

section.workshop {
	isolation: isolate;
}

section.workshop > * {
	position: relative;
	z-index: 1;
}

/* The beam sits over the doors under it, so a popout from the stock strip is not hidden behind them */
section.workshop > .workshop-beam {
	z-index: 2;
}

section.workshop::before {
	content: "";
	position: absolute;
	inset: 0 0 auto;
	height: 88px;
	z-index: 0;
	background: repeating-linear-gradient(90deg, #3a2a20 0 14px, #2b1d14 14px 28px);
	border-bottom: 8px solid #1c120b;
	box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
}

section.workshop::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	box-shadow: inset 0 0 180px 30px rgba(35, 15, 0, 0.55);
}

section.workshop > .workshop-lamps {
	position: absolute;
	inset: 0;
	z-index: 0;
	display: flex;
	justify-content: space-between;
	padding: 0 6%;
	pointer-events: none !important;
}

.workshop-lamp {
	position: relative;
	width: 28%;
	height: 100%;
	background: radial-gradient(ellipse 50% 70% at 50% 18%, rgba(255, 196, 110, 0.35), transparent 70%);
	transform-origin: 50% 0;
	animation: lamp-sway 3.4s ease-in-out infinite alternate;
}

.workshop-lamp:nth-child(2) {
	animation-delay: -1.1s;
	animation-duration: 3.9s;
}

.workshop-lamp:nth-child(3) {
	animation-delay: -2.3s;
	animation-duration: 3.1s;
}

@keyframes lamp-sway {
	from {
		rotate: -1.2deg;
	}
	to {
		rotate: 1.2deg;
	}
}

/* The cord down from the roof and the shade at the end of it, lit underneath */
.workshop-lamp::before {
	content: "";
	position: absolute;
	top: 0;
	left: 50%;
	width: 3px;
	height: 150px;
	margin-left: -1px;
	background: #1c120b;
}

.workshop-lamp::after {
	content: "";
	position: absolute;
	top: 150px;
	left: 50%;
	width: 48px;
	height: 22px;
	margin-left: -24px;
	background: #2b1d14;
	clip-path: polygon(32% 0, 68% 0, 100% 100%, 0 100%);
	border-bottom: 5px solid #ffd27a;
	box-shadow: 0 6px 16px rgba(255, 200, 120, 0.9);
}

.workshop-beam h1 {
	rotate: 0deg;
}

.workshop-beam button.link {
	--face: linear-gradient(#a56d38, #7a4a22);
	--edge-colour: #1c120b;
	color: var(--paper);
	text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.5);
}

/* The doors are wooden signs hanging on two chains each, the open one lit. The chains hang from the hook, behind
   the sign, so they stay put while the sign lifts under the pointer */
.door-hook {
	position: relative;
	display: inline-flex;
	padding-top: 16px;
}

.door-hook::before, .door-hook::after {
	content: "";
	position: absolute;
	z-index: 0;
	top: 0;
	width: 3px;
	height: 24px;
	background: repeating-linear-gradient(#8a8a8a 0 3px, #4a4a4a 3px 5px);
}

.door-hook::before {
	left: 19px;
}

.door-hook::after {
	right: 19px;
}

.door {
	--face: repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.08) 0 2px, transparent 2px 9px), linear-gradient(#a56d38, #7a4a22);
	--edge-colour: #1c120b;
	color: var(--paper);
	text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.5);
	/* Over the chains, and swinging from where they hold it */
	z-index: 1;
	transform-origin: 50% -16px;
}

.door:hover {
	animation: sign-swing 900ms ease-in-out;
}

@keyframes sign-swing {
	25% {
		rotate: 2.5deg;
	}
	60% {
		rotate: -1.5deg;
	}
}

.door.active {
	--face: repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.06) 0 2px, transparent 2px 9px), linear-gradient(#ffc457, #ff9f1c);
	color: var(--ink);
	text-shadow: none;
	box-shadow: 0 0 18px rgba(255, 196, 110, 0.7);
}

/* The stock strip in the heading, every resource with its count */

.workshop-stock {
	display: flex;
	gap: 8px;
	flex-wrap: wrap;
	margin: 0 16px 0 auto;
}

/* A chip's edge and shadow are the ones every box in the game is drawn with, named in the :where chains above.
   Drawn by hand they left a pale seam where the border met the shadow */
.stock-chip, .resource-chip {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	padding: 3px 10px 3px 6px;
	border-radius: 999px;
	--face: var(--paper);
	--edge: 2px;
	font-weight: 900;
	font-size: 14px;
	font-variant-numeric: tabular-nums;
	color: var(--ink);
}

/* A stock chip stands off the page, a chip in a recipe lies flat on it */
.stock-chip {
	font-size: 16px;
	--lift: 3px;
}

.resource-chip {
	--lift: 0px;
}

.resource-chip.short {
	--edge-colour: var(--red);
	color: var(--red);
}

/* The question dot on a short chip, the popout under it says where the resource comes from */
.how-to-get {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	margin: -2px -4px -2px 0;
	border-radius: 50%;
	background: var(--blue);
	color: var(--white);
	font-size: 12px;
	font-weight: 900;
	line-height: 1;
	cursor: help;
}

.icon-resource, .icon-expansion {
	width: 18px;
	height: 18px;
	fill: var(--ink-soft);
	flex: none;
}

.recipe-row {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	align-items: center;
	margin-top: 4px;
}

.recipe-time {
	font-size: 13px;
	margin-left: 4px;
}

.small {
	font-size: 13px;
}

.kind-chip {
	display: inline-block;
	font-family: var(--font);
	font-weight: 900;
	font-size: 11px;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	padding: 1px 7px;
	border-radius: 999px;
	background: var(--ink);
	color: var(--paper);
	vertical-align: middle;
	margin-left: 4px;
}

/* The slots, a row of cards, an empty one a big plus, a busy one its job with a timer, a done one with a Collect button */

.slot-row {
	display: flex;
	flex: 1;
	justify-content: center;
	align-items: center;
	align-content: center;
	gap: 12px;
	flex-wrap: wrap;
}

.slot-card {
	width: 170px;
	min-height: 150px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 10px;
	border-radius: 12px;
	background: var(--paper-bright);
	border: 3px dashed color-mix(in srgb, var(--ink) 35%, transparent);
	text-align: center;
	font-size: 14px;
}

.slot-card > strong, .slot-empty > span, .machine-plate, .pick-words > strong {
	text-wrap: balance;
}

.slot-card.busy {
	border-style: solid;
	border-color: var(--ink);
	box-shadow: 4px 4px 0 var(--shadow-ink);
}

.slot-card.done {
	border-color: var(--green);
	animation: slot-done 1.2s ease-in-out infinite;
}

@keyframes slot-done {
	50% {
		box-shadow: 4px 4px 0 var(--shadow-ink), 0 0 0 6px color-mix(in srgb, var(--green) 45%, transparent);
	}
}

.slot-empty {
	width: 100%;
	height: 100%;
	min-height: 126px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 4px;
	--face: transparent;
	--edge: 0px;
	--shade: transparent;
	font-family: var(--font);
	font-weight: 900;
	font-size: 14px;
	text-transform: none;
	letter-spacing: 0;
	color: var(--ink-soft);
}

.slot-empty:hover {
	transform: none;
	color: var(--ink);
}

.slot-plus {
	font-family: var(--display);
	font-size: 44px;
	line-height: 1;
	color: var(--accent-ink);
}

.slot-icon {
	width: 40px;
	height: 40px;
}

.workshop-timer {
	width: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4px;
	font-size: 12px;
}

.workshop-bar {
	width: 100%;
	height: 10px;
	border: 2px solid var(--ink);
	border-radius: 999px;
	background: var(--white);
	overflow: hidden;
}

.workshop-bar-fill {
	height: 100%;
	width: 0;
	background: linear-gradient(var(--orange-light), var(--orange));
	transition: width 250ms linear;
}

button.small {
	font-size: 14px;
	padding: 6px 14px;
}

/* The machine floor, the machines standing in a row along the back wall and the bays with the slots under them */

.workshop-floor.room-floor {
	display: flex;
	flex-direction: column;
	gap: 16px;
	grid-column: 1 / -1;
	min-height: 0;
	overflow: hidden auto;
	padding: 4px 10px 12px 4px;
}

.machine-row {
	display: flex;
	justify-content: center;
	align-items: flex-end;
	flex-wrap: wrap;
	gap: 14px;
	padding: 20px 16px 14px;
	border-radius: 14px;
	/* The wall behind the machines is in the shade, and they stand on a dark ledge */
	background: linear-gradient(rgba(30, 16, 6, 0), rgba(30, 16, 6, 0.55) 45%, rgba(30, 16, 6, 0.7));
	border-bottom: 8px solid #2b1d14;
	flex: none;
}

/* A built machine stands in the open, one not yet built is only a blueprint of itself pinned to the wall */
.machine-card {
	position: relative;
	width: 160px;
	height: 236px;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	padding: 10px 8px 14px;
	border-radius: 10px;
	text-align: center;
	font-size: 13px;
	color: var(--paper);
}

.machine-card:not(.built) {
	background-color: var(--blueprint);
	background-image: var(--blueprint-rule);
	background-size: 12px 12px;
	border: 2px solid var(--blueprint-edge);
	box-shadow: 3px 3px 0 var(--shadow-ink);
}

/* A built machine stands in its own bay, a dark recess in the wall with a lit rim */
.machine-card.built {
	background: linear-gradient(rgba(0, 0, 0, 0.28), rgba(0, 0, 0, 0.45));
	border: 2px solid rgba(0, 0, 0, 0.4);
	box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.12), inset 0 -3px 0 rgba(0, 0, 0, 0.35);
}

/* Unbuilt machines keep their painted silhouette in blueprint blue. */
.machine-card:not(.built) .machine-figure {
	filter: grayscale(1) sepia(1) saturate(3) hue-rotate(155deg);
	opacity: 0.65;
}

.machine-card .machine-figure {
	width: 112px;
	height: 112px;
	flex: none;
}

.machine-card.built .machine-figure {
	filter: drop-shadow(3px 4px 0 rgba(0, 0, 0, 0.45));
}

/* The lamp on the wall over a built machine, amber when it stands idle and blinking green while it runs */
.machine-lamp {
	position: absolute;
	top: 8px;
	right: 10px;
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: #ffb000;
	border: 2px solid #1e1712;
	box-shadow: 0 0 8px #ffb000;
}

.machine-card:not(.built) .machine-lamp {
	display: none;
}

.machine-card.running .machine-lamp {
	background: var(--green);
	box-shadow: 0 0 10px var(--green);
	animation: lamp-blink 1s steps(2) infinite;
}

@keyframes lamp-blink {
	50% {
		background: #1f6b41;
		box-shadow: none;
	}
}

/* The name on a riveted plate */
.machine-plate {
	font-family: var(--display);
	font-weight: 400;
	text-transform: uppercase;
	font-size: 14px;
	letter-spacing: 0.04em;
	padding: 3px 12px;
	border-radius: 6px;
	background: linear-gradient(#5a5048, #3a322c);
	color: var(--paper);
	border: 2px solid #1e1712;
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 2px 2px 0 var(--shadow-ink);
}

.machine-makes {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	font-weight: 800;
	text-shadow: 0 1px 0 rgba(0, 0, 0, 0.6);
}

.machine-makes .icon-resource {
	filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.6));
}

/* The last line of every card, sized for the build button so the card never changes height */
.machine-state {
	margin-top: auto;
	height: 34px;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 12px;
	font-weight: 900;
	text-shadow: 0 1px 0 rgba(0, 0, 0, 0.6);
}

/* The moving pieces use the same painted sheet as their housing. */
.machine-figure .m-working { visibility: hidden; }
.running .machine-figure .m-working { visibility: visible; }
.running .machine-figure .m-idle { visibility: hidden; }

.machine-figure .m-moving, .machine-figure .m-ram, .machine-figure .m-paddle, .machine-figure .m-mould {
	transform-box: view-box;
}

.running .machine-press .m-moving { animation: press-ram 1.1s ease-in infinite; }
.running .machine-press .m-ram {
	transform-origin: 257px 157px;
	animation: press-stem 1.1s ease-in infinite;
}
@keyframes press-stem { 40%, 55% { scale: 1 1.48; } }
@keyframes press-ram { 40%, 55% { translate: 0 54px; } }

.running .machine-foundry .m-flame { animation: flame 0.6s ease-in-out infinite alternate; }
@keyframes flame { to { filter: brightness(1.5) saturate(1.2); } }

.running .machine-vulcaniser .m-moving {
	transform-origin: 417px 95px;
	animation: needle 0.9s ease-in-out infinite alternate;
}
@keyframes needle { from { rotate: -50deg; } to { rotate: 35deg; } }
.running .machine-vulcaniser .m-mould {
	transform-origin: 239px 321px;
	animation: mould 1.4s ease-in-out infinite;
}
@keyframes mould { 40%, 60% { scale: 1 0.78; } }

.running .machine-sawmill .m-moving {
	transform-origin: 342px 178px;
	animation: blade 1.3s linear infinite;
}
@keyframes blade { to { rotate: 360deg; } }

.running .machine-loom .m-moving { animation: shuttle 0.7s ease-in-out infinite alternate; }
@keyframes shuttle { from { translate: -12px 0; } to { translate: 12px 0; } }

.running .machine-mixer .m-paddle {
	transform-origin: 264px 256px;
	animation: paddle 1s ease-in-out infinite;
}
@keyframes paddle { 50% { scale: 0.6 1; } }
.running .machine-mixer .m-drip { animation: drip 1.6s ease-in infinite; }
@keyframes drip { from { opacity: 1; translate: 0 0; } to { opacity: 0; translate: 0 45px; } }

/* The bays under the machines, a hazard stripe along the top of each */
.workshop-bays {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 16px;
	flex: none;
}

.workshop-bays .workshop-panel {
	overflow: visible;
	max-height: none;
}

/* The trim along the top of every panel says which room it is in, hazard tape on the machine floor, the clips of a
   drawing board, the slats of a garage door and the rail of a closet, and the panel's face goes with it */
.workshop-trim {
	flex: none;
	height: 8px;
	margin: -18px -18px 0;
	border-radius: 11px 11px 0 0;
}

.room-floor .workshop-trim {
	background: repeating-linear-gradient(-45deg, #ffcc33 0 12px, #2b1d12 12px 24px);
}

/* The drawing board is a wooden board with a blueprint sheet on it, a screw in each corner holding the sheet down.
   The screw is a drawing, a steel head in a dark ring with a cross slot, so it stays sharp at any size. The four sit
   on the board's face in the 30px frame round the sheet, each centred in its corner */
.room-board .workshop-panel {
	--screw: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><defs><radialGradient id='h' cx='0.38' cy='0.32' r='0.72'><stop offset='0' stop-color='%23f7f9fb'/><stop offset='0.55' stop-color='%23b7c0ca'/><stop offset='1' stop-color='%236b7683'/></radialGradient></defs><circle cx='10' cy='10' r='9.5' fill='%231d2329'/><circle cx='10' cy='10' r='8' fill='url(%23h)'/><g transform='rotate(18 10 10)' stroke-linecap='round'><path d='M10.6 5.4v9.2M5.4 10.6h9.2' stroke='%23ffffff' stroke-width='2.2' opacity='0.55'/><path d='M10 4.8v10.4M4.8 10h10.4' stroke='%23262d34' stroke-width='2.2'/><path d='M10 5.6v8.8M5.6 10h8.8' stroke='%23090c0f' stroke-width='0.9'/></g><path d='M5.6 6.4A5.6 5.6 0 0 1 12.6 4.4' stroke='%23ffffff' stroke-width='1' fill='none' opacity='0.6' stroke-linecap='round'/></svg>");
	--face: var(--screw) 4px 4px / 22px 22px no-repeat, var(--screw) calc(100% - 4px) 4px / 22px 22px no-repeat, var(--screw) 4px calc(100% - 4px) / 22px 22px no-repeat, var(--screw) calc(100% - 4px) calc(100% - 4px) / 22px 22px no-repeat, repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.08) 0 2px, transparent 2px 9px), linear-gradient(#a56d38, #7a4a22);
	--edge-colour: #1c120b;
	padding: 27px;
}

/* The trim and the gap under it make up the top of the frame, the face draws the screws */
.room-board .workshop-trim {
	height: 15px;
	margin: -27px -27px 0;
}

/* The blueprint sheet on the board, the list scrolls inside it and fades at its foot, the sheet itself never fades */
.blueprint-sheet {
	display: flex;
	flex-direction: column;
	flex: 1;
	min-height: 0;
	overflow: hidden;
	border: 2px solid var(--blueprint-edge);
	border-radius: 6px;
	background-color: var(--blueprint);
	background-image: var(--blueprint-rule);
	background-size: 12px 12px;
}

.room-board .store-scroll {
	padding: 14px 16px 20px;
	margin: 0;
}

.room-board .store-scroll > h2, .room-board .store-scroll > .muted {
	color: #f4f8ff;
}

/* The garage has a rolled up door along the top */
.room-garage .workshop-trim {
	height: 18px;
	margin-bottom: 4px;
	background: repeating-linear-gradient(#8a919b 0 5px, #5d646d 5px 9px);
	border-bottom: 2px solid #3a3a3a;
}

/* The closet has a rail with hangers along the top */
.room-closet .workshop-trim {
	height: 22px;
	margin-bottom: 2px;
	background: linear-gradient(#3a3a3a, #3a3a3a) 0 5px / 100% 3px no-repeat, repeating-linear-gradient(90deg, transparent 0 30px, #3a3a3a 30px 32px, transparent 32px 44px) 0 8px / 100% 14px no-repeat;
}

/* The pickers, one row per thing to make or build */

.workshop-dialog {
	rotate: 0deg;
	width: min(720px, 94vw);
	max-height: 86vh;
	display: flex;
	flex-direction: column;
}

.pick-list {
	gap: 8px;
	padding: 4px 8px 24px 4px;
	margin: -4px -8px -24px -4px;
}

.pick-badges {
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
}

.pick-row {
	position: relative;
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 8px 12px;
	border-radius: 12px;
	background: var(--paper-bright);
	border: 2px solid var(--ink);
}

.pick-row.faint {
	opacity: 0.55;
}

.pick-icon {
	width: 36px;
	height: 36px;
}

.pick-words {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 3px;
	flex: 1;
	min-width: 0;
	text-align: left;
	font-size: 14px;
}

.pick-words .recipe-row {
	justify-content: flex-start;
}

.pick-words .resource-chip {
	white-space: nowrap;
	flex-shrink: 0;
}

.built-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
	gap: 8px;
}

.built-card {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4px;
	padding: 6px;
	border-radius: 10px;
	background: var(--paper-bright);
	text-align: center;
}

.store-card.worn {
	box-shadow: 0 0 0 3px var(--green), 4px 4px 0 var(--shadow-ink);
}

/* Figures for the kinds without a picture of their own */

.figure-box.figure-crisp .figure-box-picture {
	image-rendering: auto;
	max-width: 80%;
	max-height: 80%;
}

.figure-box.figure-icon svg {
	width: 70%;
	height: 70%;
	fill: var(--orange-deep);
}

.figure-none {
	width: 64px;
	height: 64px;
	border: 3px dashed color-mix(in srgb, var(--ink) 30%, transparent);
	border-radius: 10px;
}

.figure-flags {
	display: flex;
	align-items: flex-end;
	justify-content: center;
	gap: 2px;
}

.figure-flag {
	width: 30%;
	height: auto;
}

.figure-card {
	position: relative;
	border: var(--line);
	border-radius: 10px;
	background: var(--card-background, var(--paper)) center / cover;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
}

.figure-card-name {
	font-family: var(--display);
	max-width: 90%;
	overflow: hidden;
}

/* The editor menu's third column */

.columns.three {
	grid-template-columns: 1fr 1fr 1fr;
	width: min(1500px, 100%);
}

@media (max-width: 1000px) {
	.columns.three {
		grid-template-columns: 1fr;
	}
}

.supply-section {
	margin-top: 10px;
}

.supply-section h3 {
	font-size: 15px;
	margin-bottom: 6px;
}

/* The arcade room, a dark room with a neon sign, the bank lit on the wall, a carpet, and the cabinets standing on it */

.arcade-room {
	justify-content: center;
}

.arcade-place {
	isolation: isolate;
	background: repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.03) 0 2px, transparent 2px 44px), linear-gradient(180deg, #0a0720 0%, #1a1240 55%, #281c5e 100%);
	overflow: hidden;
}

/* Scattered rings and woven flecks pick up the cabinets' colors without a tiled grid. */
.arcade-place::before {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 34%;
	z-index: -1;
	background-color: #19142e;
	background-image:
		linear-gradient(180deg, #09071445, transparent 25%, #09071465),
		radial-gradient(ellipse at 22% 0%, #ad427d24, transparent 65%),
		radial-gradient(ellipse at 76% 0%, #397e9524, transparent 60%),
		radial-gradient(circle at 80% 34%, transparent 0 7px, #549b98a0 7px 10px, transparent 10.5px),
		radial-gradient(ellipse 14px 3px at 60% 71%, #d97597a0 85%, transparent),
		radial-gradient(ellipse 3px 8px at 93% 68%, #c79a55a0 85%, transparent),
		radial-gradient(circle at 48% 65%, #8270b6a0 0 4px, transparent 4.5px),
		radial-gradient(ellipse 8px 3px at 95% 10%, #638baba0 85%, transparent),
		radial-gradient(circle at 6% 28%, transparent 0 7px, #549b98a0 7px 10px, transparent 10.5px),
		radial-gradient(ellipse 14px 3px at 46% 23%, #d97597a0 85%, transparent),
		radial-gradient(ellipse 3px 8px at 35% 14%, #c79a55a0 85%, transparent),
		radial-gradient(circle at 23% 13%, #8270b6a0 0 4px, transparent 4.5px),
		radial-gradient(ellipse 8px 3px at 58% 32%, #638baba0 85%, transparent),
		radial-gradient(circle at 19% 51%, transparent 0 7px, #549b98a0 7px 10px, transparent 10.5px),
		radial-gradient(ellipse 14px 3px at 66% 89%, #d97597a0 85%, transparent),
		radial-gradient(ellipse 3px 8px at 42% 72%, #c79a55a0 85%, transparent),
		radial-gradient(circle at 86% 58%, #8270b6a0 0 4px, transparent 4.5px),
		radial-gradient(ellipse 8px 3px at 9% 49%, #638baba0 85%, transparent),
		radial-gradient(circle at 13% 93%, transparent 0 7px, #549b98a0 7px 10px, transparent 10.5px),
		radial-gradient(ellipse 14px 3px at 72% 59%, #d97597a0 85%, transparent),
		radial-gradient(ellipse 3px 8px at 33% 91%, #c79a55a0 85%, transparent),
		radial-gradient(circle at 59% 89%, #8270b6a0 0 4px, transparent 4.5px),
		radial-gradient(ellipse 8px 3px at 31% 25%, #638baba0 85%, transparent),
		radial-gradient(circle at 12% 11%, transparent 0 7px, #549b98a0 7px 10px, transparent 10.5px),
		radial-gradient(ellipse 14px 3px at 98% 93%, #d97597a0 85%, transparent),
		radial-gradient(ellipse 3px 8px at 63% 57%, #c79a55a0 85%, transparent),
		radial-gradient(circle at 25% 32%, #8270b6a0 0 4px, transparent 4.5px),
		radial-gradient(ellipse 8px 3px at 86% 31%, #638baba0 85%, transparent),
		radial-gradient(circle at 64% 32%, transparent 0 7px, #549b98a0 7px 10px, transparent 10.5px),
		radial-gradient(ellipse 14px 3px at 56% 15%, #d97597a0 85%, transparent),
		radial-gradient(ellipse 3px 8px at 32% 46%, #c79a55a0 85%, transparent),
		radial-gradient(circle at 81% 67%, #8270b6a0 0 4px, transparent 4.5px),
		radial-gradient(ellipse 8px 3px at 29% 78%, #638baba0 85%, transparent),
		radial-gradient(circle at 58% 48%, transparent 0 7px, #549b98a0 7px 10px, transparent 10.5px),
		radial-gradient(ellipse 14px 3px at 48% 40%, #d97597a0 85%, transparent),
		radial-gradient(ellipse 3px 8px at 26% 95%, #c79a55a0 85%, transparent),
		radial-gradient(circle at 97% 51%, #8270b6a0 0 4px, transparent 4.5px),
		repeating-linear-gradient(0deg, #e5d6ee09 0 1px, transparent 1px 3px),
		repeating-linear-gradient(90deg, #00000012 0 1px, transparent 1px 4px);
	background-repeat: no-repeat;
	border-top: 3px solid #35e0ff;
	box-shadow: 0 -2px 18px rgba(53, 224, 255, 0.55), inset 0 30px 40px rgba(0, 0, 0, 0.45);
}

/* The corners of the room fall into the dark */
.arcade-place::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	box-shadow: inset 0 0 200px 30px rgba(0, 0, 0, 0.6);
}

/* The sign and the way out stay at the top of the screen, whatever stands in the middle of the room */
.arcade-place .screen-heading {
	position: absolute;
	top: 32px;
	left: 50%;
	translate: -50% 0;
	width: min(1200px, calc(100% - 64px));
}

/* The name of the room in neon, one letter of it on the blink */
.arcade-place h1.neon {
	font-size: 56px;
	letter-spacing: 0.08em;
	color: #fff4fb;
	text-shadow: 0 0 4px #fff, 0 0 12px #ff4fb0, 0 0 28px #ff4fb0, 0 0 52px #ff2a9d;
}

.arcade-place h1.neon span {
	display: inline-block;
	/* A space between two words is a letter of its own, or the box would fold it away */
	white-space: pre;
	animation: neon-hum 3s ease-in-out infinite;
}

.arcade-place h1.neon span:nth-child(3) {
	animation: neon-flicker 6s linear infinite;
}

@keyframes neon-hum {
	50% {
		opacity: 0.92;
	}
}

@keyframes neon-flicker {
	0%, 38%, 44%, 46%, 84%, 87%, 100% {
		opacity: 1;
	}
	41%, 45%, 86% {
		opacity: 0.25;
		text-shadow: none;
	}
}

.arcade-bolts {
	margin: 0 16px 0 auto;
}

/* The bolts on the arcade wall are the workshop chip lit up in neon. Its face and its edge are the shared ones under
   other names, a background and a border of its own would be painted over by them */
.arcade-place .stock-chip {
	font-family: var(--display);
	font-weight: 400;
	font-size: 20px;
	letter-spacing: 0.04em;
	padding: 4px 14px 4px 10px;
	--face: #12081a;
	--edge-colour: #ffd23a;
	/* Neon casts light, not an ink shadow */
	--shade: transparent;
	color: #ffd23a;
	text-shadow: 0 0 10px #ffb000;
	box-shadow: 0 0 12px rgba(255, 176, 0, 0.55);
}

/* The light inside the tube, over the face rather than under it */
.arcade-place .stock-chip::after {
	box-shadow: inset 0 0 8px rgba(255, 176, 0, 0.3);
}

.arcade-place .stock-chip .icon-bolts {
	filter: drop-shadow(0 0 4px #ffb000);
}

/* The way out is the exit sign over the door */
.arcade-place .screen-heading button.link {
	--face: #0a3d1e;
	--edge-colour: #7dffb0;
	--shade: transparent;
	--lift: 0px;
	color: #7dffb0;
	text-shadow: 0 0 8px #3ddc84;
	box-shadow: 0 0 16px rgba(61, 220, 132, 0.6);
	border-radius: 6px;
	letter-spacing: 0.08em;
	rotate: 0deg;
}

.arcade-place .screen-heading button.link:hover {
	transform: none;
	box-shadow: 0 0 26px rgba(61, 220, 132, 0.9);
}

/* The bank, an amber sign on the wall, and a note pinned up beside it */
.arcade-wall {
	width: min(1100px, 100%);
	display: flex;
	align-items: center;
	gap: 24px;
	margin: 12px 0 28px;
}

.arcade-place .cog-bank {
	display: flex;
	align-items: baseline;
	gap: 16px;
	flex-wrap: wrap;
	padding: 10px 22px;
	border-radius: 10px;
	background: #07051a;
	border: 3px solid #2e2560;
	box-shadow: inset 0 0 20px rgba(255, 176, 0, 0.15), 0 0 18px rgba(255, 176, 0, 0.25);
}

.arcade-place .cog-bank h2 {
	font-size: 26px;
	color: #ffb000;
	text-shadow: 0 0 10px #ffb000;
}

.arcade-place .cog-bank p {
	margin: 0;
	font-size: 14px;
	color: #d9c98f;
	text-shadow: 0 0 6px rgba(255, 176, 0, 0.5);
}

.arcade-place .cog-bank .arcade-cogs {
	font-family: var(--display);
	font-size: 34px;
	color: #ffd23a;
	text-shadow: 0 0 10px #ffb000;
	font-variant-numeric: tabular-nums;
}

.arcade-plaque {
	margin: 0 0 0 auto;
	max-width: 380px;
	padding: 8px 12px;
	border-radius: 6px;
	background: var(--paper);
	border: 2px solid var(--ink);
	color: var(--ink);
	font-size: 13px;
	font-weight: 700;
	rotate: 1deg;
	box-shadow: 3px 3px 0 var(--shadow-ink);
}

/* The cabinets stand in a row on the carpet, the lit ones in the middle and the unplugged ones at the ends */
.arcade-floor {
	width: 100%;
	display: flex;
	justify-content: center;
	align-items: flex-end;
	gap: 22px;
	padding: 0 16px;
	/* Room under the cabinets for the notes on the carpet, which hang outside them */
	margin-bottom: 100px;
}

.cabinet {
	--neon: #ff4fb0;
	--face: linear-gradient(90deg, #2a2150, #3a2d6e 30%, #3a2d6e 70%, #241b48);
	--edge-colour: #0b0820;
	--shade: #06041a;
	--lift: 8px;
	position: relative;
	width: 230px;
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 0;
	padding: 0;
	border-radius: 14px 14px 6px 6px;
	text-transform: none;
	letter-spacing: 0;
	color: #fff;
	box-shadow: 0 0 40px 6px color-mix(in srgb, var(--neon) 45%, transparent);
	animation: neon-breathe 2.6s ease-in-out infinite;
}

.cabinet.cabinet-gearfall {
	--neon: #7dff5a;
	animation-delay: 0.7s;
}

.cabinet.cabinet-juggle {
	--neon: #ffb03a;
	animation-delay: 1.9s;
}

.cabinet.cabinet-skittles {
	--neon: #b8ff3a;
	animation-delay: 3.1s;
}

.cabinet.cabinet-flipper {
	--neon: #5adfff;
	animation-delay: 3.7s;
}

@keyframes neon-breathe {
	50% {
		box-shadow: 0 0 64px 10px color-mix(in srgb, var(--neon) 65%, transparent);
	}
}

.cabinet:hover {
	transform: translate(-1px, -3px);
	--lift: 10px;
}

.cabinet:active {
	transform: translate(2px, 2px);
	--lift: 4px;
}

/* A cabinet off the floor, unplugged, dark and taped over */
.cabinet.dark, .cabinet.dark:hover, .cabinet.dark:active {
	--neon: transparent;
	--face: linear-gradient(90deg, #171230, #1f1840 30%, #1f1840 70%, #130f28);
	--lift: 8px;
	animation: none;
	opacity: 0.8;
	cursor: default;
	transform: none;
}

/* The marquee, the name of the game lit in the cabinet's own neon */
.cabinet-marquee {
	display: flex;
	justify-content: center;
	align-items: center;
	min-height: 52px;
	padding: 8px 8px;
	border-radius: 10px 10px 0 0;
	background: #0b0820;
	border-bottom: 3px solid #0b0820;
	box-shadow: inset 0 0 18px color-mix(in srgb, var(--neon) 35%, transparent);
}

.cabinet-name {
	font-family: var(--display);
	font-size: 22px;
	line-height: 1;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	text-align: center;
	color: var(--neon);
	text-shadow: 0 0 6px var(--neon), 0 0 14px var(--neon);
	white-space: normal;
}

.cabinet.dark .cabinet-name {
	color: #4a4468;
	text-shadow: none;
}

/* The screen, with what plays on it while nobody is at the cabinet */
.cabinet-screen {
	position: relative;
	display: flex;
	height: 190px;
	margin: 12px 14px 8px;
	border-radius: 8px;
	background: #050311;
	border: 4px solid #1a1236;
	box-shadow: inset 0 0 24px color-mix(in srgb, var(--neon) 40%, transparent);
	overflow: hidden;
}

.cabinet.dark .cabinet-screen {
	box-shadow: none;
}

.cabinet-screen::after {
	z-index: 1;
	content: "";
	position: absolute;
	inset: 0;
	background: repeating-linear-gradient(transparent 0 2px, rgba(0, 0, 0, 0.35) 2px 3px);
	pointer-events: none;
}

.cabinet:hover .cabinet-how, .cabinet:focus-visible .cabinet-how {
	opacity: 1;
}

.cabinet:hover .cabinet-screen {
	box-shadow: inset 0 0 34px color-mix(in srgb, var(--neon) 65%, transparent);
}

.cabinet-picture {
	width: 100%;
	height: 100%;
}

.picture-peg {
	fill: #8f86c9;
}

.picture-gold {
	fill: #ffd23a;
}

.picture-wall {
	stroke: #8f86c9;
}

.picture-gold-line {
	stroke: #ffd23a;
}

.picture-cog {
	fill: var(--orange);
	transform-box: fill-box;
	transform-origin: center;
}

:where(.cabinet-pachinko) .picture-cog {
	animation: cog-fall 2.2s ease-in infinite;
}

:where(.cabinet-gearfall) .picture-cog {
	animation: cog-gears 3s linear infinite;
}

:where(.cabinet-juggle) .picture-cog {
	animation: cog-juggle 1.6s ease-in infinite;
}

:where(.cabinet-skittles) .picture-cog {
	animation: cog-bowl 2.5s ease-out infinite;
}

:where(.cabinet-flipper) .picture-cog {
	animation: cog-flipper 3s linear infinite;
}

@keyframes cog-fall {
	from {
		translate: 0 0;
		rotate: 0deg;
	}
	30% {
		translate: 3px 16px;
	}
	60% {
		translate: -3px 32px;
	}
	85%, 100% {
		translate: 0 50px;
		rotate: 180deg;
	}
}

@keyframes cog-gears {
	0% { translate: 0 0; rotate: 0deg; }
	20% { translate: 0 9px; rotate: 90deg; }
	40% { translate: -15px 16px; rotate: 180deg; }
	60% { translate: -18px 29px; rotate: 270deg; }
	80% { translate: -6px 38px; rotate: 360deg; }
	95%, 100% { translate: -6px 51px; rotate: 450deg; }
}

@keyframes cog-juggle {
	0%, 100% { translate: 0 0; rotate: 0deg; }
	45% { translate: 3px 14px; rotate: 60deg; }
	50% { translate: 3px 14px; rotate: 60deg; }
	55% { translate: 2px 4px; rotate: 80deg; }
	75% { translate: 0 -8px; rotate: 120deg; }
}

@keyframes cog-bowl {
	0%, 15% { translate: 0 0; rotate: 0deg; opacity: 1; }
	65% { translate: 3px -38px; rotate: 220deg; opacity: 1; }
	85%, 100% { translate: 5px -44px; rotate: 260deg; opacity: 0; }
}

@keyframes cog-flipper {
	0% { translate: 23px 27px; rotate: 0deg; }
	12% { translate: 23px 0; rotate: 90deg; }
	24% { translate: 3px -4px; rotate: 180deg; }
	36% { translate: -19px 10px; rotate: 270deg; }
	50% { translate: 5px 29px; rotate: 360deg; }
	62% { translate: -10px 39px; rotate: 450deg; }
	75% { translate: 13px 20px; rotate: 540deg; }
	90% { translate: -7px 5px; rotate: 630deg; }
	100% { translate: 0 40px; rotate: 720deg; }
}

/* The out of order tape across a dark screen */
.cabinet-tape {
	position: relative;
	z-index: 2;
	box-shadow: 2px 5px 2px rgb(0 0 0 / 0.5);
	margin: auto;
	text-align: center;
	/* The two lines of the sign, never broken any other way */
	white-space: pre;
	line-height: 1.5;
	rotate: -8deg;
	padding: 4px 10px;
	background: #ffcc33;
	border: 3px solid #2b1d12;
	color: #2b1d12;
	font-family: var(--font);
	font-weight: 900;
	font-size: 14px;
	text-transform: uppercase;
	letter-spacing: 0.06em;
}

/* The control panel, a stick and two buttons */
.cabinet-panel {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 14px;
	height: 34px;
	margin: 0 10px;
	border-radius: 6px;
	background: linear-gradient(#4a3f7a, #2e2557);
	border: 3px solid #0b0820;
}

.cabinet-stick {
	width: 14px;
	height: 14px;
	border-radius: 50%;
	background: radial-gradient(circle at 35% 35%, #ff8080, #c01030);
	box-shadow: 0 0 0 2px #0b0820;
}

.cabinet-key {
	width: 12px;
	height: 12px;
	border-radius: 50%;
	background: radial-gradient(circle at 35% 35%, #fff59b, #e0a800);
	border: 2px solid #0b0820;
}

.cabinet-key:last-child {
	background: radial-gradient(circle at 35% 35%, #b0f4ff, #1aa8c8);
}

.cabinet.dark .cabinet-slot {
	filter: grayscale(1) brightness(0.5);
}

.cabinet.dark .cabinet-stick, .cabinet.dark .cabinet-key {
	filter: grayscale(1) brightness(0.5);
}

/* The coin slot, one cog a go */
.cabinet-slot {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	margin: 8px 10px 12px;
	font-family: var(--font);
	font-weight: 900;
	font-size: 11px;
	color: #cfc6ff;
}

.cabinet-slot::before {
	content: "";
	width: 26px;
	height: 6px;
	border-radius: 3px;
	background: #05030f;
	box-shadow: inset 0 1px 0 #5a4f8a;
}

.cabinet-slot-cog {
	width: 14px;
	height: 14px;
	fill: var(--orange);
}

/* How the game goes, on a note laid on the carpet in front of the cabinet */
.cabinet-how {
	position: absolute;
	/* Shown while the cabinet is under the pointer, seven of them at once were a wall of words */
	opacity: 0;
	transition: opacity 0.2s;
	left: 50%;
	top: calc(100% + 12px);
	translate: -50% 0;
	width: 92%;
	padding: 6px 8px;
	border-radius: 6px;
	background: var(--paper);
	border: 2px solid var(--ink);
	color: var(--ink);
	font-family: var(--font);
	font-weight: 700;
	font-size: 11px;
	line-height: 1.35;
	text-align: center;
	white-space: normal;
	rotate: -1.5deg;
	box-shadow: 2px 2px 0 var(--shadow-ink);
}

.cog-bank h2 {
	margin: 0;
}

/* The rider and their plate share one racing card. */

.profile-dialog {
	width: min(980px, 94vw);
	max-height: 90vh;
}

.profile-body {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	grid-auto-rows: max-content;
	align-content: start;
	gap: 12px;
	/* Room for the shadows of the panels and the tilt of the card */
	padding: 6px 10px 12px 6px;
	overflow-y: auto;
	min-height: 0;
}

/* A screen too short for the whole card draws it tighter rather than hiding its foot below the fold */
@media (max-height: 780px) {
	.bingo-grid {
		grid-template-rows: auto repeat(var(--bingo-side), minmax(86px, 1fr)) auto;
	}

	.bingo-square-words {
		font-size: 12px;
	}

	.bingo-band {
		padding-bottom: 8px;
	}
}

@media (max-width: 700px) {
	.profile-body {
		grid-template-columns: 1fr;
	}
}

.trophy {
	color: var(--ink);
}

.profile-hero {
	display: grid;
	grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr);
	align-items: center;
	gap: 24px;
}

.profile-hero, .profile-numbers, .profile-shelf {
	grid-column: 1 / -1;
}

/* The plate wears the card artwork; the membership date sits below it on paper. */
.profile-card {
	align-self: center;
	container-type: inline-size;
	display: flex;
	flex-direction: column;
	gap: 16px;
	padding: 12px 0;
	min-width: 0;
	--tilt: -0.5deg;
	rotate: var(--tilt);
	justify-content: center;
	align-items: center;
	text-align: center;
}

/* A soft spotlight keeps the rider clear of the surrounding paper. */
.profile-portrait {
	display: flex;
	min-width: 0;
	background: radial-gradient(ellipse at center, #ffcd6a66, transparent 68%);
	justify-content: center;
	align-items: center;
	rotate: 0.5deg;
}

.profile-portrait-picture {
	max-width: 100%;
	max-height: 200px;
	width: auto;
	height: auto;
}

/* The name on the profile is the one big name in the game, the flag and the icon beside it stay their size */
.profile-name .name-tag-name {
	white-space: normal;
	overflow-wrap: anywhere;
	text-overflow: clip;
	line-height: 1.1;
	font-family: var(--display);
	font-size: clamp(22px, 9cqi, 44px);
}

.profile-name-row {
	position: relative;
	display: flex;
	width: 100%;
	min-width: 0;
	min-height: 116px;
	padding: 26px 22px;
	align-items: center;
	justify-content: center;
	--edge: 3px;
	--edge-colour: #867b67;
	--face: var(--card-background, linear-gradient(135deg, #ece5d3, #b8b0a0));
	border-radius: 14px;
}

.profile-name-row::after {
	background-position: center;
	background-size: cover;
	background-repeat: no-repeat;
	box-shadow: inset 0 0 0 3px #ded4bf, inset 0 0 0 5px #766b58;
}

/* Four recessed mounting screws frame the name without covering the card's artwork. */
.profile-plate-screws {
	position: absolute;
	inset: 10px;
	pointer-events: none;
	background: radial-gradient(circle, #564e42 0 2px, #c9c0aa 2px 3px, #655c4c 3px 4px, transparent 4px) top left / 8px 8px no-repeat,
		radial-gradient(circle, #564e42 0 2px, #c9c0aa 2px 3px, #655c4c 3px 4px, transparent 4px) top right / 8px 8px no-repeat,
		radial-gradient(circle, #564e42 0 2px, #c9c0aa 2px 3px, #655c4c 3px 4px, transparent 4px) bottom left / 8px 8px no-repeat,
		radial-gradient(circle, #564e42 0 2px, #c9c0aa 2px 3px, #655c4c 3px 4px, transparent 4px) bottom right / 8px 8px no-repeat;
}

.profile-since {
	margin: 0;
	padding: 8px 16px;
	border-block: 1px dashed #82644166;
	color: var(--ink);
	font-weight: 900;
}

.profile-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
	gap: 10px;
}

/* The statistics stay on paper so small labels have a consistent contrast. */
.profile-cell {
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 8px;
	border-radius: 10px;
	border: 1px solid color-mix(in srgb, var(--card-outline, var(--ink)) 35%, transparent);
	background: none;
	color: var(--card-text, var(--ink));
	text-align: center;
}

.profile-cell .muted {
	color: inherit;
}

.profile-cell strong {
	font-family: var(--display);
	font-size: 30px;
	color: var(--card-name, var(--orange-deep));
	text-shadow: var(--card-letter-edge, 2px 2px 0 var(--ink));
}

.profile-numbers { gap: 8px; }

.profile-numbers .profile-grid {
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 0;
	padding-block: 4px 8px;
}

.profile-numbers .profile-cell {
	border: 0;
	border-radius: 0;
}

.profile-numbers .profile-cell + .profile-cell {
	border-left: 1px solid #82644144;
}

.profile-medals {
	justify-content: center;
	padding-top: 8px;
	border-top: 1px dashed #82644166;
}

@media (max-width: 700px) {
	.profile-hero { grid-template-columns: 1fr; gap: 0; padding: 12px; }
	.profile-hero .profile-card { grid-row: 1; gap: 8px; padding: 4px 0; }
	.profile-name-row { min-height: 80px; padding: 18px 14px; }
	.profile-since { font-size: 12px; padding: 6px 10px; }
	.profile-portrait-picture { max-height: 145px; width: auto; }
}

.trophy-shelf {
	display: flex;
	gap: 12px;
	flex-wrap: wrap;
}

/* The blueprint reveal, the darkness, the word, the roll that drops and shakes, and the sheet it unrolls into */

.reveal {
	position: fixed;
	inset: 0;
	z-index: 40;
	display: flex;
	align-items: center;
	justify-content: center;
	background: color-mix(in srgb, var(--dark) 82%, transparent);
	opacity: 0;
	transition: opacity 400ms ease;
}

.reveal.dark {
	opacity: 1;
}

.reveal-stage {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 20px;
	width: min(720px, 94vw);
	max-height: calc(100dvh - 24px);
}

.reveal-word {
	flex-shrink: 0;
	font-family: var(--display);
	font-size: min(96px, 9.5vw);
	color: var(--green);
	text-shadow: var(--outline);
	white-space: nowrap;
	rotate: -4deg;
	opacity: 0;
	translate: -100vw 0;
}

.reveal.word .reveal-word {
	animation: reveal-word-in 500ms cubic-bezier(0.2, 0.9, 0.3, 1.25) both;
	opacity: 1;
	translate: 0 0;
}

@keyframes reveal-word-in {
	from {
		translate: -100vw 0;
		rotate: -14deg;
		scale: 0.5;
	}
	to {
		translate: 0 0;
		rotate: -4deg;
		scale: 1;
	}
}

/* The roll, the picture of a rolled blueprint with a band round it, unseen until it drops */

.reveal-roll {
	position: relative;
	width: 320px;
	--face: transparent;
	--edge: 0px;
	--shade: transparent;
	padding: 0;
	opacity: 0;
	cursor: pointer;
	filter: drop-shadow(6px 6px 0 var(--shadow-ink));
}

.reveal-roll img {
	display: block;
	width: 100%;
	height: auto;
}

/* The drop and the shake after it are one animation, so nothing restarts between them */

.reveal.dropped .reveal-roll {
	animation: roll-drop 700ms cubic-bezier(0.3, 0.7, 0.4, 1.4) both, roll-shake 240ms ease-in-out 700ms infinite;
	opacity: 1;
}

.reveal-roll:hover {
	transform: scale(1.04);
}

@keyframes roll-drop {
	from {
		translate: 0 -80vh;
		rotate: -30deg;
		opacity: 1;
	}
	to {
		translate: 0 0;
		rotate: 0deg;
		opacity: 1;
	}
}

@keyframes roll-shake {
	0%, 100% {
		rotate: 0deg;
		translate: 0 0;
	}
	25% {
		rotate: -3deg;
		translate: -4px 0;
	}
	75% {
		rotate: 3deg;
		translate: 4px 0;
	}
}

/* The sheet, blue paper ruled like a blueprint, the picture inked in white then coloured in, the words under it */

.reveal-sheet {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 8px;
	width: 100%;
	min-height: 0;
	overflow-y: auto;
	padding: 28px 32px 24px;
	border-radius: 14px;
	border: var(--line);
	background:
		linear-gradient(rgba(255, 255, 255, 0.08) 1px, transparent 1px) 0 0 / 100% 24px,
		linear-gradient(90deg, rgba(255, 255, 255, 0.08) 1px, transparent 1px) 0 0 / 24px 100%,
		linear-gradient(#2a58a8, #1c3c7c);
	box-shadow: 8px 8px 0 var(--shadow-ink);
	color: var(--paper);
	animation: sheet-unroll 700ms cubic-bezier(0.2, 0.9, 0.3, 1.15) both;
	transform-origin: top center;
}

@keyframes sheet-unroll {
	from {
		scale: 1 0.1;
		opacity: 0.6;
	}
	to {
		scale: 1 1;
		opacity: 1;
	}
}

.reveal-picture {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 220px;
	flex-shrink: 0;
	/* Grey and faint while the drawing is still being made, coloured in once it is done */
	filter: grayscale(1) brightness(3) contrast(0.6) drop-shadow(0 0 2px rgba(255, 255, 255, 0.8));
	opacity: 0.55;
	transition: filter 900ms ease, opacity 900ms ease;
}

.reveal.drawn .reveal-picture {
	filter: none;
	opacity: 1;
}

.reveal-kind {
	font-family: var(--font);
	font-weight: 900;
	font-size: 14px;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: var(--orange-light);
	opacity: 0;
}

.reveal-name {
	font-size: 44px;
	color: var(--paper);
	text-shadow: 3px 3px 0 var(--shadow-ink);
	text-align: center;
	opacity: 0;
}

.reveal-words {
	margin: 0;
	text-align: center;
	max-width: 540px;
	opacity: 0;
}

.reveal-needs {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	align-items: center;
	justify-content: center;
	opacity: 0;
}

/* The grey of muted text is for paper, on the blue sheet the word is the sheet's own ink, a little dimmed */

.reveal-needs .muted {
	color: var(--paper);
	opacity: 0.8;
}

.reveal-sheet .buttons {
	opacity: 0;
	pointer-events: none;
}

.reveal.named .reveal-kind, .reveal.named .reveal-name, .reveal.named .reveal-words, .reveal.named .reveal-needs {
	animation: rise 400ms cubic-bezier(0.2, 0.9, 0.3, 1.2) both;
	opacity: 1;
}

.reveal.named .reveal-name {
	animation-delay: 80ms;
}

.reveal.named .reveal-words {
	animation-delay: 160ms;
}

.reveal.named .reveal-needs {
	animation-delay: 240ms;
}

.reveal.ready .reveal-sheet .buttons {
	animation: rise 320ms cubic-bezier(0.2, 0.9, 0.3, 1.2) both;
	opacity: 1;
	pointer-events: auto;
}

.reveal .arcade-confetti {
	z-index: 1;
}

/* Phones, the workshop, the arcade room and the reveal in one column that scrolls */

@media (max-width: 900px), (pointer: coarse) and (max-height: 600px) {
	.screen.workshop, .arcade-room, .maps {
		justify-content: flex-start;
		overflow-y: auto;
	}

	.workshop .screen-heading {
		flex-wrap: wrap;
		gap: 6px;
	}

	.workshop .screen-heading h1 {
		order: -2;
	}

	.workshop .screen-heading button.link {
		order: -1;
		margin-left: auto;
	}

	/* The stock goes on a row of its own under the title, with smaller chips */
	.workshop-stock {
		flex-basis: 100%;
		margin: 0;
		gap: 5px;
	}

	.stock-chip {
		font-size: 13px;
		padding: 2px 8px 2px 5px;
		--lift: 2px;
	}

	.stock-chip .icon-resource {
		width: 14px;
		height: 14px;
	}

	.workshop-doors {
		gap: 6px;
	}

	.door {
		font-size: 15px;
		padding: 6px 12px;
	}

	.door-hook {
		rotate: 0deg;
	}

	/* One column, the panels stacked and the page scrolling, the stage gone. Nothing may shrink to the screen,
	   the screen scrolls instead */
	.workshop .workshop, .workshop.staged .workshop {
		display: flex;
		flex-direction: column;
		flex: none;
		width: 100%;
		height: auto;
		gap: 16px;
		padding-bottom: 96px;
	}

	.workshop-panel, .workshop-panel.wide {
		flex: none;
		max-height: none;
		min-height: auto;
		overflow: visible;
		padding: 14px;
	}

	.workshop-trim {
		margin: -14px -14px 0;
	}

	.workshop-panel .store-scroll {
		overflow: visible;
		mask-image: none;
		padding: 10px 6px 6px;
		margin: -10px -6px -6px;
	}

	/* The board keeps its frame, the screws need the room, and the sheet keeps its margin */
	.room-board .workshop-panel {
		padding: 27px;
	}

	.room-board .store-scroll {
		padding: 12px 10px 16px;
		margin: 0;
	}

	.workshop-bays {
		grid-template-columns: 1fr;
	}

	.slot-card {
		width: calc(50% - 6px);
		min-height: 130px;
	}

	.machine-row {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 12px;
		padding: 12px 4px;
	}

	.machine-card {
		width: 100%;
		height: auto;
		min-height: 220px;
		padding: 10px 6px;
		font-size: 13px;
	}

	.machine-card .machine-figure {
		width: min(100%, 100px);
		height: 100px;
	}

	.pick-row {
		flex-wrap: wrap;
		gap: 8px 12px;
	}

	.pick-row > button {
		margin-left: auto;
	}

	.pick-row[data-blueprint] {
		display: grid;
		grid-template-columns: 72px minmax(0, 1fr);
	}

	.pick-row[data-blueprint] > button {
		grid-column: 1 / -1;
		width: 100%;
		margin: 0;
	}

	.workshop-dialog {
		width: 100%;
		max-height: 90vh;
	}

	.store-preview-pictures {
		flex-wrap: wrap;
	}

	/* The room scrolls, the cabinets stand in a column with their notes under them and the unplugged ones are gone */
	.arcade-room {
		overflow-y: auto;
		justify-content: flex-start;
		padding-bottom: 32px;
	}

	.arcade-place .screen-heading {
		position: static;
		translate: none;
		width: 100%;
		flex-wrap: wrap;
		gap: 12px;
	}

	.arcade-place .screen-heading h1 {
		flex-basis: 100%;
		white-space: nowrap;
		font-size: clamp(28px, 7vw, 40px);
	}

	.arcade-place .screen-heading button.link {
		margin-left: auto;
	}

	.arcade .arcade-box {
		padding-bottom: 96px;
	}

	.arcade-wall {
		margin: 12px 0 0;
	}

	.arcade-room::before {
		display: none;
	}

	.arcade-wall {
		width: 100%;
		flex-direction: column;
		align-items: stretch;
		gap: 12px;
	}

	.arcade-plaque {
		margin: 0;
		max-width: none;
	}

	.arcade-floor {
		flex: none;
		flex-direction: column;
		align-items: center;
		gap: 96px;
		margin-top: 28px;
		padding-bottom: 120px;
	}

	.profile-dialog {
		width: 100%;
		max-height: 90vh;
	}

	.profile-body {
		gap: 14px;
	}

	.arcade-wall, .arcade-floor, .columns.three, .reveal-stage {
		flex: none;
	}

	.profile-card {
		rotate: 0deg;
		min-height: 0;
	}

	.profile-name .name-tag-name {
		font-size: clamp(22px, 9cqi, 36px);
	}

	.profile-cell strong {
		font-size: 24px;
	}

	.columns.three {
		width: 100%;
	}

	.map-column-heading h2 {
		font-size: 22px;
	}

	.reveal-stage {
		width: 100%;
		padding: 0 10px;
		gap: 12px;
	}

	.reveal-roll {
		width: min(320px, 80vw);
	}

	.reveal-sheet {
		padding: 18px 14px 16px;
	}

	.reveal-picture {
		min-height: 160px;
	}

	.reveal-name {
		font-size: 30px;
	}

	.reveal-sheet .buttons {
		gap: 10px;
	}

	.reveal-sheet button.primary.big {
		font-size: 22px;
		padding: 12px 28px;
	}

	.built-grid {
		grid-template-columns: repeat(auto-fill, minmax(76px, 1fr));
	}
}

/* The admin tools and the dev debug screen, the ways in buttons in the bottom corner of the menu, the tools a wide panel with tabs */

.menu-corner {
	position: fixed;
	left: 16px;
	bottom: 16px;
	z-index: 5;
	display: flex;
	gap: 10px;
}

.menu-corner button {
	font-size: 15px;
	padding: 8px 16px;
	rotate: -1.5deg;
}

/* The dev debug screen, a row per thing it can play, the pickers and sliders in a line */
.dev-controls {
	display: flex;
	flex-wrap: wrap;
	gap: 8px 14px;
	align-items: center;
}

.dev-controls label {
	display: flex;
	align-items: center;
	gap: 6px;
	font-weight: 700;
}

.dev-controls input[type="text"] {
	width: min(280px, 100%);
	min-width: 0;
}

.dev-machines {
	display: flex;
	flex-wrap: wrap;
	gap: 14px;
}

/* The title shows the logo alone, the way into the tools waits for the menu */
.menu.intro .menu-corner {
	display: none;
}

.admin {
	justify-content: flex-start;
	overflow-y: auto;
}

.admin .editor-tabs {
	width: min(1200px, 100%);
	flex-wrap: wrap;
	margin: 10px 0 0;
}

.admin-panel {
	width: min(1200px, 100%);
	flex: none;
	margin: 10px 0 96px;
	position: relative;
	min-height: 200px;
}

.admin-list {
	display: flex;
	flex-direction: column;
	gap: 8px;
	position: relative;
	min-height: 60px;
}

.admin-row {
	display: flex;
	flex-direction: column;
	gap: 8px;
	padding: 10px 14px;
	border-radius: 12px;
	background: var(--paper-bright);
	border: 2px solid var(--ink);
}

.admin-row.banned {
	opacity: 0.7;
	border-style: dashed;
}

.admin-row-head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px 12px;
}

.admin-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
}

.admin-actions button, .admin-versions button {
	font-size: 13px;
	padding: 5px 12px;
}

.admin-actions select {
	padding: 5px 10px;
}

button.danger {
	--face: linear-gradient(#ee7b76, var(--red));
	color: var(--white);
}

.kind-chip.red {
	background: var(--red);
}

.admin-versions {
	display: flex;
	flex-direction: column;
	gap: 4px;
	padding-left: 12px;
}

.admin-version {
	display: flex;
	align-items: center;
	gap: 12px;
	font-size: 14px;
}

.admin-version.banned {
	opacity: 0.6;
}

.admin-row.chat-row {
	flex-direction: row;
	align-items: center;
	flex-wrap: wrap;
	gap: 10px;
}

.admin-chat-text {
	flex: 1;
	min-width: 200px;
	overflow-wrap: anywhere;
}

.admin-string {
	display: grid;
	grid-template-columns: 1fr auto;
	gap: 4px 10px;
	padding: 8px 12px;
	border-radius: 10px;
	background: var(--paper-bright);
	border: 2px solid color-mix(in srgb, var(--ink) 30%, transparent);
}

.admin-string.changed {
	border-color: var(--accent-ink);
}

.admin-string-head {
	grid-column: 1 / -1;
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	align-items: baseline;
	font-size: 13px;
}

.admin-string-head code {
	font-family: ui-monospace, monospace;
	font-size: 12px;
	color: var(--ink-soft);
}

.admin-string-input {
	border-radius: 8px;
	padding: 5px 10px;
	min-width: 0;
}

.admin-file {
	width: 100%;
	min-height: 50vh;
	font-family: ui-monospace, monospace;
	font-size: 13px;
	padding: 10px 12px;
	resize: vertical;
}

.admin-fields {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.admin-role-label {
	display: flex;
	align-items: center;
	gap: 6px;
}

button.role-help {
	width: 18px;
	height: 18px;
	min-height: 0;
	padding: 0;
	border-radius: 50%;
	--face: var(--blue);
	--edge: 0px;
	--shade: transparent;
	--lift: 0px;
	color: var(--white);
	font: 900 12px/18px var(--font);
	letter-spacing: 0;
	text-transform: none;
}

button.role-help:hover:not(:disabled), button.role-help:active:not(:disabled) {
	transform: none;
	--lift: 0px;
}

.admin-settings {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	gap: 8px;
}

.admin-setting {
	display: flex;
	flex-direction: column;
	padding: 8px 12px;
	border-radius: 10px;
	background: var(--paper-bright);
	font-size: 14px;
}

.admin .profile-grid {
	margin-bottom: 8px;
}

@media (max-width: 700px) {
	.menu-corner {
		left: 10px;
		bottom: calc(var(--corner-inset) + var(--corner-step));
	}

	.menu-corner button {
		font-size: 13px;
		padding: 6px 12px;
	}

	.admin-string {
		grid-template-columns: 1fr;
	}
}

/* Nothing in the rooms moves for a player who asked for less motion */
@media (prefers-reduced-motion: reduce) {
	.running .machine-figure .m-working { visibility: hidden; animation: none; }
	.running .machine-figure .m-idle { visibility: visible; }
	.workshop-lamp, .machine-figure *, .cabinet, .arcade-place h1.neon span, .picture-cog, .machine-lamp,
	.events h1.marquee span, .events-trophy .trophy-picture {
		animation: none;
	}
}

/* A popout of words under a thing while the pointer rests on it, set with hint(). One element on the body, put
   under the thing by hint() itself, so a faded or clipping ancestor of the thing never touches it */

.hint-popout {
	position: fixed;
	z-index: 50;
	width: max-content;
	max-width: 220px;
	padding: 6px 10px;
	border-radius: 8px;
	color: var(--ink);
	/* The edge and the shadow are the shared ones, named in the :where chains above. Drawn by hand they left a seam
	   between the border and the shadow that showed as a dark line while the popout came and went */
	--face: var(--paper);
	--edge: 2px;
	--lift: 3px;
	font-family: var(--font);
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0;
	text-transform: none;
	text-shadow: none;
	line-height: 1.3;
	text-align: left;
	white-space: normal;
	pointer-events: none;
	opacity: 0;
	translate: 0 -4px;
	transition: opacity 0.12s, translate 0.12s;
}

.hint-popout.shown {
	opacity: 1;
	translate: 0 0;
	transition-delay: 0.25s;
}

/* The competition board sits over a live course. */
.events {
	justify-content: flex-start;
	overflow: hidden;
	isolation: isolate;
	padding-top: 34px;
	background: transparent;
	animation: none;
}

.events::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	background: linear-gradient(180deg, #192f344d, transparent 36%, #192f3426);
}

.events .editor-panel {
	min-width: 0;
	--edge-colour: #635743;
	--shade: #253b3e66;
	--lift: 5px;
	border-radius: 14px;
}

.events .editor-panel h2 {
	letter-spacing: .025em;
}

/* The marquee marks the competition board. */
.events h1.marquee {
	font-size: 52px;
	letter-spacing: 0.06em;
	color: var(--paper);
	text-shadow: var(--outline);
}

.events h1.marquee span, .menu-events-heading .marquee>span, .guide-bolts>span, .guide-call>span {
	display: inline-block;
	white-space: pre;
}

.events h1.marquee span, .menu-events-card.join-open .marquee>span {
	animation: event-wave 3.4s ease-in-out infinite;
	animation-delay: calc(var(--letter) * .12s);
}

@keyframes event-wave {
	0%, 55%, 100% {
		translate: 0 0;
	}
	25% {
		translate: 0 var(--event-hop,-13px);
	}
}

/* The trophy catches the sun */
.events-trophy {
	position: relative;
	flex: none;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 14px 18px;
}

.events-trophy::before {
	content: "";
	position: absolute;
	inset: -6%;
	border-radius: 50%;
	background: radial-gradient(circle, rgba(255, 236, 170, 0.85) 0%, rgba(255, 226, 140, 0.3) 45%, transparent 70%);
}

.events-trophy .trophy-picture {
	position: relative;
	animation: event-bob 4.5s ease-in-out infinite;
}

@keyframes event-bob {
	50% {
		translate: 0 -6px;
		rotate: -1deg;
	}
}

.events-body {
	width: min(1200px, 100%);
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: 14px;
	/* Room for the shadows and the tilt of the panels */
	padding: 8px 10px 20px 6px;
	overflow-y: auto;
	min-height: 0;
	position: relative;
	/* No bar down the arena, a screen too short for the whole week scrolls and the bottom edge fades */
	scrollbar-width: none;
	mask-image: linear-gradient(to bottom, #000 calc(100% - 16px), transparent 100%);
}

.events-body::-webkit-scrollbar {
	display: none;
}

.events-body > .editor-panel {
	flex: none;
}

/* The standings and the hall of winners share what height is left under the rest, side by side, and only their
   own lists scroll. On a narrow screen they stack instead */
.events-bottom {
	display: flex;
	flex: 1 1 auto;
	min-height: 180px;
	gap: 18px;
	/* Never wrapped: a wrapped line takes its height from what is in it, and then the lists inside would not scroll */
	align-items: stretch;
}

/* A screen too short for the whole card draws it tighter rather than hiding its foot below the fold */
@media (max-height: 780px) {
	.bingo-grid {
		grid-template-rows: auto repeat(var(--bingo-side), minmax(86px, 1fr)) auto;
	}

	.bingo-square-words {
		font-size: 12px;
	}

	.bingo-band {
		padding-bottom: 8px;
	}
}

@media (max-width: 900px), (pointer: coarse) and (max-height: 600px) {
	.events-bottom {
		flex-direction: column;
	}
}

.events-bottom > .editor-panel {
	display: flex;
	flex-direction: column;
	min-height: 0;
}

.events-standings {
	flex: 2 1 0;
	--face: linear-gradient(145deg, #f6edda, #e9e0ca);
}

.events-winners {
	flex: 1 1 0;
	--face: linear-gradient(145deg, #f2deb0, #d9bf8d);
}

.events-hero {
	--face: linear-gradient(110deg, #f8e9c8, #fff5df 55%, #eddbb6);
	display: flex;
	flex-direction: row;
	align-items: center;
	gap: 24px;
	flex-wrap: wrap;
	padding: 14px 22px;
}

.events-hero-words {
	min-width: 0;
	flex: 1 1 320px;
	display: flex;
	flex-direction: column;
	gap: 4px;
}

/* The lines of the card are laid out by the gap, their own margins would stack on top of it */
.events-hero-words p, .events-rules p {
	margin: 0;
}

.events-hero .buttons {
	margin: 8px 0 0;
}

/* How it works sits in the corner of the top card, parted from the rest by a rule down its left */
.events-rules {
	flex: 0 1 404px;
	padding: 12px 0 12px 24px;
	border-left: 3px double #bca782;
	align-self: stretch;
	display: flex;
	flex-direction: column;
	justify-content: center;
}

.events-rules h3 {
	margin: 0;
	font-family: var(--display);
	font-weight: 400;
	font-size: 20px;
	text-transform: uppercase;
	color: var(--accent-ink);
}

.events-name {
	overflow-wrap: anywhere;
	margin: 0;
	font-size: 34px;
	line-height: 1;
	color: var(--accent-ink);
}

/* The trophy stands a little proud of the panel, like everything else in the game it is not quite straight */
.trophy-picture {
	rotate: -3deg;
	filter: drop-shadow(3px 5px 0 #493b2d55);
	flex: none;
}

.events-status {
	display: flex;
	align-items: baseline;
	gap: 12px;
	flex-wrap: wrap;
}

.events-status strong {
	font-family: var(--display);
	font-weight: 400;
	font-size: 20px;
	text-transform: uppercase;
	letter-spacing: 0.02em;
}

.events-today {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
}

.events-today strong {
	font-family: var(--display);
	font-weight: 400;
	font-size: 20px;
	text-transform: uppercase;
}

.events-mine.out {
	color: var(--red);
}

.events-mine.risk {
	color: #a34e38;
	font-weight: 800;
	white-space: pre-line;
}

/* The week's five days, one box each with an arrow between them, in a panel of their own. A day whose level is not
   out yet is a parcel, see the wrapper below */
.events-bracket {
	padding: 16px 22px 22px;
	--face: linear-gradient(120deg, #315c5e, #234549);
	--edge-colour: #203c3f;
	color: #fff0cc;
}

.events-bracket > h2 {
	color: #fff0cc;
}

.event-steps {
	display: flex;
	gap: 10px;
	flex-wrap: wrap;
	margin-top: 6px;
}

.event-step {
	flex: 1 1 150px;
	min-width: 130px;
	display: flex;
	flex-direction: column;
	gap: 6px;
	padding: 13px 14px;
	border-radius: 5px 12px 5px 12px;
	min-height: 104px;
	color: var(--ink);
	--edge: 1px;
	--edge-colour: #d5c5a5;
	--face: linear-gradient(145deg, #fff5dd, #e9dab9);
	--shade: #102f3255;
}

/* The arrow from one day to the next */
.event-arrow {
	flex: none;
	align-self: center;
	font-family: var(--display);
	font-size: 22px;
	color: #d8c99f;
}

.event-step.completed {
	--face: linear-gradient(145deg, #d4e0c7, #b4c8af);
	--edge-colour: #9bb298;
}

.event-step.now {
	--face: linear-gradient(145deg, #ffdb86, #e7ad51);
	--edge-colour: #ffe1a3;
	--shade: #0d282966;
	--lift: 5px;
}

/* The parcel over a day whose level is not out yet: orange paper in two halves, a ribbon crossing it both ways with a
   bow tied at the crossing, the day written on it and how long it stays on along the bottom. When the level comes
   out the halves swing open and the ribbon and the bow fly off, and the beats of that are in UNWRAP in eventscreen.ts */
.event-wrap {
	position: absolute;
	inset: 0;
	/* The step's corner less its edge, so the paper sits inside the outline */
	border-radius: 10px;
	overflow: hidden;
	display: flex;
	align-items: flex-end;
	justify-content: center;
	--ribbon: 15px;
	--tie: 46%;
}

.event-wrap-half {
	position: absolute;
	top: 0;
	bottom: 0;
	width: 50%;
	background:
		repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.16) 0 6px, transparent 6px 20px),
		radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.22) 0 2.6px, transparent 3.2px) 0 0 / 30px 30px,
		linear-gradient(180deg, var(--orange-light) 0%, var(--orange) 55%, var(--orange-deep) 100%);
	transition: transform 700ms cubic-bezier(0.45, 0, 0.75, 1), opacity 700ms ease-in;
}

.event-wrap-half.left {
	left: 0;
	transform-origin: left center;
}

.event-wrap-half.right {
	right: 0;
	transform-origin: right center;
}

/* The ribbon, red with an ink line down each side, the way every other edge in the game is drawn */
.event-wrap-ribbon {
	position: absolute;
	background: linear-gradient(180deg, var(--red-light) 0%, var(--red) 55%, #ab2f2a 100%);
	transition: transform 480ms ease-in, opacity 480ms ease-in;
}

.event-wrap-ribbon.down {
	left: 50%;
	top: 0;
	bottom: 0;
	width: var(--ribbon);
	translate: -50% 0;
	border-left: 2px solid var(--ink);
	border-right: 2px solid var(--ink);
}

.event-wrap-ribbon.across {
	left: 0;
	right: 0;
	top: var(--tie);
	height: var(--ribbon);
	translate: 0 -50%;
	border-top: 2px solid var(--ink);
	border-bottom: 2px solid var(--ink);
}

.event-bow {
	position: absolute;
	left: 50%;
	top: var(--tie);
	width: 70px;
	height: 48px;
	translate: -50% -44%;
	transition: transform 520ms ease-in, opacity 520ms ease-in;
	filter: drop-shadow(1px 2px 0 rgba(43, 29, 18, 0.35));
}

.bow-part {
	fill: var(--red);
	stroke: var(--ink);
	stroke-width: 3;
	stroke-linejoin: round;
}

.event-wrap-note {
	position: relative;
	margin-bottom: 6px;
	font-size: 12px;
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--paper-bright);
	text-shadow: 1px 1px 0 var(--ink), -1px 1px 0 var(--ink), 1px -1px 0 var(--ink), -1px -1px 0 var(--ink);
	transition: opacity 220ms ease;
}

/* The day is written on the paper while it is on, and back in ink the moment it starts coming off */
.event-step.wrapped .event-step-day {
	position: relative;
	z-index: 1;
	color: var(--paper-bright);
	text-shadow: 1px 1px 0 var(--ink), -1px 1px 0 var(--ink), 1px -1px 0 var(--ink), -1px -1px 0 var(--ink);
	transition: color 260ms ease;
}

.event-step.opening .event-step-day {
	color: var(--ink-soft);
	text-shadow: none;
}

.event-step.opening .event-wrap-half.left {
	transform: perspective(440px) rotateY(-105deg);
	opacity: 0;
}

.event-step.opening .event-wrap-half.right {
	transform: perspective(440px) rotateY(105deg);
	opacity: 0;
}

.event-step.opening .event-wrap-ribbon.down {
	transform: translateY(-165%) rotate(-16deg);
	opacity: 0;
}

.event-step.opening .event-wrap-ribbon.across {
	transform: translateY(-260%) rotate(9deg);
	opacity: 0;
}

.event-step.opening .event-bow {
	transform: translateY(-190%) rotate(24deg) scale(1.25);
	opacity: 0;
}

.event-step.opening .event-wrap-note {
	opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
	.event-wrap-half, .event-wrap-ribbon, .event-bow, .event-wrap-note {
		transition: none;
	}
}

.event-step.opening .event-step-day {
	color: var(--ink-soft);
	text-shadow: none;
}

.event-step.opening .event-wrap-half.left {
	transform: perspective(440px) rotateY(-105deg);
	opacity: 0;
}

.event-step.opening .event-wrap-half.right {
	transform: perspective(440px) rotateY(105deg);
	opacity: 0;
}

.event-step.opening .event-wrap-ribbon {
	transform: translateY(-150%) rotate(-14deg);
	opacity: 0;
}

.event-step.opening .event-wrap-note {
	opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
	.event-wrap-half, .event-wrap-ribbon, .event-wrap-note {
		transition: none;
	}
}

.event-step-day {
	position: relative;
	z-index: 1;
	font-family: var(--display);
	font-weight: 400;
	font-size: 15px;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--ink-soft);
	transition: color 260ms ease;
}

/* A warm ticket marks the current round without relying on colour alone. */
.event-step.now .event-step-day, .event-step.now .event-step-now {
	color: #684522;
}

.event-step-name {
	overflow-wrap: anywhere;
	font-family: var(--display);
	font-weight: 400;
	font-size: 20px;
	text-transform: uppercase;
	line-height: 1.1;
}

.event-step-now {
	font-size: 13px;
	font-weight: 800;
	text-transform: uppercase;
}

/* The standings are a board like any other, and a rider who is out is faded with their place given up.
   A long field scrolls inside the board, with no bar and the last row fading out. The fade is on the riders and
   not on the board, or the white of the board and its outline would fade away with them */
.event-riders {
	margin-top: 8px;
	flex: 1;
	/* Five full rows, the knockout line and the faded foot stay visible before this board starts scrolling */
	min-height: 240px;
	overflow: hidden;
}

.event-riders-scroll {
	display: flex;
	flex-direction: column;
	gap: 4px;
	height: 100%;
	overflow-y: auto;
	scrollbar-width: none;
	mask-image: linear-gradient(to bottom, #000 calc(100% - 30px), transparent 100%);
}

.event-riders-scroll::-webkit-scrollbar {
	display: none;
}

.event-knockout-line {
	display: flex;
	align-items: center;
	gap: 8px;
	color: var(--red);
	font-family: var(--display);
	font-size: 12px;
	letter-spacing: .04em;
	text-transform: uppercase;
}

.event-knockout-line::before, .event-knockout-line::after {
	content: "";
	flex: 1;
	border-top: 3px dotted currentColor;
}

.board-row.out {
	opacity: 0.55;
}

.board-row.out .board-rank {
	visibility: hidden;
}

.board-row.out .board-time {
	font-family: var(--font);
	font-size: 14px;
}

.event-rules {
	margin: 8px 0 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: 6px;
	font-size: 14px;
}

.event-rules li {
	display: flex;
	align-items: flex-start;
	gap: 8px;
}

/* The tick is outlined in ink and carries the same hard shadow every button does, at the size of an icon. The
   outline is the same stroke drawn wider underneath, a stroke has no outline of its own */
.event-tick {
	width: 22px;
	height: 22px;
	flex: none;
	fill: none;
	stroke-linecap: round;
	stroke-linejoin: round;
	filter: drop-shadow(2px 2px 0 var(--shadow-ink));
}

.event-tick path:first-child {
	stroke: var(--ink);
	stroke-width: 7.5;
}

.event-tick path:last-child {
	stroke: var(--green);
	stroke-width: 3.5;
}

/* The hall of winners, a trophy with the event's name and the rider under it. A long hall scrolls the same way
   the standings do */
.events-winners .trophy-shelf {
	gap: 20px;
	margin-top: 8px;
	flex: 1;
	min-height: 0;
	overflow-y: auto;
	scrollbar-width: none;
	mask-image: linear-gradient(to bottom, #000 calc(100% - 24px), transparent 100%);
}

.events-winners .trophy-shelf::-webkit-scrollbar {
	display: none;
}

.events-winners .trophy {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4px;
	text-align: center;
	width: 160px;
}

@media (max-width: 600px) {
	.events { padding: 20px 10px 0; }
	.events h1.marquee { font-size: 38px; }
	.events-body { padding: 6px 4px 22px; gap: 16px; }
	.events-hero { padding: 18px 16px; gap: 16px; }
	.events-trophy { padding: 0; margin: 0 auto; }
	.events-hero-words { flex-basis: 100%; }
	.events-name { font-size: 30px; }
	.events-rules { flex-basis: 100%; border-left: 0; border-top: 3px double #bca782; padding: 16px 0 0; }
	.events-bracket { padding: 16px; }
	.event-steps { gap: 12px; }
	.event-step { flex-basis: calc(50% - 12px); min-width: 0; }
	.event-arrow { display: none; }
	.events-bottom { flex: none; min-height: 0; }
	.events-bottom > .editor-panel { min-height: 220px; }
	.event-riders-scroll { max-height: 320px; }
}

/* Today's level on the events card of the menu */
.menu-event-level {
	display: flex;
	align-items: baseline;
	gap: 8px;
	flex-wrap: wrap;
}

.menu-event-level strong {
	font-family: var(--display);
	font-weight: 400;
	font-size: 20px;
	text-transform: uppercase;
}

/* A trophy on the profile shelf, the picture over the event's name and the week it was won */
.profile-shelf .trophy {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
	text-align: center;
	width: 140px;
}

/* The week's bingo card, sixteen small jobs on a sheet that opens over whatever screen the player is on.

   One card and nothing else: a dark band with a string of bulbs across the head, the four columns under it headed
   with the game's own four letters, a sheet of ruled squares, and what every row and every column pays standing in
   the margin at the end of its line. Closing a line strikes it through in green and lights its chip. Where the two
   margins meet in the corner stands what the whole card pays */

/* The card is the only thing to look at while it is up, so the screen under it goes right back */
.bingo-backdrop {
	background: rgba(16, 10, 4, 0.74);
	/* The card's darkness is the deepest in the game, so it takes the longest to come on */
	animation-duration: 460ms;
}

.dialog.bingo-card {
	width: min(1060px, calc(100vw - 28px));
	max-height: calc(100vh - 28px);
	padding: 0;
	gap: 0;
	rotate: -0.5deg;
	border-radius: var(--radius);
	--face: var(--paper-bright);
	animation: card-rise 460ms cubic-bezier(0.16, 0.84, 0.44, 1);
}

.dialog.bingo-card.leaving {
	animation: card-sink 340ms cubic-bezier(0.55, 0, 0.85, 0.2) forwards;
}

/* The card slides up into the page and fades in over the whole of it, and slides back down fading out */
@keyframes card-rise {
	from {
		opacity: 0;
		transform: translateY(90px);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

@keyframes card-sink {
	from {
		opacity: 1;
		transform: none;
	}
	to {
		opacity: 0;
		transform: translateY(90px);
	}
}

/* The band across the head, the bulbs strung along its top edge and the name of the game under them */
.bingo-band {
	flex-shrink: 0;
	position: relative;
	display: flex;
	align-items: center;
	gap: 14px;
	/* Out over the card's own edge on three sides, or the paper face behind would show as a pale line round the band */
	margin: calc(-1 * var(--edge)) calc(-1 * var(--edge)) 0;
	padding: 36px 19px 11px;
	border-radius: var(--radius) var(--radius) 0 0;
	background: linear-gradient(180deg, #40291a, var(--ink));
	overflow: hidden;
}

.bingo-lights {
	position: absolute;
	top: 0;
	left: -1%;
	width: 102%;
	height: 46px;
	pointer-events: none;
}

.lights-wire {
	fill: none;
	stroke: #171009;
	stroke-width: 3;
}

.lights-flex {
	stroke: #171009;
	stroke-width: 2;
}

/* Every fourth bulb burns a beat behind its neighbours, so the string runs rather than blinks */
.lights-bulb {
	stroke: #171009;
	stroke-width: 2;
	animation: bingo-bulb 1.8s ease-in-out infinite;
}

.lights-bulb.bulb1 {
	animation-delay: 0.45s;
}

.lights-bulb.bulb2 {
	animation-delay: 0.9s;
}

.lights-bulb.bulb3 {
	animation-delay: 1.35s;
}

@keyframes bingo-bulb {
	0%, 100% {
		fill: #ffe07a;
		filter: drop-shadow(0 0 6px #ffc457);
	}
	55% {
		fill: #8a6630;
		filter: none;
	}
}

.bingo-sign {
	margin: 0;
	font-family: var(--display);
	font-weight: 400;
	font-size: 30px;
	line-height: 1;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--paper-bright);
}

.bingo-clock {
	margin-left: auto;
	font-size: 13px;
	font-weight: 800;
	color: color-mix(in srgb, var(--paper) 62%, transparent);
}

.bingo-close {
	display: grid;
	place-items: center;
	width: 34px;
	height: 34px;
	padding: 0;
	border-radius: 999px;
	--face: var(--paper);
	--lift: 3px;
}

.bingo-cross {
	width: 18px;
	height: 18px;
	fill: none;
	stroke: var(--ink);
	stroke-width: 3;
	stroke-linecap: round;
}

/* The sheet under the band. A card too tall for the screen scrolls, and the bottom edge fades rather than growing
   a bar down the middle of the paper */
.bingo-sheet {
	display: flex;
	flex-direction: column;
	gap: 12px;
	padding: 16px 18px 16px;
	overflow-y: auto;
	min-height: 0;
	scrollbar-width: none;
}

.bingo-sheet::-webkit-scrollbar {
	display: none;
}

/* The card and, beside it, what the whole card pays */
.bingo-spread {
	display: flex;
	align-items: center;
	gap: 4px;
}

/* One grid holds the heads, the squares and the pay in both margins, every one placed by hand, so a chip always
   stands at the end of the line it belongs to whatever the words in the squares do */
.bingo-grid {
	flex: 1;
	min-width: 0;
	display: grid;
	grid-template-columns: repeat(var(--bingo-side), minmax(0, 1fr)) auto;
	grid-template-rows: auto repeat(var(--bingo-side), minmax(110px, 1fr)) auto;
}

/* The four letters over the four columns, the way a bingo card is headed. They light one after another, the next
   as the one before it goes out, and then the sign rests until it comes round again */
.bingo-head {
	animation: bingo-head-glow 5s ease-in-out infinite;
	padding-bottom: 7px;
	font-family: var(--display);
	font-weight: 400;
	font-size: 30px;
	line-height: 1;
	letter-spacing: 0.06em;
	text-align: center;
	color: var(--accent-ink);
	text-shadow: 2px 2px 0 rgba(43, 29, 18, 0.16);
}

@keyframes bingo-head-glow {
	0%, 8%, 100% {
		color: var(--accent-ink);
		text-shadow: 2px 2px 0 rgba(43, 29, 18, 0.16);
	}
	4% {
		color: var(--orange-light);
		text-shadow: 2px 2px 0 rgba(43, 29, 18, 0.16), 0 0 14px var(--orange-light), 0 0 30px var(--orange);
	}
}

/* One cell of the sheet. Its rule is shared with its neighbour's, so the sixteen are ruled once and framed at the
   sheet's own edge rather than floating apart as sixteen little cards */
.bingo-square {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin: -1px;
	padding: 9px 10px;
	border: 2px solid var(--ink);
	background: var(--paper-bright);
	overflow: hidden;
}

/* Every other column is a shade warmer, so the eye can follow a row across the sheet */
.bingo-square.tint {
	background: var(--paper);
}

.bingo-square-words {
	position: relative;
	z-index: 1;
	margin: 0;
	font-size: 13px;
	font-weight: 800;
	line-height: 1.3;
}

/* A square that is done goes the colour of the ink it was stamped with */
.bingo-square.done {
	background: #fbe6bd;
}

.bingo-square.done.tint {
	background: #f7e0b4;
}

/* DONE struck across a square that is ticked, the postmark's ring in red, coming down the way the medal on the
   results does. Its angle is its own, leaning up to the left like every other but never quite the same twice */
.bingo-done {
	position: absolute;
	inset: 0;
	margin: auto;
	width: 86px;
	height: 86px;
	/* Struck over the words, the way a stamp lands on a form that is already filled in */
	z-index: 2;
	padding: 6px;
	--ring: 4px;
	outline-offset: 4px;
	font-size: 21px;
	letter-spacing: 0.08em;
	color: var(--red);
	opacity: 0.88;
	pointer-events: none;
	animation: stamp 460ms both;
}

/* The bar keeps clear of the re-roll in the corner beside it */
.bingo-bar {
	position: relative;
	z-index: 1;
	margin-top: auto;
	margin-right: 32px;
	height: 8px;
	border-radius: 999px;
	border: 2px solid var(--ink);
	background: rgba(43, 29, 18, 0.14);
	overflow: hidden;
}

.bingo-bar-fill {
	height: 100%;
	background: var(--orange);
	transition: width 200ms ease;
}

.bingo-count {
	position: relative;
	z-index: 1;
	font-size: 11px;
	font-weight: 900;
	color: var(--ink-soft);
}

/* The way onto a level a square names, one of the game's own yellow buttons at a size that fits a square. It sits
   at the foot of the square where the bar of a square that counts sits, so it stands at the same height on every
   one of them however many lines the words above it take */
.bingo-square button.bingo-play {
	align-self: flex-start;
	margin-top: auto;
	font-size: 13px;
	padding: 3px 12px;
	--lift: 3px;
	--edge: 2px;
	border-radius: 8px;
}

/* The re-roll at the foot of the square, the arrow on its own with its price under the pointer. It puts itself
   there, so it is named in the :not chain of the ink shadow rules above */
.bingo-square button.bingo-swap {
	position: absolute;
	right: 6px;
	bottom: 6px;
	/* Over the words, the bar and the count, each of which is a line the width of the square and would take the
	   pointer off the parts of the button they cross */
	z-index: 2;
	display: grid;
	place-items: center;
	width: 26px;
	height: 26px;
	padding: 0;
	--face: var(--paper-bright);
	--lift: 2px;
	border-radius: 999px;
}

.bingo-swap-arrow {
	width: 14px;
	height: 14px;
	fill: none;
	stroke: var(--ink);
	stroke-width: 2.6;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* What a line pays, standing at the end of that line: a row's out in the right margin, a column's under the foot */
.bingo-pay {
	display: flex;
	align-items: center;
}

/* The chip fills the margin and stands in the middle of it, so four chips of four widths line up with each other
   rather than raggedly off the board's edge */
.bingo-pay.across {
	justify-self: stretch;
	align-self: center;
	justify-content: center;
	/* The same on both sides, or the gap off the board's edge would push the chip that far off the middle */
	padding: 0 14px;
}

/* Filled across the column and centred inside, the same way a row's chip is centred in its margin */
.bingo-pay.down {
	justify-self: stretch;
	align-self: start;
	justify-content: center;
	padding-top: 13px;
}

/* Paid rewards share the red marker ink on the sheet. */
.bingo-pay.done .stock-chip {
	--face: color-mix(in srgb, var(--red) 18%, var(--paper));
}

/* What the whole card pays, standing beside the pay list as the last and biggest line of it */
.bingo-full {
	position: relative;
	flex: none;
	align-self: stretch;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 1px;
	width: 158px;
	padding: 10px 0 12px 16px;
	border-left: 2px dashed color-mix(in srgb, var(--ink) 35%, transparent);
	text-align: center;
}

/* The pool of light the prize stands in */
.bingo-full::before {
	content: "";
	position: absolute;
	left: 50%;
	width: min(220px, 100%);
	top: 50%;
	height: 110px;
	translate: -50% -50%;
	background: radial-gradient(ellipse at center, rgba(255, 190, 90, 0.45) 0%, rgba(255, 190, 90, 0.12) 52%, transparent 74%);
	pointer-events: none;
}

/* The prize itself, hugging its own words, so what it takes to win it pops out under the prize and not under the
   foot of the card the panel is as tall as */
.bingo-full-thing {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 1px;
	text-align: center;
}

/* What is won is the blueprint for the thing, so what stands here is the blueprint: the thing drawn in white line
   on a sheet of the blue ruled paper, the same ink the reveal draws in before it colours the drawing in */
.bingo-prize-sheet {
	display: grid;
	place-items: center;
	/* Clear of the label over it and the name under it on both sides */
	margin: 10px 0 11px;
	padding: 9px;
	border-radius: 8px;
	/* Its edge and its shadow are the shared ones, named in the :where chains above. A border and a box shadow of
	   its own leave a seam between them, the same seam the days of an event grew before they were drawn this way */
	--face: var(--blueprint-rule), var(--blueprint);
	--edge: 2px;
	--edge-colour: var(--blueprint-edge);
	--lift: 3px;
}

/* The ruled paper is two of the face's three layers, the colour under them takes no size */
.bingo-prize-sheet::after {
	background-size: 12px 12px, 12px 12px, auto;
}

.bingo-full-label {
	font-size: 10px;
	font-weight: 900;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--ink-soft);
}

/* The thing itself, in the colours it will be built in, so what is played for looks like what is won. The blue paper
   behind it and the word under it are what say it comes as a blueprint. A soft halo lifts a dark one off the paper,
   which is the only thing done to it.

   It drifts over its paper, never far. The paper itself holds still: its rules are a hairline apart and shimmer if
   it moves at all */
.bingo-prize-sheet > .figure-box, .bingo-prize-sheet > .bingo-prize-empty {
	position: relative;
	animation: bingo-float 11s ease-in-out infinite;
}

.bingo-prize-sheet > .figure-box {
	filter: drop-shadow(0 0 2px rgba(255, 255, 255, 0.85)) drop-shadow(0 0 7px rgba(255, 255, 255, 0.4));
}

@keyframes bingo-float {
	0%, 100% {
		translate: 0 0;
		rotate: 0deg;
	}
	22% {
		translate: 4px -5px;
		rotate: -2deg;
	}
	48% {
		translate: -3px -7px;
		rotate: 1.4deg;
	}
	73% {
		translate: -5px -2px;
		rotate: -0.8deg;
	}
}

/* An icon is a small mark beside a name everywhere else, in the corner it fills its box */
.bingo-prize-sheet > .figure-box.figure-crisp .figure-box-picture {
	width: 88%;
	height: 88%;
	max-width: none;
	max-height: none;
}

/* A player who owns every one of the kind has nothing waiting, so the sheet carries a question instead */
.bingo-prize-empty {
	position: relative;
	font-family: var(--display);
	font-size: 64px;
	line-height: 1.2;
	color: var(--blueprint-edge);
	opacity: 0.7;
}

/* The reward type sits in an outlined pill directly beneath its name. */
.bingo-prize-note {
	position: relative;
	/* The card leans half a degree, this stands up straight against it */
	rotate: 0.5deg;
	margin-top: 7px;
	padding: 1px 8px;
	border-radius: 999px;
	border: 2px solid var(--ink);
	background: var(--paper);
	font-size: 10px;
	font-weight: 900;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ink-soft);
}

.bingo-full:has(.bingo-prize-owned) {
	min-width: max-content;
}

.bingo-prize-owned {
	margin-top: 6px;
	color: var(--ink-soft);
	font-size: 11px;
	font-weight: 700;
	white-space: nowrap;
}

.bingo-prize-name {
	position: relative;
	font-family: var(--display);
	font-weight: 400;
	font-size: 17px;
	line-height: 1.05;
	color: var(--accent-ink);
}

/* A line that is closed, one stroke from edge to edge of the sheet so it runs on toward the chip it paid. The layer
   lies over the squares alone, one unit to a square, and the stroke keeps its width whatever shape they take */
.bingo-strike {
	position: relative;
	z-index: 3;
	pointer-events: none;
}

.bingo-line-layer {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	overflow: visible;
}

/* A faint preview follows the same felt-tip stroke as a completed line. */
.bingo-line {
	fill: none;
	stroke: var(--red);
	stroke-width: 8;
	stroke-linecap: butt;
	stroke-linejoin: round;
	mix-blend-mode: multiply;
	opacity: 0;
	transition: opacity 130ms ease;
}

.bingo-line.showing {
	opacity: 0.24;
}

.bingo-line.done {
	opacity: 0.8;
}

.bingo-marker-pressure {
	stroke-width: 9;
	stroke-dasharray: 80 143 110 91;
	stroke-dashoffset: -26;
}

/* The line under the sheet: how far the week has got, and how a square is thrown away */
.bingo-foot {
	flex-shrink: 0;
	display: flex;
	align-items: center;
	gap: 12px;
	flex-wrap: wrap;
	font-size: 13px;
}

.bingo-tally {
	display: flex;
	align-items: center;
	gap: 9px;
}

.bingo-tally strong {
	font-family: var(--display);
	font-weight: 400;
	font-size: 22px;
	line-height: 1;
	letter-spacing: 0.02em;
}

/* A closed line is worth saying out loud, so the count of them is a green chip */
.bingo-lines-tally {
	padding: 3px 10px;
	border-radius: 999px;
	border: 2px solid var(--ink);
	background: var(--green);
	font-size: 12px;
	font-weight: 900;
}

.bingo-guest {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-left: auto;
	font-weight: 800;
}

/* A screen too short for the whole card draws it tighter rather than hiding its foot below the fold */
@media (max-height: 780px) {
	.bingo-grid {
		grid-template-rows: auto repeat(var(--bingo-side), minmax(86px, 1fr)) auto;
	}

	.bingo-square-words {
		font-size: 12px;
	}

	.bingo-band {
		padding-bottom: 8px;
	}
}

@media (max-width: 900px), (pointer: coarse) and (max-height: 600px) {
	.bingo-grid {
		grid-template-rows: auto repeat(var(--bingo-side), minmax(120px, auto)) auto;
	}

	.bingo-square {
		padding: 7px 8px 36px;
	}

	.bingo-square-words {
		font-size: 11px;
	}

	.bingo-head {
		font-size: 24px;
	}

	.bingo-full {
		width: 116px;
	}
}

/* Nothing on the card moves for a player who asked for less motion */
@media (prefers-reduced-motion: reduce) {
	.lights-bulb, .bingo-full::before, .bingo-done, .bingo-head, .bingo-prize-sheet > * {
		animation: none;
	}
}

/* The bingo card on the menu, the prize drawn small over how many squares are ticked */
.menu-bingo-prize {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4px;
	margin: 2px 0;
}

.menu-bingo-prize + .muted {
	text-align: center;
}

.menu-bingo-prize strong {
	font-family: var(--display);
	font-weight: 400;
	font-size: 20px;
	letter-spacing: 0.02em;
	color: var(--accent-ink);
}

@media (max-width: 900px), (pointer: coarse) and (max-height: 600px) {
	.map-editor {
		grid-template-columns: 60px minmax(0, 1fr);
		overflow: hidden;
	}

	.editor-top-bar {
		gap: 8px;
	}

	.editor-top-group.right {
		margin-left: 0;
	}

	.editor-top-bar .tab {
		padding: 6px 8px;
		font-size: 12px;
	}

	.editor-materials {
		width: 60px;
		padding: 6px;
	}

	.editor-materials .swatch {
		width: 44px;
		height: 44px;
	}

	.editor-side-panel {
		align-self: end;
		width: min(320px, 100%);
		max-height: 50dvh;
		min-height: 0;
		border-top: var(--line);
	}

	.editor-status-line {
		white-space: normal;
		max-height: 64px;
		overflow-y: auto;
		font-size: 11px;
	}

	.bingo-spread {
		flex-direction: column;
		align-items: stretch;
		gap: 16px;
		flex: none;
	}

	.bingo-grid {
		flex: none;
		width: 100%;
	}

	.bingo-full {
		width: 100%;
		padding: 16px 0 0;
		border-left: 0;
		border-top: 2px dashed color-mix(in srgb, var(--ink) 35%, transparent);
	}
}

@media (max-width: 500px) {
	.bingo-sheet {
		padding: 12px 8px;
	}

	.bingo-grid {
		grid-template-rows: auto repeat(var(--bingo-side), minmax(160px, auto)) auto;
	}

	.bingo-square {
		padding: 6px 4px 36px;
	}

	.bingo-square-words {
		font-size: 11px;
	}

	.bingo-pay.across {
		padding: 0 4px;
	}

	.bingo-pay .stock-chip {
		gap: 2px;
		padding: 2px 3px;
		font-size: 10px;
	}

	.bingo-pay .icon-resource {
		width: 12px;
		height: 12px;
	}

	.bingo-bar {
		margin-right: 0;
	}

	.bingo-square button.bingo-play {
		font-size: 11px;
		padding: 4px 6px;
	}

	.bingo-done {
		width: 46px;
		height: 46px;
		font-size: 11px;
		--ring: 2px;
	}
}

.editor-touch-controls {
	display: none;
}

@media (pointer: coarse) {
	button:not(.bingo-swap):not(.bingo-play):not(.swatch):not(.picker-choice):not(.nook-shell-button):not(.hatchery-hands) {
		min-height: 44px;
		min-width: 44px;
	}

	input[type="range"] {
		min-height: 44px;
	}

	.editor-touch-controls {
		display: flex;
	}
}

@media (max-width: 500px) {
	.result-medal.stamp {
		font-size: clamp(18px, 5.5vw, 26px);
	}

	.letter-top {
		flex-wrap: wrap;
		gap: 12px;
	}

	.letter-corner {
		margin-left: auto;
	}
}

@media (pointer: coarse) and (orientation: landscape) and (max-height: 600px) {
	.arcade {
		display: grid;
		grid-template-columns: max-content minmax(0, 360px);
		grid-template-rows: auto minmax(0, 1fr);
		justify-content: center;
		gap: 12px 24px;
	}

	.arcade .screen-heading {
		grid-column: 2;
		grid-row: 1;
		align-self: start;
	}

	.arcade .screen-heading h1 {
		font-size: clamp(22px, 4vw, 32px);
	}

	.arcade .arcade-box {
		display: contents;
	}

	.arcade .arcade-machine {
		grid-column: 1;
		grid-row: 1 / 3;
		padding: 6px;
		rotate: 0deg;
	}

	.arcade-board, .arcade-board.gearfall, .arcade-board.skittles {
		width: auto;
		height: calc(100dvh - 48px);
	}

	.arcade-side {
		grid-column: 2;
		grid-row: 2;
		align-self: start;
		gap: 12px;
		padding: 0;
	}
}

@media (pointer: coarse) and (orientation: landscape) and (max-height: 600px) {
	.menu.intro .logo :is(img, .logo-shadow) {
		max-width: 70vw;
		max-height: 44dvh;
	}

	.menu-bingo {
		display: grid;
		grid-template-columns: minmax(0, 1fr) 180px;
		gap: 6px 24px;
	}

	.menu-bingo > :not(.menu-bingo-prize) {
		grid-column: 1;
	}

	.menu-bingo-prize {
		grid-column: 2;
		grid-row: 1 / 6;
		align-self: stretch;
		justify-content: center;
		margin: 0;
		padding-left: 24px;
		border-left: 2px dashed color-mix(in srgb, var(--ink) 20%, transparent);
		text-align: center;
	}

	.result-box {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		grid-template-rows: auto auto auto auto;
		gap: 6px 24px;
		width: min(960px, 100%);
		padding: 16px 20px;
	}

	.result-box h1 {
		grid-column: 1;
		grid-row: 1;
		font-size: 24px;
	}

	.result-time {
		grid-column: 1;
		grid-row: 2;
		font-size: 48px;
		margin: 0;
	}

	.result-medal {
		grid-column: 1;
		grid-row: 3;
	}

	.result-medal.stamp {
		font-size: min(22px, 3vw);
		margin: 10px auto 16px;
	}

	.result-detail {
		grid-column: 1;
		grid-row: 4;
		margin: 0;
	}

	.result-board {
		grid-column: 2;
		grid-row: 1 / 4;
		align-self: center;
		max-height: calc(100dvh - 140px);
		margin: 0;
	}

	.result-box > .buttons {
		grid-column: 2;
		grid-row: 4;
		margin: 0;
		align-self: center;
	}

	.reveal-stage {
		width: min(960px, calc(100vw - 24px));
		gap: 8px;
		padding: 0;
	}

	.reveal-word {
		font-size: min(52px, 7vw, 12dvh);
	}

	.reveal-sheet {
		display: grid;
		grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
		gap: 6px 18px;
		padding: 14px 18px;
	}

	.reveal-picture {
		grid-column: 1;
		grid-row: 1 / 6;
		height: min(220px, 50dvh);
		min-height: 0;
	}

	.reveal-picture > * {
		max-width: 100%;
		max-height: 100%;
	}

	.reveal-sheet > :not(.reveal-picture) {
		grid-column: 2;
	}

	.reveal-name {
		font-size: 28px;
	}

	.reveal-sheet .buttons {
		margin: 4px 0 0;
	}

	.reveal-sheet button.primary.big {
		font-size: 18px;
		padding: 10px 18px;
	}
}

/* A continuous ink outline includes the lightning tail. */
.guide-radio { position:fixed; inset:0; padding:0; overflow:hidden; pointer-events:none; z-index:30; background:transparent; }
.guide-radio.over-reveal { z-index:45; }
.guide-radio.over-dialog { z-index:35; }
.guide-radio::before { pointer-events:auto; content:""; position:absolute; inset:0; background:#140c049c; animation:radio-dim .5s both; }
.guide-stage { --radio-size:clamp(180px,18vw,250px); position:absolute; inset:32px; width:min(var(--menu-width),calc(100% - 64px)); margin-inline:auto; pointer-events:none; }
.guide-device { position:absolute; bottom:0; left:0; width:var(--radio-size); aspect-ratio:520/509; transform-origin:50% 80%; animation:radio-enter .7s cubic-bezier(.2,.8,.25,1) both; }
.guide-particles { z-index:1; }
.guide-picture { display:block; width:100%; filter:drop-shadow(5px 7px 0 #1a171680); animation:radio-float 3s .7s ease-in-out infinite, radio-talk 2.1s 1s ease-in-out infinite; transform-origin:50% 80%; }
.guide-sparks { position:absolute; left:68%; top:67%; z-index:2; width:0; height:0; }
.guide-sparks svg { position:absolute; width:clamp(34px,3.5vw,49px); height:clamp(34px,3.5vw,49px); overflow:visible; fill:var(--orange-light); stroke:var(--ink); stroke-width:1; stroke-linejoin:round; filter:drop-shadow(3px 4px 0 var(--ink)); animation:radio-spark 2.5s calc(var(--spark)*-.625s) ease-out infinite; }
.guide-paper { position:absolute; left:calc(var(--radio-size)*.48); bottom:calc(var(--radio-size)*.85); width:min(545px,calc(100% - var(--radio-size)*.48)); isolation:isolate; pointer-events:auto; filter:drop-shadow(5px 7px 0 #170f0b65); transform-origin:18% 110%; animation:radio-paper .55s .32s both; }
.guide-paper::before { content:""; position:absolute; inset:-20px; z-index:-2; background:radial-gradient(circle,var(--ink) 1.8px,transparent 2.2px) 0 0/12px 12px; mask-image:radial-gradient(ellipse,#000 50%,transparent 72%); opacity:.45; pointer-events:none; }
.guide-outline { position:absolute; inset:0; width:100%; height:calc(100% + 76px); z-index:-1; overflow:visible; }
.guide-paper::before,.guide-outline { transform-origin:18% 100%; animation:radio-bubble-float 6s 1s ease-in-out infinite; }
.guide-outline path { fill:var(--white); stroke:var(--ink); stroke-width:5px; stroke-linejoin:miter; }
.guide-bubble { position:relative; display:flex; flex-direction:column; height:320px; max-height:calc(100dvh - 64px - var(--radio-size)*.85); padding:30px 36px 25px; color:var(--ink); }
.guide-header { --radio-ink:#7d3445; --radio-bright:#ffc09a; flex-shrink:0; display:flex; align-items:center; gap:10px; color:var(--radio-ink); }
.guide-callsign { font:18px var(--display); letter-spacing:1px; }
.guide-live { margin-left:auto; font-size:9px; font-weight:900; letter-spacing:1.5px; }
.guide-live::before { content:""; display:inline-block; width:6px; height:6px; margin-right:6px; border-radius:50%; background:var(--orange-deep); }
.guide-equalizer { display:flex; align-items:center; gap:3px; height:16px; }
.guide-equalizer i { width:3px; height:14px; background:currentColor; animation:radio-meter .65s calc(var(--bar)*-.13s) ease-in-out infinite alternate; }
.guide-copy { flex:1; min-height:0; overflow:auto; padding:16px 0 8px; }
.guide-title { font-size:25px; line-height:1.1; letter-spacing:.01em; }
.guide-bubble .guide-message { font-size:16px; line-height:1.5; margin:10px 0 0; font-weight:700; white-space:pre-line; }
.guide-word { display:inline-block; animation:radio-word .25s calc(var(--speech-delay,0ms) + var(--beat)*28ms) both; }
.guide-bolts { color:var(--orange); font-weight:900; -webkit-text-stroke:1.5px var(--dark); paint-order:stroke fill; text-shadow:2px 2px 0 var(--ink); }
.guide-bolts>span { animation:radio-letter-hop 3.6s calc(var(--speech-delay,0ms) + var(--beat)*28ms + .7s + var(--letter)*.18s) ease-in-out infinite; }
.guide-controls { flex-shrink:0; display:grid; grid-template-columns:44px 1fr auto; align-items:center; gap:12px; height:58px; }
.guide-dots { display:flex; align-items:center; justify-content:center; gap:7px; }
.guide-radio .guide-dots:has(>i:only-child) { visibility:hidden; }
.guide-dots i { display:block; width:6px; height:6px; border-radius:50%; background:color-mix(in srgb,var(--ink) 20%,var(--white)); }
.guide-dots .read { background:var(--ink-soft); }
.guide-dots .current { width:18px; border-radius:6px; background:var(--accent-ink); }
.guide-advance { display:flex; align-items:center; justify-content:flex-end; gap:6px; min-width:160px; }
.guide-destination { max-width:110px; font:14px/1.1 var(--display); text-align:right; }
button.guide-nav { padding:0; width:48px; height:48px; border:0; background:none; box-shadow:none; --face:transparent; --edge:0px; --shade:transparent; --lift:0px; }
button.guide-nav::before,button.guide-nav::after { display:none; }
.guide-nav svg { display:block; flex:0 0 48px; width:48px; height:48px; fill:var(--orange); stroke:var(--ink); stroke-width:2px; filter:drop-shadow(2px 3px 0 #2a1b1355); }
button.guide-forward { display:flex; align-items:center; gap:6px; width:auto; min-width:48px; }
.guide-word .icon-resource { width:1.1em; height:1.1em; vertical-align:-.15em; }
.guide-word>.icon-bolts { transform-origin:50% 50%; animation:radio-bolt-jiggle 3.6s calc(var(--speech-delay,0ms) + (var(--beat) + 1)*28ms + .7s) ease-in-out infinite; }
.guide-back svg { fill:var(--paper); }
.guide-back:disabled { visibility:hidden; }
.guide-forward svg { animation:radio-nudge 1.4s ease-in-out infinite; }
.guide-error { position:absolute; bottom:3px; left:36px; right:36px; margin:0; font-size:11px; }
.guide-error:empty { display:none; }
.guide-radio.exiting .guide-device { animation:radio-exit .46s both; }
.guide-radio.exiting .guide-paper { animation:radio-paper-out .28s both; }
.guide-radio.exiting::before { animation:radio-dim .4s reverse both; }
@keyframes radio-talk { 0%,14%,30%,46%,100% { scale:1; } 7% { scale:1.018; } 22% { scale:1.026; } 38% { scale:1.016; } }
@keyframes radio-letter-hop { 0%,5%,100% { translate:0 0; color:var(--orange); } 2.5% { translate:0 -3px; color:var(--orange-light); } }
@keyframes radio-bolt-jiggle { 0%,25%,100% { rotate:0deg; } 4% { rotate:-8deg; } 10% { rotate:8deg; } 16% { rotate:-5deg; } 22% { rotate:3deg; } }
@keyframes radio-enter { 0% { transform:translateX(-150%) rotate(-18deg); } 68% { transform:translateX(15px) rotate(5deg); } 86% { transform:translateX(-5px) rotate(-2deg); } 100% { transform:none; } }
@keyframes radio-exit {
 0% { transform:none; opacity:1; }
 22% { transform:translateX(20px) rotate(6deg); }
 40% { opacity:1; }
 100% { transform:translateX(-260%) rotate(-20deg); opacity:0; }
}
@keyframes radio-paper { 0% { opacity:0; transform:scale(.08) rotate(12deg); } 70% { opacity:1; transform:scale(1.035) rotate(-1deg); } 100% { transform:none; } }
@keyframes radio-paper-out { to { opacity:0; transform:scale(.1) rotate(12deg); } }
@keyframes radio-dim { from { opacity:0; } to { opacity:1; } }
@keyframes radio-word { from { opacity:0; transform:translateY(5px) rotate(-5deg) scale(.85); } to { opacity:1; transform:none; } }
@keyframes radio-nudge { 0%,45%,100% { transform:translateX(0); } 60%,80% { transform:translateX(-6px); } 70%,90% { transform:translateX(-2px); } }
@keyframes radio-float { 0%,100% { transform:translateY(0) rotate(-1deg); } 50% { transform:translateY(-4px) rotate(1deg); } }
@keyframes radio-bubble-float { 0%,100% { transform:translate(0,0) rotate(-.2deg); } 35% { transform:translate(2px,-3px) rotate(.2deg); } 70% { transform:translate(-2px,-1px) rotate(-.15deg); } }
@keyframes radio-meter { 0% { transform:scaleY(.25); color:var(--radio-ink); } 60% { color:var(--radio-ink); } 100% { transform:scaleY(1); color:var(--radio-bright); } }
@keyframes radio-spark { 0% { opacity:0; transform:translate(-50%,-50%) scale(.5); } 12% { opacity:1; } 80%,100% { opacity:0; transform:translate(calc(65px + var(--spark)*15px),calc(-75px - var(--spark)*18px)) scale(1.15) rotate(12deg); } }
@media(max-width:700px) {
 .guide-stage { --radio-size:145px; inset:18px; width:calc(100% - 36px); }
 .guide-paper { left:0; width:100%; bottom:calc(var(--radio-size)*.9); }
 .guide-bubble { height:330px; max-height:calc(100dvh - 36px - var(--radio-size)*.9); padding:28px 25px 24px; }
 .guide-title { font-size:22px; }
 .guide-bubble .guide-message { font-size:15px; }
 .guide-advance { min-width:132px; }
 .guide-destination { max-width:84px; font-size:13px; }
 .guide-controls { gap:4px; }
}
@media(max-height:600px) and (max-width:600px) {
 .guide-stage { --radio-size:105px; }
 .guide-bubble { padding:25px 24px 22px; }
 .guide-title { font-size:20px; }
 .guide-copy { padding:12px 0 4px; }
 .guide-bubble .guide-message { font-size:14px; line-height:1.4; margin-top:8px; }
}
@media(max-height:540px) and (min-width:601px) {
 .guide-stage { --radio-size:130px; inset:20px 32px; }
 .guide-paper { left:145px; bottom:65px; width:min(545px,calc(100% - 145px)); }
 .guide-bubble { height:300px; max-height:calc(100dvh - 105px); padding:24px 28px 22px; }
 .guide-copy { padding:8px 0; }
 .guide-title { font-size:21px; }
 .guide-bubble .guide-message { font-size:14px; line-height:1.4; }
}
@media(prefers-reduced-motion:reduce) {
 .events h1.marquee span,.menu-events-card.join-open .marquee>span,.menu-events-card.join-open .menu-cup { animation:none; }
 .guide-radio::before,.guide-device,.guide-picture,.guide-paper,.guide-paper::before,.guide-outline,.guide-equalizer i,.guide-word,.guide-bolts>span,.guide-word>.icon-bolts,.guide-forward svg { animation:none!important; }
 .guide-sparks { display:none; }
}
.nookling-picture { width:100%; max-width:360px; display:block; margin:auto; pointer-events:none; }
.nookling-picture.large { position:absolute; z-index:2; width:62%; max-width:none; left:19%; bottom:5%; margin:0; }
.nook-furniture { position:absolute; z-index:1; transform:translate(-50%,-50%); width:20%; height:24%; padding:0; border:0; background:transparent; --face:transparent; --edge:0px; --shade:transparent; box-shadow:none; touch-action:none; cursor:grab; }

.furniture-shape { display:block; width:100%; height:65%; border-radius:12px; background:#d7909e; border:4px solid #a26379; box-shadow:inset 0 8px #ffccd6,6px 9px #5e496322; }
.furniture-chair .furniture-shape { width:70%; margin:auto; background:#dbb785; border-color:#a88264; box-shadow:inset 0 12px #edcaa0,0 12px 0 -5px #95694a; }
.furniture-sofa { width:30%; }.furniture-sofa .furniture-shape { border-width:12px 10px 6px; background:#8caebb; border-color:#5f879b; box-shadow:inset 0 5px #d7ebec,2px 9px #65517222; }
.furniture-plant .furniture-shape { width:35px;height:40px;margin:auto;background:#70a479;border-color:#56875d;border-radius:80% 10% 80% 10%;box-shadow:8px 25px 0 -5px #c58866; transform:rotate(-30deg); }
.furniture-rug { width:100px;height:40px;z-index:1; }.furniture-rug .furniture-shape { background:#dac37d;border:6px double #a78e4e;border-radius:50%;box-shadow:none;height:100%; }
.furniture-ball .furniture-shape { width:45px;height:45px;margin:auto;border-radius:50%;background:linear-gradient(40deg,#f0b467 50%,#a7ceba 50%);border:3px solid #bf8d69;box-shadow:inset 3px 4px #fff5; }
.journey-tools { max-height:90vh;overflow:auto;width:min(850px,95vw);max-width:850px; }.journey-tools button { margin:5px; }
@media(prefers-reduced-motion:reduce) { .nook .sticker-icon,.contract-paper { animation:none; } }

.nook-mark { display:block;width:30px;height:35px;border-radius:55% 55% 45% 45%;background:radial-gradient(circle at 32% 43%,var(--ink) 0 4px,transparent 5px),radial-gradient(circle at 64% 68%,var(--ink) 0 5px,transparent 6px),var(--white);border:2px solid var(--ink);transform:rotate(-10deg); }

.journey-input { border:2px solid #a79282;border-radius:8px;padding:7px 9px;background:#fffaf0;min-width:0; }
.journey-celebration { width:min(540px,93vw);text-align:center;max-height:92vh;overflow:auto; }.journey-celebration>.nookling-picture { width:240px; }.journey-celebration p { line-height:1.5; }

.incubator-light { position:absolute;z-index:1;left:20%;top:40px;width:60%;height:80%;background:linear-gradient(#ffe29ab0,#fff0b110);clip-path:polygon(40% 0,60% 0,100% 100%,0 100%);transition:opacity .5s; }

/* Contracts use the game's paper surface and the Workshop stock beam. */
.construction-place { isolation:isolate; justify-content:flex-start; padding:20px 32px 90px; gap:20px; overflow-x:hidden; overflow-y:auto; scroll-padding:16px 0 90px; }
.construction-place::before { content:""; position:absolute; inset:0 0 auto; height:92px; z-index:-1; background:repeating-linear-gradient(90deg,#3a2a20 0 14px,#2b1d14 14px 28px); border-bottom:7px solid var(--ink); box-shadow:0 7px 0 #1e130d66; }
.construction-sign { flex-shrink:0; width:min(var(--menu-width),100%); height:58px; gap:18px; }
.construction-sign h1 { font-size:32px; white-space:nowrap; }
.construction-sign .workshop-stock { flex:1; justify-content:center; gap:8px; }
.construction-body { width:min(960px,100%); flex:none; margin:16px auto 0; }
.contract-board { display:grid; position:relative; grid-template-columns:220px minmax(0,1fr); align-items:start; gap:24px; }
.contract-list { display:flex; flex-direction:column; gap:20px; padding:5px; }
.contract-stack { display:grid; align-content:start; gap:9px; }
.contract-stack h2 { color:var(--paper); text-shadow:var(--outline); font-size:21px; margin:0; }
.contract-choices { display:grid; gap:10px; }
button.contract-choice { display:grid; grid-template-columns:24px minmax(0,1fr); align-items:center; gap:8px; padding:12px; text-align:left; --face:var(--paper-bright); --lift:4px; }
.contract-choice.active { outline:3px solid var(--orange); outline-offset:3px; }
.contract-choice strong { font:900 14px/1.25 var(--font); text-transform:none; letter-spacing:0; }
.contract-mini-seal { display:grid; place-items:center; border:3px double var(--ink-soft); border-radius:50%; width:24px; height:24px; color:var(--ink-soft); font:15px var(--display); }
.contract-mini-lines { grid-column:2; display:flex; gap:5px; }
.contract-mini-lines i { display:block; width:18px; height:3px; border-radius:3px; background:#ac936c70; }
.contract-mini-lines i.done { background:#517343; }
.contract-empty { margin:0; color:var(--paper); text-shadow:1px 2px 0 var(--ink); font-size:13px; }
.contract-empty-slot { display:grid; place-items:center; height:48px; border:2px dashed #fff3cf77; border-radius:12px; color:#fff3cfaa; font-size:24px; }
.contract-paper { grid-column:2; grid-row:1; position:relative; min-width:0; min-height:0; --face:var(--paper-bright); --lift:6px; display:flex; flex-direction:column; }
.contract-document { padding:22px 26px 8px; }
.contract-heading { display:flex; align-items:center; gap:12px; padding-bottom:12px; border-bottom:3px double var(--ink-soft); }
.contract-heading .contract-mini-seal { width:38px; height:38px; flex-shrink:0; font-size:24px; }
.contract-letterhead { font:16px/1.1 var(--display); letter-spacing:.04em; text-transform:uppercase; white-space:pre-line; color:var(--ink-soft); }
.contract-paper h3 { font:28px/1.1 var(--display); margin:10px 0; }
.contract-brief { font:700 14px/1.4 var(--font); white-space:pre-line; margin:0 0 12px; }
.contract-terms { font:700 13px/1.4 var(--font); margin:0 0 14px; color:var(--ink-soft); }
.contract-deadline { color:var(--ink); border-bottom:2px solid #75614455; white-space:nowrap; }
.contract-deliveries { display:grid; }
.contract-resource { display:grid; grid-template-columns:28px 72px minmax(0,1fr); align-items:center; gap:10px; min-height:48px; border-bottom:1px solid #70573533; }
.contract-resource>.icon-resource { width:28px; height:28px; }
.contract-quantity { font:900 16px/1.2 var(--font); }
.contract-quantity.revealing { mask-image:linear-gradient(to right,#000 40%,transparent 60%); mask-size:250% 100%; mask-position:100% 0; mask-repeat:no-repeat; }
.contract-quantity small { display:block; font-size:11px; font-weight:700; color:var(--ink-soft); }
.contract-packed { grid-column:3; justify-self:end; color:#426036; font-size:24px; }
.contract-resource.delivered { opacity:.55; }
.delivery-slider { position:relative; display:block; min-width:0; height:44px; }
.delivery-slider input { appearance:none; display:block; width:100%; height:44px; margin:0; padding:0; border:0; border-radius:0; background:transparent; box-shadow:none; cursor:ew-resize; touch-action:pan-y; }
.delivery-slider input::-webkit-slider-runnable-track { height:12px; border:2px solid var(--ink); border-radius:999px; background:linear-gradient(90deg,var(--orange-light) var(--fill),#d5c7a4 var(--fill)); }
.delivery-slider input::-moz-range-track { height:8px; border:2px solid var(--ink); border-radius:999px; background:linear-gradient(90deg,var(--orange-light) var(--fill),#d5c7a4 var(--fill)); }
.delivery-slider input::-webkit-slider-thumb { appearance:none; width:44px; height:34px; margin-top:-13px; background:var(--paper); border:2px solid var(--ink); border-radius:12px; box-shadow:3px 4px 0 var(--shadow-ink); }
.delivery-slider input::-moz-range-thumb { box-sizing:border-box; width:44px; height:34px; background:var(--paper); border:2px solid var(--ink); border-radius:12px; box-shadow:3px 4px 0 var(--shadow-ink); }
.delivery-slider output { pointer-events:none; position:absolute; top:0; left:calc(var(--fill) + var(--thumb-offset)); transform:translateX(-50%); display:flex; align-items:center; justify-content:center; height:44px; width:44px; font:900 12px var(--font); font-variant-numeric:tabular-nums; }
.delivery-slider:has(input:disabled) { opacity:.55; }
.contract-footer { flex-shrink:0; margin:8px 26px 14px; padding-top:10px; border-top:3px double var(--ink-soft); display:flex; align-items:center; justify-content:space-between; gap:16px; }
.contract-prize { cursor:help; display:flex; align-items:center; gap:12px; }
.contract-prize .journey-mystery { width:96px; height:90px; filter:drop-shadow(3px 4px 0 var(--shadow-ink)); }
.contract-prize strong { font:20px var(--display); color:#517e99; }
.contract-signature { flex:0 1 240px; min-width:0; max-width:60%; display:flex; flex-direction:column; align-items:stretch; text-align:center; gap:5px; }
.contract-signature>small { font:800 11px var(--font); text-transform:uppercase; letter-spacing:.06em; color:var(--ink-soft); }
.contract-signature>strong { display:block; font:600 36px/1.2 "Caveat",var(--font); color:#2a5269; rotate:-2deg; border-bottom:1px solid #58738b77; padding:0 8px 5px; overflow-wrap:anywhere; }
.contract-witness { position:relative; font:600 17px/1.1 "Caveat",var(--font); color:#705039; white-space:pre-line; }
.contract-approval { position:absolute; left:50%; bottom:0; transform:translateX(-50%); display:block; line-height:0; pointer-events:none; animation:shop-thanks 2s both; }
.contract-sign-button { font-size:17px; padding:8px 14px; min-height:40px; }
.contract-tear { position:absolute!important; right:12px; top:14px; opacity:0; transition:opacity .15s; }
.contract-paper:hover .contract-tear,.contract-paper:focus-within .contract-tear { opacity:1; }
.contract-complete-stamp { position:absolute; inset:40% auto auto 25%; font:32px var(--display); color:#4c773f; border:5px double currentColor; border-radius:12px; padding:12px; rotate:-8deg; background:#fff5dfcc; z-index:4; }
.contract-rip-half { pointer-events:none; }
.contract-rip-half.left-half { clip-path:polygon(0 0,52% 0,48% 20%,53% 40%,47% 60%,52% 80%,49% 100%,0 100%); }
.contract-rip-half.right-half { clip-path:polygon(52% 0,100% 0,100% 100%,49% 100%,52% 80%,47% 60%,53% 40%,48% 20%); }
.construction-body>.error { position:absolute; bottom:85px; left:20%; background:var(--paper); }
.construction-body>.error:empty { display:none; }
.construction-stages { display:flex; list-style:none; padding:0; margin:8px 0 10px; gap:0; }
.construction-stages li { position:relative; flex:1; text-align:center; font:800 12px var(--font); color:var(--ink-soft); cursor:help; }
.construction-stages li:not(:last-child)::before { content:""; position:absolute; top:7px; left:50%; width:100%; height:3px; background:#c1b293; }
.construction-stages i { position:relative; display:block; width:17px; height:17px; margin:0 auto 5px; border:3px solid var(--ink-soft); border-radius:50%; background:var(--paper); }
.construction-stages .current i { background:var(--orange); border-color:var(--ink); }
.construction-stages .done i,.construction-stages .done::before { background:#728658; }
.construction-stages .done i::after { content:""; position:absolute; width:7px; height:4px; top:2px; left:2px; border-left:2px solid var(--paper); border-bottom:2px solid var(--paper); transform:rotate(-45deg); }
.construction-stage-title { margin:10px 0 4px; font:19px var(--display); }
.construction-work-action { display:block; margin:14px auto 4px; min-height:44px; font-size:17px; }
.construction-site-frame { position:relative; height:180px; margin-top:8px; overflow:hidden; border-radius:14px; outline:2px solid var(--ink); outline-offset:-2px; }
.construction-countdown { margin:8px 0 0; text-align:center; font:800 13px var(--font); color:var(--ink-soft); font-variant-numeric:tabular-nums; }
.construction-plan-dialog { width:min(800px,calc(100vw - 24px)); height:min(570px,calc(100dvh - 24px)); display:flex; flex-direction:column; gap:16px; padding:24px; }
.construction-plan-dialog>h2 { margin:0 44px 0 0; font-size:28px; }
.construction-plan-stages { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:14px; min-height:0; overflow:auto; padding:5px 5px 9px; }
.construction-plan-stage { min-width:0; margin:0; padding:14px; border:2px dashed #806d4d66; border-radius:14px; }
.construction-plan-stage legend { padding:0 6px; font:21px var(--display); }
.construction-methods { display:grid; gap:8px; }
button.construction-method { min-height:44px; padding:6px 8px; font:900 14px/1.2 var(--font); text-transform:none; letter-spacing:0; --face:var(--paper-bright); --lift:3px; }
button.construction-method.active { --face:var(--orange-light); }
.construction-plan-details { display:grid; margin:14px 0 0; font:800 12px/1.6 var(--font); }
.construction-plan-bill { margin-top:auto; padding-top:12px; border-top:3px double var(--ink-soft); }
.construction-plan-bill>small { display:block; font:800 12px var(--font); margin-bottom:7px; }
.construction-plan-total { display:flex; flex-wrap:wrap; gap:6px; }
.construction-plan-timing { margin:8px 0 0; font-size:12px; color:var(--ink-soft); }
.construction-plan-dialog>.primary { align-self:flex-end; min-height:44px; }
@media(pointer:coarse) { .contract-tear { opacity:.55; } }
@media(max-width:1000px) { .construction-sign .workshop-stock { gap:4px; }.construction-sign h1 { font-size:25px; } }
@media(max-width:700px) {
 .construction-place { padding:10px 12px 78px; gap:12px; }
 .construction-place::before { height:102px; }
 .construction-sign { flex-wrap:wrap; height:88px; align-content:start; gap:8px; }
 .construction-sign h1 { flex:1; }
 .construction-sign .workshop-stock { order:3; flex-basis:100%; justify-content:flex-start; }
 .construction-sign .stock-chip { font-size:10px; padding:2px 5px; gap:2px; }
 .construction-sign .stock-chip .icon-resource { width:15px; height:15px; }
 .construction-body { margin:0; }
 .contract-board { grid-template-columns:minmax(0,1fr); grid-template-rows:auto auto; gap:12px; }
 .contract-list { gap:10px; padding:3px; overflow:visible; }
 .contract-stack { grid-template-columns:68px minmax(0,1fr); gap:8px; align-items:center; min-height:48px; }
 .contract-stack h2 { font-size:13px; }
 .contract-choices { grid-template-columns:repeat(var(--contracts),minmax(0,1fr)); gap:7px; }
 button.contract-choice { display:flex; padding:6px; height:48px; }
 .contract-choice strong { display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; font-size:11px; }
 .contract-choice .contract-mini-seal,.contract-mini-lines { display:none; }
 .contract-empty { font-size:11px; }
 .contract-paper { grid-column:1; grid-row:2; }
 .contract-document { padding:14px 16px 4px; }
 .contract-heading { gap:8px; padding-bottom:8px; }
 .contract-heading .contract-mini-seal { width:28px; height:28px; font-size:18px; }
 .contract-letterhead { font-size:12px; }
 .contract-paper h3 { font-size:22px; margin:10px 0; }
 .contract-brief { font-size:12px; line-height:1.35; margin-bottom:8px; }
 .contract-terms { font-size:11px; margin-bottom:8px; }
 .contract-resource { grid-template-columns:24px 50px minmax(0,1fr); gap:6px; min-height:48px; }
 .contract-resource>.icon-resource { width:24px; height:24px; }
 .contract-quantity { font-size:13px; }
 .contract-quantity small { font-size:10px; }
 .contract-paper.offer .contract-resource { min-height:35px; }
 .contract-footer { margin:8px 16px 14px; padding-top:10px; gap:12px; }
 .contract-prize .journey-mystery { width:56px; height:56px; }
 .contract-prize { gap:5px; }
 .contract-prize strong { font-size:14px; }
 .contract-signature>strong { font-size:29px; }
 .contract-witness { font-size:15px; }
 .contract-sign-button { font-size:15px; }
 .contract-paper.active .contract-document { padding-top:10px; }
 .contract-paper.active .contract-heading { padding-bottom:5px; gap:6px; }
 .contract-paper.active .contract-heading .contract-mini-seal { width:22px; height:22px; font-size:14px; }
 .contract-paper.active .contract-letterhead { font-size:10px; }
 .contract-paper.active h3 { margin:6px 0; }
 .contract-paper.active .contract-terms { margin-bottom:6px; }
 .contract-paper.active .contract-resource { min-height:44px; }
 .contract-paper.active .contract-footer { margin-top:6px; margin-bottom:10px; padding-top:7px; }
 .construction-stages { margin:6px 0; }
 .construction-stages li { font-size:10px; }
 .construction-stage-title { font-size:17px; margin-top:6px; }
 .construction-work-action { margin:8px auto 2px; font-size:15px; }
 .construction-site-frame { height:140px; }
 .construction-plan-dialog { height:min(650px,calc(100dvh - 24px)); padding:18px 14px; gap:10px; }
 .construction-plan-dialog>h2 { font-size:24px; }
 .construction-plan-stages { grid-template-columns:1fr; gap:12px; }
 .construction-plan-stage { padding:8px; }
 .construction-plan-stage legend { font-size:18px; }
 .construction-methods { grid-template-columns:repeat(3,minmax(0,1fr)); gap:6px; }
 button.construction-method { font-size:11px; padding:5px 3px; }
 .construction-plan-details { display:flex; justify-content:space-between; gap:6px; font-size:10px; margin-top:10px; white-space:normal; }
 .construction-plan-total .resource-chip { padding:3px 6px; font-size:12px; }
 .construction-plan-total .icon-resource { width:18px; height:18px; }

}

.nook-furniture:hover:not(:disabled),.nook-furniture:active:not(:disabled) { transform:translate(-50%,-50%);--lift:0px; }

.nook-area-empty { text-align:center; padding:20px; }
.incubator-device .incubator-light { top:0;left:10%;width:80%;height:100%; }
.bulb-drawing { position:relative; display:block; width:58px;height:67px;border:4px solid #aa8754;border-radius:48% 48% 38% 38%;background:radial-gradient(circle at 34% 25%,#fff 0 8%,#fffbd9 10%,#f8d67b 64%,#deb252);box-shadow:inset -5px -3px #cba05044,2px 4px 3px #46332635; }
.bulb-drawing::before { content:"";position:absolute;left:15px;right:15px;top:27px;height:26px;border:3px solid #b8893f;border-bottom:0;border-radius:8px 8px 0 0; }
.bulb-drawing::after { content:"";position:absolute;top:59px;left:12px;right:12px;height:22px;border:3px solid #7b7770;border-radius:0 0 9px 9px;background:repeating-linear-gradient(0deg,#b8b8a7 0 4px,#777d78 5px 7px); }
.bulb-drawing.fitted { box-shadow:0 0 22px #fcd76990; }.bulb-drawing.empty-socket { filter:grayscale(1);opacity:.25; }
.water-bottle { position:relative;display:block;width:48px;height:72px;border:4px solid #749997;border-radius:9px 9px 14px 14px;background:linear-gradient(transparent 30%,#9acbc7 31%,#79b6b7);box-shadow:inset 8px 0 #ffffff55; }
.water-bottle::before { content:"";position:absolute;left:9px;right:9px;height:11px;top:-13px;background:#6c937e;border:3px solid #517962;border-radius:3px; }
.power-cell { display:block;width:82px;height:52px;background:repeating-linear-gradient(90deg,#ccb063 0 14px,#e9cf83 15px 28px);border:5px solid #806845;border-radius:10px;box-shadow:5px 5px #58462c44; }
.dialog.hatchery-task { width:min(460px,calc(100vw - 24px)); height:min(440px,calc(100dvh - 24px)); padding:18px; gap:12px; rotate:0deg; text-align:center; }
.hatchery-task>h2 { flex:none; min-height:44px; padding:4px 48px 0 0; font-size:clamp(22px,5vw,28px); text-align:left; }
.hatchery-task-copy { flex:none; min-height:3.9em; margin:0; font:clamp(17px,4vw,20px)/1.3 var(--display); text-wrap:balance; }
.hatchery-task > progress { flex:none; width:100%; height:12px; accent-color:#6c9a63; }
.hatchery-task .hatchery-hands { position:relative; display:flex; align-items:center; justify-content:center; flex:1; min-height:110px; width:100%; padding:12px; margin:0; touch-action:none; background:#e3d7b7; border:0; border-radius:16px; box-shadow:none; --lift:0px; }
.hatchery-hands::before,.hatchery-hands::after { display:none; }
.hatchery-hands:hover:not(:disabled),.hatchery-hands:active:not(:disabled) { transform:none; --lift:0px; }
.hatchery-hands:focus:not(:focus-visible) { outline:none; }
.hatchery-hands>span { flex:none; }
.hatchery-hands .bulb-drawing { transform:translateY(calc(var(--turn,0)*.025px)) rotate(calc(var(--turn,0)*1deg));transition:transform .18s; }
.hatchery-hands .water-bottle { transform:rotate(calc(var(--turn,0)*.2deg));transition:transform .18s; }
.hatchery-hands .power-cell { transform:translateX(calc(var(--turn,0)*.1px));transition:transform .18s; }
@media(prefers-reduced-motion:reduce) { .hatchery-hands .bulb-drawing,.hatchery-hands .water-bottle,.hatchery-hands .power-cell { transition:none; } }



.journey-eyebrow { display:block; font-size:11px; letter-spacing:1.8px; text-transform:uppercase; line-height:1.5; }
.journey-toolbar { display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:12px; }
.journey-toolbar p { flex:1; margin:0; }
.journey-badge { display:inline-flex; align-self:flex-start; padding:6px 10px; background:#e3edcf; color:#405b32; border:1px solid #83946766; border-radius:6px; font-size:12px; }
.journey-intro { margin:12px 0 20px; color:var(--ink-soft); line-height:1.5; }
.journey-empty { padding:48px 24px; text-align:center; color:var(--ink); background:var(--paper); border-radius:var(--radius); grid-column:1 / -1; }
.journey-empty h3 { font-size:28px; }
.journey-empty p { color:var(--ink-soft); }
.journey-feedback { margin:0; color:#41662e; font-size:14px; }
.journey-mystery { display:block; flex-shrink:0; width:76px; height:70px; object-fit:contain; rotate:-8deg; filter:drop-shadow(2px 4px 2px #2b1d1222); }
.journey-meter { display:flex; flex-direction:column; gap:6px; font-size:13px; min-width:0; }
.journey-meter-label { display:flex; justify-content:space-between; gap:8px; }
.journey-meter progress { appearance:none; width:100%; height:9px; border:0; border-radius:9px; overflow:hidden; background:#d9ccb4; }
.journey-meter progress::-webkit-progress-bar { background:#d9ccb4; }
.journey-meter progress::-webkit-progress-value { background:#759657; border-radius:9px; transition:width .3s; }
.journey-meter progress::-moz-progress-bar { background:#759657; border-radius:9px; }
.journey-meter.low progress::-webkit-progress-value { background:#ce8354; }
.journey-meter.low progress::-moz-progress-bar { background:#ce8354; }
.journey-close { position:absolute; right:18px; top:14px; width:42px; height:42px; padding:0; font-size:28px; z-index:2; }

@keyframes nook-drop { from { translate:0 -40px; scale:.6; } 75% { translate:0 2px; scale:1.1 .8; } to { translate:0 0; scale:1; } }
@keyframes nook-sweep { to { translate:90px -5px; rotate:35deg; opacity:0; } }
.nook-product-picture { pointer-events:none; position:relative; flex-shrink:0; display:block; width:42px; height:48px; margin:0; }
.nook-product-picture>span { position:absolute; left:50%; top:50%; transform:translate(-50%,-50%) scale(.5); }
.nook-product-picture>.nook-furniture { width:70px; height:70px; }
.incubator-slot .nook-product-picture { scale:.7; margin:-8px; }
.nook-hatch-name form, .nook-hatch-name label { display:flex; flex-direction:column; gap:12px; }
@media(max-width:620px) {
	.nook-product-picture { scale:.8; transform-origin:center; }
}

/* Fixed care screens, with the same paper cross and resource pills as the game. */
.symbol-button,.nook-top-actions>.bingo-close,.panel-symbols>.bingo-close { display:grid; place-items:center; flex:none; width:38px; height:38px; padding:0; border-radius:50%; --lift:3px; }
.symbol-button svg,.nook-top-actions>.bingo-close svg,.panel-symbols>.bingo-close svg { display:block; width:24px; height:24px; fill:none; stroke:var(--ink); stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.panel-symbols,.nook-top-actions { position:absolute; z-index:10; top:18px; right:18px; display:flex; align-items:center; gap:10px; }
.panel-close { position:absolute!important; top:18px; right:18px; z-index:10; }
.dialog.nook-dialog { width:min(840px,calc(100vw - 24px)); max-width:840px; height:min(680px,calc(100dvh - 24px)); padding:24px; rotate:0deg; --face:var(--paper-bright); display:flex; flex-direction:column; overflow:hidden; gap:12px; }
.nook-dialog>h2 { font-size:27px; text-align:left; padding-right:140px; margin:0; min-height:38px; flex-shrink:0; }
.nook-dialog:has(.nook-memorial-button:not([hidden]))>h2 { padding-right:208px; }
.nook-memorial-button[hidden] { display:none; }
.nook-body { flex:1; min-height:0; overflow:auto; padding:5px; display:flex; flex-direction:column; }
.nook-residents { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px; margin-bottom:12px; flex-shrink:0; }
.nook-resident-slot { display:flex; align-items:center; justify-content:center; gap:10px; padding:2px 8px; height:50px; min-width:0; --face:var(--paper); --lift:3px; }
.nook-resident-slot .nookling-picture { flex:none; width:44px; height:auto; margin:0; }
.nook-resident-slot strong { font-size:13px; overflow:hidden; text-overflow:ellipsis; }
.nook-resident-slot.active { outline:2px solid var(--orange); outline-offset:3px; }
.nook-resident-slot.empty { border:2px dashed #9d886055; border-radius:10px; color:#8e795e88; font:25px var(--display); }
.nook-layout { display:grid; grid-template-columns:1fr; align-items:center; gap:20px; margin-block:auto; }
.nook-portrait { container-type:inline-size; position:relative; min-width:0; display:flex; flex-direction:column; align-items:center; gap:8px; text-align:center; }
.nook-portrait h3 { font-size:22px; margin:0; }
.nook-device { position:relative; isolation:isolate; width:min(380px,100%); aspect-ratio:1; }
.nook-device::after { content:""; position:absolute; inset:0; z-index:5; background:var(--nook-shell) center/contain no-repeat; pointer-events:none; }
.nook-room { position:absolute; inset:18% 15.5% 27.5%; overflow:hidden; border-radius:14%; background:linear-gradient(#edf2cb 0 65%,#b8c997 65% 68%,#dfc892 68%); }
.nook-room.sleeping { background:linear-gradient(#566476 0 65%,#596955 65% 68%,#807563 68%); }
.nook-room.sleeping::before { opacity:.5; }
.nook-room::before { content:""; position:absolute; inset:0; background:radial-gradient(ellipse at 85% 10%,#fff8d4 0 12%,transparent 13%); opacity:.8; }
.nook-room>.nookling-picture.large { width:100%; height:100%; max-width:none; inset:0; z-index:3; object-fit:fill; }
.incubator-device .nook-room { inset:31% 16% 30%; overflow:visible; border-radius:12%; background:#f5e7c9; }
/* The same shell places the egg between the rear tray and the front rim. */
.incubator-device::before { content:""; position:absolute; inset:0; z-index:7; background:var(--nook-shell) center/contain no-repeat; clip-path:inset(71% 0 0); pointer-events:none; }
.incubator-device .nookling-picture.large { width:70%; height:auto; inset:auto 15% -10%; z-index:6; }
.nook-furniture { z-index:1; }
.nook-poop { position:absolute; bottom:10%; z-index:4; width:28px; height:25px; padding:0; display:grid; place-items:center; --face:transparent; --edge:0px; --shade:transparent; --lift:0px; }
.nook-poop::before,.nook-poop::after { display:none; }
.nook-poop-picture { width:24px; height:20px; }
.nook-poop.fresh { animation:nook-drop .4s ease-out; }
.nook-broom { position:absolute; bottom:7%; z-index:8; width:55px; height:75px; fill:var(--orange); stroke:var(--ink); stroke-width:2; filter:drop-shadow(3px 4px 0 #2d241255); pointer-events:none; }
.nook-actionbar { display:grid; grid-template-columns:repeat(8,38px); gap:8px; justify-content:center; }
.nook-care-icon svg { width:23px; height:23px; fill:none; stroke:var(--ink); stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.nook-controls { min-width:0; display:flex; flex-direction:column; gap:12px; align-items:stretch; }
.nook-needs { display:grid; grid-template-columns:repeat(3,1fr); gap:12px 18px; justify-content:center; width:fit-content; margin:auto; }
.nook-need { display:flex; align-items:center; gap:9px; }
.nook-need>svg { width:23px; height:23px; flex-shrink:0; fill:none; stroke:var(--ink); stroke-width:1.6; }
.need-pips { display:flex; gap:3px; }
.need-pips i { display:block; width:8px; height:15px; border:1px solid #71604766; border-radius:2px; background:#bbae8d55; }
.need-pips i.full { background:#73935d; }
.nook-need.low .need-pips i.full { background:#c77042; }
.nook-toy-box { align-self:center; margin-top:12px; }
.nook-dialog>.journey-feedback { font-size:12px; flex-shrink:0; min-height:16px; margin:0; }
.nook-change-feedback { pointer-events:none; position:absolute; z-index:20; top:35%; left:22%; right:18%; display:flex; flex-wrap:wrap; gap:12px; justify-content:center; animation:nook-feedback 2.2s both; }
.nook-change-feedback>span { display:flex; align-items:center; gap:5px; padding:6px 10px; border:2px solid var(--ink); border-radius:14px; box-shadow:3px 4px 0 #281c1277; background:var(--paper); color:#42633a; font:23px var(--display); }
.nook-change-feedback>span.down { color:#a74832; }
.nook-change-feedback svg { width:24px; height:24px; fill:none; stroke:currentColor; stroke-width:2; }
@keyframes nook-feedback { 0% { opacity:0; transform:translateY(14px) scale(.7); } 15%,65% { opacity:1; transform:translateY(0) scale(1); } 100% { opacity:0; transform:translateY(-35px); } }
.nook-food-menu { position:absolute; inset:20% 16% auto; z-index:9; padding:10px 35px 10px 10px; border:2px solid var(--ink); border-radius:8px; background:var(--paper); box-shadow:4px 5px 0 #261a1270; animation:radio-word .2s both; }
.nook-food-menu>.bingo-close { position:absolute!important; right:5px; top:5px; width:24px; height:24px; }
.nook-food-menu .bingo-cross { width:12px; height:12px; }
.nook-food-choices { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); grid-template-rows:repeat(2,34px); gap:5px; padding-bottom:4px; }
.nook-food-menu>.inventory-pages { height:20px; margin-top:5px; gap:12px; }
.nook-food-menu .inventory-page { height:20px; font-size:20px; }
.nook-food-menu .guide-dots { gap:4px; }
.nook-food-choice { position:relative; display:grid; place-items:center; padding:0; width:100%; height:34px; min-width:0; --lift:2px; }
.nook-food-choice .icon-resource { width:22px; height:22px; }
.nook-food-choice .nook-product-picture { width:22px; height:22px; }
.food-opinion { position:absolute; z-index:1; right:-3px; bottom:-3px; display:grid; place-items:center; width:18px; height:18px; border:1.5px solid var(--ink); border-radius:50%; background:var(--paper-bright); color:var(--ink); box-shadow:1px 1px 0 #2b1d1233; pointer-events:none; }
.food-opinion svg { display:block; width:13px; height:13px; fill:none; stroke:currentColor; stroke-width:3; stroke-linecap:round; stroke-linejoin:round; }
.food-opinion.liked { color:#a14738; }
.food-opinion.liked svg,.food-opinion.neutral svg { fill:currentColor; stroke:none; }
.dialog.nook-inventory,.dialog.nook-store,.dialog.nook-equipment-dialog { rotate:0deg; --face:var(--paper-bright); display:flex; flex-direction:column; padding:24px; gap:14px; overflow:hidden; }
.dialog.nook-inventory { width:min(660px,calc(100vw - 24px)); max-width:660px; height:min(610px,calc(100dvh - 24px)); }
.nook-inventory>h2,.nook-equipment-dialog>h2 { font-size:25px; margin:0; padding-right:96px; flex-shrink:0; }
.inventory-stock { display:flex; flex-wrap:wrap; flex-shrink:0; gap:6px; min-height:24px; }
.nook-inventory-grid { flex:1; min-height:0; display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); grid-template-rows:repeat(3,minmax(0,1fr)); gap:12px; padding:4px; }
.nook-inventory-grid.nook-memorial-grid { grid-template-columns:repeat(auto-fill,minmax(110px,1fr)); grid-template-rows:none; grid-auto-rows:max-content; align-content:start; overflow-y:auto; }
.nook-memorial-card { margin:0; min-width:0; text-align:center; }
.nook-memorial-card .nookling-picture { width:100%; height:auto; margin:0; }
.nook-memorial-card figcaption { font:14px var(--display); overflow-wrap:anywhere; }
.inventory-slot { display:grid; place-items:center; position:relative; min-width:0; padding:7px; --face:var(--paper); --lift:3px; }
.inventory-slot.empty { border:2px dashed #b7a17c66; border-radius:10px; background:#c6b58c15; }
.inventory-count { position:absolute; right:8px; bottom:5px; font:13px var(--display); }
.inventory-slot .nook-product-picture { scale:1.15; }
.inventory-detail { height:52px; flex-shrink:0; padding:4px 8px; }
.inventory-detail strong { font:17px var(--display); }
.inventory-detail p { font-size:12px; margin:4px 0; }
.inventory-pages { height:32px; flex-shrink:0; display:flex; align-items:center; justify-content:center; gap:18px; }
.inventory-page { width:32px; height:30px; padding:0; font-size:25px; --face:transparent; --lift:0px; --edge:0px; --shade:transparent; }
.inventory-page::before,.inventory-page::after { display:none; }
.inventory-page:disabled { visibility:hidden; }
.nook-inventory>.error,.nook-store>.error { min-height:16px; margin:0; font-size:12px; }
.dialog.nook-equipment-dialog { width:min(560px,calc(100vw - 24px)); max-width:560px; height:min(490px,calc(100dvh - 24px)); }
.nook-equipment-dialog>.nook-controls { flex:1; min-height:0; overflow:auto; }
.nook-dialog:has(.incubator-device) .nook-layout { grid-template-columns:1fr 1fr; }
.nook-dialog:has(.egg-incubate) .nook-controls { align-items:center; }
.nook-dialog:has(.egg-incubate) .nook-controls>button { min-width:130px; }
.incubator-equipment { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px; }
.incubator-instrument { position:relative; padding:12px; border:2px solid var(--ink); border-radius:11px; box-shadow:3px 4px 0 #291c1355; background:#e5d9b9; display:grid; grid-template-columns:minmax(0,1fr) 4.5ch; grid-template-rows:auto 52px 16px 14px 44px; gap:7px; }
.incubator-instrument h4 { grid-column:1/-1; grid-row:1; margin:0; font:15px var(--display); }
.incubator-slot { grid-column:1/-1; grid-row:2; justify-self:center; align-self:center; position:relative; display:grid; place-items:center; width:60px; height:52px; padding:0; border-radius:8px; --face:#f4ecd1; --lift:2px; }
.incubator-slot:not(.installed) .nook-product-picture { opacity:.35; }
.slot-plus { position:absolute; bottom:2px; right:5px; font:bold 18px var(--font); }
.incubator-slot .nook-product-picture { scale:1; margin:0; }
.incubator-dial { grid-row:5; align-self:center; min-width:0; }
.incubator-dial input { appearance:none; display:block; width:100%; height:44px; margin:0; padding:0; border:0; background:transparent; touch-action:pan-y; }
.incubator-dial input::-webkit-slider-runnable-track { height:10px; border:2px solid var(--ink); border-radius:4px; background:linear-gradient(90deg,#c9bea1 var(--low),#7f9a63 var(--low),#7f9a63 var(--high),#c9bea1 var(--high)); }
.incubator-dial input::-moz-range-track { height:6px; border:2px solid var(--ink); border-radius:4px; background:linear-gradient(90deg,#c9bea1 var(--low),#7f9a63 var(--low),#7f9a63 var(--high),#c9bea1 var(--high)); }
.incubator-dial input::-webkit-slider-thumb { appearance:none; width:12px; height:23px; margin-top:-8px; border:2px solid var(--ink); border-radius:4px; background:var(--paper); box-shadow:2px 2px 0 #291b1244; }
.incubator-dial input::-moz-range-thumb { width:9px; height:18px; border:2px solid var(--ink); border-radius:3px; background:var(--paper); }
.incubator-instrument output { grid-row:5; align-self:center; font:14px var(--display); width:4.5ch; white-space:nowrap; text-align:left; }
.incubator-value { display:inline-block; width:3ch; text-align:left; }
.incubator-life { grid-column:1/-1; grid-row:4; margin:0; height:14px; font:800 11px/14px var(--font); text-align:center; white-space:nowrap; }
.incubator-charge { display:flex; grid-column:1/-1; grid-row:5; align-self:center; justify-content:center; gap:4px; height:23px; }
.incubator-charge i { width:12px; background:#c9bea1; border:1px solid var(--ink); border-radius:2px; }
.incubator-charge i.full { background:#7f9a63; }

.nook-screen-activity { position:absolute; inset:0; z-index:9; pointer-events:none; }
.nook-room.outdoors { background:linear-gradient(#c3e1df 0 65%,#78a574 65% 69%,#b5c584 69%); }
.nook-room.outdoors .nook-furniture,.nook-room.outdoors .nook-poop,.nook-room.outdoors .nook-floor-gift { visibility:hidden; }
.nook-screen-caption { position:absolute; top:4%; left:5%; right:5%; margin:0; text-align:center; font:800 clamp(9px,3cqw,13px)/1.2 var(--font); color:#293e30; text-shadow:0 1px #fff9; }
.nook-screen-choices { position:absolute; top:25%; left:10%; right:10%; display:grid; grid-template-columns:repeat(3,1fr); gap:10px; justify-items:center; align-items:center; }
.nook-screen-choices>svg,.nook-ball-lane>svg,.nook-cup>svg { width:28px; height:28px; fill:#ffce76; stroke:var(--ink); stroke-width:1.6; }
.nook-ball-lane { height:34px; }
.nook-ball-lane>svg { animation:game-ball .6s ease-in-out infinite alternate; }
@keyframes game-ball { to { translate:0 -7px; rotate:15deg; } }
.nook-cup { display:grid; place-items:center; width:34px; height:34px; border:2px solid #695742; border-radius:9px 9px 4px 4px; background:#faf0d1; }
.nook-screen-choices.covered .nook-cup { background:repeating-linear-gradient(90deg,#c47557 0 7px,#dc986c 7px 9px); }
.nook-screen-choices.covered .nook-cup>svg { visibility:hidden; }
.nook-game-pips { position:absolute; bottom:7%; left:50%; transform:translateX(-50%); display:flex; gap:6px; }
.nook-game-pips i { width:9px; height:9px; border:1px solid var(--ink); border-radius:50%; background:#fff7df; }
.nook-game-pips i.full { background:#79bd72; }
.nook-shell-controls { position:absolute; inset:0; z-index:6; pointer-events:none; }
button.nook-shell-button { position:absolute!important; top:84.4%; left:36.3%; translate:-50% -50%; width:13%; height:14%; min-height:44px; padding:0; border:0; border-radius:50%; background:transparent; box-shadow:none; --face:transparent; --edge:0px; --lift:0px; --shade:transparent; pointer-events:auto; touch-action:manipulation; }
button.nook-shell-button:nth-child(2) { left:50%; top:85%; }
button.nook-shell-button:nth-child(3) { left:63.7%; }
button.nook-shell-button:hover:not(:disabled),button.nook-shell-button:active:not(:disabled) { transform:none; --lift:0px; }
button.nook-shell-button::after { display:none; }
button.nook-shell-button::before { display:block; inset:auto; left:10%; top:50%; width:80%; aspect-ratio:130/137; z-index:0; translate:0 -50%; border:2px solid #c5ffa4; border-radius:50%; background:#87ee6350; box-shadow:0 0 5px 2px #a5ff88,0 0 15px 5px #58e947,inset 0 0 8px #b5ff89; opacity:0; pointer-events:none; }
button.nook-shell-button:nth-child(2)::before { left:7%; width:86%; aspect-ratio:140/144; }
button.nook-shell-button.usable::before { animation:shell-ready 1.1s ease-in-out infinite alternate; }
@keyframes shell-ready { from { opacity:.55; } to { opacity:1; } }
.nook-care-icon[aria-disabled=true] { filter:saturate(.4); opacity:.55; }
.nook-wait-label { position:absolute; inset:0; z-index:20; display:grid; place-items:center; border-radius:inherit; background:#f6edcf; color:#71674d; font:800 10px var(--font); }
.nook-sponge,.nook-drying-cloth { position:absolute; top:52%; left:45%; width:28px; height:19px; border:2px solid #ae8a3d; border-radius:7px; background:radial-gradient(#b48f45 1px,transparent 2px) 0 0/7px 7px,#f4d774; box-shadow:2px 3px #60422b44; transition:left .22s; }
.nook-drying-cloth { width:48px; height:40px; border-color:#727a9b; border-radius:4px 7px 16px 5px; background:repeating-linear-gradient(0deg,#d6dbef 0 3px,#c4cce4 3px 5px); }
.nook-screen-progress { position:absolute; left:25%; bottom:4%; width:50%; height:7px; accent-color:#62a466; }
.incubator-instrument .incubator-warning { grid-column:1/-1; grid-row:3; min-width:0; height:16px; font:700 11px/16px var(--font); color:#b76863; text-align:center; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; margin:0; }
.fitting-effect { position:absolute; left:50%; top:50%; translate:-50% -50%; pointer-events:none; font:70px/1 var(--display); color:#fff29a; text-shadow:0 0 14px #ffd65d; animation:fitting-flash .6s both; }
.hatchery-hands.fitted.bulb { box-shadow:inset 0 0 75px #fff09c; transition:box-shadow .18s; }
.hatchery-hands.fitted.power .fitting-effect { color:#89d7ff; text-shadow:25px 0 #fff4aa,-25px 7px #fff4aa; }
.hatchery-hands.fitted.water .fitting-effect { color:#72c3d4; }
@keyframes fitting-flash { 0% { scale:.3; opacity:0; } 25% { scale:1.1; opacity:1; } 100% { scale:1.7; opacity:0; } }
.inventory-shop-hint { display:flex; align-items:center; gap:4px; color:#61874b; font:17px var(--display); }
.inventory-shop-hint svg { width:30px; height:25px; }
/* The arrow that points at whatever stands next to a hint, nudging toward it. The shop hint and the waiting quick
   cups both say where to go with it */
.nudge-arrow { fill:none; stroke:currentColor; stroke-width:3; animation:arrow-nudge .7s ease-in-out infinite alternate; }
@keyframes arrow-nudge { to { translate:5px 0; } }
.nook-death-report { text-align:center; border:2px solid #bd7168; border-radius:12px; padding:16px; background:#efd4c6; }
.nook-death-report h3 { color:#934f49; }
.nook-floor-gift { position:absolute!important; bottom:10%; left:68%; z-index:8; width:27px; height:24px; padding:0; border:2px solid #6c4b34; border-radius:4px; background:#dfa064; box-shadow:2px 3px #4c3d2644; --face:transparent; --edge:0px; --lift:0px; --shade:transparent; }
.nook-floor-gift::before,.nook-floor-gift::after { display:none; }
.parcel-ribbon { position:absolute; inset:-2px 40%; background:#e8d6a0; border-inline:1px solid #9b7949; }
.parcel-ribbon::before { content:""; position:absolute; left:-7px; top:-7px; width:15px; height:7px; border:3px solid #e8d6a0; border-radius:50%; }
.parcel-sparkles { display:none; }
.nook-floor-gift.special { background:#83aaca; box-shadow:0 0 15px #ffe4a9; }
.special .parcel-sparkles { display:block; position:absolute; top:-13px; right:-10px; color:#fff4b4; font:22px var(--display); text-shadow:-33px -4px #f5d366,6px 24px #fff4b4; animation:gift-sparkle 1.6s ease-in-out infinite; }
@keyframes gift-sparkle { 50% { opacity:.4; translate:0 -4px; scale:.75; } }
.nook-gift-dialog { align-items:center; text-align:center; }
.nook-gift-dialog .nookling-picture { max-height:180px; width:180px; }
.nook-gift-dialog .journey-mystery { width:110px; height:100px; }
.nook-resource-gain { position:absolute; z-index:10; bottom:20%; left:45%; display:flex; align-items:center; color:#477543; font:20px var(--display); animation:nook-feedback 2s both; pointer-events:none; }
.poop-stink { position:absolute; top:-8px; left:8px; width:9px; height:18px; border-left:2px solid #83815e88; border-radius:50%; pointer-events:none; animation:stink-rise 2s infinite; }
@keyframes stink-rise { from { opacity:0; translate:0 5px; } 40% { opacity:.8; } to { opacity:0; translate:4px -15px; } }
.poop-fly { display:none; }
.old .poop-fly { display:block; position:absolute; top:-8px; left:2px; width:3px; height:3px; border-radius:50%; background:#3f3a2c; box-shadow:2px -2px #fff8,18px 3px #3f3a2c; animation:poop-flies 1.8s linear infinite; pointer-events:none; }
@keyframes poop-flies { 25% { translate:17px -3px; } 50% { translate:8px -14px; } 75% { translate:-9px -7px; } }
.dialog.nook-store { width:min(940px,calc(100vw - 24px)); max-width:940px; height:min(640px,calc(100dvh - 24px)); }
.nook-store>h2 { font-size:27px; padding-right:175px; margin:0; min-height:38px; }
.nook-store-body { display:grid; grid-template-columns:minmax(0,1fr) 210px; grid-template-rows:auto minmax(0,1fr); gap:15px; flex:1; min-height:0; }
.nook-store-body>.tabs { grid-column:1/-1; flex-wrap:wrap; gap:7px; margin:0; }
.nook-store .tabs button { font-size:13px; padding:7px 10px; }
.shop-catalogue { display:flex; min-height:0; mask-image:linear-gradient(#000 0 calc(100% - 26px),transparent); }
.nook-store-shelves { flex:1; min-width:0; min-height:0; display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); grid-auto-rows:minmax(160px,max-content); align-content:start; gap:12px; padding:5px 9px 32px 5px; overflow-y:auto; overscroll-behavior:contain; scroll-padding:12px; }
.nook-product { display:grid; grid-template-columns:42px minmax(0,1fr); grid-template-rows:auto auto; align-content:space-between; align-items:start; gap:8px 9px; padding:12px; min-width:0; }
.nook-product-info h3 { font:16px/1.1 var(--display); margin:0; }
.nook-product-info p { margin:7px 0 0; font:700 12px/1.4 var(--font); color:var(--ink-soft); }
.nook-product-info small { font-size:10px; }
.nook-product-purchase { grid-column:1/-1; display:flex; align-items:center; flex-wrap:wrap; gap:6px; }
button.shop-add { margin-left:auto; width:34px; height:34px; padding:0; font-size:24px; --lift:2px; }
.nook-basket { position:relative; min-width:0; min-height:0; padding:14px; border-left:2px dashed #8a745747; display:flex; flex-direction:column; gap:12px; }
.nook-basket-items { flex:1; min-height:0; overflow:auto; display:flex; flex-direction:column; gap:10px; padding:0 4px 4px 0; }
.nook-basket-totals { display:flex; flex-wrap:wrap; gap:6px; }
.nook-shop-wallet { position:absolute; right:66px; top:18px; }
.nook-basket h3 { margin:0; font-size:20px; }
.nook-basket p { font-size:12px; }
.nook-basket-row { display:flex; justify-content:space-between; align-items:center; gap:6px; font-size:12px; }
.nook-basket-row button { flex-shrink:0; width:25px; height:25px; padding:0; }
.nook-checkout { position:relative; flex:none; margin-top:auto; display:grid; gap:8px; }
.nook-checkout>button { width:100%; min-height:44px; padding:9px 12px; font-size:15px; }

.shop-thanks { position:absolute; z-index:12; left:0; right:0; bottom:100%; margin-bottom:8px; display:flex; flex-direction:column; align-items:center; font-size:36px; pointer-events:none; animation:shop-thanks 1.8s both; }
.shop-thanks>svg { width:36px; height:36px; fill:#eee; stroke:#444; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.shop-thanks strong { color:#5b9e51; font:25px var(--display); text-shadow:1px 2px 0 #f4f5d4,2px 3px 3px #315b3240; }
.nook-basket .shop-receipt { min-height:2.6em; margin:0; text-align:center; font:11px/1.3 var(--font); color:#69805a; }
@keyframes shop-thanks { 0% { translate:0 0; opacity:1; scale:.9; } 20% { scale:1; } 60% { opacity:1; } 100% { translate:0 -65px; opacity:0; } }
@media(max-width:900px) {
 .nook-store-body { grid-template-columns:1fr; grid-template-rows:auto minmax(0,1fr) auto; position:relative; }
 .nook-store-body>.tabs { flex-wrap:nowrap; overflow-x:auto; min-width:0; padding:3px 3px 7px; }
 .nook-store-body>.tabs>button { flex:none; }
 .nook-store-body>.nook-basket { display:grid; grid-template-columns:minmax(0,1fr) auto; grid-template-rows:auto 48px auto; gap:7px 10px; padding:10px 0 0; border-left:0; border-top:2px dashed #8a745747; }
 .nook-basket h3 { font-size:16px; }
 .nook-basket-items { grid-column:1/-1; grid-row:2; gap:5px; font-size:11px; }
 .nook-basket-empty { margin:4px 0; }
 .nook-basket-totals { grid-column:2; grid-row:1; justify-content:flex-end; }
 .nook-checkout { grid-column:1/-1; grid-row:3; margin:0; gap:6px; }
 .nook-basket .shop-receipt { min-height:1.3em; }
}
@media(max-width:620px) {
 .dialog.nook-dialog { padding:18px 14px; height:min(680px,calc(100dvh - 24px)); gap:8px; }
 .nook-dialog>h2 { font-size:23px; }
 .nook-top-actions { top:17px; right:14px; gap:7px; }
 .nook-top-actions>.symbol-button,.nook-top-actions>.bingo-close { width:32px; height:32px; }
 .nook-resident-slot { height:46px; gap:3px; padding:2px; }
 .nook-resident-slot .nookling-picture { width:36px; }
 .nook-resident-slot strong { font-size:11px; }
 .nook-layout { grid-template-columns:1fr; gap:15px; }
 .nook-device { width:min(300px,100%); }
 .nook-portrait h3 { font-size:21px; }
 .nook-actionbar { grid-template-columns:repeat(8,minmax(0,32px)); gap:5px; width:100%; }
 .nook-care-icon { width:100%; height:34px; }
 .nook-care-icon svg { width:20px; height:20px; }
 .nook-needs { grid-template-columns:repeat(3,1fr); gap:10px 14px; margin:auto; }
 .nook-need { gap:5px; }
 .nook-need>svg { width:20px; height:20px; }
 .need-pips { gap:2px; }
 .need-pips i { width:6px; height:12px; }
 .nook-toy-box { display:none; }
 .nook-dialog:has(.incubator-device) .nook-layout { grid-template-columns:1fr; gap:8px; }
 .nook-dialog:has(.incubator-equipment) .nook-device { width:136px; }
 .nook-dialog:has(.incubator-device) .nook-controls:not(:has(.incubator-equipment)) { flex-direction:row; justify-content:center; }
 .incubator-equipment { gap:8px; }
 .incubator-instrument { padding:7px; gap:4px; }
 .incubator-instrument h4 { font-size:14px; }
 .incubator-slot { width:50px; height:40px; }
 .incubator-instrument .nook-product-picture { scale:.8; }
 .nook-controls:has(.incubator-equipment) { display:grid; grid-template-columns:1fr 1fr; gap:9px; }
 .nook-controls>.incubator-equipment { grid-column:1/-1; }
 .nook-dialog:has(.incubator-device) .journey-meter { display:none; }
 .dialog.nook-inventory,.dialog.nook-equipment-dialog,.dialog.nook-store { padding:18px; }
 .nook-inventory-grid { gap:9px; }
 .inventory-detail { height:60px; }
 .inventory-stock { gap:4px; }
 .nook-store>h2 { font-size:23px; padding-right:44px; }
 .nook-shop-wallet { position:static; align-self:flex-start; margin-top:-6px; }
 .nook-store .tabs button { font-size:11px; padding:6px 8px; }
 .nook-product { padding:10px; gap:8px; grid-template-columns:36px minmax(0,1fr); }
 .nook-store-shelves { grid-template-columns:1fr; grid-auto-rows:minmax(132px,max-content); gap:12px; }
 .nook-product-info p { font-size:12px; }
 button.shop-add { width:40px; height:40px; }
 .nook-product .nook-product-picture { width:32px; }
 .nook-product-info h3 { font-size:14px; }
 .nook-memory { left:10%; right:10%; }
}
@media(max-height:560px) {
 .nook-body { overflow:auto; }
 .dialog.nook-inventory { gap:8px; padding:18px; }
 .nook-inventory-grid { gap:8px; }
 .inventory-detail { height:40px; }
 .inventory-detail p { font-size:11px; }
}
@media(prefers-reduced-motion:reduce) {
 .nook-change-feedback,.nook-poop.fresh,.nook-food-menu { animation:none; }
}
/* Maps and field letters pinned to the expedition office board. */
.dialog.expedition-dialog { position:relative; width:min(1160px,calc(100vw - 24px)); max-width:1160px; height:min(760px,calc(100dvh - 24px)); padding:24px; rotate:0deg; display:flex; flex-direction:column; gap:18px; border:10px solid #634129; border-radius:12px; background:radial-gradient(circle,#5c3f253b 1px,transparent 1.5px) 0 0/7px 7px,#b29465; --face:#b29465; --shade:#21160da0; --lift:8px; }
.expedition-heading { display:grid; grid-template-columns:auto minmax(0,1fr) auto; align-items:center; gap:15px; min-height:38px; flex-shrink:0; }
.expedition-heading h2 { margin:0; color:var(--paper); text-shadow:var(--outline); font-size:30px; }
.expedition-heading .workshop-stock { margin:0; justify-content:flex-end; }
.expedition-heading>.bingo-close { position:relative; grid-column:3; grid-row:1; }
.expedition-body { flex:1; min-height:0; }
.expedition-layout { min-height:0; display:grid; grid-template-rows:minmax(0,1fr); grid-template-columns:minmax(0,1.6fr) minmax(300px,1fr); gap:24px; height:100%; }
.expedition-chart { position:relative; min-width:0; min-height:0; display:flex; flex-direction:column; justify-content:center; gap:20px; }
.expedition-map-label { align-self:center; padding:7px 24px; background:var(--paper); border:2px solid var(--ink); box-shadow:3px 4px 0 #30211566; font:22px var(--display); rotate:-1deg; }
.expedition-map { display:block; align-self:center; width:auto; max-width:100%; height:auto; max-height:70%; object-fit:contain; border:2px solid var(--ink); box-shadow:5px 7px 0 #3d2b1b75; background:#e9d8ad; }
.expedition-destinations { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px; }
.expedition-destination { position:relative; padding:14px 8px 9px; text-align:center; font:15px/1.15 var(--display); white-space:normal; border-radius:2px; --face:#f4e7c8; --lift:4px; }
.map-pin { display:block; position:absolute; width:9px; height:9px; top:3px; left:50%; border:2px solid var(--ink); border-radius:50%; background:#9e5f42; box-shadow:2px 2px 0 #2d1b1244; }
.expedition-destination.active { outline:3px solid var(--orange); outline-offset:3px; }
.expedition-report { position:relative; min-width:0; min-height:0; display:flex; flex-direction:column; gap:14px; height:100%; overflow:auto; background:repeating-linear-gradient(transparent 0 26px,#9b875217 26px 27px),#fff1cf; border:2px solid var(--ink); box-shadow:5px 7px 0 #3d2b1b75; padding:30px 24px 24px; }
.expedition-report::before { content:""; position:absolute; top:8px; left:50%; width:11px; height:11px; border:2px solid var(--ink); background:#a65137; border-radius:50%; box-shadow:2px 3px 0 #31221455; }
.expedition-report h3 { font:25px/1.1 var(--display); margin:0; }
.expedition-report p { font-size:13px; line-height:1.5; white-space:pre-line; margin:0; }
.field-footer { display:flex; align-items:center; gap:12px; width:100%; margin-top:auto; padding-top:14px; }
.field-signature { flex:1; min-width:0; font:600 24px/1.2 "Caveat",var(--font); text-align:right; }
.field-postmark { align-self:center; margin:22px 0; border:4px double #447153; color:#447153; padding:12px; rotate:-12deg; font:25px var(--display); text-transform:uppercase; }
.failed-stamp { border-color:#a2392c; color:#a2392c; }
.expedition-report.failed { background-color:#eaddbc; }
.expedition-report.complete { align-items:center; text-align:center; }
.expedition-options { display:grid; gap:12px; margin-top:auto; }
.expedition-funding { display:flex; flex-direction:column; gap:14px; margin-top:auto; padding-top:18px; border-top:3px double #806a4566; }
.expedition-option { min-width:0; display:grid; grid-template-columns:32px minmax(0,1fr) auto; grid-template-rows:auto auto auto; gap:2px 10px; align-items:center; border:2px solid #7f6a4866; border-radius:4px; padding:8px 10px; background:#fff7df; }
.expedition-option .delivery-symbol { grid-column:1; grid-row:1/3; transition:transform .2s; }
.expedition-option:hover .delivery-symbol { transform:translateY(-2px) rotate(-5deg); }
.expedition-option h4 { grid-column:2; grid-row:1; }
.expedition-option .delivery-duration { grid-column:2; grid-row:2; }
.expedition-option .expedition-costs { grid-column:1/-1; grid-row:3; padding-top:6px; margin-top:4px; border-top:1px dashed #8a71484d; }
.expedition-option .expedition-send { grid-column:3; grid-row:1/3; width:auto; margin:0; min-width:72px; }
.delivery-symbol { width:30px; height:30px; fill:#e2bf75; stroke:var(--ink); stroke-width:1.6; stroke-linejoin:round; }
.expedition-option h4 { margin:0; font:18px var(--display); }
.delivery-duration { font-size:12px; color:var(--ink-soft); }

.unknown-supply { display:inline-grid; place-items:center; width:32px; height:32px; border:2px dotted #5b99c3; border-radius:7px; color:#4e88b0; font:25px var(--display); background:#8dbdd81a; }
.contract-supply-reveal { position:absolute; z-index:5; left:50%; width:min(220px,calc(100% - 48px),55dvh); aspect-ratio:1; transform:translate(-50%,-50%); pointer-events:none; }
.contract-supply-reveal>.icon-resource { position:absolute; inset:0; width:100%; height:100%; filter:drop-shadow(3px 5px 0 var(--shadow-ink)); }
.contract-supply-count.resource-chip { position:absolute!important; top:calc(100% + 6px); left:50%; transform:translateX(-50%); padding:5px 12px; font:30px/1 var(--display); --lift:3px; }
.contract-supply-cover.unknown-supply { position:absolute; inset:0; width:100%; height:100%; border-width:4px; border-radius:14px; font-size:112px; background:linear-gradient(#8dbdd82b,#8dbdd82b),var(--paper-bright); box-shadow:4px 5px 0 var(--shadow-ink); }
.contract-supply-curl { position:absolute; inset:0; background:linear-gradient(135deg,#8baec5,#eff5f7 48%,#aec8db 72%,#608aa6); filter:drop-shadow(-3px 4px 2px #2b1d1255); clip-path:polygon(100% 0,100% 0,100% 0,100% 0); }
.construction-estimates { display:flex; flex-wrap:wrap; gap:12px; align-items:center; }
.construction-estimates .resource-chip { min-width:70px; gap:8px; font-size:18px; }
.contract-estimate-label { font:15px/1.5 var(--font); color:var(--ink-soft); }
.construction-repair-report { display:grid; grid-template-columns:120px minmax(0,1fr); gap:8px 18px; padding:18px; border:2px solid #b3664d; border-radius:8px; background:repeating-linear-gradient(135deg,#a9674020 0 8px,transparent 8px 16px) top/100% 9px no-repeat,#f1dfbf; box-shadow:3px 4px #7e432f22; }
.construction-repair-report .repair-heading { grid-column:1/-1; color:#9e4637; font:23px var(--display); }
.construction-repair-report .construction-site-frame { grid-row:2/4; height:80px; margin:0; align-self:center; border-radius:4px; }
.construction-repair-report h4,.construction-repair-report p { margin:0; line-height:1.5; }
.construction-repair-report p { font-size:14px; }
@media(max-width:700px) {
 .construction-repair-report { grid-template-columns:96px minmax(0,1fr); gap:8px 12px; padding:12px; }
 .construction-repair-report .construction-site-frame { grid-row:2; height:72px; }
 .construction-repair-report h4 { align-self:center; font-size:13px; }
 .construction-repair-report p { grid-column:1/-1; font-size:12px; }
}
.supply-delivery { position:absolute; z-index:18; inset:15% 0 auto; height:150px; display:grid; place-items:center; pointer-events:none; }
.supply-delivery.anchored { right:auto; width:150px; grid-template-columns:minmax(0,1fr); transform:translate(-50%,-50%); }
.construction-work-action.delivering:disabled { opacity:1; }
.delivery-morph-source { visibility:hidden; }
.supply-delivery.anchored .dispatch-crate { animation-name:button-to-crate; }
.supply-delivery .dispatch-button { position:absolute!important; z-index:2; inset:-3px; width:calc(100% + 6px); height:calc(100% + 6px); min-height:0; margin:0; padding:0; white-space:nowrap; opacity:1; animation:crate-button-face 3s both; }
.supply-delivery.anchored .dispatch-lid { animation:crate-open 3s both,crate-assemble 3s both; }
.supply-delivery.anchored .dispatch-crate::after { animation:crate-assemble 3s both; }
.delivery-receipt { position:absolute; z-index:19; transform:translate(-50%,-100%); pointer-events:none; white-space:nowrap; color:#83b879; font:23px var(--display); text-shadow:2px 2px 0 var(--ink); animation:shop-thanks 1.8s both; }
.dispatch-crate { position:relative; width:94px; height:66px; border:3px solid #755038; border-radius:5px; background:repeating-linear-gradient(0deg,#c58f54 0 17px,#98633d 17px 19px); box-shadow:5px 9px #3c281d44; animation:crate-arrive 3s both; }
.dispatch-crate::after { content:""; position:absolute; inset:0 18%; border-inline:9px solid #e2b576; }
.dispatch-lid { position:absolute; z-index:3; left:-5px; right:-5px; top:-12px; height:16px; border:3px solid #755038; border-radius:3px; background:#dcab6f; transform-origin:50% 100%; animation:crate-open 3s both; }
.dispatch-crate>.icon-resource { position:absolute; z-index:4; width:35px; height:35px; left:calc(28px + (var(--parcel-index) - 1)*8px); top:12px; opacity:0; filter:drop-shadow(2px 3px 1px #37291755); animation:parcel-out 1.3s calc(.45s + var(--parcel-index)*.12s) both; }
@keyframes crate-arrive { 0% { translate:-140px 25px; opacity:0; rotate:-12deg; } 17%,80% { translate:0 0; opacity:1; rotate:0deg; } 100% { translate:0 25px; opacity:0; } }
@keyframes button-to-crate { 0%,4% { width:var(--button-width); height:var(--button-height); border-radius:var(--button-radius); box-shadow:none; opacity:1; translate:0 0; } 19%,80% { width:94px; height:66px; border-radius:5px; box-shadow:5px 9px #3c281d44; opacity:1; translate:0 0; } 100% { width:94px; height:66px; border-radius:5px; opacity:0; translate:0 12px; } }
@keyframes crate-button-face { 0%,4% { opacity:1; } 15%,100% { opacity:0; } }
@keyframes crate-assemble { 0%,9% { opacity:0; } 18%,100% { opacity:1; } }
@keyframes crate-open { 0%,16% { transform:none; } 28%,100% { transform:translateY(-26px) rotate(-15deg); } }
@keyframes parcel-out { 0% { translate:0 0; opacity:0; } 22% { opacity:1; } 70% { translate:calc((var(--parcel-index) - 1)*36px) -70px; opacity:1; } 100% { translate:calc((var(--parcel-index) - 1)*45px) -90px; opacity:0; } }
.expedition-dialog.is-busy .expedition-body { cursor:progress; }
.expedition-report.letter-arriving { opacity:0; }
.expedition-report { transform-origin:50% 8px; }
.expedition-report::after { content:""; position:absolute; right:0; bottom:0; width:18px; height:18px; pointer-events:none; background:linear-gradient(135deg,#c9ae7933 48%,#a6885155 49%,#fff6df 54%); }
.expedition-destination { transition:transform .2s,filter .2s; }
.expedition-destination:hover { transform:translateY(-3px) rotate(-1deg); }
.expedition-destination.active .map-pin { background:var(--orange); }
.expedition-brief { display:grid; grid-template-columns:1fr auto; gap:5px 12px; padding:10px 12px; border-left:3px solid #99774a; background:#c8aa6c16; font-size:12px; color:#6c5638; }
.expedition-brief>strong { color:var(--ink); }
.expedition-brief>small { grid-column:1/-1; font:600 18px/1.15 "Caveat",var(--font); }
.expedition-alert { display:grid; grid-template-columns:38px minmax(0,1fr); gap:10px 12px; padding:15px 12px; border:2px dashed currentColor; background:#b5553610; color:#a34e38; }
.expedition-alert.mishap { color:#936e2e; background:#cda44714; }
.expedition-alert-icon { grid-row:1/3; align-self:center; width:36px; height:36px; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.expedition-alert>strong { justify-self:center; font:18px/1.1 var(--display); text-transform:uppercase; text-align:center; transform-origin:center; }
.expedition-alert>p { font-weight:800; color:inherit; text-align:center; }
.expedition-alert-marks { display:inline-block; white-space:nowrap; padding-inline-end:.22em; }
.expedition-alert-marks>span { display:inline-block; margin-inline-start:2px; rotate:10deg; transform-origin:50% 80%; animation:expedition-alert-pulse 4.8s ease-in-out infinite; }
.expedition-alert-marks>span+span { rotate:20deg; animation-delay:.12s; }
@keyframes expedition-alert-pulse { 0%,65%,77%,89%,100% { scale:1; } 71%,83% { scale:1.18; } }
.expedition-passport { align-self:center; margin-top:auto; padding:14px 20px; border-block:1px solid #92764955; text-align:center; }
.expedition-passport>small { font:12px var(--font); text-transform:uppercase; letter-spacing:1px; color:#786242; }
.expedition-stamps { display:flex; gap:18px; justify-content:center; margin:12px 0; }
.expedition-stop-stamp { display:flex; flex-direction:column; justify-content:center; width:62px; height:62px; border:2px dotted #8d775780; border-radius:50%; color:#927e5b; font-family:var(--display); }
.expedition-stop-stamp>small { font-size:11px; }
.expedition-stop-stamp>strong { font-size:22px; line-height:1; }
.expedition-stop-stamp.supplied { border:3px double #50735f; color:#50735f; rotate:-9deg; }
.expedition-stop-stamp.supplied:nth-child(2) { rotate:8deg; }
.expedition-margin-note { font:600 20px/1.2 "Caveat",var(--font); color:#705039; }
.expedition-report .field-postmark { font-size:22px; margin:12px 0; }
.expedition-report .expedition-paid { position:absolute; z-index:20; top:42%; left:50%; translate:-50% -50%; background:#fff3d8ed; pointer-events:none; }
.expedition-send.delivering { opacity:1; }
.expedition-discovery { position:relative; display:grid; place-items:center; margin:auto; width:150px; height:150px; opacity:0; visibility:hidden; }
.expedition-discovery.recovered { opacity:1; visibility:visible; }
.expedition-discovery::before { content:""; position:absolute; inset:-18px; border-radius:50%; background:radial-gradient(circle,#f5cf7177,transparent 68%); }
.expedition-discovery .journey-mystery { position:relative; width:130px; height:120px; filter:drop-shadow(4px 6px 0 #46321e66); }
.expedition-discovery .parcel-sparkles { right:6px; top:10px; }
.expedition-report.complete .expedition-claim { align-self:stretch; }
.expedition-report .field-signature { flex-shrink:0; }
.expedition-report.accident { background:#f2e2b4; border-color:#ae873f; }
.expedition-report.accident h3 { color:#986423; }
.accident-countdown { font-weight:800; color:#7b622c; }
.expedition-costs { display:flex; justify-content:center; align-items:center; flex-wrap:wrap; gap:8px; }
.expedition-costs .resource-chip { font-size:16px; padding:5px 8px; gap:6px; white-space:nowrap; flex-shrink:0; }
.expedition-costs .icon-resource { width:27px; height:27px; }
.expedition-costs .unaffordable { color:#a2392c; }
.expedition-send { margin-top:auto; width:100%; padding:7px 8px; font:16px var(--display); --face:#f1cb77; }
.expedition-dispatch-slip { display:flex; gap:12px; align-items:center; justify-content:center; padding:12px; background:#eee1bf; border:2px solid #6f583c; box-shadow:3px 4px 0 #34271866; font:italic 15px Georgia,serif; rotate:.5deg; }
.expedition-dispatch-slip svg { width:24px; height:24px; flex-shrink:0; fill:none; stroke:var(--ink); stroke-width:1.5; }
.expedition-withdraw { flex-shrink:0; opacity:.45; }
.expedition-withdraw:hover,.expedition-withdraw:focus-visible { opacity:1; }
.expedition-deadline { font-style:italic; color:#81452c; }
.expedition-dialog>.error { position:absolute; bottom:12px; left:24px; right:24px; font-size:12px; background:var(--paper); margin:0; }
.expedition-dialog>.error:empty { display:none; }
@media(max-width:900px) {
 .dialog.expedition-dialog { padding:14px; border-width:6px; gap:10px; height:calc(100dvh - 24px); max-height:830px; }
 .expedition-heading { min-height:30px; }
 .expedition-heading h2 { font-size:24px; }
 .expedition-body { overflow:auto; padding:0 6px 8px 0; margin-right:-6px; }
 .expedition-layout { height:auto; min-height:100%; grid-template-columns:1fr; grid-template-rows:auto auto; align-content:start; gap:14px; }
 .expedition-chart { gap:8px; }
 .expedition-map-label { font-size:17px; padding:3px 12px; }
 .expedition-map { max-height:145px; }
 .expedition-destinations { gap:8px; }
 .expedition-destination { font-size:12px; padding:12px 6px 7px; }
 .expedition-report { height:auto; min-height:340px; overflow:visible; padding:28px 8px 18px; gap:10px; }
 .expedition-report h3 { font-size:22px; }
 .expedition-report p { font-size:12px; line-height:1.4; }
 .field-footer { padding-top:5px; gap:8px; }
 .field-signature { font-size:20px; }
 .expedition-brief { gap:3px 8px; padding:6px 8px; font-size:11px; }
 .expedition-brief>small { font-size:16px; }
 .expedition-alert { padding:10px 8px; gap:6px 8px; grid-template-columns:26px minmax(0,1fr); }
 .expedition-alert-icon { width:25px; height:25px; }
 .expedition-alert>strong { font-size:16px; }
 .expedition-passport { padding:8px 12px; }
 .expedition-stamps { margin:8px 0; gap:15px; }
 .expedition-report:has(.expedition-passport) .field-postmark { padding:6px 10px; margin:6px 0; }
 .expedition-stop-stamp { width:46px; height:46px; }
 .expedition-stop-stamp>small { font-size:9px; }
 .expedition-margin-note { font-size:17px; }
 .expedition-discovery { width:110px; height:110px; }
 .expedition-discovery .journey-mystery { width:100px; height:90px; }
 .expedition-options { gap:6px; }
 .expedition-option { grid-template-columns:26px minmax(0,1fr) auto; gap:2px 6px; padding:6px 8px; }
 .delivery-symbol { width:25px; }
 .expedition-option h4 { font-size:16px; }
 .delivery-duration { font-size:10px; }
 .expedition-option .expedition-send { min-width:60px; }
 .expedition-costs { gap:4px; }
 .expedition-send { padding:5px; min-height:30px; }
 .expedition-dispatch-slip { font-size:12px; padding:7px; }
 .field-postmark { margin:6px 0; font-size:23px; }
}
@media(max-width:600px) and (max-height:760px) {
 .expedition-chart:has(+.expedition-report.proposal) .expedition-map { max-height:110px; }
 .expedition-chart:has(+.expedition-report.blocked) .expedition-map { max-height:90px; }
}
@media(max-width:350px) {
 .expedition-option .resource-chip { font-size:14px; padding:4px 6px; gap:4px; }
}
.expedition-report.blocked { border-color:#9c4d37; }
.expedition-report.blocked::before { background:#d35940; }
.expedition-report.accident::before { background:#d5ae45; }
.expedition-report.complete::before { background:#70865b; }
@media(max-width:600px) {
 .expedition-heading { row-gap:8px; }
 .expedition-stock { grid-column:1/-1; grid-row:2; }
}
.nook-poop.awaiting { visibility:hidden; }
@media(max-width:350px) { .nook-actionbar { grid-template-columns:repeat(4,36px); }.nook-needs { gap:8px; }.need-pips i { width:5px; } }
@media(max-width:380px) {
	.nook-dialog:has(.nook-memorial-button:not([hidden]))>h2 { font-size:18px; }
}
@media(max-width:350px) {
 .nook-dialog:has(.nook-memorial-button:not([hidden]))>h2 { padding-right:0; min-height:88px; }
 .nook-dialog:has(.nook-memorial-button:not([hidden]))>.nook-top-actions { top:52px; }
 .nook-dialog:has(.nook-memorial-button:not([hidden])) .nook-device { max-width:clamp(180px,calc(100dvh - 460px),300px); }
}

.nook-product-picture>.nook-product-icon { position:static; transform:none; width:100%; height:100%; }

button.equipment-warning { position:absolute!important; top:0; right:0; display:grid; place-items:center; width:38px; height:38px; padding:0; border-radius:50%; --face:transparent; --edge:0px; --shade:transparent; --lift:0px; z-index:2; }
button.equipment-warning::before,button.equipment-warning::after { display:none; }
button.equipment-warning svg { display:block; box-sizing:content-box; width:16px; height:16px; padding:3px; border:2px solid var(--ink); border-radius:50%; background:var(--orange-light); box-shadow:2px 3px 0 #291c1355; fill:none; stroke:var(--ink); stroke-width:3; stroke-linecap:round; }
button.equipment-warning[hidden] { display:none; }
.nook-product:has(.equipment-warning:not([hidden])) .nook-product-info h3 { padding-right:24px; }
.inventory-entry { position:relative; min-width:0; min-height:0; }
.inventory-entry>.inventory-slot { width:100%; height:100%; }

@media(pointer:coarse) {
 .nook-actionbar { grid-template-columns:repeat(4,44px); gap:8px; }
 .nook-care-icon { width:44px; height:44px; }
 .nook-top-actions { gap:8px; top:14px; }
 .nook-dialog>h2 { padding-right:156px; }
 .nook-food-menu { inset:18% 4% auto; padding:10px; }
 .nook-food-choices { grid-template-rows:repeat(2,44px); gap:8px; }
 .nook-food-choice { height:44px; }
 .nook-food-menu>.bingo-close { top:auto; bottom:8px; right:8px; }
 .nook-food-menu>.inventory-pages { height:44px; padding-right:44px; }
 .nook-food-menu .inventory-page { height:44px; }
 @container (min-width:408px) {
  .nook-actionbar { grid-template-columns:repeat(8,44px); }
 }
 @container (max-width:407px) {
  .nook-device { max-width:330px; }
 }
}
@media(pointer:coarse) and (max-width:620px) {
 .nook-dialog>h2 { font-size:20px; }
 .nook-layout { gap:10px; }
 .nook-portrait { gap:6px; }
}
@media(min-width:560px) and (max-height:500px) {
 .dialog.nook-dialog { padding:14px 18px; gap:8px; }
 .nook-dialog>h2 { font-size:23px; }
 .nook-body { display:grid; grid-template-columns:110px minmax(0,1fr); gap:14px; }
 .nook-body:not(:has(>.nook-residents)) { grid-template-columns:minmax(0,1fr); }
 .nook-residents { grid-template-columns:1fr; align-content:start; gap:9px; margin:0; }
 .nook-resident-slot { height:48px; padding:2px; gap:3px; }
 .nook-resident-slot .nookling-picture { width:30px; }
 .nook-resident-slot strong { font-size:10px; }
 .nook-layout { grid-template-columns:minmax(0,1fr) 200px; grid-template-rows:24px 96px auto; gap:8px 14px; margin:auto 0; }
 .nook-portrait { display:contents; }
 .nook-portrait h3 { grid-column:2; grid-row:1; font-size:19px; text-align:center; }
 .nook-device { grid-column:1; grid-row:1/4; justify-self:center; width:min(240px,100%); }
 .nook-actionbar { grid-column:2; grid-row:2; grid-template-columns:repeat(4,44px); gap:8px; }
 .nook-controls { grid-column:2; grid-row:3; }
 .nook-needs { grid-template-columns:repeat(2,1fr); gap:5px 8px; }
 .nook-need { gap:4px; }
 .nook-need>svg { width:18px; height:18px; }
 .need-pips { gap:2px; }
 .need-pips i { width:5px; height:10px; }
 .nook-dialog>.journey-feedback:empty { display:none; }
 .nook-dialog:has(.incubator-device) .nook-layout { grid-template-columns:minmax(100px,1fr) minmax(0,3fr); grid-template-rows:auto; }
 .nook-dialog:has(.incubator-device) .nook-device { grid-row:1; }
 .nook-dialog:has(.incubator-device) .nook-controls { grid-row:1; display:grid; grid-template-columns:1fr 1fr; gap:8px; }
 .nook-controls>.incubator-equipment { grid-column:1/-1; grid-template-columns:repeat(4,minmax(0,1fr)); gap:8px; }
 .incubator-instrument { padding:6px; gap:3px; }
 .incubator-instrument h4 { font-size:12px; min-height:30px; }
 .incubator-slot { width:44px; height:44px; }
 .nook-dialog:has(.incubator-device) .journey-meter { display:none; }
 .nook-dialog:has(.egg-incubate) .nook-layout { grid-template-columns:1fr 1fr; }
 .nook-dialog:has(.egg-incubate) .nook-controls { display:flex; }
 .nook-inventory-grid { grid-template-columns:repeat(6,minmax(0,1fr)); grid-template-rows:repeat(2,minmax(0,1fr)); }
 .dialog.nook-store { padding:14px 18px; gap:8px; }
 .nook-store-body { grid-template-columns:minmax(0,1fr) 185px; grid-template-rows:auto minmax(0,1fr); gap:10px; }
 .nook-store-body>.nook-basket { display:flex; border-top:0; border-left:2px dashed #8a745747; padding:6px 0 0 12px; }
 .nook-basket-items { max-height:none; }
 .nook-basket .shop-receipt { min-height:2.6em; }
 .nook-checkout { margin-top:auto; }
 .nook-store .tabs button { font-size:11px; padding:6px 8px; }
 .dialog.hatchery-task { width:min(580px,calc(100vw - 24px)); display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); grid-template-rows:auto minmax(0,1fr) 12px; gap:12px 18px; }
 .hatchery-task>h2 { grid-column:1/-1; }
 .hatchery-task .hatchery-hands { grid-column:1; grid-row:2/4; height:100%; }
 .hatchery-task-copy { grid-column:2; grid-row:2; align-self:center; min-height:0; font-size:18px; }
 .hatchery-task>progress { grid-column:2; grid-row:3; }
}
@media(min-width:701px) and (max-height:500px) {
 .construction-plan-dialog { padding:14px 18px; gap:8px; }
 .construction-plan-dialog>h2 { font-size:24px; }
 .construction-plan-stages { gap:10px; }
 .construction-plan-stage { padding:8px; }
 .construction-plan-stage legend { font-size:18px; }
 .construction-methods { grid-template-columns:repeat(3,minmax(0,1fr)); gap:6px; }
 button.construction-method { font-size:10px; white-space:normal; padding:4px 3px; }
 .construction-plan-details { font-size:10px; line-height:1.4; margin-top:8px; }
 .construction-plan-bill { padding-top:6px; }
 .construction-plan-total .resource-chip { font-size:11px; padding:3px 6px; }
 .construction-plan-total .icon-resource { width:16px; height:16px; }
 .construction-plan-timing { font-size:11px; margin-top:6px; }
 .construction-place { padding:8px 14px 72px; gap:8px; }
 .construction-place::before { height:62px; }
 .construction-sign { height:48px; gap:12px; }
 .construction-sign h1 { font-size:22px; }
 .construction-sign .stock-chip { font-size:10px; padding:2px 4px; gap:2px; }
 .construction-sign .stock-chip .icon-resource { width:14px; height:14px; }
 .construction-body { margin:0; }
 .contract-board { grid-template-columns:170px minmax(0,1fr); gap:16px; }
 .contract-list { gap:12px; }
 .contract-stack h2 { font-size:15px; }
 button.contract-choice { padding:7px; }
 .contract-choice strong { font-size:11px; }
 .contract-document { padding:12px 16px 4px; }
 .contract-heading { padding-bottom:6px; }
 .contract-letterhead { font-size:12px; }
 .contract-heading .contract-mini-seal { width:26px; height:26px; font-size:18px; }
 .contract-paper h3 { font-size:21px; margin:8px 0; }
 .contract-brief,.contract-terms { font-size:12px; margin-bottom:8px; }
 .contract-footer { margin:6px 16px 10px; padding-top:6px; }
 .contract-prize .journey-mystery { width:54px; height:50px; }
 .contract-signature { gap:3px; }
 .contract-signature>strong { font-size:29px; }
 .contract-signature>small { font-size:10px; }
 .dialog.expedition-dialog { padding:12px; gap:10px; }
 .expedition-layout { grid-template-columns:minmax(0,.8fr) minmax(0,1fr); grid-template-rows:auto; gap:14px; }
 .expedition-map { max-height:calc(100% - 76px); }
 .expedition-map-label { font-size:17px; padding:3px 10px; }
 .expedition-chart { gap:8px; position:sticky; top:0; height:calc(100dvh - 118px); }
 .expedition-report { min-height:calc(100dvh - 118px); padding:28px 10px 10px; gap:8px; }
 .expedition-report.proposal .field-letter { white-space:normal; }
 .expedition-funding { gap:8px; padding-top:10px; }
 .expedition-report.proposal .field-footer { padding-top:0; }
 .expedition-report.proposal .expedition-brief { gap:2px 8px; padding-block:4px; }

}

@media(prefers-reduced-motion:reduce) {
 .nook-shell-button.usable::before,.nook-ball-lane>svg,.nudge-arrow,.special .parcel-sparkles,.poop-stink,.poop-fly,.expedition-alert-marks>span { animation:none; }
 button.nook-shell-button.usable::before { animation:none; opacity:1; }
 .dispatch-crate,.dispatch-lid,.dispatch-crate>.icon-resource,.dispatch-button,.contract-approval,.shop-thanks,.fitting-effect,.nook-resource-gain { animation-duration:.01ms; }
 .supply-delivery.anchored .dispatch-crate,.supply-delivery.anchored .dispatch-lid,.supply-delivery.anchored .dispatch-crate::after,.delivery-receipt { animation:none; }
}

/* A timed send-off: the guide's own bubble and device, above the circle without taking input or focus, and
   quicker in so the bubble has landed by the time the voice says the words. Its words stand in the middle of
   the paper in the guide's own ink, larger than a heading and tilted to the right, and one hump of the wave the
   competition board's letters ride runs over them on a short springy round and then leaves them standing. */
.guide-radio.race-call { z-index:60; }
.guide-radio.race-call::before { display:none; }
.guide-radio.race-call * { pointer-events:none!important; }
.guide-radio.race-call:not(.exiting) .guide-device { animation-duration:.3s; }
.guide-radio.race-call:not(.exiting) .guide-paper { animation-duration:.2s; animation-delay:.1s; }
.guide-radio.race-call .guide-copy { display:grid; place-content:center; padding:0; overflow:visible; }
.guide-radio.race-call .guide-title { font-size:clamp(44px,5.6vw,72px); line-height:1.15; white-space:nowrap; }
.guide-radio.race-call .guide-message { display:none; }
.guide-radio.race-call .guide-call { display:inline-block; rotate:8deg; }
.guide-radio.race-call .guide-call>span { animation:event-wave .6s calc(var(--speech-delay,0ms) + var(--letter)*.05s) cubic-bezier(.34,1.56,.64,1) 1; }

/* A changing pull is a turning compass. A lost run leaves a broken wheel to restart from. */
.race-feedback { position:absolute; inset:0; pointer-events:none; }
.gravity-cue { position:absolute; left:var(--rider-x,50%); top:clamp(64px,calc(var(--rider-y,60%) - 158px),calc(100% - 110px)); margin-left:0; width:80px; opacity:0; transform:translateX(-50%); filter:drop-shadow(0 4px 2px #24170d80); }
.gravity-cue svg { display:block; width:100%; overflow:visible; }
.gravity-cue.active { animation:compass-arrive 2.8s both; }
.compass-needle { transform-origin:60px 60px; transform:rotate(var(--to,0deg)); }
.gravity-cue.active .compass-needle { animation:compass-turn .8s cubic-bezier(.2,.85,.3,1.2) both; }
.compass-rays { stroke:#ffd37b; stroke-width:4; stroke-linecap:round; }
.gravity-cue.active .compass-rays { animation:compass-rays .8s ease-out both; }
.gravity-pull { transform-origin:60px 60px; transform:rotate(var(--to,0deg)); }
.race-feedback.failed .gravity-cue { display:none; }
.crash-cue { position:absolute; inset:0; display:grid; place-items:center; background:radial-gradient(ellipse at center,#39241418 20%,#21190fc2 100%); animation:crash-wash .55s ease-out both; }
.crash-stamp { position:relative; width:min(320px,80vw); padding:12px 22px 24px; text-align:center; color:#352619; background:linear-gradient(174deg,#fff0ca,#e2ba72); border:4px solid #4b301c; border-radius:17% 8% 13% 7% / 7% 12% 8% 13%; box-shadow:0 7px 0 #24170d90,inset 0 0 0 3px #ffefbd; animation:crash-stamp .5s cubic-bezier(.2,.9,.35,1.15) both; }
.crash-stamp::before,.crash-stamp::after { content:""; position:absolute; width:38px; height:9px; border:2px solid #684726; background:repeating-linear-gradient(125deg,#59402b 0 6px,#deb366 6px 13px); top:18px; transform:rotate(-14deg); }
.crash-stamp::before { left:-14px; }
.crash-stamp::after { right:-14px; transform:rotate(14deg); }
.crash-emblem { display:block; width:190px; max-width:75%; margin:-62px auto -5px; overflow:visible; filter:drop-shadow(0 4px 1px #24170d55); }
.wheel-left { animation:wheel-break-left .6s cubic-bezier(.2,.8,.25,1) both; transform-origin:90px 74px; }
.wheel-right { animation:wheel-break-right .6s cubic-bezier(.2,.8,.25,1) both; transform-origin:110px 74px; }
.crash-bolts { animation:crash-bolts .7s ease-out both; transform-origin:100px 74px; }
.crash-burst { animation:crash-burst .45s ease-out both; transform-origin:100px 74px; }
.crash-title { margin:0; font:clamp(30px,5vw,44px)/1.1 var(--display); text-transform:uppercase; transform:rotate(-3deg); }
.crash-explanation { margin:12px 0 18px; font-weight:700; font-size:15px; }
.crash-retry { pointer-events:auto; width:100%; min-height:50px; }
@keyframes compass-arrive { 0% { opacity:0; transform:translateX(-50%) scale(.45) rotate(-15deg); } 15%,80% { opacity:1; transform:translateX(-50%) scale(1) rotate(0); } 100% { opacity:0; transform:translateX(-50%) scale(.9) translateY(-8px); } }
@keyframes compass-turn { from { transform:rotate(var(--from)); } to { transform:rotate(var(--to)); } }
@keyframes compass-rays { from { opacity:1; } to { opacity:0; } }
@keyframes crash-wash { from { opacity:0; } to { opacity:1; } }
@keyframes crash-stamp { from { opacity:0; transform:translateY(18px) scale(.8) rotate(5deg); } to { opacity:1; transform:translateY(0) scale(1) rotate(-1deg); } }
@keyframes wheel-break-left { from { transform:translate(0,0) rotate(0); } to { transform:translate(-10px,4px) rotate(-17deg); } }
@keyframes wheel-break-right { from { transform:translate(0,0) rotate(0); } to { transform:translate(10px,-3px) rotate(14deg); } }
@keyframes crash-bolts { from { opacity:0; transform:scale(.5) rotate(-20deg); } to { opacity:1; transform:scale(1) rotate(0); } }
@keyframes crash-burst { from { transform:scale(.35); } to { transform:scale(1); } }
@media(max-height:500px) { .gravity-cue { width:64px; top:clamp(50px,calc(var(--rider-y,60%) - 125px),calc(100% - 85px)); margin-left:0; } .crash-emblem { width:135px; margin-top:-42px; } .crash-stamp { padding-bottom:12px; } .crash-explanation { margin:8px 0; } }
@media(prefers-reduced-motion:reduce) {
	.gravity-cue.active { animation:compass-still 2.8s both; }
	.gravity-cue.active .compass-needle,.gravity-cue.active .compass-rays,.crash-cue,.crash-stamp,.wheel-left,.wheel-right,.crash-bolts,.crash-burst { animation:none; }
	.wheel-left { transform:translate(-10px,4px) rotate(-17deg); }
	.wheel-right { transform:translate(10px,-3px) rotate(14deg); }
}
@keyframes compass-still { 0%,90% { opacity:1; } 100% { opacity:0; } }

.admin-bot-settings { padding: 20px; background: var(--paper); border-radius: 12px; }
.admin-bot-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; margin: 18px 0; }
.admin-bot-field { display: flex; flex-direction: column; gap: 6px; }
.admin-bot-toggle { display: flex; align-items: center; gap: 10px; }

.route-pointer { position:absolute; left:var(--rider-x,50%); top:var(--rider-y,60%); width:0; height:0; transform:rotate(var(--bearing,0deg)); transition:transform .09s linear; }
.route-arrow { position:absolute; width:68px; height:48px; top:-24px; left:clamp(65px,9vw,105px); overflow:visible; opacity:0; transform:scale(.25); transform-origin:20% 50%; filter:drop-shadow(0 3px 2px #24170d80); transition:opacity .16s,transform .2s; }
.route-pointer.active .route-arrow { opacity:1; transform:scale(1); animation:route-lock .35s cubic-bezier(.2,.8,.3,1.2); }
.route-wing { transform-box:fill-box; transform-origin:center; }
.route-pointer.active .route-wing-top { animation:route-wing-top var(--beat,.7s) ease-in-out infinite alternate; }
.route-pointer.active .route-wing-bottom { animation:route-wing-bottom var(--beat,.7s) ease-in-out infinite alternate; }
.route-pointer.active .route-trails { animation:route-stream var(--beat,.7s) linear infinite; }
.route-goal { opacity:0; }
.route-pointer.goal .route-goal { opacity:1; }
@keyframes route-lock { 0% { opacity:0; transform:translateX(-28px) scale(.3); } 70% { transform:translateX(5px) scale(1.15); } 100% { opacity:1; transform:translateX(0) scale(1); } }
@keyframes route-wing-top { from { transform:rotate(-12deg); } to { transform:rotate(8deg); } }
@keyframes route-wing-bottom { from { transform:rotate(12deg); } to { transform:rotate(-8deg); } }
@keyframes route-stream { from { opacity:0; transform:translateX(-12px); } 40% { opacity:.8; } to { opacity:0; transform:translateX(9px); } }
@media(prefers-reduced-motion:reduce) { .route-pointer,.route-arrow { transition:none; } .route-pointer.active .route-arrow,.route-pointer.active .route-wing,.route-pointer.active .route-trails { animation:none; } }

.checkpoint-cue { position:absolute; width:78px; height:78px; margin-top:-48px; transform:translate(-50%,-50%); opacity:0; filter:drop-shadow(0 3px 1px #33241980); }
.checkpoint-cue svg { width:100%; overflow:visible; }
.checkpoint-cue.active { animation:checkpoint-flash .85s both; }
.checkpoint-ring,.checkpoint-seal { transform-origin:60px 60px; }
.checkpoint-cue.active .checkpoint-ring { animation:checkpoint-ring .7s ease-out both; }
.checkpoint-cue.active .checkpoint-seal { animation:checkpoint-stamp .6s cubic-bezier(.2,.8,.3,1.2) both; }
.route-pointer.active.collected .route-arrow { animation:route-collect .5s ease-out; }
@keyframes checkpoint-flash { 0% { opacity:0; } 8%,55% { opacity:1; } 100% { opacity:0; } }
@keyframes checkpoint-ring { from { transform:scale(.45) rotate(-45deg); opacity:1; } to { transform:scale(1.8) rotate(65deg); opacity:0; } }
@keyframes checkpoint-stamp { 0% { transform:scale(.15) rotate(-40deg); } 40% { transform:scale(1.12) rotate(8deg); } 100% { transform:scale(.8) rotate(0); } }
@keyframes route-collect { 0% { transform:translateX(-35px) scale(.2) rotate(-35deg); opacity:0; } 65% { transform:translateX(5px) scale(1.15) rotate(4deg); opacity:1; } 100% { transform:translateX(0) scale(1) rotate(0); } }
@media(prefers-reduced-motion:reduce) { .checkpoint-cue.active .checkpoint-ring,.checkpoint-cue.active .checkpoint-seal,.route-pointer.active.collected .route-arrow { animation:none; } }

@media(max-height:500px) { .route-arrow { left:54px; width:52px; height:37px; top:-18.5px; } .checkpoint-cue { width:62px; height:62px; margin-top:-40px; } }

.finish-cue { position:absolute; left:clamp(125px,var(--rider-x,50%),calc(100% - 125px)); top:clamp(65px,calc(var(--rider-y,60%) - 195px),65%); width:240px; transform:translateX(-50%); opacity:0; filter:drop-shadow(0 5px 3px #24170d80); }
.finish-cue svg { display:block; width:100%; overflow:visible; }
.finish-cue.active { animation:finish-arrive 1.65s both; }
.finish-flags,.finish-medal,.finish-rays { transform-origin:150px 115px; }
.finish-cue.active .finish-flags { animation:finish-unfurl .6s cubic-bezier(.2,.8,.3,1.2) both; }
.finish-cue.active .finish-medal { animation:checkpoint-stamp .7s cubic-bezier(.2,.8,.3,1.2) both; transform-origin:center; }
.finish-cue.active .finish-rays { animation:finish-rays 1.4s ease-out both; }
@keyframes finish-arrive { 0% { opacity:0; transform:translate(-50%,20px) scale(.4); } 20%,80% { opacity:1; transform:translate(-50%,0) scale(1); } 100% { opacity:0; transform:translate(-50%,-15px) scale(1.05); } }
@keyframes finish-unfurl { from { transform:scaleX(.1) rotate(-18deg); } to { transform:scaleX(1) rotate(0); } }
@keyframes finish-rays { from { opacity:1; transform:scale(.4) rotate(-15deg); } to { opacity:0; transform:scale(1.7) rotate(15deg); } }
@media(prefers-reduced-motion:reduce) { .finish-cue.active { animation:checkpoint-flash 1.65s both; } .finish-cue.active .finish-flags,.finish-cue.active .finish-medal,.finish-cue.active .finish-rays { animation:none; } }
