/**
 * Main SCSS File
 *
 * Main stylesheet for the admin app
 *
 * @package Everyone_Accessibility_Suite
 */

@import 'variables';

$content-max-width: 1200px;
@import 'customizer.css';

/**
 * One control treatment for the whole plugin UI.
 *
 * WordPress' own `.button`, the dashboard's card links and the date picker's
 * chips were each carrying their own size, radius and shape, so a native WP
 * button sat next to a pill and a square link. Everything button-shaped runs
 * through this mixin instead - only the colour differs between the default
 * and primary variants.
 */
@mixin evas-control($size: 'default') {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	// Borders inside the box, so min-height is the height that actually
	// renders and controls of the same size line up exactly.
	box-sizing: border-box;
	border-radius: $border-radius-lg;
	font-weight: 500;
	line-height: 1;
	text-decoration: none;
	white-space: nowrap;
	cursor: pointer;

	@if $size == 'small' {
		min-height: 28px;
		padding: 0 10px;
		font-size: $font-size-xs;
	} @else {
		min-height: 32px;
		padding: 0 14px;
		font-size: $font-size-sm;
	}

	.dashicons {
		font-size: 15px;
		width: 15px;
		height: 15px;
	}
}

/** Outlined default variant - the plugin's standard button. */
@mixin evas-control-default {
	border: 1px solid $border-color;
	background: $bg-primary;
	color: $primary-color;

	&:hover:not(:disabled) {
		border-color: $primary-color;
		background: $bg-tertiary;
		color: $primary-hover;
	}
}

/** Filled variant for the single main action in a group. */
@mixin evas-control-primary {
	border: 1px solid $primary-color;
	background: $primary-color;
	color: #fff;

	&:hover:not(:disabled) {
		border-color: $primary-hover;
		background: $primary-hover;
		color: #fff;
	}
}

/* Layout */
.evas-admin-layout {
	font-family: $font-family;
	font-size: $font-size-base;
	color: $text-primary;
	background: $app-bg;
	min-height: 100vh;

	// Every control inside the plugin's own screens shares one treatment.
	// Scoped to this wrapper - the surrounding wp-admin chrome keeps its
	// native styling.
	.button,
	.button-secondary {
		@include evas-control;
		@include evas-control-default;
	}

	.button-primary {
		@include evas-control;
		@include evas-control-primary;
	}

	.button-small,
	.button.button-small {
		@include evas-control('small');
	}

	.button:disabled,
	.button[disabled] {
		opacity: 0.6;
		cursor: default;
	}

	select,
	textarea,
	input[type='text'],
	input[type='search'],
	input[type='number'],
	input[type='email'],
	input[type='url'],
	input[type='date'],
	input[type='password'] {
		border-radius: $border-radius-lg;
	}
}

.evas-admin-content {
	display: flex;
	min-height: calc(100vh - 120px);
}

.evas-admin-main {
	flex: 1;
	padding: $spacing-lg;
}

/* Header */
.evas-admin-header {
	background: $bg-primary;
	border-bottom: 1px solid $border-color;
	padding: $spacing-md $spacing-lg;

	&__content {
		width: 100%;
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: $spacing-md;
		flex-wrap: wrap;
	}

	&__branding {
		display: flex;
		align-items: center;
		gap: $spacing-sm;

		.dashicons {
			font-size: 32px;
			width: 32px;
			height: 32px;
			color: $primary-color;
		}
	}

	&__title {
		margin: 0;
		font-size: $font-size-xl;
		font-weight: 600;
	}

	&__version {
		color: $text-secondary;
		font-size: $font-size-sm;
		border: 1px solid $border-light;
		border-radius: 999px;
		padding: 1px 8px;
	}

	&__actions {
		display: flex;
		align-items: center;
		gap: $spacing-md;
	}

	&__link {
		display: inline-flex;
		align-items: center;
		gap: 6px;
		color: $text-secondary;
		text-decoration: none;
		font-size: $font-size-sm;

		.dashicons {
			font-size: 16px;
			width: 16px;
			height: 16px;
		}

		&:hover {
			color: $primary-color;
		}
	}

	&__button {
		@include evas-control;
		@include evas-control-primary;
	}
}

/* Navigation */
.evas-admin-navigation {
	width: 280px;
	background: $bg-primary;
	border-right: 1px solid $border-color;
	padding: $spacing-md 0;

	&__menu {
		list-style: none;
		margin: 0;
		padding: 0;
	}

	&__item {
		margin: 0;
	}

	&__link {
		display: flex;
		align-items: center;
		gap: $spacing-sm;
		padding: $spacing-md $spacing-lg;
		color: $text-primary;
		text-decoration: none;
		transition: background $transition-fast;
		outline: none;

		&:hover {
			background: $bg-tertiary;
		}

		&:focus,
		&:active {
			outline: none;
			box-shadow: none;
		}

		&.is-active {
			background: $bg-secondary;
			color: $primary-color;
			font-weight: 600;
			border-left: 3px solid $primary-color;
			padding-left: calc($spacing-lg - 3px);
		}

		.dashicons {
			font-size: 20px;
			width: 20px;
			height: 20px;
		}
	}

	&__label {
		flex: 1;
	}
}

/* Footer */
.evas-admin-footer {
	background: $bg-primary;
	border-top: 1px solid $border-color;
	padding: $spacing-md $spacing-lg;
	text-align: center;
	color: $text-secondary;
	font-size: $font-size-sm;

	a {
		color: $primary-color;
		text-decoration: none;

		&:hover {
			text-decoration: underline;
		}
	}
}

/* Pages */
/* Page shells - every tab gets the same content width */
.evas-dashboard-page,
.evas-components-page,
.evas-settings-page,
.evas-accessibility-page,
.evas-customizer-page,
.evas-usage-analytics-page,
.evas-module-settings-page {
	max-width: $content-max-width;
}

.evas-page-header {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: $spacing-md;
	flex-wrap: wrap;
	margin-bottom: $spacing-xl;

	h2 {
		margin: 0 0 $spacing-sm;
		font-size: 24px;
		font-weight: 600;
	}

	p {
		margin: 0;
		color: $text-secondary;
	}

	&__actions {
		flex-shrink: 0;
	}
}

/* Dashboard */
.evas-dashboard-page {
	max-width: 1320px;
}

