/* =========================================================================
   Dead Pixels / 02 components
   Buttons, links, labels, meters, tickers, edges and shared surfaces.
   ========================================================================= */

/* -------------------------------------------------------------------------
   shell + rhythm
   ---------------------------------------------------------------------- */

.shell {
	width: 100%;
	max-width: var(--shell);
	margin-inline: auto;
	padding-inline: var(--gutter);
}

.shell--narrow {
	max-width: 980px;
}

.section {
	position: relative;
	padding-block: var(--sp-section);
}

.section--tight {
	padding-block: clamp(3rem, 2rem + 4vw, 5.5rem);
}

.section--intro {
	padding-block: clamp(3rem, 6vw, 5.5rem) 0;
}

.section--split {
	padding-block: clamp(3rem, 6vw, 5rem);
}

.section--related {
	border-top: var(--border);
	padding-block: clamp(2.5rem, 5vw, 4rem);
}

.section--flush-top {
	padding-top: 0;
}

.stack > * + * {
	margin-top: var(--sp-4);
}

.stack-lg > * + * {
	margin-top: var(--sp-6);
}

/* -------------------------------------------------------------------------
   utilities
   The full set. Anything not covered here belongs in a component rule.
   ---------------------------------------------------------------------- */

.u-mt {
	margin-top: var(--sp-6);
}

.u-mt-sm {
	margin-top: var(--sp-5);
}

.u-mt-lg {
	margin-top: var(--sp-8);
}

.u-mb-sm {
	margin-bottom: var(--sp-5);
}

.u-flush {
	margin: 0;
}

.u-measure {
	max-width: 44ch;
}

.u-measure-wide {
	max-width: 56ch;
}

.u-center {
	justify-content: center;
	text-align: center;
}

/* Section label used as a heading above a block of content. */
.section-label {
	font-family: var(--font-mono);
	font-size: var(--fs-label);
	font-weight: 500;
	letter-spacing: var(--track-label);
	text-transform: uppercase;
	color: var(--fg-faint);
	margin-bottom: var(--sp-5);
}

.section-label + * {
	margin-top: 0;
}

/* -------------------------------------------------------------------------
   backdrops
   ---------------------------------------------------------------------- */

/* Fine engineering grid. Two layers: a faint mesh and stronger crosses. */
.grid-bg::before {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background-image:
		linear-gradient(to right, var(--line-soft) 1px, transparent 1px),
		linear-gradient(to bottom, var(--line-soft) 1px, transparent 1px);
	background-size: var(--grid-cell) var(--grid-cell);
	-webkit-mask-image: radial-gradient(120% 90% at 50% 0%, #000 0%, transparent 78%);
	mask-image: radial-gradient(120% 90% at 50% 0%, #000 0%, transparent 78%);
	z-index: 0;
}

/* Pixel dust: sparse squares, denser near the top edge. */
.dust::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background-image: radial-gradient(rgba(111, 210, 245, 0.5) 1px, transparent 1px);
	background-size: 68px 68px;
	background-position: 12px 30px;
	opacity: 0.22;
	z-index: 0;
}

.section > .shell {
	position: relative;
	z-index: 1;
}

/* -------------------------------------------------------------------------
   eyebrow
   ---------------------------------------------------------------------- */

.eyebrow {
	display: flex;
	align-items: center;
	gap: 0.85rem;
	font-family: var(--font-mono);
	font-size: var(--fs-label);
	font-weight: 500;
	letter-spacing: var(--track-label);
	text-transform: uppercase;
	color: var(--fg-faint);
	margin-bottom: var(--sp-5);
}

.eyebrow__index {
	color: var(--accent);
	font-weight: 600;
}

.eyebrow__rule {
	width: clamp(1.5rem, 4vw, 4rem);
	height: 1px;
	background: linear-gradient(90deg, var(--accent), transparent);
	flex: none;
}

.on-paper .eyebrow {
	color: var(--paper-ink-soft);
}

.on-paper .eyebrow__index {
	color: var(--royal);
}

.on-paper .eyebrow__rule {
	background: linear-gradient(90deg, var(--royal), transparent);
}

/* -------------------------------------------------------------------------
   buttons
   ---------------------------------------------------------------------- */

.btn {
	--btn-fg: var(--ink-000);
	--btn-bg: var(--ice);
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 0.7rem;
	padding: 0.9rem 1.25rem;
	font-family: var(--font-mono);
	font-size: var(--fs-sm);
	font-weight: 500;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--btn-fg);
	background: var(--btn-bg);
	border: 1px solid transparent;
	border-radius: var(--radius);
	overflow: hidden;
	isolation: isolate;
	transition: color var(--t-mid) var(--ease), border-color var(--t-mid) var(--ease),
		transform var(--t-fast) var(--ease);
	min-height: 48px;
}

