/* ══════════════════════════════════════════════════════════════════════
   FLIP DECK
   One stylesheet for all three layouts, scoped under .fd and branched by
   .fd--text / .fd--split / .fd--image.

   GEOMETRY MODEL
   Every card is absolutely positioned inside .fd-deck and moved with
   translateY. Because transforms do not participate in layout, the deck's
   own footprint never changes while cards are in motion — a card can rise
   clear of the widget and pass over whatever sits above it on the page,
   then settle back inside, without ever reflowing the document.

   The script owns four numbers and writes them back as custom properties:
     --fd-open-h    height of an open card (the tallest card's content)
     --fd-band-h    height of a collapsed card
     --fd-y         per card, its vertical offset for its current slot
     --fd-eyebrow-h per card, the eyebrow's measured height

   Everything else is authored by the editor through Elementor controls,
   which is why so many values below read from a variable with a fallback.

   TWO MEASUREMENT STATES
   .fd-measure      forces a card to its OPEN geometry so the script can find
                    the tallest one — eyebrow expanded, title-to-body gap
                    applied.
   .fd-measure-band forces a card to its COLLAPSED geometry so the band
                    height is read from a consistent state. Without it the
                    already-open card would report its expanded head and
                    every collapsed card would be sized from it.

   PROGRESSIVE ENHANCEMENT
   Without .fd--ready — no JavaScript, or before init — the deck renders as
   a plain vertical list of fully expanded cards. That is the crawlable
   baseline, and the reason nothing here uses display:none to hide content.
═══════════════════════════════════════════════════════════════════════ */

.fd {
	/* Negative by default: each card tucks under the one above so the deck
	   reads as layered cards rather than a list of separate bars. Positive
	   values open clear space between them instead. */
	--fd-gap: -14px;
	--fd-step: 320ms;
	--fd-lift: 72px;
	--fd-lift-z: 70px;
	--fd-lift-tilt: 8deg;
	--fd-max-visible: 0;

	--fd-card-pad-t: 18px;
	--fd-card-pad-r: 22px;
	--fd-card-pad-b: 20px;
	--fd-card-pad-l: 22px;

	--fd-eyebrow-gap: 14px;
	--fd-body-gap: 16px;

	/* Image layout */
	--fd-image-ar: 16/9;
	--fd-collapsed-h: 44px;
	--fd-pill-x: 16px;
	--fd-pill-y: 10px;
	--fd-pill-align: flex-start;

	/* Split layout */
	--fd-split-dir: row;
	--fd-media-w: 44%;
	--fd-media-gap: 24px;
	--fd-media-ar: auto;

	--fd-ease: cubic-bezier(0.4, 0, 0.2, 1);
	--fd-ease-fly: cubic-bezier(0.34, 0.06, 0.3, 1);

	position: relative;
	width: 100%;
}

.fd *,
.fd *::before,
.fd *::after {
	box-sizing: border-box;
}

/* Lift the whole widget in the stacking order only while a card is in
   flight, so the rising card paints over neighbouring content without
   sitting above sticky headers for the rest of the page's life. */
.fd.is-animating {
	z-index: 10;
}

.fd--clip .fd-deck {
	overflow: hidden;
}

.fd-deck {
	position: relative;
	perspective: 1400px;
}

/* ── Cards ─────────────────────────────────────────────────────────── */

.fd-card {
	position: relative;
	margin: 0;
	overflow: hidden;
	background: #2b2b2b;
	/* Casts onto the card below. Cards higher in the stack paint above the
	   ones beneath, so this is what gives the layers visible separation when
	   they are butted together or overlapping. */
	box-shadow: 0 3px 10px rgba(0, 0, 0, 0.28);
}

/* Pre-init / no-JS fallback only. A fixed margin rather than --fd-gap, because
   a negative gap would overlap the cards while they are still in normal flow
   and make the crawlable list unreadable. */
