/*
|--------------------------------------------------------------------------
| AMOREA — CARRITO
|--------------------------------------------------------------------------
| Todo lo específico de /carrito/ (woocommerce/cart/*.php,
| template-parts/cart/*.php).
*/

/*
 * El shortcode [woocommerce_cart] envuelve su salida en <div
 * class="woocommerce"> (WC_Shortcodes::shortcode_wrapper(), nativo) —
 * Blocksy fija ESE wrapper a width:1200px/max-width:1200px como ancho
 * genérico para cualquier página de shortcode de WooCommerce sin
 * layout propio. Eso pisaba nuestro .container por debajo: aunque
 * `body.woocommerce-page .container { max-width:1400px }` (layout.css)
 * sí aplica, sólo toca max-width — con el padre ya fijo en 1200px de
 * ancho real, "100%" (la fórmula fluida `--theme-container-width:
 * min(100%, 90vw)` que usa .container) nunca podía superar esos
 * 1200px. Encontrado inspeccionando computed style con CDP
 * (`CSS.getMatchedStylesForNode`), no adivinado. Se libera sólo en esta
 * página (scoped a body.woocommerce-cart, no sitewide, para no afectar
 * otras páginas que usan shortcodes de WooCommerce con su propio
 * layout, ej. Mi cuenta) — con esto el .container interno vuelve a
 * escalar igual que en Shop (~1296px a 1440px de viewport, tope real
 * 1400px recién en viewports muy anchos).
 */
body.woocommerce-cart .woocommerce {
	width: 100%;
	max-width: 1400px;
}

/*
 * Blocksy agrega data-vertical-spacing="top:bottom" al contenedor de
 * cualquier página singular (template-parts/single.php,
 * blocksy_get_v_spacing()) y le aplica
 * padding-top:var(--theme-content-vertical-spacing) — pensado para
 * separar el contenido de un hero que en esta página ya desactivamos
 * (ver blocksy:single:has-default-hero en cart-hooks.php). Sin hero
 * arriba, ese padding quedaba como un bloque vacío de ~80px entre el
 * menú y "Tu carrito de compras". Se quita sólo acá — el espacio real
 * lo sigue dando el padding propio de .amorea-cart-page más abajo.
 */
body.woocommerce-cart [data-vertical-spacing*="top"] {
	padding-top: 0;
}

/*
 * Header comercial completo del sitio oculto SOLO en /carrito/ — mismo
 * criterio ya probado en Checkout (ver checkout.css): `#header` es el
 * wrapper real de Blocksy, WooCommerce agrega `woocommerce-cart` al
 * `<body>` de forma nativa. Nunca se toca `#wpadminbar` (elemento
 * distinto) ni se oculta sitewide.
 */
body.woocommerce-cart #header {
	display: none;
}

.amorea-cart-page {
	padding: var(--space-6) 0 var(--space-8);
}

/*
 * Encabezado simplificado compartido con Checkout/Confirmación (ver
 * template-parts/cart/topbar.php) — reglas duplicadas a propósito
 * desde checkout.css: cart.css y checkout.css se encolan en páginas
 * mutuamente excluyentes (is_cart() / is_checkout()), así que no hay
 * forma de compartir un único archivo sin cargar CSS de más en alguna
 * de las dos. Cualquier cambio visual del topbar debe replicarse en
 * ambos archivos.
 */
.amorea-checkout-topbar {
	width: 100vw;
	margin-inline: calc(50% - 50vw);
	overflow-x: clip;
	background: var(--color-surface);
	border-bottom: 1px solid var(--color-border);
	padding: 4px 0;
}

.amorea-checkout-topbar__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-4);
}

.amorea-checkout-topbar__logo {
	flex: 0 0 auto;
}

.amorea-checkout-topbar__logo img {
	display: block;
	height: 80px;
	width: auto;
	object-fit: contain;
}

.amorea-checkout-topbar .cart-progress {
	margin: 0;
	flex: 1 1 auto;
	justify-content: center;
}

.amorea-checkout-back-link {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	color: var(--color-primary);
	font-weight: 600;
	font-size: var(--text-sm);
	text-decoration: none;
	white-space: nowrap;
}

.amorea-checkout-back-link:hover,
.amorea-checkout-back-link:focus {
	text-decoration: underline;
}

.cart-progress {
	display: flex;
	align-items: flex-start;
	list-style: none;
	margin: var(--space-2) 0 0;
	padding: 0;
}

.cart-progress__step {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-1);
	position: relative;
	width: 96px;
}

.cart-progress__step:not(:last-child)::after {
	content: "";
	position: absolute;
	top: 16px;
	left: calc(50% + 20px);
	width: calc(100% - 24px);
	border-top: 2px dashed var(--color-border);
}

.cart-progress__marker {
	width: 32px;
	height: 32px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--color-surface);
	border: 2px solid var(--color-border);
	color: var(--color-text-muted);
	font-weight: 700;
	font-size: var(--text-sm);
	z-index: 1;
}

.cart-progress__step--active .cart-progress__marker,
.cart-progress__step--done .cart-progress__marker {
	background: var(--color-primary);
	border-color: var(--color-primary);
	color: var(--color-surface);
}

.cart-progress__label {
	font-size: var(--text-xs);
	color: var(--color-text-muted);
	font-weight: 600;
	text-align: center;
	/* Mismo fix que checkout.css (.cart-progress* se duplica a
	   propósito entre ambos archivos, ver cabecera de checkout.css):
	   "Confirmación" no tiene dónde partir por defecto y se desbordaba
	   de su columna angosta en vez de pasar a 2 líneas. `max-width:100%`
	   es necesario además de overflow-wrap porque el padre es flex con
	   `align-items:center` (no stretch), así que sin esto el label se
	   dimensiona a su propio contenido e ignora el ancho de su columna. */
	max-width: 100%;
	overflow-wrap: break-word;
}

.cart-progress__step--active .cart-progress__label {
	color: var(--color-primary);
}

a.cart-progress__marker {
	cursor: pointer;
}

span.cart-progress__marker {
	cursor: default;
}

/* Layout de dos columnas */

.cart-layout {
	display: grid;
	grid-template-columns: 1fr 380px;
	gap: var(--space-8);
	align-items: start;
	padding-bottom: var(--space-6);
}

.cart-aside {
	position: sticky;
	top: var(--space-6);
	display: flex;
	flex-direction: column;
	gap: var(--space-6);
}

/* Tarjeta genérica reusada por Resumen y Dedicatoria */

.cart-card {
	background: var(--color-surface);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-sm);
	padding: var(--space-6);
}

.cart-card__title {
	font-family: var(--font-body);
	font-weight: 700;
	font-size: var(--text-xl);
	margin: 0 0 var(--space-4);
	display: flex;
	align-items: center;
	gap: var(--space-2);
	color: var(--color-text);
}

/*
 * "cart_totals" se agregó a woocommerce/cart/cart-totals.php SÓLO
 * como marcador para que el propio assets/js/frontend/cart.js de
 * WooCommerce (núcleo) encuentre y reemplace este bloque tras una
 * eliminación/actualización real por AJAX (ver
 * update_cart_totals_div()). Blocksy define estilos visuales reales
 * para esa misma clase (main.min.css: position:sticky, padding/
 * border propios, y ".cart_totals h2{font-size:15px}" — este último
 * le gana en especificidad a nuestro ".cart-card__title" de tipo
 * clase simple) — se neutralizan acá con un selector de 3 clases
 * (gana por especificidad sin !important) para que el resumen se vea
 * exactamente igual que antes de agregar el marcador.
 */
.cart-card.cart-summary.cart_totals {
	position: static;
	padding: var(--space-6);
	border: none;
}

.cart-card.cart-summary.cart_totals .cart-card__title {
	font-size: var(--text-xl);
}

.cart-card__title svg {
	color: var(--color-primary);
}

.cart-card__subtitle {
	color: var(--color-text-muted);
	font-size: var(--text-sm);
	margin: 0 0 var(--space-4);
}

/*
|--------------------------------------------------------------------------
| Tabla de productos
|--------------------------------------------------------------------------
*/

.cart-main {
	/*
	 * min-width:0 es necesario para que la columna 1fr de .cart-layout
	 * pueda encoger por debajo del ancho mínimo de su contenido — sin
	 * esto, un hijo no negociable (ej. las 5 tarjetas de "¿Olvidaste
	 * algo?" en fila) "revienta" el grid y empuja el aside fuera del
	 * viewport (bug clásico de CSS Grid: los grid items tienen
	 * min-width:auto por defecto). Encontrado con getBoundingClientRect
	 * en Playwright: el aside medía right=1648px en un viewport de
	 * 1440px.
	 */
	min-width: 0;
	background: var(--color-surface);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-sm);
	padding: var(--space-6);
}

