/*! Strand UI v0.5.0 | MIT License | dillingerstaffing.com */

/* Alert */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-alert {
	position: relative;
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	width: 100%;
	padding: var(--strand-space-6);
	border-radius: var(--strand-radius-md);
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-sm);
	background: var(--strand-surface-recessed);
}

/* ── Status variants (neutral background, status color on prefix only) ── */
.strand-alert--info {
	background: var(--strand-surface-recessed);
}

.strand-alert--success {
	background: var(--strand-surface-recessed);
}

.strand-alert--warning {
	background: var(--strand-surface-recessed);
}

.strand-alert--error {
	background: var(--strand-surface-recessed);
}

/* ── Status prefix ── */
.strand-alert__status {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-semibold);
	letter-spacing: var(--strand-tracking-wider);
	text-transform: uppercase;
	margin-right: var(--strand-space-3);
	flex-shrink: 0;
}

.strand-alert--info .strand-alert__status {
	color: var(--strand-blue-primary);
}
.strand-alert--success .strand-alert__status {
	color: var(--strand-teal-vital);
}
.strand-alert--warning .strand-alert__status {
	color: var(--strand-amber-caution);
}
.strand-alert--error .strand-alert__status {
	color: var(--strand-red-alert);
}

/* ── Content ── */
.strand-alert__content {
	flex: 1;
	min-width: 0;
}

/* ── Dismiss button ── */
.strand-alert__dismiss {
	flex-shrink: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--strand-space-6);
	height: var(--strand-space-6);
	margin-left: var(--strand-space-4);
	padding: 0;
	border: none;
	border-radius: var(--strand-radius-md);
	background: transparent;
	color: var(--strand-gray-500);
	font-size: var(--strand-text-base);
	cursor: pointer;
	transition: background var(--strand-duration-fast) var(--strand-ease-out-quart), color
		var(--strand-duration-fast) var(--strand-ease-out-quart);
}

.strand-alert__dismiss:hover {
	background: var(--strand-gray-100);
	color: var(--strand-gray-600);
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-alert__dismiss {
		transition: none;
	}
}

/* Avatar */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-avatar {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: var(--strand-radius-full);
	background: var(--strand-surface-recessed);
	overflow: hidden;
	flex-shrink: 0;
	font-family: var(--strand-font-sans);
	font-weight: var(--strand-weight-medium);
	color: var(--strand-gray-600);
	user-select: none;
}

/* ── Image ── */
.strand-avatar__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	border-radius: var(--strand-radius-full);
}

/* ── Initials ── */
.strand-avatar__initials {
	text-transform: uppercase;
	line-height: 1;
}

/* ── Sizes ── */
.strand-avatar--sm {
	width: 32px;
	height: 32px;
	font-size: var(--strand-text-xs);
}

.strand-avatar--md {
	width: 40px;
	height: 40px;
	font-size: var(--strand-text-sm);
}

.strand-avatar--lg {
	width: 48px;
	height: 48px;
	font-size: var(--strand-text-base);
}

.strand-avatar--xl {
	width: var(--strand-space-16);
	height: var(--strand-space-16);
	font-size: var(--strand-text-lg);
}

/* Badge */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Wrapper ── */
.strand-badge {
	position: relative;
	display: inline-flex;
	vertical-align: middle;
}

.strand-badge--inline {
	display: inline-flex;
}

/* ── Indicator (shared) ── */
.strand-badge__indicator {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-family: var(--strand-font-sans);
	font-weight: var(--strand-weight-semibold);
	color: var(--strand-on-blue-primary);
}

/* Position at top-right when wrapping children */
.strand-badge:not(.strand-badge--inline) > .strand-badge__indicator {
	position: absolute;
	top: 0;
	right: 0;
	transform: translate(50%, -50%);
	z-index: 1;
}

/* ── Dot variant ── */
.strand-badge--dot {
	width: 8px;
	height: 8px;
	border-radius: var(--strand-radius-full);
	font-size: 0;
	padding: 0;
}

/* ── Count variant ── */
.strand-badge--count {
	min-width: 20px;
	height: 20px;
	padding: 0 var(--strand-space-1);
	border-radius: var(--strand-radius-full);
	font-size: var(--strand-text-xs);
	line-height: 20px;
}

/* ── Status colors ── */
.strand-badge--default {
	background: var(--strand-gray-500);
}

.strand-badge--teal {
	background: var(--strand-teal-vital);
}

.strand-badge--blue {
	background: var(--strand-blue-primary);
}

.strand-badge--amber {
	background: var(--strand-amber-caution);
	color: var(--strand-blue-midnight);
}

.strand-badge--red {
	background: var(--strand-red-alert);
}

/* Banner */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Banner (DL Part XI.6: page-level persistent alert) ──
   Fixed to top of viewport. Pushes page content down.
   System-wide status: maintenance, announcements, warnings. */
.strand-banner {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 101;
	padding: var(--strand-space-3) var(--strand-space-4);
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-sm);
	line-height: var(--strand-leading-normal);
	text-align: center;
	border-bottom: 1px solid transparent;
}

/* Push nav down when banner is present.
   Two cases handled here:
   - .strand-nav--glass is position:fixed, so it must be offset via top.
   - All other nav variants (default, --instrument) are in document flow,
     so they shift via margin-top instead. The fixed-positioning rule above
     wins for --glass because top is meaningful only when position:fixed,
     and margin-top has no effect on a fixed element. */
.strand-banner ~ .strand-nav--glass {
	top: var(--strand-banner-height, 0px);
}

.strand-banner ~ .strand-nav:not(.strand-nav--glass) {
	margin-top: var(--strand-banner-height, 0px);
}

/* When the page hosts a full-bleed instrument viewport AND a banner is
   present, the viewport height calculation must subtract the banner
   height as well as the nav height. The viewport is a descendant of body,
   not a sibling of .strand-banner, so :has() is required to scope this
   rule to "any document containing a banner". */
body:has(.strand-banner) .strand-instrument-viewport--full-bleed {
	height: calc(100vh - var(--strand-nav-height) - var(--strand-banner-height, 0px));
	height: calc(100dvh - var(--strand-nav-height) - var(--strand-banner-height, 0px));
}

/* ── Variants ── */
.strand-banner--info {
	background: var(--strand-blue-glow);
	color: var(--strand-blue-deep);
	border-bottom-color: var(--strand-blue-indicator);
}

.strand-banner--warning {
	background: var(--strand-amber-tint);
	color: var(--strand-on-amber-tint);
	border-bottom-color: var(--strand-amber-caution);
}

.strand-banner--critical {
	background: var(--strand-red-tint);
	color: var(--strand-on-red-tint);
	border-bottom-color: var(--strand-red-alert);
}

/* ── Content ── */
.strand-banner__text {
	margin: 0;
	font-weight: var(--strand-weight-medium);
}

/* ── Dismiss button ── */
.strand-banner__dismiss {
	position: absolute;
	right: var(--strand-space-4);
	top: 50%;
	transform: translateY(-50%);
	background: none;
	border: none;
	cursor: pointer;
	color: inherit;
	opacity: 0.6;
	padding: var(--strand-space-2);
	min-width: 44px;
	min-height: 44px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: var(--strand-radius-md);
	transition: opacity var(--strand-duration-fast) ease;
}

.strand-banner__dismiss:hover {
	opacity: 1;
}

.strand-banner__dismiss:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
	.strand-banner__dismiss {
		transition: none;
	}
}

/* Breadcrumb */
/*! Strand UI | MIT License | dillingerstaffing.com */

.strand-breadcrumb__list {
	display: flex;
	align-items: center;
	gap: var(--strand-space-2);
	list-style: none;
	margin: 0;
	padding: 0;
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-sm);
}

.strand-breadcrumb__item {
	display: inline-flex;
	align-items: center;
	gap: var(--strand-space-2);
}

.strand-breadcrumb__separator {
	color: var(--strand-gray-400);
	user-select: none;
}

.strand-breadcrumb__link {
	color: var(--strand-gray-500);
	text-decoration: none;
	transition: color var(--strand-duration-fast) var(--strand-ease-out-quart);
}

.strand-breadcrumb__link:hover {
	color: var(--strand-gray-600);
}

.strand-breadcrumb__link:focus-visible {
	outline: 2px solid var(--strand-blue-primary);
	outline-offset: 2px;
}

.strand-breadcrumb__current {
	color: var(--strand-gray-600);
	font-weight: var(--strand-weight-medium);
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-breadcrumb__link {
		transition: none;
	}
}

/* Button */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-btn {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--strand-space-2);
	border: 1px solid transparent;
	border-radius: var(--strand-radius-md);
	font-family: var(--strand-font-sans);
	font-weight: var(--strand-weight-medium);
	line-height: var(--strand-leading-snug);
	white-space: nowrap;
	cursor: pointer;
	user-select: none;
	transition:
		background var(--strand-duration-fast) var(--strand-ease-out-quart),
		border-color var(--strand-duration-fast) var(--strand-ease-out-quart),
		color var(--strand-duration-fast) var(--strand-ease-out-quart),
		transform var(--strand-duration-fast) var(--strand-ease-out-expo),
		box-shadow var(--strand-duration-fast) var(--strand-ease-out-quart);
}

.strand-btn:active:not(:disabled) {
	transform: translateY(0);
	transition-duration: 75ms;
}

.strand-btn:disabled {
	opacity: 0.4;
	cursor: not-allowed;
}

/* ── Sizes ── */
.strand-btn--sm {
	padding: var(--strand-space-2) var(--strand-space-5);
	font-size: var(--strand-text-sm);
	min-height: var(--strand-touch-target);
}

.strand-btn--md {
	padding: var(--strand-space-3) var(--strand-space-8);
	font-size: var(--strand-text-sm);
	min-height: var(--strand-touch-target);
}

.strand-btn--lg {
	padding: var(--strand-space-3) var(--strand-space-10);
	font-size: var(--strand-text-base);
	min-height: var(--strand-touch-target);
}

/* ── Icon-only ── */
.strand-btn--icon-only.strand-btn--sm {
	padding: var(--strand-space-1);
	min-width: var(--strand-touch-target);
}

.strand-btn--icon-only.strand-btn--md {
	padding: var(--strand-space-2);
	min-width: var(--strand-touch-target);
}

.strand-btn--icon-only.strand-btn--lg {
	padding: var(--strand-space-3);
	min-width: 48px;
}

/* ── Circular modifier (icon-only only) ──
   Combine with strand-btn--icon-only + a size modifier for a
   pill/circle button. Use for inline rating stars, avatar
   actions, or reaction chips where a square outline would
   feel harsh. */
.strand-btn--circular {
	border-radius: var(--strand-radius-full);
	aspect-ratio: 1;
}

/* ── Full width ── */
.strand-btn--full-width {
	width: 100%;
}

/* ── Primary variant ── */
.strand-btn--primary {
	background: var(--strand-blue-deep);
	color: var(--strand-on-blue-deep);
}

.strand-btn--primary:hover:not(:disabled) {
	background: var(--strand-blue-midnight);
	transform: translateY(-1px);
	box-shadow: var(--strand-hover-shadow-primary);
}

.strand-btn--primary:active:not(:disabled) {
	background: var(--strand-blue-abyss);
}

/* ── Secondary variant ── */
.strand-btn--secondary {
	background: var(--strand-surface-elevated);
	color: var(--strand-blue-midnight);
	border-color: var(--strand-gray-200);
}

.strand-btn--secondary:hover:not(:disabled) {
	background: var(--strand-blue-glow);
	border-color: var(--strand-blue-indicator);
	transform: translateY(-1px);
	box-shadow: var(--strand-elevation-1);
}

.strand-btn--secondary:active:not(:disabled) {
	background: var(--strand-blue-wash);
}

/* ── Ghost variant ── */
.strand-btn--ghost {
	background: transparent;
	color: var(--strand-blue-primary);
}

.strand-btn--ghost:hover:not(:disabled) {
	background: var(--strand-blue-glow);
	transform: translateY(-1px);
}

.strand-btn--ghost:active:not(:disabled) {
	background: var(--strand-blue-wash);
}

/* ── Danger variant ── */
.strand-btn--danger {
	background: var(--strand-red-alert);
	color: var(--strand-on-red-alert);
}

.strand-btn--danger:hover:not(:disabled) {
	background: var(--strand-red-alert-vivid);
	transform: translateY(-1px);
	box-shadow: var(--strand-hover-shadow-danger);
}

.strand-btn--danger:active:not(:disabled) {
	background: var(--strand-red-alert-deep);
}

/* ── Loading state ── */
.strand-btn--loading {
	pointer-events: none;
}

/* When the loading spinner is active, hide the label so only
   the spinner is visible. We use visibility (not display) to
   keep the button width stable so the spinner does not jump. */
.strand-btn--loading .strand-btn__content {
	visibility: hidden;
}

.strand-btn__spinner {
	position: absolute;
	width: 16px;
	height: 16px;
	border: 2px solid currentColor;
	border-top-color: transparent;
	border-radius: var(--strand-radius-full);
	animation: strand-btn-spin 0.8s linear infinite;
	opacity: 0.8;
}

.strand-btn--lg .strand-btn__spinner {
	width: 20px;
	height: 20px;
}

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

/* ── Content wrapper ── */
.strand-btn__content {
	display: inline-flex;
	align-items: center;
	gap: var(--strand-space-2);
}

/* ── Focus ring (Part XII: Accessibility Ring) ── */
.strand-btn:focus-visible {
	outline: 2px solid var(--strand-blue-primary);
	outline-offset: 2px;
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-btn {
		transition: none;
	}

	.strand-btn:hover:not(:disabled) {
		transform: none;
	}

	.strand-btn__spinner {
		animation: none;
		border-style: dotted;
	}
}

/* Card */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* CF-REF: craft-test.md [17]
   DL Principle 8 (Default Philosophy): A card at default settings must look
   like a glass instrument panel, not a blank rectangle. The base includes
   elevation, border, and padding so zero-customization output is premium.
   Craft test: place next to a Bootstrap/Material card. Must be visibly more refined. */
.strand-card {
	border-radius: var(--strand-radius-lg); /* CF-REF: radius-range.md [1] */
	background: var(--strand-surface-elevated);
	border: 1px solid var(--strand-border-subtle, rgba(148, 163, 184, 0.12));
	box-shadow: var(--strand-elevation-1); /* CF-REF: earned-elevation.md [1] */
	padding: var(--strand-space-6); /* CF-REF: padding-tiers.md [1] */
	font-family: var(--strand-font-sans);
	overflow: hidden;
	box-sizing: border-box;
	max-width: 100%;
}

/* ── Variants ── */
.strand-card--outlined {
	box-shadow: none;
	border: 1px solid var(--strand-gray-200);
}

.strand-card--flat {
	box-shadow: none;
	border: none;
}

/* ── Warm variant (DL Part 7.1b) ──
   Showcase contexts where the warm wood / controlled daylight
   spatial signature should be felt. Adds the warm shadow tint
   alongside the existing cool layers. Default cool variant
   stays the default. Use on hero/landing/gallery cards, never
   on dashboard or readout cards. */
.strand-card--warm {
	box-shadow: var(--strand-elevation-1-warm);
}

.strand-card--warm.strand-card--interactive:hover {
	box-shadow: var(--strand-elevation-2-warm);
}

/* CF-REF: motion-quality-signal.md [14]
   DL Part VI.5: Card hover uses duration-normal (250ms), not fast (150ms).
   Cards are content containers -- smoother transition than buttons.
   Framerate test: play at 30fps, must feel broken. */
.strand-card--interactive {
	cursor: pointer;
	text-decoration: none;
	color: inherit;
	display: block;
	position: relative;
	transition: transform var(--strand-duration-normal) var(--strand-ease-out-expo), box-shadow
		var(--strand-duration-normal) ease;
}

.strand-card--interactive:hover {
	transform: translateY(-2px);
	box-shadow: var(--strand-elevation-2); /* CF-REF: five-level-shadow.md [1] */
}

/* The "alive" signal for live/active cards. The earlier
   implementation used a rotating conic-gradient as a continuous
   radar sweep; in user testing it read as a "weird spinning blue
   radar" rather than a subtle live indicator, so it was replaced
   with a static treatment. The active state is now communicated
   by a 1px solid blue-indicator border ring sitting just outside
   the card edge plus a tiny tinted top edge accent, both of which
   are perceived as "this thing is on" without any motion. */
.strand-card--active {
	box-shadow: 0 0 0 1px var(--strand-blue-indicator), var(--strand-elevation-1);
}

.strand-card--active::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 2px;
	border-radius: var(--strand-radius-md) var(--strand-radius-md) 0 0;
	background: linear-gradient(
		90deg,
		transparent 0%,
		var(--strand-blue-primary) 50%,
		transparent 100%
	);
	opacity: 0.6;
	pointer-events: none;
}

/* ── Padding modifiers ── */
.strand-card--pad-none {
	padding: 0;
}

.strand-card--pad-sm {
	padding: var(--strand-space-4);
}

.strand-card--pad-md {
	padding: var(--strand-space-6);
}

.strand-card--pad-lg {
	padding: var(--strand-space-8);
}

.strand-card--pad-xl {
	padding: var(--strand-space-10);
}

/* CF-REF: focus-visible.md [4] */
.strand-card--interactive:focus-visible {
	outline: 2px solid var(--strand-blue-primary);
	outline-offset: 2px;
}

/* CF-REF: reduced-motion.md [9] */
@media (prefers-reduced-motion: reduce) {
	.strand-card--interactive {
		transition: none;
	}

	.strand-card--interactive:hover {
		transform: none;
	}

	.strand-card--active::before {
		transition: none;
	}
}

/* Checkbox */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-checkbox {
	display: inline-flex;
	align-items: center;
	gap: var(--strand-space-2);
	min-height: var(--strand-touch-target);
	cursor: pointer;
	user-select: none;
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-sm);
	color: var(--strand-gray-900);
	line-height: var(--strand-leading-snug);
}

