/* site/src/assets/css/site.css
 * One stylesheet for the whole site. Order: tokens, base, nav, hero, the
 * living-type band, the doors, the proof strip, footer, motion.
 *
 * The site is loud on purpose. Colour is used in whole blocks rather than in
 * accents, because the restrained version of this page was rejected for
 * looking like every other studio template.
 */

/* ── tokens ──────────────────────────────────────────────────────────── */
:root {
	--ink: #0a0a0f;
	--ink-soft: #3a3a46;
	--paper: #fbf9f4;
	--teal: #00d9b8;
	--amber: #ffb020;
	--yellow: #ffd400;
	--blue: #2f6bff;
	--pink: #ff5f8f;
	--line: rgba(10, 10, 15, .14);

	--display: 'Bricolage Grotesque', 'Anybody', system-ui, sans-serif;
	--react: 'Anybody', 'Bricolage Grotesque', system-ui, sans-serif;
	--mono: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;

	--gutter: clamp(18px, 5vw, 64px);
	--wide: 1320px;
}

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

html { scroll-behavior: smooth; }

body {
	background: var(--paper);
	color: var(--ink);
	font-family: var(--display);
	font-size: clamp(16px, 1.05vw, 18px);
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
	overflow-x: hidden;
}

a { color: inherit; }

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

.skip {
	position: absolute; left: -9999px; top: 0; z-index: 100;
	background: var(--ink); color: var(--paper); padding: 12px 18px;
}
.skip:focus { left: 12px; top: 12px; }

:where(a, button):focus-visible {
	outline: 3px solid var(--blue);
	outline-offset: 3px;
	border-radius: 4px;
}

.label {
	font: 500 clamp(11px, .78vw, 13px)/1 var(--mono);
	letter-spacing: .16em;
	text-transform: uppercase;
}

/* ── nav ─────────────────────────────────────────────────────────────── */
.nav {
	position: fixed; inset: 0 0 auto 0; z-index: 50;
	display: flex; align-items: center; justify-content: space-between;
	gap: 20px; padding: 18px var(--gutter);
	color: var(--paper);
	mix-blend-mode: difference; /* legible over the dark hero and the bright blocks alike */
	transition: color .3s;
}

.nav__mark {
	display: inline-flex; align-items: center; gap: 9px;
	font: 700 clamp(19px, 1.5vw, 23px)/1 var(--display);
	letter-spacing: -.03em; text-decoration: none;
}
.nav__dot {
	width: 11px; height: 11px; border-radius: 50%;
	background: var(--teal);
	box-shadow: 0 0 14px var(--teal);
	animation: pulse 2.6s ease-in-out infinite;
}
.nav__stop { color: var(--teal); }

@keyframes pulse { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(.72); opacity: .55; } }

.nav__links { display: flex; align-items: center; gap: clamp(14px, 2vw, 30px); }
.nav__links a {
	font: 500 14px/1 var(--mono);
	letter-spacing: .04em;
	text-decoration: none;
	opacity: .82;
}
.nav__links a:hover, .nav__links a[aria-current] { opacity: 1; }
.nav__cta {
	border: 1.5px solid currentColor;
	border-radius: 999px;
	padding: 9px 16px;
}
@media (max-width: 720px) {
	.nav__links a:not(.nav__cta) { display: none; }
}

/* ── hero ────────────────────────────────────────────────────────────── */
.hero {
	position: relative;
	min-height: 100svh;
	background: var(--ink);
	color: var(--paper);
	display: grid;
	align-items: end;
	overflow: hidden;
}

/* The sand canvas sits behind everything and is purely decorative — the
   words it spells are also in the DOM below, for search engines and for
   anyone the canvas never renders for. */
.hero__canvas {
	position: absolute; inset: 0;
	width: 100%; height: 100%;
}

.hero__glow {
	position: absolute; inset: -20% -10% auto -10%; height: 90vh;
	background:
		radial-gradient(40vw 40vw at 22% 30%, rgba(0, 217, 184, .30), transparent 70%),
		radial-gradient(38vw 38vw at 76% 22%, rgba(255, 176, 32, .26), transparent 70%),
		radial-gradient(34vw 34vw at 55% 70%, rgba(255, 95, 143, .22), transparent 70%);
	filter: blur(30px);
	pointer-events: none;
}

.hero__inner {
	position: relative;
	padding: 0 var(--gutter) clamp(34px, 6vh, 70px);
	width: 100%;
	display: grid;
	gap: clamp(20px, 4vh, 40px);
}

