/*
 * Moving parts (ADR 0047), loaded with the elements that "require" this one.
 *
 * Carousel: the cards in one row that scrolls and snaps, as many in view as the element's columns
 * (--sv-carousel-per, set by each element for each screen size). view.js adds the arrows' and dots'
 * work and moving by itself; without it the row still swipes and scrolls.
 */
.sv-carousel {
	--sv-carousel-per: 3;
	/* Space between columns of the section it is in (ADR 0054), else Normal. */
	--sv-carousel-gap: var(--sv-colgap, var(--sv-space-md));
	position: relative;
	grid-column: 1 / -1;
	min-inline-size: 0;
}

.sv-carousel__track {
	display: flex;
	gap: var(--sv-carousel-gap);
	/*
	 * Room for shadows and lifted cards, which a scrolling row would cut off: a hover shadow reaches
	 * about 2.5rem below a card. The negative margins keep the row in its place.
	 */
	margin-block: -0.75rem -2.75rem;
	padding-block: 0.75rem 2.75rem;
	overflow-x: auto;
	overscroll-behavior-x: contain;
	scroll-behavior: smooth;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
}

.sv-carousel__track::-webkit-scrollbar {
	display: none;
}

.sv-carousel__track > * {
	flex: 0 0 calc((100% - (var(--sv-carousel-per) - 1) * var(--sv-carousel-gap)) / var(--sv-carousel-per));
	min-inline-size: 0;
	scroll-snap-align: start;
}

/* Arrows at the sides, half over the cards' edges; shown once view.js runs. */
.sv-carousel__arrow {
	position: absolute;
	inset-block-start: 50%;
	z-index: 1;
	display: none;
	place-items: center;
	inline-size: 2.75rem;
	block-size: 2.75rem;
	padding: 0;
	border: 1px solid var(--sv-color-border);
	border-radius: 50%;
	background: var(--sv-color-background);
	box-shadow: 0 6px 18px rgb(15 23 42 / 12%);
	color: var(--sv-color-text);
	cursor: pointer;
	translate: 0 -50%;
	transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, opacity 0.2s ease;
}

.sv-carousel--ready.sv-carousel--nav-arrows .sv-carousel__arrow {
	display: grid;
}

.sv-carousel__arrow--prev {
	inset-inline-start: -1.375rem;
}

.sv-carousel__arrow--next {
	inset-inline-end: -1.375rem;
}

.sv-carousel__arrow:hover {
	border-color: var(--sv-button-main-bg, var(--sv-color-primary));
	background: var(--sv-button-main-bg, var(--sv-color-primary));
	color: var(--sv-button-main-text, var(--sv-color-on-primary));
}

.sv-carousel__arrow:disabled {
	opacity: 0;
	pointer-events: none;
}

.sv-carousel__arrow svg {
	inline-size: 1.25rem;
	block-size: 1.25rem;
	fill: none;
	stroke: currentcolor;
	stroke-linecap: round;
	stroke-linejoin: round;
	stroke-width: 2;
}

[dir="rtl"] .sv-carousel__arrow svg {
	scale: -1 1;
}

/*
 * Arrows at the top (ADR 0063): both at the end of the line above the cards — beside a section's
 * heading when there is one — smaller, and dimmed rather than gone at the ends.
 */
.sv-carousel--nav-top {
	padding-block-start: 3.25rem;
}

.sv-carousel--ready.sv-carousel--nav-top .sv-carousel__arrow {
	display: grid;
}

.sv-carousel.sv-carousel--nav-top .sv-carousel__arrow {
	inset-block-start: 0;
	inline-size: 2.5rem;
	block-size: 2.5rem;
	box-shadow: none;
	translate: none;
}

.sv-carousel.sv-carousel--nav-top .sv-carousel__arrow--prev {
	inset-inline: auto 3.1rem;
}

.sv-carousel.sv-carousel--nav-top .sv-carousel__arrow--next {
	inset-inline-end: 0;
}

.sv-carousel.sv-carousel--nav-top .sv-carousel__arrow:disabled {
	opacity: 0.35;
}

