/*
 * SIA Card Base — the shared "image on top, copy below" card.
 *
 * Used by BOTH the Blog Posts widgets (post-driven) and Content Cards
 * (hand-written repeater). The card markup and every style control are
 * identical between them; only the SOURCE differs, so the card lives here
 * rather than inside either module — on the frontend Elementor loads only
 * ACTIVE modules, so a module-owned stylesheet can never be shared.
 *
 * The class prefix is `sia-bp` for historical reasons (it started life in the
 * Blog Posts module, v4.x) and is deliberately NOT renamed: the selectors are
 * referenced by every Style control in trait-card-controls.php, and by whatever
 * custom CSS sites have already written against live Blog Posts widgets.
 * Read it as "SIA base post card", not "blog posts only".
 *
 * Layout — how the cards are ARRANGED — is not here. Each widget owns that:
 * modules/blog-posts/assets/css/blog-posts.css (list / grid / carousel),
 * modules/content-cards/assets/css/content-cards.css (grid).
 *
 * Colors flow through the theme chain (--sia-color-primary/secondary/text).
 */

.sia-bp { position: relative; }

/* ─── Card ─── */
/* `box-sizing: border-box` is load-bearing for the hover Border control: it
   lets a card that has no border at rest gain one on hover without growing —
   the border eats into the padding box instead of pushing the card's own
   footprint outward and nudging the grid. */
.sia-bp__card {
	position: relative;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	box-sizing: border-box;
	background: #fff;
	border: 1px solid var(--sia-bp-line, #e3e5f2);
	border-radius: 12px;
	height: 100%;
	/* Keeps the text crisp while the card is mid-lift. A transform promotes the
	   card to its own compositor layer, and without this hint the type is
	   re-rasterised at fractional offsets on every frame. */
	backface-visibility: hidden;
	/* Unconditional — before v5.1.2 the transition only existed under
	   `.sia-bp-lift-yes`, so a card styled with a hover background or border but
	   WITHOUT the lift snapped between states instead of easing.

	   `border-width` is deliberately NOT in this list, though the Hover tab can
	   change it. Border width is a LAYOUT property: animating it reflows the
	   content box on every frame, so the copy shifts by fractions of a pixel
	   continuously and reads as the text blurring (reported in v5.2.4). A width
	   change now snaps while the colour still fades, which is both cheaper and
	   what the eye actually wants. */
	transition:
		transform var(--sia-bp-card-ease, 0.22s) var(--sia-bp-curve, cubic-bezier(0.22, 0.61, 0.36, 1)),
		box-shadow var(--sia-bp-card-ease, 0.22s) var(--sia-bp-curve, cubic-bezier(0.22, 0.61, 0.36, 1)),
		background-color var(--sia-bp-card-ease, 0.22s) var(--sia-bp-curve, cubic-bezier(0.22, 0.61, 0.36, 1)),
		border-color var(--sia-bp-card-ease, 0.22s) var(--sia-bp-curve, cubic-bezier(0.22, 0.61, 0.36, 1));
}
.sia-bp-lift-yes .sia-bp__card:hover {
	transform: translateY(calc(var(--sia-bp-lift, 4px) * -1));
	box-shadow: var(--sia-bp-lift-shadow, 0 10px 28px -10px rgba(20, 24, 57, 0.22));
	border-color: transparent;
}

/* ─── Media ─── */
.sia-bp__media {
	position: relative;
	overflow: hidden;
	line-height: 0;
	aspect-ratio: var(--sia-bp-ratio, auto);
}
.sia-bp__media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Slower than the card's own lift on purpose: the photo is the thing being
	   looked at, and a zoom that finishes at the same moment as the lift reads
	   as one abrupt jump rather than two layers settling. */
	transition: transform var(--sia-bp-zoom-ease, 0.45s) var(--sia-bp-curve, cubic-bezier(0.22, 0.61, 0.36, 1));
}
.sia-bp-zoom-yes .sia-bp__card:hover .sia-bp__media img {
	transform: scale(var(--sia-bp-zoom, 1.055));
}
/* Optional gradient/tint over the photo. Painted on a pseudo-element, which
   also means it survives Elementor's background lazy-load rule — that one
   strips `background-image` from DESCENDANTS via a trailing `*`, and `*` does
   not match pseudo-elements. Empty until an overlay control sets one. */
