/* =========================================================================
   Dead Pixels / 04 sections
   Homepage compositions, project presentations, editorial pages.
   ========================================================================= */

/* =========================================================================
   HERO
   ========================================================================= */

.hero {
	position: relative;
	min-height: min(100svh, 980px);
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	padding-top: calc(var(--header-h) + clamp(2rem, 7vh, 5rem));
	overflow: hidden;
	isolation: isolate;
}

.hero__field {
	position: absolute;
	inset: 0;
	z-index: -1;
}

.hero__field canvas {
	width: 100%;
	height: 100%;
	display: block;
}

/* Vignette so the headline always wins against the field. */
.hero::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	background:
		radial-gradient(120% 80% at 18% 42%, rgba(4, 6, 13, 0.92) 0%, rgba(4, 6, 13, 0.4) 46%, transparent 72%),
		linear-gradient(to top, var(--ink-000) 2%, transparent 34%);
}

.hero__inner {
	position: relative;
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	align-items: center;
	gap: var(--sp-6) var(--sp-5);
	flex: 1;
	padding-block: clamp(2rem, 5vh, 4rem);
}

.hero__lead {
	grid-column: 1 / span 9;
	grid-row: 1;
	position: relative;
	z-index: 2;
}

/* The headline lines are set to nowrap, so the type is capped against the
   column as well as the viewport. See the @supports block below .hero__title. */
@supports (container-type: inline-size) {
	.hero__lead {
		container-type: inline-size;
	}
}

/* The mark sits in the same row and overlaps the headline column, which is
   what gives the hero its off center balance. It stays inside the shell so the
   logo, its rings and the field aperture all share one center. */
.hero__mark {
	grid-column: 8 / span 5;
	grid-row: 1;
	position: relative;
	aspect-ratio: 1;
	display: grid;
	place-items: center;
	justify-self: center;
	align-self: center;
	width: min(100%, 30rem);
	z-index: 1;
}

.hero__eyebrow {
	display: flex;
	align-items: center;
	gap: 0.7rem;
	font-family: var(--font-mono);
	font-size: var(--fs-label);
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--fg-faint);
	margin-bottom: clamp(1rem, 3vh, 1.75rem);
}

.hero__eyebrow b {
	color: var(--ice);
	font-weight: 500;
}

.hero__eyebrow > * {
	white-space: nowrap;
}

@media (max-width: 560px) {
	.hero__eyebrow-last {
		display: none;
	}
}

/* Narrow phones: let the strap wrap rather than run under the edge. */
@media (max-width: 400px) {
	.hero__eyebrow {
		flex-wrap: wrap;
		row-gap: 0.35rem;
		gap: 0.55rem;
	}

	.hero__eyebrow-sep {
		display: none;
	}
}

/* Tracking is the system's --track-tight rather than something tighter.
   Archivo ships no kern pair for FT, and below about 3% of the font size the
   F's arm and the T's crossbar sit at the same height and merge into a single
   bar, so "SOFTWARE" reads with the T lost. This is the only flat-sided pair
   on the site that gets close, and this value clears it. */
.hero__title {
	font-size: var(--fs-hero);
	font-variation-settings: "wdth" 122, "wght" 760;
	line-height: 0.86;
	letter-spacing: var(--track-tight);
	text-transform: uppercase;
	margin: 0;
}

/* The longest authored line is about 9.4em wide, so 9.8cqw always leaves the
   column a little room no matter how the grid resolves. Browsers without
   container queries fall back to the viewport clamp above. */
@supports (container-type: inline-size) {
	.hero__title {
		font-size: min(var(--fs-hero), 9.8cqw);
	}
}

.hero__line {
	display: block;
	overflow: hidden;
}

/* Entrance animations run backwards from a hidden start rather than holding a
   hidden resting state. If animation never runs, the hero is simply visible. */
.hero__line > span {
	display: block;
	/* Line breaks are authored, not left to the browser, so the stack always
	   reads as three deliberate bars of type. Released on narrow screens. */
	white-space: nowrap;
	animation: hero-line 1s var(--ease-out) backwards;
	animation-delay: var(--d, 0ms);
}

@media (max-width: 700px) {
	.hero__line > span {
		white-space: normal;
	}
}

.hero__line--outline > span {
	color: transparent;
	-webkit-text-stroke: 1.5px var(--ice);
	padding-right: 0.06em;
}

@keyframes hero-line {
	from {
		transform: translateY(105%);
	}
	to {
		transform: translateY(0);
	}
}

.hero__text {
	max-width: 44ch;
	margin-top: clamp(1.25rem, 3vh, 2rem);
	color: var(--fg-soft);
	font-size: var(--fs-lead);
	line-height: 1.5;
	animation: fade-up 0.9s var(--ease-out) 0.72s backwards;
}

.hero__actions {
	margin-top: clamp(1.5rem, 4vh, 2.5rem);
	animation: fade-up 0.9s var(--ease-out) 0.86s backwards;
}