/* Wipe fill that sweeps in from the left on hover. */
.btn::before {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--ink-000);
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform var(--t-mid) var(--ease-out);
	z-index: -1;
}

.btn:hover::before,
.btn:focus-visible::before {
	transform: scaleX(1);
}

.btn:hover,
.btn:focus-visible {
	color: var(--ice);
	border-color: var(--ice);
}

.btn:active {
	transform: translateY(1px);
}

.btn__icon {
	display: inline-flex;
	transition: transform var(--t-mid) var(--ease-out);
}

.btn:hover .btn__icon {
	transform: translateX(4px);
}

.btn--ghost {
	--btn-bg: transparent;
	--btn-fg: var(--fg);
	border-color: var(--line-strong);
}

.btn--ghost::before {
	background: var(--ice);
}

.btn--ghost:hover,
.btn--ghost:focus-visible {
	color: var(--ink-000);
	border-color: var(--ice);
}

.btn--quiet {
	--btn-bg: transparent;
	--btn-fg: var(--fg-soft);
	border-color: transparent;
	padding-inline: 0.25rem;
}

.btn--quiet::before {
	display: none;
}

.btn--quiet:hover,
.btn--quiet:focus-visible {
	color: var(--ice);
	border-color: transparent;
}

.on-paper .btn {
	--btn-bg: var(--royal);
	--btn-fg: #fff;
}

.on-paper .btn::before {
	background: var(--paper-ink);
}

.on-paper .btn:hover,
.on-paper .btn:focus-visible {
	color: #fff;
	border-color: var(--paper-ink);
}

.on-paper .btn--ghost {
	--btn-bg: transparent;
	--btn-fg: var(--paper-ink);
	border-color: rgba(10, 14, 29, 0.25);
}

.on-paper .btn--ghost::before {
	background: var(--royal);
}

.btn-row {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-3);
	align-items: center;
}

/* -------------------------------------------------------------------------
   links
   ---------------------------------------------------------------------- */

.link {
	position: relative;
	display: inline-flex;
	align-items: baseline;
	gap: 0.4em;
	color: var(--accent);
	font-weight: 500;
	padding-bottom: 1px;
}

/* Underline wipes out to the right and back in from the left. */
.link::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 1px;
	background: currentColor;
	transform-origin: right center;
	transform: scaleX(1);
	transition: transform var(--t-mid) var(--ease-in-out);
}

.link:hover::after,
.link:focus-visible::after {
	transform-origin: left center;
	animation: link-wipe var(--t-slow) var(--ease-in-out);
}

@keyframes link-wipe {
	0% {
		transform: scaleX(1);
		transform-origin: right center;
	}
	49% {
		transform: scaleX(0);
		transform-origin: right center;
	}
	50% {
		transform: scaleX(0);
		transform-origin: left center;
	}
	100% {
		transform: scaleX(1);
		transform-origin: left center;
	}
}

