/* ==========================================================================
   Vértice Commerce 2 — core/shop.css
   Mecánica del archivo de tienda (sin estética de marca, SOLO tokens):
   wrapper, header del archivo, breadcrumbs, panel de filtros (sidebar
   desktop + off-canvas mobile), chips activos, grid de productos
   #vc-products-grid, tarjeta .vc-card (badges, wishlist, quick view),
   result count / orderby, paginación, estado vacío, modal de vista rápida
   y stepper de cantidad (para el form del quick view).

   Se encola con is_woocommerce() ⇒ cubre tienda, taxonomías de producto y
   TAMBIÉN la ficha (por eso .vc-low-stock, .vc-breadcrumbs y la
   neutralización de botones viven acá y product.css no las repite). El
   stepper .vc-qty vive en core/components.css (única fuente, §14).

   Convenciones del motor:
   - Mobile-first; breakpoints 640 / 880 / 1100 (min-width).
   - Foco: :focus-visible + var(--focus-ring), nunca outline:none sin reemplazo.
   - Motion SOLO dentro de @media (prefers-reduced-motion: no-preference).
   - z-index SOLO vía var(--z-*). Sin !important (se gana por especificidad).
   ========================================================================== */

/* ============================ 1. WRAPPER DE TIENDA ====================== */
/* global/wrapper-start.php: #primary.vc-shop > .vc-container.vc-shop__inner
   > .vc-shop__main. */
.vc-shop {
	padding-block: var(--sp-6) var(--sp-8);
}
.vc-shop__inner { display: block; }
.vc-shop__main { width: 100%; }

/* ============================ 2. BREADCRUMBS ============================ */
/* inc/woocommerce.php: nav.vc-breadcrumbs > .vc-container, ítems
   .vc-breadcrumbs__item separados por .vc-breadcrumbs__sep. */
.vc-breadcrumbs {
	padding-top: var(--sp-4);
	font-size: var(--fs-sm);
	color: var(--ink-3);
}
.vc-breadcrumbs a { color: var(--ink-2); text-decoration: none; }
.vc-breadcrumbs a:hover { color: var(--brand-strong); }
.vc-breadcrumbs a:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}
.vc-breadcrumbs__sep {
	margin-inline: 0.45rem;
	color: var(--line);
}

/* ============================ 3. HEADER DEL ARCHIVO ===================== */
/* loop/header.php: header.vc-shop-header (título + descripción del término
   vía woocommerce_archive_description, que imprime <p> sueltos). */
.vc-shop-header {
	margin-bottom: var(--sp-6);
	max-width: 70ch;
}
.vc-shop-header__title {
	font-family: var(--font-display);
	font-size: var(--fs-h1);
	line-height: var(--lh-tight);
	color: var(--ink);
	margin: 0 0 var(--sp-3);
}
.vc-shop-header .term-description,
.vc-shop-header > p {
	margin: 0;
	color: var(--ink-2);
	line-height: var(--lh-body);
}
.vc-shop-header p + p { margin-top: var(--sp-3); }

/* ============================ 4. LAYOUT ASIDE + MAIN ==================== */
/* archive-product.php: .vc-shop-layout > (.vc-shop-layout__aside con
   vc_filters_panel())? + .vc-shop-layout__main. El grid de 2 columnas solo
   existe si hay aside (sin :has el fallback es una columna, usable). */
.vc-shop-layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--sp-5);
	align-items: start;
}
@media (min-width: 880px) {
	.vc-shop-layout:has(> .vc-shop-layout__aside) {
		grid-template-columns: 260px minmax(0, 1fr);
		gap: var(--sp-7);
	}
	.vc-shop-layout__aside {
		position: sticky;
		top: calc(var(--header-h) + var(--wp-admin--admin-bar--height, 0px) + var(--sp-3));
		max-height: calc(100dvh - var(--header-h) - var(--sp-5));
		overflow-y: auto;
	}
}

/* ============================ 5. PANEL DE FILTROS ======================= */
/* inc/filters.php: form.vc-filters[data-vc-filters] method=get. Grupos como
   fieldset .vc-filters__group--{price|cats|attr|stock|order}. */
.vc-filters {
	display: flex;
	flex-direction: column;
	gap: var(--sp-4);
}
.vc-filters__group {
	margin: 0;
	padding: 0 0 var(--sp-4);
	border: 0;
	border-bottom: var(--border-w) solid var(--line);
	min-width: 0;
}
.vc-filters__legend {
	display: block;
	padding: 0;
	margin: 0 0 var(--sp-3);
	font-size: var(--fs-sm);
	font-weight: 600;
	color: var(--ink);
}

/* Precio: dos inputs numéricos en fila. */
.vc-filters__price {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
}
.vc-filters__price-input {
	width: 100%;
	min-width: 0;
	padding: 0.55rem 0.7rem;
	font: inherit;
	font-size: var(--fs-sm);
	color: var(--ink);
	background: var(--surface);
	border: var(--border-w) solid var(--line);
	border-radius: var(--radius-md);
}
.vc-filters__price-input:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}
.vc-filters__price-sep { color: var(--ink-3); flex: none; }