/* Shared card shell */
.evas-card {
	background: $bg-primary;
	border: 1px solid $card-border;
	border-radius: $card-radius;
	box-shadow: $card-shadow;
	overflow: hidden;

	// A column so the body below can claim whatever height the row gives the
	// card beyond its own content. Without it the shell stretches but the
	// inside stays a block flow, and nothing can be pinned to the bottom.
	display: flex;
	flex-direction: column;

	// Plain card headers sit directly on the body with no rule between them;
	// only the accent (blue) header reads as a separate band.
	&__header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: $spacing-sm;
		padding: $spacing-lg $spacing-lg $spacing-sm;

		h3 {
			display: flex;
			align-items: center;
			gap: $spacing-sm;
			margin: 0;
			font-size: $font-size-lg;
			font-weight: 600;

			.dashicons {
				color: $primary-color;
			}
		}

		&--accent {
			background: $primary-color;
			padding: $spacing-md $spacing-lg;

			h3 {
				font-size: $font-size-base;
			}

			h3,
			h3 .dashicons {
				color: #fff;
			}
		}
	}

	&__header-link {
		@include evas-control('small');
		@include evas-control-default;
	}

	&__header-select {
		border: 1px solid $card-border;
		background: $bg-primary;
		color: $text-primary;
		font-size: $font-size-sm;
		border-radius: $border-radius-lg;
		padding: 5px 10px;
		min-height: 0;
		line-height: 1.4;
		box-shadow: none;
	}

	&__body {
		padding: $spacing-sm $spacing-lg $spacing-lg;

		// Takes the slack when this card is shorter than its neighbour, so the
		// spare height ends up as space under the content rather than leaving
		// the card's own box short. Layout inside stays block flow.
		flex: 1;
	}

	&__empty {
		margin: 0;
		padding: $spacing-lg 0;
		text-align: center;
		color: $text-secondary;
		font-size: $font-size-sm;
	}

	&__error {
		text-align: center;
		color: $text-secondary;

		p {
			color: $error-color;
			margin: 0 0 $spacing-sm;
		}
	}
}

/* KPI row */
.evas-kpi-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: $grid-gap;
	margin-bottom: $grid-gap;

	@media (max-width: 1100px) {
		grid-template-columns: repeat(2, 1fr);
	}

	@media (max-width: 600px) {
		grid-template-columns: 1fr;
	}
}

.evas-kpi-card {
	background: $bg-primary;
	border: 1px solid $card-border;
	border-radius: $card-radius;
	box-shadow: $card-shadow;
	padding: $spacing-lg;
	display: flex;
	flex-direction: column;
	gap: $spacing-xs;

	&__head {
		display: flex;
		align-items: center;
		gap: $spacing-sm;

		.dashicons {
			color: $primary-color;

			&.is-success {
				color: $success-color;
			}
		}
	}

	&__label {
		font-size: $font-size-base;
		font-weight: 600;
		color: $text-primary;
	}

	&__value-row {
		display: flex;
		align-items: baseline;
		gap: $spacing-sm;
		flex-wrap: wrap;
	}

	&__value {
		font-size: 28px;
		font-weight: 700;
		line-height: 1.2;

		&.is-active {
			color: $success-color;
		}

		&.is-inactive {
			color: $text-secondary;
		}
	}

	&__hint {
		font-size: $font-size-xs;
		color: $text-tertiary;
	}

	&__foot {
		display: flex;
		gap: $spacing-sm;
		margin-top: auto;
		padding-top: $spacing-md;
		flex-wrap: wrap;
	}
}

.evas-delta-badge {
	font-size: $font-size-xs;
	font-weight: 600;
	padding: 2px 8px;
	border-radius: 999px;
	white-space: nowrap;

	&.is-up {
		color: $success-color;
		background: rgba($success-color, 0.12);
	}

	// Deliberately neutral rather than red: a drop is not automatically bad
	// (shorter average time, for instance), so it reads as information.
	&.is-down {
		color: $text-secondary;
		background: $bg-tertiary;
	}
}

/* Main / secondary grids */
// No align-items here on purpose: the grid default, stretch, is what makes
// both cards in a row end on the same line. Pinning them to `start` sized each
// card to its own content and left the row with a ragged bottom edge.
.evas-dashboard-main {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: $grid-gap;
	margin-bottom: $grid-gap;

	@media (max-width: 1100px) {
		grid-template-columns: 1fr;
	}
}

.evas-dashboard-secondary {
	display: grid;
	grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
	gap: $grid-gap;
	margin-bottom: $grid-gap;

	@media (max-width: 1100px) {
		grid-template-columns: 1fr;
	}
}

/* Usage Overview */

// The chart body sits directly under the accent header, which supplies its
// own padding - without this the legend, canvas and stat tiles would run
// flush to the card's edges.
.evas-overview-card__body {
	padding: $spacing-lg;

	// Same reason as .evas-card__body - this card swaps in its own body class.
	flex: 1;
}

.evas-overview-legend {
	display: flex;
	gap: $spacing-lg;
	margin-bottom: $spacing-md;
	font-size: 12px;
}

.evas-legend-item {
	display: flex;
	align-items: center;
	gap: 6px;
	color: $text-secondary;
}

.evas-legend-dot {
	width: 10px;
	height: 10px;
	border-radius: 3px;
	display: inline-block;

	&--open {
		background: rgba(37, 99, 235, 0.9);
	}

	&--loaded {
		background: rgba(148, 163, 184, 0.7);
	}
}

// Room below the chart so the stat tiles read as a separate band instead of
// crowding the bars. Horizontal breathing room is handled inside the canvas
// (see renderChart's `padding`) - CSS padding here would inflate
// getBoundingClientRect() and stretch the backing store.
.evas-overview-canvas {
	width: 100%;
	height: 200px;
	display: block;
	margin-bottom: $spacing-lg;
}

.evas-overview-stats {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: $spacing-sm;
	margin-top: $spacing-md;

	@media (max-width: 600px) {
		grid-template-columns: repeat(2, 1fr);
	}
}

.evas-overview-stat {
	border: 1px solid $card-border;
	border-radius: $border-radius-lg;
	padding: $spacing-md 6px;
	text-align: center;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4px;

	&__label {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 4px;
		font-size: $font-size-xs;
		line-height: 1.3;
		color: $text-secondary;

		.dashicons {
			flex-shrink: 0;
			font-size: 13px;
			width: 13px;
			height: 13px;
		}
	}

	&__value {
		font-size: 20px;
		font-weight: 700;
		line-height: 1.1;
	}

	// The metric the card is really about - panel opens - is tinted so it
	// reads first among the four.
	&.is-highlight {
		border-color: rgba($success-color, 0.35);
		background: rgba($success-color, 0.07);

		.evas-overview-stat__label,
		.evas-overview-stat__label .dashicons {
			color: darken($success-color, 5%);
		}
	}
}

