.inco-product-image {
	position: relative;
	display: block;
	border-radius: 12px;
	overflow: hidden;
	background: #f8fafc;
}

.inco-product-image img {
	display: block;
	width: 100%;
	height: auto;
}

.inco-product-badges {
	display: inline-flex;
	flex-wrap: wrap;
	gap: 6px;
}

.inco-badge {
	display: inline-flex;
	align-items: center;
	padding: 3px 10px;
	border-radius: 6px;
	font-size: 13px;
	font-weight: 700;
	line-height: 1.3;
	color: #fff;
}

.inco-badge--new {
	background: #7c3aed;
}

.inco-badge--sale {
	background: #e11d48;
}

.inco-badge--out-of-stock {
	background: #6b7280;
}

.inco-product-price {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.inco-product-price__top {
	display: inline-flex;
	align-items: center;
	gap: 8px;
}

.inco-product-price__regular {
	color: #9ca3af;
	text-decoration: line-through;
	font-size: 15px;
}

.inco-product-price__regular del {
	text-decoration: none;
}

.inco-product-price__discount {
	display: inline-flex;
	align-items: center;
	padding: 1px 8px;
	border-radius: 6px;
	background: #e11d48;
	color: #fff;
	font-size: 13px;
	font-weight: 700;
}

.inco-product-price__current {
	color: #0a435c;
	font-size: 26px;
	font-weight: 700;
	line-height: 1.1;
}

.inco-product-price__current .amount,
.inco-product-price__current bdi {
	color: inherit;
}

.inco-product-quantity {
	display: inline-flex;
	align-items: center;
	border: 1px solid #d1d5db;
	border-radius: 10px;
	overflow: hidden;
	background: #fff;
}

.inco-qty__btn {
	width: 40px;
	height: 44px;
	border: 0;
	background: transparent;
	color: #0a435c;
	font-size: 20px;
	line-height: 1;
	cursor: pointer;
}

.inco-qty__btn:hover {
	background: #f1f5f9;
}

.inco-qty__input {
	width: 44px;
	height: 44px;
	border: 0;
	text-align: center;
	font-size: 16px;
	color: #0a435c;
	-moz-appearance: textfield;
	appearance: textfield;
}

.inco-qty__input::-webkit-outer-spin-button,
.inco-qty__input::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}

.btn-primary.inco-add-to-cart {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	min-height: 44px;
	padding: 0 18px;
	border: 0;
	border-radius: 10px;
	background: #0d9488;
	color: #fff;
	font-size: 15px;
	font-weight: 600;
	line-height: 1;
	text-decoration: none;
	cursor: pointer;
	transition: background 0.15s ease, opacity 0.15s ease;
}

.btn-primary.inco-add-to-cart:hover {
	background: #0f766e;
	color: #fff;
}

.btn-primary.inco-add-to-cart .inco-add-to-cart__icon {
	display: inline-flex;
	padding-left: 10px;
	border-left: 1px solid rgba( 255, 255, 255, 0.35 );
}

.btn-primary.inco-add-to-cart.is-loading {
	opacity: 0.6;
	pointer-events: none;
}

.btn-primary.inco-add-to-cart.is-added {
	background: #16a34a;
}

.btn-primary.inco-add-to-cart:disabled,
.btn-primary.inco-add-to-cart[disabled] {
	opacity: 0.5;
	cursor: not-allowed;
}

.inco-product-variations {
	display: flex;
	flex-direction: column;
	gap: 8px;
	margin-bottom: 10px;
}

