/*
 * Interaction library — structural CSS only. Colours, type and spacing belong
 * to the block's style.css; this file makes the primitives FUNCTION.
 *
 * html.aisa-js     JavaScript runs and the visitor allows motion
 * html.aisa-ready  the library has booted (set by interact/index.mjs)
 */

/* --- reveal: hidden first, ONLY when JS + motion; fail-safe after 3s ---- */
html.aisa-js [data-aisa-reveal]:not(.is-in) {
	opacity: 0;
}
html.aisa-js [data-aisa-reveal="fade-up"]:not(.is-in) {
	transform: translateY(24px);
}
html.aisa-js [data-aisa-reveal="scale"]:not(.is-in) {
	transform: scale(0.94);
}
html.aisa-js [data-aisa-reveal="clip"]:not(.is-in) {
	clip-path: inset(0 0 100% 0);
}
/* The library never booted (a script threw at load): reveal everything. */
html.aisa-js:not(.aisa-ready) [data-aisa-reveal]:not(.is-in) {
	animation: aisa-failsafe 1ms 3s forwards;
}
@keyframes aisa-failsafe {
	to {
		opacity: 1;
		transform: none;
		clip-path: none;
	}
}
/* A prepared element whose reveal never fired (aisa.mjs prepare()). */
.aisa-failsafe {
	opacity: 1 !important;
	transform: none !important;
	clip-path: none !important;
	visibility: visible !important;
}

/* --- dismiss --------------------------------------------------------- */
[data-aisa-dismiss].is-dismissed {
	display: none;
}

/* --- toggle / tabs: hidden panels leave the tree ---------------------- */
[data-aisa-toggle-panel][hidden],
[data-aisa-panel][hidden] {
	display: none;
}
/*
 * NO layout for the tab list. It used to be laid out here as a wrapping flex
 * row with a 0.25rem gap, and that was this file breaking its own contract:
 * flex-wrap and a gap make nothing FUNCTION, they pick a look, and the look
 * was arbitrary. It also could not be overridden the obvious way —
 * `[data-aisa-tabs] [role="tablist"]` is (0,2,0), exactly a two-class block
 * selector, and this stylesheet is enqueued after every block's, so a block
 * asking for `display: grid` on its own tab list tied and lost on source
 * order. Silently: valid CSS, right file, discarded by the browser, and at
 * 1440px a wrapping row of five looked just like the two-column grid that was
 * asked for (lesson 67). The block owns the layout of its own markup; with no
 * rule here the buttons simply flow inline, which is a fine no-CSS default.
 */
[data-aisa-tab] {
	cursor: pointer;
}

/* --- marquee ----------------------------------------------------------- */
.aisa-marquee {
	display: flex;
	overflow: hidden;
	-webkit-mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
	mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
}
.aisa-marquee__track {
	display: flex;
	align-items: center;
	flex: 0 0 auto;
	gap: var(--aisa-marquee-gap, 3rem);
	margin: 0;
	/* padding-INLINE too, not just block: a track is usually a <ul>, and the
	   browser's own 40px list indent lands between one copy and the next. The
	   seam measured 62px against a 22px item gap for exactly this reason, and
	   the first item of the strip started 40px in from where it should. */
	padding: 0;
	list-style: none;
}
/* The seam between one copy and the next. It has to equal the gap BETWEEN
   ITEMS or the strip visibly stutters once per loop, so the value is measured
   from the track by the script and written here — and the fallback is zero,
   not a guess: a constant fallback wins the race against the block's own
   stylesheet on first paint and bakes in a seam the design never had. With no
   script there are no copies and so no seam to size. */
.aisa-marquee > .aisa-marquee__track {
	margin-inline-end: var(--aisa-marquee-gap, 0px);
}
.aisa-marquee.is-running > .aisa-marquee__track {
	animation: aisa-marquee var(--aisa-marquee-duration, 30s) linear infinite;
}
.aisa-marquee.is-running.is-reverse > .aisa-marquee__track {
	animation-direction: reverse;
}
.aisa-marquee.is-running:hover > .aisa-marquee__track,
.aisa-marquee.is-running:focus-within > .aisa-marquee__track {
	animation-play-state: paused;
}
.aisa-marquee.is-static {
	overflow-x: auto;
	mask-image: none;
	-webkit-mask-image: none;
}
/*
 * The travel must be the LAYOUT stride, not the track's own width. A copy sits
 * one width PLUS one seam away from the copy before it (margin-inline-end
 * above), but translateX(-100%) resolves against the element's own border box
 * and so stops one gap short: every loop the strip lurched forward by exactly
 * the gap, and — because AISA_Interact sizes the duration for (width + gap) —
 * ran fractionally slow the rest of the time to pay for it. Measured on a real
 * strip before the fix: stride 625px, travel 576px, a 49px jump per cycle.
 */
@keyframes aisa-marquee {
	to {
		transform: translateX(calc(-100% - var(--aisa-marquee-gap, 0px)));
	}
}

/* --- carousel ---------------------------------------------------------- */
.aisa-carousel {
	position: relative;
}
.aisa-carousel__track {
	display: flex;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
	gap: var(--aisa-carousel-gap, 1.5rem);
	margin: 0;
	padding: 0;
	list-style: none;
	cursor: grab;
}
.aisa-carousel__track::-webkit-scrollbar {
	display: none;
}
.aisa-carousel__track.is-dragging {
	cursor: grabbing;
	scroll-snap-type: none;
	user-select: none;
}
/*
 * Snapping stays off while the released drag animates to its slide. Restore it
 * at the moment of release and the browser snaps instantly from wherever the
 * hand let go, which is the jump this class exists to prevent.
 */
