/* ============================================================
   Agru-Frank — Sekcja "Produkty" (home). Tokeny z base.css.
   ============================================================ */

/* --- Nagłówek sekcji: .section-head w utilities.css --- */

.products-cf__title {
	white-space: pre-line;   /* wymuszony \n w label (products-data.php) = twardy podział wiersza */
}

/* ============================================================
   Karuzela — Embla Carousel (free-drag + momentum + loop) + coverflow scale.
   Silnik: assets/js/vendor/embla-carousel.umd.js. Scale-tween: products-coverflow.js.
   No-JS / mobile (<768): natywny poziomy scroll ze snapem (fallback).
   Klasa .is-coverflow (na .products) = Embla aktywny.
   ============================================================ */

.products-cf {
	--cf-card-w: 400px; /* why: dopasowane do najdłuższej etykiety kategorii (39 znaków) w 1
	                        wierszu + naturalny 2-wierszowy wrap tytułu, patrz --cf-card-h */
	--cf-card-h: 300px; /* why: +40px zapasu na 2-wierszowy tytuł */
	position: relative;
	margin-top: 0;   /* .products-cf__viewport ma WŁASNY padding-block:32px — margin tu by się
	                    do niego DODAWAŁ, dając za duży odstęp */
}
@media (max-width: 767.98px) {
	.products-cf {
		--cf-card-w: 70%; /* why: peek-next-card (Embla align:center) — pełna karta na środku +
		                      widoczne fragmenty sąsiadów; 85% dawało peek tylko z jednej strony */
		--cf-card-h: 316px; /* why: dopasowane do 2-wierszowego tytułu na węższej karcie (70%),
		                        jak desktop --cf-card-w */
		width: calc(100% + 2 * var(--container-pad));
		margin-inline: calc(-1 * var(--container-pad));
		margin-top: 0;   /* .products-cf__viewport ma WŁASNY padding-block:32px, który się DODAJE
		                    do tego marginesu — stąd zero tutaj, nie ruszać */
		/* full-bleed jak desktop (tam 100vw @992px) — bez tego peek obcinał się na gutterze
		   containera. calc zamiast 100vw: 100vw wciąga szerokość scrollbara (patrz hero__stats-list). */
	}
	.products-cf__title {
		white-space: normal;   /* desktop ma wymuszony \n (pre-line) — węższa karta (70%) ma
		                           naturalny wrap zamiast sztywnego punktu złamania */
	}
	.products-cf__card .u-desc {
		-webkit-line-clamp: 3;   /* .u-card--elevated .u-desc globalnie ma 2 — węższa karta (70%)
		                             łamie tekst na więcej linii, 2 obcinało za wcześnie. Scoped tu,
		                             nie w utilities.css (inne elevated-card konteksty mają inną szer.). */
	}
}

/* Viewport = maska Embla; padding daje przestrzeń na cień karty (nie ucina góra/dół).
   Top mniejszy niz bottom: --shadow-mega (0 8px 24px) siega w gore tylko 24-8=16px
   (blur minus offset), w dol 8+24=32 — top:16 to bezpieczne minimum, nie 32 jak reszta. */
.products-cf__viewport {
	position: relative;
	overflow: hidden;
	padding-top: var(--space-16);
	padding-bottom: var(--space-32);
}

