/* ALLEN — the face: the form.intelligence skin.
 *
 * Ported from form.intelligence's console token system
 * (form-intelligence/apps/console/src/styles/tokens.css), itself canonical to
 * FORM-PRESENTATION-SYSTEM.md v2.1. Values are copied, not re-derived — that is
 * how two surfaces of one brand stay one brand.
 *
 * Two token layers, and they are not redundant:
 *   1. form. tokens (--signal, --ink, --base, --line) carry the brand. Edit
 *      these to move the palette.
 *   2. Allen's semantic bridge (--bg, --fg, --muted, --border, --sev-*) is
 *      defined only in terms of layer 1, so every room re-skins without a
 *      single template change.
 *
 * Law, from the source system:
 *   - Satoshi displays · League Spartan speaks (body + uppercase labels) ·
 *     Manrope 700 tabular is the numeral face only · no monospace brand voice
 *     (real captured logs keep --font-code for column alignment).
 *   - Tracking poles are the fingerprint: -0.06em display, -0.03em numeral,
 *     0.08em label. Never invent one.
 *   - Light-led, and there is no dark mode.
 * Mobile-first: base rules target the smallest viewport; wider layouts are
 * progressive enhancement via min-width media queries.
 */

@font-face { font-family: "Satoshi"; src: url("fonts/satoshi-500.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Satoshi"; src: url("fonts/satoshi-700.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Satoshi"; src: url("fonts/satoshi-900.woff2") format("woff2"); font-weight: 900; font-style: normal; font-display: swap; }
@font-face { font-family: "Manrope Variable"; src: url("fonts/manrope-var.woff2") format("woff2-variations"); font-weight: 200 800; font-style: normal; font-display: swap; }
@font-face { font-family: "League Spartan"; src: url("fonts/leaguespartan-var.woff2") format("woff2-variations"); font-weight: 100 900; font-style: normal; font-display: swap; }

:root {
	color-scheme: light;

	/* ── layer 1 · form. tokens (the brand) ──────────────────────────── */
	/* Signal — royal blue, the one interactive accent. */
	--signal: #3d6bff;
	--signal-deep: #2e54d8;
	--signal-text: #375fe6;      /* small text only — measured AA on bone */
	--signal-wash: rgba(61, 107, 255, 0.10);
	--signal-line: rgba(61, 107, 255, 0.34);

	/* Ink on bone. */
	--ink: #0b0d12;
	--ink-soft: rgba(11, 13, 18, 0.76);
	--ink-faint: rgba(11, 13, 18, 0.56);
	--ink-dim: rgba(11, 13, 18, 0.60);
	--ink-ghost: rgba(11, 13, 18, 0.22);
	--line: rgba(11, 13, 18, 0.12);
	--line-strong: rgba(11, 13, 18, 0.22);

	/* Paper. */
	--base: #fafafa;
	--base-raise: #ffffff;
	--base-deep: #f4f5f7;

	/* State signals — status reads from these, so "failed" and "stop" cannot
	 * drift into two different reds. Anchored on form's live/warn/stop. */
	--live: #16794b;
	--warn: #8a5a00;
	--stop: #b3261e;

	/* ── layer 2 · Allen's semantic bridge (no raw values below) ─────── */
	--bg: var(--base);
	--fg: var(--ink);
	--muted: var(--ink-dim);
	--border: var(--line);
	--surface: var(--base-raise);
	--surface-raised: var(--base-deep);
	--bone: #ffffff;

	/* Severity — the ranking accent. critical=stop and low=live come straight
	 * from the state signals; two warm steps sit between them. */
	--sev-critical: var(--stop);
	--sev-high: #b5560a;
	--sev-medium: var(--warn);
	--sev-low: var(--live);

	/* Neutral micro-scale for non-brand chrome only: status dots, quiet edges. */
	--ink-3: rgba(11, 13, 18, 0.44);
	--ink-4: rgba(11, 13, 18, 0.30);

	/* form radius + rhythm. */
	--radius: 14px;
	--radius-sm: 10px;
	--space-1: 4px;
	--space-2: 8px;
	--space-3: 16px;
	--space-4: 24px;
	--space-5: 40px;

	/* Type scale for chrome (labels 11–14px; reading copy is 15.5px on body). */
	--text-xs: 0.75rem;
	--text-sm: 0.875rem;
	--text-base: 1rem;
	--text-lg: 1.25rem;
	--text-xl: 1.75rem;

	/* Tracking poles — the fingerprint. */
	--track-display: -0.06em;
	--track-numeral: -0.03em;
	--track-label: 0.08em;

	/* Voices. --font-mono IS the League Spartan label voice, so every uppercase
	 * chrome element that already asks for it becomes the metadata voice; only
	 * genuinely captured logs opt into --font-code for monospace alignment. */
	--font-display: "Satoshi", -apple-system, BlinkMacSystemFont, "Segoe UI", ui-sans-serif, sans-serif;
	--font-sans: "League Spartan", "Helvetica Neue", Arial, sans-serif;
	--font-label: "League Spartan", "Helvetica Neue", Arial, sans-serif;
	--font-numeral: "Manrope Variable", "Manrope", ui-sans-serif, system-ui, sans-serif;
	--font-mono: var(--font-label);
	--font-code: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
		"Liberation Mono", monospace;
}

* {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	background: var(--bg);
	color: var(--fg);
	font-family: var(--font-sans);
	font-size: 15.5px;
	line-height: 1.62;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

a {
	color: inherit;
}

/* One signal ring everywhere focus lands — brand and accessibility at once. */
a:focus-visible,
button:focus-visible,
summary:focus-visible {
	outline: 2px solid var(--signal);
	outline-offset: 2px;
	border-radius: var(--radius-sm);
}

/* ---- type scale — Satoshi display ladder (form leads' sizes, verbatim) ---- */

h1, h2, h3 {
	font-family: var(--font-display);
	font-weight: 600;
	letter-spacing: var(--track-display);
}

h1 {
	font-size: clamp(28px, 3.6vw, 40px);
	line-height: 1;
	margin: 0 0 var(--space-3);
}

h2 {
	font-size: clamp(19px, 2.2vw, 24px);
	line-height: 1.12;
	margin: 0 0 var(--space-2);
}

h3 {
	font-size: clamp(16px, 1.7vw, 18px);
	line-height: 1.2;
	margin: 0 0 var(--space-2);
}

/* ---- shell ---- */

.shell-header {
	position: sticky;
	top: 0;
	z-index: 10;
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: var(--space-3);
	background: var(--bg);
	border-bottom: 1px solid var(--border);
}

.shell-brand {
	font-family: var(--font-label);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: var(--track-label);
	text-decoration: none;
	flex: none;
}

/* Persistent room nav — every room is one tap from every other, not only
 * from home. Label voice; the current room reads in signal. Mobile-first:
 * the bar scrolls sideways rather than wrapping or crowding a 320px header. */
.shell-nav {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	overflow-x: auto;
	scrollbar-width: none;
}
.shell-nav::-webkit-scrollbar {
	display: none;
}
.shell-nav a {
	font-family: var(--font-label);
	text-transform: uppercase;
	letter-spacing: var(--track-label);
	font-weight: 600;
	font-size: var(--text-xs);
	color: var(--muted);
	text-decoration: none;
	white-space: nowrap;
	padding: 4px 0;
	border-bottom: 2px solid transparent;
}
.shell-nav a:hover,
.shell-nav a:focus-visible {
	color: var(--fg);
}
.shell-nav a[aria-current="page"] {
	color: var(--signal-text);
	border-bottom-color: var(--signal);
}

/* Log out sits a little apart from the rooms — it's an action, not a room. */
.shell-nav-logout {
	margin-left: var(--space-2);
	padding-left: var(--space-3);
	border-left: 1px solid var(--border);
}

/* ---- login page ---- */
/* Standalone sign-in surface (no room nav). A single centered card on the
 * bone field; mobile-first, so the card is full-width on a 320px column and
 * simply centers on wider viewports. */
.login-main {
	min-height: 100dvh;
	display: grid;
	place-items: center;
	padding: var(--space-4);
}
.login-card {
	width: 100%;
	max-width: 22rem;
	padding: var(--space-5) var(--space-4);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--surface);
}
.login-brand {
	margin: 0 0 var(--space-3);
	font-family: var(--font-label);
	text-transform: uppercase;
	letter-spacing: var(--track-label);
	font-weight: 700;
	font-size: var(--text-xs);
	color: var(--muted);
}
.login-title {
	margin: 0 0 var(--space-1);
}
.login-sub {
	margin: 0 0 var(--space-4);
	color: var(--muted);
	font-size: var(--text-sm);
}
.login-error {
	margin: 0 0 var(--space-3);
	padding: var(--space-2) var(--space-3);
	border-radius: var(--radius-sm);
	border: 1px solid var(--sev-critical);
	color: var(--sev-critical);
	background: color-mix(in srgb, var(--sev-critical) 8%, transparent);
	font-size: var(--text-sm);
}
.login-form {
	display: grid;
	gap: var(--space-2);
}
.login-form label {
	font-size: var(--text-sm);
	font-weight: 600;
	color: var(--muted);
}
.login-form input {
	width: 100%;
	padding: var(--space-2);
	border: 1px solid var(--border);
	border-radius: var(--radius-sm);
	background: var(--bg);
	color: var(--fg);
	font: inherit;
}
.login-form input:focus-visible {
	outline: 2px solid var(--signal);
	outline-offset: 1px;
	border-color: var(--signal);
}
.login-form button {
	margin-top: var(--space-2);
	padding: var(--space-2) var(--space-3);
	border: 1px solid var(--signal);
	border-radius: var(--radius-sm);
	background: var(--signal);
	color: #ffffff;
	font: inherit;
	font-family: var(--font-label);
	text-transform: uppercase;
	letter-spacing: var(--track-label);
	font-weight: 600;
	cursor: pointer;
}
.login-form button:hover,
.login-form button:focus-visible {
	background: var(--signal-deep);
	border-color: var(--signal-deep);
}

.shell-main {
	padding: var(--space-3);
	max-width: 960px;
	margin: 0 auto;
}

/* Mobile-first nav: a stacked list of rooms. A wider viewport lays the
 * same rooms out as a row. */
.room-nav {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-2);
}

@media (min-width: 640px) {
	.room-nav {
		grid-template-columns: repeat(4, 1fr);
	}
}

.room-nav a {
	display: block;
	padding: var(--space-3);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--surface);
	text-decoration: none;
	font-weight: 600;
}