.sia-bp__media::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	/* Both overlay controls paint THIS element, so normal → hover cross-fades
	   rather than stacking a second tint over the photo. */
	transition:
		background-color var(--sia-bp-card-ease, 0.25s) ease,
		background-image var(--sia-bp-card-ease, 0.25s) ease,
		opacity var(--sia-bp-card-ease, 0.25s) ease;
}

/* Terms over the image */
.sia-bp__cats--over {
	position: absolute;
	top: 12px;
	left: 12px;
	z-index: 3;
	line-height: 1.2;
}

/* ─── Body ─── */
/* `gap` rather than per-element margins: it keeps the rhythm even when a card
   is missing its terms, meta or excerpt, which is what made the old
   margin-bottom stack leave uneven holes. `flex: 1 1 0` (not auto) so every
   card in a row resolves to the same height and the read-more can be pinned to
   the bottom of it. */
.sia-bp__body {
	display: flex;
	flex-direction: column;
	gap: var(--sia-bp-body-gap, 9px);
	padding: 18px 19px 20px;
	flex: 1 1 0;
}

/* ─── Terms ─── */
.sia-bp__cats {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
}
.sia-bp__cat {
	position: relative;
	z-index: 2; /* clickable above the card stretched-link */
	display: inline-block;
	padding: 4px 10px;
	font-size: 12px;
	font-weight: 600;
	line-height: 1.2;
	border-radius: 4px;
	text-decoration: none;
	color: var(--sia-color-primary, #6EC1E4);
	background: color-mix(in srgb, var(--sia-color-secondary, #54595F) 12%, transparent);
}
a.sia-bp__cat:hover { text-decoration: underline; }

/* ─── Title ─── */
.sia-bp__title {
	margin: 0;
	font-size: 16px;
	font-weight: 800;
	line-height: 1.28;
	letter-spacing: -0.015em;
	color: var(--sia-color-text, #141839);
	transition: color var(--sia-bp-card-ease, 0.22s) ease;
}
.sia-bp__title a {
	color: inherit;
	text-decoration: none;
}

/* ─── Meta ─── */
.sia-bp__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 14px;
	font-size: 13px;
	color: #6b7280;
}
.sia-bp__meta-item {
	display: inline-flex;
	align-items: center;
	gap: 5px;
}
.sia-bp__icon {
	width: 1em;
	height: 1em;
	flex: 0 0 auto;
	opacity: 0.85;
}
.sia-bp__meta a { color: inherit; text-decoration: none; }

/* ─── Excerpt ─── */
.sia-bp__excerpt {
	margin: 0;
	font-size: 13.9px;
	color: var(--sia-bp-muted, #5b5f86);
	line-height: 1.55;
	transition: color var(--sia-bp-card-ease, 0.22s) ease;
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	overflow: hidden;
}

/* ─── Read more ─── */
/* `align-self: flex-start` keeps the underline/hit area to the text width
   rather than the full card. The top margin is the MINIMUM gap; pinning to the
   bottom is opt-in below. */
.sia-bp__more {
	display: inline-flex;
	align-items: center;
	align-self: flex-start;
	gap: 7px;
	margin-top: 6px;
	font-size: 13.1px;
	font-weight: 700;
	text-decoration: none;
	color: var(--sia-color-primary, #6EC1E4);
	transition: color var(--sia-bp-card-ease, 0.22s) ease;
}

/* Pin the link to the bottom of the card (opt-in, `bp_more_pin`).
   `margin-top: auto` inside the column flex body eats all the leftover space,
   so every card in a row lands its link on the same line no matter how long
   the copy above it runs — which is the only way to get them level when the
   descriptions differ in length. Needs the body at `flex: 1 1 0` to have space
   to give away, which it now is. */
.sia-bp-pin-yes .sia-bp__more {
	margin-top: auto;
	padding-top: var(--sia-bp-more-gap, 6px);
}
/* A real read-more link (card not clickable) must sit above nothing special;
   when the whole card IS a link the read-more is a <span> and must stay BELOW
   the stretched link so the click falls through to the card. Only raise a
   genuine standalone link. */
a.sia-bp__more {
	position: relative;
	z-index: 2;
}
/* When the whole card is a link, the read-more is a non-interactive cue. */
span.sia-bp__more { cursor: pointer; }

/* ─── Read-more icon ───
   The icon can be the built-in arrow (an inline SVG, `.sia-bp__icon`) or any
   Elementor icon the user picks (`.sia-bp__more-icon > svg|i`). Both are sized
   and animated through the wrapper, so the animations below don't care which
   one is in the markup. */
.sia-bp__more-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	line-height: 1;
	transition: transform var(--sia-bp-anim-time, 0.2s) ease, opacity var(--sia-bp-anim-time, 0.2s) ease;
}
.sia-bp__more-icon > svg,
.sia-bp__more-icon > i {
	width: 1.05em;
	height: 1.05em;
	display: block;
	fill: currentColor;
}
.sia-bp__more-icon > i {
	width: auto;
	height: auto;
	font-size: 1.05em;
}

/* Animations. The mode is a wrapper class (Elementor `prefix_class`), so it
   lands on the widget root and gates the hover rule from outside the card. */
.sia-bp-anim-slide .sia-bp__card:hover .sia-bp__more-icon {
	transform: translateX(var(--sia-bp-anim-dist, 4px));
}
.sia-bp-anim-slide-up .sia-bp__card:hover .sia-bp__more-icon {
	transform: translate(var(--sia-bp-anim-dist, 4px), calc(var(--sia-bp-anim-dist, 4px) * -1));
}
/* Swap — the arrow leaves to the right and a fresh one arrives from the left.
   Done as ONE keyframe on a single element rather than two stacked copies:
   the icon is user-supplied, and duplicating arbitrary icon markup (webfont
   <i>, inline SVG, an <img>) invites duplicate ids and double-decoded assets. */
.sia-bp-anim-swap .sia-bp__card:hover .sia-bp__more-icon {
	animation: sia-bp-icon-swap calc(var(--sia-bp-anim-time, 0.2s) * 2.4) ease;
}
@keyframes sia-bp-icon-swap {
	0%   { transform: translateX(0);     opacity: 1; }
	45%  { transform: translateX(160%);  opacity: 0; }
	46%  { transform: translateX(-160%); opacity: 0; }
	100% { transform: translateX(0);     opacity: 1; }
}
.sia-bp-anim-pop .sia-bp__card:hover .sia-bp__more-icon {
	transform: scale(1.35);
}
.sia-bp-anim-rotate .sia-bp__card:hover .sia-bp__more-icon {
	transform: rotate(45deg);
}
/* Nudge — the whole read-more block moves, icon included. */
.sia-bp-anim-nudge .sia-bp__card:hover .sia-bp__more {
	transform: translateX(var(--sia-bp-anim-dist, 4px));
}
.sia-bp-anim-nudge .sia-bp__more {
	transition: transform var(--sia-bp-anim-time, 0.2s) ease, color 0.2s ease;
}

/* ─── Whole-card stretched link (Rule 8) ─── */
.sia-bp__link {
	position: absolute;
	inset: 0;
	z-index: 1;
	background: transparent;
	border-radius: inherit;
}

/* ─── Empty state ─── */
.sia-bp--empty {
	padding: 24px;
	text-align: center;
	color: #9ca3af;
	font-style: italic;
	border: 1px dashed #d1d5db;
	background: #f9fafb;
	border-radius: 12px;
}

/* color-mix() fallback for legacy browsers */
@supports not (color: color-mix(in srgb, red, blue)) {
	.sia-bp__cat { background: var(--sia-color-secondary, #54595F); color: #fff; }
}

@media (prefers-reduced-motion: reduce) {
	.sia-bp__card,
	.sia-bp__media img,
	.sia-bp__media::after,
	.sia-bp__excerpt,
	.sia-bp__title,
	.sia-bp__more,
	.sia-bp__more-icon {
		transition: none !important;
		animation: none !important;
	}
	.sia-bp-lift-yes .sia-bp__card:hover { transform: none; }
	.sia-bp-zoom-yes .sia-bp__card:hover .sia-bp__media img { transform: none; }
	.sia-bp__card:hover .sia-bp__more-icon,
	.sia-bp__card:hover .sia-bp__more { transform: none; }
}