@keyframes fade-up {
	from {
		opacity: 0;
		transform: translateY(16px);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

/* logo composition ---------------------------------------------------- */

.hero__logo {
	position: relative;
	width: 62%;
	z-index: 2;
	filter: drop-shadow(0 0 40px rgba(11, 68, 214, 0.45));
	animation: mark-in 1.4s var(--ease-out) 0.25s backwards;
	will-change: transform;
}

@keyframes mark-in {
	from {
		opacity: 0;
		transform: scale(0.86);
	}
	to {
		opacity: 1;
		transform: scale(1);
	}
}

.hero__rings {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
}

.hero__rings circle {
	fill: none;
	stroke: var(--line-strong);
	stroke-width: 0.35;
	transform-origin: 50% 50%;
}

.hero__rings circle:nth-child(1) {
	animation: spin 58s linear infinite;
	stroke-dasharray: 34 8 3 8;
}

.hero__rings circle:nth-child(2) {
	animation: spin 92s linear infinite reverse;
	stroke-dasharray: 2 6;
	stroke: var(--line);
}

.hero__rings circle:nth-child(3) {
	stroke-dasharray: 120 260;
	stroke: color-mix(in srgb, var(--ice) 45%, transparent);
	animation: spin 26s linear infinite;
}

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

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

.hero__rail {
	position: relative;
	z-index: 2;
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr)) auto;
	border-top: var(--border);
	animation: fade-up 0.9s var(--ease-out) 1s backwards;
}

.hero__rail-item {
	padding: clamp(0.85rem, 2vh, 1.35rem) clamp(0.6rem, 1.5vw, 1.4rem);
	border-right: var(--border);
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
}

.hero__rail-item:first-child {
	padding-left: 0;
}

.hero__rail-key {
	font-family: var(--font-mono);
	font-size: var(--fs-micro);
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--fg-faint);
}

.hero__rail-val {
	font-family: var(--font-display);
	font-variation-settings: "wdth" 108, "wght" 600;
	font-size: clamp(0.9rem, 1.4vw, 1.125rem);
	color: var(--fg);
	letter-spacing: -0.01em;
}

.hero__scroll {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	padding-inline: clamp(0.6rem, 1.5vw, 1.4rem) 0;
	font-family: var(--font-mono);
	font-size: var(--fs-micro);
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--fg-faint);
	transition: color var(--t-mid) var(--ease);
}

.hero__scroll:hover {
	color: var(--ice);
}

.hero__scroll-track {
	width: 1px;
	height: 34px;
	background: var(--line-strong);
	position: relative;
	overflow: hidden;
}

.hero__scroll-track::after {
	content: "";
	position: absolute;
	inset: 0 0 auto 0;
	height: 12px;
	background: var(--ice);
	animation: scroll-cue 2.4s var(--ease-in-out) infinite;
}

@keyframes scroll-cue {
	0% {
		transform: translateY(-100%);
	}
	60%,
	100% {
		transform: translateY(340%);
	}
}

/* =========================================================================
   MANIFESTO (light region)
   ========================================================================= */

.manifesto {
	position: relative;
	padding-block: clamp(3rem, 6vw, 6rem);
	overflow: hidden;
}

.manifesto::before {
	content: "";
	position: absolute;
	inset: 0;
	background-image:
		linear-gradient(to right, rgba(10, 14, 29, 0.055) 1px, transparent 1px),
		linear-gradient(to bottom, rgba(10, 14, 29, 0.055) 1px, transparent 1px);
	background-size: var(--grid-cell) var(--grid-cell);
	pointer-events: none;
}

.manifesto__grid {
	position: relative;
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	gap: clamp(1.5rem, 4vw, 3.5rem);
	align-items: start;
}

.manifesto__head {
	grid-column: 1 / span 9;
	grid-row: 1;
}

.manifesto__statement {
	font-size: clamp(1.6rem, 0.95rem + 2.9vw, 3.5rem);
	font-variation-settings: "wdth" 104, "wght" 620;
	line-height: 1.02;
	letter-spacing: -0.035em;
	color: var(--paper-ink);
	text-wrap: balance;
}

.manifesto__statement em {
	font-style: normal;
	position: relative;
	color: var(--royal);
	white-space: nowrap;
}

/* Hand drawn feeling underline that is deliberately slightly off. */
.manifesto__statement em::after {
	content: "";
	position: absolute;
	left: -0.02em;
	right: 0.01em;
	bottom: 0.06em;
	height: 0.09em;
	background: currentColor;
	opacity: 0.22;
	transform: rotate(-0.35deg);
}

.manifesto__body {
	grid-column: 2 / span 5;
	color: var(--paper-ink-soft);
	margin-top: var(--sp-5);
}

.manifesto__body p + p {
	margin-top: 1em;
}

.manifesto__side {
	grid-column: 8 / span 5;
	margin-top: var(--sp-5);
	border-left: 2px solid rgba(10, 14, 29, 0.12);
	padding-left: clamp(1rem, 2vw, 1.75rem);
}

.denials {
	list-style: none;
	margin: var(--sp-4) 0 0;
	padding: 0;
	display: flex;
	flex-direction: column;
}

.denials li {
	position: relative;
	display: flex;
	align-items: baseline;
	gap: 0.85rem;
	padding-block: 0.7rem;
	border-bottom: 1px solid rgba(10, 14, 29, 0.1);
	font-family: var(--font-display);
	font-variation-settings: "wdth" 100, "wght" 600;
	font-size: clamp(1rem, 1.6vw, 1.375rem);
	letter-spacing: -0.015em;
	text-transform: uppercase;
	color: var(--paper-ink);
}