.room-nav a:hover,
.room-nav a:focus-visible {
	border-color: var(--signal-line);
	background: var(--signal-wash);
}

.room-nav .room-desc {
	display: block;
	margin-top: var(--space-1);
	font-weight: 400;
	font-size: 0.875rem;
	color: var(--muted);
}

/* ---- state system ---- */
/* Every room uses these four states consistently: nothing to show yet,
 * work in flight, something went wrong, or a completed result. */

.state-empty,
.state-loading,
.state-error,
.state-success {
	padding: var(--space-4);
	border-radius: var(--radius);
	border: 1px solid var(--border);
	text-align: center;
}

.state-empty {
	color: var(--muted);
	border-style: dashed;
}

.state-loading {
	color: var(--muted);
}

.state-error {
	border-color: var(--sev-critical);
	color: var(--sev-critical);
}

.state-success {
	border-color: var(--sev-low);
	color: var(--sev-low);
}

/* ---- severity tokens as elements ---- */

.sev-critical {
	color: var(--sev-critical);
}
.sev-high {
	color: var(--sev-high);
}
.sev-medium {
	color: var(--sev-medium);
}
.sev-low {
	color: var(--sev-low);
}

.sev-badge {
	display: inline-block;
	padding: 2px 8px;
	border-radius: 999px;
	font-size: 0.75rem;
	font-weight: 600;
	font-family: var(--font-mono);
	text-transform: uppercase;
	letter-spacing: 0.04em;
}
.sev-badge.sev-critical {
	background: color-mix(in srgb, var(--sev-critical) 15%, transparent);
}
.sev-badge.sev-high {
	background: color-mix(in srgb, var(--sev-high) 15%, transparent);
}
.sev-badge.sev-medium {
	background: color-mix(in srgb, var(--sev-medium) 15%, transparent);
}
.sev-badge.sev-low {
	background: color-mix(in srgb, var(--sev-low) 15%, transparent);
}