.hero__spell {
	font: 800 clamp(58px, 15.5vw, 230px)/.82 var(--display);
	font-stretch: 92%;
	letter-spacing: -.045em;
	text-transform: uppercase;
	/* Only visible while the canvas cannot draw; the particles carry it
	   otherwise. Kept in the flow so the words are real text. */
	position: absolute; left: -9999px;
}
.no-canvas .hero__spell { position: static; }

.hero__row {
	display: flex; flex-wrap: wrap; align-items: end;
	gap: clamp(20px, 4vw, 60px); justify-content: space-between;
}

.hero__claim {
	font: 600 clamp(26px, 3.6vw, 54px)/1.04 var(--display);
	letter-spacing: -.035em;
	max-width: 15ch;
}
.hero__claim em {
	font-style: normal;
	color: var(--teal);
}

.hero__meta { display: grid; gap: 14px; max-width: 34ch; }
.hero__meta p { color: rgba(251, 249, 244, .72); font-size: clamp(15px, 1.15vw, 18px); }

.hero__scroll {
	display: inline-flex; align-items: center; gap: 10px;
	color: rgba(251, 249, 244, .55);
}
.hero__scroll span { animation: sink 2s ease-in-out infinite; }
@keyframes sink { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(6px); } }

.hero__hint {
	position: absolute; right: var(--gutter); top: 42%;
	writing-mode: vertical-rl;
	color: rgba(251, 249, 244, .4);
}
@media (max-width: 860px) { .hero__hint { display: none; } }

/* ── living type ─────────────────────────────────────────────────────── */
.living {
	background: var(--paper);
	padding: clamp(80px, 14vh, 190px) var(--gutter);
	border-bottom: 1px solid var(--line);
}

.living__line {
	font-family: var(--react);
	font-size: clamp(42px, 9.5vw, 172px);
	line-height: .92;
	letter-spacing: -.045em;
	text-transform: uppercase;
	max-width: var(--wide);
	margin: 0 auto;
}

/* Each letter is its own span so the cursor can push weight and width into
   the ones it is near. js/type.js sets the variation settings. */
.living__line .ch {
	display: inline-block;
	font-variation-settings: 'wght' 400, 'wdth' 100;
	will-change: font-variation-settings;
}
.living__line .row--soft { color: var(--ink-soft); }
.living__line .row--teal { color: var(--teal); }

.living__swap {
	display: inline-grid;
	vertical-align: baseline;
	/* Smaller than the line it sits in, so the longest audience word still
	   fits beside "for" instead of falling to a line of its own. */
	font-size: .72em;
	overflow: hidden;
}
.living__swap b {
	grid-area: 1 / 1;
	font-weight: 800;
	color: var(--blue);
	opacity: 0;
	transform: translateY(.35em);
	transition: opacity .45s, transform .45s;
}
.living__swap b[data-on] { opacity: 1; transform: none; }

.living__foot {
	max-width: var(--wide);
	margin: clamp(28px, 5vh, 56px) auto 0;
	display: flex; flex-wrap: wrap; gap: 18px 40px; align-items: baseline;
	justify-content: space-between;
	color: var(--ink-soft);
}