.cart-table {
	width: 100%;
	border-collapse: collapse;
}

.cart-table thead th {
	text-align: left;
	font-size: var(--text-sm);
	color: var(--color-text-muted);
	font-weight: 600;
	padding: 0 var(--space-2) var(--space-3);
	border-bottom: 1px solid var(--color-border);
}

.cart-table__price,
.cart-table__qty,
.cart-table__subtotal {
	text-align: center;
}

.cart-table__actions {
	text-align: right;
}

.cart-table tbody tr {
	border-bottom: 1px solid var(--color-border);
}

.cart-table tbody tr:last-child {
	border-bottom: none;
}

.cart-table td {
	padding: var(--space-6) var(--space-3);
	vertical-align: middle;
	/* BUG REAL encontrado 2026-10-03 (pedido explícito de la usuaria):
	   Blocksy pinta su propio separador por defecto en CUALQUIER <td>
	   del sitio (1px dashed #E8E1DC — mismo color ya documentado como
	   "separador propio de Blocksy" más arriba en este archivo, para
	   el encabezado). En modo apilado eso se nota mucho porque cada
	   producto ya tiene su propia línea SÓLIDA real (`.cart-table
	   tbody tr{border-bottom:1px solid}`, en el <tr>, no en el <td> —
	   se anula acá sin afectar esa línea). Queda sólo la línea sólida
	   divisoria entre productos completos, ninguna entrecortada entre
	   sus sub-filas. */
	border-bottom: none;
}

.cart-item-product {
	display: flex;
	gap: var(--space-5);
	align-items: center;
	min-width: 240px;
}

/*
 * Contenedor cuadrado fijo para la miniatura — no el <img> el que
 * decide el tamaño. Antes sólo el <img> tenía width/height:108px y el
 * contenedor no tenía tamaño propio; en una fila flex sin
 * `flex-shrink:0` eso alcanza a comprimirse por debajo de 108px en
 * viewports angostos (~900px/390px, confirmado con getBoundingClientRect()
 * real: Tarjeta/Bolsa/Caja medían menos de 108px de ancho pero 108px de
 * alto, deformando el cuadrado) porque el `max-width:100%` heredado del
 * tema en cualquier <img> queda relativo al contenedor ya encogido. Fijar
 * el tamaño acá, en el contenedor, con `flex: 0 0 80px` (nunca se encoge
 * ni crece) elimina la causa de raíz sin depender de que el <img> "gane"
 * la pulseada de especificidad en cada breakpoint.
 */
.cart-item-product__media,
.cart-item-product__media > a {
	display: block;
	flex: 0 0 80px;
	width: 80px;
	min-width: 80px;
	height: 80px;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	border-radius: var(--radius-md);
}

.cart-item-product__media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	border-radius: var(--radius-md);
}

.cart-item-product__body {
	min-width: 0;
}

.cart-item-product__name {
	font-weight: 600;
	margin: 0 0 4px;
	font-size: var(--text-base);
}

.cart-item-product__name a {
	color: var(--color-text);
}

.cart-item-product__gift-badge {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	margin: 2px 0 4px;
	padding: 2px 8px;
	border-radius: var(--radius-pill);
	background: var(--color-accent);
	color: var(--color-primary);
	font-size: var(--text-xs);
	font-weight: 600;
}

.cart-item-product__attributes {
	color: var(--color-text-muted);
	font-size: var(--text-xs);
	margin: 0;
}

.cart-item-product__meta {
	color: var(--color-text-muted);
	font-size: var(--text-xs);
}

.cart-item-product__meta .variation {
	display: flex;
	flex-wrap: wrap;
	gap: 2px var(--space-2);
	margin: 0;
}

.cart-item-product__meta .variation th,
.cart-item-product__meta .variation td,
.cart-item-product__meta .variation p {
	display: inline;
	margin: 0;
	font-weight: 400;
	padding: 0;
}

.cart-item-product__stock {
	font-size: var(--text-xs);
	margin: var(--space-1) 0 0;
}

.cart-item-product__stock :is(.stock) {
	display: flex;
	align-items: center;
	gap: 4px;
	font-size: var(--text-xs);
	margin: 0;
}

.cart-item-product__stock--in :is(.stock) {
	color: var(--color-success);
}

.cart-item-product__stock--in :is(.stock)::before {
	content: "";
	flex: 0 0 auto;
	width: 12px;
	height: 12px;
	background: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / contain no-repeat;
}

.cart-item-product__stock--out :is(.stock) {
	color: var(--color-error);
}

/*
|--------------------------------------------------------------------------
| Fila "sólo referencia" (agotada, ver amorea_cart_item_is_reference_only()
| en inc/woocommerce/out-of-stock-cart-hooks.php) — foto conservada
| (nunca se quita ni se reemplaza), datos en gris, controles apagados.
| La ÚNICA acción real que sigue viva acá es "Eliminar"
| (`.cart-item-actions__remove`) — nunca se toca su estilo.
|--------------------------------------------------------------------------
*/

.amorea-cart-item--unavailable .cart-item-product__media {
	filter: grayscale(1);
	opacity: 0.55;
}

.amorea-cart-item--unavailable .cart-item-product__name,
.amorea-cart-item--unavailable .cart-item-product__attributes,
.amorea-cart-item--unavailable .cart-item-product__meta,
.amorea-cart-item--unavailable .cart-table__price,
.amorea-cart-item--unavailable .cart-table__subtotal {
	color: var(--color-text-muted);
}

/*
 * Tachado del NOMBRE — sólo el nombre, sólo dentro del carrito y los
 * mini-carritos (nunca en la ficha individual del producto, que no usa
 * esta clase). Pedido explícito del cliente para diferenciar de un
 * simple atenuado de color.
 */
.amorea-cart-item--unavailable .cart-item-product__name {
	text-decoration: line-through;
}

.amorea-cart-item--unavailable .cart-item-qty {
	opacity: 0.5;
}

.amorea-cart-item--unavailable .cart-item-qty__btn {
	cursor: not-allowed;
}

.amorea-cart-item--unavailable .cart-item-qty__btn:disabled {
	pointer-events: none;
}

/* Minicarrito (widget nativo — Blocksy pinta `.woocommerce-mini-cart-item`,
 * este archivo agrega `.amorea-cart-item--unavailable` vía
 * `woocommerce_mini_cart_item_class`). Miniatura/enlace conservados en
 * el DOM (el href queda vacío desde PHP) — acá sólo se despinta y se
 * bloquea el puntero; el teclado lo cubre la red de seguridad en
 * assets/js/cart.js (initUnavailableItemsGuard()). */
.woocommerce-mini-cart-item.amorea-cart-item--unavailable img {
	filter: grayscale(1);
	opacity: 0.55;
}

.woocommerce-mini-cart-item.amorea-cart-item--unavailable .product-title,
.woocommerce-mini-cart-item.amorea-cart-item--unavailable .quantity {
	color: var(--color-text-muted);
}

.woocommerce-mini-cart-item.amorea-cart-item--unavailable .product-title {
	text-decoration: line-through;
}

.woocommerce-mini-cart-item.amorea-cart-item--unavailable a:not(.remove):not(.remove_from_cart_button) {
	pointer-events: none;
	cursor: default;
}

/*
 * Mini-carrito propio de la ficha individual (template-parts/single-product/mini-cart-panel.php,
 * inc/woocommerce/single-product-hooks.php) — markup y clases distintas
 * al widget nativo de arriba, mismo criterio visual.
 */
.amorea-mini-cart-item.amorea-cart-item--unavailable .amorea-mini-cart-item__media {
	filter: grayscale(1);
	opacity: 0.55;
}

.amorea-mini-cart-item.amorea-cart-item--unavailable .amorea-mini-cart-item__name,
.amorea-mini-cart-item.amorea-cart-item--unavailable .amorea-mini-cart-item__price,
.amorea-mini-cart-item.amorea-cart-item--unavailable .amorea-mini-cart-item__measure {
	color: var(--color-text-muted);
}

.amorea-mini-cart-item.amorea-cart-item--unavailable .amorea-mini-cart-item__name {
	text-decoration: line-through;
}

.amorea-mini-cart-item.amorea-cart-item--unavailable .quantity,
.amorea-mini-cart-item.amorea-cart-item--unavailable .amorea-mini-cart-item__controls .quantity {
	opacity: 0.5;
}