/* Top Used Modes */
.evas-mode-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: $spacing-md;
}

.evas-mode-row {
	display: grid;
	grid-template-columns: 32px minmax(0, auto) minmax(60px, 1fr) 22px 42px;
	align-items: center;
	gap: 10px;
	font-size: $font-size-sm;

	&__icon {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 32px;
		height: 32px;
		border-radius: $border-radius-lg;
		background: rgba($primary-color, 0.1);
		color: $primary-color;

		img {
			width: 17px;
			height: 17px;
			object-fit: contain;
		}

		.dashicons {
			font-size: 17px;
			width: 17px;
			height: 17px;
		}
	}

	&__label {
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
		color: $text-primary;
	}

	&__track {
		height: 8px;
		background: $bg-tertiary;
		border-radius: 999px;
		overflow: hidden;
	}

	&__fill {
		display: block;
		height: 100%;
		background: linear-gradient(90deg, #2563eb 0%, #3b82f6 100%);
		border-radius: 999px;
		min-width: 2px;
	}

	&__value {
		font-weight: 700;
		text-align: right;
		white-space: nowrap;
	}

	&__percent {
		color: $text-tertiary;
		text-align: right;
		white-space: nowrap;
	}
}

/* Accessibility Analyzer card */
.evas-analyzer-card {
	// A column so the footer below can be pushed to the card's bottom edge.
	.evas-card__body {
		display: flex;
		flex-direction: column;
	}

	&__score {
		display: flex;
		align-items: center;
		gap: $spacing-md;

		// Carries the minimum gap to the footer's rule, which used to come from
		// the footer's own margin-top - that is now `auto` and collapses to
		// nothing once the card has no spare height.
		margin-bottom: $spacing-lg;

		@media (max-width: 480px) {
			flex-direction: column;
			align-items: flex-start;
		}
	}

	&__issues {
		flex: 1;
		min-width: 0;
		display: flex;
		flex-direction: column;
		gap: $spacing-md;
	}

	// Timestamp and actions share one row above the card's bottom edge.
	&__footer {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: $spacing-md;
		flex-wrap: wrap;
		// `auto`, so that when this card is the shorter one in its row the
		// spare height goes above the footer instead of below it - otherwise
		// its rule would sit stranded in the middle of the card.
		margin-top: auto;
		padding-top: $spacing-md;
		border-top: 1px solid $card-border;
	}

	&__meta {
		font-size: $font-size-sm;
		color: $text-secondary;
	}

	&__actions {
		display: flex;
		gap: $spacing-sm;
		margin-left: auto;
	}
}

.evas-score-ring {
	--score: 0;
	// Parameterised so the same ring can render small inside an analyzer
	// table cell. The punch-out and type scale below are derived from it,
	// otherwise a shrunken ring keeps a 9px hole and 26px digits.
	--size: 96px;
	// The passed portion is always green; only the REMAINDER carries the
	// severity colour. Colouring the whole ring by severity painted a
	// 29-of-30 page solid red, which read as "almost everything is broken"
	// when it was the opposite.
	--ring-color: #{$success-light};
	--ring-rest: #{$bg-secondary};

	position: relative;
	flex-shrink: 0;
	width: var(--size);
	height: var(--size);
	border-radius: 50%;
	background: conic-gradient(
		var(--ring-color) 0deg,
		var(--ring-color) calc(var(--score) * 3.6deg),
		var(--ring-rest) calc(var(--score) * 3.6deg),
		var(--ring-rest) 360deg
	);
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;

	&::before {
		content: '';
		position: absolute;
		inset: calc(var(--size) / 10.6);
		border-radius: 50%;
		background: $bg-primary;
	}

	&__value {
		position: relative;
		z-index: 1;
		font-size: calc(var(--size) / 3.7);
		font-weight: 700;
		color: $text-primary;
		line-height: 1;
	}

	&__max {
		position: relative;
		z-index: 1;
		font-size: calc(var(--size) / 8.7);
		color: $text-tertiary;
	}

	// Only the unpassed slice changes colour with severity.
	&.is-good {
		--ring-rest: #{$bg-secondary};
	}

	&.is-warning {
		--ring-rest: #{$warning-color};
	}

	&.is-poor {
		--ring-rest: #{$error-color};
	}
}

.evas-issue-row {
	display: grid;
	grid-template-columns: 24px minmax(0, 1fr) auto;
	align-items: center;
	gap: $spacing-sm;

	&__count {
		font-size: 22px;
		font-weight: 700;
		text-align: center;
	}

	&__label {
		display: flex;
		flex-direction: column;
		min-width: 0;
		font-weight: 600;
		font-size: $font-size-sm;
		line-height: 1.3;

		em {
			font-style: normal;
			font-weight: 400;
			font-size: 11px;
			line-height: 1.3;
			color: $text-secondary;
		}
	}

	&.is-error .evas-issue-row__count {
		color: $error-color;
	}

	&.is-warning .evas-issue-row__count {
		color: $warning-color;
	}
}

.button.button-small {
	min-height: 26px;
	line-height: 24px;
	padding: 0 8px;
	font-size: 12px;
}

/* Quick Actions */
.evas-action-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: $spacing-md;

	// Three tiles only fit once the window is wide enough that the WordPress
	// chrome and the plugin's own nav aren't eating the row; below that two
	// wider tiles read better than three with wrapped titles.
	@media (max-width: 1600px) {
		grid-template-columns: repeat(2, 1fr);
	}

	@media (max-width: 480px) {
		grid-template-columns: 1fr;
	}
}

.evas-action-tile {
	display: grid;
	grid-template-columns: 32px minmax(0, 1fr);
	align-items: center;
	gap: 8px;
	padding: 12px;
	border: 1px solid $card-border;
	border-radius: $border-radius-lg;
	text-decoration: none;
	color: $text-primary;
	transition: border-color $transition-fast, box-shadow $transition-fast;

	&:hover {
		border-color: $primary-color;
		box-shadow: $card-shadow;
		color: $text-primary;
	}

	&__icon {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 32px;
		height: 32px;
		border-radius: $border-radius-lg;
		background: rgba($primary-color, 0.1);

		.dashicons {
			color: $primary-color;
			font-size: 17px;
			width: 17px;
			height: 17px;
		}
	}

	&__text {
		display: flex;
		flex-direction: column;
		gap: 1px;
		min-width: 0;
	}

	&__title {
		font-weight: 600;
		font-size: 12px;
		line-height: 1.3;
	}

	&__desc {
		font-size: 11px;
		line-height: 1.3;
		color: $text-secondary;
	}
}