/* ---- register room ---- */

.register-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--space-2);
}

.register-row {
	padding: var(--space-3);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--surface);
}

.register-row-head {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--space-2);
}

.register-repo {
	font-weight: 600;
	font-family: var(--font-mono);
	font-size: var(--text-sm);
	margin-right: auto;
}

.boot-badge {
	display: inline-block;
	padding: 2px 8px;
	border-radius: 999px;
	font-size: var(--text-xs);
	font-weight: 600;
	font-family: var(--font-mono);
	text-transform: uppercase;
	letter-spacing: 0.04em;
}
.boot-badge.booted {
	color: var(--sev-low);
	background: color-mix(in srgb, var(--sev-low) 15%, transparent);
}
.boot-badge.not-booted {
	color: var(--sev-critical);
	background: color-mix(in srgb, var(--sev-critical) 15%, transparent);
}
.boot-badge.no-runs {
	color: var(--muted);
	background: var(--surface-raised);
}

.trend {
	font-family: var(--font-numeral);
	font-variant-numeric: tabular-nums;
	font-size: var(--text-xs);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}
.trend-healing {
	color: var(--sev-low);
}
.trend-rotting {
	color: var(--sev-critical);
}
.trend-flat {
	color: var(--muted);
}

.sev-row {
	margin-top: var(--space-2);
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-1);
}