.amorea-mini-cart-item.amorea-cart-item--unavailable .amorea-qty-decrease,
.amorea-mini-cart-item.amorea-cart-item--unavailable .amorea-qty-increase {
	cursor: not-allowed;
}

.amorea-mini-cart-item.amorea-cart-item--unavailable .amorea-qty-decrease:disabled,
.amorea-mini-cart-item.amorea-cart-item--unavailable .amorea-qty-increase:disabled,
.amorea-mini-cart-item.amorea-cart-item--unavailable [data-mini-cart-qty-input]:disabled {
	pointer-events: none;
}

/*
 * "Continuar con el envío" desactivado — carrito sin ningún producto
 * comprable (ver amorea_cart_has_purchasable_item()). Mismo estándar
 * visual "desactivado" que el resto del sitio (opacidad reducida +
 * `cursor:not-allowed`), nunca oculto — sigue anunciándose a lectores
 * de pantalla (`aria-disabled="true"`, ver
 * woocommerce/cart/proceed-to-checkout-button.php).
 */
.cart-summary__checkout.is-disabled {
	opacity: 0.5;
	cursor: not-allowed;
	pointer-events: none;
}

.cart-table__price {
	font-weight: 600;
	font-size: var(--text-base);
	white-space: nowrap;
}

.cart-table__subtotal {
	font-weight: 700;
	font-size: var(--text-base);
	color: var(--color-text);
	white-space: nowrap;
}

/* Cantidad con botones +/- alrededor del input nativo */

.cart-item-qty {
	display: flex;
	align-items: center;
	justify-content: center;
	width: fit-content;
	margin: 0 auto;
	border: 1px solid var(--color-border);
	border-radius: var(--radius-md);
	overflow: hidden;
}

.cart-item-qty .quantity {
	display: contents;
}

/*
 * Blocksy inyecta su propio stepper +/- (.ct-increase/.ct-decrease)
 * dentro de cualquier input.qty nativo — con display:contents en
 * .quantity pierden su referencia de posicionamiento absoluto y quedan
 * flotando fuera de la fila. Ya tenemos nuestros propios botones
 * (.cart-item-qty__btn), así que se ocultan sólo en este contexto (no
 * sitewide, para no tocar otras páginas que sí quieran el stepper
 * nativo de Blocksy).
 */
.cart-item-qty .ct-increase,
.cart-item-qty .ct-decrease {
	display: none !important;
}

.cart-item-qty__btn {
	width: 32px;
	height: 32px;
	border: none;
	background: var(--color-surface);
	color: var(--color-text);
	font-size: var(--text-lg);
	line-height: 1;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
}

.cart-item-qty__btn:hover {
	background: var(--color-accent);
	color: var(--color-primary);
}

/*
 * Blocksy reserva un padding-inline enorme dentro de cualquier
 * input[type=number] (calc(var(--quantity-height,55px)/1.8 + 9%) EN
 * CADA LADO — pensado para alojar sus propios .ct-increase/.ct-decrease
 * absolutamente posicionados encima del input). Como esos botones se
 * ocultan arriba y se reemplazan por los nuestros AL LADO del input (no
 * encima), ese padding sin resetear dejaba el número comprimido a un
 * área de ~0px de ancho — visualmente en blanco aunque el value, color
 * y opacity del input fueran correctos (comprobado con getComputedStyle
 * antes de este fix: el bug era espacio disponible para el glifo, no
 * color/visibilidad). Se resetea con !important porque la regla de
 * Blocksy compite con la misma especificidad (elemento+atributo vs.
 * dos clases) y a veces carga después en el orden real de impresión.
 */
.cart-item-qty input.qty {
	box-sizing: border-box;
	width: 56px;
	min-width: 56px;
	height: 32px;
	padding: 0 4px !important;
	text-align: center;
	line-height: 32px;
	border: none;
	border-left: 1px solid var(--color-border);
	border-right: 1px solid var(--color-border);
	border-radius: 0 !important;
	font-size: var(--text-sm);
	background: var(--color-surface) !important;
	color: var(--color-text) !important;
	opacity: 1 !important;
	-webkit-text-fill-color: var(--color-text) !important;
	-moz-appearance: textfield;
}

.cart-item-qty input.qty::-webkit-inner-spin-button,
.cart-item-qty input.qty::-webkit-outer-spin-button {
	-webkit-appearance: none;
	margin: 0;
}

/* Acciones por fila: favorito + eliminar — más visibles, con fondo y
   borde propios en vez de depender sólo del color del ícono. */

.cart-item-actions {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	height: 100%;
}

.cart-item-actions .product-card-toolbar__wishlist {
	width: 36px;
	height: 36px;
	border: 1px solid var(--color-border);
}

.cart-item-actions__remove {
	width: 36px;
	height: 36px;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--color-text-muted);
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: 50%;
	box-shadow: var(--shadow-sm);
	transition: color var(--transition-fast), background var(--transition-fast), border-color var(--transition-fast);
}

.cart-item-actions__remove:hover {
	color: var(--color-error);
	background: var(--color-accent);
	border-color: var(--color-error);
}

/* Botón nativo "Update cart": oculto visualmente, operativo para
   accesibilidad/teclado y como fallback sin JavaScript (ver
   docs del carrito) — reusa .screen-reader-text de wishlist.css. */

.cart-native-actions {
	margin: 0;
}

/* Fila de acciones bajo la tabla */

.cart-actions-row {
	display: flex;
	justify-content: space-between;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--space-3);
	margin-top: var(--space-5);
}

.cart-actions-row__empty-form {
	margin: 0;
}

.cart-actions-row__empty {
	color: var(--color-error);
	border-color: var(--color-error);
}

.cart-actions-row__empty:hover {
	background: var(--color-error);
	color: var(--color-surface);
}

/*
|--------------------------------------------------------------------------
| Modal "¿Vaciar todo el carrito?" — reemplaza window.confirm() (ver
| woocommerce/cart/cart.php, <dialog id="amorea-empty-cart-dialog">, y
| assets/js/cart.js, initEmptyCartConfirm()).
|
| BUG REAL (esquina superior izquierda) medido con `getComputedStyle()`,
| no adivinado: `<dialog>[open]` centra solo vía la hoja nativa del
| navegador (`position:fixed` + `margin:auto`) — pero `reset.css` tiene
| `*{margin:0}` (sitewide, a propósito, para no heredar márgenes nativos
| de párrafos/listas/etc.) y una regla de autor SIEMPRE le gana a la hoja
| nativa del navegador sin importar especificidad. Con `margin:auto`
| anulado a `0`, el `<dialog>` caía en `top:0;left:0` (confirmado:
| `getComputedStyle().margin` daba "0px" con el modal abierto). Nunca se
| toca `reset.css` (sitewide, fuera de este alcance) — se centra acá con
| `top:50%;left:50%;transform:translate(-50%,-50%)`, técnica que no
| depende de `margin:auto` en absoluto: funciona igual en escritorio
| completo, media pantalla, tablet y móvil porque es relativa al
| viewport (`position:fixed`), nunca al ancho/posición de `.cart-main`/
| `.container` del carrito.
|--------------------------------------------------------------------------
*/

.amorea-modal {
	position: fixed;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: min(360px, calc(100vw - var(--space-8, 32px)));
	max-height: calc(100vh - var(--space-8, 32px));
	overflow-y: auto;
	padding: var(--space-6);
	border: 1px solid var(--color-accent);
	border-radius: var(--radius-lg, 16px);
	box-shadow: var(--shadow-md);
	background: var(--color-surface);
	color: var(--color-text);
	text-align: center;
}

/*
 * BUG REAL (borde azul en "Cancelar"): confirmado con
 * `getComputedStyle().appearance` → "auto" — ningún `.btn` del sitio
 * resetea `-webkit-appearance` (grep sin resultados en buttons.css),
 * así que Safari sigue dibujando el widget NATIVO de <button> por
 * debajo, con su propio halo azul de foco — una capa completamente
 * aparte del `outline` CSS (por eso `:focus-visible{outline:3px solid
 * var(--color-accent)}`, ya sitewide en reset.css, nunca lo tapaba: el
 * halo nativo se pinta encima). Nunca antes se había notado porque
 * ningún otro botón del sitio recibe foco automático al cargar — este
 * modal es el primero que hace `.focus()` apenas se abre. Alcance
 * intencionalmente acotado a los botones DE ESTE modal (no se toca
 * `.btn` global, fuera de lo pedido en esta ronda).
 */
.amorea-modal .btn {
	-webkit-appearance: none;
	appearance: none;
}