/* ── Hidden native input ── */
.strand-checkbox__native {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ── Custom visual ── */
.strand-checkbox__control {
	display: flex;
	align-items: center;
	justify-content: center;
	width: var(--strand-control-size);
	height: var(--strand-control-size);
	border: 1px solid var(--strand-gray-200);
	border-radius: var(--strand-radius-sm);
	background: var(--strand-surface-elevated);
	color: var(--strand-on-blue-primary);
	flex-shrink: 0;
	transition: background var(--strand-duration-fast) var(--strand-ease-out-quart), border-color
		var(--strand-duration-fast) var(--strand-ease-out-quart), box-shadow var(--strand-duration-fast)
		var(--strand-ease-out-quart);
}

.strand-checkbox__icon {
	width: 14px;
	height: 14px;
}

/* ── Focus ring ── */
.strand-checkbox__native:focus-visible ~ .strand-checkbox__control {
	border-color: var(--strand-blue-primary);
	box-shadow: var(--strand-focus-ring);
}

/* ── Checked ── */
.strand-checkbox--checked .strand-checkbox__control {
	background: var(--strand-blue-primary);
	border-color: var(--strand-blue-primary);
}

/* ── Indeterminate ── */
.strand-checkbox--indeterminate .strand-checkbox__control {
	background: var(--strand-blue-primary);
	border-color: var(--strand-blue-primary);
}

/* ── Hover ── */
.strand-checkbox:hover:not(.strand-checkbox--disabled) .strand-checkbox__control {
	border-color: var(--strand-blue-indicator);
}

.strand-checkbox--checked:hover:not(.strand-checkbox--disabled) .strand-checkbox__control,
.strand-checkbox--indeterminate:hover:not(.strand-checkbox--disabled) .strand-checkbox__control {
	background: var(--strand-blue-vivid);
	border-color: var(--strand-blue-vivid);
}

/* ── Label ── */
.strand-checkbox__label {
	color: var(--strand-gray-900);
}

/* ── Disabled ── */
.strand-checkbox--disabled {
	opacity: 0.4;
	cursor: not-allowed;
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-checkbox__control {
		transition: none;
	}
}

/* CodeBlock */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Layout ── */
.strand-code-block {
	position: relative;
}

/* ── Label (optional language indicator) ── */
.strand-code-block__label {
	display: block;
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-medium);
	letter-spacing: var(--strand-tracking-widest);
	text-transform: uppercase;
	color: var(--strand-gray-500);
	margin-bottom: var(--strand-space-2);
}

/* ── Code area ──
   Both <pre> and the nested <code> get explicit color AND background
   so axe-core never has to walk inheritance or composite the
   inset box-shadow. Without explicit color/background on the code
   element, axe-core can compute a false-positive contrast violation
   by blending the inset shadow against the surface. */
.strand-code-block__pre,
.strand-code-block__pre code {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-sm);
	line-height: var(--strand-leading-relaxed);
	color: var(--strand-blue-abyss);
	background-color: var(--strand-surface-recessed);
}

.strand-code-block__pre {
	border-radius: var(--strand-radius-lg);
	padding: var(--strand-space-3) var(--strand-space-4);
	overflow-x: auto;
	white-space: pre;
	tab-size: 2;
	margin: 0;
	border: 1px solid var(--strand-gray-200);
}

/* ── Copy button ──
   Injected by the strand-ui vanilla runtime (strand-ui.js in dillinger)
   onto any .strand-code-block wrapper. The button sits at the top-right of the
   wrapper. The host wrapper carries [data-strand-copy] so the inner
   <pre> can reserve right-side padding for the icon without shifting
   code blocks that have no copy button.
   Default state is low-ink so it does not compete with the code. On
   hover, focus, or parent hover it gains full contrast. Success state
   swaps the icon to a check and flips the label to "Copied" for 1.5s. */
.strand-code-block[data-strand-copy] > .strand-code-block__pre {
	padding-right: var(--strand-space-10);
}

/* Visual alignment: the 44x44 touch target is preserved for
   accessibility, but the icon sits at the top of the button so it
   aligns with the vertical center of the FIRST line of code, not the
   center of the 44x44 box. Without this, on single-line or short
   multi-line snippets the icon floats 6-7px below the text baseline
   and reads as misaligned. The padding-top value is derived from:
   pre padding-top (space-3) + half line-height - half touch target -
   top offset (space-2) - 1px border. */
.strand-code-block__copy {
	position: absolute;
	top: var(--strand-space-2);
	right: var(--strand-space-2);
	display: inline-flex;
	align-items: flex-start;
	justify-content: center;
	min-width: var(--strand-touch-target);
	min-height: var(--strand-touch-target);
	padding: calc(var(--strand-space-1) + 2px) 0 0 0;
	border: 1px solid var(--strand-gray-200);
	border-radius: var(--strand-radius-md);
	background-color: var(--strand-surface-elevated);
	color: var(--strand-gray-500);
	cursor: pointer;
	opacity: 0.55;
	transition:
		opacity var(--strand-duration-fast) var(--strand-ease-out-expo),
		color var(--strand-duration-fast) ease,
		border-color var(--strand-duration-fast) ease,
		background-color var(--strand-duration-fast) ease,
		transform var(--strand-duration-fast) var(--strand-ease-out-expo);
}

.strand-code-block:hover .strand-code-block__copy,
.strand-code-block__copy:hover,
.strand-code-block__copy:focus-visible {
	opacity: 1;
	color: var(--strand-blue-primary);
	border-color: var(--strand-blue-primary);
}

.strand-code-block__copy:hover {
	transform: translateY(-1px);
}

.strand-code-block__copy:active {
	transform: translateY(0);
	transition-duration: 75ms;
}

.strand-code-block__copy:focus-visible {
	outline: 2px solid var(--strand-blue-primary);
	outline-offset: 2px;
}

/* Success state: check icon, green accent, pinned opacity. */
.strand-code-block__copy--copied,
.strand-code-block__copy--copied:hover {
	opacity: 1;
	color: var(--strand-green-positive);
	border-color: var(--strand-green-positive);
	transform: translateY(0);
}

/* Icon swap. Both icons stack in the same cell; the active one has
   display:inline, the inactive one has display:none. No opacity or
   transform animation on the swap so reduced-motion users get the
   same instant visual feedback. */
.strand-code-block__copy-icon {
	width: 16px;
	height: 16px;
	pointer-events: none;
}

.strand-code-block__copy-icon--check {
	display: none;
}

.strand-code-block__copy--copied .strand-code-block__copy-icon--clipboard {
	display: none;
}

.strand-code-block__copy--copied .strand-code-block__copy-icon--check {
	display: inline;
}

@media (prefers-reduced-motion: reduce) {
	.strand-code-block__copy {
		transition: none;
	}
	.strand-code-block__copy:hover,
	.strand-code-block__copy:active,
	.strand-code-block__copy--copied {
		transform: none;
	}
}

/* ── Inline code ── */
.strand-code-inline {
	font-family: var(--strand-font-mono);
	font-size: 0.875em;
	color: var(--strand-blue-deep);
	background: var(--strand-surface-recessed);
	padding: 0.125em 0.375em;
	border-radius: var(--strand-radius-sm);
}

/* Container */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-container {
	width: 100%;
	margin-inline: auto;
	padding-inline: clamp(1.5rem, 5vw, 4rem);
}

/* ── Sizes ── */
.strand-container--narrow {
	max-width: var(--strand-content-narrow);
}

.strand-container--default {
	max-width: var(--strand-content-default);
}

.strand-container--wide {
	max-width: var(--strand-content-wide);
}

.strand-container--full {
	max-width: var(--strand-content-full);
}

/* DataReadout */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Layout ── */
.strand-data-readout {
	display: flex;
	flex-direction: column;
	gap: var(--strand-space-1);
}

/* ── Label (overline) ── */
.strand-data-readout__label {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-medium);
	letter-spacing: var(--strand-tracking-ultra);
	text-transform: uppercase;
	color: var(--strand-gray-500);
	line-height: var(--strand-leading-normal);
}

/* ── Value (instrument readout) ── */
.strand-data-readout__value {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-3xl);
	font-weight: var(--strand-weight-light);
	letter-spacing: var(--strand-tracking-tighter);
	color: var(--strand-blue-midnight);
	line-height: var(--strand-leading-tight);
	font-variant-numeric: tabular-nums;
}

/* ── Size variants ── */
.strand-data-readout--sm .strand-data-readout__value {
	font-size: var(--strand-text-xl);
}

.strand-data-readout--lg .strand-data-readout__value {
	font-size: var(--strand-text-4xl);
}

.strand-data-readout--xl .strand-data-readout__value {
	font-size: clamp(4.5rem, 10vw, 7rem);
}

/* Dialog */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Backdrop ── */
.strand-dialog__backdrop {
	position: fixed;
	inset: 0;
	z-index: 1000;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--strand-backdrop);
}

/* ── Panel ── */
.strand-dialog__panel {
	position: relative;
	width: 100%;
	max-width: 560px;
	margin: var(--strand-space-4);
	padding: var(--strand-space-8);
	background: var(--strand-surface-elevated);
	border-radius: var(--strand-radius-xl);
	box-shadow: var(--strand-elevation-4);
	font-family: var(--strand-font-sans);
	outline: none;
}

/* ── Header ── */
.strand-dialog__header {
	margin-bottom: var(--strand-space-4);
	padding-right: var(--strand-space-8);
}

/* ── Title ── */
.strand-dialog__title {
	margin: 0;
	font-size: var(--strand-text-lg);
	font-weight: var(--strand-weight-semibold);
	color: var(--strand-blue-midnight);
	line-height: var(--strand-leading-snug);
}

/* ── Close button ── */
.strand-dialog__close {
	position: absolute;
	top: var(--strand-space-6);
	right: var(--strand-space-6);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	padding: 0;
	border: none;
	border-radius: var(--strand-radius-md);
	background: transparent;
	color: var(--strand-gray-500);
	font-size: var(--strand-text-lg);
	cursor: pointer;
	transition: background var(--strand-duration-fast) var(--strand-ease-out-quart), color
		var(--strand-duration-fast) var(--strand-ease-out-quart);
}

.strand-dialog__close:hover {
	background: var(--strand-gray-200);
	color: var(--strand-gray-900);
}

/* ── Body ── */
.strand-dialog__body {
	padding-top: var(--strand-space-6);
	color: var(--strand-gray-600);
	font-size: var(--strand-text-sm);
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-dialog__close {
		transition: none;
	}
}

/* Divider */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-divider {
	border: 0;
	margin: 0;
	padding: 0;
}

/* ── Horizontal (hr) ── */
.strand-divider--horizontal {
	width: 100%;
	border-top: 1px solid var(--strand-gray-200);
}

/* ── Vertical ── */
.strand-divider--vertical {
	align-self: stretch;
	border-left: 1px solid var(--strand-gray-200);
}

/* ── Labeled ── */
.strand-divider--labeled {
	display: flex;
	align-items: center;
	gap: var(--strand-space-3);
	border-top: 0;
}

.strand-divider__line {
	flex: 1;
	height: 0;
	border-top: 1px solid var(--strand-gray-200);
}

.strand-divider__label {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-medium);
	color: var(--strand-gray-400);
	letter-spacing: var(--strand-tracking-widest);
	text-transform: uppercase;
	white-space: nowrap;
}

/* ── Gradient (biosynthetic separator) ── */
.strand-divider--gradient {
	border-top: none;
	height: 1px;
	background: linear-gradient(
		90deg,
		transparent 0%,
		var(--strand-blue-indicator) 50%,
		transparent 100%
	);
}

/* FormField */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-form-field {
	display: flex;
	flex-direction: column;
	gap: var(--strand-space-2);
}

/* ── Label ── */
.strand-form-field__label {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-medium);
	letter-spacing: var(--strand-tracking-widest);
	text-transform: uppercase;
	color: var(--strand-gray-500);
	line-height: var(--strand-leading-snug);
}

/* ── Required indicator ──
   Uses blue-primary, not red, because the asterisk is a "this is required"
   accent (informational), not an error. Red is reserved for actual errors
   inside .strand-form-field__error. */
.strand-form-field__required {
	color: var(--strand-blue-primary);
	margin-left: var(--strand-space-1);
}

/* ── Control wrapper ── */
.strand-form-field__control {
	display: flex;
	flex-direction: column;
}

/* ── Hint ── */
.strand-form-field__hint {
	margin: 0;
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-xs);
	color: var(--strand-gray-500);
	line-height: var(--strand-leading-normal);
}

/* ── Error message ── */
.strand-form-field__error {
	margin: 0;
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-xs);
	color: var(--strand-red-alert);
	line-height: var(--strand-leading-normal);
}

/* Grid */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-grid {
	display: grid;
	overflow: hidden;
	max-width: 100%;
	box-sizing: border-box;
}

.strand-grid > * {
	min-width: 0;
}

/* ── Fixed column utilities ── */
.strand-grid--cols-2 {
	grid-template-columns: repeat(2, 1fr);
}
.strand-grid--cols-3 {
	grid-template-columns: repeat(3, 1fr);
}
.strand-grid--cols-4 {
	grid-template-columns: repeat(4, 1fr);
}

/* ── Responsive auto-fit (columns adjust to available width) ──
   Use the size that matches your card content width. The breakpoint
   behavior is determined entirely by the minmax() value:
   - auto-sm  (200px): 1col <410, 2col 410-640, 3col 640-870, 4col 870+
   - auto-220 (220px): 1col <450, 2col 450-700, 3col 700-940, 4col 940+
   - auto-md  (280px): 1col <570, 2col 570-880, 3col 880-1190, 4col 1190+
   - auto-260 (260px): 1col <530, 2col 530-820, 3col 820-1100, 4col 1100+
   - auto-lg  (360px): 1col <730, 2col 730-1120, 3col 1120-1500, 4col 1500+
   The auto-220 + auto-260 sizes match the dillinger-staffing prod
   process and lab grid breakpoints (4 cols at 1280 desktop, 2 cols at
   tablet portrait, 1 col at phone). */