/* Prose links inside editor content. */
.prose a:not(.btn):not(.link) {
	color: var(--ice);
	background-image: linear-gradient(currentColor, currentColor);
	background-size: 100% 1px;
	background-repeat: no-repeat;
	background-position: 0 100%;
	transition: background-size var(--t-mid) var(--ease), color var(--t-mid) var(--ease);
}

.prose a:not(.btn):not(.link):hover {
	background-size: 0% 1px;
	color: #fff;
}

/* -------------------------------------------------------------------------
   tags and status
   ---------------------------------------------------------------------- */

.tag {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	padding: 0.3rem 0.6rem;
	border: 1px solid var(--line);
	border-radius: var(--radius);
	font-family: var(--font-mono);
	font-size: var(--fs-micro);
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--fg-soft);
	background: rgba(255, 255, 255, 0.015);
}

.tag--accent {
	border-color: color-mix(in srgb, var(--accent) 45%, transparent);
	color: var(--accent);
}

.status {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-family: var(--font-mono);
	font-size: var(--fs-micro);
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--fg-soft);
}

.status__dot {
	width: 7px;
	height: 7px;
	background: var(--accent);
	flex: none;
	box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 60%, transparent);
	animation: pulse 2.6s var(--ease-in-out) infinite;
}

@keyframes pulse {
	0%,
	100% {
		box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent);
	}
	60% {
		box-shadow: 0 0 0 7px transparent;
	}
}

/* -------------------------------------------------------------------------
   meter
   ---------------------------------------------------------------------- */

.meter {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	flex-wrap: wrap;
}

.meter__cells {
	display: flex;
	flex-wrap: wrap;
	gap: 3px;
}

.meter__cell {
	width: 16px;
	height: 8px;
	background: var(--line);
	transition: background var(--t-mid) var(--ease), transform var(--t-mid) var(--ease);
}

.meter__cell.is-done {
	background: var(--accent);
}

.meter__cell.is-active {
	background: color-mix(in srgb, var(--accent) 45%, transparent);
	animation: meter-blink 1.9s steps(2, jump-none) infinite;
}

@keyframes meter-blink {
	50% {
		opacity: 0.35;
	}
}

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

/* -------------------------------------------------------------------------
   ticker
   ---------------------------------------------------------------------- */

.ticker {
	overflow: hidden;
	border-block: var(--border);
	padding-block: 0.85rem;
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
	mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}

.ticker__track {
	display: flex;
	width: max-content;
	animation: ticker 46s linear infinite;
}

.ticker__item {
	display: inline-flex;
	align-items: center;
	gap: 1.6rem;
	padding-inline: 1.6rem;
	font-family: var(--font-display);
	font-variation-settings: "wdth" 122, "wght" 700;
	font-size: clamp(1.4rem, 3.4vw, 2.6rem);
	letter-spacing: -0.02em;
	text-transform: uppercase;
	color: transparent;
	-webkit-text-stroke: 1px var(--line-strong);
	white-space: nowrap;
}

.ticker__item .icon {
	color: var(--accent);
	-webkit-text-stroke: 0;
	flex: none;
}

.ticker:hover .ticker__track {
	animation-play-state: paused;
}

@keyframes ticker {
	to {
		transform: translateX(-50%);
	}
}

/* -------------------------------------------------------------------------
   pixel edge between dark and light regions
   ---------------------------------------------------------------------- */

/* The strip is painted in the color of the section above it, and the teeth
   are the color of the section below, always rising from the baseline. The
   teeth are drawn 3 units taller than they read so the bob never lifts one
   clear of the bottom edge. */
.pixel-edge {
	position: relative;
	line-height: 0;
	height: clamp(28px, 4vw, 56px);
	overflow: hidden;
}

.pixel-edge svg {
	width: 100%;
	height: 100%;
	display: block;
}

.pixel-edge--down {
	background: var(--bg);
}

.pixel-edge--down svg {
	fill: var(--paper);
}