/* Container — Embla przesuwa transformem; w fallbacku natywny scroll */
.products-cf__track {
	display: flex;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Slajd — stała szerokość; odstęp jednolity przez margin-right (nie flex-gap: Embla loop liczy spójnie, w tym styk last↔first) */
.products-cf__slide {
	flex: 0 0 var(--cf-card-w);
	min-width: 0;
	height: var(--cf-card-h);
	margin-right: var(--space-32); /* gap większy niż 24: krzyżyki narożne (8px poza kartą) potrzebują oddechu, spójne z logistics.css */
}

/* Dwa wiersze marquee (snake: górny → / dolny ←), odstęp między nimi */
.products-cf__row + .products-cf__row {
	margin-top: var(--space-24);
}

/* Fallback (bez Embla — mobile / no-JS): poziomy scroll ze snapem.
   padding-block:8px — .u-card--elevated::before (krzyzyki) ma inset:-8px, czyli zamierzony
   overshoot 8px na KAZDA strone karty. Bez zapasu w torze ten overshoot liczy sie jako realny
   overflow (scrollHeight > clientHeight), a overflow-x:auto na tym samym elemencie wymusza
   overflow-y:auto przez CSS mixed-axis quirk (jedna os "visible" + druga nie-visible → visible
   liczy sie jako auto) — stad scrollbar mimo ze tekst karty mieści sie normalnie w 260px. */
.products-cf__row:not(.is-coverflow) .products-cf__track {
	overflow-x: auto;
	padding: var(--space-32);    /* nie tylko krzyzyki (8px) — box-shadow: var(--shadow-mega) ma
	                                 offset 8 + blur 24, realny zasieg do ~32px. Ta sama wartosc co
	                                 .products-cf__viewport padding-block, sprawdzona pod ten sam cel. */
	scroll-snap-type: x mandatory;
	scrollbar-width: none;       /* chowa natywny scrollbar (Firefox) — swipe dziala, UI nie */
	touch-action: pan-x;         /* overflow-x:auto bez jawnego overflow-y liczy sie jako auto na
	                                 obu osiach (mixed-axis quirk) — bez tego karte dawalo sie
	                                 przeciagac tez pionowo. pan-x ogranicza gesty do poziomu. */
}
.products-cf__row:not(.is-coverflow) .products-cf__track::-webkit-scrollbar {
	display: none;                /* Chrome/Safari */
}
/* Embla teraz zawsze docelowy silnik (desktop+mobile) — fallback wyglada wyraznie inaczej
   (flush-left zamiast wysrodkowanej karty + peek z obu stron), wiec przed window.load byl
   widoczny "skok" do finalnego stanu. Chowamy fallback na 400ms — jesli JS zdazy (typowo),
   .is-coverflow pojawi sie i ta regula juz nie dotyczy elementu; jesli JS sie nie wykona
   (blad/no-JS), po 400ms fallback i tak sam sie odsłania — nigdy nie zostaje trwale ukryty. */
.products-cf__row:not(.is-coverflow) .products-cf__viewport {
	opacity: 0;
	animation: cf-reveal-fallback 0s linear 400ms forwards;
}
@keyframes cf-reveal-fallback {
	to { opacity: 1; }
}
.products-cf__row:not(.is-coverflow) .products-cf__slide {
	scroll-snap-align: center;
}
/* Viewport = maska Embla (transform-driven slides potrzebuja zewnetrznego overflow:hidden).
   W fallbacku track ma WLASNY overflow-x:auto — viewport-owy hidden jest zbedny i tnie poziomy
   overshoot krzyzykow narozncyh (.u-card--elevated::before, inset:-8px) bo viewport nie ma
   padding-inline (tylko padding-block, dla cienia). */
.products-cf__row:not(.is-coverflow) .products-cf__viewport {
	overflow: visible;
}
/* FOUC fix: is-coverflow dodawany asynchronicznie przez JS (products-coverflow.js,
   matchMedia min-width:768) — do tego momentu KAZDA szerokosc (w tym desktop) renderuje
   sie w fallbacku, wiec overflow-x:auto na torze pokazuje natywny scrollbar na chwile
   przed przejeciem przez Embla. Chowamy go tylko >=768 — mobile ma to jako docelowy stan. */
@media (min-width: 768px) {
	.products-cf__row:not(.is-coverflow) .products-cf__track {
		overflow-x: hidden;
	}
}

/* Embla aktywny: chwyt myszą + poziomy drag (pion scroll dozwolony) */
.products-cf__row.is-coverflow .products-cf__viewport {
	cursor: grab;
}
.products-cf__row.is-coverflow .products-cf__track {
	touch-action: pan-y pinch-zoom;
}
.products-cf__row.is-coverflow.is-dragging .products-cf__viewport {
	cursor: grabbing;
}
.products-cf__row.is-dragging {
	user-select: none;
}

/* --- Karta --- */
/* Box-model + krzyżyki narożne + ramka hover: .u-card--elevated w utilities.css
   (wzorzec 1:1, wyciągnięty stąd — reużyty też na industry-hub__card). */

/* Grid-pattern (siateczka w rogu) + opis + ikona: .u-card--elevated / .u-card-grid w utilities.css */

/* --- Nagłówek z flankującymi strzałkami (‹ H2 ›) --- */
.products-cf__nav {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-24);
}
.products-cf__nav .section-head__title {
	margin: 0; /* strzałki równo z H2, bez marginesów nagłówka */
}

/* --- Strzałki (widoczne tylko w trybie coverflow: .is-coverflow na sekcji) --- */
.products-cf__arrow {
	display: none;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: var(--space-48);
	height: var(--space-48);
	padding: 0;
	background: var(--white);
	border: 1px solid var(--border);
	border-radius: var(--radius-pill);
	color: var(--graphite);
	cursor: pointer;
	transition: border-color var(--transition-base), color var(--transition-base);
}
.products.is-coverflow .products-cf__arrow {
	display: inline-flex;
}
.products-cf__arrow:hover,
.products-cf__arrow:focus-visible {
	border-color: var(--blue);
	color: var(--blue);
}

/* --- A11Y: live region (ogłaszanie centralnej kategorii) — visually hidden --- */
.products-cf__live {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* Reduced-motion: JS ustawia Embla duration=0 (scrollTo bez animacji). Scale-tween to transform per klatkę, nie animacja CSS. */

/* --- Full-bleed: karuzela wypływa na całą szerokość ekranu (desktop) --- */
.products {
	overflow-x: clip; /* zabezpieczenie przed poziomym scrollem od 100vw */
}
@media (min-width: 992px) {
	.products-cf {
		width: 100vw;
		margin-left: calc(50% - 50vw);
	}
}

/* --- Link "katalog" --- */
.products__more {
	margin-top: var(--space-32);
	text-align: center;
}
/* .products__more-link: .u-cta w utilities.css */

@media (max-width: 767.98px) {
	.products__more {
		margin-top: 0;   /* .products-cf__viewport ma własny padding-block:32px (dolna krawędź
		                    też) — margin tu by się do niego dodawał, total ma być 32px */
	}
}

/* ============================================================
   Katalog produktów — strona kategorii + podstrona produktu. Wzorce: blog.css.
   Plik ładowany na: single product, taxonomy product_category, page-produkty.
   ============================================================ */

/* ---------- Hero (kategoria + hub) — migrowany do .u-hero/.u-hero--medium/.u-split
   (utilities.css), 1:1 z industry-hero. Pokrywa i page-produkty.php (hub), i
   section-product-category.php — obie uzywaja .u-hero teraz. ---------- */
/* .u-hero__lead p — hub renderuje the_content() (moze byc kilka akapitow, wzgl. .product-hero__intro) */
.u-hero__lead p { margin: 0 0 var(--space-16); }
.u-hero__lead p:last-child { margin-bottom: 0; }

/* ---------- Siatka produktów (kategoria + "Sprawdź także") ---------- */
.product-grid {
	display: grid;
	gap: var(--space-32);
	grid-template-columns: 1fr;
	list-style: none;
	margin: 0;
	padding: 0;
}
@media (min-width: 640px) {
	.product-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 992px) {
	.product-grid { grid-template-columns: repeat(4, 1fr); }
}
.product-grid__item { display: flex; }

/* .product-archive__empty -> .u-empty-state (utilities.css) */

/* ---------- Karta produktu — wzór blog-card ---------- */
/* Stylem firmowym jak .u-card--elevated (shadow-mega + krzyżyki narożne + hover-ramka,
   zero radiusa), ale osobna klasa — elevated jest tekstowa, ta karta ma slot na zdjęcie.
   TODO: scalić wzorzec krzyżyków (u-image / u-card--elevated / product-card / agf-tabs)
   w jedną utility. */
.product-card {
	position: relative;
	background: var(--white);
	box-shadow: var(--shadow-mega);
	display: flex;
	flex-direction: column;
	width: 100%;
}
.product-card__image-link { display: block; overflow: hidden; }
.product-card__image { aspect-ratio: 4 / 3; overflow: hidden; }
.product-card__image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform var(--transition-slow);
}
.product-card:hover .product-card__image img { transform: scale(1.03); }
/* Produkt bez zdjęcia — logo firmowe zamiast losowego stocka, nigdy nie cropowane,
   to samo tło co karta-placeholder niżej. */
