/*
 * omggg.wtf: the home and the 404. One screen, a toy: the word's letters are bodies that home.js
 * runs with Matter.js. The palette and faces follow the Levo page (levo/levo.css,
 * levo/desk.css). Light and dark follow the system.
 */

:root {
	--bg: #F7F7F7;
	--ink: 0 0 0;
	--text: #1D1D1F;
	--glow-a: rgba(122, 150, 255, 0.28);
	--glow-b: rgba(255, 170, 120, 0.24);
	--lift-a: rgba(0, 0, 0, 0.14);
	--lift-b: rgba(0, 0, 0, 0.08);
	--round: ui-rounded, "SF Pro Rounded", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
	color-scheme: light dark;
}
@media (prefers-color-scheme: dark) {
	:root {
		--bg: #070707;
		--ink: 255 255 255;
		--text: #F0F0F0;
		--glow-a: rgba(98, 84, 220, 0.3);
		--glow-b: rgba(40, 120, 200, 0.22);
		--lift-a: rgba(0, 0, 0, 0.55);
		--lift-b: rgba(0, 0, 0, 0.35);
	}
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; overflow: hidden; overscroll-behavior: none; }
html { background: var(--bg); -webkit-text-size-adjust: 100%; }
body {
	color: var(--text);
	font-family: var(--round);
	-webkit-font-smoothing: antialiased;
	-webkit-user-select: none;
	user-select: none;
	-webkit-tap-highlight-color: transparent;
}
a { color: inherit; text-decoration: none; }
::selection { background: rgba(0, 178, 255, 0.3); }

/* The scene fills the window. Its floor is the window's bottom edge. */
.toy {
	position: fixed;
	inset: 0;
	overflow: hidden;
	touch-action: manipulation;
	background:
		radial-gradient(50% 55% at 50% 0%, var(--glow-a) 0%, transparent 70%),
		radial-gradient(40% 50% at 88% 100%, var(--glow-b) 0%, transparent 70%),
		var(--bg);
}
.toy-title { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* The letters: one canvas each, placed by home.js. */
.toy-letters { position: absolute; inset: 0; pointer-events: none; }
.lt { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
/* The drop shadow scales with the letter (--k: its size against the word's), so small ones look the same. */
.lt { --k: 1; filter: drop-shadow(0 calc(14px * var(--k)) calc(18px * var(--k)) var(--lift-a)) drop-shadow(0 calc(3px * var(--k)) calc(4px * var(--k)) var(--lift-b)); will-change: transform; }
.toy.is-still .lt { will-change: auto; }
.toy.can-grab { cursor: grab; }
.toy.is-held, .toy.is-held * { cursor: grabbing !important; }

/* The links: plain text in the page's ink. On hover the words hop and grow bolder (the hop is on
   an inner span, so it never fights the entrance). */
.lk { display: inline-block; font-size: 14px; font-weight: 500; letter-spacing: -0.005em; color: var(--text); transition: font-weight .22s ease; }
.lk-host:hover .lk, .lk-host:focus-visible .lk { font-weight: 700; animation: lk-hop .45s cubic-bezier(.34, 1.56, .64, 1); }
.lk-host:focus-visible { outline: 2px solid #00B2FF; outline-offset: 4px; border-radius: 6px; }
@keyframes lk-hop {
	0% { transform: none; }
	40% { transform: translateY(-3px) scale(1.04); }
	75% { transform: translateY(1px); }
	100% { transform: none; }
}

/* Cntxt Labs: alone in the bottom-trailing corner; it pops up from just below the window's edge
   once the word has arrived. */
.cntxt {
	position: fixed;
	right: calc(22px + env(safe-area-inset-right));
	bottom: calc(18px + env(safe-area-inset-bottom));
	z-index: 3;
	transform-origin: 50% 100%;
	animation: rise-in .6s cubic-bezier(.34, 1.56, .64, 1) .85s both;
}
@keyframes rise-in {
	from { transform: translateY(calc(100% + 30px + env(safe-area-inset-bottom))) scale(0.4); }
	to { transform: none; }
}

/* Levo: its icon pops up somewhere clear of the word (home.js picks the place), wobbles, then its
   question shows below it. Both open its page. */
.levo {
	position: fixed;
	left: 24px;
	top: 24px;
	z-index: 3;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	-webkit-user-drag: none;
}
.levo img { display: block; width: 68px; height: 68px; -webkit-user-drag: none; transition: transform .25s cubic-bezier(.34, 1.56, .64, 1); }
.levo:hover img { transform: scale(1.06); }
.levo-q { display: block; transform-origin: 50% 0; }
.toy.is-live .levo:not(.is-in) { visibility: hidden; }
.levo.is-in img { animation: levo-pop .6s linear both, levo-wobble .7s ease-in-out .6s both; }
.levo.is-in .levo-q { animation: levo-q .5s cubic-bezier(.34, 1.56, .64, 1) 1.15s both; }
@keyframes levo-pop {
	0% { transform: scale(0); animation-timing-function: cubic-bezier(.2, .7, .3, 1); }
	55% { transform: scale(1.2); animation-timing-function: cubic-bezier(.5, 0, .5, 1); }
	78% { transform: scale(0.96); animation-timing-function: cubic-bezier(.5, 0, .5, 1); }
	100% { transform: scale(1); }
}
@keyframes levo-wobble {
	0%, 100% { rotate: 0deg; }
	20% { rotate: -9deg; }
	45% { rotate: 7deg; }
	70% { rotate: -3deg; }
	88% { rotate: 1deg; }
}
@keyframes levo-q {
	from { opacity: 0; transform: translateY(-6px) scale(0.6); }
	to { opacity: 1; transform: none; }
}

@media (max-width: 600px) {
	.levo img { width: 58px; height: 58px; }
}

/* A shake. */
.toy.is-quake { animation: quake .5s cubic-bezier(.36, .07, .19, .97); }
@keyframes quake {
	10%, 90% { translate: -2px 1px; }
	20%, 80% { translate: 5px -2px; }
	30%, 50%, 70% { translate: -9px 3px; }
	40%, 60% { translate: 9px -3px; }
}

@media (prefers-reduced-motion: reduce) {
	.cntxt, .levo.is-in img, .levo.is-in .levo-q { animation: none; }
	.lk-host:hover .lk, .lk-host:focus-visible .lk { animation: none; }
	.toy.is-quake { animation: none; }
}