/* Under a section heading: on the heading's line, and the heading keeps clear of them. */
:where(.sv-sectionhead) + .sv-posts > .sv-carousel--nav-top {
	padding-block-start: 0;
}

:where(.sv-sectionhead) + .sv-posts > .sv-carousel--nav-top .sv-carousel__arrow {
	inset-block-start: calc(-1 * (var(--sv-space-md) + 2.5rem));
}

.sv-sectionhead:has(+ .sv-posts > .sv-carousel--nav-top) {
	padding-inline-end: 6.5rem;
}

/*
 * Arrows below (ADR 0087): under the cards, at the end of the line or centered, the size of the
 * top arrows and dimmed rather than gone at the ends.
 */
.sv-carousel:is(.sv-carousel--nav-below-end, .sv-carousel--nav-below-center) {
	padding-block-end: calc(2.5rem + var(--sv-space-sm));
}

.sv-carousel--ready:is(.sv-carousel--nav-below-end, .sv-carousel--nav-below-center) .sv-carousel__arrow {
	display: grid;
}

.sv-carousel:is(.sv-carousel--nav-below-end, .sv-carousel--nav-below-center) .sv-carousel__arrow {
	inset-block: auto 0;
	inline-size: 2.5rem;
	block-size: 2.5rem;
	box-shadow: none;
	translate: none;
}

.sv-carousel.sv-carousel--nav-below-end .sv-carousel__arrow--prev {
	inset-inline: auto 3.1rem;
}

.sv-carousel.sv-carousel--nav-below-end .sv-carousel__arrow--next {
	inset-inline: auto 0;
}

.sv-carousel.sv-carousel--nav-below-center .sv-carousel__arrow--prev {
	inset-inline: auto calc(50% + 0.3rem);
}

.sv-carousel.sv-carousel--nav-below-center .sv-carousel__arrow--next {
	inset-inline: calc(50% + 0.3rem) auto;
}

.sv-carousel:is(.sv-carousel--nav-below-end, .sv-carousel--nav-below-center) .sv-carousel__arrow:disabled {
	opacity: 0.35;
}

/*
 * Dots under the cards (made by view.js, ADR 0091): round dots in a soft pill, centered; the current one in
 * the accent color. Each dot keeps a 24px tap area.
 */
.sv-carousel__dots {
	display: flex;
	inline-size: fit-content;
	max-inline-size: 100%;
	flex-wrap: wrap;
	justify-content: center;
	margin-block-start: var(--sv-space-sm);
	margin-inline: auto;
	padding: 0.125rem 0.25rem;
	border-radius: 999px;
	background: color-mix(in srgb, var(--sv-color-text) 7%, transparent);
}

.sv-carousel__dot {
	display: grid;
	place-items: center;
	inline-size: 1.5rem;
	block-size: 1.5rem;
	padding: 0;
	border: 0;
	background: none;
	cursor: pointer;
}

.sv-carousel__dot::before {
	inline-size: 0.5rem;
	block-size: 0.5rem;
	border-radius: 999px;
	background: color-mix(in srgb, var(--sv-color-text) 22%, transparent);
	content: "";
	transition: background-color 0.3s ease;
}

.sv-carousel__dot[aria-current="true"]::before {
	background: var(--sv-accent, var(--sv-color-primary));
}

/* Gliding by itself (view.js, ADR 0087): the row moves freely, so it doesn't snap to a card. */
.sv-carousel--gliding .sv-carousel__track {
	scroll-snap-type: none;
	scroll-behavior: auto;
}

/* Everything in view: no arrows, no dots. */
.sv-carousel--still .sv-carousel__arrow[class],
.sv-carousel--still .sv-carousel__dots {
	display: none;
}

@media (max-width: 767px) {
	.sv-carousel__arrow--prev {
		inset-inline-start: 0.25rem;
	}

	.sv-carousel__arrow--next {
		inset-inline-end: 0.25rem;
	}
}

/*
 * Endless row (ADR 0047): two copies of the same items side by side, each at least as wide as the
 * element, slide by their own width and start again, so the row never ends. They travel in the
 * reading direction (new items come in at the end side); Reverse turns them; pointing pauses them.
 * Visitors who ask for less motion see one copy, wrapped.
 */
