/*
 * profile.css — landing page only, loaded via `extra.styles` in content/_index.md.
 *
 * The page states that it is about control systems, so it also demonstrates one:
 * the hero plot is the analytic step response of an underdamped second-order
 * system (zeta = 0.30), the same shape as the PID plots in Labs 5-7, and it draws
 * itself once on load.
 *
 * Colours come from the theme's custom properties, so light and dark both follow.
 * All motion is disabled under prefers-reduced-motion.
 */

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

.hero {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
	align-items: center;
	gap: 2rem 3rem;
	margin-block: 0.5rem 2rem;
}

.hero-name {
	margin: 0;
	font-size: clamp(2.25rem, 6vw, 3.5rem);
	line-height: 1.02;
	letter-spacing: -0.02em;
}

.hero .profile-links {
	display: flex;
	align-items: center;
	gap: 0.625rem;
	margin-block-start: 0.875rem;
}

.hero .profile-links a {
	display: inline-flex;
	transition: var(--transition);
	color: var(--accent-color);
}

.hero .profile-links a:hover {
	transform: translateY(-2px);
}

.hero .profile-links svg {
	fill: currentColor;
	width: 1.625rem;
	height: 1.625rem;
}

.hero-tagline {
	margin-block: 1.125rem 0;
	max-width: 32ch;
	color: var(--fg-muted-5);
	font-size: var(--font-size-large);
	line-height: 1.45;
	text-wrap: balance;
}

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

.hero-rig {
	margin: 0;
}

.hero-rig svg {
	display: block;
	width: 100%;
	height: auto;
	overflow: visible;
}

.rig-rail {
	stroke: var(--fg-muted-3);
	stroke-width: 2;
	stroke-linecap: round;
}

.rig-pole {
	stroke: var(--accent-color);
	stroke-width: 5;
	stroke-linecap: round;
}

.rig-bob {
	fill: var(--accent-color);
}

.rig-body {
	fill: var(--fg-muted-4);
}

.rig-wheel {
	fill: var(--fg-muted-3);
}

/* The pole pivots about the point it meets the cart: bottom-centre of its own
   box, which fill-box resolves against. */
.rig-arm {
	transform-box: fill-box;
	transform-origin: 50% 100%;
}

/* Trajectories are a real simulation baked into keyframes (see the generated
   block below), so the motion is physically true at zero runtime cost. */
.profile-js .rig-cart {
	animation: cart-balance 6s linear infinite;
}

.profile-js .rig-arm {
	animation: pole-balance 6s linear infinite;
}

.hero-rig figcaption {
	margin-block-start: 0.875rem;
	color: var(--fg-muted-5);
	font-size: var(--font-size-small);
	line-height: 1.5;
}