.pixel-edge--up {
	background: var(--paper);
}

.pixel-edge--up svg {
	fill: var(--bg);
}

/* Each tooth drifts on its own offset so the edge breathes instead of sitting
   still. Two alternate durations keep it from settling into a visible wave. */
.pixel-edge rect {
	animation: edge-bob 7.5s var(--ease-in-out) infinite alternate;
	animation-delay: calc(var(--i, 0) * -0.43s);
}

.pixel-edge rect:nth-child(3n) {
	animation-duration: 10.5s;
}

.pixel-edge rect:nth-child(4n + 1) {
	animation-duration: 5.5s;
}

@keyframes edge-bob {
	to {
		transform: translateY(-1.6px);
	}
}

/* -------------------------------------------------------------------------
   light region
   ---------------------------------------------------------------------- */

.on-paper {
	background: var(--paper);
	color: var(--paper-ink);
}

.on-paper .dim,
.on-paper .lead {
	color: var(--paper-ink-soft);
}

.on-paper .label,
.on-paper .micro {
	color: rgba(10, 14, 29, 0.64);
}

.on-paper strong {
	color: var(--paper-ink);
}

.on-paper .tag {
	border-color: rgba(10, 14, 29, 0.18);
	color: var(--paper-ink-soft);
	background: rgba(10, 14, 29, 0.03);
}

.on-paper ::selection {
	background: var(--royal);
	color: #fff;
}

/* -------------------------------------------------------------------------
   callout
   The single boxed element on the site. Used where an action is the point of
   the section rather than a footnote to it.
   ---------------------------------------------------------------------- */

.callout {
	position: relative;
	margin-top: var(--sp-6);
	padding: clamp(1.25rem, 3vw, 2rem);
	border: var(--border);
	border-radius: var(--radius-lg);
	background:
		radial-gradient(120% 140% at 0% 0%, rgba(58, 127, 232, 0.09), transparent 60%),
		var(--ink-050);
	overflow: hidden;
}

/* Corner tick, the same interface furniture used on the project panels. */
.callout::after {
	content: "";
	position: absolute;
	top: 12px;
	right: 12px;
	width: 12px;
	height: 12px;
	border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
	border-left: 0;
	border-bottom: 0;
}

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

.callout__text {
	color: var(--fg-soft);
	max-width: 46ch;
}

.callout__address {
	font-family: var(--font-mono);
	font-size: clamp(1rem, 2.2vw, 1.375rem);
	letter-spacing: -0.01em;
	word-break: break-all;
}

.callout__address a {
	color: #fff;
	background-image: linear-gradient(var(--accent), var(--accent));
	background-repeat: no-repeat;
	background-position: 0 100%;
	background-size: 100% 1px;
	transition: background-size var(--t-mid) var(--ease), color var(--t-mid) var(--ease);
}

.callout__address a:hover,
.callout__address a:focus-visible {
	color: var(--accent);
	background-size: 100% 2px;
}

/* -------------------------------------------------------------------------
   rules and dividers
   ---------------------------------------------------------------------- */

.rule {
	height: 1px;
	background: var(--line);
	border: 0;
}

/* Three offset hairlines echoing the nested strokes in the mark. */
.rule--layered {
	height: 5px;
	background:
		linear-gradient(var(--line-strong), var(--line-strong)) 0 0 / 100% 1px no-repeat,
		linear-gradient(var(--line), var(--line)) 0 2px / 68% 1px no-repeat,
		linear-gradient(var(--line-soft), var(--line-soft)) 0 4px / 32% 1px no-repeat;
}

/* -------------------------------------------------------------------------
   reveal on scroll
   ---------------------------------------------------------------------- */

[data-reveal] {
	opacity: 0;
	transform: translateY(22px);
	transition:
		opacity var(--t-slow) var(--ease-out),
		transform var(--t-slow) var(--ease-out);
	transition-delay: var(--reveal-delay, 0ms);
}