.denials li::before {
	content: attr(data-n);
	font-family: var(--font-mono);
	font-size: var(--fs-micro);
	letter-spacing: 0.1em;
	color: rgba(10, 14, 29, 0.62);
	font-variation-settings: normal;
	flex: none;
}

/* A rule that wipes across on hover: the thing is being refused.

   The rule is a real line-through on a transparent duplicate of the label
   stacked over the original, and the wipe is that duplicate being unclipped
   from the left. A background gradient cannot do this: Chromium ignores
   box-decoration-break on inline backgrounds, so a wrapped entry only ever
   gets a rule on its first line. Letting the browser draw the decoration means
   every line is struck, each centred on its own metrics. */
.denials__text {
	position: relative;
	display: block;
	/* Takes the rest of the row so the copy underneath wraps identically. */
	flex: 1;
	min-width: 0;
}

.denials__strike {
	position: absolute;
	inset: 0;
	color: transparent;
	text-decoration-line: line-through;
	text-decoration-color: var(--royal);
	text-decoration-thickness: 2px;
	pointer-events: none;
	clip-path: inset(0 100% 0 0);
	transition: clip-path var(--t-slow) var(--ease-out);
}

.denials li:hover .denials__strike,
.denials li:focus-within .denials__strike {
	clip-path: inset(0 0 0 0);
}

/* No hover target on touch, so the rules are simply present. */
@media (hover: none) {
	.denials__strike {
		clip-path: inset(0 0 0 0);
	}
}

/* =========================================================================
   VALUES LEDGER
   ========================================================================= */

.values__head {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 0.8fr);
	gap: var(--sp-5) var(--sp-7);
	align-items: end;
	margin-bottom: clamp(2rem, 5vw, 4rem);
}

.values__title {
	font-size: var(--fs-h2);
	text-transform: uppercase;
	font-variation-settings: "wdth" 118, "wght" 740;
	line-height: 0.94;
}

.ledger {
	list-style: none;
	margin: 0;
	padding: 0;
	border-top: var(--border);
}

.ledger__row {
	position: relative;
	display: grid;
	grid-template-columns: 4.5rem minmax(0, 0.9fr) minmax(0, 1.4fr) auto;
	gap: var(--sp-4) var(--sp-5);
	align-items: baseline;
	padding-block: clamp(1.1rem, 2.4vw, 1.9rem);
	border-bottom: var(--border);
	transition: background var(--t-mid) var(--ease), padding-left var(--t-mid) var(--ease-out);
}

.ledger__row::before {
	content: "";
	position: absolute;
	left: 0;
	top: -1px;
	bottom: -1px;
	width: 2px;
	background: var(--ice);
	transform: scaleY(0);
	transform-origin: top center;
	transition: transform var(--t-mid) var(--ease-out);
}

.ledger__row:hover {
	background: linear-gradient(90deg, rgba(58, 127, 232, 0.07), transparent 62%);
	padding-left: 1rem;
}

.ledger__row:hover::before {
	transform: scaleY(1);
}

.ledger__index {
	font-family: var(--font-mono);
	font-size: var(--fs-label);
	letter-spacing: 0.14em;
	color: var(--fg-faint);
	transition: color var(--t-mid) var(--ease);
}

.ledger__row:hover .ledger__index {
	color: var(--ice);
}

.ledger__name {
	font-family: var(--font-display);
	font-variation-settings: "wdth" 112, "wght" 680;
	font-size: clamp(1.25rem, 2.2vw, 1.875rem);
	letter-spacing: -0.025em;
	text-transform: uppercase;
	color: #fff;
}

.ledger__text {
	color: var(--fg-soft);
	font-size: var(--fs-sm);
	line-height: 1.6;
	max-width: 52ch;
}

.ledger__glyph {
	color: var(--fg-faint);
	opacity: 0.3;
	transform: translateX(-4px) rotate(-45deg);
	transition: opacity var(--t-mid) var(--ease), transform var(--t-slow) var(--ease-out), color var(--t-mid) var(--ease);
	align-self: center;
}

.ledger__row:hover .ledger__glyph {
	opacity: 1;
	color: var(--ice);
	transform: translateX(0) rotate(0deg);
}

/* =========================================================================
   PROJECTS
   ========================================================================= */

.projects {
	position: relative;
	border-top: var(--border);
}

.showcase {
	position: relative;
	border-bottom: var(--border);
	overflow: hidden;
}

.showcase__meta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-2) var(--sp-5);
	align-items: center;
	padding-block: 0.85rem;
	border-bottom: var(--border);
	font-family: var(--font-mono);
	font-size: var(--fs-micro);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--fg-faint);
}

.showcase__meta b {
	color: var(--accent);
	font-weight: 500;
}

.showcase__grid {
	display: grid;
	grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
	gap: clamp(2rem, 5vw, 5rem);
	align-items: center;
	padding-block: clamp(3rem, 6vw, 6rem);
}

/* Every second project flips its composition. nth-of-type keeps the count on
   the articles alone, so intro blocks and tickers cannot shift the rhythm. */
.showcase:nth-of-type(even) .showcase__grid {
	direction: rtl;
}

.showcase:nth-of-type(even) .showcase__grid > * {
	direction: ltr;
}

