/* =============================================================================
   COMPONENTE · Rejilla y tarjeta de producto
   =============================================================================
   Una sola pieza para TODO el sitio: portada, tienda, categoría, etiqueta,
   archivo de marca, productos relacionados y lista de deseos. La tarjeta la
   pinta `excellent_product_card()`; la rejilla, esta hoja.

   POR QUÉ TIENE ARCHIVO PROPIO (18-ago-2026)
   Este CSS vivía repartido en cuatro zonas de `main.css`, entre reglas del
   héroe, del pie y del checkout. Es el componente que más se repite del sitio y
   el que más se toca, así que tenerlo suelto significaba buscarlo cada vez y
   arriesgarse a dejar la mitad sin cambiar. Ahora se lee, se mueve y se borra
   de una pieza.

   ⚠️ SE CARGA SIEMPRE, no por pantalla. `checkout.css` y `account.css` sí son
   condicionales porque esas pantallas existen en un solo sitio; esta tarjeta
   está en casi todas. Una lista de condiciones aquí se rompería el día que se
   ponga la tarjeta en una página nueva y nadie se acuerde de añadirla.

   ⚠️ LO QUE NO ESTÁ AQUÍ, Y POR QUÉ:
   · La caja común del botón de deseos (`.wish__btn`) se queda en `main.css`:
     la comparten la ficha de producto y la ventana de vista rápida, que no son
     este componente. Aquí solo está lo que hace ese botón DENTRO de la tarjeta.
   · El posicionamiento en el carrusel (`.product-carousel__track`) es del
     carrusel, no de la tarjeta.
   · Color, tipografía y la escala `--space-*` siguen en `tokens.css`: son del
     sistema. Este archivo solo declara lo suyo.
   ============================================================================= */

/* ── La escala del COMPONENTE ────────────────────────────────────────────────
   ⚠️ Estos valores NO salen de `--space-*` a propósito, y no es un descuido.
   La escala del proyecto (8,75 · 17,5 · 26,25) está pensada para MAQUETACIÓN
   —aire entre secciones, márgenes, contenedores— y sus peldaños son demasiado
   gruesos para el interior de un componente: entre 8,75 y 17,5 no hay nada, y
   justo ahí vive la separación entre tarjetas. Con 8,75 se tocan y con 17,5 se
   sueltan.

   Así que el componente tiene su propia escala, que es práctica corriente en un
   sistema de diseño: una escala de layout y otra de componente, distintas a
   propósito. Estos tres tokens son la fuente única de la densidad de la rejilla.

   ⚠️ EL HUECO VERTICAL ES EL DOBLE QUE EL LATERAL A PROPÓSITO (15 y 30).
   Cada celda no es una foto: es foto + marca + nombre + precio, y ese texto
   pertenece a la imagen que tiene encima. Con los dos huecos iguales, el texto
   queda a la misma distancia de su propia foto que de la de abajo y el ojo
   duda. Con más aire vertical, cada tarjeta se lee como un bloque cerrado.
   La proporción 1:2 no es capricho: pasó por 25 (1:1,67) y se subió a 30 porque
   con cinco columnas las filas quedaban demasiado juntas para lo apretadas que
   van las tarjetas de lado. */
:root {
	--pg-cols: 5; /* columnas en escritorio */
	--pg-gap-x: 15px; /* entre columnas */
	--pg-gap-y: 30px; /* entre filas — el doble que el lateral, ver nota */
}

/* ── La rejilla ──────────────────────────────────────────────────────────────
   Los tres contenedores que existían por separado —la portada, el archivo de
   WooCommerce y los relacionados— pasan a ser el MISMO componente.

   Los escalones bajan de uno en uno. Antes el archivo saltaba de 4 a 2 de golpe
   y a 1100px las tarjetas se quedaban en 250px. Se cambia el TOKEN en cada
   media query, no la propiedad: así el reparto se sigue decidiendo en un solo
   sitio y cualquier regla que dependa de él se entera. */
.product-grid,
.woocommerce ul.products {
	display: grid;
	grid-template-columns: repeat(var(--pg-cols), 1fr);
	gap: var(--pg-gap-y) var(--pg-gap-x);
	margin: 0;
	padding: 0;
	list-style: none;
}