/*
 * BUG REAL reportado con 2 capturas reales del cliente: un `outline`
 * separado (cualquier color/offset) dibuja un SEGUNDO anillo además
 * del `border` de 1px que "Cancelar" (`.btn--secondary`) ya tiene —
 * se ve como "dos bordes" sin importar qué tan parecidos sean los
 * tonos. Se quita el `outline` por completo acá (`outline:none`,
 * nunca queda sin foco visible: ver abajo) y en su lugar el foco
 * ENGROSA el ÚNICO borde real que el botón ya tiene — un solo trazo,
 * más grueso, mismo rosa Amorea, sin sombra ni segundo elemento.
 * `outline-offset` no aplica a nada si no hay `outline`, se quita.
 */
.amorea-modal .btn {
	outline: none;
}

.amorea-modal .btn--secondary:focus {
	border-width: 2px;
	border-color: var(--color-primary);
}

/*
 * "Vaciar carrito" (`.btn--primary`) no tiene borde propio (fondo
 * sólido, sin `border`) — acá SÍ hace falta un anillo real para que
 * el foco se vea (nunca hay un borde que engrosar). Sin offset (pegado
 * al propio botón, nunca un segundo anillo separado) y con el mismo
 * rosa Amorea de siempre.
 */
.amorea-modal .btn--primary:focus {
	outline: 2px solid var(--color-primary);
	outline-offset: 0;
}

/* Telón oscurecido detrás — `<dialog>` sólo lo pinta cuando está
 * abierto vía showModal(), nunca en el `display:none` inicial. */
.amorea-modal::backdrop {
	background: rgba(29, 19, 23, 0.45);
}

.amorea-modal__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	margin: 0 auto var(--space-4);
	border-radius: 50%;
	background: var(--color-accent);
	color: var(--color-primary);
}

.amorea-modal__title {
	margin: 0 0 var(--space-2);
	font-family: var(--font-body);
	font-size: var(--text-lg);
	font-weight: 700;
	color: var(--color-text);
}

.amorea-modal__desc {
	margin: 0 0 var(--space-5);
	color: var(--color-text-muted);
	font-size: var(--text-sm);
}

.amorea-modal__actions {
	display: flex;
	gap: var(--space-3);
}

.amorea-modal__actions .btn {
	flex: 1 1 0;
	padding-inline: var(--space-4);
}

/*
|--------------------------------------------------------------------------
| Resumen del pedido
|--------------------------------------------------------------------------
*/

/*
 * Filas flexibles, no <table> — la referencia visual usa separadores
 * horizontales muy suaves entre filas, sin cuadrícula/bordes
 * verticales de tabla HTML.
 */
.cart-summary__rows {
	display: flex;
	flex-direction: column;
	margin-bottom: var(--space-2);
}

.cart-summary__row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-3);
	padding: var(--space-3) 0;
	border-bottom: 1px solid rgba(45, 37, 48, 0.06);
}

.cart-summary__label {
	display: flex;
	align-items: center;
	gap: var(--space-1);
	font-weight: 500;
	color: var(--color-text-muted);
	font-size: var(--text-sm);
}

.cart-summary__value {
	font-weight: 600;
	font-size: var(--text-sm);
	color: var(--color-text);
	text-align: right;
}

.cart-summary__shipping-note {
	color: var(--color-text-muted);
	font-weight: 400;
	font-size: var(--text-xs);
}

.cart-summary__discount {
	color: var(--color-success);
}

/*
 * Aviso de envío gratis por monto mínimo (cart-totals.php). Mismos tokens
 * de marca que el resto del resumen; verde de éxito sólo cuando ya llegó
 * al monto (mismo criterio "verde = confirmación" del panel).
 */
.cart-free-shipping {
	display: flex;
	align-items: flex-start;
	gap: var(--space-2);
	margin: var(--space-3) 0 var(--space-1);
	padding: var(--space-3);
	border-radius: var(--radius-md);
	background: rgba(203, 37, 90, 0.06);
	color: var(--color-primary);
}

.cart-free-shipping.is-reached {
	background: rgba(47, 125, 90, 0.08);
	color: var(--color-success);
}

.cart-free-shipping__icon {
	flex: 0 0 auto;
	width: 18px;
	height: 18px;
	margin-top: 1px;
}

.cart-free-shipping__text {
	margin: 0;
	font-size: var(--text-sm);
	line-height: 1.4;
}

.cart-free-shipping__text strong {
	font-weight: 600;
}

.cart-free-shipping__text .woocommerce-Price-amount {
	font-weight: 700;
}

.cart-free-shipping__scope {
	display: block;
	font-size: var(--text-xs);
	color: var(--color-text-muted);
}

.cart-summary__row--total {
	border-bottom: none;
	padding-top: var(--space-4);
}

.cart-summary__row--total .cart-summary__label {
	font-size: var(--text-lg);
	font-weight: 700;
	color: var(--color-text);
}

.cart-summary__total {
	font-size: var(--text-2xl) !important;
	font-weight: 800 !important;
	color: var(--color-primary) !important;
}

.cart-summary__coupons {
	list-style: none;
	margin: 0 0 var(--space-3);
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
}

.cart-summary__coupon {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: var(--space-2);
	background: var(--color-accent);
	border-radius: var(--radius-md);
	padding: var(--space-2) var(--space-3);
	font-size: var(--text-xs);
}

.cart-summary__coupon-code {
	font-weight: 600;
	text-transform: uppercase;
}

/* Acordeón de cupón */

.cart-coupon-accordion {
	border-top: 1px solid var(--color-border);
	border-bottom: 1px solid var(--color-border);
	margin: var(--space-4) 0;
	padding: var(--space-3) 0;
}

.cart-coupon-accordion__summary {
	cursor: pointer;
	font-weight: 600;
	font-size: var(--text-sm);
	list-style: none;
	display: flex;
	align-items: center;
	justify-content: space-between;
	color: var(--color-text);
}

.cart-coupon-accordion__summary::-webkit-details-marker {
	display: none;
}

.cart-coupon-accordion__summary::after {
	content: "+";
	font-size: var(--text-lg);
	color: var(--color-primary);
}

.cart-coupon-accordion[open] .cart-coupon-accordion__summary::after {
	content: "\2212";
}

.cart-coupon-accordion__form {
	display: flex;
	gap: var(--space-2);
	margin-top: var(--space-3);
	flex-wrap: wrap;
}

.cart-coupon-accordion__form .input-text {
	flex: 1 1 140px;
	padding: var(--space-2) var(--space-3);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-md);
	font-size: var(--text-sm);
}

/* Beneficios */

.cart-benefits {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	margin: 0 0 var(--space-4);
}

.cart-benefits__item {
	display: flex;
	gap: var(--space-3);
	align-items: flex-start;
}

.cart-benefits__item img {
	flex: 0 0 auto;
	margin-top: 2px;
}

.cart-benefits__title {
	font-weight: 600;
	font-size: var(--text-sm);
	margin: 0;
	color: var(--color-text);
}

.cart-benefits__text {
	color: var(--color-text-muted);
	font-size: var(--text-xs);
	margin: 2px 0 0;
}

.cart-summary__checkout {
	width: 100%;
}

.cart-payment-methods {
	margin-top: var(--space-4);
	text-align: center;
}

.cart-payment-methods__label {
	font-size: var(--text-xs);
	color: var(--color-text-muted);
	margin: 0 0 var(--space-2);
}

.cart-payment-methods__icons {
	display: flex;
	gap: var(--space-2);
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
}

.cart-payment-methods__icons img {
	height: 24px;
	width: auto;
}

/*
 * Etiqueta "vista previa" — visible ÚNICAMENTE para administradores
 * (current_user_can('manage_woocommerce') en cart-totals.php), nunca
 * para quien compra. Ver Amorea_Core_Payment_Badges en amorea-core.
 */
.cart-payment-methods__preview-tag {
	display: inline-block;
	margin-inline-start: 4px;
	padding: 1px 6px;
	border-radius: var(--radius-pill);
	background: var(--color-accent);
	color: var(--color-primary);
	font-size: 10px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	cursor: help;
}

/*
 * Badges SVG de medios de pago en modo vista previa — wordmarks
 * tipográficos con el color de referencia de cada marca (no son artes
 * de marca oficiales, ver amorea_cart_render_payment_badge_svg() en
 * inc/woocommerce/cart-hooks.php). Altura uniforme vía CSS, ancho
 * proporcional al viewBox de cada SVG — nunca deformados.
 */
.cart-payment-badge-svg {
	height: 30px;
	width: auto;
	border-radius: var(--radius-sm);
	box-shadow: var(--shadow-sm);
}