.register-row-links {
	margin-top: var(--space-2);
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-3);
}

.register-link {
	font-family: var(--font-mono);
	font-size: var(--text-xs);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--fg);
	text-decoration: none;
	border-bottom: 1px solid var(--border);
}
.register-link:hover {
	color: var(--signal-text);
	border-bottom-color: currentColor;
}

/* ---- verdict room ---- */
/* The soul of the face: one run as a designed artifact. Mobile-first — every
 * rule below is written for a 320px column; nothing here needs width to be
 * readable, and no element sets a fixed width that could overflow. */

.verdict-room {
	display: grid;
	gap: var(--space-4);
}

.verdict-kicker {
	margin: 0 0 var(--space-1);
	font-family: var(--font-mono);
	font-size: var(--text-xs);
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--muted);
}

.verdict-hero {
	padding: var(--space-4);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--surface-raised);
}
.verdict-hero h1 {
	margin: 0 0 var(--space-2);
}
.verdict-hero-sub {
	margin: 0;
	color: var(--muted);
	max-width: 60ch;
}

/* The worst three seconds: a run that did not boot is the most carefully
 * handled state — a calm, dignified surface, not a red alarm. Severity color
 * appears as a single restrained left edge, never a full-bleed panic. */
.verdict-failed {
	border-left: 3px solid var(--sev-critical);
}
.verdict-failed h1 {
	color: var(--fg);
}
.verdict-booted {
	border-left: 3px solid var(--sev-low);
}

.verdict-meta {
	margin: 0;
	display: grid;
	gap: var(--space-2);
}
.verdict-meta div {
	display: grid;
	grid-template-columns: 1fr;
	gap: 2px;
}
.verdict-meta dt {
	font-size: var(--text-xs);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--muted);
}
.verdict-meta dd {
	margin: 0;
	font-size: var(--text-sm);
	word-break: break-word;
	overflow-wrap: anywhere;
}

@media (min-width: 640px) {
	.verdict-meta {
		grid-template-columns: repeat(3, 1fr);
	}
}

/* Diagnosis — the headline. Set apart and up front: the root cause is the
 * thing a human should read first. */
.verdict-diagnosis {
	padding: var(--space-4);
	border: 1px solid var(--ink-3);
	border-radius: var(--radius);
	background: var(--surface);
}
.diagnosis-card h2 {
	font-size: var(--text-lg);
	line-height: 1.25;
	margin: 0 0 var(--space-2);
}
.diagnosis-mechanism {
	margin: 0 0 var(--space-3);
	color: var(--fg);
	max-width: 68ch;
}