.fd-card + .fd-card {
	margin-top: 10px;
}

.fd--ready .fd-deck {
	transition: height var(--fd-step) var(--fd-ease);
}

.fd--ready .fd-card {
	position: absolute;
	inset-inline: 0;
	top: 0;
	height: var(--fd-band-h, auto);
	margin: 0;
	transform:
		translateY(calc(var(--fd-y, 0px) + var(--fd-hover-y, 0px)))
		scale(var(--fd-hover-scale, 1));
	transition:
		transform var(--fd-step) var(--fd-ease),
		height var(--fd-step) var(--fd-ease),
		opacity var(--fd-step) linear,
		background-color var(--fd-step) linear;
}

.fd--ready .fd-card.is-active {
	height: var(--fd-open-h, auto);
}

.fd.is-animating .fd-card {
	will-change: transform, height;
}

/* The flight. Up and slightly toward the viewer at the apex, then down to
   the back of the deck. The script drops the z-index at the apex so the
   descent passes behind the other cards rather than across them. */
@keyframes fd-fly {
	0% {
		transform: translateY(var(--fd-y-from, 0px)) translateZ(0) rotateX(0deg);
	}
	38% {
		transform:
			translateY(calc(var(--fd-y-from, 0px) - var(--fd-lift)))
			translateZ(var(--fd-lift-z))
			rotateX(var(--fd-lift-tilt));
	}
	100% {
		transform: translateY(var(--fd-y-to, 0px)) translateZ(0) rotateX(0deg);
	}
}

.fd--ready .fd-card.is-flying {
	animation: fd-fly var(--fd-step) var(--fd-ease-fly) forwards;
	transform-origin: 50% 100%;
	height: var(--fd-open-h);
}

/* The whole open card flies. It keeps its full size for the entire lift and
   only collapses once it is past the apex and dropping in behind the stack,
   where the other cards hide the change. Collapsing it on the way up would
   read as the card shrinking rather than a hand lifting it. */
.fd--ready .fd-card.is-flying.fd-shrink {
	height: var(--fd-band-h);
	transition: height calc(var(--fd-step) * 0.62) var(--fd-ease);
}

/* ── Measurement passes ────────────────────────────────────────────── */

.fd-measuring .fd-card,
.fd-measuring .fd-deck,
.fd-measuring .fd-head,
.fd-measuring .fd-eyebrow-slot,
.fd-measuring .fd-frame img,
.fd-measuring .fd-title,
.fd-measuring .fd-trigger {
	transition: none !important;
	animation: none !important;
}

/* Open geometry. */
.fd--ready .fd-card.fd-measure {
	height: auto !important;
}

.fd--ready .fd-card.fd-measure .fd-eyebrow-slot {
	max-height: none !important;
	opacity: 1 !important;
	margin-bottom: var(--fd-eyebrow-gap) !important;
}

.fd--ready.fd--text .fd-card.fd-measure .fd-head,
.fd--ready.fd--split .fd-card.fd-measure .fd-head {
	padding-top: var(--fd-card-pad-t) !important;
	padding-bottom: var(--fd-body-gap) !important;
}

/* Collapsed geometry. Padding-top is forced back to its plain value so the
   measured strip is the VISIBLE height, excluding the tuck zone — the script
   adds the overlap back on top of this number. */
.fd--ready .fd-card.fd-measure-band .fd-head {
	padding-top: var(--fd-card-pad-t) !important;
	padding-bottom: var(--fd-card-pad-b) !important;
}

.fd--ready:not(.fd--eyebrow-head) .fd-card.fd-measure-band .fd-eyebrow-slot {
	max-height: 0 !important;
	opacity: 0 !important;
	margin-bottom: 0 !important;
}

/* ── Head band + revealed region ───────────────────────────────────── */