.showcase__index {
	font-family: var(--font-mono);
	font-size: var(--fs-label);
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--accent);
	display: block;
	margin-bottom: var(--sp-3);
}

/* Project names use one tracking wherever they appear, here and on the project
   hero, so the type system has a single value for the role. */
.showcase__name {
	font-size: clamp(2.25rem, 1.2rem + 4.2vw, 4.75rem);
	font-variation-settings: "wdth" 118, "wght" 750;
	line-height: 0.9;
	letter-spacing: var(--track-tight);
	text-transform: uppercase;
	margin-bottom: var(--sp-4);
}

.showcase__tagline {
	font-size: var(--fs-lead);
	line-height: 1.45;
	color: var(--fg-soft);
	max-width: 40ch;
}

.showcase__highlights {
	list-style: none;
	margin: var(--sp-6) 0 0;
	padding: 0;
	border-top: 1px solid var(--line-soft);
}

.showcase__highlights li {
	display: grid;
	grid-template-columns: 1rem minmax(0, 1fr);
	gap: 0.9rem;
	padding-block: 0.9rem;
	border-bottom: 1px solid var(--line-soft);
	transition: border-color var(--t-mid) var(--ease);
}

.showcase__highlights li:hover {
	border-color: color-mix(in srgb, var(--accent) 40%, transparent);
}

.showcase__highlights .icon {
	color: var(--accent);
	margin-top: 0.35em;
	opacity: 0.7;
	transition: opacity var(--t-mid) var(--ease), transform var(--t-mid) var(--ease-out);
}

.showcase__highlights li:hover .icon {
	opacity: 1;
	transform: rotate(90deg);
}

.showcase__highlights b {
	display: block;
	font-family: var(--font-display);
	font-variation-settings: "wdth" 102, "wght" 620;
	font-size: 1.0625rem;
	color: #fff;
	letter-spacing: -0.01em;
	margin-bottom: 0.15rem;
}

.showcase__highlights span {
	color: var(--fg-soft);
	font-size: var(--fs-sm);
	line-height: 1.55;
}

.showcase__foot {
	margin-top: var(--sp-6);
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-5);
	align-items: center;
	justify-content: space-between;
}

/* visual panel --------------------------------------------------------- */

.showcase__visual {
	position: relative;
	aspect-ratio: 1 / 0.92;
	display: grid;
	place-items: center;
	border: var(--border);
	border-radius: var(--radius-lg);
	overflow: hidden;
	background:
		radial-gradient(80% 80% at 50% 50%, color-mix(in srgb, var(--accent) 16%, transparent), transparent 70%),
		linear-gradient(160deg, var(--ink-100), var(--ink-000) 70%);
	isolation: isolate;
}