.cart-payment-badge--fallback {
	display: inline-flex;
	align-items: center;
	height: 30px;
	padding: 0 var(--space-2);
	border-radius: var(--radius-sm);
	background: var(--color-text-muted);
	color: #fff;
	font-size: 11px;
	font-weight: 700;
}

/*
|--------------------------------------------------------------------------
| Dedicatoria
|--------------------------------------------------------------------------
*/

.cart-dedication__textarea {
	width: 100%;
	min-height: 96px;
	padding: var(--space-3);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-md);
	font-family: var(--font-body);
	font-size: var(--text-sm);
	resize: vertical;
	background: var(--color-canvas);
}

/*
 * Blocksy define un foco azul genérico para cualquier textarea/input de
 * texto (main.min.css: "textarea:focus { outline-color: var(--theme-form-field-border-focus-color); border-color: ...; }",
 * que en este sitio resuelve a rgb(40,114,250)) — confirmado con
 * getComputedStyle() real, no una suposición. Un selector por ID le
 * gana en especificidad sin depender del orden de encolado ni de
 * !important. El foco se mantiene bien visible (nunca outline:none)
 * — sólo se reemplaza el color por el rosado de Amorea, con un
 * resplandor suave adicional para más contraste.
 */
#amorea-dedication-text:focus,
#amorea-dedication-text:focus-visible {
	outline: 2px solid var(--color-primary);
	outline-offset: 2px;
	border-color: var(--color-primary);
	box-shadow: 0 0 0 4px rgba(203, 37, 90, 0.18);
}

.cart-dedication__counter {
	text-align: right;
	font-size: var(--text-xs);
	color: var(--color-text-muted);
	margin: var(--space-1) 0 var(--space-4);
}

.cart-dedication__status {
	min-height: 1em;
	font-size: var(--text-xs);
	color: var(--color-success);
	margin: var(--space-2) 0 0;
}

/*
|--------------------------------------------------------------------------
| "¿Olvidaste algo? Completa tu regalo"
|--------------------------------------------------------------------------
*/

.cart-forgot {
	/* Fondo mucho más claro que --color-accent (#f6d3de) — la
	   referencia usa un rosado muy sutil, casi blanco. */
	background: #fdeef4;
	border-radius: var(--radius-lg);
	padding: var(--space-6);
	margin-top: var(--space-8);
}

.cart-forgot__header {
	text-align: center;
	margin-bottom: var(--space-5);
}

.cart-forgot__title {
	font-family: var(--font-body);
	font-weight: 700;
	font-size: var(--text-xl);
	color: var(--color-primary);
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	margin: 0 0 var(--space-1);
}

.cart-forgot__subtitle {
	color: var(--color-text-muted);
	font-size: var(--text-sm);
	margin: 0;
}

/*
 * Carrusel horizontal REAL (no una grilla que "hace como que" es
 * carrusel) — ya no tiene tope de 5 productos totales, sólo ~5
 * visibles a la vez en escritorio; el resto se descubre deslizando
 * (ver amorea_cart_get_forgot_something_items() en cart-hooks.php y
 * initForgotCarousel() en assets/js/cart.js). scroll-snap-type vive en
 * el track para que tanto el arrastre con mouse/JS como el gesto
 * táctil nativo del navegador terminen encajados en una tarjeta.
 */
.cart-forgot__carousel-wrap {
	position: relative;
}

.cart-forgot__arrow {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	width: 36px;
	height: 36px;
	border-radius: 50%;
	background: var(--color-surface);
	box-shadow: var(--shadow-md, var(--shadow-sm));
	border: none;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--color-primary);
	cursor: pointer;
	z-index: 2;
	transition: background var(--transition-fast), opacity var(--transition-fast);
}

.cart-forgot__arrow--prev {
	left: -4px;
}

.cart-forgot__arrow--next {
	right: -4px;
}

.cart-forgot__arrow:hover {
	background: var(--color-primary);
	color: var(--color-surface);
}

.cart-forgot__arrow:focus-visible {
	outline: 2px solid var(--color-primary);
	outline-offset: 2px;
}

/* JS marca [hidden] cuando no hay más contenido hacia ese lado — nunca
   cubre texto/precio/botón porque las tarjetas tienen padding lateral
   propio (ver .cart-forgot__carousel) que deja aire para las flechas. */
.cart-forgot__arrow[hidden] {
	display: none;
}

.cart-forgot__carousel {
	overflow-x: auto;
	overflow-y: hidden;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;
	cursor: grab;
	margin: 0 var(--space-5);
	/* Evita que arrastrar con el mouse también seleccione texto de las
	   tarjetas de paso (nombre, precio) mientras se desplaza. */
	user-select: none;
}

.cart-forgot__carousel.is-dragging {
	cursor: grabbing;
	scroll-snap-type: none;
	scroll-behavior: auto;
}

.cart-forgot__carousel::-webkit-scrollbar {
	display: none;
}

.cart-forgot__carousel .products {
	display: flex;
	gap: var(--space-4);
	list-style: none;
	margin: 0;
	padding: 0;
}

/*
 * Estándar único de tarjeta reutilizado por los dos tipos de sugerencia
 * (Bolsa/Caja armadas a mano y Tarjeta/cross-sells/Complementos
 * reales) — mismo esqueleto flex vertical para que imagen, corazón,
 * nombre, medida, precio y botón queden en la MISMA posición en todas,
 * sin excepciones por producto (ver woocommerce/cart/cross-sells.php).
 */
.cart-forgot-card {
	flex: 0 0 calc((100% - 4 * var(--space-4)) / 5);
	scroll-snap-align: start;
	display: flex;
	flex-direction: column;
	background: var(--color-surface);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-sm);
	overflow: hidden;
	padding: 0 0 var(--space-3);
	min-width: 0;
}

