/*
 * Reusable components (§25). Every future phase consumes these classes
 * instead of restyling the same element again.
 */

/* Card ---------------------------------------------------------------- */
.xn-card {
	position: relative;
	background: var(--xn-surface);
	border: 1px solid var(--xn-border);
	border-radius: var(--xn-radius-lg);
	padding: var(--xn-space-5);
	box-shadow: var(--xn-shadow);
	overflow: hidden;
}

.xn-card__title {
	font-size: var(--xn-text-card);
	font-weight: var(--xn-weight-title);
	margin-block-end: var(--xn-space-4);
}

.xn-card--empty {
	background: var(--xn-surface-secondary);
	box-shadow: none;
}

/*
 * Signature: the coating rail.
 * A thin light sweep travelling down the leading edge of a panel — the way
 * light moves across a freshly coated body panel. It is the one animated
 * element in the system; everything else stays still.
 */
.xn-card--rail::before {
	content: "";
	position: absolute;
	inset-block: 0;
	inset-inline-start: 0;
	width: 3px;
	background: linear-gradient(
		180deg,
		transparent 0%,
		var(--xn-primary) 18%,
		var(--xn-accent) 50%,
		var(--xn-primary) 82%,
		transparent 100%
	);
	background-size: 100% 220%;
	animation: xn-rail 6s var(--xn-ease) infinite;
}

@keyframes xn-rail {
	0%   { background-position: 0 -110%; }
	100% { background-position: 0 110%; }
}

/* Buttons -------------------------------------------------------------- */
.xn-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--xn-space-2);
	min-height: 44px; /* thumb-sized: staff use this on phones in the bay */
	padding-inline: var(--xn-space-5);
	border: 1px solid transparent;
	border-radius: var(--xn-radius-md);
	font-family: inherit;
	font-size: var(--xn-text-body);
	font-weight: var(--xn-weight-title);
	cursor: pointer;
	transition: transform var(--xn-speed) var(--xn-ease),
		background-color var(--xn-speed) var(--xn-ease),
		border-color var(--xn-speed) var(--xn-ease);
}

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

.xn-btn--primary {
	background: var(--xn-primary);
	color: var(--xn-primary-contrast);
	box-shadow: 0 10px 26px -14px var(--xn-glow);
}

.xn-btn--primary:hover {
	background: var(--xn-primary-light);
}

.xn-btn--ghost {
	background: transparent;
	color: var(--xn-text);
	border-color: var(--xn-border);
}

.xn-btn--ghost:hover {
	border-color: var(--xn-primary-light);
	color: var(--xn-primary-light);
}

.xn-btn--block {
	width: 100%;
}

.xn-iconbtn {
	display: inline-flex;
	align-items: center;
	gap: var(--xn-space-2);
	min-height: 40px;
	padding-inline: var(--xn-space-3);
	background: transparent;
	color: var(--xn-text-muted);
	border: 1px solid var(--xn-border);
	border-radius: var(--xn-radius-pill);
	font-family: inherit;
	font-size: var(--xn-text-small);
	font-weight: var(--xn-weight-body);
	cursor: pointer;
}

.xn-iconbtn:hover {
	color: var(--xn-text);
	border-color: var(--xn-primary-light);
}

/* Forms ---------------------------------------------------------------- */
.xn-form {
	display: grid;
	gap: var(--xn-space-4);
	margin-block-start: var(--xn-space-5);
}

/*
 * The hidden attribute must win.
 *
 * A class that sets a display — grid, flex, block — has the same specificity
 * as [hidden]'s built-in display:none and comes later in the cascade, so it
 * silently overrides it. Every element hidden by script and styled by such a
 * class stayed on screen: the warranty duration fields were the visible
 * symptom, but a dozen classes shared the fault.
 */
[hidden] {
	display: none !important;
}

.xn-field {
	display: grid;
	gap: var(--xn-space-2);
}

.xn-label {
	font-size: var(--xn-text-small);
	font-weight: var(--xn-weight-title);
	color: var(--xn-text-muted);
}