.showcase__visual::before {
	content: "";
	position: absolute;
	inset: 0;
	background-image:
		linear-gradient(to right, var(--line-soft) 1px, transparent 1px),
		linear-gradient(to bottom, var(--line-soft) 1px, transparent 1px);
	background-size: 38px 38px;
	-webkit-mask-image: radial-gradient(70% 70% at 50% 50%, transparent 30%, #000 100%);
	mask-image: radial-gradient(70% 70% at 50% 50%, transparent 30%, #000 100%);
}

/* Scanline sweep, slow and low contrast. */
.showcase__visual::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	height: 28%;
	top: -30%;
	background: linear-gradient(to bottom, transparent, color-mix(in srgb, var(--accent) 9%, transparent), transparent);
	animation: sweep 9s var(--ease-in-out) infinite;
	pointer-events: none;
}

@keyframes sweep {
	0%,
	18% {
		transform: translateY(0);
		opacity: 0;
	}
	22% {
		opacity: 1;
	}
	78% {
		opacity: 1;
	}
	100% {
		transform: translateY(460%);
		opacity: 0;
	}
}

/* An svg with a viewBox carries an intrinsic 1:1 ratio. With all four insets
   set on a panel that is not square, it keeps its own height instead of the
   inset box's and drifts off centre. The explicit size pins it to the box, and
   preserveAspectRatio then centres the square drawing inside it, so the rings
   stay concentric with the logo. */
.showcase__orbit {
	position: absolute;
	inset: 8%;
	width: 84%;
	height: 84%;
	pointer-events: none;
}

.showcase__orbit circle,
.showcase__orbit rect {
	fill: none;
	stroke: color-mix(in srgb, var(--accent) 34%, transparent);
	stroke-width: 0.3;
	transform-origin: 50% 50%;
}

.showcase__orbit circle:nth-of-type(1) {
	stroke-dasharray: 1 5;
	animation: spin 70s linear infinite;
}

.showcase__orbit circle:nth-of-type(2) {
	stroke-dasharray: 46 200;
	animation: spin 30s linear infinite reverse;
}

.showcase__orbit rect {
	stroke: var(--line);
	animation: spin 120s linear infinite;
}

.showcase__logo {
	position: relative;
	z-index: 2;
	width: 56%;
	max-width: 340px;
	transition: transform var(--t-slow) var(--ease-out), filter var(--t-slow) var(--ease-out);
	filter: drop-shadow(0 14px 40px color-mix(in srgb, var(--accent) 30%, transparent));
	will-change: transform;
}

.showcase__visual:hover .showcase__logo {
	transform: scale(1.05) translateY(-6px);
}

/* Corner ticks: interface furniture rather than decoration for its own sake. */
/* Lifted out of flow. Left static it becomes a grid row of its own and pushes
   the logo off the centre of the panel. */
.showcase__ticks {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

.showcase__ticks span {
	position: absolute;
	width: 12px;
	height: 12px;
	border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
	opacity: 0.7;
}

.showcase__ticks span:nth-child(1) {
	top: 14px;
	left: 14px;
	border-right: 0;
	border-bottom: 0;
}

.showcase__ticks span:nth-child(2) {
	top: 14px;
	right: 14px;
	border-left: 0;
	border-bottom: 0;
}

.showcase__ticks span:nth-child(3) {
	bottom: 14px;
	left: 14px;
	border-right: 0;
	border-top: 0;
}

.showcase__ticks span:nth-child(4) {
	bottom: 14px;
	right: 14px;
	border-left: 0;
	border-top: 0;
}

.showcase__badge {
	position: absolute;
	left: 16px;
	bottom: 16px;
	z-index: 3;
}

/* =========================================================================
   PROCESS DIAGRAM
   ========================================================================= */

.process {
	position: relative;
	border-bottom: var(--border);
}

.process__head {
	max-width: 46rem;
	margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
}

/* Every node sits on the bus line. The rhythm comes from the line and the
   numbering, not from offsetting alternate steps. */
.process__track {
	position: relative;
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: var(--sp-5);
	align-items: start;
}

/* The bus line runs between the first and last node centers, not edge to edge,
   so it terminates on something rather than trailing into the gutter. */
.process__line {
	position: absolute;
	top: 26px;
	left: 26px;
	width: calc(75% + 1.125rem);
	height: 1px;
	background: repeating-linear-gradient(90deg, var(--line-strong) 0 6px, transparent 6px 12px);
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform 1.4s var(--ease-out);
}

.process.is-in .process__line {
	transform: scaleX(1);
}

.process__step {
	position: relative;
	padding-top: 0;
}

.process__node {
	position: relative;
	width: 52px;
	height: 52px;
	display: grid;
	place-items: center;
	border: 1px solid var(--line-strong);
	background: var(--ink-000);
	color: var(--fg-soft);
	margin-bottom: var(--sp-5);
	transition: border-color var(--t-mid) var(--ease), color var(--t-mid) var(--ease),
		transform var(--t-mid) var(--ease-out);
}

.process__node::after {
	content: attr(data-n);
	position: absolute;
	top: -0.5rem;
	right: -1.1rem;
	font-family: var(--font-mono);
	font-size: var(--fs-micro);
	letter-spacing: 0.1em;
	color: var(--fg-faint);
}

.process__step:hover .process__node {
	border-color: var(--ice);
	color: var(--ice);
	transform: translateY(-4px);
}

.process__step h3 {
	font-size: 1.125rem;
	font-variation-settings: "wdth" 104, "wght" 640;
	text-transform: uppercase;
	letter-spacing: -0.005em;
	margin-bottom: 0.5rem;
}

.process__step p {
	color: var(--fg-soft);
	font-size: var(--fs-sm);
	line-height: 1.6;
}

/* Step offset resets so the dashed line still reads on narrow layouts. */
@media (max-width: 900px) {
	.process__track {
		grid-template-columns: minmax(0, 1fr);
		gap: 0;
	}

	.process__line {
		top: 0;
		bottom: 0;
		left: 26px;
		right: auto;
		width: 1px;
		height: auto;
		background: repeating-linear-gradient(180deg, var(--line-strong) 0 6px, transparent 6px 12px);
		transform: scaleY(0);
		transform-origin: top center;
	}

	.process.is-in .process__line {
		transform: scaleY(1);
	}

	.process__step {
		display: grid;
		grid-template-columns: 52px minmax(0, 1fr);
		gap: var(--sp-5);
		padding-block: var(--sp-5);
	}

	.process__node {
		margin-bottom: 0;
	}

	.process__node {
		margin-bottom: 0;
	}
}

/* =========================================================================
   CONTRIBUTE
   ========================================================================= */

.contribute__grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
	gap: clamp(2rem, 5vw, 5rem);
	align-items: start;
}

.contribute__title {
	font-size: clamp(2rem, 1.2rem + 3.4vw, 4rem);
	font-variation-settings: "wdth" 116, "wght" 740;
	line-height: 0.94;
	text-transform: uppercase;
	margin-bottom: var(--sp-5);
}

.routes {
	list-style: none;
	margin: 0;
	padding: 0;
	border-top: var(--border);
}

.routes li {
	border-bottom: var(--border);
}

.routes a {
	position: relative;
	display: grid;
	grid-template-columns: 2.5rem minmax(0, 1fr) auto;
	gap: var(--sp-4);
	align-items: center;
	padding-block: clamp(0.9rem, 2vw, 1.4rem);
	transition: padding-left var(--t-mid) var(--ease-out), color var(--t-mid) var(--ease);
}

.routes a:hover {
	padding-left: 0.85rem;
}

.routes__index {
	font-family: var(--font-mono);
	font-size: var(--fs-micro);
	letter-spacing: 0.12em;
	color: var(--fg-faint);
}

.routes__name {
	font-family: var(--font-display);
	font-variation-settings: "wdth" 108, "wght" 640;
	font-size: clamp(1.0625rem, 1.6vw, 1.375rem);
	text-transform: uppercase;
	letter-spacing: -0.015em;
	color: #fff;
}

.routes__name small {
	display: block;
	font-family: var(--font-body);
	font-variation-settings: normal;
	font-size: var(--fs-sm);
	font-weight: 400;
	letter-spacing: 0;
	text-transform: none;
	color: var(--fg-soft);
	margin-top: 0.2rem;
	line-height: 1.5;
}

.routes a .icon {
	color: var(--fg-faint);
	transition: transform var(--t-mid) var(--ease-out), color var(--t-mid) var(--ease);
}

.routes a:hover .icon {
	color: var(--ice);
	transform: translateX(5px);
}

/* =========================================================================
   PROJECT SINGLE
   ========================================================================= */

.project-hero {
	position: relative;
	padding-top: calc(var(--header-h) + clamp(3rem, 7vw, 6rem));
	padding-bottom: clamp(3rem, 6vw, 5rem);
	border-bottom: var(--border);
	overflow: hidden;
	background:
		radial-gradient(70% 60% at 78% 22%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 70%),
		var(--ink-000);
}

.project-hero__grid {
	position: relative;
	z-index: 1;
	display: grid;
	grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
	gap: clamp(2rem, 5vw, 4.5rem);
	align-items: center;
}

/* Same tracking as the homepage hero: this is the same role at the same size,
   and it keeps a future project name containing FT out of trouble. */
.project-hero__title {
	font-size: clamp(2.5rem, 1.2rem + 5.6vw, 6.5rem);
	font-variation-settings: "wdth" 120, "wght" 760;
	line-height: 0.86;
	letter-spacing: var(--track-tight);
	text-transform: uppercase;
	margin-block: var(--sp-3) var(--sp-4);
}

.project-hero__visual {
	position: relative;
	aspect-ratio: 1;
	display: grid;
	place-items: center;
}

.project-hero__logo {
	width: 66%;
	filter: drop-shadow(0 20px 60px color-mix(in srgb, var(--accent) 35%, transparent));
	animation: float 9s var(--ease-in-out) infinite;
}

@keyframes float {
	50% {
		transform: translateY(-12px);
	}
}

.spec {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	border-top: var(--border);
	border-left: var(--border);
}

.spec__cell {
	padding: var(--sp-4) var(--sp-5);
	border-right: var(--border);
	border-bottom: var(--border);
	display: flex;
	flex-direction: column;
	gap: 0.35rem;
	transition: background var(--t-mid) var(--ease);
}

.spec__cell:hover {
	background: rgba(58, 127, 232, 0.05);
}

.spec__key {
	font-family: var(--font-mono);
	font-size: var(--fs-micro);
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--fg-faint);
}