/* Listas de checkboxes (categorías / atributos): scroll propio si son largas. */
.vc-filters__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.15rem;
	max-height: 16rem;
	overflow-y: auto;
}
.vc-filters__item { margin: 0; }
.vc-filters__check {
	display: flex;
	align-items: center;
	gap: 0.55rem;
	padding: 0.35rem 0.25rem;
	border-radius: var(--radius-sm);
	font-size: var(--fs-sm);
	color: var(--ink-2);
	cursor: pointer;
	line-height: var(--lh-snug);
}
.vc-filters__check:hover { background: var(--surface-2); color: var(--ink); }
.vc-filters__check input[type="checkbox"] {
	flex: none;
	width: 1.05rem;
	height: 1.05rem;
	margin: 0;
	accent-color: var(--brand);
}
.vc-filters__check input[type="checkbox"]:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}
.vc-filters__check-label { min-width: 0; overflow-wrap: anywhere; }
.vc-filters__count {
	margin-left: auto;
	font-size: var(--fs-xs);
	color: var(--ink-3);
	flex: none;
}

/* Orden (select del panel; reusa ?orderby= nativo). */
.vc-filters__group--order { border-bottom: 0; padding-bottom: 0; }
.vc-filters__orderby {
	width: 100%;
	padding: 0.55rem 0.7rem;
	font: inherit;
	font-size: var(--fs-sm);
	color: var(--ink);
	background: var(--surface);
	border: var(--border-w) solid var(--line);
	border-radius: var(--radius-md);
	/* Chevron: el nativo del UA (sin appearance:none). Un data-URI no puede
	   usar tokens (currentColor no aplica en background) y el gris fijo
	   %23888888 era el único color hardcodeado del grupo — rompía el
	   contrato "SOLO tokens" y no se adaptaba a una piel oscura. El del UA
	   sigue el color-scheme. */
}
.vc-filters__orderby:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}

/* Acciones del panel. */
.vc-filters__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--sp-3);
}
.vc-filters__apply { flex: 1 1 auto; }
.vc-filters__clear {
	font-size: var(--fs-sm);
	color: var(--ink-3);
	text-decoration: underline;
	text-underline-offset: 3px;
}
.vc-filters__clear:hover { color: var(--accent-strong); }
.vc-filters__clear:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}

/* --- Off-canvas mobile (CONTRATO JS, Task 11) ---------------------------
   Sin JS: el aside queda en el flujo (arriba del grid), 100% usable.
   Con JS, en <880px:
   - inyecta button.vc-filters-toggle[data-vc-filters-toggle] al tope de
     .vc-shop-layout__main (aria-controls al aside, aria-expanded),
   - agrega .is-offcanvas al aside y lo abre/cierra con .is-open +
     body.vc-filters-open + un div.vc-filters-overlay[data-vc-filters-close].
   En ≥880px el JS quita .is-offcanvas (el CSS igual lo resetea). */
.vc-filters-toggle {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	margin-bottom: var(--sp-4);
	padding: 0.6rem 1rem;
	font: inherit;
	font-size: var(--fs-sm);
	font-weight: 500;
	color: var(--ink);
	background: var(--surface);
	border: var(--border-w) solid var(--line);
	border-radius: var(--radius-pill);
	cursor: pointer;
}
.vc-filters-toggle svg { width: 18px; height: 18px; }
.vc-filters-toggle:hover { border-color: var(--brand); color: var(--brand-strong); }
.vc-filters-toggle:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}

.vc-shop-layout__aside.is-offcanvas {
	position: fixed;
	top: 0;
	bottom: 0;
	left: 0;
	z-index: var(--z-modal);
	width: min(340px, 88vw);
	padding: var(--sp-5);
	background: var(--surface);
	border-right: var(--border-w) solid var(--line);
	box-shadow: var(--shadow-3);
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	transform: translateX(-102%);
	visibility: hidden;
}
.vc-shop-layout__aside.is-offcanvas.is-open {
	transform: none;
	visibility: visible;
}
.vc-filters-overlay {
	position: fixed;
	inset: 0;
	z-index: var(--z-overlay);
	background: color-mix(in srgb, var(--surface-inverse) 45%, transparent);
	opacity: 0;
	visibility: hidden;
}
.vc-filters-overlay.is-open { opacity: 1; visibility: visible; }
body.vc-filters-open { overflow: hidden; }

@media (min-width: 880px) {
	/* En desktop el panel jamás es off-canvas (reset defensivo por si el JS
	   no llegó a limpiar la clase en un resize). */
	.vc-filters-toggle { display: none; }
	.vc-shop-layout__aside.is-offcanvas {
		position: sticky;
		top: calc(var(--header-h) + var(--wp-admin--admin-bar--height, 0px) + var(--sp-3));
		bottom: auto;
		z-index: auto;
		width: auto;
		padding: 0;
		border-right: 0;
		box-shadow: none;
		transform: none;
		visibility: visible;
	}
	.vc-filters-overlay { display: none; }
}