.xn-input {
	width: 100%;
	min-height: 46px;
	padding-inline: var(--xn-space-4);
	background: var(--xn-surface-secondary);
	color: var(--xn-text);
	border: 1px solid var(--xn-border);
	border-radius: var(--xn-radius-md);
	font-family: inherit;
	font-size: var(--xn-text-body);
	transition: border-color var(--xn-speed) var(--xn-ease),
		box-shadow var(--xn-speed) var(--xn-ease);
}

.xn-input:focus {
	outline: none;
	border-color: var(--xn-primary-light);
	box-shadow: 0 0 0 3px var(--xn-ring);
}

.xn-check {
	display: flex;
	align-items: center;
	gap: var(--xn-space-2);
	font-size: var(--xn-text-small);
	color: var(--xn-text-muted);
	cursor: pointer;
}

.xn-check input {
	width: 18px;
	height: 18px;
	accent-color: var(--xn-primary);
}

.xn-link {
	font-size: var(--xn-text-small);
}

/* Alerts --------------------------------------------------------------- */
.xn-alert {
	margin-block: var(--xn-space-4);
	padding: var(--xn-space-3) var(--xn-space-4);
	border-radius: var(--xn-radius-md);
	border: 1px solid;
	font-size: var(--xn-text-small);
	line-height: 1.6;
}

.xn-alert--error {
	color: var(--xn-error);
	border-color: color-mix(in srgb, var(--xn-error) 40%, transparent);
	background: color-mix(in srgb, var(--xn-error) 10%, transparent);
}

.xn-alert--success {
	color: var(--xn-success);
	border-color: color-mix(in srgb, var(--xn-success) 40%, transparent);
	background: color-mix(in srgb, var(--xn-success) 10%, transparent);
}

.xn-alert--warning {
	color: var(--xn-warning);
	border-color: color-mix(in srgb, var(--xn-warning) 40%, transparent);
	background: color-mix(in srgb, var(--xn-warning) 10%, transparent);
}

.xn-alert--info {
	color: var(--xn-info);
	border-color: color-mix(in srgb, var(--xn-info) 40%, transparent);
	background: color-mix(in srgb, var(--xn-info) 10%, transparent);
}

/* Badges --------------------------------------------------------------- */
.xn-badge {
	display: inline-flex;
	align-items: center;
	padding: 2px var(--xn-space-2);
	border-radius: var(--xn-radius-pill);
	font-size: 0.6875rem;
	font-style: normal;
	font-weight: var(--xn-weight-title);
	white-space: nowrap;
}

.xn-badge--muted {
	color: var(--xn-text-muted);
	background: var(--xn-surface-secondary);
	border: 1px solid var(--xn-border);
}

.xn-badge--success {
	color: var(--xn-success);
	background: color-mix(in srgb, var(--xn-success) 14%, transparent);
	border: 1px solid color-mix(in srgb, var(--xn-success) 40%, transparent);
}

.xn-badge--accent {
	color: var(--xn-primary-dark);
	background: var(--xn-accent);
}

/* Definition list (used for record detail) ----------------------------- */
.xn-deflist {
	display: grid;
	gap: var(--xn-space-3);
}

.xn-deflist > div {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--xn-space-4);
	padding-block-end: var(--xn-space-3);
	border-block-end: 1px dashed var(--xn-border);
}

.xn-deflist > div:last-child {
	border-block-end: 0;
	padding-block-end: 0;
}

.xn-deflist dt {
	color: var(--xn-text-muted);
	font-size: var(--xn-text-small);
}

.xn-deflist dd {
	font-weight: var(--xn-weight-title);
	text-align: end;
}

/* States: loading, empty, error ---------------------------------------- */
.xn-state {
	display: flex;
	align-items: center;
	gap: var(--xn-space-3);
	color: var(--xn-text-muted);
	font-size: var(--xn-text-small);
}

.xn-spinner {
	width: 16px;
	height: 16px;
	border: 2px solid var(--xn-border);
	border-top-color: var(--xn-primary-light);
	border-radius: 50%;
	animation: xn-spin 700ms linear infinite;
}

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

/* Eyebrow label above a title ------------------------------------------ */
.xn-eyebrow {
	color: var(--xn-accent);
	font-size: var(--xn-text-small);
	font-weight: var(--xn-weight-title);
	letter-spacing: 0.08em;
	margin-block-end: var(--xn-space-1);
}