.spec__val {
	font-family: var(--font-display);
	font-variation-settings: "wdth" 106, "wght" 620;
	font-size: 1.0625rem;
	color: #fff;
	letter-spacing: -0.01em;
}

/* roadmap ------------------------------------------------------------- */

.roadmap {
	position: relative;
	display: flex;
	flex-direction: column;
	border-top: var(--border);
}

.stage {
	position: relative;
	border-bottom: var(--border);
}

.stage__toggle {
	width: 100%;
	display: grid;
	grid-template-columns: 5.5rem minmax(0, 1fr) auto auto;
	gap: var(--sp-4);
	align-items: center;
	text-align: left;
	padding-block: clamp(1rem, 2.2vw, 1.5rem);
	transition: padding-left var(--t-mid) var(--ease-out), background var(--t-mid) var(--ease);
}

.stage__toggle:hover {
	padding-left: 0.85rem;
	background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 7%, transparent), transparent 60%);
}

.stage__label {
	font-family: var(--font-mono);
	font-size: var(--fs-micro);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--fg-faint);
}

.stage.is-done .stage__label {
	color: var(--accent);
}

.stage__name {
	font-family: var(--font-display);
	font-variation-settings: "wdth" 110, "wght" 660;
	font-size: clamp(1.0625rem, 1.9vw, 1.5rem);
	letter-spacing: -0.02em;
	text-transform: uppercase;
	color: #fff;
}

.stage__count {
	font-family: var(--font-mono);
	font-size: var(--fs-micro);
	color: var(--fg-faint);
	letter-spacing: 0.1em;
}

.stage__sign {
	position: relative;
	width: 14px;
	height: 14px;
	flex: none;
}

.stage__sign::before,
.stage__sign::after {
	content: "";
	position: absolute;
	background: var(--fg-soft);
	transition: transform var(--t-mid) var(--ease-out), background var(--t-mid) var(--ease);
}

.stage__sign::before {
	left: 0;
	right: 0;
	top: 50%;
	height: 1.5px;
	margin-top: -0.75px;
}

.stage__sign::after {
	top: 0;
	bottom: 0;
	left: 50%;
	width: 1.5px;
	margin-left: -0.75px;
}

.stage__toggle[aria-expanded="true"] .stage__sign::after {
	transform: scaleY(0);
}

.stage__toggle[aria-expanded="true"] .stage__sign::before {
	background: var(--accent);
}

.stage__panel {
	display: grid;
	grid-template-rows: 0fr;
	transition: grid-template-rows var(--t-slow) var(--ease-out);
}

.stage__panel > div {
	overflow: hidden;
}