/* Empty / disabled notice (used inside cards) */
.evas-analytics-disabled {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
	gap: $spacing-sm;
	padding: $spacing-xl $spacing-lg;
	min-height: 220px;

	.dashicons {
		font-size: 40px;
		width: 40px;
		height: 40px;
		color: $border-color;
	}

	&__title {
		margin: 0;
		font-size: $font-size-lg;
		font-weight: 600;
		color: $text-primary;
	}

	&__text {
		margin: 0;
		max-width: 380px;
		color: $text-secondary;
		font-size: $font-size-sm;
		line-height: 1.5;
	}

	&__action {
		margin-top: $spacing-sm;
		text-decoration: none;
	}
}

/* Documentation banner */
.evas-dashboard-banner {
	display: flex;
	align-items: center;
	gap: $spacing-md;
	padding: $spacing-lg;
	background: rgba($primary-color, 0.05);
	border: 1px solid rgba($primary-color, 0.2);
	border-radius: $card-radius;

	@media (max-width: 700px) {
		flex-wrap: wrap;
	}

	> .dashicons {
		display: flex;
		align-items: center;
		justify-content: center;
		box-sizing: content-box;
		font-size: 22px;
		width: 22px;
		height: 22px;
		padding: 8px;
		border-radius: 50%;
		background: $bg-primary;
		color: $primary-color;
		flex-shrink: 0;
	}

	&__text {
		flex: 1;
		display: flex;
		flex-direction: column;
		gap: 2px;

		strong {
			font-size: $font-size-base;
		}

		span {
			font-size: $font-size-sm;
			color: $text-secondary;
		}
	}
}

/* Date range picker */
.evas-date-range-picker {
	position: relative;

	&__trigger {
		@include evas-control;
		@include evas-control-default;

		gap: $spacing-sm;
		color: $text-primary;

		.dashicons {
			color: $text-secondary;
		}
	}

	&__popover {
		position: absolute;
		right: 0;
		top: calc(100% + 6px);
		z-index: 50;
		width: 280px;
		background: $bg-primary;
		border: 1px solid $card-border;
		border-radius: $border-radius-lg;
		box-shadow: $shadow-lg;
		padding: $spacing-md;
	}

	&__presets {
		display: flex;
		flex-wrap: wrap;
		gap: $spacing-xs;
		margin-bottom: $spacing-md;
	}

	&__preset {
		@include evas-control('small');
		@include evas-control-default;
	}

	&__fields {
		display: flex;
		flex-direction: column;
		gap: $spacing-sm;
		margin-bottom: $spacing-md;

		label {
			display: flex;
			flex-direction: column;
			gap: 4px;
			font-size: 12px;
			color: $text-secondary;
		}

		input {
			width: 100%;
		}
	}

	&__footer {
		text-align: right;
	}
}


/* Components Page */
.evas-components-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
	gap: $spacing-lg;
}

.evas-component-card {
	background: $bg-primary;
	border-radius: $border-radius-lg;
	box-shadow: $shadow-sm;
	overflow: hidden;
	transition: box-shadow $transition-base;

	&:hover {
		box-shadow: $shadow-base;
	}

	&__header {
		padding: $spacing-lg;
		border-bottom: 1px solid $border-light;
		display: flex;
		align-items: center;
		gap: $spacing-sm;

		.dashicons {
			font-size: 32px;
			width: 32px;
			height: 32px;
			color: $primary-color;
		}

		h3 {
			margin: 0;
			font-size: $font-size-lg;
			font-weight: 600;
		}
	}

	&__body {
		padding: $spacing-lg;

		p {
			margin: 0 0 $spacing-md;
			color: $text-secondary;
		}
	}

	&__meta {
		display: flex;
		gap: $spacing-sm;
	}

	&__type,
	&__status {
		display: inline-block;
		padding: $spacing-xs $spacing-sm;
		border-radius: $border-radius-sm;
		font-size: $font-size-sm;
		font-weight: 500;
	}

	&__type {
		background: $bg-tertiary;
		color: $text-secondary;
	}

	&__status {
		background: $bg-secondary;
		color: $text-secondary;

		&.is-active {
			background: rgba($success-color, 0.1);
			color: $success-color;
		}

		&.is-locked {
			background: $bg-tertiary;
			color: $text-secondary;
		}
	}

	&__footer {
		padding: $spacing-md $spacing-lg;
		border-top: 1px solid $border-light;
		text-align: right;
	}

	// An inactive module is not an unavailable one - its card carries the
	// primary "Enable" action. Dimming the whole card used to wash that button
	// out and make it read as disabled. The "Inactive" status chip already
	// says everything the opacity was saying.
	&.is-disabled &__header .dashicons {
		color: $text-secondary;
	}
}

/* Settings Forms */
.evas-settings-form {
	background: transparent;
	padding: 0;
	box-shadow: none;
}

.evas-settings-section {
	background: $bg-primary;
	border: 1px solid $border-light;
	border-radius: $border-radius-lg;
	box-shadow: $shadow-sm;
	padding: $spacing-lg;
	margin-bottom: $spacing-lg;

	&:last-child {
		margin-bottom: 0;
	}

	h3 {
		margin: 0 0 $spacing-lg;
		font-size: $font-size-lg;
		font-weight: 600;
	}
}

.evas-form-field {
	@extend .evas-field;
}

.evas-form-actions {
	padding-top: $spacing-lg;
	border-top: 1px solid $border-light;
}

/* Accessibility Analyzer page */
.evas-analyzer-page {
	max-width: $content-max-width;
}

.evas-analyzer-summary {
	display: flex;
	align-items: center;
	gap: $spacing-xl;
	flex-wrap: wrap;
	padding: $spacing-lg;
	margin-bottom: $spacing-lg;
	background: $bg-primary;
	border: 1px solid $card-border;
	border-radius: $card-radius;
	box-shadow: $card-shadow;

	&__tiles {
		display: flex;
		flex: 1;
		flex-wrap: wrap;
		gap: $spacing-lg;
	}
}

.evas-summary-tile {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 110px;

	&__value {
		font-size: 24px;
		font-weight: 700;
		line-height: 1;
	}

	&__label {
		font-size: $font-size-sm;
		color: $text-secondary;
	}

	&.is-error &__value {
		color: $error-color;
	}

	&.is-warning &__value {
		color: $warning-color;
	}
}

