/**
 * Boksiowo Portal Engine PRO — Homepage module styles.
 * Used by both the optional front-page template and the
 * [bpe_featured_articles] / [bpe_latest_articles] shortcodes.
 */

.bpe-homepage-section {
	margin: 32px 0;
}

.bpe-homepage-section__title {
	margin: 0 0 20px;
	/* Both this and .bpe-hb-section__heading are <h2>s that otherwise
	   fall through to Astra's global H2 size (40px/52px line-height) —
	   fine for a single page title, too large repeated 5 times down one
	   homepage. Scoped here rather than touched globally, since a
	   site-wide H2 change would affect article pages and every other H2
	   on the site, not just these homepage section titles. */
	font-size: 1.75rem;
	line-height: 1.3;
}

.bpe-homepage-grid {
	display: grid;
	grid-template-columns: repeat(var(--bpe-columns, 3), 1fr);
	gap: 24px;
}

@media (max-width: 900px) {
	.bpe-homepage-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 600px) {
	.bpe-homepage-grid {
		grid-template-columns: 1fr;
	}
}

.bpe-homepage-card {
	border: 1px solid #d9e0e7;
	border-radius: 6px;
	overflow: hidden;
	display: flex;
	flex-direction: column;
}

.bpe-homepage-card--featured {
	border-color: #ff6b1a;
}

.bpe-homepage-card__thumb {
	display: block;
	/* Fixed crop height instead of the previous `height: auto` — featured
	   images have wildly different native proportions, so without this
	   every card in a row (trending's [bpe_trending_articles], the
	   homepage-builder "cards" hero) ended up a different height,
	   defeating the grid it sits in. Matches .bpe-article-card__thumb's
	   own value so the two card components read as one consistent system. */
	/* 210px (was 190px): proportional bump to match the wider card that
	   results from the 1200->1360px container increase — not an
	   independent height change, so the crop ratio stays close to before. */
	height: 210px;
	overflow: hidden;
}

.bpe-homepage-card__thumb img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.bpe-homepage-card__body {
	padding: 16px;
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.bpe-homepage-card__title {
	margin: 0;
	/* ETAP 3: was 1.1rem — bumped to match .bpe-article-card__title's
	   1.15rem and the video card title added this same pass, so every
	   card type on the homepage (trending/latest/featured/video) now
	   shares one title size instead of a near-but-not-quite mismatch. */
	font-size: 1.15rem;
	font-weight: 600;
	/* See .bpe-article-card__excerpt's comment (articles.css) — same
	   unclamped-text problem, same fix. */
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	overflow: hidden;
}

.bpe-homepage-card__title a {
	text-decoration: none;
}

.bpe-homepage-card__date {
	font-size: 0.85rem;
	color: #46515f;
}

.bpe-homepage-card__excerpt {
	font-size: 0.95rem;
	color: #46515f;
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	overflow: hidden;
}

.bpe-homepage-empty {
	color: #46515f;
	padding: 20px 0;
}

/**
 * Homepage Builder (v1.23.0) — section wrapper output by
 * Section_Renderer::wrap(). Class names below must stay in sync with
 * that method.
 */

.bpe-hb-section {
	/* Split from a single --bpe-hb-color-primary (was #d4351c, a
	   WordPress-core "danger" red never actually part of Boksiowo's
	   granat/biały/pomarańczowy palette) into two roles that were being
	   conflated: headings/stat values read as calm navy; buttons/CTAs/
	   hovers use the brand's real accent orange. Both stay overridable
	   per-section via the existing "color_primary" builder setting
	   (Section_Renderer already writes it as this same custom property
	   when set — see wrap()).
	*/
	/* ETAP 2 (kompozycja): Astra's Customizer base was updated to a new
	   palette (accent #FF6B1A, headings #172B4D, body #46515F, borders
	   #D9E0E7 — confirmed live via computed styles on body/h2, not
	   assumed) — these two variables were still the OLD values, a
	   concrete conflict since every homepage section reads them. */
	--bpe-hb-color-primary: #172b4d;
	--bpe-hb-color-accent: #ff6b1a;
	--bpe-hb-color-background: transparent;
	background: var(--bpe-hb-color-background);
}

/* Full-front-page breakout (added with the 1360px .bpe-hb-section__inner
   widening above): the whole Homepage Builder render sits inside Astra's
   own #bpe-homepage -> .ast-container, whose theme-level "Container
   Width" (Customizer, site-wide, 1240px here) silently capped every
   section to ~1200px content width no matter what max-width this
   plugin's own CSS set — .bpe-hb-section__inner's 1360px cap was
   therefore never actually reachable. Rather than raise Astra's global
   setting (would resize every other page on the site, not just the
   homepage), every homepage section now uses the exact same
   theme-agnostic calc(50% - 50vw) breakout .bpe-hb-hero already relied
   on (see below) to escape its container — scoped to "#bpe-homepage" so
   a [bpe module="..."] section embedded inside normal post content
   elsewhere (Universal_Shortcode, not this front-page template) is
   completely unaffected. .bpe-hb-section__inner's own max-width then
   centers the real content within the freed-up full viewport. */
#bpe-homepage .bpe-hb-section {
	width: 100vw;
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
}