/* GENERATED-KEYFRAMES-START */
@keyframes cart-balance {
	0.00% { transform: translateX(0.0px); }
	0.93% { transform: translateX(4.0px); }
	1.85% { transform: translateX(14.6px); }
	2.78% { transform: translateX(29.2px); }
	3.71% { transform: translateX(45.1px); }
	4.63% { transform: translateX(60.3px); }
	5.56% { transform: translateX(73.7px); }
	6.49% { transform: translateX(84.9px); }
	7.41% { transform: translateX(93.9px); }
	8.34% { transform: translateX(100.7px); }
	9.27% { transform: translateX(105.6px); }
	10.20% { transform: translateX(109.1px); }
	11.12% { transform: translateX(111.3px); }
	12.05% { transform: translateX(112.6px); }
	12.98% { transform: translateX(113.2px); }
	13.90% { transform: translateX(113.2px); }
	14.83% { transform: translateX(112.8px); }
	15.76% { transform: translateX(112.0px); }
	16.68% { transform: translateX(110.9px); }
	17.61% { transform: translateX(109.5px); }
	18.54% { transform: translateX(107.8px); }
	19.46% { transform: translateX(105.9px); }
	20.39% { transform: translateX(103.7px); }
	21.32% { transform: translateX(101.3px); }
	22.24% { transform: translateX(98.7px); }
	23.17% { transform: translateX(95.9px); }
	24.10% { transform: translateX(92.9px); }
	25.02% { transform: translateX(89.8px); }
	25.95% { transform: translateX(86.6px); }
	26.88% { transform: translateX(83.3px); }
	27.80% { transform: translateX(80.0px); }
	28.73% { transform: translateX(76.6px); }
	29.66% { transform: translateX(73.2px); }
	30.59% { transform: translateX(69.8px); }
	31.51% { transform: translateX(66.4px); }
	32.44% { transform: translateX(63.0px); }
	33.37% { transform: translateX(59.6px); }
	34.29% { transform: translateX(56.3px); }
	35.22% { transform: translateX(53.0px); }
	36.15% { transform: translateX(49.8px); }
	37.07% { transform: translateX(46.7px); }
	38.00% { transform: translateX(43.6px); }
	38.93% { transform: translateX(40.6px); }
	39.85% { transform: translateX(37.7px); }
	40.78% { transform: translateX(34.9px); }
	41.71% { transform: translateX(32.2px); }
	42.63% { transform: translateX(29.6px); }
	43.56% { transform: translateX(27.1px); }
	44.49% { transform: translateX(24.7px); }
	45.41% { transform: translateX(22.4px); }
	46.34% { transform: translateX(20.2px); }
	47.27% { transform: translateX(18.2px); }
	48.20% { transform: translateX(16.2px); }
	49.12% { transform: translateX(14.3px); }
	50.05% { transform: translateX(12.5px); }
	50.98% { transform: translateX(10.8px); }
	51.90% { transform: translateX(9.2px); }
	52.83% { transform: translateX(7.8px); }
	53.76% { transform: translateX(6.4px); }
	54.68% { transform: translateX(5.1px); }
	55.61% { transform: translateX(3.9px); }
	56.54% { transform: translateX(2.8px); }
	57.46% { transform: translateX(1.7px); }
	58.39% { transform: translateX(0.8px); }
	59.32% { transform: translateX(-0.1px); }
	60.24% { transform: translateX(-0.9px); }
	61.17% { transform: translateX(-1.6px); }
	62.10% { transform: translateX(-2.3px); }
	63.02% { transform: translateX(-2.9px); }
	63.95% { transform: translateX(-3.4px); }
	64.88% { transform: translateX(-3.9px); }
	65.80% { transform: translateX(-4.3px); }
	66.73% { transform: translateX(-4.7px); }
	67.66% { transform: translateX(-5.0px); }
	68.59% { transform: translateX(-5.3px); }
	69.51% { transform: translateX(-5.5px); }
	70.44% { transform: translateX(-5.7px); }
	71.37% { transform: translateX(-5.8px); }
	72.29% { transform: translateX(-5.9px); }
	73.22% { transform: translateX(-6.0px); }
	74.15% { transform: translateX(-6.0px); }
	75.07% { transform: translateX(-6.0px); }
	76.00% { transform: translateX(-6.0px); }
	100% { transform: translateX(-6.0px); }
}

