.psl-slider {
	position: relative;
	width: 100%;
	margin: 0 auto;
	overflow: hidden;
	/* No background color here on purpose. This container is empty until
	   frontend.js builds the slides into it, so any color set here becomes
	   whatever briefly shows (or persistently shows, if the JS never runs —
	   a script conflict, an error, a caching issue serving a stale copy)
	   before that happens. Leaving it transparent means the worst case is an
	   empty gap matching the page's own background, not an opaque color that
	   can look like a rendering bug even when the plugin is actually working
	   correctly and this is just a normal one-frame gap. If you want a
	   specific placeholder color while the slider loads, add
	   `.psl-slider { background: #yourcolor; }` via your theme's Additional
	   CSS — this is deliberately left to you rather than hardcoded. */
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
	outline: none;
	box-sizing: border-box;
	border-style: solid;
	border-color: var(--psl-border-color, transparent);
	border-width: var(--psl-border-w, 0);
	border-radius: var(--psl-radius, 0);
	/* Establishes this element as a query container for its own rendered
	   size, so layer sizing below can react to how wide the SLIDER actually
	   is (e.g. boxed narrow inside a Gutenberg column) rather than only the
	   browser viewport — a boxed slider embedded at 400px wide on a large
	   desktop viewport still needs "mobile-ish" treatment, which a plain
	   @media query can never see. */
	container-type: inline-size;
	container-name: psl;
}
/* Tablet/mobile overrides fall back through the chain (mobile -> tablet ->
   desktop) via each var()'s own second argument, so leaving a breakpoint's
   field blank in the admin — meaning that CSS variable is never output —
   simply inherits the next size up with no extra logic needed here. */
@media (max-width: 1024px) {
	.psl-slider {
		border-width: var(--psl-border-w-tablet, var(--psl-border-w, 0));
		border-radius: var(--psl-radius-tablet, var(--psl-radius, 0));
	}
}
@media (max-width: 640px) {
	.psl-slider {
		border-width: var(--psl-border-w-mobile, var(--psl-border-w-tablet, var(--psl-border-w, 0)));
		border-radius: var(--psl-radius-mobile, var(--psl-radius-tablet, var(--psl-radius, 0)));
	}
}

.psl-track {
	position: relative;
	width: 100%;
	height: 100%;
}

/* Fullscreen mode: fills the browser window on every device, independent of
   where the shortcode sits in the document. 100dvh (with a 100vh fallback for
   older browsers) accounts for mobile browser chrome resizing on scroll.
   This is a fixed overlay — it covers everything below it, including your
   footer, for as long as it's on screen. Pairs with the Blank Canvas template. */
.psl-slider.psl-mode-fullscreen {
	position: fixed;
	inset: 0;
	width: 100vw;
	height: 100vh;
	height: 100dvh;
	max-width: none;
	aspect-ratio: auto;
	z-index: 1;
}

/* Full bleed: same full browser width & height as fullscreen, but stays in
   normal document flow (position: relative, not fixed) — so your footer and
   any content after it scroll into view underneath it as normal. The
   left:50%/margin:-50vw pair is the standard "full-bleed" technique: it
   breaks the element out to the true viewport width regardless of a parent
   page-builder row's max-width or padding, without needing that row's own
   "Stretch Row" option turned on. Requires no ancestor between this element
   and <body> to have `overflow: hidden` — that would clip the breakout. */
.psl-slider.psl-mode-fullbleed {
	position: relative;
	left: 50%;
	right: 50%;
	width: 100vw;
	margin-left: -50vw;
	margin-right: -50vw;
	height: 100vh;
	height: 100dvh;
	max-width: none;
	aspect-ratio: auto;
}

.psl-rows-fly,
.psl-curtain-fly {
	position: absolute;
	inset: 0;
	z-index: 2;
	pointer-events: none;
	overflow: hidden;
}
.psl-row-fly {
	position: absolute;
	left: 0;
	width: 100%;
	background-size: cover;
	background-repeat: no-repeat;
}
.psl-curtain-fly {
	display: flex;
}
.psl-curtain-panel {
	width: 50%;
	height: 100%;
	background-size: cover;
	background-repeat: no-repeat;
}