.inco-product-variation {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.inco-product-variation label {
	font-size: 13px;
	font-weight: 600;
	color: #0a435c;
}

.inco-variation-select {
	min-height: 40px;
	padding: 0 12px;
	border: 1px solid #d1d5db;
	border-radius: 8px;
	background: #fff;
	color: #0a435c;
	font-size: 14px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   CARDUL DE PRODUS ȘI GRILA — după Figma, 31 iulie 2026

   🔑 Container queries, nu media queries.

   Cardul citește PROPRIA lățime, nu pe a ecranului. Motivul e concret: același
   card stă pe homepage la lățime plină, pe arhivă lângă filtre, și în „produse
   similare". Cu media queries, un card de 156px într-un ecran de 1440 cu
   sidebar ar primi tipografia de desktop și ar arăta îngrămădit.

   🔑 Interpolare liniară între cele două ancore din design.

   Designul dă exact două puncte: cardul de 156px (mobil) și cel de 243,2px
   (desktop). Tot ce e între ele se calculează, nu se sare în trepte:

       --inco-pc-t = (lățimea cardului − 156) / 87,2

   La 156px iese 0, la 243,2px iese 1px. Apoi fiecare proprietate înmulțește cu
   diferența ei: titlul e `14px + t × 4` → exact 14 la 156 și exact 18 la 243,2.
   `clamp()` o oprește în afara intervalului.

   ⚠️ Variabila NU se poate defini pe `.inco-product-card` însuși: unitățile
   `cq*` se rezolvă față de cel mai apropiat container ANCESTOR, deci un element
   nu se interoghează pe sine. De aceea stă pe copiii lui direcți, de unde se
   moștenește mai departe.
   ═══════════════════════════════════════════════════════════════════════════ */

.inco-products {
	container-type: inline-size;
	width: 100%;
}

/*
 * 🔴 Fără regula asta, grila iese lată de ZERO în Elementor.
 *
 * `container-type: inline-size` înseamnă `contain: inline-size`: elementul se
 * dimensionează CA ȘI CUM N-AR AVEA CONȚINUT. Deci contribuția lui la lățimea
 * intrinsecă a părinților e 0. Un container Elementor pe `flex-direction: row`
 * își dimensionează widgeturile după conținut — iar conținutul „nu există".
 * Rezultat: widget 0px, grilă 0px, carduri suprapuse.
 *
 * Măsurat pe /test/: `.e-con` avea 1344px, widgetul dinăuntru 0px.
 *
 * `flex-grow` în loc de `width: 100%` intenționat: dacă pui două shortcode-uri
 * unul lângă altul într-un rând, își împart spațiul în loc să se stivuiască.
 *
 * `:has()` e sigur aici — bug-ul apare doar unde există container queries, iar
 * un browser care le înțelege înțelege și `:has()`. Aceeași generație.
 */
.elementor-widget:has(.inco-products) {
	flex-grow: 1;
	min-width: 0;
}

.inco-products__grid {
	display: grid;
	grid-template-columns: repeat(var(--inco-c, 2), minmax(0, 1fr));
	gap: 16px;
	--inco-c: 2;
}

/* `coloane` din shortcode e un PLAFON. Se aplică în fiecare prag de mai jos,
   după valoarea implicită, deci grila tot coboară la 2 pe telefon. */
.inco-products[data-max="1"] .inco-products__grid { --inco-c: 1; }

/* Pragurile nu sunt rotunde de dragul cifrelor. Le-am ales verificând ce card
   iese la fiecare: cu 3 coloane pornite de la 480px ar ieși carduri de 149px —
   mai mici decât varianta mobilă, pe un ecran mai mare. De la 560 ies 170.

   ⚠️ Spațierea se aplică ȘI când numărul de coloane e forțat din shortcode.
   Prima variantă o avea prinsă în `:not(.has-cols)`, deci `coloane="5"` rămânea
   cu gap de 16 și cardurile ieșeau 256px în loc de 243,2. */
@container (min-width: 560px) {
	.inco-products__grid { gap: 24px; --inco-c: 3; }
	.inco-products[data-max="1"] .inco-products__grid { --inco-c: 1; }
	.inco-products[data-max="2"] .inco-products__grid { --inco-c: 2; }
}
@container (min-width: 840px) {
	.inco-products__grid { --inco-c: 4; }
	.inco-products[data-max="1"] .inco-products__grid { --inco-c: 1; }
	.inco-products[data-max="2"] .inco-products__grid { --inco-c: 2; }
	.inco-products[data-max="3"] .inco-products__grid { --inco-c: 3; }
}
@container (min-width: 1120px) {
	.inco-products__grid { gap: 32px; --inco-c: 5; }
	.inco-products[data-max="1"] .inco-products__grid { --inco-c: 1; }
	.inco-products[data-max="2"] .inco-products__grid { --inco-c: 2; }
	.inco-products[data-max="3"] .inco-products__grid { --inco-c: 3; }
	.inco-products[data-max="4"] .inco-products__grid { --inco-c: 4; }
}

.inco-products__empty {
	margin: 0;
	color: var(--inputs-palceholder, #53798a);
}

/* ─────────────────────────────────────────────────────────── cardul */

/* O singură durată pentru tot cardul. Dacă fiecare element și-ar alege viteza,
   hover-ul ar arăta ca trei animații pornite din greșeală în același timp.
   Cerință Seba: 300ms ease peste tot.

   🔑 Declarată și pe `.inco-cta`, dintr-un singur loc. Butonul o cere prin
   `var(--inco-tranzitie)`, iar în afara cardului variabila nu exista: o
   variabilă nedefinită nu lasă declarația să cadă doar pe ea, ci INVALIDEAZĂ
   toată proprietatea. Tranziția ar fi lipsit fără niciun semn. */
.inco-product-card,
.inco-btn--primary {
	/*
	 * 🔑 Butonul primar din pachetele lui Manu folosește ACELEAȘI declarații ca
	 * al nostru — e adăugat în selectoarele componentei, nu copiat lângă ea.
	 * O singură definiție, deci n-are cum să se despartă a doua oară. → §4y
	 *
	 * ⚠️ `--inco-pc-t` trebuie declarat aici: mărimile componentei sunt `clamp()`
	 * peste el, iar o variabilă nedeclarată invalidează TOATĂ declarația, nu doar
	 * bucata ei. `1` îl duce la capătul de sus, adică valorile de card lat.
	 */
	--inco-pc-t: 1;
	--inco-tranzitie: .3s ease;
	--inco-cta-gradient: linear-gradient(to left, #013465, #14a5a9);
}

.inco-cta {
	--inco-tranzitie: .3s ease;

	/* Gradientul oficial, într-un SINGUR loc. E nevoie de el în două stări
	   *(repaus și hover)*, iar scris de două ori s-ar fi despărțit. → §4k */
	--inco-cta-gradient: linear-gradient(to left, #013465, #14a5a9);
}

.inco-product-card {
	container-type: inline-size;
	display: flex;
	flex-direction: column;
	min-width: 0;
	position: relative;
}

/*
 * Tot cardul duce la produs, mai puțin zona de cumpărare.
 *
 * 🔑 Un singur link, nu trei. Titlul rămâne linkul real, iar `::after` îi
 * întinde suprafața de click peste tot cardul. Dacă am fi înfășurat fiecare
 * bucată în `<a>`, cititoarele de ecran ar fi anunțat același produs de trei
 * ori, iar Tab ar fi trecut prin trei opriri identice.
 *
 * Zona de cumpărare și butoanele din colț rămân deasupra, prin `z-index`, deci
 * click-ul pe ele nu ajunge niciodată la link.
 */
.inco-product-card__title::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
}

.inco-product-card__buy {
	position: relative;
	z-index: 1;
}

.inco-product-card > * {
	--inco-pc-t: calc((100cqi - 156px) / 87.2);
}

.inco-product-card__media,
.inco-product-card__body {
	margin-bottom: clamp(8px, calc(8px + var(--inco-pc-t) * 4), 12px);
}

/* ─────────────────────────────────────────────── imaginea */

.inco-product-card__media {
	position: relative;
	display: flex;
	align-items: flex-end;
	justify-content: center;
	height: clamp(176px, calc(176px + var(--inco-pc-t) * 40), 216px);
	overflow: hidden;
	border: 1px solid var(--grey-border-fill, #c4d2d7);
	border-radius: 8px;
	/* Alb curat, nu #fafcff: pachetele sunt fotografiate pe fundal alb, iar orice
	   nuanță se vede ca un dreptunghi în jurul produsului. Cerință Seba. */
	background: #fff;
}

.inco-product-card__media-link,
.inco-product-card__media .inco-product-image {
	display: block;
	width: 100%;
	height: 100%;
	border-radius: 0;
	background: none;
}

/* `contain`, niciodată `cover`. Produsele sunt pachete cu text pe ele — un
   crop taie exact mărimea și absorbția, adică ce caută omul.
 *
 * ⚠️ Selectorul are DOUĂ clase intenționat. Elementor are în `frontend.min.css`
 * regula `.elementor img { height: auto }` — aceeași specificitate ca varianta
 * cu o singură clasă, dar încărcată după noi, deci câștiga ea. Rezultatul:
 * imaginea rămânea la înălțimea ei naturală, iar cele înalte erau tăiate de
 * `overflow: hidden` — se vedea ca un crop, deși `object-fit` era corect.
 * Confirmat în browser: regula câștigătoare era `.elementor img`. */
.inco-product-card__media .inco-product-image img,
.inco-product-card .inco-product-card__media img {
	width: 100%;
	height: 100%;
	object-fit: contain;
}

/* ─────────────────────────────────────────────── blindaj față de temă
 *
 * Tema E deja goală — Hello Elementor Child peste Hello Elementor, minimul
 * absolut. Dar Hello tot stilizează `button`, iar butonul de adăugare poartă și
 * clasa `btn-primary`, pusă de noi pe vremea când voiam să arate ca butonul
 * temei. De acolo veneau fundalul roșu pe hover la ±, și `min-height: 44px`.
 *
 * Nu schimbăm tema pentru asta. Cardul își declară singur toate stările —
 * repaus, hover, focus, apăsat — ca o schimbare de temă sau de kit Elementor să
 * nu-l mai poată atinge.
 */

/*
 * 🔴 Vinovatul, găsit măsurând: `reset.css` din Hello Elementor are
 *
 *     [type="button"]:focus, [type="button"]:hover { background-color: #cc3366 }
 *
 * Toate butoanele cardului sunt `type="button"`, deci toate se făceau zmeurii
 * la hover ȘI rămâneau așa după click, pentru că focusul persistă până apeși în
 * altă parte. De aici și „inima rămâne colorată", și minusul roșu.
 *
 * Selectorul lor cântărește (0,2,0). Al nostru are trei clase, deci nu mai e
 * loc de discuție despre ordinea de încărcare.
 */
.inco-product-card button {
	appearance: none;
	font-family: inherit;
	text-transform: none;
	box-shadow: none;
}

/* ⚠️ `:not(.is-active)` nu e cosmetic. Fără el, regula asta cântărește exact cât
   cea a stării active, iar cine câștigă depinde de ordinea în fișier — am prins
   asta injectând CSS-ul în pagină: starea „în favorite" se stingea complet.
   Cu `:not()`, cele două nu se mai suprapun deloc.

   🔴 CLASA E DUBLATĂ, nu prefixată cu `.inco-product-card`. Corectat 14 aug.

   Era `.inco-product-card .inco-product-card__tools …`, adică regulile de STARE
   cereau un strămoș care pe pagina de produs NU EXISTĂ — divul de acolo poartă
   clasa `__tools`, dar nu stă într-un card. Rezultatul, măsurat: pastilele își
   luau forma și culoarea de repaus, dar nu și `is-active`, `:hover` sau
   `:focus`. Iar pe `:focus` intra tema, cu rozul ei `#cc3366`.

   🔑 Clasa dublată cântărește EXACT cât prefixul *(3 clase)*, deci pe card nu se
   schimbă nimic — dar nu mai cere un strămoș. **O componentă care e gândită să
   fie folosită și în altă parte nu se poate agăța de contextul ei de naștere.**
   Jumătate din regulile de mai jos erau deja scrise fără prefix; acum sunt toate. */
.inco-product-card__tools.inco-product-card__tools .inco-wishlist-button:not(.is-active),
.inco-product-card__tools.inco-product-card__tools .inco-wishlist-button:not(.is-active):focus,
.inco-product-card__tools.inco-product-card__tools .inco-compare-button,
.inco-product-card__tools.inco-product-card__tools .inco-compare-button:focus {
	background: var(--blue-card-fill-default, #e8f8ff);
	color: var(--green-fill-primary-default, #056e9b);
}

/* Butonul rămâne focusat după click, cu mouse-ul deja plecat. Dacă starea de
   focus arată ca hover, pare că a rămas apăsat. `:focus-visible` se aprinde
   doar la tastatură, unde chiar e nevoie de el. */
.inco-product-card__tools.inco-product-card__tools .inco-wishlist-button:not(.is-active):focus-visible,
.inco-product-card__tools.inco-product-card__tools .inco-compare-button:focus-visible {
	background: var(--green-fill-primary-default, #056e9b);
	color: #fff;
}

/*
 * 🔴 Hover-ul se cere ACUM, nu se presupune. Semnalat de Seba: pe telefon
 * butoanele din colțul cardului n-au aceleași culori ca pe desktop.
 *
 * 🔑 Pe un ecran tactil nu există „mouse-ul a plecat de pe element". Browserul
 * aprinde `:hover` la atingere și îl lasă aprins până atingi altceva — pe iOS,
 * până la următorul tap. Deci inima și săgețile rămâneau **albastru plin cu
 * glif alb** după ce le atingeai, în loc să revină la `#E8F8FF`. Nu e altă
 * culoare scrisă undeva pentru telefon: e chiar culoarea de hover, rămasă
 * lipită.
 *
 * ⚠️ Măsurat înainte de reparație: în TOT pluginul nu exista nicio interogare
 * `@media (hover: …)` — nici la noi, nici în pachetele lui Manu. Fiecare regulă
 * de hover se aplica pe orice fel de pointer. → **o stare gândită pentru mouse
 * trebuie să și ceară un mouse.**
 *
 * `:focus-visible` a rămas AFARĂ, deliberat: pe o tabletă cu tastatură pointerul
 * principal e degetul *(`hover: none`)*, dar navigarea la tastatură există în
 * continuare, iar conturul de focus nu are voie să dispară odată cu hover-ul.
 * De asta cele două declarații sunt scrise de două ori — nu din neatenție.
 */
@media (hover: hover) {
	.inco-product-card__tools.inco-product-card__tools .inco-wishlist-button:not(.is-active):hover,
	.inco-product-card__tools.inco-product-card__tools .inco-compare-button:hover {
		background: var(--green-fill-primary-default, #056e9b);
		color: #fff;
	}
}

/*
 * 🔴 `color` TREBUIE declarat aici, nu doar `background`.
 *
 * `reset.css` din Hello Elementor pune pe `[type="button"]:focus, :hover`
 * ȘI `color: #fff`. Iconițele ± sunt SVG cu `stroke: currentColor`, deci
 * deveneau albe pe fundal alb — adică invizibile. Se vedea ca „plusul dispare
 * după ce apeși pe el și iei mouse-ul": butonul rămâne focusat.
 */
.inco-product-card .inco-product-card__buy .inco-qty__btn,
.inco-product-card .inco-product-card__buy .inco-qty__btn:hover,
.inco-product-card .inco-product-card__buy .inco-qty__btn:focus,
.inco-product-card .inco-product-card__buy .inco-qty__btn:active {
	border: 0;
	background: none;
	box-shadow: none;
	outline: 0;
	color: var(--green-text-fill, #0a435c);
	transition: color var(--inco-tranzitie), opacity var(--inco-tranzitie);
}

/* `:not([disabled])` — un buton oprit nu reacționează la mouse. Fără asta,
   minusul de la produsele epuizate se lumina la hover și părea apăsabil. */
.inco-product-card .inco-product-card__buy .inco-qty__btn:not([disabled]):hover {
	color: var(--green-fill-primary-default, #056e9b);
}

/* Nici cursorul nu promite nimic. */
.inco-product-card .inco-qty__btn[disabled],
.inco-product-card .inco-qty__btn[disabled]:hover,
.inco-product-card .inco-qty__btn[disabled]:focus {
	color: var(--grey-border-fill, #c4d2d7);
	cursor: default;
}

.inco-product-card .inco-qty__btn:focus-visible {
	outline: 2px solid var(--green-fill-primary-default, #056e9b);
	outline-offset: -2px;
}

/* La limită butonul se stinge, NU dispare. Un control care se evaporă lasă
   impresia că s-a stricat ceva; unul palid spune „aici te-ai oprit".
   Cerință Seba, 31 iul. */
/* Culoarea din exportul Figma al minusului, nu o opacitate ghicită: designerul
   l-a trimis chiar în starea dezactivată, cu `#C4D2D7`. */
.inco-product-card .inco-qty__btn[disabled] {
	color: var(--grey-border-fill, #c4d2d7);
	opacity: 1;
	cursor: default;
}

/* Stepper-ul întreg, la produsele epuizate: aceeași formă, stinsă. */
.inco-product-card .inco-product-quantity.is-disabled {
	border-color: var(--grey-border-fill, #c4d2d7);
	background: var(--inco-bg-mut, #f6f7f8);
}

.inco-product-card .inco-product-quantity.is-disabled .inco-qty__input {
	color: var(--grey-border-fill, #c4d2d7);
	-webkit-text-fill-color: var(--grey-border-fill, #c4d2d7); /* Safari ignoră `color` pe input dezactivat */
	opacity: 1;
	cursor: default;
}

.inco-product-card__title {
	transition: color var(--inco-tranzitie);
}

/* 14px, ca linia să iasă de 12px — exact ca în exportul Figma. La 20px cât
   aveam, semnele erau vizibil mai lungi decât în design. */
.inco-product-card .inco-qty__btn svg {
	width: clamp(12px, calc(12px + var(--inco-pc-t) * 2), 14px);
	height: clamp(12px, calc(12px + var(--inco-pc-t) * 2), 14px);
}

/* ─────────────────────────────────────────────── hover pe tot cardul
 *
 * Cardul întreg reacționează, nu doar linkul: conturul imaginii și prețul trec
 * pe verdele de hover. E același `#0b8669` ca la buton — un singur verde de
 * interacțiune peste tot, nu trei nuanțe apropiate care par o greșeală.
 */

.inco-product-card:hover .inco-product-card__media {
	border-color: #0b8669;
}

.inco-product-card:hover .inco-product-price__current {
	color: #0b8669;
}

.inco-product-card__media,
.inco-product-card .inco-product-price__current {
	transition: border-color var(--inco-tranzitie), color var(--inco-tranzitie);
}

/* ─────────────────────────────────────────────── inimă + comparare */

.inco-product-card__tools {
	position: absolute;
	top: 7px;
	left: 7px;
	z-index: 3;
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.inco-product-card__tools .inco-wishlist-button,
.inco-product-card__tools .inco-compare-button {
	display: flex;
	align-items: center;
	justify-content: center;
	width: clamp(24px, calc(24px + var(--inco-pc-t) * 4), 28px);
	height: clamp(24px, calc(24px + var(--inco-pc-t) * 4), 28px);
	/* `wishlist.css` pune `margin: 8px 0` pe buton — gândit pentru un buton
	   inline, nu pentru unul lipit în colțul imaginii. Ocupa 44px pe verticală
	   în loc de 28 și cobora inima cu 8px față de design. */
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: var(--blue-card-fill-default, #e8f8ff);
	color: var(--green-fill-primary-default, #056e9b);
	cursor: pointer;
	position: relative;
	transition: background var(--inco-tranzitie), color var(--inco-tranzitie), border-color var(--inco-tranzitie);
}

.inco-product-card__tools .inco-wishlist-button svg,
.inco-product-card__tools .inco-compare-button svg {
	width: clamp(18px, calc(18px + var(--inco-pc-t) * 2), 20px);
	height: clamp(18px, calc(18px + var(--inco-pc-t) * 2), 20px);
	/* Fără asta, SVG-ul e inline și stă pe linia de bază — vezi mai jos. */
	display: block;
}

/*
 * 🔴 Iconița de comparare stătea **3,25px prea sus** în cerc.
 *
 * `Card.php` o învelește într-un `<span class="inco-compare-button__icon">`,
 * iar span-ul e **inline**. Ca element inline, înălțimea lui vine din
 * `line-height`, iar SVG-ul dinăuntru se așază pe linia de bază — deci sub el
 * rămâne spațiul de descendentă, care împinge desenul în sus.
 *
 * Butonul are `align-items: center`, dar el centrează SPAN-ul, nu desenul din
 * el. Cutia era centrată; conținutul cutiei, nu. *(A treia oară același tipar:
 * tabelul de specificații și steaua din recenzii.)*
 *
 * Măsurat: abatere `0, −3,25` înainte · `0, 0` după. Inima n-avea problema —
 * modulul Wishlist nu pune span în jurul SVG-ului.
 */
.inco-product-card__tools :is(.inco-compare-button__icon, .inco-wishlist-button__icon) {
	display: flex;
	align-items: center;
	justify-content: center;
	line-height: 0;
}

/*
 * Pe hover, când produsul E deja în listă, desenul devine un X — „scoate-l".
 * Cerut de Seba pe 10 aug, întâi pentru comparator, apoi și pentru favorite:
 * *„îmi place ce X ai adăugat pt comparator, schimbă-l și pt add to wishlist"*.
 *
 * 🔑 O singură regulă pentru amândouă butoanele. Sunt aceeași idee — „elementul
 * e în listă, apasă ca să-l scoți" — deci nu merită două seturi de reguli care
 * să se depărteze la prima corectură.
 *
 * 🔑 Amândouă desenele sunt în marcaj, iar CSS-ul alege. Schimbul se face pe
 * `:hover`, care e o stare CSS; din JS ar fi însemnat două ascultătoare pe
 * fiecare buton dintr-o grilă de 24 de carduri, plus o fereastră la încărcare
 * în care butonul n-ar fi răspuns la mouse.
 *
 * 🔑 Se schimbă DOAR pe `.is-active`. Pe un produs care nu e în listă, un X ar
 * promite ștergerea a ceva ce nu există.
 *
 * ⚠️ `:focus-visible` e aici pentru tastatură — altfel starea ar exista doar
 * pentru cine are mouse.
 *
 * ⚠️ `:is()` preia specificitatea celui mai specific argument, dar aici ambele
 * sunt clase simple, deci selectorul rămâne (0,3,0) — peste regula de bază a
 * SVG-ului, care e (0,2,1). → §4g
 */
/*
 * 🔑 Se face din OPACITATE, nu din `display` — ca să se poată anima.
 * `display` nu e animabil; `none` → `block` ar fi fost un salt. Cerut de Seba:
 * *„vreau animația cu opacity și pe X-ul nou svg"*, ca la X-ul vechi.
 *
 * Cele două desene stau **unul peste altul**: cel de bază rămâne în flux și dă
 * înălțimea, X-ul e absolut peste el. Așa se încrucișează lin, fără ca butonul
 * să-și schimbe mărimea în timpul tranziției.
 *
 * ⚠️ `var(--inco-tranzitie, .3s ease)` — cu rezervă. Variabila e declarată pe
 * `.inco-product-card`; fără rezervă, o tranziție dintr-un alt context ar fi
 * dispărut cu totul, fiindcă o variabilă nedefinită invalidează toată
 * declarația, nu doar bucata ei. → §4 „scoaterea din container"
 */
.inco-product-card__tools :is(.inco-compare-button__icon, .inco-wishlist-button__icon) {
	position: relative;
}

.inco-product-card__tools :is(.inco-compare-button, .inco-wishlist-button) svg {
	transition: opacity var(--inco-tranzitie, .3s ease);
}

.inco-product-card__tools :is(.inco-compare-button, .inco-wishlist-button) .inco-icon-x {
	position: absolute;
	inset-inline-start: 50%;
	inset-block-start: 50%;
	transform: translate(-50%, -50%);
	opacity: 0;
}

.inco-product-card__tools :is(.inco-compare-button, .inco-wishlist-button).is-active:focus-visible .inco-icon-x { opacity: 1; }

.inco-product-card__tools :is(.inco-compare-button, .inco-wishlist-button).is-active:focus-visible svg:not(.inco-icon-x) { opacity: 0; }

/*
 * ⚠️ Schimbul pe ✕ e o afordanță de MOUSE, deci cere un mouse.
 *
 * Pe telefon `:hover` rămâne aprins după atingere, deci inima unui produs deja
 * în favorite se transforma în ✕ **și rămânea așa** — pe ecran arăta ca și cum
 * produsul ar fi ieșit din listă. Pe desktop ✕-ul dispare când pleci cu
 * mouse-ul; pe telefon n-are de unde să plece.
 *
 * 🔑 Pe atingere nu e nevoie de el: acolo apeși direct, iar starea aprinsă
 * *(cerc roșu / cerc verde)* spune deja „e în listă". ✕-ul răspundea la
 * întrebarea „ce se întâmplă dacă apăs?", pe care mouse-ul o pune înainte de
 * click și degetul nu o pune deloc.
 */
@media (hover: hover) {
	.inco-product-card__tools :is(.inco-compare-button, .inco-wishlist-button).is-active:hover .inco-icon-x { opacity: 1; }

	.inco-product-card__tools :is(.inco-compare-button, .inco-wishlist-button).is-active:hover svg:not(.inco-icon-x) { opacity: 0; }

	.inco-product-card__tools .inco-wishlist-button:hover,
	.inco-product-card__tools .inco-compare-button:hover {
		background: var(--green-fill-primary-default, #056e9b);
		color: var(--white-bg, #fafcff);
	}
}

/*
 * Starea „în favorite": cerc roșu plin, inimă ALBĂ.
 *
 * 🔴 Înainte, modulul Wishlist colora inima în roșu și lăsa fundalul deschis,
 * iar regula mea punea și ea roșu — ieșea roșu pe roșu, deci inima devenea
 * invizibilă și butonul arăta ca un bulin gol. De aceea părea „blocat".
 * Aici declarăm și fundalul, și culoarea, și umplerea SVG-ului.
 */
.inco-product-card__tools.inco-product-card__tools .inco-wishlist-button.is-active,
.inco-product-card__tools.inco-product-card__tools .inco-wishlist-button.is-active:focus,
.inco-product-card__tools.inco-product-card__tools .inco-wishlist-button.is-active:hover {
	background: var(--red-label-fill-surface, #d73b3b);
	border-color: var(--red-label-fill-surface, #d73b3b);
	color: #fff;
}

/* ⚠️ Trei clase, nu două. `wishlist.css` are
   `.inco-wishlist-button.is-active .inco-wishlist-button__icon svg` — exact
   aceeași specificitate ca varianta scurtă, iar cine câștigă depinde de ordinea
   în care se încarcă modulele. O clasă în plus scoate întrebarea din discuție. */
.inco-product-card__tools.inco-product-card__tools .inco-wishlist-button.is-active svg {
	fill: #fff;
	stroke: #fff;
}

.inco-product-card__tools.inco-product-card__tools .inco-wishlist-button svg {
	fill: none;
	stroke: currentColor;
}

/* Pe hover, când e deja în favorite, inima face loc unui ✕: apăsarea SCOATE
   produsul, iar o inimă neschimbată n-ar spune asta. */
.inco-product-card__tools .inco-wishlist-button.is-active:hover {
	background: var(--red-label-fill-surface, #d73b3b);
}

/*
 * 🔴 X-ul de aici era DESENAT DIN CSS: SVG-ul trecea pe `opacity: 0`, iar un
 * `::after` de 10×10 desena două linii din gradienți, rotite 45°.
 *
 * Mergea, dar era a doua formă de X în proiect — alta decât cea din checkout,
 * din „Contul meu" și din comparator. Seba a cerut pe 10 aug să fie **același
 * peste tot**, iar acum e: un SVG adevărat, cu aceeași cale.
 *
 * ⚠️ Ștergerea NU e cosmetică. Regula veche `…:hover svg { opacity: 0 }` prindea
 * **toate** SVG-urile din buton, deci ascundea și X-ul nou — l-am urcat pe
 * server și nu se schimba nimic. Două mecanisme pentru același efect nu se
 * ignoră între ele: cel vechi îl bate pe cel nou și nimic nu semnalează.
 * → **Când adaug un mecanism, întâi caut dacă există deja unul.**
 */

.inco-product-card__tools .inco-wishlist-button__label {
	display: none;
}

/* ─────────────────────────────────────────────── badge-uri */

.inco-product-card__flags {
	position: absolute;
	top: 7px;
	right: 7px;
	z-index: 3;
	pointer-events: none; /* badge-urile nu sunt de apăsat; click-ul trece la link */
}

/* `line-height: 1` lipea textul de marginea de sus: majusculele n-au descendere,
   deci caseta rămâne mai înaltă decât litera și diferența cade toată jos.
   Centrarea pe flex nu depinde de forma literelor. */
.inco-product-card__flags .inco-badge {
	display: inline-flex;
	align-items: center;
	height: clamp(16px, calc(16px + var(--inco-pc-t) * 2), 18px);
	padding: 0 4px;
	border-radius: 4px;
	font-size: clamp(12px, calc(12px + var(--inco-pc-t) * 2), 14px);
	font-weight: 600;
	line-height: 1;
	text-transform: uppercase;
}

.inco-product-card__flags .inco-badge--new { background: var(--blue-fill-primary-default, #883dff); }

/* Reducerea are locul ei lângă preț; în colț ar dubla informația. */
.inco-product-card__flags .inco-badge--sale { display: none; }

/* ─────────────────────────────────────────────── titlu și preț */

.inco-product-card__body {
	display: flex;
	flex-direction: column;
	gap: clamp(6px, calc(6px + var(--inco-pc-t) * 2), 8px);
	min-width: 0;
}

.inco-product-card__title {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	overflow: hidden;
	color: var(--green-text-fill, #0a435c);
	font-size: clamp(14px, calc(14px + var(--inco-pc-t) * 4), 18px);
	font-weight: 600;
	line-height: clamp(1.1em, calc(1.1em + var(--inco-pc-t) * 0.1), 1.2em);
	text-decoration: none;
}

.inco-product-card__title:hover {
	color: var(--green-fill-primary-default, #056e9b);
}

/*
 * 🔴 Sublinierea titlului, a șasea oară pe același tipar.
 *
 * `text-decoration: none` e declarat mai sus, dar la (0,1,0). Hello Elementor
 * livrează în `theme.css` regula `.page-content a { text-decoration: underline }`
 * la (0,1,1) — și se încarcă DUPĂ noi. Deci pe orice pagină WordPress care are
 * `.page-content` în jur, titlurile cardurilor apar subliniate; în comparator
 * se vedea imediat, dar e valabil oriunde punem grila într-o pagină.
 *
 * Prefixat cu containerul, regula ajunge la (0,2,0) și câștigă. Aceeași soluție
 * ca la butoane, la firimituri și la câmpuri. → §4g
 *
 * ⚠️ Se declară și pe `:hover`: tema are `a:hover` propriu, iar o stare
 * nedeclarată e o stare scrisă de altcineva. → §4n
 */
.inco-product-card .inco-product-card__title,
.inco-product-card .inco-product-card__title:hover,
.inco-product-card .inco-product-card__title:focus,
.inco-product-card .inco-product-card__title:focus-visible {
	text-decoration: none;
}

.inco-product-card .inco-product-price {
	gap: clamp(2px, calc(2px + var(--inco-pc-t) * 2), 4px);
}

/* 🔑 Rândul de reducere își păstrează înălțimea și când e gol — altfel
   prețurile nu s-ar mai alinia de la un card la altul. Vezi Shortcodes::price. */
/* Înălțime FIXĂ, nu minimă. Cu `min-height`, rândul creștea la 24px când avea
   conținut (16px text × line-height 1.5) și rămânea 18px când era gol — iar
   prețurile ieșeau decalate cu 6px între cardurile cu și fără reducere.
   Măsurat pe /test/: 476 față de 470. Cu înălțime fixă și `line-height: 1` pe
   copii, toate cad la același y. */
.inco-product-card .inco-product-price__top {
	height: clamp(16px, calc(16px + var(--inco-pc-t) * 2), 18px);
	min-height: 0;
	align-items: center;
	gap: 8px;
}

.inco-product-card .inco-product-price__regular {
	color: var(--inputs-palceholder, #53798a);
	font-size: clamp(14px, calc(14px + var(--inco-pc-t) * 2), 16px);
	font-weight: 600;
	line-height: 1;
}

.inco-product-card .inco-product-price__discount {
	display: inline-flex;
	align-items: center;
	height: 100%;
	padding: 0 4px;
	border-radius: 4px;
	background: var(--red-label-fill-surface, #d73b3b);
	color: var(--white-bg, #fafcff);
	font-size: clamp(12px, calc(12px + var(--inco-pc-t) * 4), 16px);
	font-weight: 600;
	line-height: 1;
}

.inco-product-card .inco-product-price__current {
	color: var(--green-fill-primary-default, #056e9b);
	font-size: clamp(18px, calc(18px + var(--inco-pc-t) * 6), 24px);
	font-weight: 600;
	line-height: 1;
}

/* „3,80 lei / bucată" — sub preț, doar unde se cere (azi: comparatorul).
   → `Shortcodes::unit_line()`

   🔑 Înălțime FIXĂ și rând păstrat când e gol, exact ca `__top` de mai sus și
   din același motiv: în comparator cardurile stau într-un rând de tabel, iar
   166 din 276 de produse au cantitate. Fără locul rezervat, cardul unui baston
   și-ar fi ridicat butonul „Adaugă" deasupra celui de la scutece.

   Culoarea și greutatea sunt cele ale prețului vechi de deasupra: linia asta
   explică prețul, nu concurează cu el. */
.inco-product-card .inco-product-price__unit {
	height: clamp(14px, calc(14px + var(--inco-pc-t) * 2), 16px);
	min-height: 0;
	color: var(--inputs-palceholder, #53798a);
	font-size: clamp(12px, calc(12px + var(--inco-pc-t) * 2), 14px);
	font-weight: 500;
	line-height: 1;
	white-space: nowrap;
}

/* Suma dinăuntru vine din `wc_price()`, deci poartă marcajul WooCommerce.
   Fără asta ar fi moștenit culoarea prețului curent, care e declarată pe
   `.amount` mai sus. */
.inco-product-card .inco-product-price__unit .amount,
.inco-product-card .inco-product-price__unit bdi {
	color: inherit;
	font-size: inherit;
	font-weight: inherit;
}

/* ─────────────────────────────────────────────── cantitate + adaugă */

.inco-product-card__buy {
	display: flex;
	align-items: stretch;
	gap: 16px;
	margin-top: auto; /* lipește acțiunea de baza cardului, oricât de lung e titlul */
	position: relative;
	z-index: 1;
}

.inco-product-card .inco-product-quantity {
	display: flex;
	align-items: center;
	/*
	 * `0 1 auto`, nu `0 0 auto`: la 104 fix, pe cardul de 156 nu mai rămâneau
	 * decât 36 pentru butonul de alături, care are nevoie de 44. Așa steperul
	 * cedează DOAR acolo unde chiar nu încape, iar la 238 și 243 rămâne 104.
	 */
	flex: 0 1 auto;
	min-inline-size: 0;
	/*
	 * 🔴 `border-box`, altfel iese 106 în loc de 104.
	 *
	 * Cele trei bucăți fac exact 104 *(36 + 32 + 36)*, dar bordura de 1px se
	 * adăuga PESTE, fiindcă `.inco-product-card` nu-și pune `box-sizing` pe
	 * descendenți — pagina de produs îl are din `.inco-pdp *`, arhiva nu.
	 *
	 * Cei ~2px erau exact cei care lipseau butonului: la card 238 rămâneau 108
	 * disponibili și 108 necesari pentru „Adaugă", deci se tăia din rotunjire.
	 * Găsit de Seba, măsurând steperul: 105,95 în loc de 104.
	 *
	 * → 🔑 Când ceva se taie cu 2px, vinovatul poate fi vecinul, nu el.
	 */
	box-sizing: border-box;
	/* 36 + 32 + 36 din machetă. Bordura intră înăuntru, prin `border-box`. */
	inline-size: 104px;
	height: 42px;
	overflow: hidden;
	border: 1px solid var(--grey-border-fill, #c4d2d7);
	border-radius: 8px;
	background: var(--white-bg, #fafcff);
}

.inco-product-card .inco-qty__btn {
	display: flex;
	align-items: center;
	justify-content: center;
	/*
	 * 🔴 36 fix, din Figma *(nodul butonului: W 36, H 42, colț 8)*.
	 *
	 * Era interpolat, 32 → 36, iar la lățimile intermediare steperul ieșea
	 * 105,95 în loc de 104. Cei ~2px erau exact cei care lipseau butonului
	 * „Adaugă" de alături, care se tăia din rotunjire.
	 * Mijlocul ia ce rămâne: 36 + 32 + 36 = 104.
	 */
	flex: 0 0 36px;
	width: 36px;
	height: 100%;
	padding: 0;
	border: 0;
	background: none;
	color: var(--green-text-fill, #0a435c);
	font-size: 18px;
	line-height: 1;
	cursor: pointer;
}

.inco-product-card .inco-qty__input {
	/*
	 * Mijlocul ia ce rămâne din cei 104: 104 − 36 − 36 = 32.
	 * `flex` în loc de lățime fixă, ca pe cardul îngust să cedeze el, nu
	 * butoanele — alea au 36 din machetă și rămân ținte de atins cu degetul.
	 */
	flex: 1 1 auto;
	min-inline-size: 0;
	width: auto;
	height: 100%;
	padding: 0;
	border: 0;
	background: none;
	color: var(--green-text-fill, #0a435c);
	font-size: clamp(14px, calc(14px + var(--inco-pc-t) * 2), 16px);
	font-weight: 500;
	text-align: center;
	-moz-appearance: textfield;
	appearance: textfield;
}

.inco-product-card .inco-qty__input::-webkit-outer-spin-button,
.inco-product-card .inco-qty__input::-webkit-inner-spin-button {
	margin: 0;
	-webkit-appearance: none;
	appearance: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Butonul principal. Gradientul e cel oficial din design system.

   🔑 `:is(.inco-product-card, .inco-cta)` — al doilea nume îl deschide și în
   afara cardului. Homepage-ul cere ACELAȘI buton la „Adaugă în coș", iar
   alternativa era să-i copiez valorile acolo: gradient, colț 8, pastilă 44×40
   cu colț 7, verdele de hover ca strat separat. Copiate, s-ar fi despărțit la
   prima corectură — și am deja cinci comentarii aici care spun cât a costat
   fiecare dintre ele.

   ⚠️ Specificitatea NU se schimbă: `:is()` o ia pe a celui mai specific
   argument, iar ambele sunt clase simple. Rămâne (0,2,0), cât era — deci nimic
   din ce e reglat fin pe card nu se mișcă. *(§4g, unde asta mă costase)*

   ⚠️ Regulile din `@container` de mai jos RĂMÂN legate de `.inco-product-card`:
   acolo se ascunde eticheta pe cardul îngust, iar în afara cardului nu există
   container care să le declanșeze. De aia butonul de pe homepage se lungește
   după text și nu-l ascunde niciodată — n-a trebuit oprit, n-a fost pornit.
   ═══════════════════════════════════════════════════════════════════════════ */
/*
 * 🔴 `.inco-btn.inco-btn--primary` — aceeași clasă, scrisă de două ori.
 *
 * `[type="submit"]` din `reset.css`-ul temei cântărește (0,1,0), adică EXACT
 * cât `.inco-btn--primary`. La egalitate câștigă cine e mai jos, iar tema se
 * încarcă după noi — deci pe un `<button type="submit">` ieșea rozul `#CC3366`.
 * Pe linkuri și pe butoanele fără `type` nu se vedea, fiindcă regula temei nu-i
 * prindea. → §4g, a șasea oară pe același selector.
 *
 * Dublarea urcă la (0,2,0) fără să schimbe nimic altceva: aceleași declarații,
 * o singură dată, doar cu un selector în plus care le poartă mai sus.
 */
:is(.inco-product-card, .inco-cta) .inco-add-to-cart,
.inco-btn--primary,
.inco-btn.inco-btn--primary {
	display: flex;
	align-items: center;
	/*
	 * 🔴 `gap: 0`, nu 8. Al treilea ocol pe aceeași centrare.
	 *
	 * Gap-ul e VOPSIT în zona colorată — se vede — dar nu face parte din cutia
	 * etichetei. Deci textul se centra într-o cutie cu 8px mai scurtă decât ce
	 * vede ochiul și ieșea împins la stânga cu exact jumătate: **4px**. Măsurat:
	 * zona colorată 73, cutia etichetei 65.
	 *
	 * N-avem nevoie de gap: pastila e albă pe fundal colorat, deci separarea o
	 * face culoarea, nu spațiul.
	 * → 🔑 Ce se vede și ce se măsoară nu sunt aceeași cutie.
	 */
	gap: 0;
	flex: 1 1 auto;
	min-width: 0;
	height: 42px;
	/* Butonul poartă și clasa `btn-primary` a temei, care impune
	   `min-height: 44px` și îmi bătea înălțimea. Măsurat: 44 în loc de 42, iar
	   stepper-ul de lângă rămânea la 42 — se vedea nealiniat. */
	min-height: 0;
	/* 1px în dreapta, ca fundalul să se vadă ca o ramă subțire în jurul pastilei
	   albe — sus și jos vine singur, din 42 − 40. Asta e „bordura" din design:
	   nu e un contur al butonului, e butonul care se vede pe lângă pastilă.

	   🔴 În stânga NU mai e nimic. Aveam 8px puși de mine, pe care macheta nu-i
	   are. Când s-a aplicat Inter, „Adaugă" s-a tăiat: Inter e mai lat decât
	   fontul sistemului, iar textul a crescut de la 56,36 la 58,17 — cu 1,81px.
	   Aveam 57,56 disponibili, deci **lipseau 0,61px**. Scoși cei 8, rămân 7,57
	   de aer, iar eticheta e centrată oricum.
	   → 🔑 Un „trece la limită" nu e o soluție, e o datorie. Ți-o cere fontul. */
	padding: 0 1px 0 0;
	border: 0;
	border-radius: 8px;
	/* Din Figma: `bg-gradient-to-l from-[#013465] to-[#14a5a9]` — adică
	   `to left` cu #013465 la START (dreapta) și #14a5a9 la CAPĂT (stânga).
	   Valoarea stă în `--inco-cta-gradient`, mai sus. */
	background-image: var(--inco-cta-gradient);
	/* 🔴 Explicit, ca să anulez `background: #0d9488` din blocul vechi de sus.
	   Nu se vede sub un gradient opac, dar rămânea acolo ca o mină. */
	background-color: transparent;
	position: relative;
	isolation: isolate;
	color: var(--white-bg, #fafcff);
	font-size: clamp(14px, calc(14px + var(--inco-pc-t) * 2), 16px);
	font-weight: 600;
	letter-spacing: -0.01em;
	text-decoration: none;
	cursor: pointer;
	/* Pastila albă stă lipită de marginea din dreapta. Fără `overflow: hidden`
	   colțul ei drept iese peste raza de 8px a butonului și se vede tăiat urât.
	   În Figma componenta are `clip content` bifat. */
	overflow: hidden;
	transition: border-color var(--inco-tranzitie), color var(--inco-tranzitie);
}

/*
 * 🔴 `background-image` NU e o proprietate animabilă. Gradientele nu se
 * interpolează deloc în CSS — indiferent dacă schimbi într-o culoare plată sau
 * în alt gradient. Am scris în v1.7.2 că „două gradiente se interpolează curat";
 * e fals. Am oprit pâlpâitul atunci din întâmplare, nu din motivul notat.
 *
 * Aici verdele vine dintr-un strat suprapus, iar ce se animă e `opacity` — aia
 * chiar e animabilă. Gradientul rămâne neatins dedesubt, deci nu mai e nimic de
 * comutat brusc.
 *
 * `isolation: isolate` pe buton ține `z-index: -1` al stratului în interiorul
 * butonului; altfel ar aluneca sub fundalul cardului și n-ar mai fi vizibil.
 */
:is(.inco-product-card, .inco-cta) .inco-add-to-cart::before,
.inco-btn--primary::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: #0b8669;
	opacity: 0;
	/*
	 * 🔴 Aici scria că asimetria „intră brusc, iese lent" e de PERCEPȚIE, și că
	 * `ease-in-out` o compensează. **Era greșit, și am apărat greșeala de două
	 * ori.** Seba a insistat; măsurătoarea i-a dat dreptate.
	 *
	 * Cauza adevărată era în altă parte, la două sute de linii de aici:
	 * `.btn-primary.inco-add-to-cart:hover { background: #0f766e }`, din blocul
	 * vechi de sus. Shorthand-ul `background` **șterge `background-image`**, iar
	 * acela NU e animabil — deci pe hover gradientul dispărea instantaneu și
	 * apărea un verde plat, care nici măcar nu era al nostru *(#0F766E, nu
	 * #0B8669)*. La ieșire, `background-image` revenea tot instantaneu, dar
	 * stratul nostru se stingea în 300ms — de acolo „iese lent".
	 *
	 * Tranziția asta era simetrică tot timpul: 279ms la intrare, 291ms la
	 * ieșire, măsurate pe `transitionrun`/`transitionend`. N-a fost niciodată ea
	 * de vină. Acum, cu gradientul redeclarat și pe hover, ea e singurul lucru
	 * care se schimbă.
	 *
	 * → 🔑 Când ceva „pare" în neregulă și eu explic de ce e normal, întâi
	 *   măsor. O explicație plauzibilă e cel mai bun loc în care se poate
	 *   ascunde un bug.
	 *
	 * `ease`, 300ms în ambele sensuri — cerut de Seba.
	 */
	transition: opacity var(--inco-tranzitie);
}

/* `:focus-visible`, nu `:focus`: butonul rămâne focusat după click, cu mouse-ul
   deja plecat. Cu `:focus`, verdele rămânea aprins și următorul hover nu mai
   avea ce anima — o parte din „animația lipsă" venea de aici. */
:is(.inco-product-card, .inco-cta) .inco-add-to-cart:focus-visible::before,
:is(.inco-product-card, .inco-cta) .inco-add-to-cart:active::before,
.inco-btn--primary:focus-visible::before,
.inco-btn--primary:active::before {
	opacity: 1;
}

/*
 * 🔴 Verdele de hover RĂMÂNEA APRINS pe telefon. Semnalat de Seba: „s-a stricat
 * și btn-primary inco-add-to-cart pe mobil, nu mai arată ca pe ultimele
 * versiuni".
 *
 * Nu s-a stricat nimic în fișierul ăsta — `product-card.css` e **identic bit cu
 * bit** din `v1.42.2` până în `v1.46.4`, verificat pe amprenta zipurilor. Ce se
 * întâmpla: pe atingere `:hover` se aprinde și **rămâne** până atingi altceva,
 * iar stratul verde de deasupra e tocmai ce se aprinde pe hover. Deci după
 * primul tap butonul rămânea VERDE, în loc să se întoarcă la gradientul
 * albastru. Pe desktop nu se vede niciodată, fiindcă acolo mouse-ul pleacă.
 *
 * ⚠️ `:active` rămâne afară: el ține doar cât ține degetul pe ecran, deci e
 * chiar reacția la apăsare pe care o vrem pe telefon. `:focus-visible` la fel,
 * pentru tastatură.
 */
@media (hover: hover) {
	:is(.inco-product-card, .inco-cta) .inco-add-to-cart:hover::before,
	.inco-btn--primary:hover::before {
		opacity: 1;
	}
}

:is(.inco-product-card, .inco-cta) .inco-add-to-cart:hover,
:is(.inco-product-card, .inco-cta) .inco-add-to-cart:focus,
:is(.inco-product-card, .inco-cta) .inco-add-to-cart:active,
.inco-btn--primary:hover,
.inco-btn--primary:focus,
.inco-btn--primary:active {
	border-color: #0b8669;
	color: var(--white-bg, #fafcff);
	box-shadow: none;
	/*
	 * 🔴 Gradientul se REDECLARĂ pe hover. Nu e redundanță — e singurul lucru
	 * care oprește `.btn-primary.inco-add-to-cart:hover { background: #0f766e }`
	 * din blocul vechi de sus să-l șteargă.
	 *
	 * Amândouă cântăresc (0,3,0); regula asta e mai jos în fișier, deci câștigă.
	 * Valoarea nu se dublează: vine din aceeași variabilă ca starea de repaus.
	 *
	 * ⚠️ Și `background-color`, din același motiv — shorthand-ul `background`
	 * din regula veche le atinge pe amândouă deodată.
	 */
	background-image: var(--inco-cta-gradient);
	background-color: transparent;
	/*
	 * 🔴 Trebuie IDENTIC cu starea de repaus. A DOUA oară că uit perechea:
	 *
	 * - v1.7.4: aici scria `0 0 0 8px`, baza `0 1px 0 8px` → pe hover pastila
	 *   sărea 1px la dreapta și rama din dreapta dispărea.
	 * - v1.12.16: am scos cei 8px din stânga în bază, ca să încapă „Adaugă" cu
	 *   Inter, și iar am uitat aici. Rezultatul: textul se vedea întreg în
	 *   repaus și se tăia SUB MOUSE. Măsurat: −0,2px pe hover.
	 *
	 * → 🔑 Regula „se declară toate proprietățile stării" are un preț: fiecare
	 *   valoare există în două locuri, deci se schimbă în două locuri.
	 */
	padding: 0 1px 0 0;
}

/*
 * Ochiul apare DOAR pe card îngust. Pe desktop butonul rămâne text simplu —
 * „Vezi produsul" spune deja tot, iar o pastilă în plus ar fi zgomot.
 *
 * Pe îngust însă eticheta e ascunsă vizual, deci fără iconiță butonul ar rămâne
 * complet gol. Acolo iconița nu e decor, e singurul conținut.
 */
:is(.inco-product-card, .inco-cta) .inco-add-to-cart.is-view .inco-add-to-cart__icon {
	display: none;
}

/* Fără pastilă vizibilă, padding-ul asimetric n-are ce justifica. */
:is(.inco-product-card, .inco-cta) .inco-add-to-cart.is-view {
	padding: 0 8px;
}


/* Eticheta cedează prima. Fără asta, un text mai lung — pus din setări sau
   venit din altă limbă — strivește pastila cu coșul în loc să se scurteze. */
:is(.inco-product-card, .inco-cta) .inco-add-to-cart__label,
.inco-btn--primary .inco-btn__label {
	/* Medium, din machetă — nu 600, cât moștenea de la buton. */
	font-weight: 500;
	flex: 1 1 auto;
	min-width: 0;
	overflow: hidden;
	text-align: center;
	text-overflow: ellipsis;
	white-space: nowrap;
	/*
	 * `overflow: hidden` taie la marginea casetei, iar caseta unui text are
	 * înălțimea `line-height`. Cu line-height 1, coada lui „g" din „Adaugă" iese
	 * din casetă și e retezată. 1.4 lasă loc descenderelor.
	 */
	line-height: 1.4;
}

:is(.inco-product-card, .inco-cta) .inco-add-to-cart__icon,
.inco-btn--primary .inco-btn__icon {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	/*
	 * 🔴 Rămâne 44 — e mărimea din design, și tot ea e butonul întreg pe cardul
	 * îngust, unde eticheta e ascunsă.
	 *
	 * „Adaugă" se tăia din altă cauză: la 238px butonul avea 108 disponibili și
	 * 108 necesari — exact la limită, deci rotunjirea tăia. Aerul vine acum din
	 * paddingul butonului, pe care macheta nu-l are; eticheta e centrată
	 * oricum. → `.inco-add-to-cart` mai jos
	 *
	 * ⚠️ Prima mea reparație micșora iconița, prin interpolare. Mergea, dar
	 * schimba designul ca să încapă textul — Seba a arătat că problema era
	 * paddingul, nu iconița.
	 */
	width: 44px;
	height: 40px;
	/*
	 * 🔴 Vinovatul nu era tema, era fișierul ăsta.
	 *
	 * Mai sus, din vremea Loop Item-ului, există
	 *     .btn-primary.inco-add-to-cart .inco-add-to-cart__icon { padding-left: 10px }
	 * care are DOUĂ clase pe buton, deci bate un `padding: 0` cu una singură.
	 * Măsurat: glifa era perfect centrată în SVG, dar caseta SVG stătea 5,5px
	 * la dreapta în pastilă. De aceea corecțiile pe desen n-au ajutat niciodată.
	 */
	padding: 0;
	/* Colț 7, din machetă — cu 1px mai mic decât cei 8 ai butonului, ca rama
	   subțire de gradient să rămână de grosime constantă pe tot conturul. */
	border-radius: 7px;
	background: #fff;
	/* Iconița ia culoarea fundalului butonului, nu una fixă: pe hover butonul
	   devine verde, deci și coșul. Altfel rămânea albastru pe verde. */
	color: #013465;
	transition: color var(--inco-tranzitie);
}

/*
 * 🔴 `:focus-visible`, nu `:focus` — corectat odată cu hover-ul de pe telefon.
 *
 * Regula soră de mai sus *(stratul verde)* folosea deja `:focus-visible`, cu
 * motivul scris lângă ea: butonul rămâne focusat după apăsare, cu mouse-ul deja
 * plecat. Aici rămăsese `:focus`, deci coșul se făcea verde la apăsare și
 * **rămânea verde** — pe desktop până dădeai click altundeva, pe telefon la fel.
 * Două reguli pentru același buton, cu două păreri despre aceeași stare.
 *
 * ⚠️ Pe telefon nu era destul să mut `:hover` sub `@media (hover: hover)`:
 * atingerea lasă în urmă **și** focusul, deci glifa ar fi rămas verde oricum.
 * → **o stare lipită are de obicei mai multe cârlige; se scot toate, nu unul.**
 */
:is(.inco-product-card, .inco-cta) .inco-add-to-cart:focus-visible .inco-add-to-cart__icon,
:is(.inco-product-card, .inco-cta) .inco-add-to-cart:active .inco-add-to-cart__icon,
.inco-btn--primary:focus-visible .inco-btn__icon,
.inco-btn--primary:active .inco-btn__icon {
	color: #0b8669;
}

@media (hover: hover) {
	:is(.inco-product-card, .inco-cta) .inco-add-to-cart:hover .inco-add-to-cart__icon,
	.inco-btn--primary:hover .inco-btn__icon {
		color: #0b8669;
	}
}

:is(.inco-product-card, .inco-cta) .btn-primary.inco-add-to-cart .inco-add-to-cart__icon {
	padding: 0;
}

:is(.inco-product-card, .inco-cta) .inco-add-to-cart__icon svg {
	width: 24px;
	height: 24px;
}

/*
 * Sub ~200px nu mai încape „Adaugă" lângă stepper. Atunci butonul rămâne doar
 * pastila cu coșul — **aceeași cutie ca butonul cu ochiul**, doar iconița diferă.
 * Este singurul breakpoint din tot fișierul; restul se interpolează, pentru că
 * doar aici se schimbă STRUCTURA, nu mărimea.
 *
 * 🔑 Revizuit pe 7 august, cu nodul din Figma pe masă *(pastila: W 44 · H 38 ·
 * colț 6 · fill `white-bg`)*. Butonul are 42 înălțime, deci **42 − 38 = 4**:
 * gradientul se vede **2px de jur împrejur**. Ăla E „borderul de 2px" — nu e un
 * contur, e butonul care se vede pe lângă pastilă, exact ca pe desktop, doar mai
 * gros *(acolo e 1px)*.
 * ⚠️ Anulează decizia de pe 31 iulie *(„outline pe mobil")*: fundalul alb plat
 * se topea în card, motiv pentru care Seba a cerut ceva mai vizibil.
 */
@container (max-width: 199.98px) {
	/*
	 * 48 = 44 pastila + 2 + 2, ca MINIM — nu ca lățime fixă.
	 *
	 * 🔴 Fixă era greșit, și se vedea doar între 156 și 200. Regulile de aici
	 * au fost scrise pentru cardul de **156** din machetă: 92 + 16 + 48 = 156,
	 * fix. Dar `@container` ține până la 199,98 — iar la un ecran de 440px
	 * cardul iese **196**, deci rândul rămânea 156 și lăsa **40px goi la
	 * dreapta**. Măsurat de Seba pe iPhone 16 Pro Max, găsit de mine la 440.
	 *
	 * 🔑 O valoare luată dintr-o singură machetă descrie un singur punct, nu
	 * intervalul în care e folosită. Steperul rămâne 92, butonul ia restul:
	 * la 156 iese tot 48 *(nimic nu se schimbă acolo)*, la 196 iese 88.
	 *
	 * 🔴 **ANULAT pe 13 august. Butonul se întoarce la 48 fix.**
	 *
	 * Reparația de mai sus rezolva un gol adevărat, dar cu prețul greșit: a
	 * schimbat FORMA butonului. Din `v1.24.0` el se lungea odată cu cardul, deci
	 * la 196 ieșea 88 lat și 42 înalt — o bară, nu pătratul din machetă. Seba:
	 * *„nu este ca și înainte pe mobile […] arată cu totul diferit, ca și în
	 * Figma, avea 1/1 ratio."*
	 *
	 * Găsit comparând fișierul din **toate cele 38 de livrări** care îl conțin:
	 * până în `v1.22.1` scria `flex: 0 0 auto; inline-size: 48px`, din `v1.24.0`
	 * scrie `flex: 1 1 auto`. Deci nu e o bănuială — se vede în ce zi s-a
	 * schimbat și cu ce.
	 *
	 * 🔑 **Golul de 40px se dă STEPERULUI, nu butonului.** Butonul e o iconiță
	 * într-o pastilă: are o formă. Steperul e un câmp cu două butoane: el poate
	 * respira. Am întins exact lucrul care nu trebuia întins.
	 * → **când ceva „nu încape", întreabă întâi CINE are voie să crească.**
	 *
	 * Socoteala rămâne aceeași la 156 *(92 + 16 + 48)* și se închide și la 196
	 * *(132 + 16 + 48)*, deci nici gol la dreapta, nici buton deformat.
	 */
	.inco-product-card .inco-add-to-cart,
	.inco-product-card .inco-add-to-cart.is-view {
		flex: 0 0 auto;
		inline-size: 48px;
		justify-content: center;
		padding: 2px;
		border: 0;
	}

	/*
	 * 🔑 92 e PODEAUA steperului, nu lățimea lui.
	 *
	 * Cei 12px sub cei 104 obișnuiți sunt decizia lui Seba din 7 aug: la card de
	 * 156, `48 + 16 + 92 = 156`, iar gapul rămâne 16 deci butoanele nu se
	 * lipesc. „+" și „−" rămân 36 fiecare — ținta pentru deget nu se schimbă,
	 * cedează doar câmpul din mijloc, 32 → 20.
	 *
	 * Ce e nou: peste 156, **steperul ia surplusul**, nu butonul. La card 196
	 * iese 132, deci rândul se închide fix și butonul își păstrează forma.
	 */
	.inco-product-card .inco-product-quantity {
		flex: 1 1 auto;
		inline-size: auto;
		min-inline-size: 92px;
	}

	/* Ochiul se vede DOAR aici: eticheta e ascunsă, el rămâne conținutul. */
	.inco-product-card .inco-add-to-cart.is-view .inco-add-to-cart__icon {
		display: flex;
	}

	.inco-product-card .inco-add-to-cart.is-view .inco-add-to-cart__icon svg {
		width: 22px;
		height: 22px;
	}

	.inco-product-card .inco-add-to-cart__label {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
	}

	/*
	 * Pastila umple butonul, minus cei 2px de gradient.
	 *
	 * 🔴 Comentariul ăsta era ADEVĂRAT și codul de sub el nu. Semnalat de Seba
	 * cu macheta alături: *„înainte arătau ca în Figma, ceva le-a stricat"*.
	 *
	 * Cât butonul era fix pe 48, `inline-size: 44px` chiar însemna „umple, minus
	 * 2 de fiecare parte". Apoi butonul a devenit elastic *(`flex: 1 1 auto`,
	 * ca să nu mai rămână 40px goi la dreapta pe ecrane de 440)* — **și i-am
	 * spus doar butonului să crească, nu și pastilei.**
	 *
	 * Măsurat la 440, card 196: buton **88**, pastilă **44** → gradientul se
	 * vedea **2px sus și jos, dar 22px stânga și dreapta**.
	 *
	 * ⚠️ **Prima mea reparație a fost tot greșită** — am făcut pastila elastică,
	 * ca să umple butonul lungit. Rama redevenea uniformă, dar butonul rămânea o
	 * bară de 88×42 în loc de pătratul din machetă. **Am reparat simptomul.**
	 * Cauza era că butonul n-avea voie să se lungească deloc — vezi mai sus.
	 *
	 * 🔑 Cu butonul înapoi la 48 fix, `44` chiar înseamnă din nou „umple
	 * butonul, minus cei 2px": `48 − 2 − 2 = 44`. Comentariul și codul spun
	 * iar același lucru.
	 */
	.inco-product-card .inco-add-to-cart .inco-add-to-cart__icon {
		inline-size: 44px;
		block-size: 38px;
		margin: 0;
		background: var(--white-bg, #fafcff);
		color: #013465;
	}
}

/* Fără container queries (browsere foarte vechi), cardul rămâne la valorile de
   bază din `clamp()` — adică varianta mobilă. Citibil peste tot, doar nu la fel
   de generos pe ecran mare. Degradare, nu stricare. */

/* ═══════════════════════════════════════════════════════════════════════════
   CARUSEL — `[inco_products carusel="da"]`

   🔑 Scroll nativ cu `scroll-snap`, nu transform-uri.

   Așa degetul merge din prima pe telefon, tastatura merge din prima, iar
   accesibilitatea vine gratis: e o zonă derulabilă obișnuită. Un carusel făcut
   din `transform` ar fi cerut cod pentru fiecare din lucrurile astea, iar
   fiecare dintre ele ar fi putut fi stricat.

   Aceleași praguri și aceeași lățime de card ca la grilă — cardul nu știe și nu
   trebuie să știe în ce anume stă.
   ═══════════════════════════════════════════════════════════════════════════ */

.inco-products.is-carusel .inco-products__grid {
	grid-auto-flow: column;
	grid-auto-columns: calc((100% - (var(--inco-c, 2) - 1) * var(--inco-gap, 16px)) / var(--inco-c, 2));
	grid-template-columns: none;
	overflow-x: auto;
	overscroll-behavior-x: contain;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	/* Bara de derulare a sistemului ar dubla bara noastră de progres. */
	scrollbar-width: none;
	/*
	 * 🔴 Bordura din stânga a primului card vizibil era tăiată după derulare.
	 *
	 * `scroll-snap-align: start` aliniază cardul exact la marginea zonei
	 * derulabile, iar acolo `overflow` retează. Cu 1px de spațiu interior,
	 * cardul se oprește la un pixel înăuntru și bordura încape. Marginea
	 * negativă anulează spațiul, ca grila și caruselul să înceapă tot de la
	 * aceeași linie verticală în pagină.
	 *
	 * Jos, 2px pentru conturul de focus al cardurilor.
	 */
	padding: 1px 1px 2px;
	margin-inline: -1px;
	scroll-padding-inline: 1px;
}

.inco-products.is-carusel .inco-products__grid::-webkit-scrollbar { display: none; }

.inco-products.is-carusel .inco-product-card { scroll-snap-align: start; }

/* ─────────────────────────────────── carusel DOAR pe telefon *(`carusel="telefon"`)*
 *
 * Peste 900px se desface la loc în grilă. E scris ca anulare, nu ca a doua
 * definiție a caruselului: altfel aceleași valori ar fi existat în două locuri
 * și s-ar fi despărțit la prima corectură *(§4k)*.
 *
 * ⚠️ Coloanele nu se rescriu cu o cifră — se întorc la `--inco-c`, pe care îl
 * calculează container queries de mai sus. Aici nu se știe și nu trebuie să se
 * știe câte coloane ies.
 */
@media (min-width: 900px) {
	.inco-products.is-carusel--telefon .inco-products__grid {
		grid-auto-flow: row;
		grid-auto-columns: auto;
		grid-template-columns: repeat(var(--inco-c, 2), minmax(0, 1fr));
		overflow-x: visible;
		scroll-snap-type: none;
	}

	/* Bara de progres și săgețile n-au ce conduce într-o grilă. */
	.inco-products.is-carusel--telefon .inco-products__controale { display: none; }
}

/* `--inco-gap` dublează valorile de `gap` de mai sus, pentru că `calc()` nu
   poate citi spațierea efectivă a grilei. Se schimbă la aceleași praguri. */
.inco-products__grid { --inco-gap: 16px; }
@container (min-width: 560px)  { .inco-products__grid { --inco-gap: 24px; } }
@container (min-width: 1120px) { .inco-products__grid { --inco-gap: 32px; } }

/* ─────────────────────────────────────────────── bara de progres */

.inco-products__controale {
	display: flex;
	align-items: center;
	gap: 16px;
	margin-top: 20px;
}

.inco-progres {
	flex: 1 1 auto;
	height: 2px;
	overflow: hidden;
	border-radius: 99px;
	background: var(--grey-border-fill, #c4d2d7);
}

.inco-progres__umplere {
	width: 0;
	height: 100%;
	border-radius: 99px;
	background: var(--green-fill-primary-default, #056e9b);
	/* Fără tranziție: la derulare cu degetul, umplerea trebuie să urmărească
	   mișcarea în timp real, nu s-o ajungă din urmă. La apăsarea pe săgeată,
	   derularea e oricum lină, deci bara crește lin odată cu ea. */
}

/* ─────────────────────────────────────────────── săgeți */

.inco-products__sageti {
	display: flex;
	gap: 16px;
	flex: 0 0 auto;
}

/*
 * 🔴 A treia oară aceeași lecție. `reset.css` din temă dădea săgeților
 * `padding: 8px 16px` și `border: 1px solid #cc3366` — măsurat, ieșeau 54×40 cu
 * contur roz. Selectorul lui e (0,2,0), al meu era (0,1,0).
 *
 * Aici e declarat TOT, pe toate stările, cu specificitate suficientă. Nu doar
 * ce se vedea stricat în captură.
 */
.inco-products .inco-sageata,
.inco-products .inco-sageata:hover,
.inco-products .inco-sageata:focus,
.inco-products .inco-sageata:active,
.inco-products .inco-sageata[disabled] {
	/*
	 * 40×40 fix, cu săgeata de 26×14 centrată. Rămân 7px lateral și 13px
	 * sus-jos.
	 *
	 * 🔑 În Figma scrie 8 și 14, și tot ăsta e rezultatul: acolo valorile se
	 * măsoară până la GEOMETRIA săgeții (24×12), iar exportul are caseta 26×14
	 * pentru că include grosimea de 1,5 a conturului. Aceeași săgeată, două
	 * moduri de a măsura.
	 */
	box-sizing: border-box;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	min-width: 0;
	min-height: 0;
	padding: 0;
	border: 1px solid var(--grey-border-fill, #c4d2d7);
	border-radius: 8px;
	box-shadow: none;
	font-size: inherit;
	cursor: pointer;
	transition: background var(--inco-tranzitie, .3s ease), color var(--inco-tranzitie, .3s ease);
}

.inco-products .inco-sageata,
.inco-products .inco-sageata:focus {
	background: var(--green-fill-primary-default, #056e9b);
	color: var(--white-bg, #fafcff);
}

.inco-products .inco-sageata:hover,
.inco-products .inco-sageata:focus-visible {
	background: #0b8669;
	color: var(--white-bg, #fafcff);
}

/* Capătul listei. Culorile sunt cele din Figma pentru starea dezactivată. */
.inco-products .inco-sageata[disabled],
.inco-products .inco-sageata[disabled]:hover,
.inco-products .inco-sageata[disabled]:focus {
	background: var(--grey-border-fill, #c4d2d7);
	color: var(--white-bg, #fafcff);
	cursor: default;
}

.inco-products .inco-sageata svg {
	width: 26px;
	height: 14px;
	flex: 0 0 auto;
}

/* Cine a cerut mai puțină mișcare o primește: derularea rămâne, dar instant. */
@media (prefers-reduced-motion: reduce) {
	.inco-products.is-carusel .inco-products__grid { scroll-behavior: auto; }
}

/*
 * Comenzile caruselului dispar când nu e ce derula.
 *
 * 🔑 `display: none`, nu `visibility` sau `opacity`: altfel rândul ar rămâne
 * gol sub grilă, iar spațiul de sub secțiune ar fi mai mare decât la una fără
 * carusel — o diferență care se vede când două secțiuni stau una sub alta.
 *
 * Clasa o pune JS-ul, care măsoară; ea nu se poate deduce din CSS, fiindcă
 * depinde de câte carduri încap la lățimea containerului. Fără JS, comenzile
 * rămân vizibile dar dezactivate — starea din care porneste marcajul.
 */
.inco-products.is-fara-derulare .inco-products__controale {
	display: none;
}