.verdict-section-title {
	margin: 0 0 var(--space-3);
}

.finding-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--space-2);
}

.finding-card {
	border: 1px solid var(--border);
	border-left: 3px solid currentColor;
	border-radius: var(--radius);
	background: var(--surface);
}
.finding {
	color: var(--fg);
}
.finding-summary {
	display: flex;
	align-items: baseline;
	gap: var(--space-2);
	flex-wrap: wrap;
	padding: var(--space-3);
	cursor: pointer;
	list-style: none;
}
.finding-summary::-webkit-details-marker {
	display: none;
}
.finding-title {
	font-weight: 600;
	overflow-wrap: anywhere;
}
.finding-body {
	padding: 0 var(--space-3) var(--space-3);
	display: grid;
	gap: var(--space-2);
}
.finding-mechanism {
	margin: 0;
	color: var(--muted);
	overflow-wrap: anywhere;
}
.finding-loc {
	margin: 0;
	font-size: var(--text-xs);
	color: var(--muted);
	overflow-wrap: anywhere;
}
.evidence-none {
	margin: 0;
	font-size: var(--text-sm);
	color: var(--muted);
	font-style: italic;
}

/* Evidence — log excerpts and captures, rendered as escaped preformatted
 * text. Scrolls inside its own box so a long line never widens the page. */
.finding-evidence {
	display: grid;
	gap: var(--space-2);
}
.evidence {
	margin: 0;
	border: 1px solid var(--border);
	border-radius: var(--radius);
	overflow: hidden;
}
.evidence-label {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	padding: var(--space-1) var(--space-2);
	background: var(--surface-raised);
	border-bottom: 1px solid var(--border);
	font-size: var(--text-xs);
}
.evidence-kind {
	font-family: var(--font-mono);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--muted);
}
.evidence-body {
	margin: 0;
	padding: var(--space-2);
	font-family: var(--font-code);
	font-size: var(--text-xs);
	line-height: 1.5;
	white-space: pre-wrap;
	overflow-wrap: anywhere;
	overflow-x: auto;
	max-height: 22rem;
	overflow-y: auto;
}

/* The honest closing block — the machine-enforced verdict on itself. */
.verdict-closing {
	padding: var(--space-4);
	border: 1px solid var(--border);
	border-top: 3px solid var(--sev-critical);
	border-radius: var(--radius);
	background: var(--surface);
}
.verdict-closing-title {
	margin: 0 0 var(--space-3);
	font-family: var(--font-mono);
	font-size: var(--text-sm);
	letter-spacing: 0.06em;
	color: var(--sev-critical);
}
.verdict-closing-list {
	margin: 0;
	padding-left: var(--space-3);
	display: grid;
	gap: var(--space-1);
}
.verdict-closing-list li {
	overflow-wrap: anywhere;
}
.verdict-closing-empty {
	margin: 0;
	color: var(--muted);
}

/* Machine values (cost, token counts, ids): the Manrope numeral face, tabular
 * so figures line up as they change. */
.mono {
	font-family: var(--font-numeral);
	font-variant-numeric: tabular-nums;
	letter-spacing: var(--track-numeral);
}

/* ---- theater room ---- */
/* The live view: a two-axis status and an appending stage log. Mobile-first —
 * a single 320px column; the log scrolls inside its own box (follow-tail) so a
 * long run never grows the page. */

.theater-room {
	display: grid;
	gap: var(--space-4);
}

.theater-stage {
	display: grid;
	gap: var(--space-3);
}

.theater-head h1 {
	margin: 0 0 var(--space-1);
}
.theater-runid {
	margin: 0;
	font-size: var(--text-xs);
	color: var(--muted);
	word-break: break-all;
}

.theater-status {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2) var(--space-4);
	padding: var(--space-3);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--surface-raised);
}
.theater-axis {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	font-size: var(--text-sm);
}
.theater-axis-label {
	font-family: var(--font-mono);
	font-size: var(--text-xs);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--muted);
}
.theater-dot {
	width: 9px;
	height: 9px;
	border-radius: 999px;
	background: var(--ink-4);
	flex: none;
}

