/* Compiles to assets/basalt/css/components/alerts.css, linked after basalt.css by
   the pages that use it. */
/* The richer .basalt-alert layout and its variants, the page-wide
   .basalt-banner and the stacked .basalt-alert-group, all on alerts.html.
   Their script is assets/basalt/js/components/alerts.js. */
/* A visible keyboard ring in a chosen color, sitting off the element. */
/* Bootstrap's button variables for one skin. The text color holds through
   hover and press; only the fill and border move. */
/* Transitions switch off for visitors who ask the system for less motion. */
/* .basalt-alert rides on .alert plus a color class and lays it out as a
   grid: an icon tile, the body (title over text), an actions column and a
   close button pinned top right. The alert's own width, read through a
   container query, decides when the actions drop below the text. */
.basalt-alert {
	--basalt-alert-icon: 2.25rem;
	display: grid;
	gap: 0.75rem 0.9rem;
	grid-template-columns: var(--basalt-alert-icon) minmax(0, 1fr) auto;
	align-items: start;
	container-type: inline-size;
	padding: 1rem 1.1rem;
	transition:
		opacity 210ms ease,
		transform 210ms ease,
		background-color 210ms ease,
		border-color 210ms ease,
		color 210ms ease;
}
@media (prefers-reduced-motion: reduce) {
	.basalt-alert {
		transition: none;
	}
}
.basalt-alert:has(> .basalt-alert-close) {
	padding-right: 3.25rem;
}

.basalt-alert-icon {
	display: inline-grid;
	grid-column: 1;
	place-items: center;
	width: var(--basalt-alert-icon);
	height: var(--basalt-alert-icon);
	border-radius: 10px;
	font-size: 1.05rem;
	color: var(--basalt-alert-ink);
	background: color-mix(in srgb, var(--basalt-alert-tone) 18%, var(--basalt-plane));
}

.basalt-alert-body,
.basalt-alert > .basalt-alert-text {
	grid-column: 2;
	align-self: center;
	min-width: 0;
}

.basalt-alert-title {
	margin: 0;
	font-size: 0.95rem;
	font-weight: 650;
	line-height: 1.35;
	color: var(--basalt-alert-ink);
}

.basalt-alert-text {
	margin: 0;
	line-height: 1.5;
	color: var(--basalt-copy-body);
}

.basalt-alert-title + .basalt-alert-text {
	margin-top: 0.1rem;
}

.basalt-alert-mono {
	font-family: "Chivo Mono", monospace;
	font-size: 0.92em;
}

.basalt-alert-actions {
	display: flex;
	gap: 0.5rem;
	flex-wrap: wrap;
	grid-column: 3;
	align-self: center;
}
@container (max-width: 34rem) {
	.basalt-alert-actions {
		grid-column: 2/-1;
	}
}

/* Action buttons wear the alert's ink as a fill, or outline it as a ghost. */
.basalt-alert-btn {
	--bs-btn-color: var(--basalt-plane);
	--bs-btn-bg: var(--basalt-alert-ink);
	--bs-btn-border-color: var(--basalt-alert-ink);
	--bs-btn-hover-color: var(--basalt-plane);
	--bs-btn-hover-bg: color-mix(in srgb, var(--basalt-alert-ink) 84%, var(--basalt-copy));
	--bs-btn-hover-border-color: color-mix(in srgb, var(--basalt-alert-ink) 84%, var(--basalt-copy));
	--bs-btn-active-color: var(--basalt-plane);
	--bs-btn-active-bg: color-mix(in srgb, var(--basalt-alert-ink) 76%, var(--basalt-copy));
	--bs-btn-active-border-color: color-mix(in srgb, var(--basalt-alert-ink) 76%, var(--basalt-copy));
	--bs-btn-disabled-color: var(--basalt-plane);
	--bs-btn-disabled-bg: var(--basalt-alert-ink);
	--bs-btn-disabled-border-color: var(--basalt-alert-ink);
	--bs-btn-disabled-opacity: 1;
	--bs-btn-font-weight: 600;
	display: inline-flex;
	gap: 0.4rem;
	align-items: center;
	white-space: nowrap;
}
.basalt-alert-btn:focus-visible {
	box-shadow: none;
	outline: 2px solid var(--basalt-alert-ink);
	outline-offset: 2px;
}