.evas-analyzer-toolbar {
	display: flex;
	align-items: center;
	gap: $spacing-sm;
	flex-wrap: wrap;
	margin-bottom: $spacing-md;

	// Everything in this row is one height. Each control otherwise brings
	// its own metrics - WP core's input/select sizing, the chip mixin's
	// 28px and the button mixin's 32px - which made the row read as ragged.
	.evas-analyzer-search,
	.evas-analyzer-sort,
	.evas-filter-chip,
	.button {
		box-sizing: border-box;
		height: 34px;
		min-height: 34px;
	}

	// The chip group carries a bottom margin for its standalone use in the
	// detail view. Left in place here, align-items: center would centre its
	// MARGIN box and lift the chips half the margin above the other
	// controls' baseline.
	.evas-analyzer-filters {
		margin-bottom: 0;
	}

	// Native form controls need their vertical padding zeroed for the fixed
	// height above to centre the text rather than clip it.
	.evas-analyzer-search,
	.evas-analyzer-sort {
		padding-top: 0;
		padding-bottom: 0;
		line-height: 1.2;
	}
}

.evas-analyzer-search {
	flex: 1 1 160px;
	min-width: 140px;
	max-width: 320px;
}

.evas-analyzer-clear {
	margin-left: auto;
}

.evas-analyzer-filters {
	display: flex;
	gap: 6px;
	flex-wrap: wrap;
	margin-bottom: $spacing-md;
}

.evas-filter-chip {
	@include evas-control('small');
	@include evas-control-default;

	&.is-active {
		@include evas-control-primary;
	}
}

.evas-analyzer-table {
	width: 100%;
	// Fixed layout so the page column keeps the leftover space instead of
	// being squeezed by the (nowrap) actions column, and so its cells have
	// a definite width - which is what text-overflow: ellipsis needs.
	table-layout: fixed;
	border-collapse: collapse;

	// Widths are content-box here (border-collapse + default box-sizing),
	// so each renders ~32px wider once the cell padding is added. Column 1
	// is deliberately left auto: it takes whatever is left.
	th:nth-child(2), td:nth-child(2) { width: 64px; }   // score
	th:nth-child(3), td:nth-child(3) { width: 60px; }   // errors
	th:nth-child(4), td:nth-child(4) { width: 120px; }  // warnings
	th:nth-child(5), td:nth-child(5) { width: 96px; }   // last scan
	th:nth-child(6), td:nth-child(6) { width: 215px; }  // actions
	background: $bg-primary;
	border: 1px solid $card-border;
	border-radius: $card-radius;
	box-shadow: $card-shadow;
	overflow: hidden;

	th,
	td {
		padding: $spacing-sm $spacing-md;
		text-align: left;
		border-bottom: 1px solid $border-light;
		vertical-align: middle;
	}

	th {
		font-size: $font-size-sm;
		font-weight: 600;
		color: $text-secondary;
		background: $bg-secondary;
	}

	tbody tr:last-child td {
		border-bottom: none;
	}

	td.is-error {
		color: $error-color;
		font-weight: 600;
	}

	td.is-warning {
		color: $warning-color;
		font-weight: 600;
	}

	&__page {
		display: flex;
		flex-direction: column;
		gap: 2px;
		width: 100%;
		background: none;
		border: none;
		padding: 0;
		text-align: left;
		cursor: pointer;

		strong,
		span {
			display: block;
			overflow: hidden;
			text-overflow: ellipsis;
			white-space: nowrap;
		}

		strong {
			color: $primary-color;
		}

		span {
			font-size: $font-size-xs;
			color: $text-tertiary;
		}

		&:hover strong {
			text-decoration: underline;
		}
	}

	// The cell itself stays a normal table cell - display:flex here would
	// take it out of the table layout and break the column widths and the
	// row borders. Only the inner row is a flex container.
	&__actions {
		white-space: nowrap;
	}

	&__actions-row {
		display: flex;
		gap: 6px;
		justify-content: flex-end;
	}
}

/* Accessibility Statement page */
.evas-statement-page {
	max-width: $content-max-width;
}

.evas-statement-shortcode {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: $spacing-md;
	flex-wrap: wrap;
	padding: $spacing-md $spacing-lg;
	margin-bottom: $spacing-lg;
	background: $bg-primary;
	border: 1px solid $card-border;
	border-radius: $card-radius;
	box-shadow: $card-shadow;

	strong {
		display: block;
		font-size: $font-size-sm;
		color: $text-secondary;
		margin-bottom: 2px;
	}

	code {
		font-size: $font-size-base;
		user-select: all;
	}
}

.evas-statement-layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: $spacing-lg;
	align-items: start;

	@media (max-width: 1100px) {
		grid-template-columns: minmax(0, 1fr);
	}
}

.evas-statement-form,
.evas-statement-preview {
	background: $bg-primary;
	border: 1px solid $card-border;
	border-radius: $card-radius;
	box-shadow: $card-shadow;
	padding: $spacing-lg;

	h3 {
		margin: 0 0 $spacing-md;
		font-size: $font-size-lg;

		& + .evas-field,
		& + .evas-field-description {
			margin-top: 0;
		}
	}

	h3:not(:first-child) {
		margin-top: $spacing-lg;
	}
}

.evas-statement-textarea {
	width: 100%;
	// The statement is HTML, so a monospace box makes the tags readable.
	font-family: Menlo, Consolas, monospace;
	font-size: $font-size-sm;
	line-height: 1.5;
	border-radius: $border-radius-lg;
}

.evas-statement-placeholders {
	margin-top: $spacing-md;
	padding: $spacing-md;
	background: $bg-secondary;
	border-radius: $border-radius-lg;
	font-size: $font-size-sm;

	ul {
		margin: $spacing-sm 0 0;
		padding: 0;
		list-style: none;
		display: grid;
		grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
		gap: 4px;
	}

	code {
		font-size: $font-size-xs;
	}

	span {
		color: $text-secondary;
	}
}

.evas-statement-actions {
	display: flex;
	gap: $spacing-sm;
	flex-wrap: wrap;
	margin-top: $spacing-lg;
	padding-top: $spacing-md;
	border-top: 1px solid $border-light;
}

.evas-statement-preview {
	position: sticky;
	top: $spacing-lg;

	&__head {
		display: flex;
		align-items: baseline;
		justify-content: space-between;
		gap: $spacing-sm;
	}

	&__status {
		font-size: $font-size-xs;
		color: $text-tertiary;
	}

	// Rendered statement markup - keep it readable without inheriting the
	// admin form's spacing.
	&__body {
		max-height: 620px;
		overflow-y: auto;

		h2 {
			margin-top: 0;
			font-size: 22px;
		}

		h3 {
			font-size: $font-size-lg;
			margin: $spacing-lg 0 $spacing-sm;
		}

		p {
			margin: 0 0 $spacing-sm;
		}

		ul {
			margin: 0 0 $spacing-sm;
			padding-left: 20px;
			list-style: disc;
		}
	}
}