[data-reveal].is-in {
	opacity: 1;
	transform: none;
}

[data-reveal="rise"] {
	transform: translateY(40px);
}

[data-reveal="slide"] {
	transform: translateX(-28px);
}

[data-reveal="mask"] {
	clip-path: inset(0 100% 0 0);
	opacity: 1;
	transform: none;
	transition: clip-path var(--t-slow) var(--ease-out);
}

[data-reveal="mask"].is-in {
	clip-path: inset(0 0 0 0);
}

.no-motion [data-reveal],
.no-js [data-reveal] {
	opacity: 1 !important;
	transform: none !important;
	clip-path: none !important;
}

/* -------------------------------------------------------------------------
   icons
   ---------------------------------------------------------------------- */

.icon {
	flex: none;
	vertical-align: middle;
}

.icon--star {
	fill: currentColor;
	stroke: none;
}

.icon--signal {
	fill: currentColor;
	stroke: none;
}

/* -------------------------------------------------------------------------
   prose (editor content)
   ---------------------------------------------------------------------- */

.prose {
	max-width: var(--measure);
}

.prose > * + * {
	margin-top: 1.15em;
}

.prose h2 {
	font-size: var(--fs-h3);
	margin-top: 2.4em;
	margin-bottom: 0.2em;
}

.prose h3 {
	font-size: var(--fs-h4);
	margin-top: 2em;
	margin-bottom: 0.2em;
}

.prose h2 + p,
.prose h3 + p {
	margin-top: 0.6em;
}

.prose ul,
.prose ol {
	padding-left: 1.2rem;
	color: var(--fg-soft);
}

.prose li + li {
	margin-top: 0.5em;
}

.prose ul {
	list-style: none;
	padding-left: 0;
}

.prose ul li {
	position: relative;
	padding-left: 1.6rem;
}

.prose ul li::before {
	content: "";
	position: absolute;
	left: 0.15rem;
	top: 0.62em;
	width: 6px;
	height: 6px;
	background: var(--accent);
	transform: rotate(45deg);
}

.prose blockquote {
	border-left: 2px solid var(--accent);
	padding: 0.2rem 0 0.2rem 1.4rem;
	font-size: var(--fs-lead);
	line-height: 1.45;
	color: var(--fg);
	font-family: var(--font-display);
	font-variation-settings: "wdth" 100, "wght" 500;
}

.prose img {
	border: var(--border);
}

.prose code {
	background: var(--ink-100);
	border: var(--border);
	padding: 0.1em 0.35em;
	color: var(--ice);
}

.prose pre {
	background: var(--ink-050);
	border: var(--border);
	padding: var(--sp-5);
	overflow-x: auto;
}

.prose hr {
	border: 0;
	height: 1px;
	background: var(--line);
	margin-block: 2.4em;
}

.prose p {
	color: var(--fg-soft);
}

.prose > p:first-child {
	color: var(--fg);
	font-size: var(--fs-lead);
	line-height: 1.5;
}

.on-paper .prose p,
.on-paper .prose ul,
.on-paper .prose ol {
	color: var(--paper-ink-soft);
}

/* -------------------------------------------------------------------------
   forms
   ---------------------------------------------------------------------- */

input[type="text"],
input[type="email"],
input[type="search"],
input[type="url"],
textarea {
	width: 100%;
	background: var(--ink-050);
	border: var(--border);
	border-radius: var(--radius);
	padding: 0.8rem 0.9rem;
	color: var(--fg);
	transition: border-color var(--t-mid) var(--ease), background var(--t-mid) var(--ease);
}

input::placeholder,
textarea::placeholder {
	color: var(--fg-faint);
}

input:focus,
textarea:focus {
	border-color: var(--ice);
	background: var(--ink-100);
}

.search-form {
	display: flex;
	gap: var(--sp-2);
	max-width: 460px;
}

.search-form label {
	flex: 1;
}