/* ============================ 6. CHIPS DE FILTROS ACTIVOS =============== */
/* inc/filters.php (vc_filters_chips): viven DENTRO de #vc-products-grid. */
.vc-filters-chips {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--sp-2) var(--sp-3);
	margin-bottom: var(--sp-4);
}
.vc-filters-chips__label {
	font-size: var(--fs-sm);
	color: var(--ink-3);
}
.vc-filters-chips__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-2);
}
.vc-filters-chips__item { margin: 0; }

.vc-chip {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	padding: 0.3rem 0.75rem;
	font-size: var(--fs-xs);
	font-weight: 500;
	line-height: 1.2;
	color: var(--brand-strong);
	background: var(--brand-soft);
	border: var(--border-w) solid transparent;
	border-radius: var(--radius-pill);
	text-decoration: none;
}
.vc-chip:hover { border-color: var(--brand); }
.vc-chip:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}
.vc-chip__x { display: inline-grid; place-items: center; }
.vc-chip__x svg { width: 14px; height: 14px; }
.vc-chip--clear {
	background: transparent;
	border-color: var(--line);
	color: var(--ink-3);
}
.vc-chip--clear:hover { color: var(--accent-strong); border-color: var(--accent); }

/* ============================ 7. GRID DE PRODUCTOS ====================== */
/* inc/filters.php (vc_shop_grid): #vc-products-grid.vc-shop-grid es el nodo
   que el AJAX reemplaza entero. Adentro: chips + notices + result count +
   ul.products + paginación. */
#vc-products-grid { display: block; }

/* woocommerce_product_loop_start imprime <ul class="products columns-N">.
   GOTCHA CONOCIDO: el CSS del core clearfixea ul.products con ::before/
   ::after; como ítems de grid generan una "celda fantasma" que descuadra la
   primera fila. Se anulan SIEMPRE, en todos los contextos. */
ul.products::before,
ul.products::after,
.woocommerce ul.products::before,
.woocommerce ul.products::after,
.woocommerce-page ul.products::before,
.woocommerce-page ul.products::after {
	content: none;
}

/* La grilla. Mobile-first: 2 por fila; ≥640px celdas fluidas. La versión
   .woocommerce/.woocommerce-page repite la regla con la especificidad
   necesaria para ganarle a los floats/anchos del CSS del core (sin
   !important). */
ul.products,
.woocommerce ul.products,
.woocommerce-page ul.products,
.woocommerce ul.products.columns-1,
.woocommerce ul.products.columns-2,
.woocommerce ul.products.columns-3,
.woocommerce ul.products.columns-4,
.woocommerce ul.products.columns-5,
.woocommerce ul.products.columns-6 {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--sp-3);
	margin: 0;
	padding: 0;
	list-style: none;
}
@media (min-width: 640px) {
	ul.products,
	.woocommerce ul.products,
	.woocommerce-page ul.products,
	.woocommerce ul.products.columns-1,
	.woocommerce ul.products.columns-2,
	.woocommerce ul.products.columns-3,
	.woocommerce ul.products.columns-4,
	.woocommerce ul.products.columns-5,
	.woocommerce ul.products.columns-6 {
		grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
		gap: var(--sp-4);
	}
}
ul.products > li,
.woocommerce ul.products li.product,
.woocommerce-page ul.products li.product {
	width: auto;
	margin: 0;
	padding: 0;
	float: none;
	clear: none;
	list-style: none;
	display: flex; /* la tarjeta estira al alto de la fila */
}

/* ============================ 8. TARJETA .vc-card ======================= */
/* content-product.php: li.vc-card-item > article.vc-card. */
.vc-card {
	position: relative;
	display: flex;
	flex-direction: column;
	width: 100%;
	min-width: 0;
	background: var(--surface-raised);
	border: var(--border-w) solid var(--line);
	border-radius: var(--radius-card);
	overflow: hidden;
}
.vc-card:hover { border-color: color-mix(in srgb, var(--brand) 40%, var(--line)); box-shadow: var(--shadow-1); }

/* Media: la piel puede cambiar la proporción con --vc-card-aspect. */
.vc-card__media {
	position: relative;
	background: var(--surface-2);
	overflow: hidden;
}
.vc-card__media-link {
	display: block;
	width: 100%;
	aspect-ratio: var(--vc-card-aspect, 1 / 1);
}
.vc-card__media-link img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.vc-card:hover .vc-card__media-link img { transform: scale(1.03); }