/* Password field with a reveal control --------------------------------- */
.xn-input-wrap {
	position: relative;
	display: flex;
	align-items: center;
}

.xn-input--withbtn {
	padding-inline-end: 5rem;
}

.xn-reveal {
	position: absolute;
	inset-inline-end: var(--xn-space-2);
	min-height: 32px;
	padding-inline: var(--xn-space-3);
	background: var(--xn-surface);
	color: var(--xn-text-muted);
	border: 1px solid var(--xn-border);
	border-radius: var(--xn-radius-sm);
	font-family: inherit;
	font-size: var(--xn-text-small);
	cursor: pointer;
}

.xn-reveal:hover {
	color: var(--xn-text);
	border-color: var(--xn-primary-light);
}

/* Inline field hint / validation message ------------------------------- */
.xn-hint {
	margin-block-start: var(--xn-space-1);
	font-size: var(--xn-text-small);
	color: var(--xn-error);
}

.xn-hint.xn-muted {
	color: var(--xn-text-muted);
}

.xn-input.is-invalid {
	border-color: var(--xn-error);
}

/* Table ---------------------------------------------------------------- */
.xn-tablewrap {
	overflow-x: auto;
	/* Table scrolls instead of stretching the card on a phone. */
	-webkit-overflow-scrolling: touch;
}

.xn-table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--xn-text-small);
}

.xn-table th,
.xn-table td {
	padding: var(--xn-space-2) var(--xn-space-3);
	text-align: start;
	border-block-end: 1px solid var(--xn-border);
	white-space: nowrap;
}

.xn-table thead th {
	color: var(--xn-text-muted);
	font-weight: var(--xn-weight-title);
}

.xn-table tbody tr:last-child th,
.xn-table tbody tr:last-child td {
	border-block-end: 0;
}

/* Grant / deny marks read without relying on colour alone. */
.xn-mark {
	font-weight: var(--xn-weight-title);
}

.xn-mark--yes {
	color: var(--xn-success);
}

.xn-mark--no {
	color: var(--xn-text-muted);
}

/* Icons ---------------------------------------------------------------- */
.xn-icon {
	display: block;
	width: 20px;
	height: 20px;
	flex: none;
}

/* Only the glyph matching the active mode is drawn, decided by CSS so the
   correct one is already correct on first paint. */
[data-theme="dark"] .xn-icon--sun,
[data-theme="light"] .xn-icon--moon {
	display: none;
}

/* Square icon-only control -------------------------------------------- */
.xn-iconbtn--square {
	width: 40px;
	min-height: 40px;
	padding: 0;
	justify-content: center;
	color: var(--xn-text-muted);
}

.xn-iconbtn--square:hover {
	color: var(--xn-accent);
	border-color: var(--xn-primary-light);
}

/* Official logo -------------------------------------------------------- */
.xn-logo {
	display: block;
	/* Width arrives as a custom property, so a media query can override it
	   without fighting an inline style. */
	width: var(--xn-logo-w, 240px);
	height: auto;
	max-width: 100%;
	/* The artwork is transparent, so it sits directly on the surface: no
	   plate, no border, no shadow, nothing added to the mark. */
}

/* Only the variant matching the active surface is drawn. */
[data-theme="dark"] .xn-logo--on-light,
[data-theme="light"] .xn-logo--on-dark {
	display: none;
}

/* Data table rows ------------------------------------------------------ */
.xn-table--data tbody tr:hover {
	background: var(--xn-surface-secondary);
}

.xn-table--data td {
	vertical-align: middle;
}

.xn-table__actions {
	display: flex;
	gap: var(--xn-space-2);
	justify-content: flex-end;
}

/* Small button for row actions. */
.xn-btn--sm {
	min-height: 34px;
	padding-inline: var(--xn-space-3);
	font-size: var(--xn-text-small);
}

/* Status pills --------------------------------------------------------- */
.xn-badge--on {
	color: var(--xn-success);
	background: color-mix(in srgb, var(--xn-success) 14%, transparent);
	border: 1px solid color-mix(in srgb, var(--xn-success) 40%, transparent);
}

.xn-badge--off {
	color: var(--xn-text-muted);
	background: var(--xn-surface-secondary);
	border: 1px solid var(--xn-border);
}