.sv-marquee {
	--sv-marquee-duration: 40s;
	--sv-marquee-gap: var(--sv-space-md);
	position: relative;
	display: flex;
	/* Clipped, not scrollable: focusing a link in the row (or its pause button) never shifts it sideways (ADR 0102). */
	overflow: clip;
}

.sv-marquee--slow {
	--sv-marquee-duration: 64s;
}

.sv-marquee--fast {
	--sv-marquee-duration: 24s;
}

.sv-marquee__copy {
	display: flex;
	flex: none;
	gap: var(--sv-marquee-gap);
	align-items: center;
	justify-content: space-around;
	min-inline-size: 100%;
	margin: 0;
	padding: 0;
	padding-inline-end: var(--sv-marquee-gap);
	list-style: none;
	animation: sv-marquee var(--sv-marquee-duration) linear infinite;
}

[dir="rtl"] .sv-marquee__copy {
	animation-name: sv-marquee-rtl;
}

.sv-marquee--reverse .sv-marquee__copy {
	animation-direction: reverse;
}

/*
 * Pointing pauses it unless it should never stop (ADR 0087); keyboard focus on what it shows always does.
 * The pause button (ADR 0102) stops it until pressed again; pointing at or focusing the button itself
 * doesn't count, so pressing Play starts it at once.
 */
.sv-marquee:not(.sv-marquee--nonstop):hover:not(:has(> .sv-pause:hover)) .sv-marquee__copy,
.sv-marquee:has(> .sv-marquee__copy:focus-within) .sv-marquee__copy,
.sv-marquee--paused .sv-marquee__copy {
	animation-play-state: paused;
}

/*
 * The pause button, added by view.js at the row's end (ADR 0102): small and quiet, a soft tint of the
 * text color with the row blurred behind it, so it reads on any background. Pressed, it shows Play.
 */
.sv-pause {
	position: absolute;
	inset-block-start: 50%;
	inset-inline-end: 0.5rem;
	z-index: 2;
	display: grid;
	place-items: center;
	inline-size: 2rem;
	block-size: 2rem;
	padding: 0;
	border: 1px solid color-mix(in srgb, currentColor 22%, transparent);
	border-radius: 50%;
	background-color: color-mix(in srgb, currentColor 10%, transparent);
	color: var(--sv-color-text);
	cursor: pointer;
	opacity: 0.8;
	translate: 0 -50%;
	-webkit-backdrop-filter: blur(8px);
	backdrop-filter: blur(8px);
	transition: opacity 0.2s ease;
}

.sv-pause:is(:hover, :focus-visible) {
	opacity: 1;
}

.sv-pause::before {
	inline-size: 0.75rem;
	block-size: 0.75rem;
	background-color: currentColor;
	content: "";
	-webkit-mask: var(--sv-pause-glyph) center / contain no-repeat;
	mask: var(--sv-pause-glyph) center / contain no-repeat;
	--sv-pause-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Crect x='2' y='1.5' width='2.6' height='9' rx='0.8'/%3E%3Crect x='7.4' y='1.5' width='2.6' height='9' rx='0.8'/%3E%3C/svg%3E");
}

.sv-pause[aria-pressed="true"]::before {
	--sv-pause-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 1.8v8.4a.7.7 0 0 0 1.06.6l6.8-4.2a.7.7 0 0 0 0-1.2L4.06 1.2A.7.7 0 0 0 3 1.8z'/%3E%3C/svg%3E");
}

/* The play triangle points along the reading direction. */
[dir="rtl"] .sv-pause[aria-pressed="true"]::before {
	scale: -1 1;
}

@keyframes sv-marquee {
	to {
		translate: -100% 0;
	}
}

@keyframes sv-marquee-rtl {
	to {
		translate: 100% 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.sv-carousel__track {
		scroll-behavior: auto;
	}

	.sv-marquee,
	.sv-marquee__copy {
		flex-wrap: wrap;
	}

	.sv-marquee__copy {
		flex: 1 1 100%;
		animation: none;
	}

	.sv-marquee__copy[aria-hidden="true"],
	.sv-pause {
		display: none;
	}
}
