/* ==========================================================================
   Vladyslav Kryklyvenko — portfolio
   Hand-written CSS. No framework, no build step.
   Sections: tokens, reset, primitives, layout, components, motion, responsive
   ========================================================================== */

/* --- Fonts: self-hosted, no third-party requests -------------------------- */
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 100 900;
	font-display: swap;
	src: url('../fonts/inter-latin.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
		U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 100 900;
	font-display: swap;
	src: url('../fonts/inter-latin-ext.woff2') format('woff2');
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
		U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
		U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
	font-family: 'JetBrains Mono';
	font-style: normal;
	font-weight: 400 700;
	font-display: swap;
	src: url('../fonts/jetbrains-mono-latin.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
		U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
	font-family: 'JetBrains Mono';
	font-style: normal;
	font-weight: 400 700;
	font-display: swap;
	src: url('../fonts/jetbrains-mono-latin-ext.woff2') format('woff2');
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
		U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
		U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --- Design tokens -------------------------------------------------------- */
:root {
	/* Surfaces, from deepest to most elevated */
	--bg: #08090b;
	--bg-soft: #0b0d11;
	--surface: #101319;
	--surface-2: #161a22;
	--line: #1e232d;
	--line-strong: #2b323f;

	/* Text — all pairs verified at 4.5:1+ against --bg */
	--text: #e9ecf1;
	--text-dim: #a7afbd;
	--text-faint: #7c8595;

	/* Accent */
	--accent: #4f7dff;
	--accent-soft: #8caaff;
	/* Darker fill so white button labels clear 4.5:1 (4.75:1) — the lighter
	   --accent stays for text, links and borders on the dark background */
	--accent-btn: #3a68f0;
	--accent-wash: rgba(79, 125, 255, 0.12);
	--accent-line: rgba(79, 125, 255, 0.35);

	--danger: #ff6b6b;
	--success: #4ade80;

	/* Type scale — fluid, 4pt-aligned at the ends */
	--step--1: clamp(0.82rem, 0.79rem + 0.14vw, 0.89rem);
	--step-0: clamp(1rem, 0.96rem + 0.18vw, 1.09rem);
	--step-1: clamp(1.2rem, 1.12rem + 0.38vw, 1.44rem);
	--step-2: clamp(1.45rem, 1.3rem + 0.72vw, 1.9rem);
	--step-3: clamp(1.75rem, 1.48rem + 1.3vw, 2.5rem);
	--step-4: clamp(2.1rem, 1.61rem + 2.4vw, 3.5rem);
	--step-5: clamp(2.6rem, 1.6rem + 4.6vw, 5.25rem);

	/* Spacing — 4pt rhythm */
	--sp-1: 0.25rem;
	--sp-2: 0.5rem;
	--sp-3: 0.75rem;
	--sp-4: 1rem;
	--sp-5: 1.5rem;
	--sp-6: 2rem;
	--sp-7: 3rem;
	--sp-8: 4rem;
	--sp-9: 6rem;
	--sp-10: 8rem;

	--radius-sm: 8px;
	--radius: 14px;
	--radius-lg: 20px;

	--container: 1180px;
	--gutter: clamp(1.25rem, 4vw, 3rem);

	--ease: cubic-bezier(0.22, 0.61, 0.36, 1);
	--dur: 220ms;

	--z-nav: 100;
	--z-toast: 1000;

	--shadow-card: 0 1px 2px rgba(0, 0, 0, 0.5), 0 12px 32px -16px rgba(0, 0, 0, 0.8);
	--shadow-lift: 0 2px 4px rgba(0, 0, 0, 0.5), 0 24px 56px -20px rgba(0, 0, 0, 0.9);
}

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

html {
	scroll-behavior: smooth;
	/* Keep anchored headings clear of the sticky nav */
	scroll-padding-top: 5.5rem;
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	background: var(--bg);
	color: var(--text);
	font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
	font-size: var(--step-0);
	line-height: 1.65;
	font-feature-settings: 'cv11', 'ss01';
	-webkit-font-smoothing: antialiased;
	overflow-x: hidden;
}

h1, h2, h3, h4 {
	margin: 0;
	line-height: 1.1;
	letter-spacing: -0.022em;
	font-weight: 600;
	text-wrap: balance;
}

p { margin: 0; text-wrap: pretty; }
ul, ol { margin: 0; padding: 0; list-style: none; }

img, svg { display: block; max-width: 100%; }
img { height: auto; }

a { color: var(--accent-soft); text-decoration: none; }
a:hover { color: var(--text); }

button, input, textarea { font: inherit; color: inherit; }

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

::selection { background: var(--accent); color: #fff; }

/* --- Primitives ----------------------------------------------------------- */
.container {
	width: 100%;
	max-width: var(--container);
	margin-inline: auto;
	padding-inline: var(--gutter);
}

.skip-link {
	position: absolute;
	left: var(--sp-4);
	top: -100%;
	z-index: calc(var(--z-nav) + 1);
	padding: var(--sp-3) var(--sp-4);
	background: var(--accent-btn);
	color: #fff;
	border-radius: var(--radius-sm);
	font-weight: 600;
}
.skip-link:focus { top: var(--sp-4); color: #fff; }

.mono {
	font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
	font-feature-settings: 'zero';
}

.eyebrow {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
	font-family: 'JetBrains Mono', ui-monospace, monospace;
	font-size: var(--step--1);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--text-faint);
}
.eyebrow--accent { color: var(--accent-soft); }

.section { padding-block: clamp(4rem, 9vw, 7.5rem); position: relative; }
.section + .section { border-top: 1px solid var(--line); }

.section__head { max-width: 62ch; margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.section__title { font-size: var(--step-3); margin-block: var(--sp-4) var(--sp-4); }
.section__lead { color: var(--text-dim); font-size: var(--step-1); line-height: 1.55; }

.accent { color: var(--accent-soft); }

.gradient-text {
	background: linear-gradient(100deg, var(--text) 10%, var(--accent-soft) 55%, var(--accent) 95%);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

/* --- Buttons -------------------------------------------------------------- */
.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--sp-2);
	/* Keeps the tap target at 48px without relying on line-height */
	min-height: 48px;
	padding: var(--sp-3) var(--sp-5);
	border: 1px solid transparent;
	border-radius: 999px;
	font-size: var(--step-0);
	font-weight: 550;
	cursor: pointer;
	text-align: center;
	transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
		color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.btn:active { transform: scale(0.98); }

.btn--primary {
	background: var(--accent-btn);
	color: #fff;
	box-shadow: 0 8px 24px -12px var(--accent);
}
/* Hover lifts and glows instead of lightening, which would drop the label
   below the contrast floor */
.btn--primary:hover {
	background: var(--accent-btn);
	color: #fff;
	box-shadow: 0 12px 30px -10px var(--accent);
	transform: translateY(-1px);
}
.btn--primary:active { transform: translateY(0) scale(0.98); }

.btn--ghost {
	border-color: var(--line-strong);
	background: transparent;
	color: var(--text);
}
.btn--ghost:hover { border-color: var(--accent-line); background: var(--accent-wash); color: var(--text); }

.btn[disabled] { opacity: 0.45; cursor: not-allowed; transform: none; }

/* --- Icons ---------------------------------------------------------------- */
/* Icon sprite: out of flow without an inline style attribute, which the CSP blocks */
.sprite { position: absolute; }

.icon { width: 1.25em; height: 1.25em; flex: none; stroke-width: 1.6; }

/* --- Navigation ----------------------------------------------------------- */
.nav {
	position: sticky;
	top: 0;
	z-index: var(--z-nav);
	background: color-mix(in srgb, var(--bg) 78%, transparent);
	backdrop-filter: blur(14px) saturate(140%);
	-webkit-backdrop-filter: blur(14px) saturate(140%);
	border-bottom: 1px solid transparent;
	transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.nav.is-stuck { border-bottom-color: var(--line); }

.nav__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-5);
	min-height: 68px;
}

.nav__brand {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-3);
	color: var(--text);
	font-weight: 600;
	letter-spacing: -0.01em;
}
.nav__mark {
	display: grid;
	place-items: center;
	width: 34px;
	height: 34px;
	border-radius: 10px;
	background: linear-gradient(140deg, var(--accent-btn), #2748b8);
	color: #fff;
	font-family: 'JetBrains Mono', monospace;
	font-size: 0.8rem;
	font-weight: 700;
	letter-spacing: -0.03em;
}

.nav__links { display: flex; align-items: center; gap: var(--sp-1); }
.nav__link {
	display: inline-block;
	padding: var(--sp-2) var(--sp-3);
	border-radius: var(--radius-sm);
	color: var(--text-dim);
	font-size: var(--step--1);
	transition: color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.nav__link:hover { color: var(--text); background: var(--surface); }
.nav__link[aria-current='true'] { color: var(--accent-soft); }

.nav__cta { display: none; }

/* --- Hero ----------------------------------------------------------------- */
.hero {
	position: relative;
	padding-block: clamp(4rem, 12vw, 9rem) clamp(4rem, 9vw, 7rem);
	overflow: hidden;
}

/* Layered glow + grid, purely CSS so there is no hero image to download */
.hero__bg {
	position: absolute;
	inset: -20% -10% auto;
	height: 130%;
	pointer-events: none;
	background:
		radial-gradient(52rem 32rem at 18% 8%, rgba(79, 125, 255, 0.2), transparent 62%),
		radial-gradient(38rem 26rem at 88% 4%, rgba(120, 80, 255, 0.14), transparent 65%);
}
.hero__grid {
	position: absolute;
	inset: 0;
	pointer-events: none;
	background-image:
		linear-gradient(to right, rgba(255, 255, 255, 0.045) 1px, transparent 1px),
		linear-gradient(to bottom, rgba(255, 255, 255, 0.045) 1px, transparent 1px);
	background-size: 72px 72px;
	mask-image: radial-gradient(60% 55% at 50% 0%, #000 0%, transparent 100%);
	-webkit-mask-image: radial-gradient(60% 55% at 50% 0%, #000 0%, transparent 100%);
}

.hero__inner { position: relative; }

.status {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
	padding: var(--sp-2) var(--sp-4);
	border: 1px solid var(--line-strong);
	border-radius: 999px;
	background: var(--surface);
	font-family: 'JetBrains Mono', monospace;
	font-size: var(--step--1);
	color: var(--text-dim);
}
.status__dot {
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--success);
	box-shadow: 0 0 0 3px rgba(74, 222, 128, 0.18);
	animation: pulse 2.4s var(--ease) infinite;
}

.hero__name {
	margin-top: var(--sp-6);
	font-family: 'JetBrains Mono', monospace;
	font-size: var(--step--1);
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--text-faint);
}

.hero__title {
	margin-top: var(--sp-4);
	font-size: var(--step-5);
	font-weight: 620;
	letter-spacing: -0.035em;
	max-width: 15ch;
}

.hero__lead {
	margin-top: var(--sp-5);
	max-width: 60ch;
	font-size: var(--step-1);
	color: var(--text-dim);
	line-height: 1.6;
}

.hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-3);
	margin-top: var(--sp-7);
}

.stats {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	gap: var(--sp-1);
	margin-top: clamp(3rem, 7vw, 5rem);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: linear-gradient(180deg, var(--surface), var(--bg-soft));
	overflow: hidden;
}
/* column-reverse so the <dd> value renders above its <dt> label
   while the markup keeps the semantic dt → dd order */
.stat {
	display: flex;
	flex-direction: column-reverse;
	padding: var(--sp-5);
	border-right: 1px solid var(--line);
}
.stat:last-child { border-right: 0; }
.stat__value {
	margin: 0;
	font-family: 'JetBrains Mono', monospace;
	font-size: var(--step-2);
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	color: var(--text);
	letter-spacing: -0.03em;
}
.stat__label {
	margin-top: var(--sp-1);
	order: 1;
	font-size: var(--step--1);
	color: var(--text-faint);
	line-height: 1.4;
}

/* --- Card grids ----------------------------------------------------------- */
.grid { display: grid; gap: var(--sp-4); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); }

.card {
	position: relative;
	padding: var(--sp-6);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: linear-gradient(180deg, var(--surface), var(--bg-soft));
	transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease),
		box-shadow var(--dur) var(--ease);
}
.card:hover { border-color: var(--line-strong); transform: translateY(-3px); box-shadow: var(--shadow-card); }