.strand-grid--auto-sm {
	grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.strand-grid--auto-220 {
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.strand-grid--auto-md {
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.strand-grid--auto-260 {
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.strand-grid--auto-lg {
	grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
}

/* ── Gap utilities ── */
.strand-grid--gap-1 {
	gap: var(--strand-space-1);
}
.strand-grid--gap-2 {
	gap: var(--strand-space-2);
}
.strand-grid--gap-3 {
	gap: var(--strand-space-3);
}
.strand-grid--gap-4 {
	gap: var(--strand-space-4);
}
.strand-grid--gap-5 {
	gap: var(--strand-space-5);
}
.strand-grid--gap-6 {
	gap: var(--strand-space-6);
}
.strand-grid--gap-8 {
	gap: var(--strand-space-8);
}

/* Input */
/*! Strand UI | MIT License | dillingerstaffing.com */

.strand-input {
	position: relative;
	display: flex;
	align-items: center;
	background: var(--strand-surface-elevated);
	border: 1px solid var(--strand-gray-200);
	border-radius: var(--strand-radius-md);
	transition: border-color var(--strand-duration-fast) var(--strand-ease-out-quart), box-shadow
		var(--strand-duration-fast) var(--strand-ease-out-quart);
}

.strand-input:focus-within {
	border-color: var(--strand-blue-primary);
	box-shadow: var(--strand-focus-ring);
}

/* ── Field ── */
.strand-input__field {
	flex: 1;
	width: 100%;
	padding: var(--strand-space-3) var(--strand-space-4);
	background: transparent;
	border: none;
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-base);
	color: var(--strand-gray-900);
	outline: none;
}

.strand-input__field::placeholder {
	color: var(--strand-gray-400);
}

/* ── Addons ── */
.strand-input__leading,
.strand-input__trailing {
	display: flex;
	align-items: center;
	color: var(--strand-gray-500);
	font-size: var(--strand-text-sm);
}

.strand-input__leading {
	padding-left: var(--strand-space-3);
}

.strand-input__trailing {
	padding-right: var(--strand-space-3);
}

.strand-input--has-leading .strand-input__field {
	padding-left: var(--strand-space-2);
}

.strand-input--has-trailing .strand-input__field {
	padding-right: var(--strand-space-2);
}

/* ── Error ── */
.strand-input--error {
	border-color: var(--strand-red-alert);
}

.strand-input--error:focus-within {
	border-color: var(--strand-red-alert);
	box-shadow: var(--strand-focus-ring-error);
}

/* ── Disabled ── */
.strand-input--disabled {
	opacity: 0.4;
	cursor: not-allowed;
}

.strand-input--disabled .strand-input__field {
	cursor: not-allowed;
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-input {
		transition: none;
	}
}

/* InstrumentViewport */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ══════════════════════════════════════════════════
   INSTRUMENT VIEWPORT (DL Part 9.3: Dark Mode Island)
   ══════════════════════════════════════════════════
   The viewport is the only place dark backgrounds appear in the
   lab. The frame around it stays the white lab surface. Inside
   the viewport, every primitive (search bar, panel, pin, legend,
   coordinate readout, scanline, vignette) is built from the
   instrument tokens defined in tokens.css. None of these
   primitives leak the dark surface to the rest of the page.

   Three modes:
   - Default (recessed inside a card)
   - --grid (with subtle blue grid overlay)
   - --full-bleed (page-filling instrument cabinet, requires
     body to be marked .strand-body--instrument so the page
     surface is dark all the way to the edges) */

.strand-instrument-viewport {
	background: var(--strand-blue-abyss);
	color: var(--strand-gray-100);
	border-radius: var(--strand-radius-lg);
	overflow: hidden;
	position: relative;
}

.strand-instrument-viewport__label {
	color: var(--strand-gray-400);
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-medium);
	letter-spacing: var(--strand-tracking-widest);
	text-transform: uppercase;
}

.strand-instrument-viewport__value {
	color: var(--strand-on-blue-primary);
	font-family: var(--strand-font-mono);
	font-variant-numeric: tabular-nums;
}

/* ── Map slot (base layer inside the viewport) ──
   When the instrument viewport hosts a map (DL 9.3 explicitly
   lists maps as supported content), the consumer's map library
   container div must be given a known size. Without explicit
   dimensions a raw <div> collapses to height: 0 and libraries
   like maplibre-gl silently initialize into a zero-size canvas
   and render nothing.

   This slot primitive fills the viewport so the map canvas has
   somewhere to paint. It deliberately does NOT set z-index: a
   z-index would create a new stacking context that traps the
   map library's markers below the viewport's FUI overlays
   (scanline, vignette). Without a z-index, the markers can be
   promoted into the viewport's own stacking context via the
   library-specific marker rules below.

   NOTE on specificity: the selector is scoped via the parent
   .strand-instrument-viewport to outrank .maplibregl-map, which
   maplibre-gl.css (appended at runtime, after strand-ui.css)
   sets to position: relative. Without the descendant selector
   the single-class rules would tie on specificity, and later
   source order would hand the win to maplibre, leaving the
   container as a relatively-positioned in-flow element whose
   height: 100% can collapse to 0 in some mobile browsers when
   the parent chain's explicit heights are not yet resolved at
   paint time. Absolute positioning anchored via inset: 0
   guarantees the container always fills its containing block,
   regardless of maplibre's cascade. */
.strand-instrument-viewport .strand-instrument-viewport__map {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
}

/* ── Optional grid overlay ── */
.strand-instrument-viewport--grid::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(var(--strand-viewport-grid-line) 1px, transparent 1px),
		linear-gradient(90deg, var(--strand-viewport-grid-line) 1px, transparent 1px);
	background-size: var(--strand-viewport-grid-size) var(--strand-viewport-grid-size);
	pointer-events: none;
}

/* ── Full-bleed variant (page-filling instrument cabinet) ──
   The viewport occupies all the space below the nav. The body
   must be marked .strand-body--instrument so the dark surface
   reaches the edge of the screen, not just the rounded card. */
.strand-instrument-viewport--full-bleed {
	width: 100%;
	height: calc(100vh - var(--strand-nav-height));
	height: calc(100dvh - var(--strand-nav-height));
	border-radius: 0;
}

/* ── Atmospheric grid overlay (always-on for full-bleed) ── */
.strand-instrument-viewport--full-bleed::before {
	content: "";
	position: absolute;
	inset: 0;
	background-image: linear-gradient(var(--strand-viewport-grid-line) 1px, transparent 1px),
		linear-gradient(90deg, var(--strand-viewport-grid-line) 1px, transparent 1px);
	background-size: 60px 60px;
	pointer-events: none;
	z-index: 3;
}

/* ── Ambient breathing glow (DL Part 7: alive signal) ── */
.strand-instrument-viewport--full-bleed::after {
	content: "";
	position: absolute;
	inset: 0;
	background: radial-gradient(
		ellipse 60% 50% at 50% 40%,
		var(--strand-instrument-glow-soft) 0%,
		transparent 70%
	);
	pointer-events: none;
	z-index: 2;
	animation: strand-instrument-breathe 8s var(--strand-ease-in-out-sine) infinite;
}

@keyframes strand-instrument-breathe {
	0%,
	100% {
		opacity: 0.5;
	}
	50% {
		opacity: 1;
	}
}

/* ──────────────────────────────────────────────
   BODY MODE: full-bleed dark surface
   ──────────────────────────────────────────────
   When a page hosts a full-bleed instrument viewport, the body
   itself must be dark all the way to the edges. The nav also
   needs to switch to its instrument variant. Add
   .strand-body--instrument to <body> to enable this mode. */

.strand-body--instrument {
	background: var(--strand-instrument-bg);
	overflow: hidden;
}

/* ──────────────────────────────────────────────
   NAV: instrument variant (dark glassmorphic)
   ──────────────────────────────────────────────
   When the body is in instrument mode, the nav must also be
   dark + glassmorphic to match the cabinet aesthetic. Apply
   .strand-nav--instrument alongside .strand-nav for a dark
   blurred bar with blue-tinted hairline.

   The selectors compose .strand-nav with .strand-nav--instrument
   so they outweigh the bare .strand-nav rules even though Nav.css
   is bundled later than InstrumentViewport.css. Without the
   compound selector, the white surface from Nav.css would win
   on source order. */

.strand-nav.strand-nav--instrument {
	background: var(--strand-instrument-bg-translucent);
	-webkit-backdrop-filter: blur(16px);
	backdrop-filter: blur(16px);
	border-bottom: 1px solid var(--strand-instrument-border);
}

.strand-nav.strand-nav--instrument .strand-nav__logo {
	color: var(--strand-blue-primary);
	text-shadow: 0 0 12px rgba(59, 142, 246, 0.3);
}

.strand-nav.strand-nav--instrument .strand-nav__link {
	color: var(--strand-instrument-text-secondary);
}

.strand-nav.strand-nav--instrument .strand-nav__link:hover {
	color: var(--strand-instrument-text-primary);
}

/* ──────────────────────────────────────────────
   NAV ACCESSORIES (mono titles + ghost CTAs)
   ──────────────────────────────────────────────
   Lab pages render a small mono title between the logo and the
   primary CTA. The accessories live in the nav__inner container,
   between logo and actions. */

.strand-nav__title {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-sm);
	font-weight: var(--strand-weight-semibold);
	letter-spacing: var(--strand-tracking-widest);
	text-transform: uppercase;
	color: var(--strand-instrument-text-primary);
	text-shadow: 0 0 16px rgba(59, 142, 246, 0.15);
	margin-right: auto;
}

.strand-nav__title-tag {
	font-weight: var(--strand-weight-regular);
	color: var(--strand-gray-400);
	margin-left: var(--strand-space-1);
}

/* ──────────────────────────────────────────────
   FUI: SCANLINE
   ──────────────────────────────────────────────
   A horizontal pulse that sweeps the viewport from top to bottom
   on every scan trigger. Uses Principle 7 (alive signal) at the
   highest visibility tier: an event the user can perceive when
   the system is actively processing. Combine with .scanline-
   ambient for the slow continuous baseline pulse. */

.strand-scanline {
	position: absolute;
	left: 0;
	right: 0;
	height: 2px;
	top: -2px;
	background: linear-gradient(
		90deg,
		transparent 0%,
		rgba(59, 142, 246, 0.2) 15%,
		var(--strand-instrument-glow-strong) 50%,
		rgba(59, 142, 246, 0.2) 85%,
		transparent 100%
	);
	box-shadow: 0 0 16px rgba(59, 142, 246, 0.3), 0 0 48px rgba(59, 142, 246, 0.1), 0 1px 0
		var(--strand-instrument-border);
	pointer-events: none;
	z-index: 5;
	opacity: 0;
}

.strand-scanline--active {
	animation: strand-scan 2s var(--strand-ease-out-quart) forwards;
}

@keyframes strand-scan {
	0% {
		top: -2px;
		opacity: 0;
	}
	5% {
		opacity: 0.5;
	}
	90% {
		opacity: 0.5;
	}
	100% {
		top: 100%;
		opacity: 0;
	}
}

/* ── Ambient continuous scan (slow breathing baseline) ── */
.strand-scanline--ambient {
	position: absolute;
	left: 0;
	right: 0;
	height: 1px;
	top: -1px;
	background: linear-gradient(
		90deg,
		transparent 0%,
		rgba(59, 142, 246, 0.08) 30%,
		var(--strand-instrument-glow-medium) 50%,
		rgba(59, 142, 246, 0.08) 70%,
		transparent 100%
	);
	pointer-events: none;
	z-index: 5;
	opacity: 1;
	animation: strand-scan-slow 6s linear infinite;
}

@keyframes strand-scan-slow {
	0% {
		top: -1px;
	}
	100% {
		top: 100%;
	}
}

/* ──────────────────────────────────────────────
   FUI: VIEWPORT VIGNETTE (cursor-following spotlight)
   ──────────────────────────────────────────────
   A radial gradient that follows the user's cursor (via JS that
   sets --mouse-x / --mouse-y custom properties on the viewport),
   darkening the edges so the user's eye is drawn toward whatever
   they are pointing at. The "instrument focus" effect from
   cinematic FUI work. */

.strand-viewport-vignette {
	position: absolute;
	inset: 0;
	pointer-events: none;
	z-index: 4;
	background: radial-gradient(
		ellipse 70% 60% at var(--mouse-x, 50%) var(--mouse-y, 50%),
		transparent 45%,
		rgba(15, 25, 42, 0.35) 100%
	);
	transition: background-position 0.15s ease;
}

/* ──────────────────────────────────────────────
   FUI: COORDINATE READOUT
   ──────────────────────────────────────────────
   A small mono panel in the bottom-left corner that displays the
   instrument's current coordinate (latitude/longitude, or any
   tabular numeric pair). The blinking cursor before the values
   is the alive signal -- the system is reading position right
   now. */

.strand-coord-readout {
	position: absolute;
	bottom: var(--strand-space-4);
	left: var(--strand-space-4);
	z-index: 10;
	font-family: var(--strand-font-mono);
	font-size: 13px;
	font-variant-numeric: tabular-nums;
	letter-spacing: var(--strand-tracking-widest);
	color: rgba(148, 163, 184, 0.65);
	display: flex;
	align-items: center;
	gap: var(--strand-space-4);
	background: var(--strand-instrument-bg-overlay);
	border: 1px solid var(--strand-instrument-border);
	border-radius: var(--strand-radius-sm);
	padding: var(--strand-space-2) var(--strand-space-3);
	box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.3);
}

.strand-coord-readout::before {
	content: "";
	display: inline-block;
	width: 2px;
	height: 12px;
	background: var(--strand-instrument-glow-strong);
	border-radius: var(--strand-radius-sm);
	animation: strand-coord-blink 1.2s steps(2) infinite;
}

@keyframes strand-coord-blink {
	0%,
	49% {
		opacity: 1;
	}
	50%,
	100% {
		opacity: 0;
	}
}

.strand-coord-readout__lat,
.strand-coord-readout__lng {
	display: inline-block;
}

/* ──────────────────────────────────────────────
   FUI: MAP LEGEND (sector classification HUD)
   ──────────────────────────────────────────────
   A small HUD panel listing the sector classifications used by
   the instrument. The colored dots are the connector between
   the legend and the map pins. Hovering an item dims unrelated
   pins so the user can scan one sector at a time. */

.strand-map-legend {
	position: absolute;
	bottom: calc(var(--strand-space-6) + 6rem);
	right: var(--strand-space-4);
	z-index: 10;
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	letter-spacing: var(--strand-tracking-wide);
	color: rgba(148, 163, 184, 0.6);
	display: flex;
	flex-direction: column;
	gap: var(--strand-space-2);
	background: rgba(15, 25, 42, 0.7);
	border: 1px solid var(--strand-instrument-border);
	border-radius: var(--strand-radius-md);
	padding: var(--strand-space-3) var(--strand-space-4);
	-webkit-backdrop-filter: blur(8px);
	backdrop-filter: blur(8px);
	box-shadow: var(--strand-instrument-shadow-inset), var(--strand-instrument-shadow-soft);
}

.strand-map-legend__title {
	font-weight: var(--strand-weight-semibold);
	text-transform: uppercase;
	letter-spacing: var(--strand-tracking-widest);
	color: rgba(148, 163, 184, 0.4);
	margin-bottom: var(--strand-space-1);
	display: flex;
	align-items: center;
	gap: var(--strand-space-2);
}

.strand-map-legend__title::before {
	content: "";
	width: 4px;
	height: 4px;
	background: var(--strand-instrument-glow-strong);
	border-radius: var(--strand-radius-full);
	animation: strand-instrument-breathe 3s var(--strand-ease-in-out-sine) infinite;
}

.strand-map-legend__item {
	display: flex;
	align-items: center;
	gap: var(--strand-space-3);
	padding: 2px 0;
	cursor: pointer;
	transition: color var(--strand-duration-fast) ease;
}

.strand-map-legend__item:hover {
	color: rgba(226, 232, 240, 0.9);
}

.strand-map-legend__item:hover .strand-map-legend__dot {
	transform: scale(1.4);
	filter: brightness(1.3);
}

.strand-map-legend__dot {
	width: 8px;
	height: 8px;
	border-radius: var(--strand-radius-full);
	transition: transform var(--strand-duration-fast) var(--strand-ease-out-expo), filter
		var(--strand-duration-fast) ease;
}

.strand-map-legend__dot--tech {
	background: var(--strand-sector-tech);
	box-shadow: 0 0 8px rgba(59, 142, 246, 0.5);
}

.strand-map-legend__dot--health {
	background: var(--strand-sector-health);
	box-shadow: 0 0 8px rgba(20, 184, 166, 0.5);
}

.strand-map-legend__dot--trades {
	background: var(--strand-sector-trades);
	box-shadow: 0 0 8px rgba(34, 211, 238, 0.5);
}

.strand-map-legend__dot--finance {
	background: var(--strand-sector-finance);
	box-shadow: 0 0 8px rgba(139, 92, 246, 0.5);
}

/* ──────────────────────────────────────────────
   SEARCH BAR (floating glassmorphic, instrument)
   ──────────────────────────────────────────────
   A floating search bar centered above the viewport. Glass-
   morphic dark surface, biosynthetic blue focus glow. This is
   the input device the user reaches for first inside an
   instrument viewport. */

.strand-search-bar {
	position: absolute;
	top: var(--strand-space-4);
	left: 50%;
	transform: translateX(-50%);
	z-index: 10;
	width: min(520px, calc(100% - var(--strand-space-8)));
	transition: left var(--strand-duration-normal) var(--strand-ease-out-expo), transform
		var(--strand-duration-normal) var(--strand-ease-out-expo), width var(--strand-duration-normal)
		var(--strand-ease-out-expo);
}

.strand-search-bar--shifted {
	left: calc(340px + var(--strand-space-4) + var(--strand-space-4));
	transform: none;
	width: min(480px, calc(100% - 340px - var(--strand-space-4) * 3));
}

.strand-search-bar__inner {
	display: flex;
	align-items: center;
	gap: var(--strand-space-2);
	background: linear-gradient(135deg, rgba(15, 25, 42, 0.88) 0%, rgba(15, 23, 42, 0.85) 100%);
	-webkit-backdrop-filter: blur(20px);
	backdrop-filter: blur(20px);
	border: 1px solid rgba(59, 142, 246, 0.15);
	border-radius: var(--strand-radius-lg);
	padding: var(--strand-space-2) var(--strand-space-4);
	box-shadow: var(--strand-instrument-shadow-deep);
	transition: border-color var(--strand-duration-normal) ease, box-shadow
		var(--strand-duration-normal) ease;
}

.strand-search-bar__inner:has(.strand-search-bar__input:focus) {
	border-color: var(--strand-instrument-border-strong);
	box-shadow: var(--strand-instrument-shadow-deep), inset 0 0 24px rgba(59, 142, 246, 0.06);
}

.strand-search-bar__input {
	flex: 1;
	background: transparent;
	border: none;
	outline: none;
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-base);
	color: var(--strand-instrument-text-primary);
	padding: var(--strand-space-2) 0;
}

.strand-search-bar__input::placeholder {
	color: var(--strand-gray-500);
}

.strand-search-bar__action {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border: 1px solid rgba(59, 142, 246, 0.2);
	border-radius: var(--strand-radius-md);
	background: transparent;
	color: var(--strand-gray-400);
	cursor: pointer;
	transition: color var(--strand-duration-fast) ease, border-color var(--strand-duration-fast) ease,
		box-shadow var(--strand-duration-fast) ease;
}

.strand-search-bar__action:hover {
	color: var(--strand-blue-primary);
	border-color: var(--strand-blue-primary);
	box-shadow: 0 0 8px rgba(59, 142, 246, 0.2);
}

.strand-search-bar__action:hover svg {
	filter: drop-shadow(0 0 3px rgba(59, 142, 246, 0.5));
}

.strand-search-bar__action:active {
	transform: scale(0.95);
}

.strand-search-bar__action--danger {
	border-color: rgba(239, 68, 68, 0.2);
}

.strand-search-bar__action--danger:hover {
	color: var(--strand-red-alert);
	border-color: var(--strand-red-alert);
	box-shadow: 0 0 8px rgba(239, 68, 68, 0.2);
}

.strand-search-bar__action[hidden] {
	display: none;
}

.strand-search-bar__action--locating {
	color: var(--strand-blue-primary);
	border-color: var(--strand-blue-primary);
	animation: strand-search-bar-pulse 1s var(--strand-ease-in-out-sine) infinite;
}

@keyframes strand-search-bar-pulse {
	0%,
	100% {
		border-color: var(--strand-blue-primary);
	}
	50% {
		border-color: rgba(59, 142, 246, 0.3);
	}
}

/* ──────────────────────────────────────────────
   RESULTS PANEL (instrument left sidebar)
   ──────────────────────────────────────────────
   The list of items returned by an instrument query. Glass-
   morphic dark surface, fixed left side on desktop, bottom
   sheet on mobile. Holds count, scrollable items, empty/error
   states. */

.strand-results-panel {
	position: absolute;
	top: var(--strand-space-4);
	left: var(--strand-space-4);
	width: 340px;
	max-height: calc(100% - var(--strand-space-8));
	z-index: 10;
	display: flex;
	flex-direction: column;
	background: var(--strand-instrument-bg-glass);
	-webkit-backdrop-filter: blur(16px);
	backdrop-filter: blur(16px);
	border: 1px solid rgba(59, 142, 246, 0.12);
	border-radius: var(--strand-radius-lg);
	overflow: hidden;
	box-shadow: var(--strand-instrument-shadow-medium);
}