@media (max-width: 1400px) { .product-grid, .woocommerce ul.products { --pg-cols: 4; } }
@media (max-width: 1150px) { .product-grid, .woocommerce ul.products { --pg-cols: 3; } }
@media (max-width: 900px)  { .product-grid, .woocommerce ul.products { --pg-cols: 2; } }
@media (max-width: 560px)  { .product-grid, .woocommerce ul.products { --pg-cols: 2; --pg-gap-x: 10px; --pg-gap-y: 20px; } }

/* Reinicios del marcado de WooCommerce, que trae layout flotante de serie. */
.woocommerce ul.products li.product { width: auto; margin: 0; float: none; text-align: left; }
.woocommerce ul.products li.product .button { display: none; }

/* ── Variantes por instancia ─────────────────────────────────────────────────
   Redefinen los tokens; NO duplican el componente. Es el mecanismo que permite
   tener armonía sin aplanar la jerarquía: misma tarjeta, misma tipografía, mismo
   comportamiento, distinta densidad donde el propósito de la página lo pide.

   La PORTADA y los RELACIONADOS son bloques de SELECCIÓN, no catálogo: enseñan
   ocho piezas escogidas y su trabajo es seducir, no dejar recorrer. Ahí una
   columna menos significa una fotografía más grande, que es el argumento de
   venta. La categoría, en cambio, existe para recorrer: cuanto más producto por
   pantalla, mejor.

   ⚠️ Esto es lo ÚNICO que puede cambiar una instancia. Si alguien necesita algo
   más, no es una variante: es que el componente se le queda corto y hay que
   hablarlo. */
.product-grid--seleccion { --pg-cols: 4; }
@media (max-width: 1150px) { .product-grid--seleccion { --pg-cols: 3; } }
@media (max-width: 900px)  { .product-grid--seleccion { --pg-cols: 2; } }

/* ── La tarjeta ───────────────────────────────────────────────────────────── */
.product-card { position: relative; display: flex; flex-direction: column; }
.product-card__media { position: relative; aspect-ratio: var(--product-media-ratio); overflow: hidden; background: var(--c-soft); margin-bottom: var(--space-2); }
.product-card__badge { position: absolute; top: var(--space-2); left: var(--space-2); z-index: 2; background: var(--c-sale); color: var(--c-white); font-size: var(--fs-2xs); font-weight: 700; padding: .35rem .6rem; line-height: 1; }
.product-card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .4s var(--ease); }
.product-card:hover .product-card__media img { transform: scale(1.06); }

/* === Galería de la tarjeta: barras indicadoras (18-ago) ===
   Una barra por foto, repartidas a lo ancho de la fotografía. La activa dice
   cuál se está viendo.

   ⚠️ `pointer-events: none` NO ES OPCIONAL. La tarjeta se abre con un enlace
   estirado (`.product-card__link`, inset:0) y cualquier cosa por encima que
   reciba el ratón le roba el clic: la foto dejaría de abrir el producto. Las
   barras son un indicador, no un control.

   Sobre la foto se lee con blanco y una sombra, no con el truco de invertir el
   color de fondo: sobre una prenda blanca una barra invertida desaparece, y
   media tienda son camisas blancas. */
.product-card__barras {
	position: absolute; inset-inline: 0; bottom: 0; z-index: 2;
	display: flex; gap: var(--card-barra-gap);
	padding: var(--card-barra-gap);
	pointer-events: none;
}
.product-card__barra {
	flex: 1 1 auto; height: var(--card-barra-h);
	background: var(--c-white);
	opacity: var(--card-barra-op);
	box-shadow: 0 0 2px rgb(0 0 0 / .35);
	transition: opacity .2s var(--ease);
}
.product-card:hover .product-card__barra { opacity: var(--card-barra-op-hover); }
.product-card__barra.is-active,
.product-card:hover .product-card__barra.is-active { opacity: var(--card-barra-op-activa); }

/* La foto NO se agranda mientras se recorre la galería: el zoom del hover y el
   cambio de imagen a la vez se leen como un salto. Se recupera al salir. */