.card--featured { border-color: var(--accent-line); }
.card--featured::after {
	content: '';
	position: absolute;
	inset: -1px;
	border-radius: inherit;
	pointer-events: none;
	background: radial-gradient(24rem 12rem at 12% 0%, var(--accent-wash), transparent 70%);
}

.card__icon {
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	margin-bottom: var(--sp-5);
	border: 1px solid var(--line-strong);
	border-radius: 12px;
	background: var(--surface-2);
	color: var(--accent-soft);
}
.card__title { font-size: var(--step-1); margin-bottom: var(--sp-3); }
.card__text { color: var(--text-dim); font-size: var(--step-0); }

.card__tag {
	display: inline-block;
	margin-bottom: var(--sp-3);
	padding: 2px 10px;
	border: 1px solid var(--accent-line);
	border-radius: 999px;
	background: var(--accent-wash);
	color: var(--accent-soft);
	font-family: 'JetBrains Mono', monospace;
	font-size: 0.72rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

/* --- Stack ---------------------------------------------------------------- */
.stack-group + .stack-group { margin-top: var(--sp-6); }
.stack-group__label {
	font-family: 'JetBrains Mono', monospace;
	font-size: var(--step--1);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--text-faint);
	margin-bottom: var(--sp-3);
}
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.chip {
	padding: var(--sp-2) var(--sp-4);
	border: 1px solid var(--line);
	border-radius: 999px;
	background: var(--surface);
	color: var(--text-dim);
	font-size: var(--step--1);
	transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease),
		background var(--dur) var(--ease);
}
.chip:hover { border-color: var(--accent-line); color: var(--text); background: var(--surface-2); }