/* 1. Contenedor de imagen — idéntico con foto real o placeholder. */
.cart-forgot-card__media {
	position: relative;
	width: 100%;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	border-radius: var(--radius-lg) var(--radius-lg) 0 0;
	margin: 0 0 var(--space-2);
	background: var(--color-bg-subtle, #f7f2f2);
}

.cart-forgot-card__media a {
	display: block;
	width: 100%;
	height: 100%;
}

.cart-forgot-card__media img {
	width: 100%;
	height: 100%;
	max-width: none;
	object-fit: cover;
	display: block;
	/* Sin esto, empezar el arrastre con el mouse ENCIMA de la imagen
	   dispara el "drag nativo de imagen" del navegador (guardar/
	   arrastrar la foto) en vez de nuestro scroll-con-mouse propio —
	   ver initForgotCarousel() en assets/js/cart.js. */
	-webkit-user-drag: none;
	user-drag: none;
}

/* 2. Corazón de favoritos — SIEMPRE dentro del contenedor de imagen,
   arriba a la derecha, sin ocupar espacio del contenido inferior. Es
   el mismo backend real de Favoritos (amorea_wishlist_button_html())
   en toda la tienda, sólo reposicionado acá con position:absolute. */
.cart-forgot-card__media .product-card-toolbar__wishlist {
	position: absolute;
	top: 8px;
	right: 8px;
	z-index: 1;
	background: var(--color-surface);
	box-shadow: var(--shadow-sm);
}

/* 3. Nombre — dos líneas siempre reservadas, para que el resto de la
   tarjeta (medida/precio/botón) empiece a la misma altura sin importar
   si el nombre real ocupa una línea o dos. */
.cart-forgot-card__title {
	font-family: var(--font-body);
	font-size: var(--text-sm);
	font-weight: 600;
	line-height: 1.3;
	margin: 0 var(--space-3);
	min-height: calc(1.3em * 2);
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	color: var(--color-text);
}

/* 4. Medida en cm — una línea fija, presente en todas las tarjetas
   (altura del peluche para Bolsa/Caja, dimensiones nativas de
   WooCommerce para el resto — amorea_cart_get_product_measure_html()).
   La variante --empty reserva el mismo alto cuando un producto
   temporalmente no tiene dimensión cargada, para no romper la
   alineación de precio/botón del resto de la fila. */
.cart-forgot-card__measure,
.cart-forgot-card__measure--empty {
	font-size: var(--text-xs);
	line-height: 1.4;
	min-height: 1.4em;
	color: var(--color-text-muted);
	margin: 2px var(--space-3) 0;
}

/* 5. Precio — una línea fija, alineada entre todas las tarjetas. */
.cart-forgot-card__price.price {
	display: block;
	margin: 4px var(--space-3) var(--space-2) !important;
	font-size: var(--text-base);
	font-weight: 700;
	color: var(--color-primary);
}

/* 6. Botón "+ Agregar" — anclado abajo con margin-top:auto, mismo
   ancho/alto en las dos variantes de formulario (form propio de
   Bolsa/Caja vs. el <a> nativo de WooCommerce para el resto). Nunca
   hay márgenes especiales por ID/nombre/tipo de producto. */
.cart-forgot-card__actions {
	margin-top: auto;
	padding: 0 var(--space-3);
}

.cart-forgot__package-form {
	margin: 0;
}

/*
 * Reportado en vivo con captura real: los botones "+Agregar" de Bolsa/
 * Caja (el `<button data-package-add-to-cart>` armado a mano, ver
 * woocommerce/cart/cross-sells.php) medían 34px como acá se pide, pero
 * los de Tarjeta/cross-sells/Complementos (el `<a class="button ...
 * add_to_cart_button">` real de WooCommerce, vía
 * woocommerce_template_loop_add_to_cart()) medían 48px — se veían más
 * grandes, sólo en las tarjetas 'native'. Causa real, confirmada con
 * getComputedStyle(): Blocksy fija `min-height: 48px` nativo sobre
 * cualquier elemento con su clase `.button` (main.min.css, variable
 * `--theme-button-height`) — el `<a>` real SÍ trae esa clase
 * (`class="button product_type_simple add_to_cart_button ..."`), el
 * `<button>` armado a mano no, así que sólo el primero se veía
 * afectado. Un `min-height` mayor que el `height` declarado siempre
 * gana por spec, sin importar la especificidad del `height` — se fija
 * `min-height: 34px` acá (igual al `height`, nunca deja lugar a que el
 * de 48px vuelva a ganar), mismo criterio ya aplicado a
 * `.added_to_cart` más abajo.
 */
.cart-forgot-card__actions .add_to_cart_button,
.cart-forgot-card__actions .button.product_type_variable,
.cart-forgot-card__actions .button.product_type_simple {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 4px;
	width: 100%;
	height: 34px;
	min-height: 34px;
	padding: 0 var(--space-2);
	border-radius: var(--radius-md);
	background: var(--color-primary);
	font-size: var(--text-xs);
	font-weight: 700;
	color: var(--color-surface);
	box-shadow: var(--shadow-sm);
	transition: background var(--transition-fast);
}

.cart-forgot-card__actions .add_to_cart_button:hover,
.cart-forgot-card__actions .button.product_type_variable:hover,
.cart-forgot-card__actions .button.product_type_simple:hover {
	/*
	 * Blocksy define un `.button:hover` global (main.min.css) con
	 * `transform: var(--theme-button-transform, translate3d(0, -3px, 0))`
	 * — un "lift" de 3px que se aplica a CUALQUIER elemento con clase
	 * `.button`/`.add_to_cart_button` del sitio, esta tarjeta incluida.
	 * A pedido del cliente estos botones no deben moverse al pasar el
	 * mouse — como el cascade es por propiedad, alcanza con declarar
	 * `transform: none` acá (esta regla ya es más específica que la de
	 * Blocksy, comprobado con CSS.getMatchedStylesForNode vía CDP).
	 */
	transform: none;
	background: var(--color-primary-hover);
	color: var(--color-surface);
}

.cart-forgot-card__actions .add_to_cart_button::before {
	/*
	 * Blocksy define un ::before decorativo compartido en un montón de
	 * selectores de botón (".button::before, ...") con
	 * display:var(--theme-button-shadow, block) para un efecto de
	 * sombra/glow — esa regla no declara "content" con nuestro "+", pero
	 * como nuestra regla tampoco declaraba "display", esa propiedad
	 * quedaba resuelta SÓLO por la de Blocksy (el cascade es por
	 * propiedad, no por bloque de regla) y --theme-button-shadow
	 * resuelve a "none" en este sitio → el "+" nunca se pintaba aunque
	 * el content sí estuviera activo. Se fija display explícito acá.
	 */
	display: inline-block;
	position: static;
	z-index: auto;
	filter: none;
	opacity: 1;
	content: "+";
	font-size: var(--text-base);
	line-height: 1;
}

/*
 * Blocksy trae un `.button, ..., .added_to_cart, ...` global
 * (main.min.css) con fondo/tipografía/bordes propios (variables
 * --theme-button-*, de ahí el botón azul con la tipografía de botón
 * de Blocksy en vez de la de la página) — esta regla nunca declaraba
 * background/padding/border/font-family, así que esas propiedades
 * quedaban resueltas SÓLO por la de Blocksy pese a que `color` (que sí
 * se declaraba acá) ganaba por especificidad — de ahí la combinación
 * rota de fondo azul con texto verde. Se completa el set entero para
 * que quede un botón secundario rosado, mismo alto/tipografía que
 * "Agregar" arriba.
 */
/*
 * Reportado en vivo con captura real: el texto "Ver carrito" se veía
 * corrido hacia arriba, no centrado — causa real, confirmada con
 * getComputedStyle(): Blocksy fija `min-height: 48px` nativo sobre
 * este enlace (`.added_to_cart`, main.min.css, variable
 * `--theme-button-height`) que GANABA sobre el `height: 34px` de acá
 * (un `min-height` mayor que el `height` declarado siempre prevalece,
 * por spec) — la caja terminaba midiendo 48px real pese al `height:
 * 34px`/`line-height: 34px` de esta regla, así que el texto (centrado
 * verticalmente sólo respecto a esos 34px) quedaba corrido hacia
 * arriba dentro de una caja más alta. Se fuerza `min-height: 34px`
 * (gana el empate al ser IGUAL al `height`, sin dejar lugar a que el
 * nativo de 48px vuelva a ganar) + `display:flex` con
 * align-items/justify-content:center en vez de line-height — mismo
 * criterio ya usado en `.add_to_cart_button` de acá abajo, inmune a
 * cualquier min-height que vuelva a colarse en el futuro.
 */
.cart-forgot-card__actions .added_to_cart {
	display: flex;
	align-items: center;
	justify-content: center;
	margin: var(--space-2) 0 0;
	padding: 0 var(--space-2);
	height: 34px;
	min-height: 34px;
	border-radius: var(--radius-md);
	background: var(--color-surface);
	border: 1px solid var(--color-primary);
	font-family: var(--font-body);
	font-size: var(--text-xs);
	font-weight: 700;
	text-align: center;
	text-decoration: none;
	color: var(--color-primary);
}

.cart-forgot-card__actions .added_to_cart:hover {
	/* Mismo "lift" global de Blocksy que el resto de los botones de
	   esta tarjeta (ver el comentario de .add_to_cart_button:hover más
	   arriba) — se cancela acá también por consistencia. */
	transform: none;
	background: var(--color-accent);
	color: var(--color-primary);
}

/* Escritorio reducido / tablet (~900px): 3 tarjetas visibles. */
@media (max-width: 900px) {
	.cart-forgot-card {
		flex: 0 0 calc((100% - 2 * var(--space-4)) / 3);
	}
}

/*
 * Móvil (~390px): 2 tarjetas COMPLETAS visibles a la vez — reportado en
 * vivo con captura real: la versión anterior (1 tarjeta completa + un
 * adelanto de ~20% de la siguiente) dejaba una franja de espacio en
 * blanco entre el borde de esa segunda tarjeta cortada y el borde real
 * de la pantalla, y el cliente prefiere ver 2 tarjetas enteras a la vez
 * en vez de una sola con un adelanto parcial. El carrusel se sigue
 * pudiendo deslizar para ver el resto (nunca tiene tope de productos,
 * ver amorea_cart_get_forgot_something_items()); con 2 tarjetas por
 * "página" el usuario igual nota que hay más contenido gracias a la
 * flecha "siguiente".
 */
@media (max-width: 600px) {
	.cart-forgot-card {
		flex: 0 0 calc((100% - var(--space-4)) / 2);
	}

	.cart-forgot__carousel {
		margin: 0 var(--space-4);
	}

	.cart-forgot__arrow {
		width: 32px;
		height: 32px;
	}

	.cart-forgot__arrow--prev {
		left: 0;
	}

	.cart-forgot__arrow--next {
		right: 0;
	}
}

/*
|--------------------------------------------------------------------------
| Bloques de confianza + reseñas
|--------------------------------------------------------------------------
*/

.cart-trust {
	padding: var(--space-16) 0 var(--space-10);
}

.cart-trust__title {
	text-align: center;
	font-family: var(--font-body);
	font-weight: 700;
	font-size: var(--text-2xl);
	margin: 0 0 var(--space-8);
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	color: var(--color-text);
}

.cart-trust__title svg {
	color: var(--color-primary);
}

.cart-trust__grid {
	display: grid;
	grid-template-columns: repeat(5, 1fr);
	background: var(--color-surface);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-sm);
	padding: var(--space-6);
}