.basalt-alert-btn-ghost {
	--bs-btn-color: var(--basalt-alert-ink);
	--bs-btn-bg: transparent;
	--bs-btn-border-color: color-mix(in srgb, var(--basalt-alert-ink) 45%, transparent);
	--bs-btn-hover-color: var(--basalt-alert-ink);
	--bs-btn-hover-bg: color-mix(in srgb, var(--basalt-alert-tone) 14%, var(--basalt-plane));
	--bs-btn-hover-border-color: var(--basalt-alert-ink);
	--bs-btn-active-color: var(--basalt-alert-ink);
	--bs-btn-active-bg: color-mix(in srgb, var(--basalt-alert-tone) 20%, var(--basalt-plane));
	--bs-btn-active-border-color: var(--basalt-alert-ink);
}

/* While busy, a spinner leads the label and the button holds its width. */
.basalt-alert-btn.is-busy {
	cursor: progress;
}
.basalt-alert-btn.is-busy::before {
	content: "";
	width: 0.85em;
	height: 0.85em;
	border-radius: 50%;
	border: 2px solid currentColor;
	border-right-color: transparent;
	animation: basalt-alert-spin 700ms linear infinite;
}
@media (prefers-reduced-motion: reduce) {
	.basalt-alert-btn.is-busy::before {
		animation-duration: 2s;
	}
}

@keyframes basalt-alert-spin {
	to {
		transform: rotate(360deg);
	}
}
.basalt-alert-close {
	position: absolute;
	top: 0.7rem;
	right: 0.7rem;
	display: inline-grid;
	place-items: center;
	width: 2rem;
	height: 2rem;
	padding: 0;
	border: 0;
	border-radius: 8px;
	font-size: 0.85rem;
	color: var(--basalt-alert-ink);
	background: transparent;
	cursor: pointer;
	transition: background-color 170ms ease;
}
@media (prefers-reduced-motion: reduce) {
	.basalt-alert-close {
		transition: none;
	}
}
.basalt-alert-close:hover {
	background: color-mix(in srgb, var(--basalt-alert-tone) 16%, var(--basalt-plane));
}
.basalt-alert-close:focus-visible {
	outline: 2px solid var(--basalt-alert-ink);
	outline-offset: 1px;
}

/* On its way out the alert fades and rises a little, then the script hides it. */
.basalt-alert.is-leaving {
	transform: translateY(-4px);
	opacity: 0;
}

/* The countdown variant: a draining bar, the seconds left, and a keep link. */
.basalt-alert-timer {
	display: flex;
	gap: 0.3rem 0.75rem;
	flex-wrap: wrap;
	align-items: center;
	margin-top: 0.7rem;
	font-size: 0.77rem;
	color: var(--basalt-alert-ink);
}
.basalt-alert-timer[hidden] {
	display: none;
}

.basalt-alert-timer-track {
	flex: 1 1 8rem;
	max-width: 14rem;
	height: 4px;
	border-radius: 999px;
	overflow: hidden;
	background: color-mix(in srgb, var(--basalt-alert-tone) 24%, var(--basalt-plane));
}

.basalt-alert-timer-bar {
	transform-origin: left center;
	transform: scaleX(var(--basalt-alert-left, 1));
	display: block;
	height: 100%;
	border-radius: inherit;
	background: var(--basalt-alert-ink);
}