/* Connection axis: are we listening? */
.theater-axis[data-axis="connection"][data-state="connecting"] .theater-dot {
	background: var(--sev-medium);
}
.theater-axis[data-axis="connection"][data-state="live"] .theater-dot {
	background: var(--sev-low);
}
.theater-axis[data-axis="connection"][data-state="closed"] .theater-dot {
	background: var(--ink-4);
}

/* Run axis: is work happening / finished? */
.theater-axis[data-axis="run"][data-state="running"] .theater-dot {
	background: var(--sev-high);
}
.theater-axis[data-axis="run"][data-state="done"] .theater-dot {
	background: var(--sev-low);
}
.theater-axis[data-state="live"] .theater-axis-label,
.theater-axis[data-state="done"] .theater-axis-label {
	color: var(--fg);
}

.theater-running {
	margin: 0;
	font-family: var(--font-mono);
	font-size: var(--text-xs);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--sev-high);
}

.theater-log {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--space-1);
	max-height: 26rem;
	overflow-y: auto;
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--surface);
}
.theater-log-empty {
	padding: var(--space-3);
	color: var(--muted);
	font-size: var(--text-sm);
}
.theater-log-row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--space-2);
	padding: var(--space-2) var(--space-3);
	border-bottom: 1px solid var(--border);
}
.theater-log-row:last-child {
	border-bottom: none;
}
.theater-log-stage {
	font-weight: 600;
}
.theater-log-status {
	font-size: var(--text-xs);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--muted);
}
.theater-log-row[data-status="passed"] .theater-log-status {
	color: var(--sev-low);
}
.theater-log-row[data-status="failed"] .theater-log-status {
	color: var(--sev-critical);
}
.theater-log-row[data-status="skipped"] .theater-log-status {
	color: var(--sev-medium);
}

/* ---- vault room ---- */

.vault-room {
	display: grid;
	gap: var(--space-4);
}

.vault-banner {
	margin: 0;
	text-align: left;
}

.vault-section h2 {
	margin-bottom: var(--space-3);
}

/* Shared form styling for both the register-project form and every
 * per-project add/rotate-entry form: a stacked, mobile-first field list —
 * label directly above its input, full-width inputs, no side-by-side layout
 * that would cramp a 320px viewport. */
.vault-form {
	display: grid;
	gap: var(--space-2);
	max-width: 28rem;
	padding: var(--space-3);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--surface);
}

.vault-form label {
	font-size: var(--text-sm);
	font-weight: 600;
	color: var(--muted);
}

.vault-form input {
	width: 100%;
	padding: var(--space-2);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--bg);
	color: var(--fg);
	font: inherit;
}

.vault-form input:focus-visible {
	outline: 2px solid var(--signal);
	outline-offset: 1px;
	border-color: var(--signal);
}

.vault-form button {
	justify-self: start;
	padding: var(--space-2) var(--space-3);
	border: 1px solid var(--signal);
	border-radius: var(--radius-sm);
	background: var(--signal);
	color: #ffffff;
	font: inherit;
	font-family: var(--font-label);
	text-transform: uppercase;
	letter-spacing: var(--track-label);
	font-weight: 600;
	cursor: pointer;
}

.vault-form button:hover,
.vault-form button:focus-visible {
	background: var(--signal-deep);
	border-color: var(--signal-deep);
}

.vault-project-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--space-3);
}

.vault-project {
	display: grid;
	gap: var(--space-2);
	padding: var(--space-3);
	border: 1px solid var(--border);
	border-radius: var(--radius);
	background: var(--surface-raised);
}

.vault-project-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
}

.vault-repo {
	font-weight: 600;
}

.vault-entry-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
}

.vault-entry {
	padding: 2px 8px;
	border-radius: 999px;
	background: var(--surface);
	border: 1px solid var(--border);
	font-size: var(--text-xs);
}

.vault-entries-empty {
	padding: var(--space-2);
	text-align: left;
}

.vault-entry-form {
	max-width: none;
	background: transparent;
	border-style: dashed;
}
