/* Qaiyo Content Slider Pro — extra layouts.
   Loaded only on pages that actually render one of these layouts (the free
   plugin enqueues the handle for the active layout only). */

/* The free stylesheet paints an autoplay progress fill into the active
   indicator; these layouts use round dots, which must stay plain. */
[data-layout="accordion"] .qcs-indicator-active::after,
[data-layout="cardstack"] .qcs-indicator-active::after,
[data-layout="featurecards"] .qcs-indicator-active::after,
[data-layout="splithero"] .qcs-indicator-active::after {
	display: none !important;
}

/* =========================================================================
   Accordion — a row of tall cards, all visible at once. The active card
   reveals its heading + text + button in a bottom card; the inactive cards
   show only their heading in a slim bottom bar. The JS runtime translates the
   track so the active card is pinned to the left.
   ========================================================================= */
[data-layout="accordion"].qcs-slider {
	background: transparent;
	border-radius: 0;
	overflow: visible;
	padding-bottom: 60px;
}

[data-layout="accordion"] .qcs-slides {
	position: relative;
	display: flex;
	gap: 18px;
	align-items: stretch;
	overflow: hidden;
	border-radius: 0;
	min-height: var(--qcs-min-height, 480px);
	transition: transform 0.55s cubic-bezier(0.16, 1, 0.3, 1);
	will-change: transform;
}

[data-layout="accordion"] .qcs-slide {
	position: relative;
	inset: auto;
	flex: 0 0 30%;
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	border-radius: var( --qcs-radius, 16px );
	overflow: hidden;
	/* Neutralise the free fade / slide transition engine — the track moves. */
	transform: none !important;
}

/* Bottom scrim for text legibility (replaces the left overlay gradient). */
[data-layout="accordion"] .qcs-slide::after {
	background: linear-gradient(to top, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 55%);
}

/* Inactive card: heading-only bar anchored to the bottom, full width. */
[data-layout="accordion"] .qcs-slide-box {
	position: absolute;
	inset: auto 16px 16px 16px;
	width: auto;
	max-width: none;
	margin: 0;
	padding: 13px 18px;
	border-radius: 12px;
	background: rgba(20, 21, 26, 0.55);
	color: #ffffff;
	box-shadow: none;
	transition: background 0.35s ease, padding 0.35s ease;
}

[data-layout="accordion"] .qcs-slide-heading {
	color: var( --qcs-heading-color, #ffffff );
	font-size: var( --qcs-heading-size, 1.35em );
}

[data-layout="accordion"] .qcs-slide-text {
	color: var( --qcs-text-color, rgba(255, 255, 255, 0.82) );
}

/* Inactive cards hide the description + CTA; only the heading shows. */
[data-layout="accordion"] .qcs-slide:not(.qcs-slide-active) .qcs-slide-text,
[data-layout="accordion"] .qcs-slide:not(.qcs-slide-active) .qcs-cta {
	display: none;
}

[data-layout="accordion"] .qcs-slide:not(.qcs-slide-active) .qcs-slide-heading {
	margin: 0;
}

/* Active card: a taller text card at the bottom, honouring box position. */
[data-layout="accordion"] .qcs-slide-active .qcs-slide-box {
	right: auto;
	max-width: 78%;
	padding: 20px 22px;
	background: rgba(18, 19, 24, 0.62);
}

[data-layout="accordion"] .qcs-slide-active[data-position="right"] .qcs-slide-box {
	left: auto;
	right: 16px;
}

/* Dot indicators bottom-left; arrows in the band bottom-right. */
[data-layout="accordion"] .qcs-indicators {
	top: auto;
	bottom: 20px;
	left: 4px;
	right: auto;
	justify-content: flex-start;
}

[data-layout="accordion"] .qcs-indicator {
	flex: 0 0 auto;
	width: 8px;
	height: 8px;
	min-width: 0;
	border-radius: 50%;
	background: rgba(20, 21, 26, 0.28);
}

[data-layout="accordion"] .qcs-indicator-active {
	background: #1d2327;
}

[data-layout="accordion"] .qcs-controls {
	top: auto;
	bottom: 8px;
	right: 4px;
	left: auto;
}

/* Thin closing rule above the controls band. */
[data-layout="accordion"].qcs-slider::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 52px;
	height: 1px;
	background: rgba(0, 0, 0, 0.1);
}