.fd-head {
	position: relative;
	display: block;
	width: 100%;
	margin: 0;
	padding: var(--fd-card-pad-t) var(--fd-card-pad-r) var(--fd-card-pad-b) var(--fd-card-pad-l);
	transition:
		padding-top var(--fd-step) var(--fd-ease),
		padding-bottom var(--fd-step) var(--fd-ease);
}

/* The button wraps only the title text, so it stays valid inside a heading.
   ::after stretches its hit area across the band — and no further, so links
   inside an open card's body remain clickable.

   THE INTERACTIVE STATES ARE LISTED DELIBERATELY. Themes style bare `button`,
   and a type-plus-pseudo-class selector such as `button:hover` (0,0,1,1)
   outranks a lone class like `.fd-trigger` (0,0,1,0). Resetting only the
   default state therefore leaves the theme free to repaint the title the
   moment it is hovered or focused — Hello Elementor's reset.css does exactly
   that, painting button:hover with its own accent. `.fd-trigger:hover`
   (0,0,2,0) reclaims it from a bare theme.

   It does NOT reclaim it from Elementor. A kit writes its global button styles
   as `.elementor-kit-123 button:hover`, which is (0,0,2,1) — one element more
   than `.fd-trigger:hover` and therefore the winner. That is why a deck on a
   site with Global Settings > Buttons configured repaints on hover no matter
   what the widget's own Style controls say. Scoping every one of these to the
   deck root, `.fd .fd-trigger:hover` (0,0,3,0), puts them back in front
   without reaching for !important.

   white-space is reset for the same reason: that theme pins buttons to nowrap,
   which would stop a long title from ever wrapping. Everything here is a
   neutralisation of generic form styling, not a design choice — the deck's
   real appearance comes from the widget's Style controls. */
.fd .fd-trigger,
.fd .fd-trigger:hover,
.fd .fd-trigger:focus,
.fd .fd-trigger:active,
.fd .fd-trigger:visited {
	display: inline;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: none;
	box-shadow: none;
	font: inherit;
	color: inherit;
	letter-spacing: inherit;
	text-transform: inherit;
	text-align: inherit;
	text-decoration: none;
	white-space: inherit;
	transition: none;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
	/* The card moves out from under the pointer as it is clicked, so without
	   this the browser can read press-then-move as a drag and select the label.
	   A control's own label should not be selectable regardless. Scoped to the
	   trigger, so body copy inside an open card stays selectable and copyable. */
	-webkit-user-select: none;
	user-select: none;
}

.fd-trigger::after {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 1;
}

.fd-trigger:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 3px;
}

.fd-card.is-active .fd-trigger {
	cursor: default;
}


/* ── Hover ──────────────────────────────────────────────────────────────
   Only collapsed cards respond: they are the ones that do something when
   clicked. The open card is already open, so a hover state there would
   promise an action that does not exist.

   Motion goes through --fd-hover-y / --fd-hover-scale rather than a transform
   of its own, so it composes with the riffle instead of overwriting it, and a
   card being animated is excluded outright — the deck is mid-flight and the
   pointer happens to be over it. */
.fd--ready .fd-card:not(.is-active):hover {
	--fd-hover-y: var(--fd-hover-lift, 0px);
	--fd-hover-scale: var(--fd-hover-zoom, 1);
}

.fd.is-animating .fd-card:hover {
	--fd-hover-y: 0px;
	--fd-hover-scale: 1;
}

@media (hover: none) {
	/* A touch device holds :hover after a tap, which would leave a card stuck
	   in its hover state behind the one that just opened. */
	.fd--ready .fd-card:not(.is-active):hover {
		--fd-hover-y: 0px;
		--fd-hover-scale: 1;
	}
}

/* THE TUCK ZONE.
   Overlapping means the top --fd-overlap pixels of every collapsed card sit
   behind the card above and cannot be seen. So a collapsed head reserves that
   much extra top padding, pushing its title down into the part that is
   actually visible. Two things fall out of this: the title stops being
   eclipsed, and the head now exactly fills the collapsed card — which is what
   stops the body underneath peeking out below the title. */