.strand-results-panel[hidden] {
	display: none;
}

.strand-results-panel__count {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	letter-spacing: var(--strand-tracking-widest);
	text-transform: uppercase;
	color: var(--strand-instrument-text-tertiary);
	padding: var(--strand-space-3) var(--strand-space-4);
	border-bottom: 1px solid rgba(59, 142, 246, 0.08);
}

.strand-results-panel__items {
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	max-height: calc(100vh - 240px);
	overscroll-behavior: contain;
}

.strand-results-panel__state {
	padding: var(--strand-space-6) var(--strand-space-4);
	text-align: center;
}

.strand-results-panel__state-title {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	letter-spacing: var(--strand-tracking-wide);
	color: var(--strand-instrument-text-tertiary);
}

.strand-results-panel__state-hint {
	font-size: var(--strand-text-xs);
	color: var(--strand-instrument-text-quiet);
	margin-top: var(--strand-space-2);
}

.strand-results-panel__error-link {
	display: inline-block;
	margin-top: var(--strand-space-3);
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	color: var(--strand-blue-primary);
	text-decoration: none;
	border: 1px solid rgba(59, 142, 246, 0.3);
	border-radius: var(--strand-radius-sm);
	padding: var(--strand-space-2) var(--strand-space-3);
	transition: background var(--strand-duration-fast) ease;
}

.strand-results-panel__error-link:hover {
	background: rgba(59, 142, 246, 0.1);
}

/* ── Result card ── */
.strand-result-card {
	display: block;
	padding: var(--strand-space-3) var(--strand-space-4);
	border-bottom: 1px solid rgba(59, 142, 246, 0.06);
	cursor: pointer;
	transition: background var(--strand-duration-fast) ease;
}

.strand-result-card:hover {
	background: rgba(59, 142, 246, 0.08);
}

.strand-result-card.is-active,
.strand-result-card--active {
	background: rgba(59, 142, 246, 0.12);
	border-left: 2px solid var(--strand-blue-primary);
	padding-left: calc(var(--strand-space-4) - 2px);
}

.strand-result-card__title {
	font-size: var(--strand-text-sm);
	font-weight: var(--strand-weight-medium);
	color: var(--strand-instrument-text-primary);
	margin-bottom: 2px;
	line-height: 1.3;
}

.strand-result-card__company {
	font-size: var(--strand-text-xs);
	color: rgba(148, 163, 184, 0.7);
	margin-bottom: 4px;
}

.strand-result-card__meta {
	display: flex;
	align-items: center;
	gap: var(--strand-space-2);
	flex-wrap: wrap;
}

.strand-result-card__location {
	font-family: var(--strand-font-mono);
	font-size: 10px;
	letter-spacing: var(--strand-tracking-wide);
	color: var(--strand-instrument-text-tertiary);
}

.strand-result-card__salary {
	font-family: var(--strand-font-mono);
	font-size: 10px;
	color: var(--strand-blue-indicator);
}

.strand-result-card__badge {
	font-family: var(--strand-font-mono);
	font-size: 9px;
	letter-spacing: var(--strand-tracking-wide);
	text-transform: uppercase;
	padding: 1px 6px;
	border-radius: var(--strand-radius-sm);
}

.strand-result-card__badge--remote {
	color: var(--strand-teal-vital);
	background: rgba(20, 184, 166, 0.12);
}

.strand-result-card__badge--source {
	color: rgba(148, 163, 184, 0.4);
	background: rgba(148, 163, 184, 0.06);
}

/* ──────────────────────────────────────────────
   DETAIL PANEL (instrument right slide-over)
   ──────────────────────────────────────────────
   The expanded detail surface that slides in from the right
   side of the viewport when the user opens an item. Light
   surface, white frame inside the dark cabinet. Animated
   reveal with staggered children. */

.strand-detail-panel {
	position: absolute;
	top: 0;
	right: 0;
	width: 360px;
	max-width: 100%;
	height: 100%;
	z-index: 20;
	background: linear-gradient(135deg, rgba(248, 250, 252, 0.98) 0%, rgba(241, 245, 249, 0.97) 100%);
	-webkit-backdrop-filter: blur(8px);
	backdrop-filter: blur(8px);
	border-left: 1px solid rgba(59, 142, 246, 0.1);
	box-shadow: -4px 0 32px rgba(0, 0, 0, 0.25), inset 1px 0 0 rgba(255, 255, 255, 0.4);
	padding: 120px var(--strand-space-6) var(--strand-space-8);
	transform: translateX(100%);
	transition: transform var(--strand-duration-slow) var(--strand-ease-out-expo);
	overflow-y: auto;
}

.strand-detail-panel[hidden] {
	display: none;
}

.strand-detail-panel.is-open,
.strand-detail-panel--open,
.strand-detail-panel.open {
	transform: translateX(0);
}

/* ── Staggered content reveal (Principle 7: alive signal) ──
   The panel and its children share three equivalent state hooks:
   .is-open (BEM-state), --open (BEM-modifier), and .open (legacy
   alias kept for downstream consumers that already use it). All
   three trigger the same reveal sequence. */
.strand-detail-panel.is-open > .strand-overline,
.strand-detail-panel--open > .strand-overline,
.strand-detail-panel.open > .strand-overline {
	animation: strand-detail-fade var(--strand-duration-slow) var(--strand-ease-out-expo) 0.1s both;
}

.strand-detail-panel.is-open .strand-detail-panel__title,
.strand-detail-panel--open .strand-detail-panel__title,
.strand-detail-panel.open .strand-detail-panel__title {
	animation: strand-detail-fade var(--strand-duration-slow) var(--strand-ease-out-expo) 0.18s both;
}

.strand-detail-panel.is-open .strand-detail-panel__meta,
.strand-detail-panel--open .strand-detail-panel__meta,
.strand-detail-panel.open .strand-detail-panel__meta {
	animation: strand-detail-fade var(--strand-duration-slow) var(--strand-ease-out-expo) 0.26s both;
}

.strand-detail-panel.is-open .strand-detail-panel__salary,
.strand-detail-panel--open .strand-detail-panel__salary,
.strand-detail-panel.open .strand-detail-panel__salary {
	animation: strand-detail-fade var(--strand-duration-slow) var(--strand-ease-out-expo) 0.34s both;
}

.strand-detail-panel.is-open .strand-detail-panel__cta,
.strand-detail-panel--open .strand-detail-panel__cta,
.strand-detail-panel.open .strand-detail-panel__cta {
	animation: strand-detail-fade var(--strand-duration-slow) var(--strand-ease-out-expo) 0.42s both;
}

.strand-detail-panel.is-open .strand-detail-panel__source,
.strand-detail-panel--open .strand-detail-panel__source,
.strand-detail-panel.open .strand-detail-panel__source {
	animation: strand-detail-fade var(--strand-duration-slow) var(--strand-ease-out-expo) 0.48s both;
}

@keyframes strand-detail-fade {
	from {
		opacity: 0;
		transform: translateY(10px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

.strand-detail-panel__close {
	position: absolute;
	top: 80px;
	right: var(--strand-space-4);
	width: 32px;
	height: 32px;
	display: flex;
	align-items: center;
	justify-content: center;
	background: transparent;
	border: 1px solid var(--strand-gray-200);
	border-radius: var(--strand-radius-md);
	font-size: var(--strand-text-lg);
	color: var(--strand-gray-500);
	cursor: pointer;
	transition: color var(--strand-duration-fast) ease, border-color var(--strand-duration-fast) ease,
		background var(--strand-duration-fast) ease;
}

.strand-detail-panel__close:hover {
	color: var(--strand-blue-primary);
	border-color: rgba(59, 142, 246, 0.3);
	background: rgba(59, 142, 246, 0.05);
}

.strand-detail-panel__close-text {
	display: none;
}

.strand-detail-panel__close-icon {
	display: inline;
}

.strand-detail-panel__title {
	font-size: 1.375rem;
	font-weight: var(--strand-weight-medium);
	letter-spacing: var(--strand-tracking-tight);
	color: var(--strand-gray-900);
	margin: 0 0 var(--strand-space-4);
	line-height: 1.3;
}

.strand-detail-panel__meta {
	display: flex;
	flex-direction: column;
	gap: var(--strand-space-1);
	padding-bottom: var(--strand-space-4);
	border-bottom: 1px solid rgba(59, 142, 246, 0.08);
	margin-bottom: var(--strand-space-5);
}

.strand-detail-panel__company,
.strand-detail-panel__location {
	font-size: var(--strand-text-sm);
	color: var(--strand-gray-700);
	line-height: 1.4;
}

.strand-detail-panel__salary {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-lg);
	font-weight: var(--strand-weight-light);
	letter-spacing: var(--strand-tracking-tight);
	color: var(--strand-blue-midnight);
	margin-bottom: var(--strand-space-6);
}

.strand-detail-panel__cta {
	display: block;
	text-align: center;
	text-decoration: none;
	margin-bottom: var(--strand-space-3);
	transition: box-shadow var(--strand-duration-fast) ease, transform var(--strand-duration-fast)
		var(--strand-ease-out-expo);
}

.strand-detail-panel__cta:hover {
	box-shadow: 0 8px 24px rgba(29, 90, 216, 0.25);
}

.strand-detail-panel__cta:active {
	transform: translateY(0) scale(0.98);
}

.strand-detail-panel__source {
	display: block;
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	letter-spacing: var(--strand-tracking-wide);
	color: var(--strand-gray-400);
	text-align: center;
}

/* ──────────────────────────────────────────────
   MAP LOADING (instrument startup screen)
   ──────────────────────────────────────────────
   The full-bleed loading screen that hides the instrument while
   it boots. Centered spinner, mono caption, sweeping bar.
   Fades out via opacity transition. */

.strand-map-loading {
	position: absolute;
	inset: 0;
	z-index: 30;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--strand-space-6);
	background: var(--strand-instrument-bg);
	transition: opacity 0.6s ease;
}

.strand-map-loading.is-hidden,
.strand-map-loading--hidden,
.strand-map-loading.hidden {
	display: none;
}

.strand-map-loading__spinner {
	width: 40px;
	height: 40px;
	border: 1.5px solid rgba(59, 142, 246, 0.15);
	border-top-color: rgba(59, 142, 246, 0.7);
	border-radius: var(--strand-radius-full);
	animation: strand-map-loading-spin 1s linear infinite;
}

@keyframes strand-map-loading-spin {
	to {
		transform: rotate(360deg);
	}
}

.strand-map-loading__text {
	font-family: var(--strand-font-mono);
	font-size: 11px;
	letter-spacing: var(--strand-tracking-widest);
	text-transform: uppercase;
	color: var(--strand-instrument-text-tertiary);
}

.strand-map-loading__bar {
	width: 160px;
	height: 1px;
	background: rgba(59, 142, 246, 0.1);
	border-radius: var(--strand-radius-sm);
	overflow: hidden;
}

.strand-map-loading__bar::after {
	content: "";
	display: block;
	height: 100%;
	width: 40%;
	background: linear-gradient(90deg, transparent, rgba(59, 142, 246, 0.6), transparent);
	animation: strand-map-loading-sweep 1.4s var(--strand-ease-in-out-sine) infinite;
}

@keyframes strand-map-loading-sweep {
	0% {
		transform: translateX(-200%);
	}
	100% {
		transform: translateX(500%);
	}
}

/* ──────────────────────────────────────────────
   MAP PINS + CLUSTER MARKERS
   ──────────────────────────────────────────────
   Pins are the data points the instrument plots on the map.
   Each pin gets a sector color (tech/health/trades/finance) and
   carries a continuous breathing ring + an initial beacon ring
   on spawn. Cluster markers are the metro-level aggregates
   shown when no query is active. */

.strand-map-pin {
	width: 24px;
	height: 24px;
	border-radius: var(--strand-radius-full);
	border: 2.5px solid rgba(255, 255, 255, 0.85);
	cursor: pointer;
	animation: strand-map-pin-spawn var(--strand-duration-slow) var(--strand-ease-spring) both;
	transition: scale var(--strand-duration-fast) var(--strand-ease-out-expo), background
		var(--strand-duration-fast) var(--strand-ease-out-quart);
	box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.15), 0 0 12px currentColor, 0 0 28px currentColor, 0 0
		56px currentColor;
	position: relative;
}

.strand-map-pin::before {
	content: "";
	position: absolute;
	inset: -8px;
	border-radius: var(--strand-radius-full);
	border: 1.5px solid currentColor;
	animation: strand-map-pin-breathe var(--strand-duration-cinematic-slow)
		var(--strand-ease-in-out-sine) infinite;
	animation-delay: inherit;
	pointer-events: none;
}

.strand-map-pin::after {
	content: "";
	position: absolute;
	inset: -4px;
	border-radius: var(--strand-radius-full);
	border: 2px solid rgba(255, 255, 255, 0.5);
	opacity: 0;
	animation: strand-map-pin-beacon var(--strand-duration-cinematic) var(--strand-ease-out-quart)
		forwards;
	animation-delay: inherit;
	pointer-events: none;
}

.strand-map-pin:hover {
	scale: 1.6;
	box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.3), 0 0 16px currentColor, 0 0 40px currentColor, 0 0
		72px currentColor;
}

.strand-map-pin:hover::before {
	animation: none;
	opacity: 0;
}

.strand-map-pin:hover::after {
	animation: strand-map-pin-pulse 1s var(--strand-ease-out-expo) infinite;
}

.strand-map-pin--tech {
	background: var(--strand-sector-tech);
	color: var(--strand-sector-tech);
}

.strand-map-pin--health {
	background: var(--strand-sector-health);
	border-color: rgba(20, 184, 166, 0.7);
	color: var(--strand-sector-health);
}

.strand-map-pin--trades {
	background: var(--strand-sector-trades);
	border-color: rgba(34, 211, 238, 0.7);
	color: var(--strand-sector-trades);
}

.strand-map-pin--finance {
	background: var(--strand-sector-finance);
	border-color: rgba(139, 92, 246, 0.7);
	color: var(--strand-sector-finance);
}

.strand-map-pin.is-highlighted,
.strand-map-pin--highlighted {
	scale: 1.6;
	box-shadow: 0 0 16px currentColor, 0 0 36px currentColor, 0 0 64px rgba(59, 142, 246, 0.4);
	z-index: 10;
}

.strand-map-pin.is-dimmed,
.strand-map-pin--dimmed {
	opacity: 0.15;
	transition: opacity var(--strand-duration-fast) ease;
}

@keyframes strand-map-pin-pulse {
	0% {
		box-shadow: 0 0 0 0 rgba(59, 142, 246, 0.6);
	}
	100% {
		box-shadow: 0 0 0 18px rgba(59, 142, 246, 0);
	}
}

@keyframes strand-map-pin-spawn {
	0% {
		scale: 0;
		opacity: 0;
	}
	50% {
		opacity: 1;
	}
	100% {
		scale: 1;
	}
}

@keyframes strand-map-pin-beacon {
	0% {
		scale: 1;
		opacity: 0.7;
	}
	100% {
		scale: 3;
		opacity: 0;
	}
}

@keyframes strand-map-pin-breathe {
	0%,
	100% {
		opacity: 0.25;
		scale: 1;
	}
	50% {
		opacity: 0.55;
		scale: 1.5;
	}
}

/* ── Cluster marker (metro-level aggregate) ── */
.strand-cluster-marker {
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: var(--strand-radius-full);
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-semibold);
	color: var(--strand-instrument-text-primary);
	border: 2px solid rgba(59, 142, 246, 0.6);
	box-shadow: 0 0 20px rgba(59, 142, 246, 0.4), 0 0 40px rgba(59, 142, 246, 0.15);
	cursor: pointer;
	transition: transform var(--strand-duration-fast) var(--strand-ease-out-expo), box-shadow
		var(--strand-duration-fast) ease;
}

.strand-cluster-marker:hover {
	transform: scale(1.15);
	box-shadow: 0 0 28px rgba(59, 142, 246, 0.6), 0 0 56px rgba(59, 142, 246, 0.25);
}

/* ──────────────────────────────────────────────
   MAPLIBRE COMPATIBILITY OVERRIDES
   ──────────────────────────────────────────────
   When MapLibre GL is rendered inside an instrument viewport,
   its default chrome must be muted and re-themed to fit the
   dark cabinet. These overrides should ONLY take effect inside
   .strand-instrument-viewport so they do not pollute lighter
   maps elsewhere on the site. */

.strand-instrument-viewport .maplibregl-marker {
	z-index: 6 !important;
}

.strand-instrument-viewport .maplibregl-ctrl-bottom-left {
	opacity: 0.25;
	transition: opacity var(--strand-duration-fast) ease;
}

.strand-instrument-viewport .maplibregl-ctrl-bottom-left:hover {
	opacity: 0.7;
}

.strand-instrument-viewport .maplibregl-ctrl-bottom-right {
	bottom: 40px;
	right: 12px;
}

.strand-instrument-viewport .maplibregl-ctrl-bottom-right .maplibregl-ctrl-group {
	background: rgba(15, 25, 42, 0.85);
	border: 1px solid rgba(59, 142, 246, 0.2);
	border-radius: var(--strand-radius-md);
	-webkit-backdrop-filter: blur(8px);
	backdrop-filter: blur(8px);
}

.strand-instrument-viewport .maplibregl-ctrl-bottom-right .maplibregl-ctrl-group button {
	width: 36px;
	height: 36px;
	background: transparent;
	border: none;
	color: var(--strand-gray-300);
	cursor: pointer;
}

.strand-instrument-viewport .maplibregl-ctrl-bottom-right .maplibregl-ctrl-group button:hover {
	color: var(--strand-blue-primary);
}

