/**
 * Advanced Accordion / FAQ
 *
 * The open/close animation uses a grid row transition, not a measured height.
 * That is deliberate:
 *
 * - No JS measures scrollHeight, so there is no resize listener, no font-load
 *   reflow and no stale cached height.
 * - The panel animates to whatever the content actually is, so long answers
 *   and localized text do not clip.
 * - Reduced motion and RTL need no special casing.
 *
 * `min-height: 0` on the content is what makes the collapse possible; without
 * it the grid item refuses to shrink below its content size.
 */

.fast-accordion {
	--fast-acc-transition: 0.3s ease-out;
	--fast-acc-icon-size: 1em;
	--fast-acc-title-color: inherit;
	--fast-acc-content-color: inherit;
	--fast-acc-bg: transparent;
	--fast-acc-active-bg: transparent;
	--fast-acc-active-title-color: inherit;
	--fast-acc-active-border-color: transparent;
	--fast-acc-border-width: 0;
	--fast-acc-border-color: transparent;
	--fast-acc-radius: 0;
	--fast-acc-title-gap: 0.5em;
	--fast-acc-content-bg: transparent;
	--fast-acc-content-padding: 0;
	--fast-acc-content-radius: 0;
	--fast-acc-content-border-width: 0;
	--fast-acc-content-border-color: transparent;
	--fast-acc-item-gap: 0;
	--fast-acc-item-radius: 0;
	--fast-acc-separator-color: currentColor;
	--fast-acc-active-icon-color: currentColor;

	display: flex;
	flex-direction: column;
	gap: var( --fast-acc-item-gap );
}

/**
 * Each row.
 */
.fast-accordion__item {
	border-radius: var( --fast-acc-item-radius );
	overflow: hidden;
}

/**
 * Heading wrapper.
 *
 * `margin: 0` matters: a default h3 margin would push the trigger out of the
 * gap rhythm and break the item spacing control.
 */
.fast-accordion__heading {
	margin: 0;
	font: inherit;
	color: inherit;
}

/**
 * The clickable header.
 *
 * A real button, so Enter and Space work and screen readers announce the
 * expanded state without any key handler. `width: 100%` plus flex lets the
 * icon sit on either edge.
 */
.fast-accordion__trigger {
	display: flex;
	align-items: center;
	gap: var( --fast-acc-title-gap );
	width: 100%;
	margin: 0;
	padding: 0;
	background: var( --fast-acc-bg );
	color: var( --fast-acc-title-color );
	border: var( --fast-acc-border-width ) solid var( --fast-acc-border-color );
	border-radius: var( --fast-acc-radius );
	font: inherit;
	text-align: inherit;
	cursor: pointer;
	transition: background-color var( --fast-acc-transition ),
		color var( --fast-acc-transition ),
		border-color var( --fast-acc-transition );
}

.fast-accordion--icon-right .fast-accordion__trigger {
	flex-direction: row-reverse;
	justify-content: flex-end;
}

.fast-accordion--icon-right .fast-accordion__title {
	margin-left: auto;
}

/**
 * Icon slot.
 *
 * Both glyphs stay in the DOM and CSS picks the visible one. That keeps the
 * open/close transition free of any DOM mutation.
 */
.fast-accordion__icon {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: var( --fast-acc-icon-size );
	height: var( --fast-acc-icon-size );
	font-size: var( --fast-acc-icon-size );
	color: var( --fast-acc-active-icon-color );
	transition: transform var( --fast-acc-transition ),
		color var( --fast-acc-transition );
}

.fast-accordion__icon-closed,
.fast-accordion__icon-open {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
}

/**
 * Closed state shows the closed glyph.
 */
.fast-accordion__icon-open {
	display: none;
}

.fast-accordion__item.is-active .fast-accordion__icon-closed {
	display: none;
}

.fast-accordion__item.is-active .fast-accordion__icon-open {
	display: inline-flex;
}

/**
 * Title.
 */
.fast-accordion__title {
	flex: 1 1 auto;
	min-width: 0;
}

/**
 * The animated row.
 *
 * This is the whole animation. `0fr` to `1fr` is animatable because the row
 * sizes are interpolatable, unlike `height: auto`.
 */
.fast-accordion__content-wrapper {
	display: grid;
	grid-template-rows: 0fr;
	transition: grid-template-rows var( --fast-acc-transition );
}

.fast-accordion__item.is-active .fast-accordion__content-wrapper {
	grid-template-rows: 1fr;
}

/**
 * The collapsible cell.
 *
 * `overflow: hidden` is the child that actually clips. `min-height: 0` lets it
 * shrink below the content height, which is the part that is easy to forget.
 */
.fast-accordion__content {
	overflow: hidden;
	min-height: 0;
	background: var( --fast-acc-content-bg );
	color: var( --fast-acc-content-color );
	padding: var( --fast-acc-content-padding );
	border: var( --fast-acc-content-border-width ) solid var( --fast-acc-content-border-color );
	border-radius: var( --fast-acc-content-radius );
}

/**
 * Active state.
 */
.fast-accordion__item.is-active > .fast-accordion__heading > .fast-accordion__trigger {
	background: var( --fast-acc-active-bg );
	color: var( --fast-acc-active-title-color );
	border-color: var( --fast-acc-active-border-color );
}

.fast-accordion__item.is-active .fast-accordion__title {
	color: var( --fast-acc-active-title-color );
}

/**
 * Visible focus.
 *
 * Only for keyboard users; a mouse click should not draw a ring.
 */
.fast-accordion__trigger:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}

/**
 * Reduced motion.
 *
 * The state still changes instantly, it just does not travel. Keeping the
 * transition here rather than in JS means there is nothing to unhook.
 */
@media (prefers-reduced-motion: reduce) {
	.fast-accordion__content-wrapper,
	.fast-accordion__trigger,
	.fast-accordion__icon {
		transition-duration: 0.01ms;
	}
}