.fd--ready.fd--text .fd-head,
.fd--ready.fd--split .fd-head {
	padding-top: calc(var(--fd-card-pad-t) + var(--fd-overlap, 0px));
}

/* A collapsed head is meant to exactly fill its card, which is what keeps the
   revealed region below the fold. "Exactly" is the problem: the band height is
   measured with offsetHeight, which rounds to whole pixels, while real text
   layout is fractional. Round up and the card ends a fraction taller than the
   head — enough to show the top edge of whatever the reveal begins with, most
   visibly an image. Filling the card outright removes the class of bug instead
   of chasing the fraction. */
.fd--ready.fd--text .fd-card:not(.is-active):not(.is-flying) .fd-head,
.fd--ready.fd--split .fd-card:not(.is-active):not(.is-flying) .fd-head {
	min-height: 100%;
}

.fd-measuring .fd-head {
	min-height: 0 !important;
}

/* An open card has nothing above it, so it needs no tuck zone. The
   title-to-body gap belongs to the open card only, so a collapsed card keeps
   its normal bottom padding and the band stays tight. A card in flight counts
   as open until it starts shrinking, so its interior does not reflow on the
   way up. */
.fd--ready.fd--text .fd-card.is-active .fd-head,
.fd--ready.fd--split .fd-card.is-active .fd-head,
.fd--ready.fd--text .fd-card.is-flying:not(.fd-shrink) .fd-head,
.fd--ready.fd--split .fd-card.is-flying:not(.fd-shrink) .fd-head {
	padding-top: var(--fd-card-pad-t);
	padding-bottom: var(--fd-body-gap);
}

.fd-reveal {
	padding: 0 var(--fd-card-pad-r) var(--fd-card-pad-b) var(--fd-card-pad-l);
}

.fd-title {
	margin: 0;
	font-size: 16px;
	font-weight: 700;
	line-height: 1.35;
	color: #ffffff;
	transition: color var(--fd-step) linear;
}

.fd-body {
	margin: 0;
	color: #d7d7d7;
	font-size: 15px;
	line-height: 1.7;
}

.fd-body > *:first-child { margin-top: 0; }
.fd-body > *:last-child  { margin-bottom: 0; }

.fd-eyebrow {
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.06em;
	line-height: 1.3;
	color: #ffffff;
}

/* By default the eyebrow belongs to the open card only, so a collapsed card
   shows nothing but its title. Text and Split clip from the bottom, so the
   eyebrow has to be collapsed deliberately; Image clips from the top, where
   anything above the label is cut off for free. */
.fd--ready.fd--text .fd-eyebrow-slot,
.fd--ready.fd--split .fd-eyebrow-slot {
	overflow: hidden;
	max-height: 0;
	opacity: 0;
	margin-bottom: 0;
	transition:
		max-height var(--fd-step) var(--fd-ease),
		opacity calc(var(--fd-step) * 0.7) linear,
		margin-bottom var(--fd-step) var(--fd-ease);
}

.fd--ready.fd--text .fd-card.is-active .fd-eyebrow-slot,
.fd--ready.fd--split .fd-card.is-active .fd-eyebrow-slot,
.fd--ready.fd--text .fd-card.is-flying:not(.fd-shrink) .fd-eyebrow-slot,
.fd--ready.fd--split .fd-card.is-flying:not(.fd-shrink) .fd-eyebrow-slot {
	max-height: var(--fd-eyebrow-h, 4em);
	opacity: 1;
	margin-bottom: var(--fd-eyebrow-gap);
}

/* The switch that keeps the eyebrow on collapsed cards too. */
.fd--eyebrow-head.fd--ready.fd--text .fd-eyebrow-slot,
.fd--eyebrow-head.fd--ready.fd--split .fd-eyebrow-slot {
	max-height: none;
	opacity: 1;
	margin-bottom: var(--fd-eyebrow-gap);
}