/* Badges: columna arriba a la izquierda. */
.vc-card__badges {
	position: absolute;
	top: var(--sp-2);
	left: var(--sp-2);
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.3rem;
	pointer-events: none;
}
.vc-badge {
	display: inline-flex;
	align-items: center;
	padding: 0.28rem 0.65rem;
	font-size: var(--fs-xs);
	font-weight: 500;
	line-height: 1;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	border-radius: var(--radius-pill);
	background: var(--surface-2);
	color: var(--ink-2);
}
.vc-badge--oferta { background: var(--accent-soft); color: var(--accent-strong); }
.vc-badge--nuevo { background: var(--brand-soft); color: var(--brand-strong); }
.vc-badge--agotado { background: var(--surface-2); color: var(--ink-3); }

/* El sale flash sale como span.onsale.vc-badge--oferta. El CSS del core lo
   posiciona absolute con min-width/height propios y GANA por especificidad
   (.woocommerce span.onsale / .woocommerce ul.products li.product .onsale).
   Se fuerza a fluir dentro de .vc-card__badges con selectores MÁS
   específicos (fix woo-overrides.css:8: especificidad acotada, sin
   !important). */
.vc-card__badges .onsale,
.woocommerce ul.products li.product .vc-card__badges .onsale,
.woocommerce-page ul.products li.product .vc-card__badges .onsale {
	position: static;
	inset: auto;
	margin: 0;
	min-width: 0;
	min-height: 0;
	width: auto;
	height: auto;
	display: inline-flex;
	align-items: center;
	padding: 0.28rem 0.65rem;
	font-size: var(--fs-xs);
	font-weight: 500;
	line-height: 1;
	border-radius: var(--radius-pill);
	background: var(--accent-soft);
	color: var(--accent-strong);
	text-transform: uppercase;
}

/* Botón wishlist (corazón). aria-pressed=true ⇒ activo (relleno). */
.vc-wish {
	position: absolute;
	top: var(--sp-2);
	right: var(--sp-2);
	z-index: 2;
	display: grid;
	place-items: center;
	width: 40px;
	height: 40px;
	padding: 0;
	border: var(--border-w) solid var(--line);
	border-radius: var(--radius-pill);
	background: var(--surface-raised);
	color: var(--ink-2);
	cursor: pointer;
	box-shadow: var(--shadow-1);
}
.vc-wish svg { width: 19px; height: 19px; }
.vc-wish:hover { color: var(--accent-strong); border-color: var(--accent); }
.vc-wish:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}
.vc-wish[aria-pressed="true"] { color: var(--accent); }
.vc-wish[aria-pressed="true"] svg { fill: currentColor; }

/* Disparador de vista rápida (inc/quick-view.php:
   a.vc-quick-view.vc-qv-btn[href][data-product-id] — sin JS navega a la
   ficha; con JS abre el modal). Cubre el pie de la media; oculto hasta
   hover/foco. En dispositivos sin hover queda siempre visible (si no,
   sería inalcanzable). */
.vc-qv-btn {
	position: absolute;
	inset: auto 0 0 0;
	z-index: 2;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.45rem;
	padding: 0.6rem 0.75rem;
	border: 0;
	font: inherit;
	font-size: var(--fs-xs);
	font-weight: 500;
	background: color-mix(in srgb, var(--surface-inverse) 78%, transparent);
	color: var(--surface);
	cursor: pointer;
	opacity: 0;
	transform: translateY(0.5rem);
}
/* Como <a>, el a:hover del reset (0,1,1) le ganaría al color del componente
   (0,1,0): se fija explícito para no perder contraste sobre el fondo oscuro. */
.vc-qv-btn:hover { color: var(--surface); }
.vc-qv-btn__ico { width: 16px; height: 16px; flex: none; }
.vc-qv-btn__label {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	min-width: 0;
}
.vc-card:hover .vc-qv-btn,
.vc-card:focus-within .vc-qv-btn,
.vc-qv-btn:focus-visible {
	opacity: 1;
	transform: none;
}
.vc-qv-btn:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: -2px;
}
@media (hover: none) {
	.vc-qv-btn { opacity: 1; transform: none; }
}

/* Cuerpo de la tarjeta. */
.vc-card__body {
	display: flex;
	flex-direction: column;
	flex: 1;
	gap: 0.3rem;
	padding: var(--sp-3) var(--sp-3) var(--sp-4);
}
.vc-card__cat {
	font-size: var(--fs-xs);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ink-3);
}
.vc-card__title {
	margin: 0;
	font-family: var(--font-display);
	font-size: var(--fs-body);
	font-weight: 600;
	line-height: var(--lh-snug);
}
.vc-card__title a {
	color: var(--ink);
	text-decoration: none;
}
.vc-card__title a:hover { color: var(--brand-strong); }
.vc-card__title a:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}
.vc-card__rating {
	display: flex;
	align-items: center;
	gap: 0.35rem;
}
.vc-card__rating .star-rating {
	font-size: 0.85rem;
	color: var(--accent);
}
.vc-card__rating-count {
	font-size: var(--fs-xs);
	color: var(--ink-3);
}
.vc-card__price {
	font-size: var(--fs-body);
	font-weight: 600;
	color: var(--ink);
	font-variant-numeric: lining-nums tabular-nums;
}
.vc-card__price del {
	font-size: var(--fs-sm);
	font-weight: 400;
	color: var(--ink-3);
}
.vc-card__price ins {
	text-decoration: none;
	color: var(--accent-strong);
}