.product-card__image img.product-card__image-placeholder {
	object-fit: contain;
	padding: var(--space-24);
	background: color-mix(in srgb, var(--graphite) 5%, var(--white));
}
.product-card:hover .product-card__image img.product-card__image-placeholder { transform: none; }
.product-card__body {
	padding: var(--space-24);
	display: flex;
	flex-direction: column;
	flex: 1;
	gap: var(--space-8);
}
.product-card__title {
	font-size: var(--text-lead);
	font-weight: 500;
	line-height: 1.3;
	color: var(--graphite);
	margin: 0;
}
.product-card__title a {
	color: inherit;
	text-decoration: none;
	transition: color var(--transition-fast);
}
.product-card__title a:hover { color: var(--blue); }
/* Karta = zdjęcie + tytuł + CTA, świadomie bez lead/opisu */
.product-card__cta {
	margin-top: var(--space-16);   /* reszta z u-cta--sm; product-card nie jest .u-card, wiec margin tutaj */
}

/* Karta placeholder — produkt bez podstrony (seed po arkuszu ~6.08); nazwa+link do slugu, brak
   foto. Zaprojektowana JAK realna karta (cień, CTA blue, media 4/3 jak zdjęcie) — jedyna
   różnica: media-slot szary zamiast zdjęcia. */
.product-card__image--empty {
	aspect-ratio: 4 / 3;
	background: color-mix(in srgb, var(--graphite) 5%, var(--white));
	display: grid;
	place-items: center;
}

/* ---------- Podstrona produktu: hero split ---------- */
.product-single__hero { padding-block: var(--section-py-compact); }
@media (max-width: 767.98px) {
	.product-single__hero { padding-block-start: var(--space-32); }   /* mobile: hero bliżej breadcrumbs niż desktop */
}
.product-single__hero-grid {
	display: grid;
	gap: var(--space-40);
	column-gap: var(--space-96);
	grid-template-columns: 1fr;
	align-items: center;
}
@media (min-width: 992px) {
	.product-single__hero-grid { grid-template-columns: 1fr 1fr; }
}
/* Zdjęcie hero: firmowy wzorzec .u-image (shadow-mega + krzyżyki, bez radiusa).
   aspect-ratio na BAZOWEJ klasie (nie .product-slideshow) — produkt z 1 zdjęciem
   nie dostaje klasy .product-slideshow (PHP: count($slides) > 1), więc bez tego
   img renderowałby się w naturalnej proporcji pliku, rozpychając kontener. */
.product-single__hero-media {
	aspect-ratio: 4 / 3;                                 /* stabilna wysokość — zero CLS przy zmianie slajdu */
}
.product-single__hero-media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Slideshow hero (featured + galeria) — crossfade, kropki kwadratowe (system: zero radiusa) */
.product-slideshow {
	cursor: zoom-in;                                     /* klik slajdu otwiera lightbox (kropki mają własny pointer) */
	/* bez overflow:hidden — ścinałby krzyżyki .u-image (wystają 8px);
	   slajdy nie wystają (inset 0 + object-fit cover przycina wewnątrz img) */
}
.product-slideshow .product-slideshow__slide {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0;
	transition: opacity var(--transition-slow);
	user-select: none;
	-webkit-user-drag: none;                             /* Safari/Chrome: bez ghost-dragu obrazka (FF: draggable="false" w markup) */
}
.product-slideshow .product-slideshow__slide.is-active { opacity: 1; }
/* ponytail: cover na wszystkich slajdach (31.07, decyzja Tomka — wypełnij frame).
   Portret miał wcześniej contain (28.07: zasuwy klinowe traciły pokrętło+kołnierz
   przy cover) — świadomie cofnięte, wyraźnie pionowe zdjęcia znów mogą tracić góra/dół. */
/* Brak zdjęcia — logo firmowe zamiast losowego stocka, nigdy nie cropowane. */
.product-slideshow__slide.is-placeholder {
	object-fit: contain;
	padding: var(--space-64);
	background: color-mix(in srgb, var(--graphite) 5%, var(--white));
}
/* Kropki: poziomo na dole, okrągłe (kanon nawigacji slidera = hero home). Widoczna 10px /
   aktywna 12px, ale klikalny obszar 24px (WCAG 2.2 SC 2.5.8 — hit area ważniejsza niż wygląd). */