.stage.is-open .stage__panel {
	grid-template-rows: 1fr;
}

.stage__features {
	list-style: none;
	margin: 0;
	padding: 0 0 var(--sp-6);
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
	gap: 1px;
	background: var(--line-soft);
	border: 1px solid var(--line-soft);
}

.stage__features li {
	background: var(--ink-000);
	padding: var(--sp-4) var(--sp-5);
	transition: background var(--t-mid) var(--ease);
}

.stage__features li:hover {
	background: var(--ink-050);
}

.stage__features b {
	display: block;
	font-family: var(--font-display);
	font-variation-settings: "wdth" 102, "wght" 620;
	font-size: 1rem;
	color: #fff;
	margin-bottom: 0.25rem;
	letter-spacing: -0.01em;
}

.stage__features span {
	color: var(--fg-soft);
	font-size: var(--fs-sm);
	line-height: 1.55;
}

/* Wrapper so the grid gap does not fight the collapse animation. */
.stage__panel .stage__features {
	margin-bottom: 0;
}

/* =========================================================================
   PROJECT INDEX CARDS
   ========================================================================= */

.project-index {
	display: grid;
	gap: 1px;
	background: var(--line-soft);
	border: 1px solid var(--line-soft);
}

.project-index__item {
	position: relative;
	background: var(--ink-000);
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 0.6fr);
	gap: var(--sp-5);
	align-items: center;
	padding: clamp(1.75rem, 4vw, 3rem);
	transition: background var(--t-mid) var(--ease);
	overflow: hidden;
}

.project-index__item::before {
	content: "";
	position: absolute;
	inset: 0;
	background: radial-gradient(60% 90% at 82% 50%, color-mix(in srgb, var(--accent) 13%, transparent), transparent 70%);
	opacity: 0;
	transition: opacity var(--t-slow) var(--ease);
}

.project-index__item:hover::before {
	opacity: 1;
}

.project-index__item > * {
	position: relative;
}

.project-index__text {
	font-size: var(--fs-sm);
	max-width: 50ch;
}

.project-index__name {
	font-size: clamp(1.75rem, 3.4vw, 3rem);
	font-variation-settings: "wdth" 116, "wght" 740;
	text-transform: uppercase;
	letter-spacing: -0.035em;
	line-height: 0.95;
	margin-block: 0.35rem 0.6rem;
}

.project-index__logo {
	justify-self: end;
	width: min(190px, 46%);
	transition: transform var(--t-slow) var(--ease-out);
	filter: drop-shadow(0 10px 30px color-mix(in srgb, var(--accent) 26%, transparent));
}

.project-index__item:hover .project-index__logo {
	transform: scale(1.07) rotate(-2deg);
}

/* =========================================================================
   POSTS AND ARCHIVES
   ========================================================================= */

.post-list {
	border-top: var(--border);
}

.post-row {
	display: grid;
	grid-template-columns: 9rem minmax(0, 1fr) auto;
	gap: var(--sp-5);
	align-items: baseline;
	padding-block: clamp(1.2rem, 2.5vw, 2rem);
	border-bottom: var(--border);
	transition: padding-left var(--t-mid) var(--ease-out), background var(--t-mid) var(--ease);
}

.post-row:hover {
	padding-left: 0.85rem;
	background: linear-gradient(90deg, rgba(58, 127, 232, 0.06), transparent 60%);
}

.post-row__date {
	font-family: var(--font-mono);
	font-size: var(--fs-micro);
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--fg-faint);
}

.post-row__title {
	font-family: var(--font-display);
	font-variation-settings: "wdth" 108, "wght" 640;
	font-size: clamp(1.125rem, 2vw, 1.625rem);
	letter-spacing: -0.02em;
	color: #fff;
}

.post-row__excerpt {
	color: var(--fg-soft);
	font-size: var(--fs-sm);
	margin-top: 0.4rem;
	max-width: 60ch;
}

.pagination {
	display: flex;
	gap: var(--sp-2);
	margin-top: var(--sp-7);
	font-family: var(--font-mono);
	font-size: var(--fs-sm);
}

.pagination .page-numbers {
	display: inline-grid;
	place-items: center;
	min-width: 42px;
	height: 42px;
	border: var(--border);
	color: var(--fg-soft);
	transition: border-color var(--t-mid) var(--ease), color var(--t-mid) var(--ease);
}

.pagination .page-numbers:hover,
.pagination .current {
	border-color: var(--ice);
	color: var(--ice);
}

/* =========================================================================
   CONTACT CHANNELS
   ========================================================================= */

.channels {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
	gap: 1px;
	background: var(--line-soft);
	border: 1px solid var(--line-soft);
	margin-top: var(--sp-6);
}

.channels a,
.channels div {
	background: var(--ink-000);
	padding: var(--sp-5);
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
	transition: background var(--t-mid) var(--ease);
}

.channels a:hover {
	background: var(--ink-100);
}

.channels .icon {
	color: var(--ice);
	margin-bottom: var(--sp-2);
}

.channels b {
	font-family: var(--font-display);
	font-variation-settings: "wdth" 104, "wght" 620;
	font-size: 1.0625rem;
	color: #fff;
}

.channels span {
	color: var(--fg-soft);
	font-size: var(--fs-sm);
	line-height: 1.55;
}