.basalt-alert-timer-text {
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

.basalt-alert.is-paused .basalt-alert-timer-bar {
	opacity: 0.55;
}

.basalt-alert-keep {
	padding: 0;
	border: 0;
	border-radius: 4px;
	font: inherit;
	font-weight: 600;
	text-decoration: underline;
	text-underline-offset: 0.2em;
	color: inherit;
	background: none;
	cursor: pointer;
}
.basalt-alert-keep:focus-visible {
	outline: 2px solid var(--basalt-alert-ink);
	outline-offset: 2px;
}

/* The progress variant: a filled track with a caption row beneath. */
.basalt-alert-progress {
	height: 6px;
	margin-top: 0.75rem;
	border-radius: 999px;
	overflow: hidden;
	background: color-mix(in srgb, var(--basalt-alert-tone) 22%, var(--basalt-plane));
}
.basalt-alert-progress > span {
	display: block;
	width: var(--basalt-alert-progress, var(--share, 0%));
	height: 100%;
	border-radius: inherit;
	background: var(--basalt-alert-ink);
	transition: width 200ms linear;
}
@media (prefers-reduced-motion: reduce) {
	.basalt-alert-progress > span {
		transition: none;
	}
}

.basalt-alert-meta {
	display: flex;
	gap: 1rem;
	justify-content: space-between;
	margin: 0.4rem 0 0;
	font-size: 0.77rem;
	font-variant-numeric: tabular-nums;
	color: var(--basalt-copy-body);
}

/* The summary variant lists the fields that need attention, each a link. */
.basalt-alert-list {
	margin: 0.4rem 0 0;
	padding-left: 1.1rem;
}
.basalt-alert-list li + li {
	margin-top: 0.2rem;
}
.basalt-alert-list a {
	border-radius: 3px;
	font-weight: 600;
	text-decoration: underline;
	text-underline-offset: 0.2em;
	color: var(--basalt-alert-ink);
}
.basalt-alert-list a:hover {
	text-decoration-thickness: 2px;
}
.basalt-alert-list a:focus-visible {
	outline: 2px solid var(--basalt-alert-ink);
	outline-offset: 2px;
}

/* The expanding variant hides its detail rows behind a toggle. */
.basalt-alert-toggle {
	display: inline-flex;
	gap: 0.3rem;
	align-items: center;
	margin-top: 0.5rem;
	padding: 0;
	border: 0;
	border-radius: 4px;
	font-size: 0.8rem;
	font-weight: 600;
	color: var(--basalt-alert-ink);
	background: none;
	cursor: pointer;
}
.basalt-alert-toggle .bi {
	font-size: 0.75rem;
	transition: transform 200ms ease;
}
@media (prefers-reduced-motion: reduce) {
	.basalt-alert-toggle .bi {
		transition: none;
	}
}
.basalt-alert-toggle[aria-expanded="true"] .bi {
	transform: rotate(180deg);
}
.basalt-alert-toggle:hover {
	text-decoration: underline;
	text-underline-offset: 0.2em;
}
.basalt-alert-toggle:focus-visible {
	outline: 2px solid var(--basalt-alert-ink);
	outline-offset: 2px;
}

.basalt-alert-rows {
	margin: 0.75rem 0 0.6rem;
	padding: 0;
	font-size: 0.84rem;
	color: var(--basalt-copy-body);
	list-style: none;
}
.basalt-alert-rows li {
	display: grid;
	gap: 0.75rem;
	grid-template-columns: 4.5rem minmax(0, 1fr) auto;
	padding: 0.4rem 0;
	border-top: 1px solid color-mix(in srgb, var(--basalt-alert-tone) 28%, var(--basalt-plane));
}

/* The compact variant is a single slim row with everything centered. */
.basalt-alert-compact {
	--basalt-alert-icon: 1.6rem;
	gap: 0.5rem 0.65rem;
	align-items: center;
	padding: 0.5rem 0.7rem;
	border-radius: 10px;
	font-size: 0.84rem;
}
.basalt-alert-compact .basalt-alert-icon {
	border-radius: 7px;
	font-size: 0.85rem;
}
.basalt-alert-compact:has(> .basalt-alert-close) {
	padding-right: 2.6rem;
}
.basalt-alert-compact .basalt-alert-close {
	top: 50%;
	right: 0.4rem;
	transform: translateY(-50%);
	width: 1.75rem;
	height: 1.75rem;
	font-size: 0.75rem;
}

/* Accent keeps a plain surface and marks the tone with a bar on the left. */
.basalt-alert-accent {
	--bs-alert-bg: var(--basalt-plane);
	--bs-alert-border-color: var(--basalt-edge);
}
.basalt-alert-accent::before {
	content: "";
	position: absolute;
	top: 0.75rem;
	bottom: 0.75rem;
	left: -1px;
	width: 3px;
	border-radius: 0 3px 3px 0;
	background: var(--basalt-alert-tone);
}

/* Outline drops the fill and lets a stronger border carry the tone. */
.basalt-alert-outline {
	--bs-alert-bg: transparent;
	--bs-alert-border-color: color-mix(in srgb, var(--basalt-alert-tone) 60%, var(--basalt-plane));
}
.basalt-alert-outline .basalt-alert-icon {
	font-size: 1.1rem;
	background: transparent;
}

/* Solid fills with the ink, so every part inside turns to the surface color. */
.basalt-alert-solid {
	--bs-alert-bg: var(--basalt-alert-ink);
	--bs-alert-border-color: var(--basalt-alert-ink);
	--bs-alert-color: var(--basalt-plane);
}
.basalt-alert-solid .basalt-alert-icon {
	color: var(--basalt-plane);
	background: color-mix(in srgb, var(--basalt-plane) 18%, transparent);
}

.basalt-alert-solid .basalt-alert-title,
.basalt-alert-solid .basalt-alert-text {
	color: var(--basalt-plane);
}

.basalt-alert-solid .basalt-alert-btn {
	--bs-btn-color: var(--basalt-alert-ink);
	--bs-btn-bg: var(--basalt-plane);
	--bs-btn-border-color: var(--basalt-plane);
	--bs-btn-hover-color: var(--basalt-alert-ink);
	--bs-btn-hover-bg: color-mix(in srgb, var(--basalt-plane) 86%, var(--basalt-alert-tone));
	--bs-btn-hover-border-color: var(--basalt-plane);
	--bs-btn-active-color: var(--basalt-alert-ink);
	--bs-btn-active-bg: color-mix(in srgb, var(--basalt-plane) 80%, var(--basalt-alert-tone));
	--bs-btn-active-border-color: var(--basalt-plane);
}
.basalt-alert-solid .basalt-alert-btn:focus-visible {
	outline-color: var(--basalt-plane);
}

/* .basalt-banner runs the full width of the page top and shows one slide
   (.basalt-banner-slide) at a time, with an optional pager and count. Its fill
   is the tone mixed into the text color and its words take the surface color,
   which reads the same way in light and dark. Warning, danger and success
   swap the tone. */
.basalt-banner {
	--basalt-banner-tone: var(--basalt-hue);
	--basalt-banner-bg: color-mix(in srgb, var(--basalt-banner-tone) 42%, var(--basalt-copy));
	display: flex;
	gap: 0.5rem 0.85rem;
	flex-wrap: wrap;
	align-items: center;
	padding: 0.6rem 0.75rem 0.6rem 1rem;
	font-size: 0.86rem;
	line-height: 1.45;
	color: var(--basalt-plane);
	background: var(--basalt-banner-bg);
}
.basalt-banner[hidden] {
	display: none;
}
.basalt-banner + .basalt-banner {
	border-top: 1px solid color-mix(in srgb, var(--basalt-plane) 20%, transparent);
}

.basalt-banner-warning {
	--basalt-banner-tone: var(--basalt-warning);
}

.basalt-banner-danger {
	--basalt-banner-tone: var(--basalt-danger);
}

.basalt-banner-success {
	--basalt-banner-tone: var(--basalt-success);
}

.basalt-banner-icon {
	display: inline-grid;
	flex-shrink: 0;
	place-items: center;
	width: 1.9rem;
	height: 1.9rem;
	border-radius: 8px;
	background: color-mix(in srgb, var(--basalt-plane) 16%, transparent);
}

.basalt-banner-slides {
	flex: 1 1 16rem;
	min-width: 0;
}

.basalt-banner-slide {
	margin: 0;
}
.basalt-banner-slide[hidden] {
	display: none;
}
.basalt-banner-slide.is-entering {
	animation: basalt-banner-in 260ms ease;
}
@media (prefers-reduced-motion: reduce) {
	.basalt-banner-slide.is-entering {
		animation: none;
	}
}

@keyframes basalt-banner-in {
	from {
		transform: translateY(4px);
		opacity: 0;
	}
}
.basalt-banner a {
	border-radius: 3px;
	font-weight: 600;
	text-decoration: underline;
	text-underline-offset: 0.2em;
	white-space: nowrap;
	color: inherit;
}
.basalt-banner a:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}