/* Aviso de stock bajo (inc/product-extras.php). También aparece en la ficha
   y en el quick view (esta hoja carga en ambos contextos). */
.vc-low-stock {
	margin: 0;
	font-size: var(--fs-xs);
	font-weight: 600;
	color: var(--warn);
}

/* Pie: add-to-cart del core (hook woocommerce_after_shop_loop_item) con
   clases vc-btn (filtro woocommerce_loop_add_to_cart_args). */
.vc-card__foot { margin-top: auto; padding-top: var(--sp-2); }
.vc-card__foot .button.loading { opacity: 0.7; pointer-events: none; }
.vc-card__foot .added_to_cart {
	display: inline-flex;
	margin-top: var(--sp-2);
	font-size: var(--fs-xs);
	color: var(--brand-strong);
	text-decoration: underline;
	text-underline-offset: 3px;
}
.vc-card__foot .added_to_cart:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}

/* ============================ 9. RESULT COUNT / ORDERBY ================= */
.vc-result-count,
.woocommerce .woocommerce-result-count.vc-result-count {
	margin: 0 0 var(--sp-4);
	float: none;
	font-size: var(--fs-sm);
	color: var(--ink-3);
}

/* Fallback del select nativo (loop/orderby.php) para quien llame a
   woocommerce_catalog_ordering() por su cuenta. */
.vc-orderby,
.woocommerce .woocommerce-ordering.vc-orderby {
	margin: 0 0 var(--sp-4);
	float: none;
	display: flex;
	align-items: center;
	gap: var(--sp-2);
}
.vc-orderby__label { font-size: var(--fs-sm); color: var(--ink-3); }
.vc-orderby__select {
	min-width: 200px;
	padding: 0.55rem 0.7rem;
	font: inherit;
	font-size: var(--fs-sm);
	color: var(--ink);
	background: var(--surface);
	border: var(--border-w) solid var(--line);
	border-radius: var(--radius-md);
}
.vc-orderby__select:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}

/* ============================ 10. PAGINACIÓN ============================ */
/* loop/pagination.php: nav.vc-pagination > ul.page-numbers (paginate_links
   type=list). El core pinta la paginación como caja con borde y divisores;
   se resetea con especificidad suficiente (sin !important) y se reaplican
   píldoras. */
.vc-pagination { margin-top: var(--sp-7); }
.vc-pagination ul.page-numbers,
.woocommerce nav.vc-pagination ul.page-numbers {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0.4rem;
	list-style: none;
	margin: 0;
	padding: 0;
	border: 0;
	white-space: normal;
}
.vc-pagination ul.page-numbers li,
.woocommerce nav.vc-pagination ul.page-numbers li {
	margin: 0;
	padding: 0;
	border: 0;
	float: none;
	overflow: visible;
	display: inline-flex;
}
.vc-pagination .page-numbers,
.woocommerce nav.vc-pagination ul.page-numbers li a,
.woocommerce nav.vc-pagination ul.page-numbers li span {
	display: inline-grid;
	place-items: center;
	min-width: 44px;
	height: 44px;
	padding: 0 0.8rem;
	margin: 0;
	border: var(--border-w) solid var(--line);
	border-radius: var(--radius-pill);
	font-size: var(--fs-sm);
	line-height: 1;
	color: var(--ink);
	background: var(--surface);
	text-decoration: none;
}
.vc-pagination a.page-numbers:hover,
.woocommerce nav.vc-pagination ul.page-numbers li a:hover {
	border-color: var(--brand);
	color: var(--brand-strong);
	background: var(--brand-soft);
}
.vc-pagination a.page-numbers:focus-visible,
.woocommerce nav.vc-pagination ul.page-numbers li a:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}
.vc-pagination .page-numbers.current,
.woocommerce nav.vc-pagination ul.page-numbers li span.current {
	background: var(--brand);
	border-color: var(--brand);
	color: var(--cta-ink);
}
.vc-pagination .page-numbers.dots,
.woocommerce nav.vc-pagination ul.page-numbers li span.dots {
	border-color: transparent;
	background: transparent;
	min-width: auto;
	padding: 0 0.35rem;
	color: var(--ink-3);
}

/* ============================ 11. ESTADO VACÍO ========================== */
/* loop/no-products-found.php: .vc-empty (notice + acción). */
.vc-empty {
	text-align: center;
	padding-block: var(--sp-7);
	max-width: 46ch;
	margin-inline: auto;
}
.vc-empty .woocommerce-info { text-align: left; }
.vc-empty__action { margin-top: var(--sp-4); }