.product-slideshow__dots {
	position: absolute;
	inset: auto 0 var(--space-16) 0;                     /* poziomo, 16px od dołu, wyśrodkowane */
	display: flex;
	justify-content: center;
	align-items: center;
	gap: var(--space-8);
	z-index: 1;
}
.product-slideshow__dot {
	position: relative;
	width: var(--space-24);
	height: var(--space-24);
	padding: 0;
	border: 0;
	background: transparent;
	cursor: pointer;
}
.product-slideshow__dot::before {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 10px;
	height: 10px;
	transform: translate(-50%, -50%);
	border-radius: 50%; /* css-lint-ok: kropka slidera = koło, kanon hero home (nie karta/CTA) */
	background: color-mix(in srgb, var(--graphite) 45%, transparent);
	transition: background var(--transition-fast), width var(--transition-fast), height var(--transition-fast);
}
.product-slideshow__dot.is-active::before {
	width: 12px;
	height: 12px;
	background: var(--blue);
}
.product-slideshow__dot:hover::before { background: var(--blue); }
.product-single__eyebrow {
	display: inline-block;
	font-size: var(--text-label);
	font-weight: 600;
	letter-spacing: 0.08em;   /* sync z pozostałymi eyebrow (hero-slider, blog-hero, product-hero) */
	text-transform: uppercase;
	color: var(--blue);
	text-decoration: none;
	margin: 0 0 var(--space-8);                          /* rytm hero home: 8/16/32 (sync 2026-07-22) */
}
.product-single__eyebrow:hover { text-decoration: underline; text-underline-offset: 3px; }
.product-single__title {
	font-size: var(--text-display);                      /* skala jak headline hero home */
	font-weight: 600;
	line-height: 1.1;
	color: var(--graphite);
	margin: 0 0 var(--space-16);
}
.product-single__lead {
	font-size: var(--text-lead);
	line-height: 1.7;
	color: color-mix(in srgb, var(--graphite) 80%, transparent);
	margin: 0 0 var(--space-32);
}
.product-single__actions { display: flex; gap: var(--space-16); flex-wrap: wrap; }

/* Przyciski karty: systemowy .agf-btn / .agf-btn--outline (base.css) —
   nie twórz lokalnej klasy przycisku tutaj. */

/* ---------- Sekcje produktu ---------- */
.product-section--alt {
	background: #3E3E3D0A;                                          /* fallback graphite 4% */
	background: color-mix(in srgb, var(--graphite) 4%, transparent);
}
.product-section__title {
	font-size: var(--text-h2);
	font-weight: 600;
	line-height: 1.2;
	color: var(--graphite);
	margin: 0 0 var(--space-32);
}
/* Offset kotwic pod sticky header + nav */
.product-section[id],
.product-single__hero[id] {
	scroll-margin-top: calc(var(--header-height) + var(--space-64));
}

/* Treść opisu — reuse stylu single-post body (produkty mają ten sam WYSIWYG) */
.product-single__body { font-size: var(--text-lead); line-height: 1.75; color: var(--graphite); max-width: var(--measure); }
.product-single__body p { margin: 0 0 var(--space-24); }
.product-single__body h2 { font-size: var(--text-h3); font-weight: 600; line-height: 1.25; margin: var(--space-32) 0 var(--space-24); color: var(--graphite); }   /* mobile ma inny top-margin, patrz blok niżej */
.product-single__body h3 { font-size: var(--text-h4); font-weight: 600; line-height: 1.3; margin: var(--space-32) 0 var(--space-16); color: var(--graphite); }
.product-single__body ul, .product-single__body ol { padding-left: var(--space-32); margin: 0 0 var(--space-24); }
.product-single__body li { margin-bottom: var(--space-8); }
.product-single__body a { color: var(--blue); text-decoration: underline; }
.product-single__body a:hover { color: var(--blue); }

/* Opis + branże: treść | aside (wzór .realization-single__layout) */
.product-opis__layout {
	display: grid;
	grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
	gap: var(--space-64);
	align-items: start;
}
@media (max-width: 991px) {
	.product-opis__layout { grid-template-columns: 1fr; gap: var(--space-32); }
}
.product-industries-aside {
	position: sticky;
	top: calc(var(--header-height, 88px) + var(--space-24));
}
@media (max-width: 991px) {
	.product-industries-aside { position: static; }   /* pod opisem na tablet/mobile — kolejność DOM */
}
.product-industries-aside h3 { font-size: var(--text-h4); font-weight: 600; margin: 0 0 var(--space-24); color: var(--graphite); }
/* Tabele w treści (np. zakresy średnic półproduktów) — hairline, bez zebry */
.product-single__body table { width: 100%; border-collapse: collapse; margin: 0 0 var(--space-24); font-size: var(--text-body); }
.product-single__body th,
.product-single__body td { padding: var(--space-8) var(--space-16); border: 1px solid var(--border); text-align: left; }

/* Dostępne modele — prosta lista, typografia jak treść opisu */
.product-models { max-width: var(--measure); padding-left: var(--space-32); margin: 0; font-size: var(--text-lead); line-height: 1.75; color: var(--graphite); }
.product-models__item { margin-bottom: var(--space-8); }