/* --- Timeline ------------------------------------------------------------- */
.timeline { position: relative; display: grid; gap: var(--sp-6); }
.timeline::before {
	content: '';
	position: absolute;
	left: 11px;
	top: 8px;
	bottom: 8px;
	width: 1px;
	background: linear-gradient(180deg, var(--accent-line), var(--line) 45%, transparent);
}
.tl { position: relative; padding-left: calc(var(--sp-6) + var(--sp-3)); }
.tl::before {
	content: '';
	position: absolute;
	left: 5px;
	top: 9px;
	width: 13px;
	height: 13px;
	border-radius: 50%;
	background: var(--bg);
	border: 2px solid var(--line-strong);
}
.tl--now::before { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-wash); }
.tl__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--sp-3);
	margin-bottom: var(--sp-2);
}
.tl__year {
	font-family: 'JetBrains Mono', monospace;
	font-size: var(--step--1);
	font-variant-numeric: tabular-nums;
	color: var(--accent-soft);
	letter-spacing: 0.04em;
}
.tl__title { font-size: var(--step-1); }
.tl__text { color: var(--text-dim); max-width: 64ch; }

/* --- Work ----------------------------------------------------------------- */
.work-grid {
	display: grid;
	gap: var(--sp-4);
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
}

.work {
	position: relative;
	display: flex;
	flex-direction: column;
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: var(--surface);
	overflow: hidden;
	color: inherit;
	transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease),
		box-shadow var(--dur) var(--ease);
}
.work:hover { border-color: var(--line-strong); transform: translateY(-4px); box-shadow: var(--shadow-lift); color: inherit; }