.product-card__media.is-viendo img { transform: none; }

@media (prefers-reduced-motion: reduce) {
	.product-card__barra { transition: none; }
}
/* Bloque de textos: separación uniforme y tokenizada entre marca/nombre/precio */
/* El interlineado se fija en el contenedor para que las tres líneas lo hereden
   igual: es lo que hace que --product-card-gap signifique lo que dice. */
.product-card__info { display: flex; flex-direction: column; gap: var(--product-card-gap); line-height: var(--product-card-lh); }
/* Jerarquía de la tarjeta: la marca sitúa, el nombre identifica, el PRECIO
   decide. Antes nombre y precio eran idénticos —17,5px y peso 700 los dos— así
   que competían y ninguno mandaba. Con 18 de 29 productos en oferta, el precio
   es lo que hay que poder barrer de un vistazo por toda la rejilla. */
/* Sin tracking: la marca es un nombre propio, no una etiqueta. Espaciada se
   leía como un rótulo y además obligaba a partir las marcas largas. */
.product-card__brand { font-family: var(--font-body); font-size: var(--product-card-brand-fs); font-weight: 500; letter-spacing: 0; color: var(--c-muted); }
/* La jerarquía frente al precio la lleva el PESO (500 contra 700), no el
   tamaño: así el nombre no tiene que encogerse para que el precio mande. */
/* El interlineado va explícito aunque el contenedor ya lo declare: el nombre es
   un <h3> y la regla base de titulares se lo pone a 1,08, que gana a la
   herencia. Con un nombre de dos líneas —los hay— esas dos líneas se tocaban. */
.product-card__name {
	font-family: var(--font-body); font-weight: 500; font-size: var(--product-card-name-fs);
	text-transform: none; letter-spacing: 0; color: var(--c-ink); margin: 0;
	line-height: var(--product-card-lh);
	/* Tope de líneas con puntos suspensivos. `-webkit-box` es el único mecanismo
	   con soporte real para recortar por líneas; pese al prefijo, lo entienden
	   todos los navegadores actuales. El nombre completo sigue disponible en el
	   `title` del elemento y en el texto para lectores de pantalla del enlace. */
	display: -webkit-box;
	-webkit-line-clamp: var(--product-card-name-lines);
	line-clamp: var(--product-card-name-lines);
	-webkit-box-orient: vertical;
	overflow: hidden;
	/* ⚠️ SIN ALTO RESERVADO (18-ago, decidido por el cliente).
	   Aquí hubo un `min-height` de dos líneas para que el precio de todas las
	   tarjetas de una fila cayera a la misma altura. El efecto secundario era
	   visible: con un nombre de UNA línea sobraban 20px dentro de su caja y el
	   precio quedaba despegado, colgando del fondo —24px de hueco contra los 4
	   de un nombre de dos líneas—.
	   Se quita: el precio va pegado al nombre, siempre.
	   A cambio, los precios de una fila YA NO SE ALINEAN entre sí cuando los
	   nombres tienen distinto número de líneas. Es la contrapartida y está
	   asumida; si algún día molesta, la solución NO es devolver este
	   `min-height` —vuelve el hueco— sino empujar el precio con `margin-top:
	   auto` desde un `.product-card__info` estirado: alinea igual y sin hueco. */
}
.product-card__price { font-family: var(--font-body); font-weight: 600; font-size: var(--product-card-price-fs); color: var(--c-ink); }
.product-card__price del { color: var(--c-muted); font-weight: 400; margin-right: var(--space-1); }
.product-card__price ins { text-decoration: none; color: var(--c-sale); }


/* Enlace estirado. La tarjeta dejó de ser un <a> porque el corazón es un botón
   y un botón dentro de un enlace es HTML inválido: el navegador no sabe si
   quieres ir al producto o guardarlo. Con este patrón sigue habiendo un único
   enlace por tarjeta, que es también lo correcto para un lector de pantalla. */
.product-card__link { position: absolute; inset: 0; z-index: 1; }
.product-card__link:focus-visible { outline: var(--focus-w) solid var(--c-gold); outline-offset: 3px; }