/* ============================ 12. NOTICES (contexto tienda) ============= */
/* woocommerce_output_all_notices dentro de #vc-products-grid. Anula el look
   del core (banda superior + ícono ::before) con especificidad acotada. */
.woocommerce .woocommerce-notices-wrapper .woocommerce-message,
.woocommerce .woocommerce-notices-wrapper .woocommerce-info,
.woocommerce .woocommerce-notices-wrapper .woocommerce-error,
.vc-empty .woocommerce-info {
	margin: 0 0 var(--sp-4);
	padding: var(--sp-3) var(--sp-4);
	list-style: none;
	border: var(--border-w) solid var(--line);
	border-top-width: var(--border-w);
	border-radius: var(--radius-md);
	background: var(--surface-2);
	color: var(--ink);
	font-size: var(--fs-sm);
}
.woocommerce .woocommerce-notices-wrapper .woocommerce-message::before,
.woocommerce .woocommerce-notices-wrapper .woocommerce-info::before,
.woocommerce .woocommerce-notices-wrapper .woocommerce-error::before,
.vc-empty .woocommerce-info::before {
	display: none;
}
.woocommerce .woocommerce-notices-wrapper .woocommerce-message {
	border-color: color-mix(in srgb, var(--ok) 35%, var(--line));
	background: var(--ok-soft);
}
.woocommerce .woocommerce-notices-wrapper .woocommerce-error {
	border-color: color-mix(in srgb, var(--error) 35%, var(--line));
	background: var(--error-soft);
	color: var(--error);
}
.woocommerce .woocommerce-notices-wrapper .woocommerce-message .button,
.woocommerce .woocommerce-notices-wrapper .woocommerce-info .button,
.woocommerce .woocommerce-notices-wrapper .woocommerce-error .button {
	float: right;
	margin-left: var(--sp-3);
	font-size: var(--fs-xs);
}

/* ============================ 13. BOTONES .vc-btn SOBRE WC CORE ========= */
/* FIX woo-overrides.css:8 — el core (woocommerce-general) estila
   .woocommerce a.button (0,2,1) con su gris propio. En vez de !important
   genérico, se re-aplica el contrato del design system SOLO a botones que
   llevan .vc-btn (todos los del tema), variante por variante, con
   especificidad (0,3,1)+. Un botón de plugin sin .vc-btn conserva el look
   del core a propósito. Los valores usan los MISMOS tokens que
   components.css: cero drift posible. */
.woocommerce a.button.vc-btn,
.woocommerce button.button.vc-btn,
.woocommerce input.button.vc-btn,
.woocommerce a.button.alt.vc-btn,
.woocommerce button.button.alt.vc-btn,
.woocommerce-page a.button.vc-btn,
.woocommerce-page button.button.vc-btn,
.woocommerce-page input.button.vc-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	padding: 0.8rem 1.4rem;
	font-family: var(--font-sans);
	font-size: var(--fs-sm);
	font-weight: 500;
	line-height: 1;
	text-decoration: none;
	text-shadow: none;
	box-shadow: none;
	cursor: pointer;
	background: var(--cta-bg);
	color: var(--cta-ink);
	border: var(--border-w) solid transparent;
	border-radius: var(--radius-pill);
}
.woocommerce a.button.vc-btn:hover,
.woocommerce button.button.vc-btn:hover,
.woocommerce input.button.vc-btn:hover,
.woocommerce a.button.alt.vc-btn:hover,
.woocommerce button.button.alt.vc-btn:hover,
.woocommerce-page a.button.vc-btn:hover,
.woocommerce-page button.button.vc-btn:hover,
.woocommerce-page input.button.vc-btn:hover {
	background: var(--cta-bg-hover);
	color: var(--cta-ink);
}
.woocommerce a.button.vc-btn:focus-visible,
.woocommerce button.button.vc-btn:focus-visible,
.woocommerce input.button.vc-btn:focus-visible,
.woocommerce-page a.button.vc-btn:focus-visible,
.woocommerce-page button.button.vc-btn:focus-visible,
.woocommerce-page input.button.vc-btn:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}
/* Variante fantasma. */
.woocommerce a.button.vc-btn--ghost,
.woocommerce button.button.vc-btn--ghost,
.woocommerce input.button.vc-btn--ghost,
.woocommerce-page a.button.vc-btn--ghost,
.woocommerce-page button.button.vc-btn--ghost,
.woocommerce-page input.button.vc-btn--ghost {
	background: transparent;
	color: var(--brand-strong);
	border-color: var(--brand);
}
.woocommerce a.button.vc-btn--ghost:hover,
.woocommerce button.button.vc-btn--ghost:hover,
.woocommerce input.button.vc-btn--ghost:hover,
.woocommerce-page a.button.vc-btn--ghost:hover,
.woocommerce-page button.button.vc-btn--ghost:hover,
.woocommerce-page input.button.vc-btn--ghost:hover {
	background: var(--brand);
	color: var(--cta-ink);
}
/* Tamaños / block. */
.woocommerce a.button.vc-btn--sm,
.woocommerce button.button.vc-btn--sm,
.woocommerce input.button.vc-btn--sm,
.woocommerce-page a.button.vc-btn--sm,
.woocommerce-page button.button.vc-btn--sm,
.woocommerce-page input.button.vc-btn--sm { padding: 0.6rem 1rem; font-size: var(--fs-xs); }
.woocommerce a.button.vc-btn--lg,
.woocommerce button.button.vc-btn--lg,
.woocommerce-page a.button.vc-btn--lg,
.woocommerce-page button.button.vc-btn--lg { padding: 1rem 1.8rem; font-size: var(--fs-body); min-height: 52px; }
.woocommerce a.button.vc-btn--block,
.woocommerce button.button.vc-btn--block,
.woocommerce input.button.vc-btn--block,
.woocommerce-page a.button.vc-btn--block,
.woocommerce-page button.button.vc-btn--block { display: flex; width: 100%; }
/* Estados del add-to-cart AJAX del core. */
.woocommerce a.button.vc-btn.added,
.woocommerce-page a.button.vc-btn.added { background: var(--cta-bg-hover); }
.woocommerce a.button.vc-btn.loading,
.woocommerce-page a.button.vc-btn.loading { opacity: 0.7; pointer-events: none; }