/* The lead project keeps the accent treatment instead of a wider cell, so the
   grid stays a clean 3x2 with no half-empty row. */
.work--featured { border-color: var(--accent-line); }
.work--featured:hover { border-color: var(--accent); }

.work__media {
	position: relative;
	aspect-ratio: 3 / 2;
	overflow: hidden;
	background: var(--surface-2);
}
/* <picture> is inline by default, so a percentage height on the <img> has no
   definite containing block to resolve against. display:contents removes it
   from the box tree and lets the <img> fill .work__media directly. */
.work__media picture { display: contents; }
.work__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: top center;
	transition: transform 500ms var(--ease), filter 500ms var(--ease);
	filter: saturate(0.85) contrast(1.02);
}
.work:hover .work__media img { transform: scale(1.04); filter: saturate(1) contrast(1.02); }
.work__media::after {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, transparent 45%, rgba(8, 9, 11, 0.85));
}

.work__role {
	position: absolute;
	left: var(--sp-4);
	top: var(--sp-4);
	z-index: 1;
	padding: 4px 10px;
	border-radius: 999px;
	background: rgba(8, 9, 11, 0.75);
	backdrop-filter: blur(6px);
	border: 1px solid var(--accent-line);
	color: var(--accent-soft);
	font-family: 'JetBrains Mono', monospace;
	font-size: 0.72rem;
	letter-spacing: 0.05em;
	text-transform: uppercase;
}

.work__body { display: flex; flex-direction: column; gap: var(--sp-3); padding: var(--sp-5); flex: 1; }
.work__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); }
.work__title { font-size: var(--step-1); }
.work__link {
	flex: none;
	color: var(--text-faint);
	transition: color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.work:hover .work__link { color: var(--accent-soft); transform: translate(2px, -2px); }
.work__text { color: var(--text-dim); font-size: var(--step--1); line-height: 1.6; flex: 1; }
.work__stack {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-2);
	font-family: 'JetBrains Mono', monospace;
	font-size: 0.72rem;
	color: var(--text-faint);
}
.work__stack li { padding: 2px 8px; border: 1px solid var(--line); border-radius: 6px; }