/* Square icon-only variant of the shared button treatment. */
.evas-icon-button {
	width: 28px;
	padding: 0;
	flex-shrink: 0;

	.dashicons {
		font-size: 16px;
		width: 16px;
		height: 16px;
	}
}

.evas-analyzer-empty {
	text-align: center;
	padding: $spacing-xl;
	background: $bg-primary;
	border: 1px solid $card-border;
	border-radius: $card-radius;

	.dashicons {
		font-size: 40px;
		width: 40px;
		height: 40px;
		color: $text-tertiary;
	}

	h3 {
		margin: $spacing-sm 0;
	}

	p {
		max-width: 520px;
		margin: 0 auto $spacing-md;
		color: $text-secondary;
	}
}

/* Analyzer detail view */
.evas-analyzer-back {
	@include evas-control('small');
	@include evas-control-default;
	margin-bottom: $spacing-md;
}

.evas-analyzer-detail {
	&__head {
		display: flex;
		align-items: center;
		gap: $spacing-xl;
		flex-wrap: wrap;
		padding: $spacing-lg;
		margin-bottom: $spacing-lg;
		background: $bg-primary;
		border: 1px solid $card-border;
		border-radius: $card-radius;
		box-shadow: $card-shadow;
	}

	&__meta {
		flex: 1;
		min-width: 240px;

		h3 {
			margin: 0 0 4px;
		}

		> a {
			font-size: $font-size-sm;
			word-break: break-all;
		}
	}

	&__stats {
		margin: $spacing-sm 0;
		color: $text-secondary;
	}

	&__actions {
		display: flex;
		gap: $spacing-sm;
		flex-wrap: wrap;
	}
}

.evas-issue-groups {
	display: flex;
	flex-direction: column;
	gap: $spacing-sm;
}