/* ── proof strip ─────────────────────────────────────────────────────── */
.strip {
	background: var(--ink);
	color: var(--paper);
	padding: clamp(60px, 9vh, 120px) var(--gutter);
}
.strip__grid {
	max-width: var(--wide); margin: 0 auto;
	display: grid; gap: clamp(28px, 4vw, 60px);
	grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.strip__item h3 {
	font: 800 clamp(38px, 4.4vw, 68px)/1 var(--display);
	letter-spacing: -.04em;
	color: var(--teal);
}
.strip__item p { color: rgba(251, 249, 244, .68); margin-top: 8px; max-width: 26ch; }

/* ── footer ──────────────────────────────────────────────────────────── */
.foot {
	background: var(--ink);
	color: var(--paper);
	padding: clamp(60px, 9vh, 110px) var(--gutter) 34px;
	border-top: 1px solid rgba(251, 249, 244, .12);
}
.foot__top { max-width: var(--wide); margin: 0 auto; display: grid; gap: 14px; }
.foot__word {
	font: 800 clamp(58px, 13vw, 190px)/.85 var(--display);
	letter-spacing: -.05em;
	background: linear-gradient(96deg, var(--teal), var(--amber) 55%, var(--pink));
	-webkit-background-clip: text; background-clip: text; color: transparent;
}
.foot__line { color: rgba(251, 249, 244, .7); max-width: 46ch; }

.foot__cols {
	max-width: var(--wide); margin: clamp(40px, 6vh, 70px) auto 0;
	display: grid; gap: 30px;
	grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
.foot__cols h2 { font: 500 12px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--teal); margin-bottom: 14px; }
.foot__cols a { display: block; text-decoration: none; color: rgba(251, 249, 244, .74); padding: 5px 0; }
.foot__cols a:hover { color: var(--paper); }

.foot__base {
	max-width: var(--wide); margin: clamp(36px, 5vh, 60px) auto 0;
	padding-top: 20px; border-top: 1px solid rgba(251, 249, 244, .12);
	display: flex; flex-wrap: wrap; gap: 12px; justify-content: space-between;
	font: 400 13px/1.4 var(--mono); color: rgba(251, 249, 244, .5);
}

/* ── motion ──────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* ── typed echo ──────────────────────────────────────────────────────── */
/* What the visitor typed, repeated small under the sand so they can see the
   machine heard them. Empty and invisible until the first key. */
.hero__echo {
	position: absolute;
	left: var(--gutter); top: 44%;
	font: 500 clamp(13px, 1vw, 16px)/1 var(--mono);
	letter-spacing: .1em;
	color: var(--teal);
	opacity: 0;
	transform: translateY(6px);
	transition: opacity .3s, transform .3s;
	pointer-events: none;
}
.hero__echo[data-on] { opacity: .85; transform: none; }

/* ── the lens over the living type ───────────────────────────────────── */
.living { position: relative; overflow: hidden; }

.lens {
	position: absolute; left: 0; top: 0;
	width: clamp(120px, 15vw, 230px); aspect-ratio: 1;
	border-radius: 50%;
	background: var(--paper);
	mix-blend-mode: difference;
	opacity: 0;
	transition: opacity .25s;
	pointer-events: none;
	z-index: 2;
}
.lens[data-on] { opacity: 1; }

/* ── route 254 ───────────────────────────────────────────────────────── */
.route {
	--p: 0;
	height: 320vh;           /* the scroll distance the matatu travels */
	background: var(--ink);
	color: var(--paper);
}

.route__stage {
	position: sticky; top: 0;
	height: 100svh;
	display: grid;
	grid-template-rows: auto 1fr;
	gap: clamp(20px, 4vh, 48px);
	align-content: center;
	padding: clamp(70px, 10vh, 120px) var(--gutter) clamp(50px, 9vh, 90px);
	overflow: hidden;
}

.route__head { max-width: var(--wide); width: 100%; margin: 0 auto; display: grid; gap: 10px; }
.route__head .label { color: var(--amber); }
.route__head h2 {
	font: 800 clamp(34px, 5.2vw, 84px)/.95 var(--display);
	letter-spacing: -.04em;
}
.route__sub { color: rgba(251, 249, 244, .7); max-width: 46ch; }

.route__road { position: relative; width: 100%; max-width: var(--wide); margin: 0 auto; }

/* The tarmac, with the dashes crawling as the matatu moves. */
.route__tarmac {
	position: absolute; left: 0; right: 0; top: 50%;
	height: 6px; border-radius: 99px;
	background:
		repeating-linear-gradient(90deg, rgba(251, 249, 244, .55) 0 26px, transparent 26px 60px);
	background-position: calc(var(--p) * -300px) 0;
	box-shadow: 0 26px 60px rgba(0, 0, 0, .6);
}
.route__tarmac::before {
	content: '';
	position: absolute; inset: -14px 0 auto 0; height: 3px;
	background: linear-gradient(90deg, var(--teal), var(--amber), var(--pink));
	opacity: .5;
	transform-origin: left;
	transform: scaleX(var(--p));
}

.route__stops {
	position: relative;
	list-style: none;
	height: 100%;
	margin: 0;
}

.route__stop {
	position: absolute;
	left: var(--at);
	top: 50%;
	width: clamp(150px, 15vw, 210px);
	transform: translate(-50%, 26px);
	text-align: center;
	opacity: .32;
	transition: opacity .4s, transform .4s;
}
.route__stop[data-passed] { opacity: 1; transform: translate(-50%, 18px); }
.route__stop h3 {
	font: 700 clamp(17px, 1.6vw, 24px)/1.1 var(--display);
	letter-spacing: -.02em;
	margin-top: 16px;
}
.route__stop p { font-size: clamp(12px, .9vw, 14px); color: rgba(251, 249, 244, .66); margin-top: 6px; }

.route__pin {
	position: absolute; left: 50%; top: -12px;
	width: 14px; height: 14px; border-radius: 50%;
	transform: translate(-50%, -50%);
	background: var(--ink);
	border: 3px solid rgba(251, 249, 244, .5);
}
.route__stop[data-passed] .route__pin {
	background: var(--teal);
	border-color: var(--teal);
	box-shadow: 0 0 0 8px rgba(0, 217, 184, .16);
}

/* First and last stop keep their labels inside the road rather than off the
   edge of the screen. */
.route__stop:first-child { text-align: left; transform: translate(-12px, 26px); }
.route__stop:first-child[data-passed] { transform: translate(-12px, 18px); }
.route__stop:first-child .route__pin { left: 12px; }
.route__stop:last-child { text-align: right; transform: translate(calc(-100% + 12px), 26px); }
.route__stop:last-child[data-passed] { transform: translate(calc(-100% + 12px), 18px); }
.route__stop:last-child .route__pin { left: calc(100% - 12px); }

.route__bus {
	position: absolute;
	top: 50%;
	left: clamp(0px, calc(var(--p) * 100%), 100%);
	width: clamp(120px, 14vw, 200px);
	/* The wheels sit on the tarmac rather than hovering over it: the SVG's
	   wheel bottoms are at 92% of its height. */
	transform: translate(-50%, -92%) rotate(var(--tilt, 0deg));
	filter: drop-shadow(0 18px 24px rgba(0, 0, 0, .55));
	will-change: left, transform;
}
.route__bus svg { width: 100%; height: auto; }
.route__wheel { transform-box: fill-box; transform-origin: center; animation: roll 1.1s linear infinite; }
@keyframes roll { to { transform: rotate(360deg); } }

@media (max-width: 860px) {
	.route { height: 300vh; }
	.route__stop p { display: none; }
	.route__stop { width: 110px; }
}

/* ── the desk ────────────────────────────────────────────────────────── */
/* A top down desk you can throw things around on. Physics in js/desk.js;
   everything here is the look of the objects and the surface they slide on. */
.desk {
	background: linear-gradient(176deg, #f3ece0, #e9dfcd);
	color: var(--ink);
	padding: clamp(60px, 9vh, 110px) var(--gutter) clamp(40px, 6vh, 70px);
	border-bottom: 1px solid rgba(10, 10, 15, .12);
}

.desk__head {
	max-width: var(--wide); margin: 0 auto clamp(24px, 4vh, 44px);
	display: grid; gap: 10px; justify-items: start;
}
.desk__head .label { color: #a8642a; }
.desk__head h2 {
	font: 800 clamp(34px, 5.2vw, 84px)/.95 var(--display);
	letter-spacing: -.04em;
}
.desk__sub { color: #5b5346; max-width: 46ch; }

.desk__shuffle {
	margin-top: 8px;
	font: 500 13px/1 var(--mono);
	letter-spacing: .12em; text-transform: uppercase;
	background: var(--ink); color: var(--paper);
	border: 0; border-radius: 999px;
	padding: 13px 22px;
	cursor: pointer;
	transition: transform .2s, background .2s;
}
.desk__shuffle:hover { transform: rotate(-2deg) scale(1.04); background: #22222c; }

.desk__surface {
	position: relative;
	max-width: var(--wide);
	margin: 0 auto;
	height: clamp(460px, 76vh, 700px);
	border-radius: 24px;
	background:
		radial-gradient(120% 90% at 20% 0%, rgba(255, 255, 255, .55), transparent 60%),
		repeating-linear-gradient(91deg, rgba(150, 110, 60, .05) 0 3px, transparent 3px 9px),
		linear-gradient(160deg, #e5d8c1, #d9c9ac);
	box-shadow: inset 0 2px 0 rgba(255, 255, 255, .6), inset 0 -30px 60px rgba(120, 88, 48, .18);
	overflow: hidden;
	touch-action: none; /* dragging a thing must not scroll the page */
}

/* Every object on the desk. Position comes from a transform set in JS, so
   nothing here may set left/top. */
.thing {
	position: absolute; left: 0; top: 0;
	display: grid;
	gap: 6px;
	padding: 10px;
	text-decoration: none;
	color: var(--ink);
	cursor: grab;
	user-select: none;
	-webkit-user-drag: none;
	box-shadow: 0 10px 22px rgba(80, 55, 20, .28);
	transition: box-shadow .2s, filter .2s;
	will-change: transform;
}
.thing:hover { filter: brightness(1.03); box-shadow: 0 16px 30px rgba(80, 55, 20, .34); }
.thing--held { cursor: grabbing; box-shadow: 0 26px 46px rgba(60, 40, 12, .42); z-index: 5; }
.thing__cap { font: 500 11px/1.2 var(--mono); letter-spacing: .04em; color: #4a4336; }

/* Polaroid and the safari print */
.thing--polaroid, .thing--safari {
	width: clamp(140px, 15vw, 186px);
	background: #fffdf7;
	padding: 11px 11px 14px;
	border-radius: 3px;
}
.thing__shot {
	display: block; aspect-ratio: 1.12;
	border-radius: 2px;
	background: linear-gradient(145deg, #06221f, #0a0a0f 55%, #2a1330);
	box-shadow: inset 0 0 40px rgba(0, 217, 184, .35);
}
.thing__shot--sand { background: linear-gradient(160deg, #e8a13c, #b4541f 60%, #3c2410); box-shadow: inset 0 0 30px rgba(255, 220, 160, .4); }

/* Phone */
.thing--phone {
	width: clamp(96px, 10vw, 124px);
	background: #14141c;
	border-radius: 16px;
	padding: 9px 9px 11px;
	border: 2px solid #2b2b38;
}
.thing--phone .thing__cap { color: rgba(251, 249, 244, .6); text-align: center; }
.thing__screen {
	display: grid; place-items: center; gap: 8px;
	aspect-ratio: .52; border-radius: 9px;
	background: radial-gradient(70% 50% at 50% 38%, rgba(0, 217, 184, .3), #07070c 70%);
}
.thing__orb {
	width: 34px; height: 34px; border-radius: 50%;
	background: radial-gradient(circle at 38% 34%, #b8fff3, var(--teal) 55%, #036c5c);
	box-shadow: 0 0 22px rgba(0, 217, 184, .8);
}
.thing__wave {
	width: 46px; height: 12px;
	background: repeating-linear-gradient(90deg, var(--teal) 0 3px, transparent 3px 7px);
	opacity: .65;
	mask-image: linear-gradient(90deg, transparent, #000 30%, #000 70%, transparent);
}

/* Matatu route board */
.thing--board {
	width: clamp(150px, 16vw, 200px);
	background: linear-gradient(#ffd400, #f5b800);
	border-radius: 6px;
	padding: 10px 12px 12px;
	border: 3px solid #14141c;
	text-align: center;
}
.thing__no { font: 800 clamp(26px, 3vw, 38px)/1 var(--display); letter-spacing: -.02em; }
.thing__route { font: 500 10px/1.3 var(--mono); letter-spacing: .08em; text-transform: uppercase; }

/* M-PESA sticker */
.thing--mpesa {
	width: clamp(104px, 11vw, 132px);
	background: #14a54a;
	color: #fff;
	border-radius: 50% 50% 48% 52%;
	padding: 20px 14px;
	text-align: center;
	font: 500 12px/1.3 var(--mono);
	letter-spacing: .06em;
	border: 2px dashed rgba(255, 255, 255, .55);
}
.thing--mpesa b { font-size: 15px; letter-spacing: .04em; }

/* Sticky note */
.thing--note {
	width: clamp(120px, 12vw, 150px);
	aspect-ratio: 1;
	display: grid; place-items: center;
	background: linear-gradient(#fff4a3, #ffe86a);
	font: 400 clamp(13px, 1.1vw, 16px)/1.35 'Bricolage Grotesque', cursive;
	text-align: center;
	box-shadow: 0 12px 18px rgba(120, 95, 20, .3);
}

/* Business card */
.thing--card {
	width: clamp(150px, 15vw, 186px);
	background: #0a0a0f;
	color: var(--paper);
	border-radius: 4px;
	padding: 14px 15px;
}
.thing--card b { font: 700 15px/1.2 var(--display); }
.thing--card span { font: 400 10px/1.3 var(--mono); color: var(--teal); letter-spacing: .06em; }

/* Conference ops checklist */
.thing--ops {
	width: clamp(120px, 13vw, 158px);
	background: #ddf7ec;
	border-radius: 4px;
	padding: 14px 13px 12px;
	border-left: 5px solid #17a97f;
}
.thing__tick { font: 600 15px/1 var(--mono); color: #17a97f; letter-spacing: .3em; }

@media (max-width: 720px) {
	.desk__surface { height: clamp(420px, 68vh, 560px); }
	.thing--polaroid, .thing--safari { width: 116px; }
	.thing--board { width: 124px; }
	.thing--note { width: 96px; }
	.thing--card { width: 132px; }
	.thing--ops { width: 108px; }
	.thing--mpesa { width: 92px; font-size: 11px; }
}