/* --- AI callout ----------------------------------------------------------- */
.ai {
	position: relative;
	padding: clamp(2rem, 5vw, 3.5rem);
	border: 1px solid var(--accent-line);
	border-radius: var(--radius-lg);
	background:
		radial-gradient(40rem 20rem at 90% 0%, rgba(79, 125, 255, 0.14), transparent 70%),
		linear-gradient(180deg, var(--surface), var(--bg-soft));
	overflow: hidden;
}
.ai__list { display: grid; gap: var(--sp-4); margin-top: var(--sp-6); }
.ai__item { display: flex; gap: var(--sp-4); align-items: flex-start; }
.ai__check { color: var(--accent-soft); margin-top: 3px; }
.ai__item p { color: var(--text-dim); }
.ai__item strong { color: var(--text); font-weight: 600; }

/* --- Contact -------------------------------------------------------------- */
.contact-grid { display: grid; gap: clamp(2rem, 5vw, 4rem); align-items: start; }

.contact-list { display: grid; gap: var(--sp-3); margin-top: var(--sp-6); }
.contact-list a {
	display: flex;
	align-items: center;
	gap: var(--sp-4);
	min-height: 48px;
	padding: var(--sp-3) var(--sp-4);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: var(--surface);
	color: var(--text);
	transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.contact-list a:hover { border-color: var(--accent-line); background: var(--surface-2); }
.contact-list svg { color: var(--accent-soft); }
.contact-list__label {
	display: block;
	font-size: 0.72rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--text-faint);
	font-family: 'JetBrains Mono', monospace;
}

/* --- Form ----------------------------------------------------------------- */
.form {
	display: grid;
	gap: var(--sp-5);
	padding: clamp(1.5rem, 4vw, 2.25rem);
	border: 1px solid var(--line);
	border-radius: var(--radius-lg);
	background: linear-gradient(180deg, var(--surface), var(--bg-soft));
}
.field { display: grid; gap: var(--sp-2); }
.field label { font-size: var(--step--1); font-weight: 550; color: var(--text); }
.field__hint { font-size: 0.78rem; color: var(--text-faint); }

.field input, .field textarea {
	width: 100%;
	min-height: 48px;
	padding: var(--sp-3) var(--sp-4);
	border: 1px solid var(--line-strong);
	border-radius: var(--radius-sm);
	background: var(--bg);
	color: var(--text);
	/* 16px minimum stops iOS from zooming on focus */
	font-size: 1rem;
	transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.field textarea { resize: vertical; min-height: 132px; line-height: 1.6; }
.field input::placeholder, .field textarea::placeholder { color: var(--text-faint); }
.field input:focus, .field textarea:focus {
	outline: none;
	border-color: var(--accent);
	box-shadow: 0 0 0 3px var(--accent-wash);
}
.field input:user-invalid, .field textarea:user-invalid { border-color: var(--danger); }

/* Honeypot: off-screen rather than display:none, which some bots skip */
.hp-field {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.form__foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4); }
.form__note { font-size: 0.78rem; color: var(--text-faint); flex: 1; min-width: 16ch; }
#turnstile:not(:empty) { margin-bottom: calc(var(--sp-2) * -1); }

/* --- Toast ---------------------------------------------------------------- */
.toasts {
	position: fixed;
	right: var(--sp-4);
	bottom: var(--sp-4);
	z-index: var(--z-toast);
	display: grid;
	gap: var(--sp-2);
	max-width: min(360px, calc(100vw - 2rem));
}
.toast {
	display: flex;
	align-items: flex-start;
	gap: var(--sp-3);
	padding: var(--sp-4);
	border: 1px solid var(--line-strong);
	border-radius: var(--radius);
	background: var(--surface-2);
	box-shadow: var(--shadow-lift);
	font-size: var(--step--1);
	animation: toast-in 260ms var(--ease);
}
.toast--success { border-color: rgba(74, 222, 128, 0.4); }
.toast--success svg { color: var(--success); }
.toast--error { border-color: rgba(255, 107, 107, 0.4); }
.toast--error svg { color: var(--danger); }
.toast svg { flex: none; margin-top: 2px; }
.toast.is-leaving { animation: toast-out 200ms var(--ease) forwards; }

/* --- Footer --------------------------------------------------------------- */
.footer { border-top: 1px solid var(--line); padding-block: var(--sp-7); }
.footer__inner {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-4);
	align-items: center;
	justify-content: space-between;
	color: var(--text-faint);
	font-size: var(--step--1);
}
.footer__links { display: flex; flex-wrap: wrap; gap: var(--sp-5); }