/* ============================ 14. STEPPER DE CANTIDAD =================== */
/* global/quantity-input.php: .quantity.vc-qty > [-] input.qty [+]. El
   stepper vive COMPLETO en core/components.css (única fuente: se encola
   siempre y cubre tienda + ficha + quick view + carrito; sus transiciones,
   en core/motion.css). Acá NO se repite: el bloque duplicado que había
   generaba drift real (hover --ink vs --brand-strong, focus/disabled solo
   de un lado) entre tienda/ficha y carrito. */

/* ============================ 15. VISTA RÁPIDA (modal) ================== */
/* CONTRATO JS (Task 11): el shell del modal lo monta el JS en <body>:
   .vc-qv-modal[aria-hidden] > .vc-qv-modal__overlay[data-vc-qv-close]
                             + .vc-qv-modal__dialog[role=dialog]
                               [aria-modal=true][aria-labelledby=vc-qv-title]
                               > .vc-qv-modal__close[data-vc-qv-close]
                               + .vc-qv-modal__body (recibe el fragmento
                                 article.vc-qv del endpoint vc_quick_view).
   Estados: [hidden] (display none), body.vc-qv-open (scroll lock). Foco
   atrapado con vcFocusTrap; Esc cierra. */
.vc-qv-modal {
	position: fixed;
	inset: 0;
	z-index: var(--z-modal);
	display: grid;
	place-items: center;
	padding: var(--sp-4);
}
.vc-qv-modal[hidden] { display: none; }
body.vc-qv-open { overflow: hidden; }

.vc-qv-modal__overlay {
	position: absolute;
	inset: 0;
	background: color-mix(in srgb, var(--surface-inverse) 55%, transparent);
}
.vc-qv-modal__dialog {
	position: relative;
	z-index: 1;
	width: min(880px, 100%);
	max-height: min(92dvh, 100%);
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	background: var(--surface-raised);
	border: var(--border-w) solid var(--line);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-3);
}
.vc-qv-modal__close {
	position: absolute;
	top: var(--sp-3);
	right: var(--sp-3);
	z-index: 2;
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 0;
	border-radius: var(--radius-pill);
	background: var(--surface-2);
	color: var(--ink);
	cursor: pointer;
}
.vc-qv-modal__close svg { width: 20px; height: 20px; }
.vc-qv-modal__close:hover { background: var(--line); }
.vc-qv-modal__close:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}
.vc-qv-modal__body { min-height: 200px; }

/* Contenido del fragmento (inc/quick-view.php: article.vc-qv[data-vc-qv]). */
.vc-qv {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--sp-4);
}
@media (min-width: 640px) {
	.vc-qv { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); }
}
.vc-qv__media {
	background: var(--surface-2);
	overflow: hidden;
}
.vc-qv__media img,
.vc-qv__img {
	display: block;
	width: 100%;
	height: 100%;
	aspect-ratio: var(--vc-card-aspect, 1 / 1);
	object-fit: cover;
}
.vc-qv__body {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--sp-3);
	padding: var(--sp-5) var(--sp-5) var(--sp-5) 0;
	min-width: 0;
}
@media (max-width: 639.98px) {
	.vc-qv__body { padding: 0 var(--sp-4) var(--sp-5); }
}
.vc-qv__title {
	margin: 0;
	padding-right: 44px; /* aire para el botón de cierre */
	font-family: var(--font-display);
	font-size: var(--fs-h3);
	line-height: var(--lh-tight);
	color: var(--ink);
}
.vc-qv__rating { display: flex; align-items: center; gap: 0.35rem; }
.vc-qv__rating .star-rating { font-size: 0.9rem; color: var(--accent); }
.vc-qv__rating-count { font-size: var(--fs-xs); color: var(--ink-3); }
.vc-qv__price {
	font-size: var(--fs-h3);
	font-weight: 600;
	color: var(--ink);
	font-variant-numeric: lining-nums tabular-nums;
}
.vc-qv__price del { font-size: var(--fs-sm); font-weight: 400; color: var(--ink-3); }
.vc-qv__price ins { text-decoration: none; color: var(--accent-strong); }
.vc-qv__excerpt {
	font-size: var(--fs-sm);
	color: var(--ink-2);
	line-height: var(--lh-body);
}
.vc-qv__excerpt p { margin: 0 0 var(--sp-2); }
.vc-qv__stock.out-of-stock { color: var(--error); font-weight: 500; }