.cart-reviews {
	padding-bottom: var(--space-10);
}

.cart-reviews__box {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	gap: var(--space-8);
	background: var(--color-accent);
	padding: var(--space-6) var(--space-10);
	border-radius: var(--radius-pill);
}

.cart-reviews__customers,
.cart-reviews__ratings {
	display: flex;
	align-items: center;
	gap: var(--space-3);
}

.cart-reviews__ratings {
	padding-inline-start: var(--space-8);
	border-inline-start: 1px solid rgba(45, 37, 48, 0.12);
}

.cart-reviews__avatars {
	display: flex;
}

/* Círculos con el corazón de marca — nunca fotos de clientes inventados. */
.cart-reviews__avatar {
	width: 32px;
	height: 32px;
	border-radius: 50%;
	background: var(--color-surface);
	color: var(--color-primary);
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: var(--shadow-sm);
	margin-inline-start: -10px;
	border: 2px solid var(--color-accent);
}

.cart-reviews__avatar:first-child {
	margin-inline-start: 0;
}

.cart-reviews__customers-text,
.cart-reviews__ratings-text {
	margin: 0;
	font-weight: 600;
	font-size: var(--text-sm);
	color: var(--color-text);
}

.cart-reviews__stars {
	color: #f5a623;
	letter-spacing: 1px;
	font-size: var(--text-lg);
	line-height: 1;
}

.cart-reviews__stars--empty {
	color: var(--color-text-muted);
}

/*
|--------------------------------------------------------------------------
| Carrito vacío
|--------------------------------------------------------------------------
*/

.cart-empty {
	text-align: center;
	padding: var(--space-16) var(--space-4);
	max-width: var(--container-reading);
	margin: 0 auto;
}

.cart-empty__icon {
	display: inline-flex;
	color: var(--color-accent);
	margin-bottom: var(--space-4);
}

.cart-empty__text {
	color: var(--color-text-muted);
	font-size: var(--text-lg);
	margin: 0 0 var(--space-6);
}

.cart-empty__actions {
	margin: 0;
}

/*
|--------------------------------------------------------------------------
| Responsive — tablet (900px) y móvil (390px), probado también a 1440px
|--------------------------------------------------------------------------
*/

@media (max-width: 1024px) {
	/*
	 * Pedido explícito de la usuaria 2026-10-03: en una sola columna,
	 * la "Lista de productos" y el "Resumen de tu pedido" dejan de ser
	 * 2 tarjetas separadas (antes: toda la lista arriba, Seguir
	 * comprando/Vaciar carrito, y recién después el resumen con el
	 * botón de pago bien abajo — probado en vivo por la clienta,
	 * demasiado scroll para llegar al botón). Pasan a ser UNA sola
	 * tarjeta con las secciones REORDENADAS: título → productos →
	 * cupón → totales → botón de pago → métodos de pago → beneficios.
	 * Nunca se duplica ni se mueve el HTML de verdad (sigue siendo el
	 * mismo <form>/mismo div#cart_totals que WooCommerce actualiza por
	 * AJAX) — `display:contents` en los 3 envoltorios
	 * (.cart-main/.cart-aside/.cart_totals) hace que sus propios hijos
	 * pasen a ser ítems directos de ESTE grid de una columna, y
	 * `order` los reacomoda visualmente. El fondo/padding de tarjeta
	 * que tenían esos 3 envoltorios (ahora invisibles) se traslada acá,
	 * a .cart-layout, que pasa a ser la única tarjeta visible.
	 */
	.cart-layout {
		grid-template-columns: 1fr;
		background: var(--color-surface);
		border-radius: var(--radius-lg);
		box-shadow: var(--shadow-sm);
		padding: var(--space-6);
		gap: var(--space-5);
	}

	.cart-aside {
		position: static;
	}

	.cart-main,
	.cart-aside,
	.cart_totals {
		display: contents;
	}

	form.woocommerce-cart-form {
		order: 2;
	}

	/* "Seguir comprando" ya existe en el encabezado de esta página;
	   "Vaciar carrito" desaparece a propósito — en móvil se elimina
	   producto por producto con el ícono de cada fila. */
	.cart-actions-row {
		display: none;
	}

	.cart-forgot {
		order: 9;
	}

	.cart_totals > .cart-card__title {
		order: 1;
	}

	.cart_totals > .cart-coupon-accordion {
		order: 3;
		/* BUG REAL encontrado 2026-10-03 (pedido explícito de la
		   usuaria): el acordeón trae su propio `margin:16px 0` (pensado
		   para su posición original, rodeado de otro contenido en
		   flujo normal) — sumado al `gap` que ya separa a los hijos de
		   este grid fusionado, "Subtotal" quedaba 36px por debajo de
		   la línea divisoria del acordeón en vez de la separación
		   normal entre secciones. Se quita el margen inferior propio
		   (var(--space-5), 20px, ya lo da el `gap`) y se resta un poco
		   más (pedido explícito, segunda vuelta) para que quede más
		   pegado a la línea divisoria. */
		margin-bottom: -12px;
	}

	.cart_totals > .cart-summary__rows,
	.cart_totals > .cart-summary__coupons {
		order: 4;
	}

	.cart_totals > .wc-proceed-to-checkout {
		order: 5;
	}

	.cart_totals > .cart-payment-methods {
		order: 6;
	}

	.cart_totals > .cart-benefits {
		order: 7;
	}

	#amorea-dedication-slot {
		order: 8;
	}
}

/*
 * BUG REAL encontrado 2026-10-03 (reporte en vivo de la usuaria,
 * barrido propio, prueba real con Range.getClientRects() por palabra
 * — un primer intento contando líneas dio falsos negativos):
 * `.cart-trust` vive FUERA de `.cart-layout` (page-close.php, después
 * del grid de 2 columnas) — su ancho real es simplemente el del
 * viewport completo, sin interferencia del sidebar. Aun así, "5
 * columnas" (regla base) no tiene espacio real hasta 1440px, y "3
 * columnas" tampoco hasta 881px — ninguno de los 2 coincidía con el
 * quiebre de 1024px que se usaba antes (pensado para la fusión de
 * `.cart-layout`, un componente totalmente distinto). Se separan en su
 * propio quiebre, independiente del de la fusión de arriba.
 */
@media (max-width: 1439px) {
	.cart-trust__grid {
		grid-template-columns: repeat(3, 1fr);
		row-gap: var(--space-6);
	}

	.value-card.cart-trust__item:nth-child(4) {
		border-left: none;
	}
}

@media (max-width: 880px) {
	.cart-trust__grid {
		grid-template-columns: repeat(2, 1fr);
	}

	.value-card.cart-trust__item {
		border-left: none !important;
		text-align: center;
		flex-direction: column;
		padding-inline: var(--space-2);
	}
}

/*
 * Mismo hallazgo, un nivel más angosto: incluso en 2 columnas,
 * "Atención personalizada" (la más larga) seguía partiéndose a media
 * palabra por debajo de 375px reales de columna — medido en vivo,
 * limpio desde 375px, roto por debajo. A una sola columna cada tarjeta
 * tiene de sobra (>200px incluso a 280px de viewport).
 */
@media (max-width: 375px) {
	.cart-trust__grid {
		grid-template-columns: 1fr;
	}
}

@media (max-width: 900px) {
	.cart-progress__step {
		width: 74px;
	}

	.cart-progress__label {
		font-size: 10px;
	}
}

/*
 * BUG REAL reportado por el cliente con captura (ronda 2): esta regla
 * envolvía logo+"Seguir comprando" en una primera fila y el progreso
 * en una segunda fila completa debajo — el cliente pidió que Carrito
 * usara exactamente el mismo patrón de una sola fila (logo — pasos —
 * enlace) que ya está aprobado en Checkout (ver checkout.css,
 * `@media(max-width:640px)` cerca de la línea 2408 — MISMO bloque,
 * copiado tal cual, nunca modificado). `.amorea-checkout-topbar`
 * antepuesto a `.cart-progress__step`/`__marker`/`::after`/`__label`
 * (que en Checkout no lo necesitan, ese archivo no tiene otros
 * tramos que compitan) sube la especificidad lo justo para ganarle
 * a los tramos YA EXISTENTES y sin tocar de este mismo archivo
 * (`@media max-width:900px` línea ~1500, `@media max-width:600px`
 * línea ~1630) sin reordenar ni editar esos bloques.
 *
 * BUG REAL encontrado 2026-10-03: quiebre subido a 680px, mismo fix
 * que checkout.css (ver su propio comentario, idéntico, junto a la
 * regla equivalente) — el ancho real de `.inner` no alcanza para la
 * fila completa hasta 680px, no 640px.
 */