/* --- 404 ------------------------------------------------------------------ */
/* Styles live here rather than in a <style> block because the CSP is
   `style-src 'self'` — inline styles are blocked in production. */
.nf-body { min-height: 100dvh; }

.nf {
	position: relative;
	display: grid;
	place-items: center;
	min-height: 100dvh;
	padding: var(--sp-7) var(--gutter);
	overflow: hidden;
}

.nf__inner {
	position: relative;
	width: 100%;
	max-width: 46rem;
	text-align: center;
}

.nf__code {
	font-family: 'JetBrains Mono', ui-monospace, monospace;
	font-size: clamp(5rem, 22vw, 13rem);
	font-weight: 700;
	line-height: 0.9;
	letter-spacing: -0.06em;
	background: linear-gradient(170deg, var(--text) 8%, var(--accent-soft) 48%, rgba(79, 125, 255, 0.25) 96%);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

.nf__title {
	margin-top: var(--sp-5);
	font-size: var(--step-3);
}

/* Request line — reads like the response the visitor just got */
.nf__request {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-3);
	max-width: 100%;
	margin-top: var(--sp-5);
	padding: var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-4);
	border: 1px solid var(--line-strong);
	border-radius: 999px;
	background: var(--surface);
	font-family: 'JetBrains Mono', ui-monospace, monospace;
	font-size: var(--step--1);
}
.nf__method { color: var(--text-faint); letter-spacing: 0.06em; }
.nf__path {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	color: var(--text);
}
.nf__status {
	flex: none;
	padding: 2px 10px;
	border-radius: 999px;
	background: rgba(255, 107, 107, 0.14);
	color: var(--danger);
	font-variant-numeric: tabular-nums;
}

.nf__text {
	max-width: 48ch;
	margin: var(--sp-5) auto 0;
	color: var(--text-dim);
}

.nf__links {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-2);
	justify-content: center;
	margin-top: var(--sp-6);
}

.nf__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-3);
	justify-content: center;
	margin-top: var(--sp-6);
}

@media (max-width: 480px) {
	.nf__actions .btn { flex: 1 1 100%; }
}

/* --- Motion --------------------------------------------------------------- */
@keyframes pulse {
	0%, 100% { opacity: 1; }
	50% { opacity: 0.35; }
}
@keyframes toast-in {
	from { opacity: 0; transform: translateY(12px) scale(0.98); }
	to { opacity: 1; transform: none; }
}
@keyframes toast-out {
	to { opacity: 0; transform: translateY(8px) scale(0.98); }
}

/* Scroll reveal — opacity/transform only, so it never triggers layout */
[data-reveal] {
	opacity: 0;
	transform: translateY(18px);
	transition: opacity 600ms var(--ease), transform 600ms var(--ease);
	transition-delay: var(--reveal-delay, 0ms);
}
[data-reveal].is-visible { opacity: 1; transform: none; }

/* Stagger, done with nth-child because inline style attributes are blocked by
   the CSP. Each container restarts the sequence. */
.grid > [data-reveal]:nth-child(2),
.timeline > [data-reveal]:nth-child(2),
.work-grid > [data-reveal]:nth-child(3n + 2) { --reveal-delay: 70ms; }

.grid > [data-reveal]:nth-child(3),
.timeline > [data-reveal]:nth-child(3),
.work-grid > [data-reveal]:nth-child(3n + 3) { --reveal-delay: 140ms; }

.timeline > [data-reveal]:nth-child(4) { --reveal-delay: 210ms; }

/* No JS: content must never stay invisible */
.no-js [data-reveal] { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}
	[data-reveal] { opacity: 1; transform: none; }
}

/* --- Responsive ----------------------------------------------------------- */
@media (max-width: 760px) {
	.nav__links { display: none; }
	.nav__cta { display: inline-flex; }
	.nav__brand { white-space: nowrap; }
	.stat { border-right: 0; border-bottom: 1px solid var(--line); }
	.stat:last-child { border-bottom: 0; }
	.hero__actions .btn { flex: 1 1 100%; }
}

/* Below this the full name competes with the CTA, so only the mark stays */
@media (max-width: 560px) {
	.nav__brand > span:not(.nav__mark) {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip-path: inset(50%);
	}
}

@media (min-width: 900px) {
	.contact-grid { grid-template-columns: 0.85fr 1.15fr; }
	.ai__list { grid-template-columns: repeat(2, 1fr); gap: var(--sp-5) var(--sp-6); }
}