.strand-instrument-viewport .maplibregl-ctrl-bottom-right .maplibregl-ctrl-group button + button {
	border-top: 1px solid rgba(59, 142, 246, 0.15);
}

.strand-instrument-viewport .maplibregl-popup-content {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	background: var(--strand-instrument-bg-translucent);
	color: var(--strand-instrument-text-primary);
	border: 1px solid rgba(59, 142, 246, 0.2);
	border-radius: var(--strand-radius-md);
	padding: var(--strand-space-2) var(--strand-space-3);
	box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
}

.strand-instrument-viewport .maplibregl-popup-tip {
	border-top-color: var(--strand-instrument-bg-translucent);
}

/* ──────────────────────────────────────────────
   RESPONSIVE
   ──────────────────────────────────────────────
   On mobile, the results panel becomes a bottom sheet, the
   detail panel slides up from the bottom, the search bar
   takes the full width, and the FUI overlays (legend, coord
   readout) hide because they would crowd small screens. */

@media (max-width: 768px) {
	.strand-results-panel {
		top: auto;
		bottom: 0;
		left: 0;
		width: 100%;
		max-height: 40vh;
		border-radius: var(--strand-radius-lg) var(--strand-radius-lg) 0 0;
		overflow-y: auto;
		-webkit-overflow-scrolling: touch;
		overscroll-behavior: contain;
	}

	.strand-results-panel__items {
		max-height: none;
		overflow-y: visible;
	}

	.strand-search-bar,
	.strand-search-bar--shifted {
		top: var(--strand-space-3);
		left: var(--strand-space-4) !important;
		width: calc(100% - (var(--strand-space-4) * 2)) !important;
		transform: none !important;
		transition: none !important;
	}

	.strand-search-bar__action {
		width: 44px;
		height: 44px;
	}

	.strand-map-pin {
		width: 24px;
		height: 24px;
	}
}

@media (max-width: 640px) {
	.strand-detail-panel {
		width: 100%;
		height: auto;
		max-height: 70vh;
		top: auto;
		bottom: 0;
		border-radius: var(--strand-radius-xl) var(--strand-radius-xl) 0 0;
		padding: 0 var(--strand-space-4) var(--strand-space-6);
		transform: translateY(100%);
		box-shadow: 0 -4px 32px rgba(0, 0, 0, 0.2);
	}

	.strand-detail-panel.is-open,
	.strand-detail-panel--open,
	.strand-detail-panel.open {
		transform: translateY(0);
	}

	.strand-detail-panel__close {
		position: relative;
		top: 0;
		left: 0;
		right: 0;
		width: 100%;
		height: 48px;
		border-radius: 0;
		border: none;
		border-bottom: 1px solid var(--strand-gray-200);
		background: transparent;
		font-family: var(--strand-font-mono);
		font-size: var(--strand-text-sm);
		font-weight: var(--strand-weight-medium);
		letter-spacing: var(--strand-tracking-wider);
		color: var(--strand-blue-primary);
		margin-bottom: var(--strand-space-4);
	}

	.strand-detail-panel__close:hover {
		background: var(--strand-blue-glow);
	}

	.strand-detail-panel__close-icon {
		display: none;
	}

	.strand-detail-panel__close-text {
		display: inline;
	}

	.strand-detail-panel > .strand-overline {
		margin-bottom: var(--strand-space-2);
	}

	.strand-map-legend,
	.strand-coord-readout {
		display: none;
	}

	.strand-search-bar__input {
		font-size: 16px;
	}
}

/* ──────────────────────────────────────────────
   REDUCED MOTION
   ──────────────────────────────────────────────
   Strip every animation and transition from the FUI primitives
   when the user has prefers-reduced-motion. The instrument is
   still readable, just static. */

@media (prefers-reduced-motion: reduce) {
	.strand-scanline,
	.strand-scanline--ambient {
		display: none;
	}

	.strand-instrument-viewport--full-bleed::after {
		animation: none;
	}

	.strand-map-pin {
		animation: none;
	}

	.strand-map-pin::before,
	.strand-map-pin::after {
		animation: none;
	}

	.strand-map-pin:hover {
		animation: none;
	}

	.strand-map-pin:hover::before,
	.strand-map-pin:hover::after {
		animation: none;
	}

	.strand-detail-panel {
		transition: none;
	}

	.strand-detail-panel.is-open > .strand-overline,
	.strand-detail-panel--open > .strand-overline,
	.strand-detail-panel.open > .strand-overline,
	.strand-detail-panel.is-open .strand-detail-panel__title,
	.strand-detail-panel--open .strand-detail-panel__title,
	.strand-detail-panel.open .strand-detail-panel__title,
	.strand-detail-panel.is-open .strand-detail-panel__meta,
	.strand-detail-panel--open .strand-detail-panel__meta,
	.strand-detail-panel.open .strand-detail-panel__meta,
	.strand-detail-panel.is-open .strand-detail-panel__salary,
	.strand-detail-panel--open .strand-detail-panel__salary,
	.strand-detail-panel.open .strand-detail-panel__salary,
	.strand-detail-panel.is-open .strand-detail-panel__cta,
	.strand-detail-panel--open .strand-detail-panel__cta,
	.strand-detail-panel.open .strand-detail-panel__cta,
	.strand-detail-panel.is-open .strand-detail-panel__source,
	.strand-detail-panel--open .strand-detail-panel__source,
	.strand-detail-panel.open .strand-detail-panel__source {
		animation: none;
	}

	.strand-map-legend__title::before {
		animation: none;
	}

	.strand-coord-readout::before {
		animation: none;
	}

	.strand-map-loading__spinner {
		animation: none;
		border-color: rgba(59, 142, 246, 0.4);
	}

	.strand-search-bar__action--locating {
		animation: none;
	}
}

/* Link */
/*! Strand UI | MIT License | dillingerstaffing.com */

.strand-link {
	color: var(--strand-blue-primary);
	text-decoration: none;
	font-family: var(--strand-font-sans);
	background-image: linear-gradient(currentColor, currentColor);
	background-position: 0% 100%;
	background-repeat: no-repeat;
	background-size: 0% 1px;
	transition: background-size var(--strand-duration-normal) var(--strand-ease-out-expo);
	cursor: pointer;
}

.strand-link:hover {
	background-size: 100% 1px;
}

/* ── Focus ring ── */
.strand-link:focus-visible {
	outline: 2px solid var(--strand-blue-primary);
	outline-offset: 2px;
}

/* ── CTA link variant ── */
.strand-link--cta {
	display: inline-flex;
	align-items: center;
	min-height: var(--strand-touch-target);
	padding-block: var(--strand-space-2);
	font-size: var(--strand-text-sm);
}

.strand-link--cta:hover {
	color: var(--strand-blue-vivid);
}

/* ── Monospace link variant (footer, overline-style) ── */
.strand-link--mono {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	letter-spacing: var(--strand-tracking-wider);
	color: var(--strand-gray-400);
	background-image: none;
}

.strand-link--mono:hover {
	color: var(--strand-blue-primary);
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-link {
		transition: none;
	}
}

/* Nav */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Nav bar ── */
.strand-nav {
	position: relative;
	width: 100%;
	height: var(--strand-nav-height);
	background: var(--strand-surface-elevated);
	border-bottom: 1px solid var(--strand-gray-200);
	font-family: var(--strand-font-sans);
}

/* ── Inner layout ── */
.strand-nav__inner {
	display: flex;
	align-items: center;
	height: 100%;
	padding: 0 var(--strand-space-6);
	max-width: 1280px;
	margin: 0 auto;
}

/* ── Logo ──
   DL Part IV.5 brand identifier: mono uppercase wide letter-spacing,
   semibold weight, blue-midnight color. The logo is the only typographic
   identity on the page, so it carries the brand even at this small size. */
.strand-nav__logo {
	flex-shrink: 0;
	margin-right: var(--strand-space-8);
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-sm);
	font-weight: var(--strand-weight-semibold);
	letter-spacing: var(--strand-tracking-widest);
	text-transform: uppercase;
	color: var(--strand-blue-midnight);
	text-decoration: none;
	position: relative;
}

/* ── Logo with animated pulse underline (DL Principle 7: alive signal) ──
   A 2px blue underline that pulses in slow rhythm. Use on the brand
   identifier for the active site to signal "this is the live system." */
.strand-nav__logo--pulse::after {
	content: "";
	position: absolute;
	bottom: -4px;
	left: 0;
	right: 0;
	height: 2px;
	background: var(--strand-blue-primary);
	border-radius: var(--strand-radius-sm);
	animation: strand-nav-logo-pulse 2s var(--strand-ease-in-out-sine) infinite;
}

@keyframes strand-nav-logo-pulse {
	0%,
	100% {
		opacity: 1;
	}
	50% {
		opacity: 0.4;
	}
}

@media (prefers-reduced-motion: reduce) {
	.strand-nav__logo--pulse::after {
		animation: none;
		opacity: 0.6;
	}
}

/* ── Desktop items ──
   Pushed to the right edge so logo and primary nav have visual breathing
   room. The old (pre-v0.5) "flex: 1" caused items to cluster against the
   logo, leaving the right edge empty. margin-left auto restores the
   space-between layout most navbars expect. */
.strand-nav__items {
	display: flex;
	align-items: center;
	gap: var(--strand-space-6);
	margin-left: auto;
	list-style: none;
}

/* ── Links ── */
.strand-nav__link {
	color: var(--strand-gray-600);
	text-decoration: none;
	font-size: var(--strand-text-sm);
	font-weight: var(--strand-weight-medium);
	transition: color var(--strand-duration-fast) var(--strand-ease-out-quart);
}

.strand-nav__link:hover {
	color: var(--strand-gray-900);
}

.strand-nav__link:focus-visible {
	outline: 2px solid var(--strand-blue-primary);
	outline-offset: 2px;
}

.strand-nav__link--active {
	color: var(--strand-blue-primary);
	font-weight: var(--strand-weight-medium);
}

/* ── Actions ── */
.strand-nav__actions {
	display: flex;
	align-items: center;
	gap: var(--strand-space-3);
	margin-left: auto;
}

/* ── Hamburger ── */
.strand-nav__hamburger {
	display: none;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	margin-left: auto;
	padding: 0;
	border: none;
	border-radius: var(--strand-radius-md);
	background: transparent;
	color: var(--strand-gray-600);
	cursor: pointer;
	transition: background var(--strand-duration-fast) var(--strand-ease-out-quart);
}

.strand-nav__hamburger:hover {
	background: var(--strand-gray-200);
}

.strand-nav__hamburger:focus-visible {
	outline: 2px solid var(--strand-blue-primary);
	outline-offset: 2px;
}

.strand-nav__hamburger-icon {
	display: block;
	width: 20px;
	height: 2px;
	background: currentColor;
	position: relative;
}

.strand-nav__hamburger-icon::before,
.strand-nav__hamburger-icon::after {
	content: "";
	position: absolute;
	left: 0;
	width: 100%;
	height: 2px;
	background: currentColor;
}

.strand-nav__hamburger-icon::before {
	top: -6px;
}

.strand-nav__hamburger-icon::after {
	top: 6px;
}

/* ── Mobile menu ──
   Drops down from beneath the nav as an overlay. Hidden by default;
   show via JS by adding strand-nav__mobile-menu--open. The position:
   fixed (vs absolute on the parent nav) means the menu floats above
   page content instead of pushing layout. */
.strand-nav__mobile-menu {
	display: none;
	position: fixed;
	top: var(--strand-nav-height);
	left: 0;
	right: 0;
	flex-direction: column;
	width: 100%;
	padding: var(--strand-space-4) var(--strand-space-6);
	background: var(--strand-surface-elevated);
	border-bottom: 1px solid var(--strand-gray-200);
	box-shadow: var(--strand-elevation-2);
	z-index: 99;
}

.strand-nav__mobile-menu--open {
	display: flex;
}

.strand-nav__mobile-link {
	display: block;
	padding: var(--strand-space-3) 0;
	color: var(--strand-gray-600);
	text-decoration: none;
	font-size: var(--strand-text-sm);
	font-weight: var(--strand-weight-medium);
	transition: color var(--strand-duration-fast) var(--strand-ease-out-quart);
}

.strand-nav__mobile-link:hover {
	color: var(--strand-gray-900);
}

.strand-nav__mobile-link--active {
	color: var(--strand-blue-primary);
	font-weight: var(--strand-weight-semibold);
}

/* ── Responsive ──
   At mobile widths the desktop items + actions hide and the
   hamburger button shows. The mobile menu stays display:none until
   JS toggles strand-nav__mobile-menu--open on click. */
@media (max-width: 767px) {
	.strand-nav__items {
		display: none;
	}

	.strand-nav__actions {
		display: none;
	}

	.strand-nav__hamburger {
		display: inline-flex;
	}

	.strand-nav {
		height: auto;
		min-height: var(--strand-nav-height);
	}
}

/* ── Glassmorphic variant (DL 11.5: "white or glassmorphic") ── */
.strand-nav--glass {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 100;
	height: auto;
	padding: var(--strand-space-4) 0;
	background: var(--strand-glass-bg);
	-webkit-backdrop-filter: blur(var(--strand-glass-blur));
	backdrop-filter: blur(var(--strand-glass-blur));
	border-bottom: 1px solid var(--strand-glass-border);
}

/* ── Scrolled state (DL Part XIX.1) ──
   Apply via JS scroll listener. Adds shadow + blue-shifted border. */
.strand-nav--scrolled {
	box-shadow: var(--strand-elevation-1);
	border-bottom-color: var(--strand-nav-scrolled-border);
}

.strand-nav--glass {
	transition: box-shadow var(--strand-duration-normal) ease, border-color
		var(--strand-duration-normal) ease;
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-nav__link,
	.strand-nav__mobile-link,
	.strand-nav__hamburger,
	.strand-nav--glass {
		transition: none;
	}
}

/* Progress */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Bar base ── */
.strand-progress--bar {
	width: 100%;
	background: var(--strand-gray-200);
	border-radius: var(--strand-radius-full);
	overflow: hidden;
}

/* ── Bar sizes ── */
.strand-progress--bar.strand-progress--sm {
	height: 4px;
}

.strand-progress--bar.strand-progress--md {
	height: 8px;
}

.strand-progress--bar.strand-progress--lg {
	height: 12px;
}

/* ── Bar fill ── */
.strand-progress--bar .strand-progress__fill {
	height: 100%;
	background: var(--strand-blue-primary);
	border-radius: var(--strand-radius-full);
	transition: width var(--strand-duration-normal) var(--strand-ease-out-quart);
}

/* ── Bar indeterminate ── */
.strand-progress--bar.strand-progress--indeterminate .strand-progress__fill {
	width: 40%;
	animation: strand-progress-shimmer var(--strand-duration-cinematic) var(--strand-ease-in-out-sine)
		infinite;
}

@keyframes strand-progress-shimmer {
	0% {
		transform: translateX(-100%);
	}
	100% {
		transform: translateX(350%);
	}
}

/* ── Ring base ── */
.strand-progress--ring {
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

/* ── Ring track and fill ── */
.strand-progress__track {
	stroke: var(--strand-gray-200);
}

.strand-progress__fill {
	stroke: var(--strand-blue-primary);
}

.strand-progress--ring .strand-progress__ring {
	transition: stroke-dashoffset var(--strand-duration-normal) var(--strand-ease-out-quart);
}

/* ── Ring indeterminate ── */
.strand-progress--ring.strand-progress--indeterminate .strand-progress__ring {
	animation: strand-progress-rotate 1.2s linear infinite;
}

@keyframes strand-progress-rotate {
	to {
		transform: rotate(360deg);
	}
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-progress--bar .strand-progress__fill {
		transition: none;
	}

	.strand-progress--bar.strand-progress--indeterminate .strand-progress__fill {
		animation: none;
		width: 100%;
		opacity: 0.4;
	}

	.strand-progress--ring.strand-progress--indeterminate .strand-progress__ring {
		animation: none;
	}
}

/* Radio */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-radio {
	display: inline-flex;
	align-items: center;
	gap: var(--strand-space-2);
	min-height: var(--strand-touch-target);
	cursor: pointer;
	user-select: none;
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-sm);
	color: var(--strand-gray-900);
	line-height: var(--strand-leading-snug);
}