/* Modal ---------------------------------------------------------------- */
.xn-modal {
	position: fixed;
	inset: 0;
	z-index: 60;
	display: grid;
	place-items: center;
	padding: var(--xn-space-4);
}

.xn-modal[hidden] {
	display: none;
}

.xn-modal__backdrop {
	position: absolute;
	inset: 0;
	background: rgba(5, 5, 5, 0.62);
}

.xn-modal__panel {
	position: relative;
	width: 100%;
	max-width: 520px;
	max-height: 88vh;
	overflow-y: auto;
	padding: var(--xn-space-5);
	background: var(--xn-surface);
	border: 1px solid var(--xn-border);
	border-radius: var(--xn-radius-lg);
	box-shadow: var(--xn-shadow);
}

.xn-modal__panel--wide {
	max-width: 720px;
}

.xn-modal__head .xn-card__title {
	/* A panel heading sits one step above a card heading in the type scale. */
	font-size: var(--xn-text-section);
	margin-block-end: 0;
}

.xn-modal__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--xn-space-3);
	margin-block-end: var(--xn-space-2);
}

/* Form layouts --------------------------------------------------------- */
.xn-form--grid {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

.xn-form--inline {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: var(--xn-space-3);
	margin-block: var(--xn-space-4);
}

.xn-form--inline .xn-field {
	flex: 1 1 220px;
}

.xn-field--full {
	grid-column: 1 / -1;
}

.xn-form__actions {
	display: flex;
	gap: var(--xn-space-3);
}

select.xn-input {
	appearance: none;
	padding-inline-end: var(--xn-space-5);
}

@media (max-width: 640px) {
	.xn-form--grid {
		grid-template-columns: 1fr;
	}
}

/* Toast ---------------------------------------------------------------- */
.xn-toasts {
	position: fixed;
	inset-block-end: var(--xn-space-5);
	inset-inline-start: var(--xn-space-5);
	z-index: 80;
	display: grid;
	gap: var(--xn-space-2);
}

.xn-toast {
	padding: var(--xn-space-3) var(--xn-space-4);
	background: var(--xn-surface);
	border: 1px solid var(--xn-border);
	border-radius: var(--xn-radius-md);
	box-shadow: var(--xn-shadow);
	font-size: var(--xn-text-small);
	font-weight: var(--xn-weight-title);
}

.xn-toast--success {
	border-color: color-mix(in srgb, var(--xn-success) 45%, transparent);
	color: var(--xn-success);
}

.xn-toast--error {
	border-color: color-mix(in srgb, var(--xn-error) 45%, transparent);
	color: var(--xn-error);
}

/* Avatar --------------------------------------------------------------- */
.xn-avatar {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	flex: none;
	border-radius: 50%;
	background: var(--xn-surface-secondary);
	border: 1px solid var(--xn-border);
	color: var(--xn-text-muted);
	overflow: hidden;
}

.xn-avatar--lg {
	width: 84px;
	height: 84px;
}

.xn-avatar--lg .xn-icon {
	width: 40px;
	height: 40px;
}

.xn-avatar__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.xn-avatar__img[hidden] {
	display: none;
}

.xn-avatar-row {
	display: flex;
	align-items: center;
	gap: var(--xn-space-4);
	margin-block-end: var(--xn-space-4);
}

.xn-avatar-row__actions {
	display: grid;
	gap: var(--xn-space-2);
	justify-items: start;
}

/* A file input styled through its label keeps the native picker and its
   keyboard behaviour instead of reimplementing either. */
label.xn-btn {
	cursor: pointer;
}

.xn-input[readonly] {
	opacity: 0.75;
	cursor: not-allowed;
}

/* Denial screen -------------------------------------------------------- */
.xn-denied {
	max-width: 560px;
	text-align: start;
}

.xn-denied__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 52px;
	height: 52px;
	margin-block-end: var(--xn-space-4);
	border-radius: var(--xn-radius-md);
	background: color-mix(in srgb, var(--xn-warning) 14%, transparent);
	color: var(--xn-warning);
}

.xn-denied__icon .xn-icon {
	width: 26px;
	height: 26px;
}

.xn-denied .xn-btn {
	margin-block-start: var(--xn-space-5);
}