.channels code {
	color: var(--ice);
	font-size: var(--fs-sm);
	word-break: break-all;
}

/* =========================================================================
   404
   ========================================================================= */

.notfound {
	position: relative;
	min-height: 78svh;
	display: grid;
	place-items: center;
	text-align: center;
	padding-top: var(--header-h);
	overflow: hidden;
}

.notfound__title {
	font-size: var(--fs-h3);
	text-transform: uppercase;
	margin-top: var(--sp-5);
}

.notfound__text {
	margin: var(--sp-4) auto 0;
	max-width: 44ch;
}

.notfound__search {
	margin-top: var(--sp-7);
	display: flex;
	justify-content: center;
}

.notfound__code {
	font-family: var(--font-display);
	font-variation-settings: "wdth" 125, "wght" 800;
	font-size: clamp(6rem, 26vw, 20rem);
	line-height: 0.8;
	letter-spacing: -0.06em;
	color: transparent;
	-webkit-text-stroke: 1px var(--line-strong);
	position: relative;
}

.notfound__code::after {
	content: "404";
	position: absolute;
	inset: 0;
	color: var(--ice);
	-webkit-text-stroke: 0;
	clip-path: inset(44% 0 42% 0);
	animation: glitch 5.5s steps(1) infinite;
	opacity: 0.85;
}

@keyframes glitch {
	0%,
	86%,
	100% {
		transform: translate(0);
		clip-path: inset(44% 0 42% 0);
	}
	88% {
		transform: translate(-6px, 2px);
		clip-path: inset(22% 0 66% 0);
	}
	90% {
		transform: translate(5px, -3px);
		clip-path: inset(62% 0 20% 0);
	}
	92% {
		transform: translate(-3px, 0);
		clip-path: inset(38% 0 50% 0);
	}
}

/* =========================================================================
   RESPONSIVE
   ========================================================================= */

@media (max-width: 1100px) {
	/* The headline column keeps its nine tracks here. Narrowing it while the
	   type is still large clips the longest line. The mark gives way instead. */
	.hero__mark {
		grid-column: 9 / span 4;
		opacity: 0.85;
	}

	.manifesto__head {
		grid-column: 1 / span 12;
	}

	.manifesto__body {
		grid-column: 1 / span 7;
		grid-row: 2;
	}

	.manifesto__side {
		grid-column: 1 / span 12;
	}
}

@media (max-width: 900px) {
	.hero {
		min-height: auto;
		padding-bottom: 0;
	}

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

	.hero__lead {
		grid-column: 1 / -1;
		grid-row: 2;
	}

	.hero__mark {
		grid-column: 1 / -1;
		grid-row: 1;
		width: min(72%, 20rem);
		justify-self: start;
		margin-bottom: calc(var(--sp-5) * -1);
	}

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

	.hero__rail-item:nth-child(2n) {
		border-right: 0;
	}

	.hero__rail-item:nth-child(-n + 2) {
		border-bottom: var(--border);
	}

	.hero__rail-item:nth-child(3) {
		padding-left: 0;
	}

	.hero__scroll {
		display: none;
	}

	.values__head,
	.showcase__grid,
	.contribute__grid,
	.project-hero__grid {
		grid-template-columns: minmax(0, 1fr);
	}

	.showcase:nth-child(even) .showcase__grid {
		direction: ltr;
	}

	.showcase__visual {
		order: -1;
		aspect-ratio: 4 / 3;
	}

	.project-hero__visual {
		order: -1;
		aspect-ratio: 3 / 2;
	}

	.project-hero__logo {
		width: 44%;
	}

	.ledger__row {
		grid-template-columns: 3rem minmax(0, 1fr);
		gap: 0.35rem var(--sp-4);
	}

	.ledger__text {
		grid-column: 2;
	}

	.ledger__glyph {
		display: none;
	}

	.stage__toggle {
		grid-template-columns: minmax(0, 1fr) auto;
		gap: 0.35rem var(--sp-4);
		row-gap: 0.4rem;
	}

	.stage__label {
		grid-column: 1;
	}

	.stage__name {
		grid-column: 1;
	}

	.stage__count {
		grid-column: 1;
	}

	.stage__sign {
		grid-column: 2;
		grid-row: 1 / span 3;
		align-self: center;
	}

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

	.project-index__logo {
		justify-self: start;
		width: 130px;
		order: -1;
	}

	.post-row {
		grid-template-columns: minmax(0, 1fr);
		gap: 0.4rem;
	}
}

@media (max-width: 620px) {
	.manifesto__head,
	.manifesto__body,
	.manifesto__side {
		grid-column: 1 / -1;
		grid-row: auto;
	}

	.manifesto__side {
		border-left: 0;
		border-top: 2px solid rgba(10, 14, 29, 0.12);
		padding-left: 0;
		padding-top: var(--sp-5);
	}

	.showcase__foot {
		flex-direction: column;
		align-items: flex-start;
	}

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

	.hero__rail-item {
		flex-direction: row;
		justify-content: space-between;
		align-items: baseline;
		border-right: 0;
		border-bottom: var(--border);
		padding-inline: 0;
	}

	.hero__rail-item:last-of-type {
		border-bottom: 0;
	}

	.btn {
		width: 100%;
		justify-content: space-between;
	}

	.btn-row {
		width: 100%;
	}
}