.basalt-banner-pager {
	display: inline-flex;
	gap: 0.1rem;
	align-items: center;
	margin-left: auto;
}

.basalt-banner-count {
	min-width: 2.6rem;
	font-size: 0.77rem;
	text-align: center;
	font-variant-numeric: tabular-nums;
}

/* The pager arrows and the close button share one quiet square button. */
.basalt-banner-nav,
.basalt-banner-close {
	display: inline-grid;
	place-items: center;
	width: 1.9rem;
	height: 1.9rem;
	padding: 0;
	border: 0;
	border-radius: 8px;
	font-size: 0.8rem;
	color: inherit;
	background: transparent;
	cursor: pointer;
	transition: background-color 170ms ease;
}

.basalt-banner-nav:hover,
.basalt-banner-close:hover {
	background: color-mix(in srgb, var(--basalt-plane) 18%, transparent);
}

.basalt-banner-nav:focus-visible,
.basalt-banner-close:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 1px;
}

@media (prefers-reduced-motion: reduce) {
	.basalt-banner-nav,
	.basalt-banner-close {
		transition: none;
	}
}

/* .basalt-alert-group folds several alerts into one card. Closed, the first
   shows in full and the next two peek out under it like a deck of cards;
   .is-open spreads them all. The script owns the count and the tally and
   removes the items that get cleared. */
.basalt-alert-group {
	padding: 1rem;
	border: 1px solid var(--basalt-edge);
	border-radius: 14px;
	background: var(--basalt-plane);
}