/* Account layout ------------------------------------------------------- */
.xn-account {
	display: grid;
	gap: var(--xn-space-4);
	grid-column: 1 / -1;
	grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
	align-items: start;
}

/* Live board ----------------------------------------------------------- */
.xn-live-bar {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--xn-space-3);
	margin-block-end: var(--xn-space-4);
}

.xn-live-bar__stamp {
	margin-inline-start: auto;
}

.xn-input--sm {
	min-height: 38px;
	font-size: var(--xn-text-small);
	width: auto;
	min-width: 200px;
}

.xn-stat {
	display: grid;
	gap: var(--xn-space-2);
}

.xn-stat__label {
	color: var(--xn-text-muted);
	font-size: var(--xn-text-small);
}

.xn-stat__value {
	font-size: var(--xn-text-page);
	font-weight: var(--xn-weight-display);
	line-height: 1.1;
}

.xn-pending-list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--xn-space-2);
	margin-block-start: var(--xn-space-4);
}

/* Filter bar ----------------------------------------------------------- */
.xn-filters {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: var(--xn-space-3);
	margin-block-end: var(--xn-space-5);
	padding-block-end: var(--xn-space-4);
	border-block-end: 1px solid var(--xn-border);
}

.xn-filters .xn-field {
	flex: 1 1 170px;
	min-width: 0;
	gap: var(--xn-space-1);
}

.xn-filters__actions {
	display: flex;
	gap: var(--xn-space-2);
	margin-inline-start: auto;
}

.xn-textarea {
	min-height: 96px;
	padding-block: var(--xn-space-3);
	resize: vertical;
	line-height: 1.7;
}

select[multiple].xn-input {
	min-height: 120px;
	padding-block: var(--xn-space-2);
}

/* Pagination ----------------------------------------------------------- */
.xn-pager {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--xn-space-4);
	margin-block-start: var(--xn-space-4);
}

.xn-pager button[disabled] {
	opacity: 0.45;
	cursor: not-allowed;
}

/* Status pills for the work order states ------------------------------- */
.xn-badge--new {
	color: var(--xn-info);
	background: color-mix(in srgb, var(--xn-info) 14%, transparent);
	border: 1px solid color-mix(in srgb, var(--xn-info) 40%, transparent);
}

.xn-badge--in_progress {
	color: var(--xn-warning);
	background: color-mix(in srgb, var(--xn-warning) 14%, transparent);
	border: 1px solid color-mix(in srgb, var(--xn-warning) 40%, transparent);
}

.xn-badge--completed {
	color: var(--xn-success);
	background: color-mix(in srgb, var(--xn-success) 14%, transparent);
	border: 1px solid color-mix(in srgb, var(--xn-success) 40%, transparent);
}

.xn-badge--cancelled {
	color: var(--xn-error);
	background: color-mix(in srgb, var(--xn-error) 12%, transparent);
	border: 1px solid color-mix(in srgb, var(--xn-error) 40%, transparent);
}

@media (max-width: 640px) {
	/* Filters stack rather than squeeze; the actions keep full width so the
	   apply button is never clipped on a phone. */
	.xn-filters .xn-field {
		flex: 1 1 100%;
	}

	.xn-filters__actions {
		margin-inline-start: 0;
		width: 100%;
	}

	.xn-filters__actions .xn-btn {
		flex: 1;
	}
}

/* Customer profile ----------------------------------------------------- */
.xn-backlink {
	display: inline-block;
	margin-block-end: var(--xn-space-4);
}

.xn-profile-head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--xn-space-4);
}

.xn-profile-head__meta {
	display: flex;
	flex-wrap: wrap;
	gap: var(--xn-space-2) var(--xn-space-4);
	margin-block-start: var(--xn-space-2);
	color: var(--xn-text-muted);
	font-size: var(--xn-text-small);
}

.xn-profile-head__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--xn-space-2);
}

.xn-card__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--xn-space-3);
	margin-block-end: var(--xn-space-4);
}

.xn-card__head .xn-card__title {
	margin-block-end: 0;
}

.xn-btn[disabled] {
	opacity: 0.5;
	cursor: not-allowed;
}

/*
 * Long names, emails and addresses wrap instead of forcing the table or the
 * definition list wider than the viewport.
 */