.aisa-carousel__track.is-settling {
	scroll-snap-type: none;
}
.aisa-carousel__track:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 4px;
}
.aisa-carousel__slide {
	flex: 0 0 calc((100% - (var(--aisa-per-view, 1) - 1) * var(--aisa-carousel-gap, 1.5rem)) / var(--aisa-per-view, 1));
	scroll-snap-align: start;
	min-width: 0;
}
.aisa-carousel__track[data-per-view="1"] { --aisa-per-view: 1; }
.aisa-carousel__track[data-per-view="2"] { --aisa-per-view: 2; }
.aisa-carousel__track[data-per-view="3"] { --aisa-per-view: 3; }
.aisa-carousel__track[data-per-view="4"] { --aisa-per-view: 4; }
@media (max-width: 1023px) {
	.aisa-carousel__track[data-per-view="3"],
	.aisa-carousel__track[data-per-view="4"] { --aisa-per-view: 2; }
}
@media (max-width: 767px) {
	.aisa-carousel__track[data-per-view] { --aisa-per-view: 1; }
}

/*
 * per-view="auto": the BLOCK sizes its own slides. Everything here is driven by
 * --aisa-slide-width, which the block sets on the carousel root, so the block
 * never has to out-specify this stylesheet — the enqueue order between a block's
 * style handle and this file is not something either side should have to know
 * (lesson 61: a cascade claim is a measurement, so do not create the question).
 * The selectors carry the attribute purely so they beat the tiled rules above
 * regardless of source order.
 *
 * The inline padding is what lets the FIRST and LAST slide reach the centre;
 * without it a centred carousel can never show slide one centred, which reads
 * as the track being stuck.
 */
.aisa-carousel__track[data-per-view="auto"] {
	/* The fallback lives in the var() call, never as a declaration here: setting
	   the property ON the track would beat the value the block set on the root
	   and inheritance would carry nothing. */
	padding-inline: max(0px, calc((100% - var(--aisa-slide-width, min(100%, 34rem))) / 2));
	scroll-padding-inline: max(0px, calc((100% - var(--aisa-slide-width, min(100%, 34rem))) / 2));
}
.aisa-carousel__track[data-per-view="auto"] > .aisa-carousel__slide {
	flex: 0 0 var(--aisa-slide-width, min(100%, 34rem));
	scroll-snap-align: center;
}
/*
 * A looped track has cloned slides either side, so it needs no padding to bring
 * its first and last into the middle — the padding IS the empty space beside
 * card one that a peek layout is trying not to have.
 */
.aisa-carousel__track[data-looped] {
	padding-inline: 0;
	scroll-padding-inline: 0;
}

/*
 * A control the design drew stays where the design put it; only its state
 * changes. aria-disabled is set on non-button elements, which get no :disabled.
 */
.aisa-carousel [data-aisa-carousel-prev].is-disabled,
.aisa-carousel [data-aisa-carousel-next].is-disabled {
	opacity: 0.35;
	pointer-events: none;
}
.aisa-carousel__nav {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 1rem;
	margin-top: 1.25rem;
}
.aisa-carousel__btn {
	inline-size: 2.75rem;
	block-size: 2.75rem;
	border-radius: 999px;
	border: 1px solid currentColor;
	background: transparent;
	color: inherit;
	cursor: pointer;
	display: grid;
	place-items: center;
	padding: 0;
}
.aisa-carousel__btn::before {
	content: "";
	inline-size: 0.6rem;
	block-size: 0.6rem;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: rotate(-45deg) translate(-1px, -1px);
}
.aisa-carousel__btn--prev::before {
	transform: rotate(135deg) translate(-1px, -1px);
}
.aisa-carousel__btn:disabled {
	opacity: 0.35;
	cursor: default;
}
.aisa-carousel__btn:focus-visible,
.aisa-carousel__dot:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}
.aisa-carousel__dots {
	display: flex;
	gap: 0.5rem;
}
.aisa-carousel__dot {
	inline-size: 0.6rem;
	block-size: 0.6rem;
	padding: 0;
	border-radius: 999px;
	border: 0;
	background: currentColor;
	opacity: 0.3;
	cursor: pointer;
}
.aisa-carousel__dot.is-active {
	opacity: 1;
}

/* --- modal --------------------------------------------------------------- */
dialog[data-aisa-modal] {
	border: 0;
	padding: 0;
	max-inline-size: min(90vw, 40rem);
	background: var(--wp--preset--color--base, #fff);
	color: var(--wp--preset--color--contrast, #000);
}
dialog[data-aisa-modal]::backdrop {
	background: rgba(0, 0, 0, 0.6);
}

/* --- sticky header --------------------------------------------------------- */
.aisa-sticky-header {
	position: sticky;
	top: 0;
	z-index: 50;
	transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.aisa-sticky-header.is-scrolled {
	box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08);
}
.aisa-sticky-header.is-hidden {
	transform: translateY(-100%);
}
@media (prefers-reduced-motion: reduce) {
	.aisa-sticky-header {
		transition: none;
	}
}