@keyframes pole-balance {
	0.00% { transform: rotate(0.42deg); }
	0.93% { transform: rotate(3.94deg); }
	1.85% { transform: rotate(3.23deg); }
	2.78% { transform: rotate(-0.04deg); }
	3.71% { transform: rotate(-4.11deg); }
	4.63% { transform: rotate(-7.91deg); }
	5.56% { transform: rotate(-10.9deg); }
	6.49% { transform: rotate(-12.9deg); }
	7.41% { transform: rotate(-13.96deg); }
	8.34% { transform: rotate(-14.22deg); }
	9.27% { transform: rotate(-13.89deg); }
	10.20% { transform: rotate(-13.15deg); }
	11.12% { transform: rotate(-12.18deg); }
	12.05% { transform: rotate(-11.11deg); }
	12.98% { transform: rotate(-10.05deg); }
	13.90% { transform: rotate(-9.04deg); }
	14.83% { transform: rotate(-8.12deg); }
	15.76% { transform: rotate(-7.3deg); }
	16.68% { transform: rotate(-6.57deg); }
	17.61% { transform: rotate(-5.92deg); }
	18.54% { transform: rotate(-5.33deg); }
	19.46% { transform: rotate(-4.79deg); }
	20.39% { transform: rotate(-4.29deg); }
	21.32% { transform: rotate(-3.82deg); }
	22.24% { transform: rotate(-3.38deg); }
	23.17% { transform: rotate(-2.96deg); }
	24.10% { transform: rotate(-2.57deg); }
	25.02% { transform: rotate(-2.19deg); }
	25.95% { transform: rotate(-1.84deg); }
	26.88% { transform: rotate(-1.5deg); }
	27.80% { transform: rotate(-1.19deg); }
	28.73% { transform: rotate(-0.9deg); }
	29.66% { transform: rotate(-0.63deg); }
	30.59% { transform: rotate(-0.38deg); }
	31.51% { transform: rotate(-0.15deg); }
	32.44% { transform: rotate(0.07deg); }
	33.37% { transform: rotate(0.26deg); }
	34.29% { transform: rotate(0.43deg); }
	35.22% { transform: rotate(0.59deg); }
	36.15% { transform: rotate(0.74deg); }
	37.07% { transform: rotate(0.86deg); }
	38.00% { transform: rotate(0.98deg); }
	38.93% { transform: rotate(1.08deg); }
	39.85% { transform: rotate(1.16deg); }
	40.78% { transform: rotate(1.24deg); }
	41.71% { transform: rotate(1.3deg); }
	42.63% { transform: rotate(1.35deg); }
	43.56% { transform: rotate(1.39deg); }
	44.49% { transform: rotate(1.43deg); }
	45.41% { transform: rotate(1.45deg); }
	46.34% { transform: rotate(1.47deg); }
	47.27% { transform: rotate(1.48deg); }
	48.20% { transform: rotate(1.48deg); }
	49.12% { transform: rotate(1.48deg); }
	50.05% { transform: rotate(1.47deg); }
	50.98% { transform: rotate(1.45deg); }
	51.90% { transform: rotate(1.43deg); }
	52.83% { transform: rotate(1.41deg); }
	53.76% { transform: rotate(1.38deg); }
	54.68% { transform: rotate(1.35deg); }
	55.61% { transform: rotate(1.31deg); }
	56.54% { transform: rotate(1.28deg); }
	57.46% { transform: rotate(1.24deg); }
	58.39% { transform: rotate(1.2deg); }
	59.32% { transform: rotate(1.16deg); }
	60.24% { transform: rotate(1.12deg); }
	61.17% { transform: rotate(1.07deg); }
	62.10% { transform: rotate(1.03deg); }
	63.02% { transform: rotate(0.98deg); }
	63.95% { transform: rotate(0.94deg); }
	64.88% { transform: rotate(0.89deg); }
	65.80% { transform: rotate(0.85deg); }
	66.73% { transform: rotate(0.8deg); }
	67.66% { transform: rotate(0.76deg); }
	68.59% { transform: rotate(0.72deg); }
	69.51% { transform: rotate(0.67deg); }
	70.44% { transform: rotate(0.63deg); }
	71.37% { transform: rotate(0.59deg); }
	72.29% { transform: rotate(0.55deg); }
	73.22% { transform: rotate(0.51deg); }
	74.15% { transform: rotate(0.47deg); }
	75.07% { transform: rotate(0.44deg); }
	76.00% { transform: rotate(0.4deg); }
	100% { transform: rotate(0.4deg); }
}
/* GENERATED-KEYFRAMES-END */

/* ------------------------------------------------------------ spec strip ---- */

.spec-strip {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 0.75rem;
	margin-block: 0 2.5rem;
	border-block: max(1px, 0.0625rem) solid var(--fg-muted-2);
	padding: 0.875rem 0;
	list-style: none;
}