.xn-deflist dd,
.xn-profile-head .xn-title {
	overflow-wrap: anywhere;
}

.xn-table--data td {
	overflow-wrap: anywhere;
}

/* Server-side search picker --------------------------------------------- */
.xn-results {
	max-height: 220px;
	margin-block-start: var(--xn-space-2);
	overflow-y: auto;
	border: 1px solid var(--xn-border);
	border-radius: var(--xn-radius-md);
	background: var(--xn-surface-secondary);
}

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

.xn-results__item {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--xn-space-3);
	width: 100%;
	min-height: 44px;
	padding: var(--xn-space-2) var(--xn-space-3);
	background: transparent;
	color: var(--xn-text);
	border: 0;
	border-block-end: 1px solid var(--xn-border);
	font-family: inherit;
	font-size: var(--xn-text-small);
	text-align: start;
	cursor: pointer;
}

.xn-results__item:last-child {
	border-block-end: 0;
}

.xn-results__item:hover {
	background: var(--xn-surface);
	color: var(--xn-primary-light);
}

/* The chosen record, locked until it is cleared. */
.xn-picked {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--xn-space-3);
	min-height: 46px;
	padding: var(--xn-space-2) var(--xn-space-3);
	background: var(--xn-surface-secondary);
	border: 1px solid var(--xn-border);
	border-radius: var(--xn-radius-md);
	font-weight: var(--xn-weight-title);
	font-size: var(--xn-text-small);
}

.xn-picked[hidden] {
	display: none;
}

/* Form sections -------------------------------------------------------- */
.xn-fieldset {
	margin: 0;
	padding: var(--xn-space-4);
	border: 1px solid var(--xn-border);
	border-radius: var(--xn-radius-md);
	background: color-mix(in srgb, var(--xn-surface-secondary) 55%, transparent);
	min-width: 0;
}

.xn-fieldset__legend {
	padding-inline: var(--xn-space-2);
	color: var(--xn-text);
	font-weight: var(--xn-weight-title);
	font-size: var(--xn-text-small);
}

/* A legend that carries the enable switch keeps the control on the same
   line as the section name. */
.xn-fieldset__legend .xn-check {
	margin: 0;
}

/* Dimmed rather than hidden when switched off, so the operator can see what
   they are declining. */
.xn-fieldset [data-xn-vehicle-fields][hidden] {
	display: none;
}

/* Master-data catalogue ------------------------------------------------ */
.xn-catalog {
	display: grid;
	gap: var(--xn-space-5);
	grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
	align-items: start;
	margin-block-start: var(--xn-space-4);
}

.xn-catalog__col {
	min-width: 0;
}

/* Operations queue ----------------------------------------------------- */
.xn-opgrid {
	display: grid;
	gap: var(--xn-space-4);
	grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}

.xn-opcard {
	display: grid;
	gap: var(--xn-space-3);
	padding: var(--xn-space-4);
	background: var(--xn-surface-secondary);
	border: 1px solid var(--xn-border);
	border-radius: var(--xn-radius-md);
	min-width: 0;
}

.xn-opcard__head {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--xn-space-3);
}

.xn-opcard__vehicle {
	font-weight: var(--xn-weight-display);
	font-size: var(--xn-text-card);
	overflow-wrap: anywhere;
}

.xn-opcard__meta {
	display: grid;
	gap: var(--xn-space-1);
	color: var(--xn-text-muted);
	font-size: var(--xn-text-small);
}

.xn-opcard__services {
	display: flex;
	flex-wrap: wrap;
	gap: var(--xn-space-2);
}

.xn-opcard__foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--xn-space-3);
	padding-block-start: var(--xn-space-3);
	border-block-start: 1px solid var(--xn-border);
}

/*
 * The stage is the one thing that must read across a workshop, so it gets
 * more weight than a normal badge — using the existing accent, not a new
 * colour system.
 */
.xn-stage-pill {
	display: inline-flex;
	align-items: center;
	padding: var(--xn-space-2) var(--xn-space-3);
	border-radius: var(--xn-radius-pill);
	background: color-mix(in srgb, var(--xn-primary) 22%, transparent);
	border: 1px solid color-mix(in srgb, var(--xn-primary) 45%, transparent);
	color: var(--xn-text);
	font-weight: var(--xn-weight-title);
	font-size: var(--xn-text-small);
	white-space: nowrap;
}