/* ---- Acciones rápidas de la tarjeta ----
   Tres botones apilados sobre la foto. La COLUMNA es la que se posiciona y va
   por delante del enlace estirado; si no, el clic se lo comería la tarjeta y
   ninguno de los tres llegaría a funcionar. */
.cardacc {
	position: absolute; top: var(--wish-inset); right: var(--wish-inset); z-index: 2;
	display: grid; gap: var(--cardacc-gap); justify-items: end;
	/* ⚠️ El glifo se acota AQUÍ y no en `tokens.css` a propósito. `--wish-icon`
	   es global: lo usan también el corazón de la ficha y el de la lista de
	   deseos, que viven sobre blanco, llevan rótulo al lado y no tienen por qué
	   encoger. Redefinirlo en `.cardacc` lo hereda solo esta pila de tres.
	   Se le quita la mitad que a la caja —0,5px contra 1— para que la
	   proporción entre glifo y caja se mantenga: 19,6px dentro de 38,4. */
	--wish-icon: calc(1.15rem - 0.5px);
}
.cardacc__form { margin: 0; display: contents; }
/* Antes se posicionaba solo; ahora lo hace la columna. Se deja estático para
   que no se salga de la pila. */
.wish--card { position: static; }

/* Hover: la caja se invierte a negro. Se invierte la caja y no se tiñe el
   glifo porque sobre una foto cualquiera un cambio de color de trazo puede
   perderse; un bloque negro no. Solo dentro de la tarjeta: en la ficha y en la
   lista de deseos el corazón vive sobre blanco y ahí basta su hover de siempre. */
.cardacc__btn:hover,
.cardacc .wish__btn:hover { background: var(--cardacc-hover-bg); color: var(--cardacc-hover-fg); }
/* El corazón guardado conserva su relleno también en negativo. */
.cardacc .wish__btn.is-on:hover svg { fill: var(--cardacc-hover-fg); stroke: var(--cardacc-hover-fg); }
.cardacc__btn:focus-visible { outline: var(--focus-w) solid var(--c-gold); outline-offset: 2px; }

.cardacc__btn.is-loading { opacity: var(--op-inactivo); cursor: default; }

/* Caja común de los tres botones. Se declara una sola vez: si cada uno
   trajera la suya, bastaría tocar una para que dejaran de medir igual. */
.wish__btn,
.cardacc__btn {
	display: inline-flex; align-items: center; justify-content: center; gap: .55em;
	width: var(--wish-size); height: var(--wish-size);
	padding: 0; border: 0; cursor: pointer;
	background: rgba(255, 255, 255, .9); color: var(--c-ink);
	transition: background .2s var(--ease), color .2s var(--ease);
}
/* El fondo de los tres botones DE LA TARJETA, más transparente que el 90% de la
   caja común de arriba. Se acota aquí y no se cambia allí porque esa regla la
   comparte el corazón de otras pantallas: da igual que hoy todas lo
   sobrescriban —la vista rápida y la ficha lo ponen transparente—; si mañana
   aparece un cuarto sitio, no tiene por qué heredar una decisión que se tomó
   mirando una fotografía de fondo. */