.psl-slide {
	position: absolute;
	inset: 0;
	visibility: hidden;
	overflow: hidden;
	will-change: transform, opacity, clip-path;
}
.psl-slide.is-active { visibility: visible; }

/* Page-builder themes (Uncode, and others built on WPBakery/similar builders)
   often add global link underline animations via ::before/::after pseudo
   elements and text-decoration rules. Scope those back out inside the
   slider/CTA so theme link styling doesn't visually clash with layer
   buttons, arrows, or dots. */
.psl-slider a,
.psl-cta a,
.psl-fullscreen-block a {
	text-decoration: none;
}
.psl-slider a::before,
.psl-slider a::after,
.psl-cta a::before,
.psl-cta a::after,
.psl-fullscreen-block a::before,
.psl-fullscreen-block a::after {
	display: none !important;
	content: none !important;
}

.psl-bg-layer {
	position: absolute;
	inset: -12%;
	z-index: 0;
	background-size: cover;
	background-position: center;
	will-change: transform;
}
.psl-bg-overlay {
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(180deg, rgba(0,0,0,0) 35%, rgba(0,0,0,0.55) 100%);
	pointer-events: none;
}

.psl-layer-pos {
	position: absolute;
	z-index: 3;
	max-width: 90%;
}
/* The alignment anchor transform lives here, on the wrapper — never on
   .psl-layer itself, since that element's own `transform` is already used
   by the entrance animation (translateX/Y for slide-in, scale for zoom-in).
   Putting both on the same element would mean the last one applied wins,
   silently breaking either the alignment or the animation. */

.psl-layer,
.psl-layer-link-wrap {
	margin: 0;
	line-height: 1.25;
	will-change: transform, opacity;
}
.psl-layer-link-wrap {
	display: block;
	text-decoration: none;
}

h2.psl-layer {
	font-weight: 700;
	letter-spacing: -0.01em;
}
p.psl-layer {
	opacity: 0.9;
}
img.psl-layer {
	display: block;
	max-width: 100%;
	height: auto;
}
a.psl-btn.psl-layer {
	display: inline-block;
	padding: 12px 26px;
	border: 1.5px solid currentColor;
	border-radius: 3px;
	text-decoration: none;
	font-weight: 600;
	letter-spacing: 0.02em;
	transition: background-color .2s ease, color .2s ease;
}
/* :not(.psl-hv-custom) is the important part here, not decoration — a
   per-layer custom hover color/background is applied as a separate
   generated rule (see PSLSlider._applyHoverStyle in frontend.js), and that
   rule targets a plain class selector with lower specificity than this one.
   Both need !important to override the inline color set from the layer's
   own color field, and when two !important declarations for the same
   property collide, the more specific selector always wins regardless of
   source order — which would silently make a custom hover color
   ineffective on buttons specifically. Excluding .psl-hv-custom here means
   this rule simply doesn't match at all on a layer with a custom hover
   style, so there's no specificity contest to lose. */
a.psl-btn.psl-layer:hover:not(.psl-hv-custom) {
	background-color: currentColor;
	color: #111 !important;
}

.psl-arrow {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 10;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	border: 1px solid rgba(255,255,255,0.65);
	background: rgba(0,0,0,0.25);
	color: #fff;
	font-size: 20px;
	line-height: 1;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background-color .2s ease;
}
.psl-arrow:hover { background: rgba(0,0,0,0.55); }
.psl-arrow-prev { left: 18px; }
.psl-arrow-next { right: 18px; }