/* #bpe-homepage itself sits as a flex/shrink-to-fit item in Astra's own
   markup, not a plain block box. Once every child above uses a 100vw
   width, the browser's shrink-to-fit ("fit-content") calculation for
   THIS element sees a vw-based (viewport-relative, not content-relative)
   child size and resolves its own width to 0 instead of the normal
   "fill the containing block" behaviour a plain block would use — which
   in turn breaks the calc(50% - 50vw) math above (it needs an accurate
   containing-block width to cancel out to the true viewport edge).
   Pinning this to 100% forces the normal fill behaviour back. */
#bpe-homepage {
	width: 100%;
}

.bpe-hb-section__heading {
	margin: 0 0 16px;
	color: var(--bpe-hb-color-primary);
	/* See .bpe-homepage-section__title's comment just above — same
	   Astra-inherited 40px H2 default, same scoped-down fix. */
	font-size: 1.75rem;
	line-height: 1.3;
}

.bpe-hb-section__heading + .bpe-hb-section__subheading {
	margin: -14px 0 20px;
}

.bpe-hb-section__subheading {
	margin: 0 0 20px;
	color: #46515f;
	font-size: 1.05rem;
}

/* Alignment fix: Section_Renderer::wrap() (class-section-renderer.php)
   outputs the heading/subheading as SIBLINGS of .bpe-hb-section__inner,
   both direct children of <section> — confirmed via the live HTML
   (curl), not assumed. That was harmless while <section> itself was
   boxed by Astra's theme container, but since the ETAP 2 breakout made
   <section> span the full viewport, the heading (with no width/centering
   rule of its own) started spanning edge-to-edge while
   .bpe-hb-section__inner's cards stayed centered at 1360px below it —
   exactly the "heading left, cards indented" misalignment reported live.
   Selector specificity matches the "heading + subheading" rule above and
   is placed after it, so only margin-left/right change here — the
   existing top/bottom margins on each rule are left intact. */
.bpe-hb-section .bpe-hb-section__heading,
.bpe-hb-section .bpe-hb-section__subheading {
	max-width: 1360px;
	margin-left: auto;
	margin-right: auto;
	padding-left: 24px;
	padding-right: 24px;
	box-sizing: border-box;
}