.cardacc__btn,
.cardacc .wish__btn { background: var(--cardacc-bg); }
.cardacc__btn svg { width: var(--wish-icon); height: var(--wish-icon); fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.wish__btn svg { width: var(--wish-icon); height: var(--wish-icon); fill: none; stroke: currentColor; stroke-width: 1.6; }
.wish__btn:hover { background: #fff; }
/* Guardado = corazón relleno. El cambio de contorno a macizo se lee de lejos
   sin meter un color nuevo en el sistema. */
.wish__btn.is-on svg { fill: var(--wish-on); stroke: var(--wish-on); }
.wish__btn:focus-visible { outline: var(--focus-w) solid var(--c-gold); outline-offset: 2px; }
/* Mientras viaja la petición el botón se bloquea: dos clics seguidos dejarían
   el corazón diciendo lo contrario de lo que hay guardado. */
.wish__btn[disabled] { opacity: var(--op-inactivo); cursor: default; }

/* ---- Aparecer solo al pasar el ratón ----
   ⚠️ ESTE BLOQUE VA DESPUÉS de la caja común de arriba, y no antes. Estuvo
   antes y el resultado fue un fallo difícil de ver: la caja común declara
   `transition` para `.cardacc__btn` con la MISMA especificidad, así que al ir
   después le borraba la transición de opacidad y desplazamiento. El corazón se
   salvaba —su selector `.cardacc .wish__btn` es más específico— y los otros dos
   aparecían de golpe tras su retraso. Parecía un problema de orden y era de
   cascada. Si algún día se reordena este archivo, esto vuelve a romperse.

   Bajo `(hover: hover)` a propósito: en una pantalla táctil NO hay ratón que
   pasar, así que ahí los botones se quedan siempre a la vista. Sin la consulta,
   en el móvil no habría forma de guardar ni de añadir. */
@media (hover: hover) {
	.cardacc__btn,
	.cardacc .wish__btn {
		opacity: 0;
		/* Entran deslizándose desde la derecha. Vienen del borde de la foto, que
		   es de donde el ojo espera que salga algo pegado a él. */
		transform: translateX(var(--cardacc-in));
		/* Sin esto se podría pulsar un botón invisible: siguen por delante del
		   enlace estirado aunque no se vean. */
		pointer-events: none;
		transition: opacity var(--cardacc-dur) var(--cardacc-ease),
		            transform var(--cardacc-dur) var(--cardacc-ease),
		            background .2s var(--ease), color .2s var(--ease);
		/* Sin retraso al SALIR: se van los tres juntos. Escalonar la salida hace
		   que la tarjeta parezca pegajosa al pasar el ratón por un listado, que
		   es justo lo que uno hace mirando. */
		transition-delay: 0s;
	}
	.product-card:hover .cardacc__btn,
	.product-card:hover .cardacc .wish__btn,
	/* Con el teclado no hay hover: sin esto, tabular por el listado llevaría el
	   foco a botones invisibles y no se sabría dónde se está. */
	.product-card:focus-within .cardacc__btn,
	.product-card:focus-within .cardacc .wish__btn {
		opacity: 1;
		transform: none;
		pointer-events: auto;
	}

	/* Uno detrás de otro, de arriba abajo. El retraso va SOLO en la entrada.
	   No se puede usar :nth-child: los tres cuelgan de padres distintos —el
	   carrito y el corazón viven cada uno dentro de su formulario—, así que se
	   apunta a cada uno por lo que es.

	   ⚠️ POR ESO ESTO NO SIGUE SOLO AL MARCADO. El orden lo decide
	   `excellent_card_acciones()` en el plugin, y desde el 17-ago es
	   carrito · vista rápida · corazón. Si allí se reordena, hay que reordenar
	   estos tres retrasos o los botones entrarán salteados: el de abajo primero
	   y el de arriba el último, que se lee como que algo va mal.

	   1.º carrito — dentro de `.cardacc__form`, sin retraso.
	   2.º vista rápida — hijo directo de `.cardacc`, un tiempo.
	   3.º corazón — dentro de `form.wish`, dos tiempos. */
	.product-card:hover .cardacc__form .cardacc__btn,
	.product-card:focus-within .cardacc__form .cardacc__btn { transition-delay: 0s; }
	.product-card:hover > .product-card__media > .cardacc > .cardacc__btn,
	.product-card:focus-within > .product-card__media > .cardacc > .cardacc__btn { transition-delay: var(--cardacc-stagger); }
	.product-card:hover .cardacc .wish__btn,
	.product-card:focus-within .cardacc .wish__btn { transition-delay: calc(var(--cardacc-stagger) * 2); }

	/* El corazón de un producto YA guardado no se esconde ni se desliza: si se
	   escondiera, recorrer el listado no diría qué tienes guardado y ya, que es
	   justo para lo que sirve la marca. */
	.cardacc .wish__btn.is-on {
		opacity: 1;
		transform: none;
		pointer-events: auto;
		transition-delay: 0s;
	}

/* Quien pide menos movimiento recibe el cambio, no el viaje. */
@media (prefers-reduced-motion: reduce) {
	.cardacc__btn, .cardacc .wish__btn { transition: none; transform: none; }
}