.xn-stage-pill--ready {
	background: color-mix(in srgb, var(--xn-success) 18%, transparent);
	border-color: color-mix(in srgb, var(--xn-success) 45%, transparent);
	color: var(--xn-success);
}

.xn-stage-pill--closed {
	background: var(--xn-surface);
	border-color: var(--xn-border);
	color: var(--xn-text-muted);
}

.xn-stage-buttons {
	display: flex;
	flex-wrap: wrap;
	gap: var(--xn-space-2);
}

/* Money and ledgers ----------------------------------------------------- */
.xn-deflist--money dd {
	font-variant-numeric: tabular-nums;
}

.xn-ledger,
.xn-timeline {
	display: grid;
	gap: var(--xn-space-2);
	margin-block-start: var(--xn-space-3);
	padding: 0;
	list-style: none;
}

.xn-ledger li,
.xn-timeline li {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--xn-space-2) var(--xn-space-3);
	padding: var(--xn-space-2) var(--xn-space-3);
	background: var(--xn-surface-secondary);
	border-radius: var(--xn-radius-sm);
	font-size: var(--xn-text-small);
}

.xn-timeline__time {
	color: var(--xn-text-muted);
	font-family: var(--xn-font-mono);
}

@media (max-width: 640px) {
	.xn-opcard__head {
		flex-direction: column;
	}
}

/* Work order service lines --------------------------------------------- */
.xn-lines {
	display: grid;
	gap: var(--xn-space-2);
}

.xn-line {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--xn-space-3);
	padding: var(--xn-space-3);
	background: var(--xn-surface-secondary);
	border: 1px solid var(--xn-border);
	border-radius: var(--xn-radius-sm);
}

.xn-line__name {
	flex: 1 1 160px;
	font-weight: var(--xn-weight-title);
	min-width: 0;
	overflow-wrap: anywhere;
}

.xn-line__field {
	display: flex;
	align-items: center;
	gap: var(--xn-space-2);
	font-size: var(--xn-text-small);
	color: var(--xn-text-muted);
}

.xn-line__field .xn-input {
	width: 110px;
	min-height: 38px;
}

.xn-lines__add {
	display: flex;
	flex-wrap: wrap;
	gap: var(--xn-space-2);
}

.xn-totals {
	padding: var(--xn-space-3);
	background: var(--xn-surface-secondary);
	border-radius: var(--xn-radius-sm);
}

@media (max-width: 640px) {
	.xn-line__field .xn-input {
		width: 100%;
	}

	.xn-line__field {
		flex: 1 1 100%;
	}
}

/* Paired control and its unit selector ---------------------------------- */
.xn-inputgroup {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--xn-space-2);
	min-width: 0;
}

.xn-inputgroup > .xn-input {
	flex: 1 1 120px;
	min-width: 0;
}

.xn-inputgroup > select.xn-input {
	flex: 0 0 auto;
	width: auto;
}

@media (max-width: 640px) {
	.xn-inputgroup > .xn-input,
	.xn-inputgroup > select.xn-input {
		flex: 1 1 100%;
		width: 100%;
	}
}

/* Server-decided values, shown rather than chosen ----------------------- */
.xn-classification,
.xn-readback {
	display: inline-flex;
	align-items: center;
	min-height: 46px;
	margin: 0;
	padding: var(--xn-space-2) var(--xn-space-3);
	background: var(--xn-surface-secondary);
	border: 1px solid var(--xn-border);
	border-radius: var(--xn-radius-md);
	color: var(--xn-text);
	font-weight: var(--xn-weight-title);
	font-size: var(--xn-text-small);
}

/* A returning customer is worth noticing at a glance. */
.xn-classification--returning {
	background: color-mix(in srgb, var(--xn-primary) 18%, transparent);
	border-color: color-mix(in srgb, var(--xn-primary) 45%, transparent);
}

.xn-readback--unassigned {
	color: var(--xn-text-muted);
	font-weight: var(--xn-weight-body);
}

/* Warranty ------------------------------------------------------------- */

