/**
 * Notifications
 * @file notifications.css
 * @description The stack of on-screen notifications. Top right on a desktop,
 *              where it sits clear of the page; along the bottom on a phone,
 *              where the top of the screen belongs to the header and the
 *              thumb is nearer the bottom anyway.
 */

.notify-stack {
	position: fixed;
	inset-block-start: 4.75rem;
	inset-inline-end: 20px;
	z-index: 1080;
	display: flex;
	flex-direction: column;
	width: min(380px, calc(100vw - 40px));
	max-height: calc(100vh - 40px);
	overflow-y: auto;
	scrollbar-width: none;
	pointer-events: none;
}

.notify-stack::-webkit-scrollbar {
	display: none;
}

.notify {
	position: relative;
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: start;
	gap: 12px;
	margin-block-end: 12px;
	padding: 14px 14px 15px;
	border: 1px solid var(--border-color);
	border-radius: 14px;
	background-color: var(--white);
	box-shadow: 0 12px 30px rgba(15, 23, 42, 0.16);
	overflow: hidden;
	pointer-events: auto;
	/* Entrance: in from the edge it belongs to */
	opacity: 0;
	transform: translateX(24px) scale(0.98);
	transition:
		opacity 0.26s cubic-bezier(0.21, 1, 0.4, 1),
		transform 0.26s cubic-bezier(0.21, 1, 0.4, 1),
		height 0.26s ease,
		margin 0.26s ease;
}

.notify.is-shown {
	opacity: 1;
	transform: translateX(0) scale(1);
}

/* Leaving reverses the arrival, and the height going to zero is what makes the
   notifications underneath slide up rather than snap */
.notify.is-leaving {
	opacity: 0;
	transform: translateX(24px) scale(0.98);
	padding-block: 0;
	border-width: 0;
}

/* The colour runs down the edge it opens from */
.notify::before {
	content: '';
	position: absolute;
	inset-block: 0;
	inset-inline-start: 0;
	width: 4px;
	background-color: var(--notify-tone);
}

.notify__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	margin-inline-start: 4px;
	border-radius: 11px;
	background-color: var(--neutral-100);
	color: var(--notify-tone);
	font-size: 1.125rem;
	line-height: 1;
	flex-shrink: 0;
}

@supports (background-color: color-mix(in srgb, red 10%, transparent)) {
	.notify__icon {
		background-color: color-mix(in srgb, var(--notify-tone) 16%, transparent);
	}
}

.notify__text {
	display: flex;
	flex-direction: column;
	gap: 3px;
	min-width: 0;
	padding-block-start: 2px;
}

/* The type, read before the sentence is */
.notify__title {
	color: var(--text-primary-light);
	font-size: 0.8125rem;
	font-weight: 700;
	line-height: 1.3;
}

/* The message wraps rather than truncating - a notification that cannot be
   read in full is not worth showing */
.notify__message {
	color: var(--text-secondary-light);
	font-size: 0.8125rem;
	font-weight: 500;
	line-height: 1.5;
	overflow-wrap: anywhere;
}

.notify__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	padding: 0;
	border: 0;
	border-radius: 8px;
	background-color: transparent;
	color: var(--text-secondary-light);
	font-size: 1rem;
	line-height: 1;
	flex-shrink: 0;
	opacity: 0.7;
	transition:
		background-color 0.16s ease,
		color 0.16s ease,
		opacity 0.16s ease;
}

.notify__close:hover,
.notify__close:focus-visible {
	background-color: var(--neutral-100);
	color: var(--text-primary-light);
	opacity: 1;
}

/* How long is left, drawn along the bottom edge. It is the timer made visible,
   which is also what makes pausing on hover legible. */
.notify__life {
	position: absolute;
	inset-block-end: 0;
	inset-inline: 0;
	height: 3px;
	background-color: var(--neutral-100);
}

.notify__life > span {
	display: block;
	height: 100%;
	background-color: var(--notify-tone);
	transform: scaleX(1);
	transform-origin: left center;
}

/* === one tone per type =================================================== */
.notify {
	--notify-tone: var(--primary-600);
}

.notify--success {
	--notify-tone: var(--success-main);
}

.notify--danger {
	--notify-tone: var(--danger-main);
}

.notify--warning {
	--notify-tone: var(--warning-main);
}

.notify--info {
	--notify-tone: var(--info-600);
}

/* === on a phone ========================================================== */
/* The top of the screen is the header's, so the stack moves to the bottom and
   takes the width - a 380px card floating over a 360px screen is not a card,
   it is a wall. Newest sits at the bottom, nearest the thumb. */
@media (max-width: 575.98px) {
	.notify-stack {
		inset-block-start: auto;
		inset-block-end: 12px;
		inset-inline: 12px;
		flex-direction: column-reverse;
		width: auto;
		/* However many arrive at once, the page keeps most of the screen; past
		   this the stack scrolls rather than growing over the content */
		max-height: 60vh;
		overflow-y: auto;
		scrollbar-width: none;
	}

	.notify-stack::-webkit-scrollbar {
		display: none;
	}

	.notify {
		margin-block-end: 0;
		margin-block-start: 10px;
		padding: 12px;
		border-radius: 12px;
		transform: translateY(16px) scale(0.98);
	}

	.notify.is-shown {
		transform: translateY(0) scale(1);
	}

	.notify.is-leaving {
		transform: translateY(16px) scale(0.98);
	}

	.notify__icon {
		width: 30px;
		height: 30px;
		border-radius: 10px;
		font-size: 1rem;
	}
}

@media (prefers-reduced-motion: reduce) {
	.notify {
		transition: opacity 0.01ms, height 0.01ms, margin 0.01ms;
		transform: none;
	}

	.notify.is-shown,
	.notify.is-leaving {
		transform: none;
	}

	/* The bar still empties, it just does not glide */
	.notify__life > span {
		transition: none !important;
	}
}