/* ── Hidden native input ── */
.strand-radio__native {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ── Custom visual ── */
.strand-radio__control {
	display: flex;
	align-items: center;
	justify-content: center;
	width: var(--strand-control-size);
	height: var(--strand-control-size);
	border: 1px solid var(--strand-gray-200);
	border-radius: var(--strand-radius-full);
	background: var(--strand-surface-elevated);
	flex-shrink: 0;
	transition: background var(--strand-duration-fast) var(--strand-ease-out-quart), border-color
		var(--strand-duration-fast) var(--strand-ease-out-quart), box-shadow var(--strand-duration-fast)
		var(--strand-ease-out-quart);
}

.strand-radio__dot {
	width: 8px;
	height: 8px;
	border-radius: var(--strand-radius-full);
	background: var(--strand-on-blue-primary);
	transform: scale(0);
	transition: transform var(--strand-duration-fast) var(--strand-ease-out-expo);
}

/* ── Focus ring ── */
.strand-radio__native:focus-visible ~ .strand-radio__control {
	border-color: var(--strand-blue-primary);
	box-shadow: var(--strand-focus-ring);
}

/* ── Checked ── */
.strand-radio--checked .strand-radio__control {
	background: var(--strand-blue-primary);
	border-color: var(--strand-blue-primary);
}

.strand-radio--checked .strand-radio__dot {
	transform: scale(1);
}

/* ── Hover ── */
.strand-radio:hover:not(.strand-radio--disabled) .strand-radio__control {
	border-color: var(--strand-blue-indicator);
}

.strand-radio--checked:hover:not(.strand-radio--disabled) .strand-radio__control {
	background: var(--strand-blue-vivid);
	border-color: var(--strand-blue-vivid);
}

/* ── Label ── */
.strand-radio__label {
	color: var(--strand-gray-900);
}

/* ── Disabled ── */
.strand-radio--disabled {
	opacity: 0.4;
	cursor: not-allowed;
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-radio__control,
	.strand-radio__dot {
		transition: none;
	}
}

/* ScrollReveal */
/*! Strand UI | MIT License | dillingerstaffing.com */

.strand-reveal {
	opacity: 0;
	transform: translateY(24px);
	transition: opacity var(--strand-duration-glacial) var(--strand-ease-out-expo), transform
		var(--strand-duration-glacial) var(--strand-ease-out-expo);
}

.strand-reveal--visible {
	opacity: 1;
	transform: translateY(0);
}

/* Stagger children */
.strand-reveal-group > .strand-reveal:nth-child(1) {
	transition-delay: 0ms;
}
.strand-reveal-group > .strand-reveal:nth-child(2) {
	transition-delay: var(--strand-stagger-delay);
}
.strand-reveal-group > .strand-reveal:nth-child(3) {
	transition-delay: calc(var(--strand-stagger-delay) * 2);
}
.strand-reveal-group > .strand-reveal:nth-child(4) {
	transition-delay: calc(var(--strand-stagger-delay) * 3);
}
.strand-reveal-group > .strand-reveal:nth-child(5) {
	transition-delay: calc(var(--strand-stagger-delay) * 4);
}
.strand-reveal-group > .strand-reveal:nth-child(6) {
	transition-delay: var(--strand-duration-slow);
}

/* ── CSS-only scroll-driven animation (no JS required) ── */
@supports (animation-timeline: view()) {
	.strand-reveal {
		opacity: 0;
		transform: translateY(24px);
		transition: none;
		animation: strand-reveal-up linear both;
		animation-timeline: view();
		animation-range: entry 0% entry 100%;
	}

	.strand-reveal-group > .strand-reveal {
		animation: strand-reveal-up linear both;
		animation-timeline: view();
		animation-range: entry 0% entry 100%;
	}

	@keyframes strand-reveal-up {
		from {
			opacity: 0;
			transform: translateY(24px);
		}
		to {
			opacity: 1;
			transform: translateY(0);
		}
	}
}

@media (prefers-reduced-motion: reduce) {
	.strand-reveal {
		opacity: 1;
		transform: none;
		transition: none;
		animation: none;
	}
}

/* Section */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-section {
	width: 100%;
}

/* ── Variants ── */
.strand-section--standard {
	padding-block: clamp(4rem, 8vw, 8rem);
}

.strand-section--hero {
	padding-block: clamp(6rem, 12vw, 12rem);
	text-align: center;
	position: relative;
	overflow: hidden;
}

.strand-section--hero-xl {
	padding-block: clamp(8rem, 15vw, 14rem);
	text-align: center;
	position: relative;
	overflow: hidden;
}

/* ── Backgrounds ── */
.strand-section--bg-primary {
	background-color: var(--strand-surface-primary);
}

.strand-section--bg-elevated {
	background-color: var(--strand-surface-elevated);
}

.strand-section--bg-recessed {
	background-color: var(--strand-surface-recessed);
}

/* ── Compact variant ── */
.strand-section--compact {
	padding-block: var(--strand-space-12);
}

/* ── Border variant ── */
.strand-section--border-top {
	border-top: 1px solid var(--strand-gray-200);
}

/* ── Scroll target (anchored section with nav offset) ── */
.strand-section--scroll-target {
	scroll-margin-top: 5rem;
}

/* Select */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-select {
	position: relative;
	display: inline-flex;
	align-items: center;
	background: var(--strand-surface-elevated);
	border: 1px solid var(--strand-gray-200);
	border-radius: var(--strand-radius-md);
	transition: border-color var(--strand-duration-fast) var(--strand-ease-out-quart), box-shadow
		var(--strand-duration-fast) var(--strand-ease-out-quart);
}

.strand-select:focus-within {
	border-color: var(--strand-blue-primary);
	box-shadow: var(--strand-focus-ring);
}

/* ── Field ── */
.strand-select__field {
	flex: 1;
	width: 100%;
	padding: var(--strand-space-3) var(--strand-space-8) var(--strand-space-3) var(--strand-space-4);
	background: transparent;
	border: none;
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-base);
	color: var(--strand-gray-900);
	outline: none;
	appearance: none;
	cursor: pointer;
}

/* ── Arrow indicator (auto via ::after, no markup needed) ──
   Renders a chevron-down on the right edge of every strand-select
   wrapper, sized to align with the field text. Consumers can also
   place an explicit <span class="strand-select__arrow"> for control. */
.strand-select::after {
	content: "";
	position: absolute;
	right: var(--strand-space-3);
	top: 50%;
	width: 0;
	height: 0;
	margin-top: -2px;
	border-left: 5px solid transparent;
	border-right: 5px solid transparent;
	border-top: 5px solid var(--strand-gray-500);
	pointer-events: none;
}

.strand-select__arrow {
	position: absolute;
	right: var(--strand-space-3);
	top: 50%;
	transform: translateY(-50%);
	width: 0;
	height: 0;
	border-left: 5px solid transparent;
	border-right: 5px solid transparent;
	border-top: 5px solid var(--strand-gray-500);
	pointer-events: none;
}

/* ── Error ── */
.strand-select--error {
	border-color: var(--strand-red-alert);
}

.strand-select--error:focus-within {
	border-color: var(--strand-red-alert);
	box-shadow: var(--strand-focus-ring-error);
}

/* ── Disabled ── */
.strand-select--disabled {
	opacity: 0.4;
	cursor: not-allowed;
}

.strand-select--disabled .strand-select__field {
	cursor: not-allowed;
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-select {
		transition: none;
	}
}

/* Skeleton */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-skeleton {
	display: block;
	background: var(--strand-gray-100);
}

/* ── Shimmer ── */
.strand-skeleton--shimmer {
	background: linear-gradient(
		90deg,
		var(--strand-gray-100) 25%,
		var(--strand-gray-50) 50%,
		var(--strand-gray-100) 75%
	);
	background-size: 200% 100%;
	animation: strand-skeleton-shimmer 1.8s var(--strand-ease-in-out-sine) infinite;
}

@keyframes strand-skeleton-shimmer {
	0% {
		background-position: 200% 0;
	}
	100% {
		background-position: -200% 0;
	}
}

/* ── Text variant ── */
.strand-skeleton--text {
	height: 1em;
	border-radius: var(--strand-radius-sm);
}

/* ── Rectangle variant ── */
.strand-skeleton--rectangle {
	border-radius: var(--strand-radius-md);
}

/* ── Circle variant ── */
.strand-skeleton--circle {
	border-radius: var(--strand-radius-full);
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-skeleton--shimmer {
		animation: none;
		background: var(--strand-gray-100);
	}
}

/* Slider */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-slider {
	position: relative;
	display: flex;
	align-items: center;
	width: 100%;
}

/* ── Field ── */
.strand-slider__field {
	/* The field itself is a 44px-tall transparent hit area so the
     full WCAG 2.5.5 touch target is draggable. The visible track
     is painted via the runnable-track pseudo-element. */
	width: 100%;
	min-height: var(--strand-touch-target);
	height: var(--strand-touch-target);
	appearance: none;
	background: transparent;
	outline: none;
	cursor: pointer;
}

/* ── Track: Webkit ── */
.strand-slider__field::-webkit-slider-runnable-track {
	height: 6px;
	background: var(--strand-gray-200);
	border-radius: var(--strand-radius-full);
}

/* ── Thumb: Webkit ──
   The earlier approach of width: 20px + border: 12px solid transparent +
   background-clip: padding-box collapses to a hollow ring in webkit
   because the slider thumb pseudo-element does not honor the
   padding-box clip the way regular elements do. The painted box
   shows only the (currently empty) padding region while the
   transparent border consumes the visible area. The fix is to use
   a flat 20x20 thumb with NO transparent border. The 44px hit area
   is provided by the field height above, not by an oversized
   thumb. */
.strand-slider__field::-webkit-slider-thumb {
	appearance: none;
	width: 20px;
	height: 20px;
	margin-top: -7px;
	background: var(--strand-blue-primary);
	border: none;
	border-radius: var(--strand-radius-full);
	cursor: pointer;
	box-shadow: var(--strand-elevation-1);
	transition: background var(--strand-duration-fast) var(--strand-ease-out-quart), transform
		var(--strand-duration-fast) var(--strand-ease-out-expo);
}

.strand-slider__field:hover:not(:disabled)::-webkit-slider-thumb {
	background: var(--strand-blue-vivid);
	transform: scale(1.15);
}

.strand-slider__field:active:not(:disabled)::-webkit-slider-thumb {
	background: var(--strand-blue-deep);
	transform: scale(1.05);
}

/* ── Thumb: Firefox ──
   Firefox does not need the manual margin offset because
   ::-moz-range-thumb is centered on the track automatically. */
.strand-slider__field::-moz-range-thumb {
	width: 20px;
	height: 20px;
	background: var(--strand-blue-primary);
	border: none;
	border-radius: var(--strand-radius-full);
	cursor: pointer;
	box-shadow: var(--strand-elevation-1);
	transition: background var(--strand-duration-fast) var(--strand-ease-out-quart), transform
		var(--strand-duration-fast) var(--strand-ease-out-expo);
}

.strand-slider__field:hover:not(:disabled)::-moz-range-thumb {
	background: var(--strand-blue-vivid);
	transform: scale(1.15);
}

.strand-slider__field:active:not(:disabled)::-moz-range-thumb {
	background: var(--strand-blue-deep);
	transform: scale(1.05);
}

/* ── Track: Firefox ── */
.strand-slider__field::-moz-range-track {
	height: 6px;
	background: var(--strand-gray-200);
	border-radius: var(--strand-radius-full);
}

/* ── Focus ── */
.strand-slider__field:focus-visible::-webkit-slider-thumb {
	box-shadow: var(--strand-focus-ring);
}

.strand-slider__field:focus-visible::-moz-range-thumb {
	box-shadow: var(--strand-focus-ring);
}

/* ── Disabled ── */
.strand-slider--disabled {
	opacity: 0.4;
	cursor: not-allowed;
}

.strand-slider--disabled .strand-slider__field {
	cursor: not-allowed;
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-slider__field::-webkit-slider-thumb {
		transition: none;
	}

	.strand-slider__field::-moz-range-thumb {
		transition: none;
	}
}

/* Spinner */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-spinner {
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

/* ── Ring ── */
.strand-spinner__ring {
	display: block;
	border: 2px solid var(--strand-gray-200);
	border-top-color: var(--strand-blue-primary);
	border-radius: var(--strand-radius-full);
	animation: strand-spinner-rotate 0.8s linear infinite;
}

/* ── Sizes ── */
.strand-spinner--sm .strand-spinner__ring {
	width: 16px;
	height: 16px;
}

.strand-spinner--md .strand-spinner__ring {
	width: 20px;
	height: 20px;
}

.strand-spinner--lg .strand-spinner__ring {
	width: 32px;
	height: 32px;
}

/* ── Animation ── */
@keyframes strand-spinner-rotate {
	to {
		transform: rotate(360deg);
	}
}

/* ── Screen reader only text ── */
.strand-spinner__sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-spinner__ring {
		animation: none;
		border-style: dotted;
	}
}

/* Stack */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-stack {
	display: flex;
	max-width: 100%;
	box-sizing: border-box;
}

.strand-stack > * {
	min-width: 0;
}

/* ── Direction ── */
.strand-stack--vertical {
	flex-direction: column;
}

.strand-stack--horizontal {
	flex-direction: row;
}

/* ── Alignment ── */
.strand-stack--align-start {
	align-items: flex-start;
}

.strand-stack--align-center {
	align-items: center;
}

.strand-stack--align-end {
	align-items: flex-end;
}

/* Default stretch handled by flexbox default */

/* ── Justification ── */
.strand-stack--justify-start {
	justify-content: flex-start;
}

.strand-stack--justify-center {
	justify-content: center;
}

.strand-stack--justify-end {
	justify-content: flex-end;
}

.strand-stack--justify-between {
	justify-content: space-between;
}

.strand-stack--justify-around {
	justify-content: space-around;
}

/* ── Wrap ── */
.strand-stack--wrap {
	flex-wrap: wrap;
}

/* ── Responsive direction (DL Part XV: small-screen reflow) ──
   Combine with strand-stack--horizontal: at <=768px the stack
   collapses to a vertical column, alignment recenters, and
   children are allowed to grow to a comfortable max-width via
   strand-stack__item--responsive (sets max-width 280px width 100%). */
@media (max-width: 768px) {
	.strand-stack--horizontal.strand-stack--responsive {
		flex-direction: column;
		align-items: center;
	}

	.strand-stack--responsive > .strand-stack__item--full-mobile,
	.strand-stack--responsive > .strand-btn {
		width: 100%;
		max-width: 280px;
	}
}

/* ── Gap utilities ── */
.strand-stack--gap-1 {
	gap: var(--strand-space-1);
}
.strand-stack--gap-2 {
	gap: var(--strand-space-2);
}
.strand-stack--gap-3 {
	gap: var(--strand-space-3);
}
.strand-stack--gap-4 {
	gap: var(--strand-space-4);
}
.strand-stack--gap-5 {
	gap: var(--strand-space-5);
}
.strand-stack--gap-6 {
	gap: var(--strand-space-6);
}
.strand-stack--gap-8 {
	gap: var(--strand-space-8);
}

/* Switch */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-switch {
	display: inline-flex;
	align-items: center;
	gap: var(--strand-space-2);
	min-height: var(--strand-touch-target);
	cursor: pointer;
	user-select: none;
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-sm);
	color: var(--strand-gray-900);
	line-height: var(--strand-leading-snug);
}

/* ── Track ── */
.strand-switch__track {
	position: relative;
	display: inline-flex;
	align-items: center;
	width: 40px;
	height: 22px;
	padding: 0;
	border: 1px solid var(--strand-gray-200);
	border-radius: var(--strand-radius-full);
	background: var(--strand-gray-200);
	cursor: pointer;
	flex-shrink: 0;
	transition: background var(--strand-duration-fast) var(--strand-ease-out-quart), border-color
		var(--strand-duration-fast) var(--strand-ease-out-quart), box-shadow var(--strand-duration-fast)
		var(--strand-ease-out-quart);
}

.strand-switch__track:focus-visible {
	border-color: var(--strand-blue-primary);
	box-shadow: var(--strand-focus-ring);
	outline: none;
}

/* ── Thumb ── */
.strand-switch__thumb {
	position: absolute;
	left: 2px;
	width: 16px;
	height: 16px;
	border-radius: var(--strand-radius-full);
	background: var(--strand-surface-elevated);
	box-shadow: var(--strand-elevation-1);
	transition: transform var(--strand-duration-fast) var(--strand-ease-out-expo);
}

/* ── Checked ── */
.strand-switch--checked .strand-switch__track {
	background: var(--strand-blue-primary);
	border-color: var(--strand-blue-primary);
}

.strand-switch--checked .strand-switch__thumb {
	transform: translateX(18px);
}

/* ── Hover ── */
.strand-switch:hover:not(.strand-switch--disabled) .strand-switch__track {
	border-color: var(--strand-blue-indicator);
}

.strand-switch--checked:hover:not(.strand-switch--disabled) .strand-switch__track {
	background: var(--strand-blue-vivid);
	border-color: var(--strand-blue-vivid);
}

/* ── Label ── */
.strand-switch__label {
	color: var(--strand-gray-900);
}

/* ── Disabled ── */
.strand-switch--disabled {
	opacity: 0.4;
	cursor: not-allowed;
}

.strand-switch--disabled .strand-switch__track {
	cursor: not-allowed;
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-switch__track,
	.strand-switch__thumb {
		transition: none;
	}
}

/* Table */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Wrapper (responsive scroll) ── */
.strand-table-wrapper {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

/* ── Table ── */
.strand-table {
	width: 100%;
	border-collapse: collapse;
	border-spacing: 0;
}

/* ── Header ── */
.strand-table__th {
	padding: var(--strand-space-3) var(--strand-space-4);
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-medium);
	letter-spacing: var(--strand-tracking-widest);
	text-transform: uppercase;
	color: var(--strand-gray-500);
	text-align: left;
	border-bottom: 1px solid var(--strand-gray-200);
	white-space: nowrap;
}

/* ── Sort button ── */
.strand-table__sort-btn {
	display: inline-flex;
	align-items: center;
	gap: var(--strand-space-1);
	padding: 0;
	border: none;
	background: none;
	font: inherit;
	color: inherit;
	letter-spacing: inherit;
	text-transform: inherit;
	cursor: pointer;
	white-space: nowrap;
}

.strand-table__sort-btn:hover {
	color: var(--strand-gray-600);
}

.strand-table__sort-btn:focus-visible {
	outline: 2px solid var(--strand-blue-primary);
	outline-offset: 2px;
}

.strand-table__sort-indicator {
	font-size: var(--strand-text-xs);
	opacity: 0.6;
}

/* ── Body ── */
.strand-table__td {
	padding: var(--strand-space-3) var(--strand-space-4);
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-sm);
	color: var(--strand-gray-600);
	border-bottom: 1px solid var(--strand-gray-200);
}

/* ── Row hover ── */
.strand-table__row {
	transition: background var(--strand-duration-fast) var(--strand-ease-out-quart);
}

.strand-table__row:hover {
	background: var(--strand-blue-glow);
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-table__row {
		transition: none;
	}
}

/* Tabs */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Tab list ── */
.strand-tabs [role="tablist"] {
	display: flex;
	gap: var(--strand-space-1);
	border-bottom: 1px solid var(--strand-gray-200);
}