/* Gdzie zastosowano — lista linków do realizacji (jak modele, ale klikalne + meta) */
.product-realizations { max-width: var(--measure); margin: 0; padding: 0; list-style: none; }
.product-realizations__item:not(:first-child) { border-top: 1px solid var(--border); }
.product-realizations__link { display: flex; align-items: center; justify-content: space-between; gap: var(--space-16); padding: var(--space-16) 0; text-decoration: none; }
.product-realizations__text { display: flex; flex-direction: column; gap: var(--space-4); }
.product-realizations__title { font-size: var(--text-lead); font-weight: 500; color: var(--graphite); }
.product-realizations__link:hover .product-realizations__title,
.product-realizations__link:focus-visible .product-realizations__title { color: var(--blue); }
.product-realizations__arrow { flex-shrink: 0; color: var(--blue); }

/* Mobile: typografia prozy tabów (za definicjami — kaskada) */
@media (max-width: 767.98px) {
	.product-single__body,
	.product-models { font-size: var(--text-body); }            /* proza tabów 16 — spójna ze specs/FAQ (16) */
	.product-models { list-style: none; padding-left: 0; }   /* od lewej; domknięcie dołu robi body (24); bullet własny (UA inside dawał za duży odstęp) */
	.product-models__item::before { content: "\2022"; margin-right: var(--space-8); }        /* • przy lewej, odstęp 8 */
	.product-single__body h2 {
		font-size: var(--text-lead);                            /* 17 — śródtytuły prozy bliżej tekstu (accordion ma własne nagłówki sekcji) */
		margin-top: var(--space-24);                            /* akapit→h2 = 24, jak nagłówek sekcji→treść (collapse z p margin-bottom 24) */
	}
}

/* ---------- Parametry techniczne ---------- */
.product-specs { margin: 0; max-width: var(--measure); }
.product-specs__row {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-8);
	padding: var(--space-24) 0;                          /* rytm jak FAQ (spójność) */
	border-bottom: 1px solid var(--border);
}
@media (min-width: 480px) {
	.product-specs__row { grid-template-columns: 240px 1fr; gap: var(--space-24); }
}
@media (max-width: 767.98px) {
	.product-specs__row { border-bottom: 0; padding: 0 0 var(--space-24); }   /* mobile: bez linii, suma odstępu między wierszami = 24 (top 0 + bottom 24) */
}
.product-specs__label { font-size: var(--text-body); font-weight: 600; color: var(--graphite); margin: 0; }
.product-specs__value { font-size: var(--text-body); color: color-mix(in srgb, var(--graphite) 80%, transparent); margin: 0; }

/* ---------- Galeria ---------- */
.product-gallery {
	display: grid;
	gap: var(--space-24);
	column-gap: var(--space-32);
	grid-template-columns: repeat(2, 1fr);
	list-style: none;
	margin: 0;
	padding: 0;
}
@media (min-width: 640px) { .product-gallery { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 992px) { .product-gallery { grid-template-columns: repeat(4, 1fr); } }
/* Mobile peek-carousele (Embla): galeria + Sprawdź także — wzorzec realizations:
   bleed do krawędzi, slajd 70%, padding-block 32 = zapas na shadow-mega + krzyżyki.
   Bez JS fallback = grid wyżej. */
@media (max-width: 767.98px) {
	#panel-galeria-body,
	#panel-sprawdz-takze-body { padding-bottom: 0; }         /* viewport karuzeli ma własny padding-block 32 (zapas na cień) — body dublowało */
	.agf-tabs__body > .product-gallery__viewport.is-embla,
	.agf-tabs__body > .product-related__viewport.is-embla {
		overflow: hidden;
		padding-block: var(--space-24);                      /* zapas na cień slajdów (nie ucina go overflow:hidden) */
		margin-block: calc(-1 * var(--space-24)) calc(-1 * var(--space-8));
		/* ujemne marginesy KOMPENSUJĄ zapas w rytmie sekcji (wzorzec home realizations):
		   nagłówek→slajd = pad acc 24 (zapas znika z odstępu), slajd→hairline = 24 (24+8 body − 8).
		   Prefiks .agf-tabs__body > podbija specificity nad reset ":first-child { margin-top:0 }"
		   z tabs.css (ładowany później — zerował górną kompensację). */
		width: calc(100% + 2 * var(--container-pad));
		margin-inline: calc(-1 * var(--container-pad));
		cursor: grab;
	}
	.agf-tabs__body > .product-related__viewport.is-embla { margin-block-end: 0; }   /* karty mają krzyżyki wystające 8px w dół — bez dolnej kompensacji (do hairline 32, do krzyżyka optycznie 24) */
	.product-gallery__viewport.is-embla.is-dragging,
	.product-related__viewport.is-embla.is-dragging {
		cursor: grabbing;
		user-select: none;
	}
	.product-gallery__viewport.is-embla .product-gallery,
	.product-related__viewport.is-embla .product-grid {
		display: flex;
		gap: 0;                                              /* gap gridu dublowałby się z margin-right slajdów (lekcja home) */
		margin: 0;
	}
	.product-gallery__viewport.is-embla .product-gallery__item,
	.product-related__viewport.is-embla .product-grid__item {
		flex: 0 0 70%;
		min-width: 0;
		margin-right: var(--space-32);
	}
}

/* Zdjęcia firmowo: pełny wzorzec .u-image na linku (shadow + krzyżyki + ramka, jak hero) */
.product-gallery__figure { margin: 0; }
.product-gallery__link { display: block; aspect-ratio: 4 / 3; cursor: zoom-in; }   /* jak hero slideshow — oba otwierają lightbox */
/* Galeria: krzyżyki narożne (u-image::before) zostają — ramka (::after) świadomie wyłączona */
.product-gallery__link.u-image::after { content: none; }
/* Podpis pod zdjęciem — z pola alt (polskie opisy ze starej strony) */
.product-gallery__caption { margin-top: var(--space-8); font-size: var(--text-caption); font-weight: 500; color: color-mix(in srgb, var(--graphite) 70%, transparent); }

/* ---------- Lightbox (podgląd zdjęcia bez opuszczania strony) ---------- */
.agf-lightbox {
	position: fixed;
	inset: 0;
	z-index: 200;                                        /* nad sticky headerem (--z-header 100) */
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--space-48);
	background: color-mix(in srgb, var(--graphite) 92%, transparent);
	cursor: zoom-out;
}
.agf-lightbox[hidden] { display: none; }
/* Zdjęcie + podpis (nazwa wariantu z alta) w kolumnie, wycentrowane */
.agf-lightbox__media {
	position: relative;                                  /* kotwica strzałek nawigacji (na zdjęciu) */
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-16);
	margin: 0;
	max-width: 100%;
	max-height: 100%;
	min-height: 0;
}
.agf-lightbox__img {
	max-width: 90%;
	max-height: 72vh;                                    /* zapas pod zdjęciem na podpis */
	box-shadow: var(--shadow-mega);
	cursor: default;
}
.agf-lightbox__caption {
	color: var(--white);
	font-size: var(--text-body);
	font-weight: 500;
	text-align: center;
	cursor: default;
}
/* Strzałki nawigacji — systemowa arrow (Lucide stroke, jak CTA kart) w blue,
   na zdjęciu przy krawędziach (absolute w .agf-lightbox__media) */