.basalt-alert-group-head {
	display: flex;
	gap: 0.3rem 0.75rem;
	flex-wrap: wrap;
	align-items: center;
	margin-bottom: 0.85rem;
}

.basalt-alert-group-title {
	margin: 0;
	font-size: 0.95rem;
	font-weight: 650;
	color: var(--basalt-copy);
}

/* The tally is a row of colored dots with counts, one per tone. */
.basalt-alert-group-tally {
	display: inline-flex;
	gap: 0.25rem 0.7rem;
	flex-wrap: wrap;
	font-size: 0.77rem;
	color: color-mix(in srgb, var(--basalt-copy-muted) 72%, var(--basalt-copy));
}
.basalt-alert-group-tally span {
	display: inline-flex;
	gap: 0.3rem;
	align-items: center;
}
.basalt-alert-group-tally span::before {
	content: "";
	width: 0.5rem;
	height: 0.5rem;
	border-radius: 50%;
	background: var(--basalt-alert-tone, var(--basalt-hue));
}
.basalt-alert-group-tally [data-tone="danger"] {
	--basalt-alert-tone: var(--basalt-danger);
}
.basalt-alert-group-tally [data-tone="warning"] {
	--basalt-alert-tone: var(--basalt-warning);
}
.basalt-alert-group-tally [data-tone="success"] {
	--basalt-alert-tone: var(--basalt-success);
}
.basalt-alert-group-tally [data-tone="info"] {
	--basalt-alert-tone: var(--basalt-flare);
}

.basalt-alert-group-tools {
	display: inline-flex;
	gap: 1rem;
	margin-left: auto;
	font-size: 0.8rem;
}

.basalt-alert-group-list {
	display: flex;
	flex-direction: column;
	margin: 0;
	padding: 0;
	list-style: none;
}
.basalt-alert-group-list > .alert {
	position: relative;
	max-height: 8rem;
	margin: 0;
	transition:
		max-height 260ms ease,
		margin 260ms ease,
		opacity 260ms ease;
}
@media (prefers-reduced-motion: reduce) {
	.basalt-alert-group-list > .alert {
		transition: none;
	}
}
.basalt-alert-group-list > .alert + .alert {
	margin-top: 0.5rem;
}
.basalt-alert-group-list > .alert.is-front {
	margin-top: 0;
}

/* Closed, the group is a deck. The script tags the alerts still in view as
   is-front, is-peek, is-peek-2 and is-tucked; any others are hidden. */
.basalt-alert-group:not(.is-open) .basalt-alert-group-list > .alert:is(.is-peek, .is-peek-2, .is-tucked) {
	max-height: 0.4rem;
	margin-top: 0;
	border-top-width: 0;
	border-top-left-radius: 0;
	border-top-right-radius: 0;
	overflow: hidden;
	box-shadow: none;
}
.basalt-alert-group:not(.is-open) .basalt-alert-group-list > .alert.is-front {
	z-index: 3;
}
.basalt-alert-group:not(.is-open) .basalt-alert-group-list > .alert.is-peek {
	z-index: 2;
	min-height: 0.4rem;
	margin-inline: 0.6rem;
	opacity: 0.85;
}
.basalt-alert-group:not(.is-open) .basalt-alert-group-list > .alert.is-peek-2 {
	z-index: 1;
	min-height: 0.4rem;
	margin-inline: 1.2rem;
	opacity: 0.7;
}
.basalt-alert-group:not(.is-open) .basalt-alert-group-list > .alert.is-tucked {
	display: none;
}
.basalt-alert-group:not(.is-open) .basalt-alert-group-list > .alert:is(.is-peek, .is-peek-2, .is-tucked) > * {
	display: none;
}

/* Once every alert is cleared, a calm all-clear note takes their place. */
.basalt-alert-group-empty {
	display: flex;
	gap: 0.5rem;
	flex-direction: column;
	align-items: center;
	padding: 1.25rem 1rem;
	font-size: 0.88rem;
	text-align: center;
	color: var(--basalt-copy-body);
}
.basalt-alert-group-empty[hidden] {
	display: none;
}
.basalt-alert-group-empty .bi {
	font-size: 1.5rem;
	color: color-mix(in srgb, var(--basalt-success) 60%, var(--basalt-copy));
}
.basalt-alert-group-empty p {
	margin: 0;
}

/* Printed pages have nothing to animate. */
@media print {
	.basalt-alert,
	.basalt-alert-group-list > .alert {
		transition: none;
	}
}