.evas-issue-group {
	background: $bg-primary;
	border: 1px solid $card-border;
	border-left: 3px solid $text-tertiary;
	border-radius: $card-radius;
	overflow: hidden;

	&.is-critical { border-left-color: #b32d2e; }
	&.is-serious  { border-left-color: $error-color; }
	&.is-moderate { border-left-color: $warning-color; }
	&.is-minor    { border-left-color: $text-tertiary; }

	&__header {
		display: flex;
		align-items: center;
		gap: $spacing-sm;
		width: 100%;
		padding: $spacing-sm $spacing-md;
		background: none;
		border: none;
		cursor: pointer;
		text-align: left;

		&:hover {
			background: $bg-tertiary;
		}
	}

	&__title {
		flex: 1;
		font-weight: 600;
	}

	&__count {
		font-size: $font-size-sm;
		color: $text-secondary;
		white-space: nowrap;
	}

	&__body {
		padding: 0 $spacing-md $spacing-md;
		border-top: 1px solid $border-light;
	}

	&__desc {
		color: $text-secondary;
	}
}

.evas-impact-chip {
	display: inline-block;
	padding: 2px 8px;
	border-radius: 999px;
	font-size: 10px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.4px;
	color: #fff;
	white-space: nowrap;

	&.is-critical { background: #b32d2e; }
	&.is-serious  { background: $error-color; }
	&.is-moderate { background: $warning-color; }
	&.is-minor    { background: $text-tertiary; }
}

.evas-wcag-chip {
	padding: 2px 8px;
	border: 1px solid $border-color;
	border-radius: 999px;
	font-size: 11px;
	color: $text-secondary;
	white-space: nowrap;
}

.evas-issue-nodes {
	list-style: none;
	margin: 0;
	padding: 0;

	li {
		padding: $spacing-sm 0;
		border-bottom: 1px solid $border-light;

		&:last-child {
			border-bottom: none;
		}
	}

	code {
		display: inline-block;
		margin-bottom: 4px;
		font-size: $font-size-xs;
		word-break: break-all;
	}

	pre {
		margin: 0 0 4px;
		padding: $spacing-sm;
		background: $bg-secondary;
		border-radius: $border-radius-lg;
		font-size: $font-size-xs;
		white-space: pre-wrap;
		word-break: break-all;
		overflow-x: auto;
	}

	&__fix {
		margin: 0;
		color: $text-secondary;
		font-size: $font-size-sm;
		// axe's failureSummary is newline-formatted prose.
		white-space: pre-wrap;
	}
}

/* Empty State */
.evas-empty-state {
	text-align: center;
	padding: $spacing-xl;
	color: $text-secondary;
}

/* Utilities */
.button-primary {
	background: $primary-color;
	border-color: $primary-color;

	&:hover {
		background: $primary-hover;
		border-color: $primary-hover;
	}
}

/* Navigation with descriptions */
.evas-admin-navigation {
	&__link {
		display: flex;
		align-items: center;
		gap: $spacing-md;
	}

	&__content {
		display: flex;
		flex-direction: column;
		flex: 1;
		min-width: 0;
	}

	&__label {
		font-size: $font-size-base;
		font-weight: 500;
		line-height: 1.3;
	}

	&__description {
		font-size: $font-size-xs;
		color: $text-tertiary;
		line-height: 1.3;
		margin-top: 2px;
		opacity: 0.8;
	}

	&__link.is-active &__description {
		opacity: 1;
	}
}

/* Module Settings Page */
.evas-module-settings {

	&__header {
		margin-bottom: $spacing-xl;
		padding-bottom: $spacing-lg;
		border-bottom: 1px solid $border-light;

		h2 {
			margin: 0 0 $spacing-sm;
			font-size: 24px;
			font-weight: 600;
		}
	}

	&__description {
		margin: 0;
		color: $text-secondary;
	}

	&__loading {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: $spacing-sm;
		padding: $spacing-xl;
		color: $text-secondary;

		.spinner {
			float: none;
		}
	}

	&__error {
		padding: $spacing-lg;
		text-align: center;
		color: $error-color;
	}

	&__info {
		display: flex;
		gap: $spacing-lg;
		margin-bottom: $spacing-xl;
		padding: $spacing-md;
		background: $bg-secondary;
		border-radius: $border-radius-base;
	}

	&__status,
	&__version {
		display: flex;
		align-items: center;
		gap: $spacing-sm;
	}

	&__form {
		margin-bottom: $spacing-xl;
	}

	&__actions {
		padding-top: $spacing-lg;
		border-top: 1px solid $border-light;
	}

	&__empty {
		text-align: center;
		padding: $spacing-xl;
		color: $text-secondary;

		p {
			margin: 0 0 $spacing-sm;
		}
	}
}

/* Settings Groups */
.evas-field {
	margin-bottom: $spacing-lg;

	&:last-child {
		margin-bottom: 0;
	}

	> label {
		display: block;
		margin-bottom: $spacing-xs;
		font-weight: 500;
		color: $text-primary;
	}

	input[type="text"],
	input[type="password"],
	input[type="number"],
	input[type="email"],
	input[type="url"],
	select,
	textarea {
		width: 100%;
		max-width: 400px;
		padding: $spacing-sm $spacing-md;
		border: 1px solid $border-color;
		border-radius: $border-radius-base;
		background: $bg-primary;
		font-size: $font-size-base;
		color: $text-primary;

		&:focus {
			outline: none;
			border-color: $primary-color;
			box-shadow: 0 0 0 1px $primary-color;
		}

		&:disabled {
			opacity: 0.6;
			cursor: not-allowed;
		}
	}

	select {
		padding-right: 32px;
		background-image: url("data:image/svg+xml,%3Csvg width='12' height='12' viewBox='0 0 12 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2 4L6 8L10 4' stroke='%23666' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
		background-repeat: no-repeat;
		background-position: right 10px center;
		background-size: 12px;
		appearance: none;
	}

	input[type="range"] {
		flex: 1;
		max-width: 320px;
	}

	.evas-field-description {
		margin-top: $spacing-xs;
	}
}

.evas-range-control {
	display: flex;
	align-items: center;
	gap: $spacing-md;
}

.evas-range-value {
	min-width: 48px;
	font-weight: 600;
	color: $primary-color;
}

.evas-features-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
	gap: $spacing-md;
}

.evas-features-group {
	background: $bg-secondary;
	padding: $spacing-md;
	border-radius: $border-radius-base;

	h4 {
		margin: 0 0 $spacing-sm;
		font-size: $font-size-base;
		font-weight: 600;
	}

	label {
		display: flex;
		align-items: center;
		gap: $spacing-xs;
	}
}

/* Notices */
.evas-notice {
	padding: $spacing-md;
	border-radius: $border-radius-base;
	margin-bottom: $spacing-lg;

	p {
		margin: 0;
	}

	&--error {
		background: rgba($error-color, 0.1);
		color: $error-color;
		border: 1px solid rgba($error-color, 0.3);
	}

	&--success {
		background: rgba($success-color, 0.1);
		color: darken($success-color, 10%);
		border: 1px solid rgba($success-color, 0.3);
	}

	&--warning {
		background: rgba($warning-color, 0.1);
		color: darken($warning-color, 20%);
		border: 1px solid rgba($warning-color, 0.3);
	}
}

/* Badges */
.evas-badge {
	display: inline-block;
	padding: $spacing-xs $spacing-sm;
	border-radius: $border-radius-sm;
	font-size: $font-size-sm;
	font-weight: 500;

	&--success {
		background: rgba($success-color, 0.1);
		color: $success-color;
	}

	&--warning {
		background: rgba($warning-color, 0.1);
		color: darken($warning-color, 15%);
	}

	&--error {
		background: rgba($error-color, 0.1);
		color: $error-color;
	}
}

.evas-label {
	font-weight: 500;
	color: $text-secondary;
}

/* Toggle Switches - Readabler Style */
.evas-toggle-field {
	margin-bottom: $spacing-md;
	padding: $spacing-sm 0;
}

.evas-toggle-label {
	display: flex;
	align-items: flex-start;
	gap: $spacing-md;
	cursor: pointer;
}

.evas-toggle-switch {
	position: relative;
	display: inline-block;
	width: 44px;
	height: 24px;
	flex-shrink: 0;
	margin-top: 2px;

	input {
		opacity: 0;
		width: 0;
		height: 0;
	}
}

.evas-toggle-slider {
	position: absolute;
	cursor: pointer;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background-color: $bg-tertiary;
	transition: 0.3s;
	border-radius: 24px;

	// Track 44x24, knob 16 - so 4px of clearance on every side. It used to
	// be pinned with bottom/left: 2px, which left 6px above and 6px to the
	// right of the travelled knob: visibly low in the track and off-centre
	// at both ends.
	&::before {
		position: absolute;
		content: "";
		height: 16px;
		width: 16px;
		top: 4px;
		left: 4px;
		background-color: $bg-primary;
		transition: 0.3s;
		border-radius: 50%;
		box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
	}
}

.evas-toggle-switch input:checked + .evas-toggle-slider {
	background-color: $primary-color;
}

.evas-toggle-switch input:checked + .evas-toggle-slider::before {
	transform: translateX(20px);
}

.evas-toggle-switch input:disabled + .evas-toggle-slider {
	opacity: 0.5;
	cursor: not-allowed;
}

.evas-toggle-switch input:focus + .evas-toggle-slider {
	box-shadow: 0 0 0 2px rgba($primary-color, 0.2);
}

.evas-toggle-content {
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: $spacing-xs;
}

.evas-toggle-text {
	font-weight: 500;
	color: $text-primary;
	line-height: 1.5;
}

.evas-field-description {
	margin: 0;
	font-size: $font-size-sm;
	color: $text-secondary;
	line-height: 1.4;
}

/* Toggle Grid */
.evas-toggle-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
	gap: $spacing-sm;
}

/* Collapsible Sections */
.evas-settings-section {
	&.is-collapsible {
		border: 1px solid $border-light;
		border-radius: $border-radius-lg;
		padding: 0;
		margin-bottom: $spacing-lg;

		.evas-section-header {
			cursor: pointer;
			display: flex;
			align-items: flex-start;
			justify-content: space-between;
			padding: $spacing-lg;
			background: $bg-secondary;
			border-radius: $border-radius-lg $border-radius-lg 0 0;
			transition: background $transition-fast;
			gap: $spacing-md;

			&:hover {
				background: $bg-tertiary;
			}

			h3 {
				margin: 0;
				flex: 1;
			}

			.evas-section-description {
				margin: $spacing-xs 0 0;
			}

			.dashicons {
				color: $text-secondary;
				transition: transform $transition-fast;
				flex-shrink: 0;
				margin-top: 2px;
			}
		}

		.evas-section-content {
			padding: $spacing-lg;
			border-top: 1px solid $border-light;
		}

		&:not(.is-open) {
			.evas-section-header {
				border-radius: $border-radius-lg;
			}

			.evas-section-content {
				display: none;
			}
		}
	}
}

.evas-section-header {
	> div {
		flex: 1;
	}
}

.evas-section-description {
	margin: $spacing-xs 0 0;
	font-size: $font-size-sm;
	color: $text-secondary;
}

/* Accessibility Page Specific */
.evas-accessibility-page {
	max-width: $content-max-width;

	.evas-toggle-grid {
		padding: $spacing-md;
		background: $bg-secondary;
		border-radius: $border-radius-base;
		margin-top: $spacing-md;
	}

	// First toggle in a section (Show Section Heading) is a section switch
	.evas-section-content > .evas-toggle-field:first-child {
		padding-bottom: $spacing-md;
		margin-bottom: $spacing-md;
		border-bottom: 1px solid $border-light;
	}
}

/* Loading State */
.evas-loading {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: $spacing-sm;
	padding: $spacing-xl;
	color: $text-secondary;

	.spinner {
		float: none;
		margin: 0;
	}
}

/* Notice Styles */
/* Usage Analytics Page */
.evas-usage-analytics-page {
	max-width: $content-max-width;
}

.evas-analytics-overview {
	background: $bg-primary;
	padding: $spacing-lg;
	border-radius: $border-radius-lg;
	box-shadow: $shadow-sm;
	margin-bottom: $spacing-xl;

	h3 {
		margin: 0 0 $spacing-lg;
		font-size: $font-size-lg;
		font-weight: 600;
	}
}

.evas-analytics-stats-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: $spacing-md;

	@media (max-width: 768px) {
		grid-template-columns: repeat(2, 1fr);
	}
}