.psl-dots {
	position: absolute;
	bottom: 18px;
	left: 50%;
	transform: translateX(-50%);
	z-index: 10;
	display: flex;
	gap: 8px;
}
.psl-dot {
	width: 9px;
	height: 9px;
	border-radius: 50%;
	border: 1px solid rgba(255,255,255,0.8);
	background: transparent;
	padding: 0;
	cursor: pointer;
	transition: background-color .2s ease;
}
.psl-dot.is-active { background: #fff; }

.psl-progress {
	position: absolute;
	left: 0; bottom: 0;
	width: 100%;
	height: 3px;
	background: rgba(255,255,255,0.15);
	z-index: 10;
}
.psl-progress-bar {
	height: 100%;
	width: 0%;
	background: rgba(255,255,255,0.85);
}

.psl-cta {
	padding: 20px 16px;
	text-align: center;
}
.psl-cta-btn-container {
	display: block;
	margin-bottom: 12px;
}
.psl-cta-caption {
	font-size: 15px;
	line-height: 1.5;
	display: inline-block;
}
.psl-cta-btn {
	display: inline-block;
	padding: 12px 28px;
	border: 1.5px solid currentColor;
	border-radius: 3px;
	text-decoration: none;
	font-weight: 600;
	font-size: 14px;
	letter-spacing: 0.02em;
	color: inherit;
	transition: background-color .2s ease, color .2s ease;
}
.psl-cta-btn:hover {
	background-color: currentColor;
	color: #111;
}

/* Sits as a caption/CTA bar under a fullscreen slider (which is position:fixed and
   therefore removes itself from normal document flow) without needing the page
   to scroll — pairs with the slider's "Full screen" display mode. */
.psl-cta.psl-cta-overlay-bottom {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 5;
	padding: 26px 16px 30px;
	color: #fff;
	background: linear-gradient(0deg, rgba(0,0,0,0.6) 0%, rgba(0,0,0,0) 100%);
	pointer-events: none;
}
.psl-cta.psl-cta-overlay-bottom .psl-cta-btn,
.psl-cta.psl-cta-overlay-bottom .psl-cta-caption {
	pointer-events: auto;
}

/* A standalone fullscreen block (not tied to the slider) — same viewport-filling
   approach as the slider's Full screen display mode, with a button + caption
   pinned to the bottom of the viewport. */
.psl-fullscreen-block {
	position: fixed;
	inset: 0;
	width: 100vw;
	height: 100vh;
	height: 100dvh;
	overflow: hidden;
	z-index: 1;
}
.psl-fullscreen-cta {
	position: absolute;
	inset: 0;
	z-index: 3;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: flex-end;
	padding: 30px 16px 40px;
	text-align: center;
	color: #fff;
}
.psl-fullscreen-cta.psl-fullscreen-cta--center {
	justify-content: center;
	padding: 20px;
}

@media (max-width: 640px) {
	.psl-arrow { width: 36px; height: 36px; font-size: 16px; }
	.psl-layer-pos { max-width: 82%; }
	.psl-cta.psl-cta-overlay-bottom { padding: 18px 14px 22px; }
	.psl-cta-caption { font-size: 14px; }
	.psl-fullscreen-cta { padding: 20px 14px 28px; }
}

/* Container-query equivalent of the viewport media query above, but reacting
   to the SLIDER's own rendered width instead of the browser window. This is
   what makes a boxed slider embedded narrow — e.g. inside a Gutenberg column
   or a sidebar widget — get sensible sizing even on a wide desktop viewport,
   which a @media query can never detect since it only ever sees the browser
   window's width. Layered on top of (not instead of) the @media rule above
   as a fallback for older browsers without container query support. */
@supports (container-type: inline-size) {
	@container psl (max-width: 640px) {
		.psl-arrow { width: 36px; height: 36px; font-size: 16px; }
		.psl-layer-pos { max-width: 82%; }
	}
	@container psl (max-width: 420px) {
		.psl-arrow { width: 30px; height: 30px; font-size: 14px; }
		.psl-dots { bottom: 10px; }
		.psl-layer-pos { max-width: 88%; }
	}
}

@media (prefers-reduced-motion: reduce) {
	.psl-slide, .psl-layer, .psl-layer-link-wrap { transition: none !important; }
}