/* A second line under the service name, not a second column. */
.xn-line-note {
	display: block;
	margin-block-start: 2px;
}

/*
 * The warranty inputs sit together under their own toggle. Full width so the
 * number and its unit never wrap awkwardly on a narrow screen.
 */
.xn-field--warranty {
	flex: 1 1 100%;
	min-width: 0;
}

.xn-field--warranty .xn-inputgroup > .xn-input {
	min-width: 0;
}

/* Service workflow stages ---------------------------------------------- */

/* Wraps rather than scrolls, so a long stage list never widens the page. */
.xn-stagepick {
	display: flex;
	flex-wrap: wrap;
	gap: var(--xn-space-2);
	min-width: 0;
}

.xn-stagepick .xn-check {
	flex: 0 1 auto;
	padding: var(--xn-space-2) var(--xn-space-3);
	background: var(--xn-surface-secondary);
	border: 1px solid var(--xn-border);
	border-radius: var(--xn-radius-sm);
	min-height: 40px;
}

/* Disabled controls ----------------------------------------------------- */

/*
 * A blocked step should read as "not yet", not as broken. Muted and flat
 * rather than faded to near-invisible, and unmistakably not clickable.
 */
.xn-btn:disabled,
.xn-btn[disabled] {
	background: var(--xn-surface-secondary);
	border-color: var(--xn-border);
	color: var(--xn-text-muted);
	cursor: not-allowed;
	box-shadow: none;
	opacity: 1;
}

.xn-btn:disabled:hover,
.xn-btn[disabled]:hover {
	background: var(--xn-surface-secondary);
	color: var(--xn-text-muted);
}

/* WhatsApp connection --------------------------------------------------- */

.xn-statusline {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--xn-space-3);
}

/*
 * The self-test result. Pass and fail are marked with a leading glyph as well
 * as a colour, so the outcome is readable to someone who cannot distinguish
 * the two colours.
 */
.xn-checklist {
	display: grid;
	gap: var(--xn-space-2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.xn-checklist__item {
	padding: var(--xn-space-2) var(--xn-space-3);
	border: 1px solid var(--xn-border);
	border-radius: var(--xn-radius-sm);
	background: var(--xn-surface-secondary);
	font-size: var(--xn-text-small);
	color: var(--xn-text-muted);
}

.xn-checklist__item.is-pass {
	border-color: color-mix(in srgb, var(--xn-success) 45%, var(--xn-border));
	color: var(--xn-text);
}

.xn-checklist__item.is-fail {
	border-color: color-mix(in srgb, var(--xn-error) 45%, var(--xn-border));
	color: var(--xn-text);
}

/* Tabs ------------------------------------------------------------------ */

/*
 * One page divided into sections rather than more sidebar entries. Scrolls
 * sideways on a narrow screen instead of wrapping into an uneven block.
 */
.xn-tabs {
	display: flex;
	gap: var(--xn-space-1);
	margin-block-end: var(--xn-space-4);
	padding-block-end: var(--xn-space-2);
	border-block-end: 1px solid var(--xn-border);
	overflow-x: auto;
	scrollbar-width: thin;
}

.xn-tab {
	flex: none;
	padding: var(--xn-space-2) var(--xn-space-4);
	border-radius: var(--xn-radius-sm);
	background: transparent;
	color: var(--xn-text-muted);
	font-weight: var(--xn-weight-title);
	font-size: var(--xn-text-small);
	white-space: nowrap;
	cursor: pointer;
}

.xn-tab:hover {
	background: var(--xn-surface-secondary);
	color: var(--xn-text);
}

.xn-tab.is-active {
	background: var(--xn-primary);
	color: #fff;
}

/* Logout ---------------------------------------------------------------- */

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

.xn-logout__icon {
	display: inline-flex;
}

/*
 * Icon only on a phone. The markup already carried both an icon and a label
 * and an accessible name on the button itself, but nothing ever hid the
 * label — so the widest control in the bar was the one nobody presses.
 * Hiding the text keeps the same button, the same action, and the same name
 * for a screen reader.
 */
@media (max-width: 900px) {
	.xn-logout__label {
		display: none;
	}

	.xn-logout {
		padding-inline: var(--xn-space-3);
	}
}