/* Form de compra del modal (simple y variable). */
.vc-qv__form {
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
	gap: var(--sp-2);
	width: 100%;
}
.vc-qv__form .single_add_to_cart_button { flex: 1 1 auto; min-width: 10rem; }
.vc-qv__form.variations_form { display: block; }
.vc-qv__form .variations {
	width: 100%;
	border-collapse: collapse;
	margin: 0 0 var(--sp-3);
}
.vc-qv__form .variations th.label,
.vc-qv__form .variations td.value {
	display: block;
	padding: 0;
	border: 0;
	text-align: left;
}
.vc-qv__form .variations th.label {
	font-size: var(--fs-sm);
	font-weight: 500;
	color: var(--ink-2);
	padding-bottom: 0.3rem;
}
.vc-qv__form .variations td.value { padding-bottom: var(--sp-3); }
.vc-qv__form .variations select {
	width: 100%;
	padding: 0.55rem 0.7rem;
	font: inherit;
	font-size: var(--fs-sm);
	color: var(--ink);
	background: var(--surface);
	border: var(--border-w) solid var(--line);
	border-radius: var(--radius-md);
}
.vc-qv__form .variations select:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}
.vc-qv__form .reset_variations {
	display: inline-block;
	margin-top: 0.3rem;
	font-size: var(--fs-xs);
	color: var(--ink-3);
}
.vc-qv__form .single_variation_wrap .woocommerce-variation-price .price {
	font-size: var(--fs-h3);
	font-weight: 600;
	color: var(--ink);
}
.vc-qv__form .woocommerce-variation-add-to-cart {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-2);
	margin-top: var(--sp-3);
}
.vc-qv__form .woocommerce-variation-add-to-cart .single_add_to_cart_button { flex: 1 1 auto; }

/* Link a la ficha completa. */
.vc-qv__full {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	margin-top: auto;
	font-size: var(--fs-sm);
	font-weight: 500;
	color: var(--brand-strong);
	text-decoration: underline;
	text-underline-offset: 3px;
}
.vc-qv__full-ico { width: 16px; height: 16px; }
.vc-qv__full:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}

/* ============================ 16. MOTION ================================ */
/* Todas las transiciones de esta hoja viven acá: con reduce, nada se mueve. */
@media (prefers-reduced-motion: no-preference) {
	.vc-card { transition: border-color var(--tr) var(--ease-out), box-shadow var(--tr) var(--ease-out); }
	.vc-card__media-link img { transition: transform var(--tr-slow) var(--ease-out); }
	.vc-wish { transition: color var(--tr) var(--ease-out), border-color var(--tr) var(--ease-out); }
	.vc-qv-btn { transition: opacity var(--tr) var(--ease-out), transform var(--tr) var(--ease-out); }
	.vc-chip { transition: border-color var(--tr) var(--ease-out), color var(--tr) var(--ease-out); }
	.vc-filters__check { transition: background var(--tr) var(--ease-out); }
	.vc-shop-layout__aside.is-offcanvas { transition: transform var(--tr-slow) var(--ease-out), visibility var(--tr-slow); }
	.vc-filters-overlay { transition: opacity var(--tr) var(--ease-out), visibility var(--tr); }
	.vc-pagination .page-numbers,
	.woocommerce nav.vc-pagination ul.page-numbers li a { transition: background var(--tr) var(--ease-out), color var(--tr) var(--ease-out), border-color var(--tr) var(--ease-out); }
	/* .vc-qty__btn: transición en core/motion.css (única fuente del stepper). */
	.vc-qv-modal__dialog { animation: vc-qv-in var(--tr-slow) var(--ease-out) both; }
	.vc-qv-modal__overlay { animation: vc-fade-in var(--tr) var(--ease-out) both; }
}
@keyframes vc-qv-in {
	from { opacity: 0; transform: translateY(0.75rem) scale(0.98); }
	to { opacity: 1; transform: none; }
}
@keyframes vc-fade-in {
	from { opacity: 0; }
	to { opacity: 1; }
}