.evas-analytics-stat {
	text-align: center;
	padding: $spacing-md;
	background: $bg-secondary;
	border-radius: $border-radius-base;

	&__value {
		display: block;
		font-size: 28px;
		font-weight: 700;
		color: $primary-color;
		line-height: 1.2;
	}

	&__label {
		display: block;
		font-size: $font-size-sm;
		color: $text-secondary;
		margin-top: $spacing-xs;
	}
}

.evas-range-field {
	margin-bottom: $spacing-lg;

	label {
		display: block;
		margin-bottom: $spacing-sm;
		font-weight: 500;
		color: $text-primary;
	}
}

.evas-range-control {
	display: flex;
	align-items: center;
	gap: $spacing-md;

	input[type="range"] {
		flex: 1;
		max-width: 300px;
		height: 6px;
		-webkit-appearance: none;
		appearance: none;
		background: $bg-tertiary;
		border-radius: 3px;
		outline: none;

		&::-webkit-slider-thumb {
			-webkit-appearance: none;
			appearance: none;
			width: 18px;
			height: 18px;
			background: $primary-color;
			border-radius: 50%;
			cursor: pointer;
			transition: background $transition-fast;
		}

		&::-webkit-slider-thumb:hover {
			background: $primary-hover;
		}

		&::-moz-range-thumb {
			width: 18px;
			height: 18px;
			background: $primary-color;
			border-radius: 50%;
			cursor: pointer;
			border: none;
		}

		&:disabled {
			opacity: 0.5;
			cursor: not-allowed;

			&::-webkit-slider-thumb {
				cursor: not-allowed;
			}
		}
	}
}

.evas-range-value {
	min-width: 50px;
	font-weight: 600;
	color: $primary-color;
	text-align: center;
}

// Skeleton loader styles
@keyframes evas-skeleton-pulse {
	0%, 100% {
		opacity: 1;
	}
	50% {
		opacity: 0.5;
	}
}

.evas-skeleton-line {
	background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
	background-size: 200% 100%;
	animation: evas-skeleton-pulse 1.5s ease-in-out infinite;
	border-radius: 4px;
	height: 16px;
	
	&--metric-value {
		width: 60px;
		height: 24px;
		margin-bottom: 8px;
	}
	
	&--metric-label {
		width: 50px;
		height: 14px;
	}
	
	&--legend {
		width: 80px;
		height: 14px;
	}
	
	&--tab {
		width: 60px;
		height: 20px;
	}
	
	&--bar-label {
		width: 100px;
		height: 16px;
	}
	
	&--bar-value {
		width: 30px;
		height: 16px;
	}
}

.evas-skeleton-select {
	width: 100px;
	height: 30px;
	background: linear-gradient(90deg, rgba(255, 255, 255, 0.2) 25%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0.2) 75%);
	background-size: 200% 100%;
	animation: evas-skeleton-pulse 1.5s ease-in-out infinite;
	border-radius: 4px;
	border: none;
}

.evas-skeleton-canvas {
	background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
	background-size: 200% 100%;
	animation: evas-skeleton-pulse 1.5s ease-in-out infinite;
	border-radius: 4px;
	width: 100%;
	height: 120px;
}

.evas-skeleton-tab {
	background: transparent;
	border: none;
	padding: 8px 16px;
	cursor: default;
	display: flex;
	align-items: center;
	justify-content: center;
}

.evas-skeleton-bar-row {
	display: flex;
	align-items: center;
	gap: 12px;
	margin-bottom: 12px;
}

.evas-skeleton-bar-track {
	flex: 1;
	height: 20px;
	background: #f0f0f0;
	border-radius: 10px;
	overflow: hidden;
}

.evas-skeleton-bar-fill {
	height: 100%;
	width: 40%;
	background: linear-gradient(90deg, #e0e0e0 25%, #d0d0d0 50%, #e0e0e0 75%);
	background-size: 200% 100%;
	animation: evas-skeleton-pulse 1.5s ease-in-out infinite;
	border-radius: 10px;
}

.evas-skeleton-legend {
	display: flex;
	align-items: center;
	gap: 8px;
}


/* ==========================================================================
   Customizer colour presets
   ========================================================================== */

.evas-preset-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
	gap: $spacing-md;
}

.evas-preset-card {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: $spacing-sm;
	padding: $spacing-sm;
	background: $bg-primary;
	border: 1px solid $card-border;
	border-radius: $border-radius-lg;
	cursor: pointer;
	text-align: center;
	transition: border-color $transition-fast, box-shadow $transition-fast;

	&:hover:not(:disabled) {
		border-color: $primary-color;
		box-shadow: $card-shadow;
	}

	&:disabled {
		opacity: 0.6;
		cursor: default;
	}

	// Light and dark halves sit side by side: a preset defines both, and
	// judging one without the other is exactly what makes picking colours slow.
	&__preview {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: 2px;
		height: 52px;
		border-radius: $border-radius-base;
		overflow: hidden;
	}

	&__label {
		font-size: $font-size-sm;
		font-weight: 600;
		color: $text-primary;
	}
}

.evas-preset-swatch {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 6px;

	// The two dots are the key and text colours of that half, shown against
	// its own background - the three values a preset actually sets.
	span {
		width: 13px;
		height: 13px;
		border-radius: 50%;
		box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.12);
	}
}