/* ── Tab button ── */
.strand-tabs__tab {
	position: relative;
	padding: var(--strand-space-2) var(--strand-space-4);
	border: none;
	border-bottom: 2px solid transparent;
	background: none;
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-sm);
	font-weight: var(--strand-weight-medium);
	color: var(--strand-gray-500);
	cursor: pointer;
	transition: color var(--strand-duration-fast) var(--strand-ease-out-quart), border-color
		var(--strand-duration-fast) var(--strand-ease-out-expo);
}

.strand-tabs__tab:hover {
	color: var(--strand-gray-600);
}

.strand-tabs__tab:focus-visible {
	outline: 2px solid var(--strand-blue-primary);
	outline-offset: 2px;
}

.strand-tabs__tab--active {
	color: var(--strand-blue-primary);
	border-bottom-color: var(--strand-blue-primary);
}

/* ── Instrument variant (mono uppercase, control-panel feel) ──
   Use for state switches like "For Talent / For Employers" where
   the tab acts like a toggle on a control panel rather than a
   content navigation. Pairs with strand-tabs__panel--reveal. */
.strand-tabs--instrument [role="tablist"] {
	justify-content: center;
	gap: 0;
	border-bottom: 1px solid var(--strand-surface-subtle);
}

.strand-tabs--instrument .strand-tabs__tab {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-medium);
	letter-spacing: var(--strand-tracking-widest);
	text-transform: uppercase;
	color: var(--strand-gray-600);
	padding: var(--strand-space-3) var(--strand-space-6);
}

.strand-tabs--instrument .strand-tabs__tab--active {
	color: var(--strand-blue-midnight);
	border-bottom-color: var(--strand-blue-primary);
}

/* ── Panel ── */
.strand-tabs [role="tabpanel"] {
	padding: var(--strand-space-4) 0;
}

/* ── Panel reveal animation (DL Part VI motion: subtle entry) ──
   Apply to the active tab panel when switching tabs. Fades in
   with a small upward slide. JS toggles strand-tabs__panel--reveal
   on the panel that becomes active. */
@keyframes strand-tabs-reveal {
	from {
		opacity: 0;
		transform: translateY(8px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

.strand-tabs__panel--reveal {
	animation: strand-tabs-reveal var(--strand-duration-normal) var(--strand-ease-out-expo) both;
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-tabs__tab {
		transition: none;
	}
	.strand-tabs__panel--reveal {
		animation: none;
	}
}

/* Tag */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-tag {
	display: inline-flex;
	align-items: center;
	gap: var(--strand-space-1);
	padding: var(--strand-space-1) var(--strand-space-2);
	border-radius: var(--strand-radius-sm);
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-medium);
	line-height: var(--strand-leading-snug);
	white-space: nowrap;
	border: 1px solid transparent;
}

/* ── Solid variant ── */
.strand-tag--solid.strand-tag--default {
	background: var(--strand-surface-recessed);
	color: var(--strand-gray-600);
}

.strand-tag--solid.strand-tag--teal {
	background: var(--strand-surface-recessed);
	color: var(--strand-on-teal-tint);
}

.strand-tag--solid.strand-tag--blue {
	background: var(--strand-blue-glow);
	color: var(--strand-blue-deep);
}

.strand-tag--solid.strand-tag--amber {
	background: var(--strand-surface-recessed);
	color: var(--strand-on-amber-tint);
}

.strand-tag--solid.strand-tag--red {
	background: var(--strand-surface-recessed);
	color: var(--strand-on-red-tint);
}

/* ── Outlined variant ── */
.strand-tag--outlined {
	background: transparent;
}

.strand-tag--outlined.strand-tag--default {
	border-color: var(--strand-gray-200);
	color: var(--strand-gray-600);
}

.strand-tag--outlined.strand-tag--teal {
	border-color: var(--strand-teal-vital);
	color: var(--strand-on-teal-tint);
}

.strand-tag--outlined.strand-tag--blue {
	border-color: var(--strand-blue-primary);
	color: var(--strand-blue-deep);
}

.strand-tag--outlined.strand-tag--amber {
	border-color: var(--strand-amber-caution);
	color: var(--strand-on-amber-tint);
}

.strand-tag--outlined.strand-tag--red {
	border-color: var(--strand-red-alert);
	color: var(--strand-on-red-tint);
}

/* ── Remove button ── */
.strand-tag__remove {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	border: none;
	background: none;
	color: currentColor;
	opacity: 0.6;
	cursor: pointer;
	border-radius: var(--strand-radius-sm);
	transition: opacity var(--strand-duration-fast) var(--strand-ease-out-quart);
}

.strand-tag__remove:hover {
	opacity: 1;
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-tag__remove {
		transition: none;
	}
}

/* Textarea */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Base ── */
.strand-textarea {
	position: relative;
	display: flex;
	flex-direction: column;
	background: var(--strand-surface-elevated);
	border: 1px solid var(--strand-gray-200);
	border-radius: var(--strand-radius-md);
	transition: border-color var(--strand-duration-fast) var(--strand-ease-out-quart), box-shadow
		var(--strand-duration-fast) var(--strand-ease-out-quart);
}

.strand-textarea:focus-within {
	border-color: var(--strand-blue-primary);
	box-shadow: var(--strand-focus-ring);
}

/* ── Field ── */
.strand-textarea__field {
	width: 100%;
	min-height: 80px;
	padding: var(--strand-space-3) var(--strand-space-4);
	background: transparent;
	border: none;
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-base);
	color: var(--strand-gray-900);
	outline: none;
	resize: vertical;
	line-height: var(--strand-leading-normal);
}

.strand-textarea__field::placeholder {
	color: var(--strand-gray-400);
}

/* ── Auto-resize ── */
.strand-textarea--auto-resize .strand-textarea__field {
	resize: none;
	overflow: hidden;
}

/* ── Character count ── */
.strand-textarea__count {
	align-self: flex-end;
	padding: var(--strand-space-1) var(--strand-space-3) var(--strand-space-2);
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-xs);
	color: var(--strand-gray-500);
}

/* ── Error ── */
.strand-textarea--error {
	border-color: var(--strand-red-alert);
}

.strand-textarea--error:focus-within {
	border-color: var(--strand-red-alert);
	box-shadow: var(--strand-focus-ring-error);
}

/* ── Disabled ── */
.strand-textarea--disabled {
	opacity: 0.4;
	cursor: not-allowed;
}

.strand-textarea--disabled .strand-textarea__field {
	cursor: not-allowed;
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-textarea {
		transition: none;
	}
}

/* Toast */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Container ── */
.strand-toast__container {
	position: fixed;
	right: var(--strand-space-6);
	bottom: var(--strand-space-6);
	z-index: 1100;
	display: flex;
	flex-direction: column-reverse;
	gap: var(--strand-space-3);
	pointer-events: none;
}

/* ── Toast ── */
.strand-toast {
	display: flex;
	align-items: center;
	justify-content: space-between;
	min-width: 280px;
	max-width: 420px;
	padding: var(--strand-space-4) var(--strand-space-5);
	background: var(--strand-surface-elevated);
	border-radius: var(--strand-radius-lg);
	box-shadow: var(--strand-elevation-3);
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-sm);
	pointer-events: auto;
	animation: strand-toast-in var(--strand-duration-normal) var(--strand-ease-out-expo);
}

/* ── Status prefix ── */
.strand-toast__status {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-semibold);
	letter-spacing: var(--strand-tracking-wider);
	text-transform: uppercase;
	margin-right: var(--strand-space-3);
	flex-shrink: 0;
}

.strand-toast--info .strand-toast__status {
	color: var(--strand-blue-primary);
}
.strand-toast--success .strand-toast__status {
	color: var(--strand-teal-vital);
}
.strand-toast--warning .strand-toast__status {
	color: var(--strand-amber-caution);
}
.strand-toast--error .strand-toast__status {
	color: var(--strand-red-alert);
}

/* ── Message ── */
.strand-toast__message {
	flex: 1;
	min-width: 0;
	color: var(--strand-gray-900);
}

/* ── Dismiss button ── */
.strand-toast__dismiss {
	flex-shrink: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--strand-space-6);
	height: var(--strand-space-6);
	margin-left: var(--strand-space-3);
	padding: 0;
	border: none;
	border-radius: var(--strand-radius-md);
	background: transparent;
	color: var(--strand-gray-500);
	font-size: var(--strand-text-base);
	cursor: pointer;
	transition: background var(--strand-duration-fast) var(--strand-ease-out-quart), color
		var(--strand-duration-fast) var(--strand-ease-out-quart);
}

.strand-toast__dismiss:hover {
	background: var(--strand-gray-200);
	color: var(--strand-gray-600);
}

/* ── Animations ── */
@keyframes strand-toast-in {
	from {
		opacity: 0;
		transform: translateY(8px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-toast {
		animation: none;
	}

	.strand-toast__dismiss {
		transition: none;
	}
}

/* Tooltip */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Wrapper ── */
.strand-tooltip__wrapper {
	position: relative;
	display: inline-flex;
}

/* ── Tooltip ── */
.strand-tooltip {
	position: absolute;
	z-index: 1200;
	padding: var(--strand-space-1) var(--strand-space-2);
	background: var(--strand-gray-900);
	color: var(--strand-on-blue-primary);
	font-family: var(--strand-font-sans);
	font-size: var(--strand-text-xs);
	border-radius: var(--strand-radius-md);
	white-space: nowrap;
	pointer-events: none;
	opacity: 0;
	transition: opacity var(--strand-duration-fast) var(--strand-ease-out-quart);
}

.strand-tooltip--visible {
	opacity: 1;
}

/* ── Positions ── */
.strand-tooltip--top {
	bottom: 100%;
	left: 50%;
	transform: translateX(-50%);
	margin-bottom: var(--strand-space-2);
}

.strand-tooltip--bottom {
	top: 100%;
	left: 50%;
	transform: translateX(-50%);
	margin-top: var(--strand-space-2);
}

.strand-tooltip--left {
	right: 100%;
	top: 50%;
	transform: translateY(-50%);
	margin-right: var(--strand-space-2);
}

.strand-tooltip--right {
	left: 100%;
	top: 50%;
	transform: translateY(-50%);
	margin-left: var(--strand-space-2);
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
	.strand-tooltip {
		transition: none;
	}
}

/* Static */
/*! Strand UI | MIT License | dillingerstaffing.com */

/* ── Presentation mode ──
   Add .strand-static to a parent element to render components
   at full visual fidelity without interaction.
   Use for documentation, showcases, and screenshots. */

.strand-static {
	pointer-events: none;
}

.strand-static [disabled],
.strand-static [aria-disabled="true"] {
	opacity: 1;
	cursor: default;
}

.strand-static .strand-btn:disabled {
	opacity: 1;
	cursor: default;
}

.strand-static .strand-toast {
	position: static;
}

.strand-static .strand-tooltip {
	position: static;
}

.strand-static *,
.strand-static *::before,
.strand-static *::after {
	transition: none !important;
	animation: none !important;
}

/* ── Recessed viewport ──
   The instrument viewport sits below the card surface.
   Use for component previews, showcases, and documentation. */

.strand-viewport {
	background: var(--strand-surface-recessed);
	box-shadow: var(--strand-shadow-inset);
	border-radius: var(--strand-radius-lg);
	padding: var(--strand-space-6);
}

/* ── Frosted viewport (DL Part 9.4) ──
   Light data-dense context with frosted-glass character. The
   "frosted instrument panel embedded in the lab bench" feel,
   without going dark. Backdrop-filter requires content behind it. */
.strand-viewport--frosted {
	background: var(--strand-glass-bg);
	-webkit-backdrop-filter: blur(var(--strand-glass-blur));
	backdrop-filter: blur(var(--strand-glass-blur));
	border: 1px solid var(--strand-glass-border);
	border-radius: var(--strand-radius-lg);
	box-shadow: var(--strand-shadow-inset);
	padding: var(--strand-space-6);
}

/* ── Glass surface utility (DL Part 9.5) ──
   Frosted-glass treatment for any element that wants the
   "glass walls with controlled daylight" character. Apply to
   nav, sticky toolbars, modal headers, surfaces above content.
   backdrop-filter only renders meaningfully when there is
   something behind the element. */
.strand-glass-surface {
	background: var(--strand-glass-bg);
	-webkit-backdrop-filter: blur(var(--strand-glass-blur));
	backdrop-filter: blur(var(--strand-glass-blur));
	border: 1px solid var(--strand-glass-border);
}

/* ── Overline (specimen label pattern, DL Part IV.5) ── */
.strand-overline {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-medium);
	letter-spacing: var(--strand-tracking-ultra);
	text-transform: uppercase;
	color: var(--strand-gray-500);
	line-height: var(--strand-leading-normal);
}

/* ── Overline accent variant (blue instead of gray) ──
   Uses blue-deep so the small uppercase text meets WCAG AA 4.5:1
   contrast on the default white surface. blue-primary (#3b82f6)
   only scores 3.28:1 at 10.4px mono. blue-deep stays vibrant
   without violating contrast. */
.strand-overline--accent {
	color: var(--strand-blue-deep);
}

/* ── Overline with pulse dot (DL Part 7: alive signal) ──
   Adds an animated dot prefix that pulses in a slow rhythm. Use on
   the primary hero overline to signal "this is a living system."
   Combine with strand-overline--accent for the blue brand color.
   The dot uses blue-primary; on dark backgrounds use teal-vital.

   The display: inline-block + relative positioning shrinks the
   overline to its text width so the absolutely-positioned dot
   sits immediately to the LEFT of the text -- not to the left of
   a full-width parent container. */
.strand-overline--pulse {
	position: relative;
	padding-left: var(--strand-space-4);
	display: inline-block !important;
}

.strand-overline--pulse::before {
	content: "";
	position: absolute;
	left: 0;
	top: 50%;
	width: 6px;
	height: 6px;
	margin-top: -3px;
	border-radius: var(--strand-radius-full);
	background: var(--strand-blue-primary);
	animation: strand-overline-pulse 2s var(--strand-ease-in-out-sine) infinite;
}

@keyframes strand-overline-pulse {
	0%,
	100% {
		opacity: 1;
	}
	50% {
		opacity: 0.4;
	}
}

@media (prefers-reduced-motion: reduce) {
	.strand-overline--pulse::before {
		animation: none;
	}
}

/* DL Part XVII.2: Contrast-safe pairing on recessed surfaces.
   gray-500 on surface-recessed fails 4.5:1 for small text.
   Auto-darken to gray-600 when inside a recessed context. */
.strand-section--bg-recessed .strand-overline {
	color: var(--strand-gray-600);
}

.strand-section--bg-recessed .strand-overline--accent {
	color: var(--strand-blue-deep);
}

.strand-section--bg-recessed .strand-lead {
	color: var(--strand-gray-600);
}

.strand-section--bg-recessed .strand-text-secondary {
	color: var(--strand-gray-600);
}

.strand-section--bg-recessed .strand-step-indicator {
	color: var(--strand-blue-deep);
}

/* All small text on recessed surfaces needs darker colors for WCAG 4.5:1 */
.strand-section--bg-recessed .strand-tabs__tab,
.strand-section--bg-recessed .strand-form-field__label,
.strand-section--bg-recessed .strand-form-field__hint,
.strand-section--bg-recessed .strand-badge--default {
	color: var(--strand-gray-600);
}

.strand-section--bg-recessed .strand-tabs__tab--active {
	color: var(--strand-blue-deep);
	border-bottom-color: var(--strand-blue-deep);
}

/* ── Headline (display heading, DL Part IV.5) ── */
.strand-headline {
	font-family: var(--strand-font-mono);
	font-weight: var(--strand-weight-light);
	letter-spacing: var(--strand-tracking-widest);
	text-transform: uppercase;
	color: var(--strand-blue-midnight);
	line-height: var(--strand-leading-tight);
}

.strand-headline--xl {
	font-size: clamp(2.5rem, 5vw + 1rem, 5rem);
	letter-spacing: 0.35em;
}

.strand-headline--lg {
	font-size: clamp(1.5rem, 3vw + 0.5rem, 2.5rem);
	letter-spacing: var(--strand-tracking-tighter);
}

/* ── Gradient text effect (premium hero headlines) ── */
.strand-headline--gradient {
	background: linear-gradient(180deg, var(--strand-gray-900) 0%, var(--strand-blue-midnight) 100%);
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
}

/* ── Title (human voice display, DL Part IV.7) ── */
.strand-title {
	font-family: var(--strand-font-sans);
	font-weight: var(--strand-weight-light);
	letter-spacing: var(--strand-tracking-tighter);
	color: var(--strand-blue-midnight);
	font-size: clamp(1.5rem, 3vw + 0.5rem, 2.5rem);
	line-height: var(--strand-leading-snug);
}

/* ── Lead (intro paragraph, DL Part IV.6) ── */
.strand-lead {
	font-size: var(--strand-text-lg);
	color: var(--strand-gray-500);
	max-width: 50ch;
	line-height: var(--strand-leading-relaxed);
}

/* ── Secondary text (caption/description, DL Part III.8 Color Roles) ── */
.strand-text-secondary {
	font-size: var(--strand-text-sm);
	color: var(--strand-gray-500);
	line-height: var(--strand-leading-relaxed);
}

.strand-text-secondary strong {
	color: var(--strand-gray-700);
}

.strand-text-secondary a {
	color: var(--strand-blue-primary);
	text-decoration: none;
}

.strand-text-secondary a:hover {
	color: var(--strand-blue-vivid);
}

.strand-text-secondary--xs {
	font-size: var(--strand-text-xs);
}

/* ══════════════════════════════════════════════════
   COMPOSITION MOLECULES (DL Part XI-B Grammar)
   Named derivations of DL composition primitives.
   Each molecule is a convenience class for a common
   derivation chain. See DL 11.10 Productions for the
   grammar rules; DL 11.12 Derivation for verification.
   ══════════════════════════════════════════════════ */

/* ── Card Section ──
   Derivation: section-boundary production (DL 11.10).
   OVERLINE + border-bottom + margin-bottom + padding-bottom */
.strand-card-section {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: var(--strand-space-3);
	padding-bottom: var(--strand-space-2);
	border-bottom: 1px solid var(--strand-gray-200);
}

/* ── Key-Value Row ──
   Derivation: inline-pair + ranked-sequence (DL 11.10).
   identifier(OVERLINE) + quantifier(MONO_VALUE) + RANK_BORDER */
.strand-kv {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding-block: var(--strand-space-2);
}

.strand-kv + .strand-kv {
	border-top: 1px solid var(--strand-border-subtle);
}

.strand-kv__label {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-medium);
	letter-spacing: var(--strand-tracking-wider);
	text-transform: uppercase;
	color: var(--strand-gray-500);
}