/* ── Split layout ──────────────────────────────────────────────────── */

.fd--split .fd-split {
	display: flex;
	flex-direction: var(--fd-split-dir);
	gap: var(--fd-media-gap);
	align-items: flex-start;
}

.fd--split .fd-text {
	flex: 1 1 auto;
	min-width: 0;
}

.fd--split .fd-media {
	flex: 0 0 auto;
	width: var(--fd-media-w);
	max-width: 100%;
	overflow: hidden;
	line-height: 0;
}

.fd--split .fd-media img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: var(--fd-media-ar);
	object-fit: cover;
}

/* ── Image layout ──────────────────────────────────────────────────── */

.fd--image .fd-card {
	background: none;
}

/* Before init the frame is in normal flow at its natural height, so a
   visitor with no JavaScript sees every picture in full. The sizer is only
   needed once the frame is lifted out of flow. */
.fd--image .fd-ar {
	display: none;
}

.fd--image .fd-frame {
	position: relative;
	width: 100%;
	overflow: hidden;
	line-height: 0;
}

.fd--image .fd-frame img {
	--fd-img-gray: 100%;
	--fd-img-bright: 55%;
	display: block;
	width: 100%;
	height: auto;
	object-fit: cover;
	filter: grayscale(var(--fd-img-gray)) brightness(var(--fd-img-bright));
	transition: filter var(--fd-step) linear;
}

.fd--image .fd-card.is-active .fd-frame img {
	--fd-img-gray: 0%;
	--fd-img-bright: 100%;
}

.fd--ready.fd--image .fd-ar {
	display: block;
	width: 100%;
	aspect-ratio: var(--fd-image-ar);
}

/* NOTE: this layout deliberately has NO card-height rule of its own.
   --fd-collapsed-h is the editor's INPUT — the strip height asked for. The
   height a card is actually given is --fd-band-h, which the script computes
   from it by adding the overlap and applying the label floor. Sizing a card
   from the input instead skips both corrections, and because a
   .fd--ready.fd--image .fd-card selector outranks the shared
   .fd--ready .fd-card one, it does so silently and only for this layout.
   Card height belongs to the shared rules above. Leave it there. */

/* Bottom-pinned at a fixed height, so shrinking the card clips the TOP of
   the picture and the image itself never moves, rescales or squashes. */
.fd--ready.fd--image .fd-frame {
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	height: var(--fd-open-h);
}

.fd--ready.fd--image .fd-frame img {
	height: 100%;
}

/* Covers the whole card and bottom-anchors its contents, so the label sits
   in the visible strip in both states. */
.fd--image .fd-head {
	display: flex;
	flex-direction: column;
	align-items: var(--fd-pill-align);
	justify-content: flex-end;
	padding: 0 var(--fd-pill-x) var(--fd-pill-y);
}

.fd--ready.fd--image .fd-head {
	position: absolute;
	inset: 0;
}

.fd--image .fd-title {
	display: inline-block;
	padding: 8px 16px;
	border-radius: 99px;
	background: rgba(20, 20, 20, 0.72);
	font-size: 13px;
	letter-spacing: 0.04em;
	transition:
		color var(--fd-step) linear,
		background-color var(--fd-step) linear;
}

.fd--image .fd-eyebrow-slot {
	margin-bottom: var(--fd-eyebrow-gap);
}

/* ── Reduced motion ────────────────────────────────────────────────────
   No flight and no auto-advance (the script disables the timer separately).
   Cards still change slot instantly, so the deck remains fully usable. */
@media (prefers-reduced-motion: reduce) {
	.fd--ready .fd-deck,
	.fd--ready .fd-card,
	.fd--ready .fd-head,
	.fd--ready .fd-eyebrow-slot,
	.fd--image .fd-frame img,
	.fd-title {
		transition: none !important;
	}

	.fd--ready .fd-card.is-flying {
		animation: none !important;
	}
}