.bpe-hb-section__cta {
	display: inline-block;
	margin-top: 20px;
	padding: 10px 22px;
	background: var(--bpe-hb-color-accent, #ff6b1a);
	color: #fff;
	text-decoration: none;
	border-radius: 4px;
	font-weight: 600;
}

.bpe-hb-section__cta:hover,
.bpe-hb-section__cta:focus {
	opacity: 0.9;
	color: #fff;
}

.bpe-hb-section__inner {
	/* Raised from 1200px: on anything wider than ~1400px this container
	   left 35-65% of the viewport as unused side margin, which read as a
	   narrow single column rather than a portal using its screen. 1360px
	   keeps a controlled, professional margin at 1920px+ (doesn't stretch
	   edge-to-edge) while nearly filling common 1440px laptop screens. */
	max-width: 1360px;
	margin: 0 auto;
	padding: 0 24px;
}

.bpe-hb-section--spacing-top-none { padding-top: 0; }
.bpe-hb-section--spacing-top-small { padding-top: 16px; }
.bpe-hb-section--spacing-top-default { padding-top: 32px; }
.bpe-hb-section--spacing-top-large { padding-top: 56px; }

.bpe-hb-section--spacing-bottom-none { padding-bottom: 0; }
.bpe-hb-section--spacing-bottom-small { padding-bottom: 16px; }
.bpe-hb-section--spacing-bottom-default { padding-bottom: 32px; }
.bpe-hb-section--spacing-bottom-large { padding-bottom: 56px; }

.bpe-hb-section--style-cards .bpe-hb-section__inner {
	background: #fff;
	border-radius: 8px;
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
	padding: 24px 20px;
}

.bpe-hb-section--style-minimal .bpe-hb-section__heading {
	font-size: 1.15rem;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

.bpe-hb-section--style-list .bpe-hb-section__inner {
	max-width: 760px;
}

/*
 * Scroll-reveal animations: only armed once homepage-builder-frontend.js
 * has confirmed IntersectionObserver support (it adds "bpe-hb-anim-ready"
 * to <html>) and toggles "is-visible" as each section enters the
 * viewport. Without JS, or before that class lands, sections stay fully
 * visible — so nothing ever gets stuck invisible.
 */

.bpe-hb-anim-ready .bpe-hb-section--anim-fade {
	opacity: 0;
	transition: opacity 0.6s ease;
}

.bpe-hb-anim-ready .bpe-hb-section--anim-fade.is-visible {
	opacity: 1;
}

.bpe-hb-anim-ready .bpe-hb-section--anim-slide-up {
	opacity: 0;
	transform: translateY(24px);
	transition: opacity 0.6s ease, transform 0.6s ease;
}

.bpe-hb-anim-ready .bpe-hb-section--anim-slide-up.is-visible {
	opacity: 1;
	transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
	.bpe-hb-anim-ready .bpe-hb-section--anim-fade,
	.bpe-hb-anim-ready .bpe-hb-section--anim-slide-up {
		opacity: 1;
		transform: none;
		transition: none;
	}
}

/*
 * Sprint 1, Etap 1.1 — shared Image Picker component's frontend rendering.
 * Every image rendered by Image_Renderer::render() (class-image-renderer.php)
 * is a `.bpe-img-frame` wrapping one `.bpe-img-frame__img` — fit, position,
 * corner radius, shadow, hover-zoom and entrance-animation are all defined
 * ONCE here, so any current or future Homepage Builder section that mounts
 * the shared Image Picker (see builder.php's #bpe-hb-image-picker-template)
 * gets identical, already-tested styling instead of its own copy.
 */
.bpe-img-frame {
	position: relative;
	display: block;
	overflow: hidden;
}

.bpe-img-frame__img {
	display: block;
	width: 100%;
	height: 100%;
}

.bpe-img-frame--fit-cover .bpe-img-frame__img {
	object-fit: cover;
}

.bpe-img-frame--fit-contain .bpe-img-frame__img {
	object-fit: contain;
}

.bpe-img-frame--position-center .bpe-img-frame__img { object-position: center; }
.bpe-img-frame--position-top .bpe-img-frame__img { object-position: top; }
.bpe-img-frame--position-bottom .bpe-img-frame__img { object-position: bottom; }
.bpe-img-frame--position-left .bpe-img-frame__img { object-position: left; }
.bpe-img-frame--position-right .bpe-img-frame__img { object-position: right; }

/* Radius buckets: "medium" (16px) intentionally matches the "split" Hero
   layout's pre-Etap-1.1 hardcoded border-radius — see the long comment on
   `hero_image_radius` in class-section.php for why that is the default. */
.bpe-img-frame--radius-none { border-radius: 0; }
.bpe-img-frame--radius-small { border-radius: 8px; }
.bpe-img-frame--radius-medium { border-radius: 16px; }
.bpe-img-frame--radius-large { border-radius: 24px; }

.bpe-img-frame--shadow {
	box-shadow: 0 20px 40px rgba(15, 23, 42, 0.18);
}

.bpe-img-frame--hover-zoom {
	transition: transform 0.4s ease;
}

.bpe-img-frame--hover-zoom:hover .bpe-img-frame__img,
.bpe-img-frame--hover-zoom:focus-within .bpe-img-frame__img {
	transform: scale(1.06);
}

.bpe-img-frame--hover-zoom .bpe-img-frame__img {
	transition: transform 0.4s ease;
}

/*
 * Entrance animation reuses the exact same "bpe-hb-anim-ready"/"is-visible"
 * mechanism as the whole-section animations above — extended here to also
 * watch individual framed images (see initScrollReveal() in
 * assets/js/homepage-builder-frontend.js).
 */
.bpe-hb-anim-ready .bpe-img-frame--anim-fade {
	opacity: 0;
	transition: opacity 0.6s ease;
}

.bpe-hb-anim-ready .bpe-img-frame--anim-fade.is-visible {
	opacity: 1;
}

.bpe-hb-anim-ready .bpe-img-frame--anim-zoom-in {
	opacity: 0;
	transform: scale(0.92);
	transition: opacity 0.6s ease, transform 0.6s ease;
}

.bpe-hb-anim-ready .bpe-img-frame--anim-zoom-in.is-visible {
	opacity: 1;
	transform: scale(1);
}

.bpe-hb-anim-ready .bpe-img-frame--anim-slide-up {
	opacity: 0;
	transform: translateY(24px);
	transition: opacity 0.6s ease, transform 0.6s ease;
}

.bpe-hb-anim-ready .bpe-img-frame--anim-slide-up.is-visible {
	opacity: 1;
	transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
	.bpe-hb-anim-ready .bpe-img-frame--anim-fade,
	.bpe-hb-anim-ready .bpe-img-frame--anim-zoom-in,
	.bpe-hb-anim-ready .bpe-img-frame--anim-slide-up {
		opacity: 1;
		transform: none;
		transition: none;
	}

	.bpe-img-frame--hover-zoom,
	.bpe-img-frame--hover-zoom .bpe-img-frame__img {
		transition: none;
	}

	.bpe-img-frame--hover-zoom:hover .bpe-img-frame__img,
	.bpe-img-frame--hover-zoom:focus-within .bpe-img-frame__img {
		transform: none;
	}
}

.bpe-hb-hide-desktop,
.bpe-hb-hide-tablet,
.bpe-hb-hide-mobile {
	display: initial;
}

@media (min-width: 901px) {
	.bpe-hb-hide-desktop { display: none !important; }
}

@media (min-width: 601px) and (max-width: 900px) {
	.bpe-hb-hide-tablet { display: none !important; }
}

@media (max-width: 600px) {
	.bpe-hb-hide-mobile { display: none !important; }
}

/* Hero (Sprint 1) */

.bpe-hb-hero {
	--bpe-hero-title-color: #fff;
	--bpe-hero-text-color: #f2f2f2;
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: center;
	background-color: #1d2327;
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
	overflow: hidden;
	padding: 48px 24px;
	box-sizing: border-box;
	/*
	 * Full-bleed breakout: the Homepage Builder's own output has no width
	 * constraint of its own (see templates/homepage/front-page.php), but
	 * it still renders inside get_header()/get_footer() — i.e. inside
	 * whatever content-width wrapper the ACTIVE THEME's header.php opens
	 * (Astra's default "boxed" content area, ~1200-1400px). Without this,
	 * a "pełnoekranowe tło" Hero is visually boxed like a regular content
	 * block instead of the edge-to-edge banner its own name promises —
	 * confirmed live on a fresh Astra install. `calc(50% - 50vw)` is the
	 * standard theme-agnostic fix: the 50% is relative to the (centered)
	 * parent, so it exactly cancels the parent's own offset from the
	 * viewport edge, landing this element flush with the real viewport
	 * edge regardless of how deeply nested it is or how wide the parent
	 * container is — no JS, works even if a future theme swap changes
	 * that container's width.
	 */
	width: 100vw;
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
}

.bpe-hb-hero--height-small { min-height: 320px; }
.bpe-hb-hero--height-medium { min-height: 480px; }
.bpe-hb-hero--height-large { min-height: 640px; }
.bpe-hb-hero--height-fullscreen { min-height: 100vh; }

.bpe-hb-hero__content {
	position: relative;
	z-index: 1;
	max-width: 760px;
	width: 100%;
	margin: 0 auto;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.bpe-hb-hero--align-left .bpe-hb-hero__content {
	margin-left: 48px;
	margin-right: auto;
	text-align: left;
	align-items: flex-start;
}

/* Contrast safety net for left-aligned text over a photo, without a
   flat tint across the whole image (would dull it everywhere, not just
   behind the text) and without depending on the optional
   hero_overlay_color setting (unset here, and its fixed 60% opacity
   would be heavier than this photo needs). A left-to-right darkening
   fades out by the horizontal midpoint, so the photo's right two-thirds
   — where the subject is — stays exactly as bright/vivid as the
   original. `.bpe-hb-hero__content` already sets z-index:1 to sit above
   this. Desktop-only (min-width matches the point .bpe-hb-hero--align-left
   stops being re-centred by the mobile block below); mobile already has
   its own bottom-anchored gradient + text-shadow further down. */
@media (min-width: 601px) {
	.bpe-hb-hero--align-left::before {
		content: "";
		position: absolute;
		inset: 0;
		background: linear-gradient(to right, rgba(15, 23, 42, 0.6) 0%, rgba(15, 23, 42, 0.25) 40%, rgba(15, 23, 42, 0) 65%);
		pointer-events: none;
	}

	.bpe-hb-hero--align-left .bpe-hb-hero__title,
	.bpe-hb-hero--align-left .bpe-hb-hero__subtitle {
		text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
	}
}

.bpe-hb-hero--align-center .bpe-hb-hero__content {
	text-align: center;
	align-items: center;
}

.bpe-hb-hero--align-right .bpe-hb-hero__content {
	margin-left: auto;
	margin-right: 48px;
	text-align: right;
	align-items: flex-end;
}

.bpe-hb-hero__title {
	margin: 0;
	font-size: clamp(28px, 5vw, 52px);
	font-weight: 800;
	line-height: 1.1;
	color: var(--bpe-hero-title-color);
}

.bpe-hb-hero__subtitle {
	margin: 0;
	font-size: clamp(16px, 2.2vw, 22px);
	font-weight: 600;
	color: var(--bpe-hero-text-color);
}

.bpe-hb-hero__description {
	margin: 0;
	font-size: 16px;
	line-height: 1.6;
	color: var(--bpe-hero-text-color);
	max-width: 60ch;
}

.bpe-hb-hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	margin-top: 8px;
}

.bpe-hb-hero--align-center .bpe-hb-hero__actions { justify-content: center; }
.bpe-hb-hero--align-right .bpe-hb-hero__actions { justify-content: flex-end; }

.bpe-hb-hero__cta {
	display: inline-block;
	padding: 14px 28px;
	border-radius: 999px;
	font-weight: 700;
	font-size: 16px;
	text-decoration: none;
	transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.bpe-hb-hero__cta--primary {
	background: var(--bpe-hb-color-accent, #ff6b1a);
	color: #fff;
}

.bpe-hb-hero__cta--secondary {
	background: transparent;
	color: var(--bpe-hero-title-color);
	border: 2px solid var(--bpe-hero-title-color);
}

.bpe-hb-hero__cta:hover,
.bpe-hb-hero__cta:focus {
	transform: translateY(-2px);
	box-shadow: 0 6px 18px rgba(0, 0, 0, 0.25);
}

@media (max-width: 900px) {
	.bpe-hb-hero--height-large { min-height: 480px; }
	.bpe-hb-hero--height-fullscreen { min-height: 80vh; }
}

@media (max-width: 600px) {
	.bpe-hb-hero {
		padding: 24px 16px 240px;
		text-align: center;
		/* Anchor content toward the bottom of the image instead of dead
		   centre: a photo's face/subject is very often centred, so
		   vertically-centred text is the layout most likely to land right
		   on top of it. Bottom-anchoring keeps the upper two-thirds of the
		   photo clear and pairs with the gradient below, which is darkest
		   exactly where the text now sits.
		   The large bottom padding (vs. 32px elsewhere) reserves room for
		   the fixed LUKI/Boksio AI dock that sits on top of the hero's
		   bottom-right corner at this same breakpoint (see
		   .bpe-ai-chat__luki-teaser in ai-chat.css) — content stays flush
		   above that reserved strip instead of running underneath it. */
		justify-content: flex-end;
	}

	/* Readability safety net: guarantees contrast for white hero text
	   regardless of what's directly behind it in the photo, rather than
	   relying on the image happening to be dark there. content:"" keeps
	   this out of the accessibility tree. */
	.bpe-hb-hero::before {
		content: "";
		position: absolute;
		inset: 0;
		background: linear-gradient(to top, rgba(0, 0, 0, 0.72) 0%, rgba(0, 0, 0, 0.32) 45%, rgba(0, 0, 0, 0.05) 75%);
		pointer-events: none;
	}

	.bpe-hb-hero--height-medium { min-height: 380px; }
	.bpe-hb-hero--height-large { min-height: 420px; }
	.bpe-hb-hero--height-fullscreen { min-height: 70vh; }

	.bpe-hb-hero--align-left .bpe-hb-hero__content,
	.bpe-hb-hero--align-right .bpe-hb-hero__content {
		margin-left: auto;
		margin-right: auto;
		text-align: center;
		align-items: center;
	}

	.bpe-hb-hero__title,
	.bpe-hb-hero__subtitle {
		text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
	}

	.bpe-hb-hero--align-left .bpe-hb-hero__actions,
	.bpe-hb-hero--align-right .bpe-hb-hero__actions {
		justify-content: center;
	}

	.bpe-hb-hero__cta {
		flex: 1 1 auto;
		text-align: center;
	}
}

/* Hero — "split" layout (Sprint 1, Etap 1) */

.bpe-hb-hero--split {
	--bpe-hero-title-color: #1d2327;
	--bpe-hero-text-color: #4b5563;
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	/*
	 * Etap 2A fix: was "center" — a grid item with align-items:center
	 * shrinks to its own content height instead of stretching to fill the
	 * row, so .bpe-hb-hero__split-media's "height:100%" (and the .bpe-img-
	 * frame/.bpe-img-frame__img "height:100%" chain inside it — see
	 * class-image-renderer.php's frontend rendering rules above) had no
	 * resolvable height to fill, breaking the picked photo's display.
	 * "stretch" (the grid default) lets both columns share the row's real
	 * height instead; .bpe-hb-hero__split-text re-centers its own content
	 * with justify-content below, so the text still looks vertically
	 * centered exactly as before.
	 */
	align-items: stretch;
	gap: 56px;
	padding: 88px 48px;
	background: linear-gradient(180deg, #eef2ff 0%, #fff 60%);
	background-image: none;
}

.bpe-hb-hero--split.bpe-hb-hero--height-small { min-height: 320px; }
.bpe-hb-hero--split.bpe-hb-hero--height-medium { min-height: 420px; }
.bpe-hb-hero--split.bpe-hb-hero--height-large { min-height: 560px; }
.bpe-hb-hero--split.bpe-hb-hero--height-fullscreen { min-height: 100vh; }

.bpe-hb-hero__split-text {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 20px;
	max-width: 560px;
}

.bpe-hb-hero--split .bpe-hb-hero__title {
	color: var(--bpe-hero-title-color);
}

.bpe-hb-hero--split .bpe-hb-hero__subtitle,
.bpe-hb-hero--split .bpe-hb-hero__description {
	color: var(--bpe-hero-text-color);
}

.bpe-hb-hero--split .bpe-hb-hero__actions {
	margin-top: 8px;
	gap: 16px;
}

.bpe-hb-hero--split .bpe-hb-hero__cta {
	padding: 16px 32px;
	font-size: 16px;
}

.bpe-hb-hero--split .bpe-hb-hero__cta--primary {
	background: var(--bpe-hb-color-primary, #2563eb);
	box-shadow: 0 14px 28px -10px rgba(37, 99, 235, 0.5);
}

.bpe-hb-hero--split .bpe-hb-hero__cta--secondary {
	color: var(--bpe-hb-color-primary, #2563eb);
	border-color: var(--bpe-hb-color-primary, #2563eb);
}

.bpe-hb-hero--split .bpe-hb-hero__cta--secondary:hover,
.bpe-hb-hero--split .bpe-hb-hero__cta--secondary:focus {
	background: var(--bpe-hb-color-primary, #2563eb);
	color: #fff;
}

.bpe-hb-hero__split-media {
	width: 100%;
	height: 100%;
	min-height: 380px;
}

/*
 * Sprint 1, Etap 1.1: the photo itself is now rendered by
 * Image_Renderer::render() as a .bpe-img-frame > .bpe-img-frame__img (see
 * class-image-renderer.php) — fit/position/radius/shadow/hover-zoom/
 * entrance-animation rules for that shared component live further down
 * this file, so .bpe-hb-hero__split-media only needs to size the frame
 * to fill its column.
 */
.bpe-hb-hero__split-media .bpe-img-frame {
	width: 100%;
	height: 100%;
	min-height: 380px;
}

/*
 * Etap 2A (poprawka): statystyki jako właściwe kafelki (karta: tło,
 * obramowanie, cień, zaokrąglenie), nie wiersz z separatorami — ikona w
 * okrągłym tle + liczba + podpis, wyśrodkowane. Nadal czysty CSS
 * (::before jako ikona) — te same, prawdziwe liczby ze Stats_Helper,
 * żadna zmiana znaczników ani logiki.
 */
.bpe-hb-hero__stats {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 16px;
	margin-top: 40px;
}

.bpe-hb-hero__stat {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: 8px;
	padding: 22px 12px;
	background: #fff;
	border: 1px solid rgba(37, 99, 235, 0.12);
	border-radius: 16px;
	box-shadow: 0 10px 24px -14px rgba(15, 23, 42, 0.25);
}

.bpe-hb-hero__stat::before {
	content: "🐾";
	display: flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	border-radius: 50%;
	background: rgba(37, 99, 235, 0.1);
	font-size: 15px;
	line-height: 1;
}

.bpe-hb-hero__stat-value {
	font-size: clamp(28px, 3.6vw, 38px);
	font-weight: 800;
	color: var(--bpe-hb-color-primary, #2563eb);
	line-height: 1.1;
	font-variant-numeric: tabular-nums;
}

.bpe-hb-hero__stat-label {
	font-size: 12px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: var(--bpe-hero-text-color);
}

@media (max-width: 900px) {
	.bpe-hb-hero--split {
		grid-template-columns: 1fr;
		gap: 32px;
		padding: 56px 24px;
	}

	.bpe-hb-hero__split-text {
		max-width: none;
		text-align: center;
		align-items: center;
	}

	.bpe-hb-hero--split .bpe-hb-hero__actions {
		justify-content: center;
	}

	.bpe-hb-hero__split-media {
		order: -1;
		min-height: 280px;
	}

	.bpe-hb-hero__split-media .bpe-img-frame {
		min-height: 280px;
	}

	/* Tablet: 2x2 tiles instead of a cramped 4-across row. */
	.bpe-hb-hero__stats {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 600px) {
	.bpe-hb-hero__stats {
		gap: 12px;
	}

	.bpe-hb-hero__stat {
		padding: 18px 10px;
	}
}

/* Newsletter section */

.bpe-hb-newsletter {
	max-width: 640px;
	margin: 0 auto;
	text-align: center;
}

.bpe-hb-newsletter__description {
	margin: 0 0 16px;
	color: #46515f;
}

.bpe-hb-newsletter__row {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	justify-content: center;
}

.bpe-hb-newsletter__input {
	flex: 1 1 260px;
	padding: 10px 14px;
	border: 1px solid #d9e0e7;
	border-radius: 4px;
	font-size: 1rem;
}

.bpe-hb-newsletter__submit {
	padding: 10px 22px;
	background: var(--bpe-hb-color-accent, #ff6b1a);
	color: #fff;
	border: none;
	border-radius: 4px;
	font-weight: 600;
	cursor: pointer;
}

.bpe-hb-newsletter__submit:hover {
	opacity: 0.9;
}

.bpe-hb-newsletter__hp {
	position: absolute !important;
	left: -9999px !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.bpe-hb-newsletter__message {
	margin: 12px 0 0;
	font-size: 0.9rem;
}

.bpe-hb-newsletter__message--success {
	color: #1a7f37;
}

/* Statystyki section */

.bpe-hb-stats {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
	gap: 24px;
	text-align: center;
}

.bpe-hb-stats__item {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.bpe-hb-stats__value {
	font-size: 2.4rem;
	font-weight: 700;
	line-height: 1.1;
	color: var(--bpe-hb-color-primary, #ff6b1a);
}

.bpe-hb-stats__label {
	font-size: 0.95rem;
	color: #46515f;
}

@media (max-width: 600px) {
	.bpe-hb-stats {
		grid-template-columns: repeat(2, 1fr);
	}
}

.bpe-hb-newsletter__message--error {
	color: #b32d2e;
}

/* Partners / Sponsors logo grid */

.bpe-hb-logo-grid {
	display: grid;
	grid-template-columns: repeat(var(--bpe-hb-logo-cols, 4), 1fr);
	gap: 24px;
	align-items: center;
}

.bpe-hb-logo-grid--cols-1 { --bpe-hb-logo-cols: 1; }
.bpe-hb-logo-grid--cols-2 { --bpe-hb-logo-cols: 2; }
.bpe-hb-logo-grid--cols-3 { --bpe-hb-logo-cols: 3; }
.bpe-hb-logo-grid--cols-4 { --bpe-hb-logo-cols: 4; }
.bpe-hb-logo-grid--cols-5 { --bpe-hb-logo-cols: 5; }
.bpe-hb-logo-grid--cols-6 { --bpe-hb-logo-cols: 6; }

@media (max-width: 900px) {
	.bpe-hb-logo-grid {
		grid-template-columns: repeat(3, 1fr);
	}
}

@media (max-width: 600px) {
	.bpe-hb-logo-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

.bpe-hb-logo-grid__item {
	display: flex;
	align-items: center;
	justify-content: center;
	filter: grayscale(100%);
	opacity: 0.75;
	transition: opacity 0.2s ease, filter 0.2s ease;
}

.bpe-hb-logo-grid__item:hover {
	filter: grayscale(0%);
	opacity: 1;
}

.bpe-hb-logo-grid__img {
	max-width: 100%;
	height: auto;
}

/* Footer Builder (v1.33.0) */

.bpe-hb-footer {
	display: grid;
	grid-template-columns: repeat(var(--bpe-hb-footer-cols, 4), 1fr);
	gap: 32px;
	align-items: start;
}

.bpe-hb-footer--cols-1 { --bpe-hb-footer-cols: 1; }
.bpe-hb-footer--cols-2 { --bpe-hb-footer-cols: 2; }
.bpe-hb-footer--cols-3 { --bpe-hb-footer-cols: 3; }
.bpe-hb-footer--cols-4 { --bpe-hb-footer-cols: 4; }

@media (max-width: 900px) {
	.bpe-hb-footer {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 600px) {
	.bpe-hb-footer {
		grid-template-columns: 1fr;
	}
}

.bpe-hb-footer__column {
	display: flex;
	flex-direction: column;
	gap: 14px;
	min-width: 0;
}

.bpe-hb-footer__widget {
	min-width: 0;
}

.bpe-hb-footer-widget__logo-link {
	display: inline-block;
}

/* The uploaded custom logo (Wygląd → Dostosuj → Tożsamość strony) has a
   transparent background with white lettering, designed to sit on a dark
   surface — same asset the header's .bpe-header__logo:has(img) gives a
   dark chip to (see header.css) for the same reason. Unlike the header,
   this chip is NOT conditioned on html.bpe-dark: on this site that class
   does not reliably track the footer's actual rendered background (it can
   be present while the footer still renders light), so a conditional
   chip here would go dark-mode-invisible again on a light-background
   render — always showing the chip is the safe choice: the wordmark
   needs it whenever the surface behind it is actually light, and a
   dark-on-dark chip is a harmless no-op when the surface is actually
   dark. */
.bpe-hb-footer-widget__logo-link:has(img) {
	background: #111827;
	padding: 12px 22px;
	border-radius: 10px;
}

/* Specificity note: assets/css/public.css's generic ".bpe-frontend img {
   max-width: 100% }" reset (specificity 0,1,1) otherwise beats a single
   ".bpe-hb-footer-widget__logo-img" class (0,1,0) — this selector chains
   the wrapping link's class too (0,2,0) so the enlarged size here actually
   wins instead of silently falling back to the generic reset. */
.bpe-hb-footer-widget__logo-link .bpe-hb-footer-widget__logo-img {
	max-width: 240px;
	height: auto;
}

.bpe-hb-footer-widget__logo-text {
	font-size: 20px;
	font-weight: 700;
	text-decoration: none;
	color: inherit;
}

.bpe-hb-footer-widget__description {
	margin: 0;
	opacity: 0.85;
	line-height: 1.6;
}

.bpe-hb-footer-widget__menu-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.bpe-hb-footer-widget__menu-list a {
	text-decoration: none;
	color: inherit;
	opacity: 0.85;
}

.bpe-hb-footer-widget__menu-list a:hover {
	opacity: 1;
	text-decoration: underline;
}

.bpe-hb-footer-widget__html {
	line-height: 1.6;
}

.bpe-hb-footer-widget__social {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

.bpe-hb-footer-widget__social-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	border-radius: 50%;
	background: rgba(127, 127, 127, 0.12);
	color: inherit;
	transition: background-color 0.15s ease, opacity 0.15s ease;
	opacity: 0.85;
}

.bpe-hb-footer-widget__social-link:hover {
	opacity: 1;
	background: var(--bpe-hb-color-accent, #ff6b1a);
	color: #fff;
}

.bpe-hb-footer-widget__copyright {
	margin: 0;
	font-size: 13px;
	opacity: 0.75;
}

.bpe-hb-footer-widget__link {
	display: inline-block;
	text-decoration: none;
	color: inherit;
	opacity: 0.85;
	font-size: 13px;
}

.bpe-hb-footer-widget__link:hover {
	opacity: 1;
	text-decoration: underline;
}

/* "Poznaj rasę bokser" intro block */

.bpe-hb-breed-intro {
	display: grid;
	gap: 40px;
}

.bpe-hb-breed-intro--with-media {
	grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
	align-items: center;
}

.bpe-hb-breed-intro__media .bpe-img-frame {
	width: 100%;
}

.bpe-hb-breed-intro__media .bpe-img-frame__img {
	width: 100%;
	height: 100%;
	max-height: 480px;
}

.bpe-hb-breed-intro__tiles {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 20px;
}

.bpe-hb-breed-intro--with-media .bpe-hb-breed-intro__tiles {
	grid-template-columns: repeat(2, 1fr);
}

.bpe-hb-breed-tile {
	padding: 24px 20px;
	background: #f7f7f8;
	border-radius: 12px;
	text-align: left;
}

.bpe-hb-breed-tile__title {
	margin: 0 0 8px;
	font-size: 1.05rem;
	color: var(--bpe-hb-color-primary, #ff6b1a);
}

.bpe-hb-breed-tile__text {
	margin: 0;
	font-size: 0.92rem;
	line-height: 1.6;
	color: #46515f;
}

@media (max-width: 900px) {
	.bpe-hb-breed-intro--with-media {
		grid-template-columns: 1fr;
	}

	.bpe-hb-breed-intro__media .bpe-img-frame__img {
		max-height: 360px;
	}

	.bpe-hb-breed-intro__tiles {
		grid-template-columns: repeat(2, 1fr);
	}

	.bpe-hb-breed-intro--with-media .bpe-hb-breed-intro__tiles {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 600px) {
	.bpe-hb-breed-intro__tiles,
	.bpe-hb-breed-intro--with-media .bpe-hb-breed-intro__tiles {
		grid-template-columns: 1fr;
	}
}

/* ETAP 2 (kompozycja) — "Wyróżnione artykuły" ([bpe_featured], meta_key
   _bpe_featured). Was: repeat(auto-fit, minmax(340px,1fr)) — equal-size
   cards (ETAP 3). Brief now asks for an editorial "1 large + rest
   small" layout instead. Single fallback (auto-fit) still covers the
   1-item and 4+-item cases; the 2-column magazine split below only
   engages when a real 2nd card exists (:has), so it adapts to whatever
   count is actually flagged Featured without a template/data change. */
.bpe-hb-section--featured .bpe-shortcode__grid {
	grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
}

@media (min-width: 769px) {
	.bpe-hb-section--featured .bpe-shortcode__grid:has(> :nth-child(2)) {
		grid-template-columns: 2fr 1fr;
		grid-auto-rows: 1fr;
		align-items: stretch;
	}

	.bpe-hb-section--featured .bpe-shortcode__grid:has(> :nth-child(2)) > :nth-child(1) {
		grid-column: 1;
		grid-row: 1 / -1;
		display: flex;
		flex-direction: column;
	}

	.bpe-hb-section--featured .bpe-shortcode__grid:has(> :nth-child(2)) > :nth-child(1) .bpe-article-card__thumb {
		height: 380px;
	}

	.bpe-hb-section--featured .bpe-shortcode__grid:has(> :nth-child(2)) > :nth-child(1) .bpe-article-card__title {
		font-size: 1.55rem;
		-webkit-line-clamp: 3;
	}

	.bpe-hb-section--featured .bpe-shortcode__grid:has(> :nth-child(2)) > :nth-child(1) .bpe-article-card__body {
		flex: 1;
		justify-content: center;
	}

	.bpe-hb-section--featured .bpe-shortcode__grid:has(> :nth-child(2)) > :nth-child(2) {
		grid-column: 2;
		grid-row: 1;
	}

	.bpe-hb-section--featured .bpe-shortcode__grid:has(> :nth-child(2)) > :nth-child(3) {
		grid-column: 2;
		grid-row: 2;
	}

	/* Secondary cards (2nd, 3rd...): compact module, not a shrunk copy of
	   the spotlight — smaller thumb, no excerpt, so they read as
	   secondary at a glance instead of competing with card 1. */
	.bpe-hb-section--featured .bpe-shortcode__grid:has(> :nth-child(2)) > :nth-child(n+2) .bpe-article-card {
		display: flex;
		flex-direction: row;
		height: 100%;
	}

	.bpe-hb-section--featured .bpe-shortcode__grid:has(> :nth-child(2)) > :nth-child(n+2) .bpe-article-card__thumb {
		width: 120px;
		height: auto;
		flex-shrink: 0;
	}

	.bpe-hb-section--featured .bpe-shortcode__grid:has(> :nth-child(2)) > :nth-child(n+2) .bpe-article-card__excerpt {
		display: none;
	}

	.bpe-hb-section--featured .bpe-shortcode__grid:has(> :nth-child(2)) > :nth-child(n+2) .bpe-article-card__title {
		font-size: 1rem;
		-webkit-line-clamp: 3;
	}

	.bpe-hb-section--featured .bpe-shortcode__grid:has(> :nth-child(2)) > :nth-child(n+2) .bpe-article-card__body {
		justify-content: center;
		gap: 4px;
	}
}

/* ETAP 3 — Newsletter: purely decorative, CSS-only icon (no new copy —
   the section's "subheading"/"description" Builder fields are both
   empty right now, checked in bpe_homepage_layouts before touching
   this, so nothing is invented here beyond a glyph in front of the
   existing "Newsletter" heading). Centered to match the already-centered
   .bpe-hb-newsletter card below it. */
.bpe-hb-section--newsletter .bpe-hb-section__heading {
	text-align: center;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
}

.bpe-hb-section--newsletter .bpe-hb-section__heading::before {
	content: "\2709";
	color: var(--bpe-hb-color-accent, #ff6b1a);
	font-size: 1.4rem;
}