.spec-strip li {
	color: var(--fg-muted-5);
	font-size: var(--font-size-x-small);
	font-family: var(--font-monospace, ui-monospace, monospace);
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.spec-strip li + li::before {
	margin-inline-end: 0.75rem;
	color: var(--fg-muted-3);
	content: "/";
}

/* --------------------------------------------------------------- profile ---- */

.profile {
	display: grid;
	grid-template-columns: minmax(0, 16rem) minmax(0, 1fr);
	align-items: start;
	gap: 2rem;
	margin-block-end: 3rem;
}

.profile-photo img {
	display: block;
	transition: var(--transition);
	box-shadow: var(--shadow-glass, 0 1rem 2rem rgb(0 0 0 / 0.12));
	border-radius: var(--rounded-corner);
	width: 100%;
	height: auto;
}

.profile-bio p:first-child {
	margin-block-start: 0;
}

.org-logos {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1.75rem;
	margin-block-start: 1.75rem;
}

.org-logos a {
	display: inline-flex;
	transition: var(--transition);
}

.org-logos a:hover {
	transform: translateY(-3px);
}

.org-logos img {
	border: none;
	box-shadow: none;
	background-color: transparent;
	width: auto;
	max-width: 100%;
	height: 5.5rem;
}

/* -------------------------------------------------------------- timeline ---- */

.lab-index-heading {
	margin-block: 0 1.5rem;
}

.lab-timeline {
	position: relative;
	margin: 0;
	padding: 0 0 0 2.4rem;
	list-style: none;
}

/* The spine. Sits behind the markers, inset so it starts and ends on a dot. */
.lab-timeline::before {
	position: absolute;
	inset-block: 0.9rem 1.1rem;
	inset-inline-start: 0.6875rem;
	background: linear-gradient(
		to bottom,
		var(--accent-color),
		var(--fg-muted-2)
	);
	width: max(2px, 0.125rem);
	content: "";
}

.lab-timeline-item {
	position: relative;
	padding-block: 0.5rem 1.375rem;
}

.lab-timeline-marker {
	display: flex;
	position: absolute;
	align-items: center;
	justify-content: center;
	inset-block-start: 0.4rem;
	inset-inline-start: -2.4rem;
	transition: var(--transition);
	box-shadow: 0 0 0 max(4px, 0.25rem) var(--bg-color);
	border-radius: 999px;
	background-color: var(--fg-muted-2);
	width: 1.75rem;
	height: 1.75rem;
	color: var(--fg-color);
	font-weight: 700;
	font-size: var(--font-size-x-small);
	font-variant-numeric: tabular-nums;
	line-height: 1;
}

.lab-timeline-item:hover .lab-timeline-marker {
	background-color: var(--accent-color);
	color: var(--contrast-color);
}

.lab-timeline-date {
	display: block;
	margin-block-end: 0.125rem;
	color: var(--fg-muted-4);
	font-size: var(--font-size-x-small);
	font-family: var(--font-monospace, ui-monospace, monospace);
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.lab-timeline-title {
	font-weight: 600;
	font-size: var(--font-size-large);
	text-decoration: none;
}

.lab-timeline-title:hover {
	text-decoration: underline;
}

.lab-timeline-description {
	margin-block: 0.25rem 0;
	max-width: 60ch;
	color: var(--fg-muted-5);
	font-size: var(--font-size-small);
}

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

/* Only armed once profile.js has confirmed it is running, so a failed script
   can never leave the page blank. */
.profile-js .reveal {
	opacity: 0;
	transform: translateY(1.25rem);
}

.profile-js .reveal.is-visible {
	transition:
		opacity 0.6s ease-out,
		transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
	opacity: 1;
	transform: none;
}

/* Stagger consecutive timeline rows slightly as a group scrolls in. */
.profile-js .lab-timeline-item:nth-child(2n).is-visible {
	transition-delay: 0.06s;
}

.profile-js .lab-timeline-item:nth-child(2n + 1).is-visible {
	transition-delay: 0.12s;
}

/* ------------------------------------------------------------ responsive ---- */

@media only screen and (max-width: 900px) {
	.hero {
		grid-template-columns: minmax(0, 1fr);
		gap: 1.5rem;
	}

	.hero-tagline {
		max-width: none;
	}

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

	.profile-photo {
		max-width: 14rem;
	}

	.lab-timeline {
		padding-inline-start: 2.1rem;
	}

	.lab-timeline-marker {
		inset-inline-start: -2.1rem;
	}
}

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

@media (prefers-reduced-motion: reduce) {
	.profile-js .rig-cart,
	.profile-js .rig-arm {
		animation: none;
	}

	.org-logos a:hover {
		transform: none;
	}

	.profile-js .reveal,
	.profile-js .reveal.is-visible {
		transition: none;
		opacity: 1;
		transform: none;
	}

	.hero .profile-links a:hover {
		transform: none;
	}
}