.agf-lightbox__nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--space-48);
	height: var(--space-48);                             /* ×2 (48) — svg wypełnia, hit-area > tap-target-min */
	border: 0;
	padding: 0;
	background: transparent;
	color: var(--blue);
	cursor: pointer;
}
.agf-lightbox__nav--prev { left: var(--space-8); }
.agf-lightbox__nav--prev svg { transform: scaleX(-1); }
.agf-lightbox__nav--next { right: var(--space-8); }
.agf-lightbox__nav:hover { color: var(--blue-light, var(--blue)); }
.agf-lightbox__close {
	position: absolute;
	top: var(--space-24);
	right: var(--space-24);
	width: var(--tap-target-min);
	height: var(--tap-target-min);
	border: 0;
	padding: 0;
	background: transparent;
	color: var(--white);
	font-size: var(--text-h3);
	line-height: 1;
	cursor: pointer;
}
.agf-lightbox__close:hover { color: var(--blue-light, var(--blue)); }
/* bez hover-zoom: skalowany img wychodził na krzyżyki (overflow hidden ściąłby
   pseudoelementy u-image); "zobacz bliżej" robi lightbox */
.product-gallery__link img { width: 100%; height: 100%; object-fit: cover; }

/* ---------- Do pobrania ----------
   Wiersze ostre (hairline, zero radiusa — styl firmowy).
   Desktop: 3 kolumny, wszystkie kafle równej wysokości (auto-rows 1fr).
   Ikona file-text zamiast badge "PDF" (usunięty 30.07 — user: "chujowo to wyglada"). */
.downloads { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-24); grid-auto-rows: 1fr; }
@media (min-width: 992px) {
	.downloads { grid-template-columns: repeat(3, 1fr); }
}
.downloads__item { display: flex; }
.downloads__card {
	display: flex;
	align-items: center;
	gap: var(--space-8);
	width: 100%;
	min-height: var(--tap-target-min);
	padding: var(--space-16);
	background: var(--white);
	box-shadow: var(--shadow-mega);                      /* tylko cień, świadomie bez ramki */
	text-decoration: none;
	color: var(--graphite);
	transition: background var(--transition-fast);
}
.downloads__card:hover { background: color-mix(in srgb, var(--blue) 5%, var(--white)); }
.downloads__icon { flex-shrink: 0; color: var(--blue); }
.downloads__label { flex: 1; font-size: var(--text-label); font-weight: 400; }
@media (max-width: 767.98px) {
	.downloads { grid-auto-rows: auto; }                    /* 1 kolumna: kafel swojej wysokości (1fr równało do najwyższego) */
	.downloads__card { padding-block: 0; }                  /* kafel zwarty 44 (min-height + flex centrują 1-liniowe) */
}

/* /do-pobrania/ — grupy kategorii to podgrupy JEDNEJ listy, nie osobne sekcje strony
   (wzorzec 1:1 .product-catalog__sec niżej w tym pliku): odstęp margin-bottem, nie
   .section/.section--tight per grupa. Kotwice #kdwu/#cenniki (docs/REDIRECT-MAP.md)
   muszą też lądować pod fixed headerem, nie pod nim. */
.do-pobrania__group { margin-bottom: var(--space-64); scroll-margin-top: calc(var(--header-height) + var(--space-24)); }
.do-pobrania__group:last-child { margin-bottom: 0; }
/* h3 (.u-card-title) za ciężki tu jako etykieta grupy — scoped override wagi/odstępu,
   .u-card-title samo zostaje 600/8px dla realnych kart gdzie indziej. */
.do-pobrania__group .u-card-title { margin: 0 0 var(--space-32); font-weight: 500; }

/* ---------- Powiązane branże (koniec taba Opis) — link = .agf-chip (base.css), wrapper jak .realization-products ---------- */
.product-industries {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-8);
	list-style: none;
	margin: 0;
	padding: 0;
}