@media (max-width: 680px) {
	.amorea-checkout-topbar__inner {
		gap: clamp(4px, 2vw, var(--space-4));
	}

	.amorea-checkout-topbar__logo img {
		height: clamp(26px, 8vw, 80px);
	}

	.amorea-checkout-back-link {
		gap: clamp(3px, 1vw, 6px);
		font-size: clamp(10px, 2.4vw, var(--text-sm));
	}

	.amorea-checkout-back-link svg {
		width: clamp(10px, 2.6vw, 16px);
		height: clamp(10px, 2.6vw, 16px);
	}

	.amorea-checkout-topbar .cart-progress {
		flex: 0 1 auto;
		justify-content: center;
		min-width: 0;
	}

	/* BUG REAL encontrado 2026-10-03: había una regla duplicada más
	   abajo en este mismo bloque (`width:72px`/`font-size:10px` fijos,
	   resto de una versión anterior a este clamp()) que ganaba el
	   empate de especificidad por ir después, anulando el piso fluido
	   — mismo bug, misma corrección que checkout.css (ver su propio
	   comentario, idéntico, junto a la regla equivalente). */
	.amorea-checkout-topbar .cart-progress__step {
		width: clamp(36px, 11vw, 72px);
	}

	.amorea-checkout-topbar .cart-progress__marker {
		width: clamp(18px, 5vw, 32px);
		height: clamp(18px, 5vw, 32px);
	}

	.amorea-checkout-topbar .cart-progress__step:not(:last-child)::after {
		top: clamp(9px, 2.5vw, 16px);
	}

	.amorea-checkout-topbar .cart-progress__label {
		font-size: clamp(8.5px, 1.8vw, 10px);
	}
}

/*
 * BUG REAL encontrado 2026-10-03 (barrido de desborde genérico): la
 * tabla de productos tiene un ancho mínimo real de 648px (medido
 * directamente, `table.scrollWidth` — ninguna columna se encoge más
 * allá de ese punto). El viejo quiebre a "modo tarjeta apilada" vivía
 * en `@media(max-width:600px)` — pero el ANCHO REAL de
 * `form.woocommerce-cart-form` no depende sólo del viewport: con el
 * sidebar de resumen activo (`.cart-layout` en 2 columnas, ≥1025px) el
 * formulario mide bastante MENOS que el viewport, y entre 1025-1220px
 * medía apenas 476-638px — por debajo del mínimo de la tabla, pero por
 * encima del quiebre de 600px, así que nunca se apilaba. Mismo problema
 * en 620-760px con el layout de 1 columna. Resultado: la tabla se
 * desbordaba hasta 172px en un rango de ancho real (620-1220px) que
 * cubre tablets y laptops angostas, nunca solo un caso de laboratorio.
 * `container-type:inline-size` en el propio `<form>` + `@container`
 * (en vez de `@media`) hace que el modo tarjeta se active según el
 * ANCHO REAL del formulario, sea cual sea la razón (sidebar presente o
 * no, viewport, zoom) — elimina la clase de bug "el quiebre de
 * viewport no captura todos los anchos reales posibles", mismo
 * principio ya aplicado hoy en single-product.css y checkout.css.
 */
form.woocommerce-cart-form {
	container-type: inline-size;
	container-name: amorea-cart-table;
}

@container amorea-cart-table (max-width: 650px) {
	.cart-table thead {
		display: none;
	}

	.cart-table,
	.cart-table tbody {
		display: block;
		width: 100%;
	}

	/*
	 * Pedido explícito de la usuaria 2026-10-03: en vez de 4 filas
	 * apiladas (Precio / Cantidad / Subtotal / Acciones, una debajo de
	 * otra), queda sólo UNA fila con [Subtotal] [cantidad] ... [me
	 * gusta] [eliminar] — "Precio" se oculta del todo (con cantidad=1
	 * mostraba el mismo número que "Subtotal"; con esta fusión sólo
	 * tiene sentido mostrar uno, y Subtotal es el correcto porque sigue
	 * siendo preciso si la cantidad cambia). La fila (`<tr>`) pasa a
	 * `flex` con salto de línea: el producto ocupa toda la primera
	 * línea por su propio ancho (100%), y precio+cantidad+acciones
	 * fluyen juntos en la segunda línea.
	 */
	.cart-table tr {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		column-gap: var(--space-3);
		row-gap: var(--space-2);
	}

	.cart-table td {
		display: block;
		width: auto;
		padding: var(--space-2) 0;
	}

	td.cart-table__product {
		/* Mismo empate de especificidad que `td.cart-table__price` de
		   abajo — sin el elemento `td`, `.cart-table td{width:auto}`
		   ganaba y el producto se encogía a su contenido en vez de
		   ocupar toda la fila, dejando un resto de ancho variable
		   (según el largo del nombre) para precio/cantidad/acciones —
		   eso era lo que los desalineaba de forma distinta en cada
		   fila. */
		width: 100%;
		order: 1;
	}

	td.cart-table__price {
		/* `.cart-table td{display:block}` (arriba) empata en
		   especificidad con una clase sola — `td.cart-table__price`
		   iguala esa especificidad para ganar por ir después. */
		display: none;
	}

	.cart-item-product {
		align-items: center;
		/* BUG REAL encontrado 2026-10-03: `min-width:240px` (regla base,
		   pensada para la fila de tabla en escritorio, con columnas de
		   precio/cantidad/subtotal/acciones al lado) seguía aplicando
		   acá — en modo apilado esta celda YA ocupa el 100% real de la
		   fila (`.cart-table td{width:100%}`), así que el mínimo fijo
		   sólo causaba desborde bajo 240px de ancho real (240 vs
		   214-232px medidos a 280-300px de viewport). */
		min-width: 0;
	}

	.cart-item-product__media,
	.cart-item-product__media > a {
		flex: 0 0 72px;
		width: 72px;
		min-width: 72px;
		height: 72px;
	}

	.cart-table__subtotal {
		order: 2;
		text-align: left;
	}

	td.cart-table__qty {
		order: 3;
		display: flex;
	}

	.cart-item-qty {
		margin: 0;
	}

	td.cart-table__actions {
		order: 4;
		display: flex;
		margin-left: auto;
	}

	.cart-item-actions {
		flex-direction: row;
	}
}

@media (max-width: 600px) {
	.cart-main,
	.cart-card {
		padding: var(--space-4);
	}

	.cart-actions-row {
		flex-direction: column-reverse;
		align-items: stretch;
	}

	.cart-actions-row .btn {
		width: 100%;
	}

	.cart-progress__step {
		width: 60px;
	}

	.cart-progress__marker {
		width: 26px;
		height: 26px;
	}

	.cart-progress__step:not(:last-child)::after {
		top: 13px;
	}

}

/*
 * BUG REAL encontrado 2026-10-03 (reporte en vivo de la usuaria): este
 * tratamiento vivía en `@media(max-width:600px)`, pero
 * `.cart-reviews__box` (flex con `flex-wrap:wrap`) en realidad se
 * apila en un rango bastante más ancho — medido en vivo: se apila
 * desde el ancho mínimo hasta 707px, no sólo hasta 600px. Entre
 * 601-707px quedaba apilado pero SIN dividir en 2 óvalos (el bug que
 * reportó: "0 reseñas" debajo de "0 clientes..." compartiendo un solo
 * óvalo rosa). Quiebre propio a 710px (707 + margen), separado del
 * resto de ajustes de 600px que no tienen este problema.
 */
@media (max-width: 710px) {
	.cart-reviews__box {
		flex-direction: column;
		align-items: stretch;
		background: none;
		padding: 0;
		border-radius: 0;
		gap: var(--space-4);
	}

	.cart-reviews__customers,
	.cart-reviews__ratings {
		justify-content: center;
		border-radius: var(--radius-pill);
		padding: var(--space-5) var(--space-6);
	}

	.cart-reviews__customers {
		background: var(--color-surface);
		/* Pedido explícito de la usuaria: borde del mismo color que el
		   fondo rosado del óvalo de reseñas, para que el óvalo blanco
		   no se pierda contra el fondo de la página. */
		border: 1px solid var(--color-accent);
	}

	.cart-reviews__ratings {
		background: var(--color-accent);
		border-inline-start: none;
		padding-inline-start: var(--space-6);
	}
}