.strand-kv__value {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	color: var(--strand-gray-600);
	font-variant-numeric: tabular-nums;
}

.strand-kv__value--status {
	color: var(--strand-teal-vital);
}

/* ── Diagnostic Log Entry ──
   Derivation: inline-sequence + ranked-sequence (DL 11.10).
   time(OVERLINE) + status(OVERLINE+COLOR_SEMANTIC) + text(SECONDARY) + RANK_BORDER */
.strand-log {
	display: flex;
	gap: var(--strand-space-3);
	padding-block: var(--strand-space-2);
}

.strand-log + .strand-log {
	border-top: 1px solid var(--strand-border-subtle);
}

.strand-log__time {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-medium);
	letter-spacing: var(--strand-tracking-wider);
	text-transform: uppercase;
	color: var(--strand-gray-400);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.strand-log__status {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-semibold);
	letter-spacing: var(--strand-tracking-wider);
	text-transform: uppercase;
	white-space: nowrap;
}

.strand-log__status--complete {
	color: var(--strand-teal-vital);
}
.strand-log__status--process {
	color: var(--strand-blue-primary);
}
.strand-log__status--warning {
	color: var(--strand-amber-caution);
}
.strand-log__status--error {
	color: var(--strand-red-alert);
}

/* ── Metric Row ──
   Derivation: centered-group (DL 11.10).
   self-contained(atom)* with center distribution + responsive gap */
.strand-metric-row {
	display: flex;
	justify-content: center;
	gap: clamp(2rem, 5vw, 4rem);
	text-align: center;
}

/* ── Bar Chart ──
   Derivation: column-array (DL 11.10).
   column(amount? + bar + label)* with equal flex + flex-end alignment.
   Blue Discipline: one color (--strand-blue-indicator). Part XIII viz rules. */
.strand-bar-chart {
	display: flex;
	gap: var(--strand-space-2);
	align-items: flex-end;
	height: var(--strand-space-24);
	padding: var(--strand-space-5);
}

.strand-bar-chart__col {
	flex: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--strand-space-1);
	height: 100%;
	justify-content: flex-end;
}

.strand-bar-chart__bar {
	width: 100%;
	background: var(--strand-blue-indicator);
	border-radius: var(--strand-radius-sm) var(--strand-radius-sm) 0 0;
	min-height: var(--strand-space-1);
}

.strand-bar-chart__amount {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-medium);
	letter-spacing: var(--strand-tracking-wider);
	text-transform: uppercase;
	color: var(--strand-gray-300);
	font-variant-numeric: tabular-nums;
}

.strand-bar-chart__label {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-medium);
	letter-spacing: var(--strand-tracking-wider);
	text-transform: uppercase;
	color: var(--strand-gray-400);
}

/* ══════════════════════════════════════════════════
   UTILITIES
   ══════════════════════════════════════════════════ */

/* ── Screen reader only ── */
.strand-sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ── Section header ──
   Derivation: section-boundary production (DL 11.10).
   Centered heading group with bottom margin. */
.strand-section-header {
	margin-bottom: clamp(2rem, 4vw, 4rem);
}

/* ── Step indicator ──
   Numbered position indicator for sequential steps. */
.strand-step-indicator {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--strand-space-8);
	height: var(--strand-space-8);
	border-radius: var(--strand-radius-full);
	background: var(--strand-blue-glow);
	color: var(--strand-blue-primary);
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-sm);
	font-weight: var(--strand-weight-semibold);
	margin-bottom: var(--strand-space-3);
}

/* ── Text center ── */
.strand-text-center {
	text-align: center;
}

/* ── Code name (mono identifier heading) ── */
.strand-code-name {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-base);
	font-weight: var(--strand-weight-semibold);
	color: var(--strand-blue-midnight);
	margin: 0;
}

/* ── Heading small (section heading inside cards) ── */
.strand-heading--sm {
	font-size: var(--strand-text-lg);
	font-weight: var(--strand-weight-medium);
	color: var(--strand-gray-800);
	margin: 0;
}

/* ═══ HEADLINE MONO VARIANT (DL Part IV.5) ═══
   Mono-family headline with medium weight, tight tracking,
   and sentence case (NOT uppercase). Use for product/lab
   titles where the brand identity is typed in lowercase or
   mixed case ("trust" vs "TRUST"). Composes with
   strand-headline--sm/md/lg for size. */
.strand-headline--mono {
	font-family: var(--strand-font-mono);
	font-weight: var(--strand-weight-medium);
	text-transform: none;
	letter-spacing: var(--strand-tracking-tight);
}

.strand-headline--md {
	font-size: clamp(1.25rem, 2vw + 0.5rem, 1.75rem);
	letter-spacing: var(--strand-tracking-tight);
}

/* ═══ STATUS CHIP (DL Part XVII: small classification label) ═══
   Inline pill for lab/product status. Mono uppercase, small tint.
   Pair with strand-card or header rows. */
.strand-status-chip {
	display: inline-block;
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-medium);
	letter-spacing: var(--strand-tracking-wide);
	text-transform: uppercase;
	padding: var(--strand-space-1) var(--strand-space-2);
	border-radius: var(--strand-radius-sm);
	line-height: var(--strand-leading-normal);
}

.strand-status-chip--live {
	color: var(--strand-on-teal-tint);
	background: var(--strand-teal-tint);
}

.strand-status-chip--neutral {
	color: var(--strand-gray-600);
	background: var(--strand-gray-tint);
}

.strand-status-chip--accent {
	color: var(--strand-blue-deep);
	background: var(--strand-blue-tint);
}

.strand-status-chip--caution {
	color: var(--strand-on-amber-tint);
	background: var(--strand-amber-tint);
}

/* ── Viewport flex modifiers (component showcase layout) ── */
.strand-viewport--flex {
	display: flex;
	align-items: center;
	gap: var(--strand-space-4);
	flex-wrap: wrap;
}

.strand-viewport--flex-col {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--strand-space-4);
}

/* ═══ CONNECTED STEPS (DL Part XI-B: connected-sequence production) ═══
   Sequential process steps with a visual connector line between cards.
   Use with a grid of strand-card elements inside. */
.strand-steps-connected {
	position: relative;
}

.strand-steps-connected::before {
	content: "";
	position: absolute;
	top: 50%;
	left: var(--strand-space-8);
	right: var(--strand-space-8);
	height: 1px;
	background: linear-gradient(
		90deg,
		transparent 0%,
		var(--strand-blue-indicator) 20%,
		var(--strand-blue-indicator) 80%,
		transparent 100%
	);
	z-index: 0;
	pointer-events: none;
}

.strand-steps-connected > * {
	position: relative;
	z-index: 1;
}

@media (max-width: 767px) {
	.strand-steps-connected::before {
		display: none;
	}
}

/* ═══ FOOTER (DL Part XIX.5) ═══
   Compact closing panel. Border-top, centered, quiet. */
.strand-footer {
	padding: var(--strand-space-12) 0;
	border-top: 1px solid var(--strand-gray-200);
	text-align: center;
}

.strand-footer__nav {
	display: flex;
	justify-content: center;
	gap: var(--strand-space-6);
	flex-wrap: wrap;
	margin-bottom: var(--strand-space-6);
}

.strand-footer__link {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	letter-spacing: var(--strand-tracking-wider);
	color: var(--strand-gray-400);
	text-decoration: none;
	transition: color var(--strand-duration-fast) ease;
}

.strand-footer__link:hover {
	color: var(--strand-blue-primary);
}

.strand-footer__copy {
	font-size: var(--strand-text-xs);
	color: var(--strand-gray-400);
}

/* ═══ FORM LAYOUT (DL Part XVIII.1: Specimen Collection Room) ═══ */
.strand-form-grid {
	display: grid;
	gap: var(--strand-space-6);
}

.strand-form-row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--strand-space-6);
}

@media (max-width: 639px) {
	.strand-form-row {
		grid-template-columns: 1fr;
	}
}

/* ═══ HONEYPOT (DL Part XI.1: form security) ═══
   Hidden field that bots fill but humans never see.
   NOT display:none (some bots skip those).
   Positioned offscreen with aria-hidden and tabindex=-1. */
.strand-honeypot {
	position: absolute;
	left: -9999px;
	top: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
	opacity: 0;
	pointer-events: none;
}

/* ═══ HERO BACKGROUND (DL Part IX.4: hero surface treatment) ═══
   Full-bleed container behind hero content. Holds animated SVG,
   WebGL canvas, gradient, or any hero visual. */
.strand-hero-bg {
	position: absolute;
	inset: 0;
	overflow: hidden;
	pointer-events: none;
	z-index: 0;
}

.strand-hero-bg > * {
	width: 100%;
	height: 100%;
}

/* ═══ HERO NODE GRID (DL Part IX.4 + Principle 7: alive signal) ═══
   Animated SVG background showing a field of pulsing connection
   points. Use inside strand-hero-bg with an inline <svg>. Nodes and
   lines inherit color via currentColor; wire animation delays with
   the .strand-hero-grid__line--N modifiers (1-18). */
.strand-hero-grid {
	color: var(--strand-blue-primary);
}

.strand-hero-grid svg {
	width: 100%;
	height: 100%;
}

.strand-hero-grid__nodes {
	fill: currentColor;
	opacity: 0.2;
}

.strand-hero-grid__lines {
	stroke: currentColor;
	fill: none;
	stroke-width: 0.5;
	opacity: 0.08;
}

.strand-hero-grid__line {
	animation: strand-hero-grid-glow 12s var(--strand-ease-in-out-sine) infinite;
}

.strand-hero-grid__line--1 {
	animation-delay: 0s;
}
.strand-hero-grid__line--2 {
	animation-delay: 1s;
}
.strand-hero-grid__line--3 {
	animation-delay: 2s;
}
.strand-hero-grid__line--4 {
	animation-delay: 0.5s;
}
.strand-hero-grid__line--5 {
	animation-delay: 3s;
}
.strand-hero-grid__line--6 {
	animation-delay: 1.5s;
}
.strand-hero-grid__line--7 {
	animation-delay: 4s;
}
.strand-hero-grid__line--8 {
	animation-delay: 2.5s;
}
.strand-hero-grid__line--9 {
	animation-delay: 5s;
}
.strand-hero-grid__line--10 {
	animation-delay: 3.5s;
}
.strand-hero-grid__line--11 {
	animation-delay: 6s;
}
.strand-hero-grid__line--12 {
	animation-delay: 4.5s;
}
.strand-hero-grid__line--13 {
	animation-delay: 7s;
}
.strand-hero-grid__line--14 {
	animation-delay: 5.5s;
}
.strand-hero-grid__line--15 {
	animation-delay: 8s;
}
.strand-hero-grid__line--16 {
	animation-delay: 6.5s;
}
.strand-hero-grid__line--17 {
	animation-delay: 9s;
}
.strand-hero-grid__line--18 {
	animation-delay: 7.5s;
}

@keyframes strand-hero-grid-glow {
	0%,
	100% {
		stroke-opacity: 0.08;
	}
	50% {
		stroke-opacity: 0.4;
	}
}

/* ═══ PULSE INDICATOR (DL Principle 7: alive signal) ═══
   Small pulsing dot. Indicates "this element is live/active."
   Same concept as strand-card--active but as a point indicator.
   Use as ::after on logos, status dots, live badges. */
.strand-pulse {
	position: relative;
}

.strand-pulse::after {
	content: "";
	position: absolute;
	top: 0;
	right: -6px;
	width: 6px;
	height: 6px;
	border-radius: var(--strand-radius-full);
	background: var(--strand-teal-vital);
	animation: strand-pulse-glow 3s var(--strand-ease-in-out-sine) infinite;
}

@keyframes strand-pulse-glow {
	0%,
	100% {
		opacity: 0.4;
		transform: scale(1);
	}
	50% {
		opacity: 1;
		transform: scale(1.2);
	}
}

/* ═══ AUTH INDICATOR (nav utility) ═══
   Small text indicator for signed-in state in nav. */
.strand-auth-indicator {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	color: var(--strand-gray-400);
	letter-spacing: var(--strand-tracking-wide);
	white-space: nowrap;
}

.strand-auth-avatar {
	width: 28px;
	height: 28px;
	border-radius: var(--strand-radius-full);
	background: var(--strand-blue-glow);
	color: var(--strand-blue-primary);
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-semibold);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	text-decoration: none;
}

/* ═══ EMPTY STATES (DL Part XXI) ═══
   When an instrument has no data, it does not disappear.
   It shows an idle state. The label remains, the value
   becomes a placeholder. The user understands the
   instrument exists and will activate when data arrives. */

/* ── Idle Readout (DL Part 21.1) ──
   A DataReadout with no value. Shows -- in the value
   position, with the label still visible. Apply alongside
   .strand-data-readout. */
.strand-idle-readout .strand-data-readout__value::before {
	content: "--";
	color: var(--strand-gray-300);
	font-variant-numeric: tabular-nums;
}

.strand-idle-readout .strand-data-readout__value > * {
	display: none;
}

/* ── Empty Collection (DL Part 21.2) ──
   A list or grid with no items. Centered message in
   instrument voice. No illustration. The absence of data
   IS the visual. */
.strand-empty-collection {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	padding: var(--strand-space-16) var(--strand-space-6);
	text-align: center;
	color: var(--strand-gray-400);
	font-family: var(--strand-font-sans);
}

.strand-empty-collection__message {
	font-size: var(--strand-text-base);
	color: var(--strand-gray-500);
	margin: 0;
}

.strand-empty-collection__action {
	margin-top: var(--strand-space-4);
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-xs);
	font-weight: var(--strand-weight-medium);
	letter-spacing: var(--strand-tracking-widest);
	text-transform: uppercase;
	color: var(--strand-blue-primary);
	text-decoration: none;
	background-image: linear-gradient(var(--strand-blue-primary), var(--strand-blue-primary));
	background-size: 0% 1px;
	background-position: left bottom;
	background-repeat: no-repeat;
	transition: background-size var(--strand-duration-normal) var(--strand-ease-out-expo);
}

.strand-empty-collection__action:hover {
	background-size: 100% 1px;
}

/* ── Empty Search (DL Part 21.3) ──
   "0 matches detected." plus suggestion in secondary text.
   The search instrument ran and returned nothing. */
.strand-empty-search {
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: var(--strand-space-12) var(--strand-space-6);
	text-align: center;
}

.strand-empty-search__count {
	font-family: var(--strand-font-mono);
	font-size: var(--strand-text-sm);
	font-weight: var(--strand-weight-medium);
	letter-spacing: var(--strand-tracking-wider);
	text-transform: uppercase;
	color: var(--strand-gray-500);
	margin-bottom: var(--strand-space-2);
}

.strand-empty-search__suggestion {
	font-size: var(--strand-text-sm);
	color: var(--strand-gray-400);
	line-height: var(--strand-leading-relaxed);
	max-width: 50ch;
}

/* ═══ UTILITY CLASSES ══════════════════════════════
   Atomic, single-property helpers. Token-only values.
   Use sparingly: prefer named primitives and molecules
   when a coherent concept exists. These exist to absorb
   the long tail of one-off layout glue without forcing
   consumers to ship inline styles or per-page CSS files.
   ═══════════════════════════════════════════════════ */

/* ── Display ── */
.strand-block {
	display: block;
}

/* ── Flex / sizing ── */
.strand-flex-1 {
	flex: 1;
}
.strand-min-w-0 {
	min-width: 0;
}
.strand-full-width {
	width: 100%;
}
.strand-w-full {
	width: 100%;
}

/* ── Margin top (token scale 1-8) ── */
.strand-mt-1 {
	margin-top: var(--strand-space-1);
}
.strand-mt-2 {
	margin-top: var(--strand-space-2);
}
.strand-mt-3 {
	margin-top: var(--strand-space-3);
}
.strand-mt-4 {
	margin-top: var(--strand-space-4);
}
.strand-mt-5 {
	margin-top: var(--strand-space-5);
}
.strand-mt-6 {
	margin-top: var(--strand-space-6);
}
.strand-mt-8 {
	margin-top: var(--strand-space-8);
}

/* ── Margin bottom (token scale 1-8) ── */
.strand-mb-1 {
	margin-bottom: var(--strand-space-1);
}
.strand-mb-2 {
	margin-bottom: var(--strand-space-2);
}
.strand-mb-3 {
	margin-bottom: var(--strand-space-3);
}
.strand-mb-4 {
	margin-bottom: var(--strand-space-4);
}
.strand-mb-5 {
	margin-bottom: var(--strand-space-5);
}
.strand-mb-6 {
	margin-bottom: var(--strand-space-6);
}
.strand-mb-8 {
	margin-bottom: var(--strand-space-8);
}

/* ── Margin auto (centering) ── */
.strand-mx-auto {
	margin-inline: auto;
}

@media (prefers-reduced-motion: reduce) {
	.strand-footer__link {
		transition: none;
	}

	.strand-pulse::after {
		animation: none;
		opacity: 0.6;
	}

	.strand-hero-bg {
		display: none;
	}
}