/* ---------- FAQ (details/summary) ---------- */
.product-faq { max-width: var(--measure); }
.product-faq__item { border-bottom: 1px solid var(--border); }
.product-faq__q {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-16);
	padding: var(--space-24) var(--space-8) var(--space-24) 0;
	font-size: var(--text-lead);
	font-weight: 600;
	color: var(--graphite);
	cursor: pointer;
	list-style: none;
}
/* Pierwszy wiersz BEZ globalnego zerowania top-padu (bylo, cofniete) — product-faq zyje
   w tabs (desktop: plain panel, brak kompensujacej gory jak industry-faq's section-head;
   mobile: agf-tabs__acc daje 24 bottom-pad, WIEC zerowanie tylko tam — patrz tabs.css). */
.product-faq__q::-webkit-details-marker { display: none; }
.product-faq__q:focus-visible {
	outline: var(--focus-ring);
	outline-offset: calc(-1 * var(--focus-offset));   /* inset — wiersz bez ramki, outline na zewnątrz ginie przy krawędziach (sync industry-faq) */
}
/* Plus/minus — utilities.css (scalone z industry-faq/benefits/tabs, audit prio 2.3) */
.product-faq__a { padding: 0 0 var(--space-24); }   /* typografia: .u-desc.u-desc--loose (utilities.css), sync z industry-faq */
@media (max-width: 767.98px) {
	.product-faq__q { padding-block: var(--space-16); font-size: var(--text-body); }   /* mobile: wiersz zwarty 16/16, font 16 (desktop 24 / 17) */
}
.product-faq__a p { margin: 0 0 var(--space-16); }
.product-faq__a p:last-child { margin-bottom: 0; }

/* ---------- Pola formularza (styleguide demo — .product-form__form/__field/__input/__label/__consent/__textarea) ---------- */
/* Zgoda RODO */
.product-form__consent { display: flex; align-items: flex-start; gap: var(--space-8); font-size: var(--text-caption); line-height: 1.6; color: color-mix(in srgb, var(--graphite) 75%, transparent); cursor: pointer; }
/* Checkbox zgody: appearance none = pełna kontrola — natywny miał radius (system: zero
   radiusa poza pills) i 13px (ginął przy 4 liniach). Zaznaczenie = kwadrat w kwadracie. */
.product-form__consent input {
	appearance: none;
	-webkit-appearance: none;
	width: 20px;
	height: 20px;
	flex-shrink: 0;
	margin-top: 0;
	border: 1px solid var(--graphite);
	background: var(--white);
	display: inline-grid;
	place-content: center;
	cursor: pointer;
}
.product-form__consent input::before {
	content: "";
	width: 10px;
	height: 10px;
	background: var(--blue);
	transform: scale(0);
	transition: transform var(--transition-fast);
}
.product-form__consent input:checked::before { transform: scale(1); }
.product-form__consent input:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.product-form__consent a { color: var(--blue); text-decoration: underline; }
.product-form__form { display: grid; gap: var(--space-16); }
.product-form__form .agf-btn { justify-self: start; margin-top: var(--space-8); }    /* CTA naturalnej szerokości; zgoda→submit = gap 16 + 8 = 24 */
.product-form__field { display: flex; flex-direction: column; gap: var(--space-8); }
.product-form__label { font-size: var(--text-label); font-weight: 600; color: var(--graphite); }
.product-form__input {
	height: var(--tap-target-min);                       /* równo 44px — jak CTA (textarea niżej: auto) */
	padding: 0 var(--space-16);
	border: 1px solid var(--border);
	box-shadow: var(--shadow-mega);                      /* bez radiusa — styl firmowy (zero-radius + shadow) */
	font-size: var(--text-body);
	font-family: inherit;
	background: var(--white);
	color: var(--graphite);
	transition: border-color var(--transition-fast);
}
.product-form__input:focus { border-color: var(--blue); }
.product-form__textarea { resize: vertical; height: auto; min-height: 120px; padding-block: var(--space-8); }
.product-form__input::placeholder { color: color-mix(in srgb, var(--graphite) 45%, transparent); }

/* ---------- Katalog hub /produkty/ (master-detail + scrollspy, wariant 6) ---------- */
.product-catalog { display: grid; grid-template-columns: 1fr; gap: var(--space-32); }
@media (min-width: 900px) { .product-catalog { grid-template-columns: 300px 1fr; gap: var(--space-32); align-items: start; } }
.product-catalog__main { min-width: 0; }   /* grid item domyślnie nie kurczy się poniżej content-width — Embla flex track (bez wrap) wewnątrz rozpychał całą kolumnę */

/* Lewa: nawigacja kategorii — język .agf-tabs__bar (tabs.css) w pionie: bar tło
   graphite 8%, aktywny = białe tło + niebieska ramka hairline + krzyżyki mini. */