/* Arrows sit on the light page background here — dark outline, not white. */
[data-layout="accordion"] .qcs-arrow {
	background: var( --qcs-arrow-bg, #ffffff );
	border: 1px solid #d1d5db;
	color: var( --qcs-arrow-color, #1d2327 );
}

[data-layout="accordion"] .qcs-arrow:hover,
[data-layout="accordion"] .qcs-arrow:focus {
	background: var( --qcs-arrow-bg, #f3f4f6 );
}

/* Peeking cards are clickable/focusable to expand. */
[data-layout="accordion"] .qcs-slide:not(.qcs-slide-active) {
	cursor: pointer;
}

[data-layout="accordion"] .qcs-slide:not(.qcs-slide-active):focus-visible {
	outline: 3px solid var(--qcsp-fc-accent, #6c5ce7);
	outline-offset: -3px;
}

/* =========================================================================
   Card deck — a stacked deck of quote cards. The front card is fully
   visible; the ones behind peek out lower and narrower. On advance the front
   card animates away (up + fade) and the next comes forward.
   ========================================================================= */
[data-layout="cardstack"].qcs-slider {
	background: transparent;
	border-radius: 0;
	overflow: visible;
	padding-bottom: 96px;
}

[data-layout="cardstack"] .qcs-slides {
	position: relative;
	overflow: visible;
	min-height: var(--qcs-min-height, 460px);
}

[data-layout="cardstack"] .qcs-slide {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
	gap: 22px;
	padding: 48px 56px;
	box-sizing: border-box;
	background: var( --qcs-slide-bg, var(--qcsp-fc-surface, #ffffff) );
	border-radius: var( --qcs-radius, 24px );
	box-shadow: 0 18px 50px rgba(19, 22, 40, 0.12);
	transform-origin: center top;
	transition: transform 0.55s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.45s ease;
	will-change: transform, opacity;
}

/* No image-overlay gradient inside a card. */
[data-layout="cardstack"] .qcs-slide::after {
	display: none;
}

/* The front card lifts up and fades on a forward advance. */
[data-layout="cardstack"] .qcs-slide.qcs-slide-leaving {
	transform: translateY(-32px) scale(1.04) !important;
	opacity: 0 !important;
}

/* Logo: a small, contained mark at the top (not a full-bleed image). */
[data-layout="cardstack"] .qcs-slide-media {
	position: relative;
	inset: auto;
	overflow: visible;
	flex: 0 0 auto;
	width: auto;
}

[data-layout="cardstack"] .qcs-slide-img {
	width: auto;
	max-width: 220px;
	max-height: 64px;
	height: auto;
	object-fit: contain;
	margin: 0 auto;
}

/* Divider under the logo. */
[data-layout="cardstack"] .qcs-slide-box::before {
	content: "";
	display: block;
	width: 30%;
	min-width: 120px;
	height: 1px;
	margin: 0 auto 26px;
	background: var(--qcsp-fc-border, #e5e7eb);
}

/* The card body is a plain centred column, no floating-box chrome. */
[data-layout="cardstack"] .qcs-slide-box {
	position: static;
	z-index: auto;
	width: 100%;
	max-width: none;
	margin: 0;
	padding: 0;
	border-radius: 0;
	background: transparent;
	box-shadow: none;
	color: inherit;
}

[data-layout="cardstack"] .qcs-slide-heading {
	font-size: var( --qcs-heading-size, clamp(1.5em, 2.4vw, 2.1em) );
	line-height: 1.25;
	font-weight: 800;
	color: var( --qcs-heading-color, var(--qcsp-fc-text, #1a1c2e) );
	margin: 0 0 20px;
}

[data-layout="cardstack"] .qcs-slide-text {
	font-size: var( --qcs-text-size, 1.05em );
	font-weight: 600;
	color: var( --qcs-text-color, var(--qcsp-fc-muted, #8a8f9c) );
	margin: 0 0 26px;
}

[data-layout="cardstack"] .qcs-slide-text::before {
	content: "\2014\00a0";
}

[data-layout="cardstack"] .qcs-cta {
	padding: 14px 34px;
	font-size: var( --qcs-button-size, 1em );
}

/* Controls below the deck: arrows flanking a centred dot row. */
[data-layout="cardstack"] .qcs-live {
	position: absolute;
}

[data-layout="cardstack"] .qcs-controls {
	top: auto;
	bottom: 0;
	left: 50%;
	transform: translateX(-50%);
	width: 340px;
	max-width: 86%;
	justify-content: space-between;
	pointer-events: none;
}

[data-layout="cardstack"] .qcs-arrow {
	pointer-events: auto;
	width: 44px;
	height: 44px;
	background: var( --qcs-arrow-bg, var(--qcsp-fc-surface, #ffffff) );
	border: 1px solid var(--qcsp-fc-border, #e5e7eb);
	color: var( --qcs-arrow-color, var(--qcsp-fc-text, #1d2327) );
	box-shadow: 0 4px 12px rgba(19, 22, 40, 0.08);
}

[data-layout="cardstack"] .qcs-arrow-next {
	border-color: var(--qcsp-fc-accent, #6c5ce7);
	color: var(--qcsp-fc-accent, #6c5ce7);
}

[data-layout="cardstack"] .qcs-arrow:hover,
[data-layout="cardstack"] .qcs-arrow:focus {
	background: var( --qcs-arrow-bg, var(--qcsp-fc-page, #f8f6ff) );
}

/* Hide the pause button here — the deck has none. */
[data-layout="cardstack"] .qcs-pause {
	display: none;
}

[data-layout="cardstack"] .qcs-indicators {
	top: auto;
	bottom: 14px;
	left: 50%;
	transform: translateX(-50%);
	width: auto;
	gap: 8px;
	align-items: center;
	justify-content: center;
	z-index: 3;
}

[data-layout="cardstack"] .qcs-indicator {
	flex: 0 0 auto;
	width: 8px;
	height: 8px;
	min-width: 0;
	border-radius: 50%;
	background: var(--qcsp-fc-border, #d1d5db);
	transition: width 0.3s ease, background 0.3s ease;
}

[data-layout="cardstack"] .qcs-indicator-active {
	width: 30px;
	border-radius: 4px;
	background: var(--qcsp-fc-accent, #6c5ce7);
}

/* =========================================================================
   Feature cards — a row of icon/heading/text cards on a tinted page, each
   with a round button that opens a detail panel. All cards stay visible and
   interactive; the arrows page the track sideways.
   ========================================================================= */
[data-layout="featurecards"].qcs-slider {
	background: var(--qcsp-fc-page, #f5f5f7);
	border-radius: var( --qcs-radius, 22px );
	overflow: hidden;
	min-height: 0;
	padding: 36px 0 84px;
}

[data-layout="featurecards"] .qcs-slides {
	--qcsp-fc-cols: 4;
	--qcsp-fc-gap: 20px;

	position: relative;
	display: flex;
	gap: var(--qcsp-fc-gap);
	align-items: stretch;
	min-height: 0;
	padding: 0 36px;
	box-sizing: border-box;
	transition: transform 0.55s cubic-bezier(0.16, 1, 0.3, 1);
	will-change: transform;
}

[data-layout="featurecards"] .qcs-slide {
	position: relative;
	inset: auto;
	flex: 0 0 calc((100% - (var(--qcsp-fc-cols) - 1) * var(--qcsp-fc-gap)) / var(--qcsp-fc-cols));
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	background: var( --qcs-slide-bg, var(--qcsp-fc-surface, #ffffff) );
	color: var(--qcsp-fc-text, #1d1d1f);
	border-radius: var( --qcs-radius, 18px );
	padding: 26px 24px 76px;
	box-sizing: border-box;
	/* The free transition engine must not move these cards. */
	transform: none !important;
	transition: none;
}

[data-layout="featurecards"] .qcs-slide::after {
	display: none;
}

/* Icon — either the slide image, or a Dashicon when no image is set. */
[data-layout="featurecards"] .qcs-slide-media {
	position: relative;
	inset: auto;
	order: -1;
	overflow: visible;
	flex: 0 0 auto;
	width: auto;
	margin-bottom: 18px;
}

[data-layout="featurecards"] .qcs-slide-img {
	width: auto;
	height: auto;
	max-width: 44px;
	max-height: 40px;
	object-fit: contain;
}

[data-layout="featurecards"] .qcsp-fc-icon {
	order: -1;
	margin-bottom: 18px;
	font-size: 34px;
	width: 34px;
	height: 34px;
	line-height: 1;
	color: var(--qcsp-fc-text, #1d1d1f);
}

[data-layout="featurecards"] .qcs-slide-box {
	position: static;
	width: 100%;
	max-width: none;
	margin: 0;
	padding: 0;
	border-radius: 0;
	background: transparent;
	box-shadow: none;
	color: inherit;
	text-align: left;
}

[data-layout="featurecards"] .qcs-slide-heading {
	font-size: var( --qcs-heading-size, 1.32em );
	line-height: 1.24;
	font-weight: 700;
	color: var( --qcs-heading-color, var(--qcsp-fc-text, #1d1d1f) );
	margin: 0 0 12px;
}

[data-layout="featurecards"] .qcs-slide-text {
	font-size: var( --qcs-text-size, 0.95em );
	line-height: 1.5;
	color: var( --qcs-text-color, var(--qcsp-fc-muted, #6e6e73) );
	margin: 0;
}

/* The free CTA is replaced by the round button below. */
[data-layout="featurecards"] .qcs-cta {
	display: none;
}

/* Round action button, bottom-right of each card. */
.qcsp-fc-toggle {
	position: absolute;
	right: 22px;
	bottom: 22px;
	width: 34px;
	height: 34px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: var(--qcsp-fc-btn, #1d1d1f);
	color: var(--qcsp-fc-btn-fg, #ffffff);
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	text-decoration: none;
	transition: transform 0.2s ease, opacity 0.2s ease;
}

.qcsp-fc-toggle:hover,
.qcsp-fc-toggle:focus {
	transform: scale(1.08);
	color: var(--qcsp-fc-btn-fg, #ffffff);
}

/* "+" glyph drawn with two bars so no icon font is needed. */
.qcsp-fc-toggle-glyph {
	position: relative;
	width: 14px;
	height: 14px;
}

.qcsp-fc-toggle-glyph::before,
.qcsp-fc-toggle-glyph::after {
	content: "";
	position: absolute;
	background: currentColor;
	border-radius: 1px;
	transition: transform 0.25s ease;
}

.qcsp-fc-toggle-glyph::before {
	left: 0;
	right: 0;
	top: 6px;
	height: 2px;
}

.qcsp-fc-toggle-glyph::after {
	top: 0;
	bottom: 0;
	left: 6px;
	width: 2px;
}

/* Link variant: a chevron instead of a plus — same glyph box, redrawn. */
.qcsp-fc-toggle-link .qcsp-fc-toggle-glyph::before {
	left: 2px;
	top: 3px;
	right: auto;
	bottom: auto;
	width: 8px;
	height: 8px;
	background: none;
	border-right: 2px solid currentColor;
	border-top: 2px solid currentColor;
	border-radius: 0;
	transform: rotate(45deg);
}

.qcsp-fc-toggle-link .qcsp-fc-toggle-glyph::after {
	display: none;
}

/* Bottom-right paging arrows for the whole section. */
[data-layout="featurecards"] .qcs-controls {
	top: auto;
	bottom: 26px;
	right: 36px;
	left: auto;
	gap: 8px;
}

[data-layout="featurecards"] .qcs-arrow {
	width: 38px;
	height: 38px;
	border: 0;
	background: var( --qcs-arrow-bg, var(--qcsp-fc-border, rgba(0, 0, 0, 0.08)) );
	color: var( --qcs-arrow-color, var(--qcsp-fc-text, #1d1d1f) );
	font-size: 18px;
}

[data-layout="featurecards"] .qcs-arrow:hover,
[data-layout="featurecards"] .qcs-arrow:focus {
	background: var( --qcs-arrow-bg, var(--qcsp-fc-accent, #6c5ce7) );
	color: var( --qcs-arrow-color, #ffffff );
}

[data-layout="featurecards"] .qcs-pause {
	display: none;
}

[data-layout="featurecards"] .qcs-indicators {
	top: auto;
	bottom: 32px;
	left: 36px;
	right: auto;
	width: auto;
	gap: 7px;
}

[data-layout="featurecards"] .qcs-indicator {
	flex: 0 0 auto;
	width: 7px;
	height: 7px;
	min-width: 0;
	border-radius: 50%;
	background: var(--qcsp-fc-border, rgba(0, 0, 0, 0.15));
}

[data-layout="featurecards"] .qcs-indicator-active {
	background: var(--qcsp-fc-accent, #6c5ce7);
}

/* -------------------------------------------------------------------------
   Detail panel. The JS runtime moves these to <body> on init, because the
   track uses a transform, and a transformed ancestor becomes the containing
   block for position:fixed — which would trap the panel inside the slider.
   ------------------------------------------------------------------------- */
.qcsp-fc-backdrop {
	position: fixed;
	inset: 0;
	z-index: 100000;
	background: var(--qcsp-fc-scrim, rgba(255, 255, 255, 0.6));
	-webkit-backdrop-filter: blur(24px);
	backdrop-filter: blur(24px);
	opacity: 0;
	transition: opacity 0.3s ease;
}

.qcsp-fc-backdrop.is-open {
	opacity: 1;
}

.qcsp-fc-panel {
	position: fixed;
	z-index: 100001;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%) scale(0.96);
	width: min(560px, calc(100vw - 32px));
	max-height: min(82vh, 660px);
	overflow-y: auto;
	box-sizing: border-box;
	padding: 44px 44px 40px;
	border-radius: 22px;
	background: var(--qcsp-fc-surface, #ffffff);
	color: var(--qcsp-fc-text, #1d1d1f);
	box-shadow: 0 24px 70px rgba(0, 0, 0, 0.22);
	opacity: 0;
	transition: opacity 0.3s ease, transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.qcsp-fc-panel.is-open {
	opacity: 1;
	transform: translate(-50%, -50%) scale(1);
}

.qcsp-fc-panel[hidden] {
	display: none;
}

.qcsp-fc-close {
	position: absolute;
	top: 18px;
	right: 18px;
	width: 34px;
	height: 34px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: var(--qcsp-fc-btn, #1d1d1f);
	color: var(--qcsp-fc-btn-fg, #ffffff);
	font-size: 20px;
	line-height: 1;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
}

.qcsp-fc-close:hover,
.qcsp-fc-close:focus {
	opacity: 0.85;
	color: var(--qcsp-fc-btn-fg, #ffffff);
}

.qcsp-fc-eyebrow {
	margin: 0 0 14px;
	font-size: 0.92em;
	font-weight: 600;
	color: var(--qcsp-fc-text, #1d1d1f);
}

.qcsp-fc-title {
	margin: 0 0 20px;
	font-size: clamp(1.6em, 3vw, 2.2em);
	line-height: 1.18;
	font-weight: 800;
	color: var(--qcsp-fc-text, #1d1d1f);
}

.qcsp-fc-body {
	font-size: 1em;
	line-height: 1.55;
	color: var(--qcsp-fc-muted, #6e6e73);
}

.qcsp-fc-link {
	display: inline-block;
	margin-top: 22px;
	font-size: 1em;
	font-weight: 500;
	color: var(--qcsp-fc-link, #6c5ce7);
	text-decoration: none;
}

.qcsp-fc-link::after {
	content: "\00a0\203A";
}

.qcsp-fc-link:hover,
.qcsp-fc-link:focus {
	text-decoration: underline;
	color: var(--qcsp-fc-link, #6c5ce7);
}

/* Page behind an open panel must not scroll. */
html.qcsp-fc-locked,
body.qcsp-fc-locked {
	overflow: hidden;
}

/* =========================================================================
   Split hero — a full-bleed hero band: a full-height image filling one half,
   a solid colour content panel filling the other, and a vertical indicator
   rail pinned to the left edge.

   The colours are the free plugin's own per-slider / per-slide controls, so
   there is no second set of pickers to keep in sync:
     --qcs-box-bg     ("Box background") paints the content panel
     --qcs-font-color ("Font color")     paints the text, icon and rail, and
                                         is inverted for the CTA
   Everything inside the panel is optional: the free template only prints the
   heading / text / button it actually has, and the icon comes from this
   plugin's before-content hook only when one is chosen.

   The slide stays absolutely positioned inside .qcs-slides, so the free
   fade / slide transition engine drives this layout unchanged.
   ========================================================================= */
[data-layout="splithero"].qcs-slider {
	border-radius: var( --qcs-radius, 0 );
	/* Painted behind the slides so a cross-fade never flashes the free
	   stylesheet's dark default between two panels. */
	background: var( --qcs-box-bg, #ffffff );
}

/* Full-width breakout. --qcsp-sh-vw is set by the layout runtime to
   documentElement.clientWidth, which EXCLUDES the scrollbar — plain 100vw
   includes it and would make the page scroll sideways by the scrollbar's
   width. The 100vw fallback only applies with JS off.

   The negative margins carry !important because a block theme's constrained
   layout ships `margin-left/right: auto !important` on every child of
   .is-layout-constrained; without it the element keeps its full-viewport
   width but stays inside the container's padding, overflowing the page by
   exactly that padding. The percentage resolves against the container, so
   the same formula lands the slider at the viewport edge whatever the
   theme's content width happens to be. */
[data-layout="splithero"][data-qcsp-full="1"].qcs-slider,
[data-layout="mosaic"][data-qcsp-full="1"].qcs-slider,
[data-layout="showcase"][data-qcsp-full="1"].qcs-slider {
	width: var( --qcsp-sh-vw, 100vw );
	max-width: var( --qcsp-sh-vw, 100vw );
	margin-left: calc( 50% - var( --qcsp-sh-vw, 100vw ) / 2 ) !important;
	margin-right: calc( 50% - var( --qcsp-sh-vw, 100vw ) / 2 ) !important;
}

/* Two stretched panels. The free markup order is media → box, so the default
   row puts the image left; data-position="left" means the TEXT box is on the
   left, which reverses the row and sends the image to the right. */
[data-layout="splithero"] .qcs-slide {
	align-items: stretch;
	flex-direction: row;
	background: var( --qcs-slide-bg, var( --qcs-box-bg, #ffffff ) );
}

[data-layout="splithero"] .qcs-slide[data-position="left"] {
	flex-direction: row-reverse;
}

/* The image becomes a real panel rather than an absolute backdrop. */
[data-layout="splithero"] .qcs-slide-media {
	position: relative;
	inset: auto;
	flex: 1 1 50%;
	min-width: 0;
	align-self: stretch;
}

/* No darkening gradient — the image owns its own half. */
[data-layout="splithero"] .qcs-slide::after {
	display: none;
}

[data-layout="splithero"] .qcs-slide-box {
	flex: 1 1 50%;
	min-width: 0;
	display: flex;
	flex-direction: column;
	justify-content: center;
	max-width: none;
	margin: 0;
	border-radius: 0;
	box-shadow: none;
	padding: clamp( 40px, 6vw, 96px ) clamp( 28px, 4vw, 72px );
}

/* When the panel is the left one it sits under the indicator rail, so it
   needs enough inset to clear it. */
[data-layout="splithero"] .qcs-slide[data-position="left"] .qcs-slide-box {
	padding-left: clamp( 64px, 8vw, 140px );
}

/* Optional icon above the heading. */
[data-layout="splithero"] .qcsp-sh-icon {
	font-size: 34px;
	width: 34px;
	height: 34px;
	line-height: 1;
	margin: 0 0 18px;
	color: inherit;
}

[data-layout="splithero"] .qcs-slide-heading {
	font-size: var( --qcs-heading-size, clamp( 1.9em, 3.1vw, 3em ) );
	line-height: 1.08;
	letter-spacing: -0.02em;
	margin: 0 0 18px;
}

[data-layout="splithero"] .qcs-slide-text {
	line-height: 1.65;
	max-width: 46ch;
	opacity: 0.88;
	margin: 0 0 28px;
}

/* Inverted CTA: the panel's text colour becomes the fill, the panel colour
   becomes the label — so it contrasts with whatever panel colour is set. */
[data-layout="splithero"] .qcs-cta {
	align-self: flex-start;
	display: inline-flex;
	align-items: center;
	gap: 10px;
	border-radius: 0;
	padding: 14px 26px;
	font-size: var( --qcs-button-size, 0.95em );
	background: var( --qcs-button-bg, var( --qcs-font-color, #ffffff ) );
	color: var( --qcs-button-color, var( --qcs-box-bg, #1d2327 ) );
	transition: opacity 0.18s ease, transform 0.18s ease;
}

[data-layout="splithero"] .qcs-cta::before {
	content: "\203A";
	font-size: 1.3em;
	line-height: 0;
	font-weight: 400;
}

[data-layout="splithero"] .qcs-cta:hover,
[data-layout="splithero"] .qcs-cta:focus {
	background: var( --qcs-button-bg, var( --qcs-font-color, #ffffff ) );
	color: var( --qcs-button-color, var( --qcs-box-bg, #1d2327 ) );
	opacity: 0.85;
	transform: translateX( 2px );
}

/* ---- Vertical indicator rail, always pinned to the left ---------------- */
[data-layout="splithero"] .qcs-indicators {
	flex-direction: column;
	top: 50%;
	bottom: auto;
	left: clamp( 16px, 2vw, 30px );
	right: auto;
	transform: translateY( -50% );
	gap: 2px;
	/* currentColor drives the dots; over the content panel the panel's own
	   text colour is guaranteed to contrast with it. */
	color: var( --qcs-font-color, #ffffff );
}

/* When the ACTIVE slide puts the content on the right, the rail sits over the
   image instead — switch to white with a shadow so it stays readable on any
   photo. :has() re-evaluates on every slide change, so this tracks live. */
[data-layout="splithero"]:has( .qcs-slide-active[data-position="right"] ) .qcs-indicators {
	color: #ffffff;
	filter: drop-shadow( 0 1px 3px rgba( 0, 0, 0, 0.5 ) );
}

/* The dot is drawn as a pseudo-element so the button itself can stay a
   24x24 hit area (WCAG 2.2 SC 2.5.8 Target Size) while the visible dot
   stays small. The gap is tightened to compensate for the padding. */
[data-layout="splithero"] .qcs-indicators .qcs-indicator {
	position: relative;
	flex: 0 0 auto;
	width: 24px;
	height: 24px;
	min-width: 0;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
}

[data-layout="splithero"] .qcs-indicators .qcs-indicator::before {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: currentColor;
	opacity: 0.8;
	transform: translate( -50%, -50% );
	transition: width 0.2s ease, height 0.2s ease, opacity 0.2s ease;
}

[data-layout="splithero"] .qcs-indicators .qcs-indicator:hover::before,
[data-layout="splithero"] .qcs-indicators .qcs-indicator:focus-visible::before {
	opacity: 1;
}

/* Active dot: an outlined ring, as in the reference design. */
[data-layout="splithero"] .qcs-indicators .qcs-indicator-active::before {
	width: 12px;
	height: 12px;
	background: transparent;
	border: 2px solid currentColor;
	opacity: 1;
}

/* ---- Arrows / pause: bottom of whichever half holds the content -------- */
[data-layout="splithero"] .qcs-controls {
	bottom: clamp( 18px, 2.4vw, 32px );
	left: clamp( 64px, 8vw, 140px );
	right: auto;
}

[data-layout="splithero"]:has( .qcs-slide-active[data-position="right"] ) .qcs-controls {
	left: auto;
	right: clamp( 28px, 4vw, 72px );
}

/* =========================================================================
   Content mosaic — a STATIC grid: every tile is on screen at once, so there
   is no active slide, no autoplay and no slider chrome. The free engine still
   owns the markup and the dynamic sources; this layout only re-arranges them.

   Each tile is a real <img> photo (never a CSS background, so it stays
   indexable) with an optional caption over a bottom scrim. The whole tile is
   one stretched link named after its heading, and the heading turns into a
   button on hover / keyboard focus.

   Patterns repeat every 3 (or 2) tiles, so more slides simply extend the grid
   downwards; the rules at the end of this block tidy up a ragged last row.
   ========================================================================= */
[data-layout="mosaic"].qcs-slider {
	--qcsp-mo-row: calc( var( --qcs-min-height, 560px ) / 2 );
	background: transparent;
	border-radius: 0;
	overflow: visible;
}

/* This layout renders no navigation at all. */
[data-layout="mosaic"] .qcs-indicators,
[data-layout="mosaic"] .qcs-controls {
	display: none;
}

[data-layout="mosaic"] .qcs-slides {
	position: relative;
	display: grid;
	grid-template-columns: repeat( 2, minmax( 0, 1fr ) );
	/* minmax(), not a fixed row height: the tile clips its overflow, so at 200%
	   text zoom a long caption in a short tile would otherwise be cut off at
	   the top (WCAG 1.4.4). The row keeps its nominal height and only grows
	   when a caption genuinely needs more room. */
	grid-auto-rows: minmax( var( --qcsp-mo-row ), auto );
	gap: var( --qcsp-mo-gap, 16px );
	min-height: 0;
	height: auto;
}

/* Tiles are laid out by the grid, so the absolute-positioned fade / slide
   transition engine has to be switched off for them. */
[data-layout="mosaic"] .qcs-slide {
	position: relative;
	inset: auto;
	display: flex;
	align-items: flex-end;
	min-width: 0;
	overflow: hidden;
	border-radius: var( --qcsp-mo-radius, 18px );
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transition: none;
	transform: none !important;
	/* Fallback plate, so a tile with no image never collapses the grid. */
	background: var( --qcs-slide-bg, #c3cad9 );
}

/* Ken Burns animates only the active slide, which is meaningless in a grid. */
[data-layout="mosaic"] .qcs-slide-img {
	animation: none !important;
	transition: transform 0.5s cubic-bezier( 0.16, 1, 0.3, 1 );
}

[data-layout="mosaic"] .qcs-slide:hover .qcs-slide-img {
	transform: scale( 1.05 );
}

/* Bottom scrim instead of the free left-to-right gradient — and only when
   there is a caption to make legible. */
[data-layout="mosaic"] .qcs-slide::after {
	z-index: 1;
	background: linear-gradient( to top, rgba( 0, 0, 0, 0.62 ) 0%, rgba( 0, 0, 0, 0.16 ) 38%, rgba( 0, 0, 0, 0 ) 64% );
}

[data-layout="mosaic"] .qcs-slide:not( :has( .qcs-slide-heading, .qcs-slide-text ) )::after {
	display: none;
}

/* ---- Caption ---------------------------------------------------------- */
[data-layout="mosaic"] .qcs-slide-box {
	position: relative;
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 8px;
	width: 100%;
	max-width: none;
	margin: 0;
	padding: clamp( 20px, 2.2vw, 32px );
	border-radius: 0;
	background: transparent;
	box-shadow: none;
	color: #ffffff;
}

/* An empty caption box would still eat padding at the bottom of the tile. */
[data-layout="mosaic"] .qcs-slide-box:not( :has( .qcs-slide-heading, .qcs-slide-text ) ) {
	display: none;
}

/* The position control aligns the caption inside its own tile. */
[data-layout="mosaic"] .qcs-slide[data-position="right"] .qcs-slide-box {
	align-items: flex-end;
	text-align: right;
}

/* Plain caption heading. The tile is still one big link — its focus ring
   (on .qcsp-mo-link below) is the keyboard affordance — but the heading
   itself no longer turns into a button on hover. */
[data-layout="mosaic"] .qcs-slide-heading {
	margin: 0;
	font-size: var( --qcs-heading-size, clamp( 1.05em, 1.5vw, 1.45em ) );
	line-height: 1.2;
	color: var( --qcs-heading-color, #ffffff );
	text-shadow: 0 1px 3px rgba( 0, 0, 0, 0.45 );
}

[data-layout="mosaic"] .qcs-slide-text {
	margin: 0;
	max-width: 46ch;
	font-size: var( --qcs-text-size, 0.9em );
	line-height: 1.5;
	color: var( --qcs-text-color, rgba( 255, 255, 255, 0.92 ) );
	text-shadow: 0 1px 3px rgba( 0, 0, 0, 0.5 );
}

/* Same reasoning as the scrim in the free stylesheet: the shadow is there to
   lift the caption off a photo. On a tile that is a plain colour it is only
   fuzz around the letters. */
[data-layout="mosaic"] .qcs-slide:not( :has( > .qcs-slide-media ) ) .qcs-slide-heading,
[data-layout="mosaic"] .qcs-slide:not( :has( > .qcs-slide-media ) ) .qcs-slide-text {
	text-shadow: none;
}

/* The heading is the call to action here, so the free button is redundant. */
[data-layout="mosaic"] .qcs-cta {
	display: none;
}

/* ---- Stretched tile link ---------------------------------------------- */
[data-layout="mosaic"] .qcsp-mo-link {
	position: absolute;
	inset: 0;
	z-index: 3;
	border-radius: inherit;
}

[data-layout="mosaic"] .qcsp-mo-link:focus-visible {
	outline: 3px solid #ffffff;
	outline-offset: -6px;
}

/* ---- Fill the surrounding column --------------------------------------- */

/* Normally each grid row is a fixed slice of Minimum height, which leaves the
   mosaic shorter (or taller) than whatever sits beside it. In fill mode the
   rows share the height they are given instead, so the grid ends level with
   the neighbouring column.

   `min-height: 0` matters as much as the height itself: the free base plants
   a 420px floor on every slider, which would otherwise stop the grid from
   shrinking into a shorter column. */
[data-qcsp-mo-fill="1"].qcs-slider {
	height: 100%;
	min-height: 0;
}

/* minmax(row, 1fr), not minmax(0, 1fr): the rows still share whatever height
   they are given, but they never fall below the nominal one. Without that
   floor a wrapper that passes no height down would let 1fr collapse to the
   caption text — turning the setting into a way to shrink the mosaic rather
   than a no-op. This way fill mode degrades to exactly the fixed-row layout
   whenever the surrounding column has no height of its own. */
[data-qcsp-mo-fill="1"] .qcs-slides {
	height: 100%;
	grid-auto-rows: minmax( var( --qcsp-mo-row ), 1fr );
}

/* A percentage height only resolves when every ancestor up to the sized one
   passes it down, and a page builder's shortcode wrapper almost never does.
   That wrapper is the one link in the chain a plugin can reach — and
   `height: 100%` is simply ignored when the grandparent has no height of its
   own, so this stays inert everywhere it is not needed. html and body are
   excluded so a slider dropped straight into the body cannot resize the page.
   Without :has() support the mosaic just keeps its fixed rows. */
:not( html ):not( body ):has( > [data-qcsp-mo-fill="1"].qcs-slider ) {
	height: 100%;
}

/* ---- Tile patterns ----------------------------------------------------- */

/* Two columns: every third tile is full height on the left... */
[data-qcsp-mosaic="col-tall"][data-qcsp-mosaic-reverse="0"] .qcs-slide:nth-child( 3n + 1 ) {
	grid-row: span 2;
}

/* ...or on the right, which needs dense packing so the two small tiles
   backfill the column the tall one skipped. */
[data-qcsp-mosaic="col-tall"][data-qcsp-mosaic-reverse="1"] .qcs-slides {
	grid-auto-flow: row dense;
}

[data-qcsp-mosaic="col-tall"][data-qcsp-mosaic-reverse="1"] .qcs-slide:nth-child( 3n + 1 ) {
	grid-column: 2;
	grid-row: span 2;
}

/* Two rows: a full-width band on top... */
[data-qcsp-mosaic="row-wide"][data-qcsp-mosaic-reverse="0"] .qcs-slide:nth-child( 3n + 1 ) {
	grid-column: span 2;
}

/* ...or underneath the two halves. */
[data-qcsp-mosaic="row-wide"][data-qcsp-mosaic-reverse="1"] .qcs-slide:nth-child( 3n + 3 ) {
	grid-column: span 2;
}

/* ---- Ragged last row --------------------------------------------------- */

/* A single leftover tile fills the row rather than leaving a hole beside it. */
[data-qcsp-mosaic="col-tall"] .qcs-slide:nth-child( 3n + 1 ):last-child,
[data-qcsp-mosaic="row-wide"] .qcs-slide:nth-child( 3n + 1 ):last-child,
[data-qcsp-mosaic="grid"] .qcs-slide:nth-child( odd ):last-child {
	grid-column: 1 / -1;
	grid-row: span 1;
}

/* Two leftover tiles sit side by side instead of one tall + one short. */
[data-qcsp-mosaic="col-tall"][data-qcsp-mosaic-reverse="0"] .qcs-slide:nth-child( 3n + 1 ):nth-last-child( 2 ) {
	grid-row: span 1;
}

[data-qcsp-mosaic="col-tall"][data-qcsp-mosaic-reverse="1"] .qcs-slide:nth-child( 3n + 1 ):nth-last-child( 2 ) {
	grid-column: 2;
	grid-row: span 1;
}

[data-qcsp-mosaic="row-wide"][data-qcsp-mosaic-reverse="0"] .qcs-slide:nth-child( 3n + 1 ):nth-last-child( 2 ) {
	grid-column: auto;
}


/* =========================================================================
   Bento grid — the mosaic's tiles, laid out row by row: the editor says how
   many tiles each row shows (2, 3 or 4) and that pattern repeats down the
   grid. The base is a 12-column grid and every tile carries its own span, so
   each row fills the width exactly and the order on screen is the order in
   the list. Tile styling matches the mosaic.
   ========================================================================= */
[data-layout="bento"].qcs-slider {
	--qcsp-bn-row: calc( var( --qcs-min-height, 560px ) / 2 );
	background: transparent;
	border-radius: 0;
	overflow: visible;
}

/* This layout renders no navigation at all. */
[data-layout="bento"] .qcs-indicators,
[data-layout="bento"] .qcs-controls {
	display: none;
}

[data-layout="bento"] .qcs-slides {
	position: relative;
	display: grid;
	/* 12 divides by 2, 3 and 4, so a row of any size fills the width exactly:
	   6+6, 4+4+4 or 3+3+3+3. Each tile is given its own span in PHP. */
	grid-template-columns: repeat( 12, minmax( 0, 1fr ) );
	/* minmax(), not a fixed row height: a tile clips its overflow, so at 200%
	   text zoom a long caption in a short tile would be cut off (WCAG 1.4.4).
	   The row keeps its nominal height and only grows when a caption needs it. */
	grid-auto-rows: minmax( var( --qcsp-bn-row ), auto );
	gap: var( --qcsp-bn-gap, 16px );
	min-height: 0;
	height: auto;
}

/* Mirrored: the grid runs right to left, each tile's own content does not. */
[data-qcsp-bento-reverse="1"] .qcs-slides {
	direction: rtl;
}

[data-qcsp-bento-reverse="1"] .qcs-slide {
	direction: ltr;
}

/* Tiles are laid out by the grid, so the absolute-positioned fade / slide
   transition engine has to be switched off for them. */
[data-layout="bento"] .qcs-slide {
	grid-column: span var( --qcsp-bn-span, 4 );
	position: relative;
	inset: auto;
	display: flex;
	align-items: flex-end;
	min-width: 0;
	overflow: hidden;
	border-radius: var( --qcsp-bn-radius, 18px );
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transition: none;
	transform: none !important;
	/* Fallback plate, so a tile with no image never collapses the grid. */
	background: var( --qcs-slide-bg, #c3cad9 );
}

/* Ken Burns animates only the active slide, which is meaningless in a grid. */
[data-layout="bento"] .qcs-slide-img {
	animation: none !important;
	transition: transform 0.5s cubic-bezier( 0.16, 1, 0.3, 1 );
}

[data-layout="bento"] .qcs-slide:hover .qcs-slide-img {
	transform: scale( 1.05 );
}

/* Bottom scrim instead of the free left-to-right gradient — and only when
   there is a caption to make legible. */
[data-layout="bento"] .qcs-slide::after {
	z-index: 1;
	background: linear-gradient( to top, rgba( 0, 0, 0, 0.62 ) 0%, rgba( 0, 0, 0, 0.16 ) 38%, rgba( 0, 0, 0, 0 ) 64% );
}

[data-layout="bento"] .qcs-slide:not( :has( .qcs-slide-heading, .qcs-slide-text ) )::after {
	display: none;
}

/* ---- Caption ---------------------------------------------------------- */
[data-layout="bento"] .qcs-slide-box {
	position: relative;
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 8px;
	width: 100%;
	max-width: none;
	margin: 0;
	padding: clamp( 20px, 2.2vw, 32px );
	border-radius: 0;
	background: transparent;
	box-shadow: none;
	color: #ffffff;
}

/* An empty caption box would still eat padding at the bottom of the tile. */
[data-layout="bento"] .qcs-slide-box:not( :has( .qcs-slide-heading, .qcs-slide-text ) ) {
	display: none;
}

/* The position control aligns the caption inside its own tile. */
[data-layout="bento"] .qcs-slide[data-position="right"] .qcs-slide-box {
	align-items: flex-end;
	text-align: right;
}

/* Plain caption heading. The tile is still one big link — its focus ring
   (on .qcsp-mo-link below) is the keyboard affordance — but the heading
   itself no longer turns into a button on hover. */
[data-layout="bento"] .qcs-slide-heading {
	margin: 0;
	font-size: var( --qcs-heading-size, clamp( 1.05em, 1.5vw, 1.45em ) );
	line-height: 1.2;
	color: var( --qcs-heading-color, #ffffff );
	text-shadow: 0 1px 3px rgba( 0, 0, 0, 0.45 );
}

[data-layout="bento"] .qcs-slide-text {
	margin: 0;
	max-width: 46ch;
	font-size: var( --qcs-text-size, 0.9em );
	line-height: 1.5;
	color: var( --qcs-text-color, rgba( 255, 255, 255, 0.92 ) );
	text-shadow: 0 1px 3px rgba( 0, 0, 0, 0.5 );
}

/* Same reasoning as the scrim in the free stylesheet: the shadow is there to
   lift the caption off a photo. On a tile that is a plain colour it is only
   fuzz around the letters. */
[data-layout="bento"] .qcs-slide:not( :has( > .qcs-slide-media ) ) .qcs-slide-heading,
[data-layout="bento"] .qcs-slide:not( :has( > .qcs-slide-media ) ) .qcs-slide-text {
	text-shadow: none;
}

/* The heading is the call to action here, so the free button is redundant. */
[data-layout="bento"] .qcs-cta {
	display: none;
}

/* ---- Stretched tile link ---------------------------------------------- */
[data-layout="bento"] .qcsp-mo-link {
	position: absolute;
	inset: 0;
	z-index: 3;
	border-radius: inherit;
}

[data-layout="bento"] .qcsp-mo-link:focus-visible {
	outline: 3px solid #ffffff;
	outline-offset: -6px;
}

/* ---- Fill the surrounding column --------------------------------------- */

/* Normally each grid row is a fixed slice of Minimum height, which leaves the
   mosaic shorter (or taller) than whatever sits beside it. In fill mode the
   rows share the height they are given instead, so the grid ends level with
   the neighbouring column.

   `min-height: 0` matters as much as the height itself: the free base plants
   a 420px floor on every slider, which would otherwise stop the grid from
   shrinking into a shorter column. */
[data-qcsp-bn-fill="1"].qcs-slider {
	height: 100%;
	min-height: 0;
}

/* minmax(row, 1fr), not minmax(0, 1fr): the rows still share whatever height
   they are given, but they never fall below the nominal one. Without that
   floor a wrapper that passes no height down would let 1fr collapse to the
   caption text — turning the setting into a way to shrink the mosaic rather
   than a no-op. This way fill mode degrades to exactly the fixed-row layout
   whenever the surrounding column has no height of its own. */
[data-qcsp-bn-fill="1"] .qcs-slides {
	height: 100%;
	grid-auto-rows: minmax( var( --qcsp-bn-row ), 1fr );
}

/* A percentage height only resolves when every ancestor up to the sized one
   passes it down, and a page builder's shortcode wrapper almost never does.
   That wrapper is the one link in the chain a plugin can reach — and
   `height: 100%` is simply ignored when the grandparent has no height of its
   own, so this stays inert everywhere it is not needed. html and body are
   excluded so a slider dropped straight into the body cannot resize the page.
   Without :has() support the mosaic just keeps its fixed rows. */
:not( html ):not( body ):has( > [data-qcsp-bn-fill="1"].qcs-slider ) {
	height: 100%;
}
/* Narrow screens ignore the row pattern: four tiles across a phone would be
   unreadable, so narrow tablets show two per row and phones one. Landscape
   tablets and laptops keep the pattern as it was set. */
@media ( max-width: 900px ) {
	[data-layout="bento"] .qcs-slide {
		grid-column: span 6;
	}
}

@media ( max-width: 782px ) {
	[data-layout="bento"] .qcs-slides {
		grid-auto-rows: minmax( calc( var( --qcsp-bn-row ) * 0.8 ), auto );
	}

	[data-layout="bento"] .qcs-slide {
		grid-column: 1 / -1;
	}

	[data-qcsp-bn-fill="1"].qcs-slider,
	[data-qcsp-bn-fill="1"] .qcs-slides,
	:not( html ):not( body ):has( > [data-qcsp-bn-fill="1"].qcs-slider ) {
		height: auto;
	}
}

/* The hover zoom is motion like any other. */
@media ( prefers-reduced-motion: reduce ) {
	[data-layout="bento"] .qcs-slide-img {
		transition: none;
	}

	[data-layout="bento"] .qcs-slide:hover .qcs-slide-img {
		transform: none;
	}
}

/* =========================================================================
   Card showcase — a paged row of image cards. Each card is a full-bleed
   photo with, over it, a small label, a heading and a button pinned to the
   bottom; the button rests in the box background colour and flips to the
   chosen hover colour when pointed at.

   The engine still owns one "current" slide; the runtime snaps it to a page
   boundary and translates the track a whole page at a time, so autoplay,
   swipe, the keyboard and the indicators all move by a page.

   --qcsp-sc-per is written inline by the runtime. The declarations here are
   the no-JS fallback, which is why the breakpoints below must stay in step
   with perView() in qcsp-layouts.js.
   ========================================================================= */
[data-layout="showcase"].qcs-slider {
	--qcsp-sc-per: var( --qcsp-sc-per-desktop, 3 );
	background: transparent;
	border-radius: 0;
	min-height: 0;
	overflow: hidden;
}

[data-layout="showcase"] .qcs-slides {
	position: relative;
	display: flex;
	align-items: stretch;
	gap: var( --qcsp-sc-gap, 20px );
	width: 100%;
	height: auto;
	min-height: 0;
	transition: transform 0.55s cubic-bezier( 0.16, 1, 0.3, 1 );
}

/* Cards are laid out by the flex track, so the absolutely-positioned
   fade / slide transition engine has to be switched off for them. */
[data-layout="showcase"] .qcs-slide {
	position: relative;
	inset: auto;
	flex: 0 0 calc( ( 100% - ( var( --qcsp-sc-per, 3 ) - 1 ) * var( --qcsp-sc-gap, 20px ) ) / var( --qcsp-sc-per, 3 ) );
	max-width: calc( ( 100% - ( var( --qcsp-sc-per, 3 ) - 1 ) * var( --qcsp-sc-gap, 20px ) ) / var( --qcsp-sc-per, 3 ) );
	display: flex;
	align-items: stretch;
	min-width: 0;
	overflow: hidden;
	border-radius: var( --qcsp-sc-radius, 24px );
	aspect-ratio: 1 / 1;
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transition: none;
	transform: none !important;
	/* Fallback plate, so a card with no image never collapses the row. */
	background: var( --qcs-slide-bg, #c3cad9 );
}

[data-qcsp-sc-ratio="tall"] .qcs-slide {
	aspect-ratio: 3 / 4;
}

[data-qcsp-sc-ratio="wide"] .qcs-slide {
	aspect-ratio: 4 / 3;
}

/* "Fixed height" instead of a shape: the free Minimum height drives it, and
   auto lets a long caption push the card taller rather than clipping it. */
[data-qcsp-sc-ratio="auto"] .qcs-slide {
	aspect-ratio: auto;
	min-height: var( --qcs-min-height, 420px );
}

/* Ken Burns animates only the active slide, which would single out one card
   in a row of equals. */
[data-layout="showcase"] .qcs-slide-img {
	animation: none !important;
	transition: transform 0.6s cubic-bezier( 0.16, 1, 0.3, 1 );
}

[data-layout="showcase"] .qcs-slide:hover .qcs-slide-img {
	transform: scale( 1.04 );
}

/* The free left-to-right scrim is replaced by an optional flat veil in the
   box background colour: white lightens a dark photo under dark text, and a
   dark box colour darkens a light photo under light text. 0 = no veil. */
[data-layout="showcase"] .qcs-slide::after {
	z-index: 1;
	background: var( --qcs-box-bg, #ffffff );
	opacity: var( --qcsp-sc-scrim, 0 );
}

/* ---- Card content ------------------------------------------------------ */
[data-layout="showcase"] .qcs-slide-box {
	position: relative;
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 6px;
	width: 100%;
	max-width: none;
	margin: 0;
	padding: clamp( 20px, 2vw, 30px );
	border-radius: 0;
	background: transparent;
	box-shadow: none;
	color: var( --qcs-font-color, #1d1d1f );
}

/* The position control aligns the caption inside its own card. */
[data-layout="showcase"] .qcs-slide[data-position="right"] .qcs-slide-box {
	align-items: flex-end;
	text-align: right;
}

/* The slide's text is the card's small label rather than a paragraph — the
   reference design's "Carried, seen, remembered" line — so it is styled down
   instead of being given a field of its own, which keeps every custom-field
   mapping working. Whether it sits above or below the heading is the free
   plugin's Heading position setting, which swaps the two in the markup. */
[data-layout="showcase"] .qcs-slide-text {
	margin: 0;
	max-width: 34ch;
	font-size: var( --qcs-text-size, 0.95em );
	line-height: 1.35;
}

[data-layout="showcase"] .qcs-slide-heading {
	margin: 0;
	max-width: 20ch;
	font-size: var( --qcs-heading-size, clamp( 1.2em, 1.7vw, 1.75em ) );
	line-height: 1.15;
	font-weight: 700;
}

/* Caption pinned to the bottom of the card: the spare room goes ABOVE the
   first line instead of between the text and the button, so the two end up
   stacked together at the bottom edge. Whatever comes first is pushed down —
   a card with no caption at all still keeps its button in place. */
[data-qcsp-sc-text="bottom"] .qcs-slide-box > *:first-child {
	margin-top: auto;
}

/* ---- Button ------------------------------------------------------------ */
[data-layout="showcase"] .qcs-cta {
	display: inline-flex;
	align-items: center;
	/* Pushes the button to the bottom of the card whatever the text above. */
	margin-top: auto;
	padding: 11px 26px;
	/* WCAG 2.2 SC 2.5.8 Target Size. */
	min-height: 44px;
	box-sizing: border-box;
	border-radius: 999px;
	/* The card's own design defaults, NOT the box background and font colour:
	   a white heading over a dark photo must not drag the button's label to
	   white as well. Button background / Button text colour override them. */
	background: var( --qcs-button-bg, #ffffff );
	color: var( --qcs-button-color, #1d1d1f );
	font-size: var( --qcs-button-size, 0.95em );
	font-weight: 600;
	box-shadow: 0 2px 10px rgba( 0, 0, 0, 0.12 );
	transition: background-color 0.2s ease, color 0.2s ease;
}

/* With the caption already at the bottom, the button only needs a gap above
   it — a second auto margin would split the free space between the two. */
[data-qcsp-sc-text="bottom"] .qcs-cta {
	margin-top: 12px;
}

[data-layout="showcase"] .qcs-cta:hover,
[data-layout="showcase"] .qcs-cta:focus-visible {
	background: var( --qcsp-sc-btn-hover, #111111 );
	color: var( --qcsp-sc-btn-hover-fg, #ffffff );
}

/* The whole card is hovered, not just the button: pointing anywhere on the
   card previews its action, exactly as in the reference design. */
[data-layout="showcase"] .qcs-slide:hover .qcs-cta {
	background: var( --qcsp-sc-btn-hover, #111111 );
	color: var( --qcsp-sc-btn-hover-fg, #ffffff );
}

[data-layout="showcase"] .qcs-slide[data-position="right"] .qcs-cta {
	align-self: flex-end;
}

/* ---- Arrows ------------------------------------------------------------ */

/* The controls row becomes a transparent overlay so each arrow can be pinned
   to its own edge; only the buttons themselves take pointer events. */
[data-layout="showcase"] .qcs-controls {
	position: absolute;
	inset: 0;
	display: block;
	pointer-events: none;
}

[data-layout="showcase"] .qcs-arrow {
	position: absolute;
	top: 50%;
	width: 44px;
	height: 44px;
	border: 0;
	background: var( --qcs-arrow-bg, #17171a );
	color: var( --qcs-arrow-color, #ffffff );
	font-size: 20px;
	transform: translateY( -50% );
	box-shadow: 0 6px 18px rgba( 0, 0, 0, 0.28 );
	pointer-events: auto;
	transition: background-color 0.2s ease;
}

/* The aspect-ratio cards make the row's height predictable, so on the
   "fixed height" setting the arrow still lands in the middle of the cards. */
[data-layout="showcase"] .qcs-arrow-next {
	right: clamp( 12px, 1.6vw, 24px );
}

[data-layout="showcase"] .qcs-arrow-prev {
	left: clamp( 12px, 1.6vw, 24px );
}

[data-layout="showcase"] .qcs-arrow:hover,
[data-layout="showcase"] .qcs-arrow:focus-visible {
	background: var( --qcs-arrow-bg, #000000 );
}

[data-layout="showcase"] .qcs-pause {
	position: absolute;
	left: clamp( 12px, 1.6vw, 24px );
	bottom: clamp( 12px, 1.6vw, 24px );
	pointer-events: auto;
}

/* One roaming arrow: it sits on the right while there is a page ahead and
   swaps to the left edge on the last page. The runtime keeps the attribute
   in step with the current page and the direction of travel. */
[data-qcsp-sc-arrow="next"] .qcs-arrow-prev,
[data-qcsp-sc-arrow="prev"] .qcs-arrow-next,
[data-qcsp-sc-arrow="none"] .qcs-arrow {
	display: none;
}

/* ---- Indicators: one dot per PAGE, below the row ----------------------- */
[data-layout="showcase"] .qcs-indicators {
	position: relative;
	top: auto;
	left: auto;
	right: auto;
	justify-content: center;
	gap: 2px;
	margin-top: 10px;
	color: var( --qcs-font-color, #1d1d1f );
}

/* Cards outside the current page keep their dot out of the row; the runtime
   marks every indicator that is not a page start. */
[data-layout="showcase"] .qcs-indicator.qcsp-sc-dot-off {
	display: none;
}

/* As on Split hero: a 24x24 hit area with a small drawn dot inside it. */
[data-layout="showcase"] .qcs-indicators .qcs-indicator {
	position: relative;
	flex: 0 0 auto;
	width: 24px;
	height: 24px;
	min-width: 0;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
}

[data-layout="showcase"] .qcs-indicators .qcs-indicator::before {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: currentColor;
	opacity: 0.35;
	transform: translate( -50%, -50% );
	transition: opacity 0.2s ease;
}

[data-layout="showcase"] .qcs-indicators .qcs-indicator-active::before {
	opacity: 1;
}

/* The free autoplay progress fill assumes a wide bar, not a round dot. */
[data-layout="showcase"] .qcs-indicator-active::after {
	display: none !important;
}

/* -------------------------------------------------------------------------
   Responsive
   ------------------------------------------------------------------------- */
@media (max-width: 1200px) {
	[data-layout="featurecards"] .qcs-slides {
		--qcsp-fc-cols: 3;
	}
}

@media (max-width: 900px) {
	[data-layout="mosaic"].qcs-slider {
		--qcsp-mo-row: calc( var( --qcs-min-height, 560px ) / 2.5 );
	}


	[data-layout="featurecards"] .qcs-slides {
		--qcsp-fc-cols: 2;
	}

	[data-layout="accordion"] .qcs-slide {
		flex-basis: 46%;
	}

	[data-layout="showcase"].qcs-slider {
		--qcsp-sc-per: 2;
	}
}

@media (max-width: 600px) {
	/* ---- Content mosaic: a single column of equal cards ----------------- */
	[data-layout="mosaic"] .qcs-slides {
		grid-template-columns: 1fr;
		grid-auto-flow: row;
		grid-auto-rows: auto;
	}

	/* One declaration retires every pattern rule above, whichever is active. */
	[data-layout="mosaic"] .qcs-slide {
		grid-column: auto !important;
		grid-row: auto !important;
		aspect-ratio: 16 / 11;
	}

	/* Stacked into one column the tiles keep their own shape, so sharing out a
	   column height would only squash them. */
	[data-qcsp-mo-fill="1"].qcs-slider,
	[data-qcsp-mo-fill="1"] .qcs-slides,
	:not( html ):not( body ):has( > [data-qcsp-mo-fill="1"].qcs-slider ) {
		height: auto;
	}


	/* ---- Split hero: stack the two panels, image on top ---------------- */
	[data-layout="splithero"] .qcs-slide,
	[data-layout="splithero"] .qcs-slide[data-position="left"] {
		flex-direction: column;
	}

	[data-layout="splithero"] .qcs-slide-media {
		flex: 0 0 42%;
		min-height: 190px;
	}

	[data-layout="splithero"] .qcs-slide-box,
	[data-layout="splithero"] .qcs-slide[data-position="left"] .qcs-slide-box {
		flex: 1 1 auto;
		padding: 26px 20px 30px;
	}

	[data-layout="splithero"] .qcsp-sh-icon {
		font-size: 28px;
		width: 28px;
		height: 28px;
		margin-bottom: 12px;
	}

	[data-layout="splithero"] .qcs-slide-heading {
		font-size: var( --qcs-heading-size, 1.55em );
		margin-bottom: 12px;
	}

	[data-layout="splithero"] .qcs-slide-text {
		margin-bottom: 20px;
	}

	/* The rail stays on the left, but moves to the top so it never collides
	   with the CTA at the bottom of the stacked content panel. It now sits
	   over the image, so it is white with a shadow in both positions. */
	[data-layout="splithero"] .qcs-indicators,
	[data-layout="splithero"]:has( .qcs-slide-active[data-position="right"] ) .qcs-indicators {
		flex-direction: row;
		top: 16px;
		bottom: auto;
		left: 16px;
		right: auto;
		transform: none;
		color: #ffffff;
		filter: drop-shadow( 0 1px 3px rgba( 0, 0, 0, 0.5 ) );
	}

	/* Arrows move to the bottom-right so they clear the CTA. */
	[data-layout="splithero"] .qcs-controls,
	[data-layout="splithero"]:has( .qcs-slide-active[data-position="right"] ) .qcs-controls {
		left: auto;
		right: 16px;
		bottom: 16px;
	}


	/* Show one card plus a peek of the next, so paging is discoverable. */
	[data-layout="featurecards"] .qcs-slides {
		--qcsp-fc-cols: 1.15;
		--qcsp-fc-gap: 14px;
		padding: 0 18px;
	}

	[data-layout="featurecards"].qcs-slider {
		padding: 24px 0 76px;
		border-radius: var( --qcs-radius, 16px );
	}

	[data-layout="featurecards"] .qcs-slide {
		padding: 22px 20px 70px;
	}

	[data-layout="featurecards"] .qcs-controls {
		right: 18px;
		bottom: 22px;
	}

	[data-layout="featurecards"] .qcs-indicators {
		left: 18px;
		bottom: 28px;
	}

	.qcsp-fc-panel {
		padding: 40px 24px 28px;
		border-radius: 18px;
		max-height: 86vh;
	}

	/* Accordion: show ~1.3 cards so the active one dominates. */
	[data-layout="accordion"] .qcs-slides {
		gap: 12px;
	}

	[data-layout="accordion"] .qcs-slide {
		flex-basis: 78%;
	}

	[data-layout="accordion"] .qcs-slide-active .qcs-slide-box {
		max-width: none;
	}

	/* Card deck: tighter padding on small screens. */
	[data-layout="cardstack"] .qcs-slide {
		padding: 32px 24px;
		gap: 16px;
	}

	[data-layout="cardstack"] .qcs-controls {
		width: 100%;
	}

	/* ---- Card showcase: one card at a time ----------------------------- */
	[data-layout="showcase"].qcs-slider {
		--qcsp-sc-per: 1;
	}

	[data-layout="showcase"] .qcs-arrow {
		width: 40px;
		height: 40px;
	}
}

@media (prefers-reduced-motion: reduce) {
	[data-layout="mosaic"] .qcs-slide-img,
	[data-layout="splithero"] .qcs-cta,
	[data-layout="splithero"] .qcs-indicators .qcs-indicator::before,
	[data-layout="accordion"] .qcs-slides,
	[data-layout="cardstack"] .qcs-slide,
	[data-layout="featurecards"] .qcs-slides,
	[data-layout="showcase"] .qcs-slides,
	[data-layout="showcase"] .qcs-slide-img,
	[data-layout="showcase"] .qcs-cta,
	.qcsp-fc-panel,
	.qcsp-fc-backdrop {
		transition: none !important;
	}
}