.product-catalog__nav {
	display: flex;
	flex-direction: column;
	gap: var(--space-8);
	padding-block: var(--space-16);
	background: var(--bg-page);                                          /* fallback solidny */
	background: color-mix(in srgb, var(--graphite) 8%, var(--white));
}
@media (min-width: 900px) {
	.product-catalog__nav {
		position: sticky;
		top: calc(var(--header-height) + var(--space-16));
	}
}
.product-catalog__nav-label { font-size: var(--text-caption); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: color-mix(in srgb, var(--graphite) 50%, transparent); margin: 0 0 var(--space-8) var(--space-16); flex-shrink: 0; }
.product-catalog__nav-list { display: flex; flex-direction: column; gap: var(--space-8); }
.product-catalog__nav-link {
	position: relative;
	display: flex;
	align-items: center;
	gap: var(--space-16);
	padding: var(--space-16);
	text-decoration: none;
	color: var(--graphite);
	transition: background var(--transition-base), color var(--transition-fast);
}
.product-catalog__nav-link:hover { color: var(--blue); }
.product-catalog__nav-link.is-active { background: var(--white); color: var(--graphite); }
/* Aktywny: niebieska ramka hairline (::after) + krzyżyki narożne mini (::before) — 1:1 .agf-tabs__tab */
.product-catalog__nav-link::after {
	content: "";
	position: absolute;
	inset: 0;
	border: 1px solid var(--blue);
	pointer-events: none;
	opacity: 0;
	transition: opacity var(--transition-base);
}
.product-catalog__nav-link.is-active::after { opacity: 1; }
.product-catalog__nav-link::before {
	content: "";
	position: absolute;
	inset: calc(var(--space-8) / -2);
	pointer-events: none;
	opacity: 0;
	transition: opacity var(--transition-base);
	background:
		linear-gradient(var(--blue), var(--blue)) left var(--space-4) top 0 / 1px var(--space-8) no-repeat,
		linear-gradient(var(--blue), var(--blue)) left 0 top var(--space-4) / var(--space-8) 1px no-repeat,
		linear-gradient(var(--blue), var(--blue)) right var(--space-4) top 0 / 1px var(--space-8) no-repeat,
		linear-gradient(var(--blue), var(--blue)) right 0 top var(--space-4) / var(--space-8) 1px no-repeat,
		linear-gradient(var(--blue), var(--blue)) left var(--space-4) bottom 0 / 1px var(--space-8) no-repeat,
		linear-gradient(var(--blue), var(--blue)) left 0 bottom var(--space-4) / var(--space-8) 1px no-repeat,
		linear-gradient(var(--blue), var(--blue)) right var(--space-4) bottom 0 / 1px var(--space-8) no-repeat,
		linear-gradient(var(--blue), var(--blue)) right 0 bottom var(--space-4) / var(--space-8) 1px no-repeat;
}
.product-catalog__nav-link.is-active::before { opacity: 1; }
.product-catalog__nav-text { display: flex; flex-direction: column; }
.product-catalog__nav-name { font-size: var(--text-body); font-weight: 500; line-height: 1.2; }

/* Prawa: sekcje per kategoria */
.product-catalog__sec { margin-bottom: var(--space-96); scroll-margin-top: calc(var(--header-height) + var(--space-24)); }
.product-catalog__sec:last-child { margin-bottom: 0; }
.product-catalog__sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-16); margin-bottom: var(--space-8); }
.product-catalog__sec-title { font-size: var(--text-h4); font-weight: 500; color: var(--graphite); margin: 0; }
.product-catalog__sec-link { display: inline-flex; align-items: center; gap: var(--space-4); font-size: var(--text-label); font-weight: 600; color: var(--blue); text-decoration: none; white-space: nowrap; }
.product-catalog__sec-link svg { flex-shrink: 0; transition: transform var(--transition-fast); }
.product-catalog__sec-link:hover svg { transform: translateX(3px); }
.product-catalog__sec-desc { font-size: var(--text-lead); line-height: 1.6; color: color-mix(in srgb, var(--graphite) 80%, transparent); margin: 0 0 var(--space-24); max-width: var(--measure); }
/* Link "Cała kategoria" pod peek-carouselem (nie obok tytułu) — mobile only,
   wzorzec .products__more (home): wyśrodkowany blok pod slajderem. */
.product-catalog__sec-more { display: none; }
.product-catalog__grid { display: grid; gap: var(--space-32); grid-template-columns: 1fr; list-style: none; margin: 0; padding: 0; }
@media (min-width: 560px) { .product-catalog__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1280px) { .product-catalog__grid { grid-template-columns: repeat(3, 1fr); } }
/* Mobile peek-carousele (Embla) — wzorzec 1:1 product-gallery/product-related (products.css
   ~522), bez .agf-tabs__body prefiksu (katalog nie żyje w tabs). Bez JS fallback = grid wyżej. */
@media (max-width: 767.98px) {
	.product-catalog__viewport.is-embla {
		overflow: hidden;
		padding-block: var(--space-24);
		margin-block: calc(-1 * var(--space-24)) calc(-1 * var(--space-8));
		width: calc(100% + 2 * var(--container-pad));
		margin-inline: calc(-1 * var(--container-pad));
		cursor: grab;
	}
	.product-catalog__viewport.is-embla.is-dragging {
		cursor: grabbing;
		user-select: none;
	}
	.product-catalog__viewport.is-embla .product-catalog__grid {
		display: flex;
		gap: 0;
		margin: 0;
	}
	.product-catalog__viewport.is-embla .product-grid__item {
		flex: 0 0 70%;
		min-width: 0;
		margin-right: var(--space-32);
	}
	.product-catalog__sec-link { display: none; }   /* przenosi się pod carousel jako .sec-more-link */
	.product-catalog__sec-more { display: block; text-align: center; margin-top: var(--space-24); }
}

/* Nav mobile (<900px): pionowa lista bez sticky — tabs-frame (hairline+krzyżyki) z desktopu
   dziedziczy się bez zmian, sam .product-catalog__nav wraca do naturalnego flow (usunięty
   dawny poziomy pasek pigułek sticky pod headerem). */
@media (max-width: 899px) {
	.product-catalog__sec { scroll-margin-top: calc(var(--header-height) + var(--space-64)); }
	.product-catalog__sec-desc:not(.u-empty-state) { display: none; }   /* realny opis kategorii schowany na mobile; "w przygotowaniu" (empty-state) zostaje */
	.product-catalog__sec-head { margin-bottom: var(--space-24); }   /* sec-desc dawał 24 margin-bottom, po ukryciu head:8 zostawał jako jedyny odstęp — za mało */
}
