/* ============================================================
   Ajustes que sólo existen porque WooCommerce está de por medio.
   No es diseño nuevo: son correcciones sobre el CSS aprobado.
   Cada bloque dice QUÉ regla de Woo está peleando y CÓMO se detectó.
   ============================================================ */

/* ------------------------------------------------------------------
   1 · El logo del encabezado, a su tamaño

   `woocommerce-layout.css` trae:

       .woocommerce img, .woocommerce-page img { height: auto; max-width: 100% }

   En cuanto WooCommerce le pone la clase `woocommerce-page` al body —o sea
   en la tienda, la ficha, el carrito y el checkout— esa regla le gana a
   `.logo__img{height:54px}` por especificidad y el logo sale a su tamaño
   natural: 654 × 483 px.

   Se detectó porque el catálogo daba 48.1% y el encabezado salía enorme,
   mientras la portada seguía en 0%. La diferencia entre las dos páginas era
   justo la clase del body.
   ------------------------------------------------------------------ */
.woocommerce .logo__img,
.woocommerce-page .logo__img {
  height: 54px;
  width: auto;
}
.woocommerce .logo--claro .logo__img,
.woocommerce-page .logo--claro .logo__img {
  height: 64px;
}
@media (max-width: 1000px) {
  .woocommerce .logo__img,
  .woocommerce-page .logo__img { height: 44px; }
}

/* ------------------------------------------------------------------
   2 · Las fotos de producto llenan su marco

   Misma regla de arriba: `height:auto` deja que la foto tome su alto
   natural dentro de `.prod__img`, que es un marco de proporción 4/5. El
   resultado son tarjetas de distinto alto y una retícula desalineada.

   `.prod__img .foto` ya es `position:absolute;inset:0` en el CSS aprobado;
   lo único que falta es que Woo no le quite el alto.
   ------------------------------------------------------------------ */
.woocommerce .prod__img .foto,
.woocommerce-page .prod__img .foto {
  height: 100%;
  width: 100%;
  object-fit: cover;
}

/* ------------------------------------------------------------------
   3 · El ordenador de WooCommerce con la forma del prototipo

   `woocommerce_catalog_ordering()` imprime un <form> con su propio <select>.
   El prototipo tiene un <select class="select"> suelto. Se le da la misma
   forma en vez de escribir uno propio: reimplementarlo significaría perder
   «más vendidos», que sale de las ventas reales de Woo.
   ------------------------------------------------------------------ */
.woocommerce-ordering { margin: 0; }

/*
 * Los valores son EXACTAMENTE los de `.select` en styles.css:
 *   border:1px · padding:10px 14px · font-size:.78rem · radius:var(--radio)
 *
 * No están copiados a ojo. En el primer intento se pusieron valores
 * «parecidos» (padding 9px, font .82rem) y el <select> salió 1 px más bajo:
 * `.cat-bar` medía 62 px contra 63 del prototipo y ESE PIXEL corría las 36
 * tarjetas hacia arriba. El catálogo se quedaba en 10% de diferencia por un
 * píxel de relleno.
 *
 * Si el prototipo cambia `.select`, esto se cambia igual.
 */
.woocommerce-ordering select {
  font-family: var(--sans, 'Jost', sans-serif);
  font-size: .78rem;
  padding: 10px 14px;
  border: 1px solid var(--gris-linea, #E4DEE0);
  border-radius: var(--radio, 2px);
  background: var(--blanco, #fff);
  color: var(--negro, #1A1A1A);
  cursor: pointer;
}

/* ------------------------------------------------------------------
   4 · Estado vacío del catálogo

   En Kevstore dos categorías respondían 200 con el texto de Woo «no se
   encontraron productos», que se lee como filtro fallido. Aquí el bloque
   dice qué pasó y ofrece a dónde ir.
   ------------------------------------------------------------------ */
.cat-vacio {
  grid-column: 1 / -1;
  text-align: center;
  padding: clamp(40px, 6vw, 80px) 20px;
  background: var(--hueso, #F4F1F2);
  border-radius: 12px;
}

/* ------------------------------------------------------------------
   5 · Mensajes de WooCommerce (producto agregado, errores, avisos)

   ⚠️ SALÍAN COMO TEXTO PELÓN, sin caja.

   `woocommerce-layout.css` —el que se conserva— sólo los POSICIONA. La caja
   (fondo, relleno, la barra de color, el ícono) vive en
   `woocommerce-general.css`, que sí se quita. Sin ella, «Producto agregado al
   carrito» y los errores del checkout salen como un párrafo suelto y el botón
   que traen dentro sale como un enlace de texto flotado a la derecha.

   Se detectó en «Mis pedidos»: el aviso de confirmar correo aparecía como dos
   frases sueltas en renglones distintos. Afecta a TODOS los avisos del sitio,
   no sólo a ése — el más frecuente es el de agregar al carrito.

   La caja es la del prototipo (`.info-box`), con su variante por tipo:
   azul para avisos, verde para confirmaciones, magenta para errores.
   ------------------------------------------------------------------ */
.woocommerce-message,
.woocommerce-info,
.woocommerce-error {
  font-family: var(--sans, 'Jost', sans-serif);
  font-size: .86rem;
  line-height: 1.6;
  list-style: none;
  margin: 0 0 24px;
  padding: 16px 20px;
  border-radius: 6px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
}

/* Aviso — la misma caja azul de `.info-box` */
.woocommerce-info {
  border: 1px solid #B7CDEE;
  background: #EEF4FD;
  color: #26497F;
}

/* Confirmación — «producto agregado», «pedido recibido» */
.woocommerce-message {
  border: 1px solid #9FD4B4;
  background: #F2FAF6;
  color: var(--exito, #1D7A54);
}

/* Error — se usa el magenta de la marca, no el rojo de Woo */
.woocommerce-error {
  border: 1px solid #F2B8D3;
  background: #FDF0F6;
  color: var(--magenta, #D6006E);
}
.woocommerce-error li { list-style: none; }

/*
 * Los botones que Woo mete DENTRO del aviso —«Ver carrito», «Confirmar mi
 * correo»—. `woocommerce-layout.css` los flota a la derecha y sin la caja de
 * general.css se salían del renglón. Con el flex de arriba ya no hace falta
 * flotarlos: se ponen al final y ya.
 */
.woocommerce-message .button,
.woocommerce-info .button,
.woocommerce-error .button {
  float: none;
  order: 2;
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  padding: 9px 18px;
  border: 1px solid currentColor;
  border-radius: var(--radio, 2px);
  background: transparent;
  color: inherit;
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: var(--trans, all .25s ease);
}
/* 🚨 6 · AQUÍ EL BOTÓN SE VOLVÍA INVISIBLE AL PASARLE EL CURSOR.
 *
 * Estaba escrito así:
 *
 *     ...button:hover { background: currentColor; }
 *     .woocommerce-message .button:hover { color: #F2FAF6; }
 *
 * `currentColor` en `background` NO toma el color de antes del hover: toma el
 * color COMPUTADO del propio elemento, que dos líneas abajo se estaba poniendo
 * en #F2FAF6. Así que al pasar el cursor quedaba fondo #F2FAF6 con texto
 * #F2FAF6 — blanco sobre blanco. El botón «Ver carrito» seguía ahí, seguía
 * siendo clicable, y no se veía. Fer lo reportó como «el aviso desaparece».
 *
 * ⚠️ La lección: `background: currentColor` sólo es seguro si en ESE MISMO
 * estado no se toca `color`. En cuanto los dos cambian juntos, el resultado es
 * un elemento que se traga a sí mismo. Y no da error: se ve como un hueco.
 *
 * Ahora los dos colores van explícitos, para que se puedan leer de un vistazo
 * y para que ninguno dependa del otro. */
.woocommerce-message .button:hover { background: #1D7A54; color: #F2FAF6; border-color: #1D7A54; }
.woocommerce-info .button:hover    { background: #1B4F9C; color: #EEF4FD; border-color: #1B4F9C; }
.woocommerce-error .button:hover   { background: #B3134F; color: #FDF0F6; border-color: #B3134F; }

/* ------------------------------------------------------------------
   6 · El formulario de compra, con la forma del prototipo

   `woocommerce_template_single_add_to_cart()` imprime su propio <form>:
   un .quantity con <input type=number> y un <button class="single_add_to_cart_button">.

   Se le da la forma en vez de escribir uno propio. Reimplementarlo
   significaría perder el AJAX, la validación de existencias y el enganche
   de los plugins de pago — y eso es justo lo que hace que el botón sirva.
   ------------------------------------------------------------------ */
.pdp__info form.cart {
  display: grid;
  gap: 14px;
  margin: 22px 0 0;
}

/* El contador, con la caja del prototipo (.qty) */
.pdp__info form.cart .quantity {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--gris-linea, #E4DEE0);
  border-radius: var(--radio, 2px);
  overflow: hidden;
  width: max-content;
}
.pdp__info form.cart .quantity label {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap;
}
.pdp__info form.cart .quantity input.qty {
  width: 62px;
  border: 0;
  text-align: center;
  font-family: var(--sans, 'Jost', sans-serif);
  /* 16 px y no .95rem: abajo de 16 Safari hace zoom al tocar el campo — ver el
     bloque 26. Se corrige AQUÍ, en su origen, porque esta regla le gana por
     especificidad a la general y pelearle con `!important` sería esconder el
     problema en vez de arreglarlo. */
  font-size: 16px;
  font-weight: 600;
  padding: 12px 4px;
  background: transparent;
  color: var(--negro, #1A1A1A);
  -moz-appearance: textfield;
}
.pdp__info form.cart .quantity input.qty::-webkit-outer-spin-button,
.pdp__info form.cart .quantity input.qty::-webkit-inner-spin-button {
  /* Las flechitas del navegador no caben en el diseño y en móvil son
     imposibles de picar. El +/− va aparte. */
  -webkit-appearance: none; margin: 0;
}

/* El botón principal: negro, ancho completo, como el prototipo */
.pdp__info form.cart button.single_add_to_cart_button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 16px 30px;
  border: 1px solid var(--negro, #1A1A1A);
  border-radius: var(--radio, 2px);
  background: var(--negro, #1A1A1A);
  color: var(--blanco, #fff);
  font-family: var(--sans, 'Jost', sans-serif);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: var(--trans, all .25s ease);
}
.pdp__info form.cart button.single_add_to_cart_button:hover {
  background: var(--magenta, #D6006E);
  border-color: var(--magenta, #D6006E);
}
.pdp__info form.cart button.single_add_to_cart_button.loading { opacity: .7; }

/* ------------------------------------------------------------------
   7 · Estado vacío de opiniones
   ------------------------------------------------------------------ */
.res-vacio {
  text-align: center;
  padding: clamp(36px, 5vw, 64px) 20px;
  background: var(--blanco, #fff);
  border-radius: 14px;
}

/* ------------------------------------------------------------------
   8 · «Mi cuenta»: la retícula del prototipo en vez de los flotados

   ⚠️ ESTE ERA UN BUG DE CONTENIDO INVISIBLE, no de estilo.

   `woocommerce-layout.css` —que se conserva porque posiciona los mensajes de
   «producto agregado»— flota las DOS columnas de Mi cuenta:

       .woocommerce-MyAccount-navigation { float: left;  width: 30% }
       .woocommerce-MyAccount-content    { float: right; width: 68% }

   El clearfix que las contiene vive en `woocommerce-general.css`, que sí se
   quita. Sin él el contenedor colapsa a CERO de alto: el contenido está en el
   DOM —Playwright lo leía completo— pero no ocupa nada y la página se pinta
   con el encabezado pegado al pie.

   Las cinco páginas de cuenta medían exactamente 1000 px, la altura de la
   ventana. Ese número idéntico en las cinco fue la pista: un diseño roto no
   da el mismo alto cinco veces.
   ------------------------------------------------------------------ */
.woocommerce-account .woocommerce {
  /* Sin `display` propio: la retícula la pone `.cuenta` dentro de
     `myaccount/my-account.php`, que es la del prototipo. Aquí sólo hay que
     deshacer los flotados para que el contenedor no colapse. */
  display: block;
}
.woocommerce-account .woocommerce-MyAccount-navigation,
.woocommerce-account .woocommerce-MyAccount-content {
  float: none;
  width: auto;
}

/* ------------------------------------------------------------------
   9 · Casillas de verificación: una sola, no dos

   El prototipo no tiene JavaScript, así que su casilla es un `<span class="fbox">`
   dibujado a mano, sin `<input>` detrás. Al pasarlo a WordPress hay que poner el
   input de verdad —si no, el formulario no manda el dato— y entonces se pintan
   LAS DOS: la casilla del navegador y el cuadrito del diseño, una junto a otra.

   Se esconde el input sin sacarlo del formulario ni del foco del teclado
   (`opacity:0` encima del cuadrito, no `display:none`), y el `.fbox` se prende
   con `:checked`. Así la casilla se ve como el diseño, se puede tabular y se
   manda.

   Esto también arregla la casilla de «Necesito factura (CFDI)» del checkout,
   que traía el mismo par duplicado.
   ------------------------------------------------------------------ */
.fopt { position: relative; }
.fopt > input[type="checkbox"] {
  position: absolute;
  left: 0;
  width: 15px;
  height: 15px;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.fopt > input[type="checkbox"]:checked + .fbox {
  background: var(--magenta, #D6006E);
  border-color: var(--magenta, #D6006E);
}
.fopt > input[type="checkbox"]:checked + .fbox::after {
  content: "";
  position: absolute;
  inset: 3px;
  background: #fff;
  clip-path: polygon(14% 47%, 0 60%, 40% 100%, 100% 22%, 86% 8%, 38% 70%);
}
.fopt > input[type="checkbox"]:focus-visible + .fbox {
  outline: 2px solid var(--magenta, #D6006E);
  outline-offset: 2px;
}
.fopt .fbox { position: relative; }

/* ------------------------------------------------------------------
   10 bis · El aviso de privacidad que imprime WooCommerce

   Sale con el tamaño del cuerpo del texto y compite con el formulario. En el
   prototipo es letra chica y gris (`.aviso-form`). Se le da esa forma en vez
   de escribir uno propio: el de Woo es el que enlaza a la página de privacidad
   configurada en Ajustes, así que sigue funcionando si RV la cambia de sitio.
   ------------------------------------------------------------------ */
.woocommerce-privacy-policy-text p {
  font-size: .8rem;
  color: var(--gris, #7B7176);
  margin-top: 16px;
  line-height: 1.6;
}
.woocommerce-privacy-policy-text a {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ------------------------------------------------------------------
   11 · Pedidos cancelados o devueltos

   El prototipo tiene tres píldoras —entregado, en camino, preparando— porque
   enseña un cliente al corriente. WooCommerce tiene siete estados, y los que
   faltan (cancelado, reembolsado, fallido) sí le salen a alguien.

   Se les da una píldora gris a propósito: pintarlos de rojo convierte una
   devolución resuelta en una alarma cada vez que la clienta entra a su cuenta.
   ------------------------------------------------------------------ */
.estado--baja {
  background: var(--hueso, #F4F1F2);
  color: var(--gris, #7B7176);
  border: 1px solid var(--gris-linea, #E4DEE0);
}

/* ------------------------------------------------------------------
   12 · «Pedido recibido»

   ⚠️ ESTE BLOQUE SÍ ES DISEÑO NUEVO, y es el único del tema que lo es.

   El prototipo aprobado NO tiene pantalla de gracias — tiene carrito y
   checkout, y ahí se corta. Así que no hay contra qué comparar y el comparador
   visual no la mide.

   Se construye con los tokens del prototipo y reusando sus piezas (`.ck-pasos`,
   `.aviso-zona`, `.btn`), para que se reconozca como la misma tienda. Nada de
   valores nuevos: todo sale de `--magenta`, `--hueso`, `--radio`, `--sans`.

   Cuando RV apruebe un diseño para esta pantalla, se mide como las demás.
   ------------------------------------------------------------------ */

/* La cabeza: círculo con palomita, título y qué sigue */
.ty-cab { text-align: center; margin-bottom: clamp(28px, 4vw, 44px); }
.ty-circ {
  display: inline-grid;
  place-items: center;
  width: 62px; height: 62px;
  border-radius: 50%;
  background: #F2FAF6;
  border: 1px solid #9FD4B4;
  margin-bottom: 18px;
}
.ty-tick { width: 28px; height: 28px; fill: none; stroke: var(--exito, #1D7A54); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.ty-titulo { margin: 0; }
.ty-sub {
  max-width: 560px;
  margin: 12px auto 0;
  font-size: .95rem;
  color: var(--negro-suave, #3A3437);
  line-height: 1.65;
}

/* Los cuatro datos del pedido */
.ty-datos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1px;
  background: var(--gris-linea, #E4DEE0);
  border: 1px solid var(--gris-linea, #E4DEE0);
  border-radius: 6px;
  overflow: hidden;
  max-width: 860px;
  margin-inline: auto;
}
.ty-datos > div { background: var(--blanco, #fff); padding: 18px 20px; }
/*
 * ⚠️ `> div > span` Y NO `span` A SECAS.
 *
 * `.ty-datos span` agarraba también los `<span>` que WooCommerce mete DENTRO
 * del precio —`.woocommerce-Price-amount` y `.woocommerce-Price-currencySymbol`—
 * y los volvía bloque: el total salía con el «$» en un renglón y «1,620» en el
 * de abajo, los dos en minúsculas grises de etiqueta.
 *
 * Es el mismo error que ya está documentado en `modulos.css` con `.f label`
 * pisando las etiquetas de opción. Un selector de un nivel de más.
 */
.ty-datos > div > span { display: block; font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; color: var(--gris, #7B7176); margin-bottom: 6px; }
.ty-datos b { font-size: 1rem; font-weight: 600; }
.ty-num { color: var(--magenta, #D6006E); }

/* El bloque de la transferencia — el que cobra */
.ty-pago {
  max-width: 860px;
  margin: clamp(24px, 3vw, 36px) auto 0;
  padding: clamp(22px, 3vw, 32px);
  border: 1px solid #EAD3AE;
  background: #FDF8EF;
  border-radius: 6px;
  text-align: center;
}
.ty-pago-tit { font-family: var(--serif, 'Playfair Display', serif); font-size: 1.3rem; color: #7A5400; margin: 0 0 18px; }

/*
 * La CLABE, grande y con su botón de copiar.
 *
 * `font-variant-numeric: tabular-nums` no es cosmético: con cifras de ancho
 * variable, 18 dígitos seguidos se leen mal y se teclean peor. Aquí se copian
 * a mano cuando el botón no funciona.
 */
.ty-clabe {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  justify-content: center;
  padding: 14px 18px;
  background: var(--blanco, #fff);
  border: 1px solid #EAD3AE;
  border-radius: 6px;
}
.ty-clabe-et { font-size: .7rem; letter-spacing: .14em; text-transform: uppercase; color: var(--gris, #7B7176); }
.ty-clabe b {
  font-size: clamp(1.05rem, 2.4vw, 1.35rem);
  font-weight: 600;
  letter-spacing: .06em;
  font-variant-numeric: tabular-nums;
  user-select: all;
}
.ty-copiar {
  padding: 7px 14px;
  border: 1px solid var(--negro, #1A1A1A);
  border-radius: var(--radio, 2px);
  background: transparent;
  font-family: var(--sans, 'Jost', sans-serif);
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: var(--trans, all .25s ease);
}
.ty-copiar:hover { background: var(--negro, #1A1A1A); color: var(--blanco, #fff); }
.ty-copiar[data-copiado] { border-color: var(--exito, #1D7A54); color: var(--exito, #1D7A54); background: #F2FAF6; }

.ty-pago-quien { margin-top: 12px; font-size: .88rem; color: #6E5A32; }

.ty-wa {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-top: 20px;
  padding: 14px 26px;
  border-radius: var(--radio, 2px);
  background: var(--exito, #1D7A54);
  color: #fff;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  transition: var(--trans, all .25s ease);
}
.ty-wa:hover { background: #17603F; color: #fff; }

.ty-pago-nota { margin-top: 18px; font-size: .82rem; color: #6E5A32; line-height: 1.6; }

@media (max-width: 600px) {
  .ty-clabe { gap: 10px; }
  .ty-clabe b { font-size: 1rem; }
}

/* ------------------------------------------------------------------
   13 · La tabla del pedido y las direcciones, en «Pedido recibido»

   ⚠️ SIN ESTO LA PANTALLA SE PARTE A LA MITAD.

   De `woocommerce_thankyou` cuelgan `order/order-details.php` y
   `order/order-details-customer.php`, que NO están sobrescritas — a propósito:
   de ellas cuelgan los plugins de facturación y de rastreo, y reescribirlas es
   la manera de perderlos en la siguiente actualización.

   Pero salen crudas: «Producto / Total» en negritas sueltas, «Subtotal:» con
   sangría, la dirección en cursiva. Arriba la tienda vestida y abajo
   WooCommerce — exactamente el defecto que se corrigió en Kevstore.

   Se les da la ropa por CSS y los hooks quedan intactos.
   ------------------------------------------------------------------ */
.woocommerce-order-details,
.woocommerce-customer-details {
  max-width: 860px;
  margin: clamp(28px, 4vw, 44px) auto 0;
}
.woocommerce-order-details__title,
.woocommerce-column__title,
.woocommerce-customer-details h2 {
  font-family: var(--serif, 'Playfair Display', serif);
  font-size: 1.2rem;
  font-weight: 500;
  margin: 0 0 14px;
}

.woocommerce-table--order-details {
  width: 100%;
  border-collapse: collapse;
  font-size: .88rem;
  border: 1px solid var(--gris-linea, #E4DEE0);
  border-radius: 6px;
  overflow: hidden;
}
.woocommerce-table--order-details th,
.woocommerce-table--order-details td {
  padding: 14px 16px;
  text-align: left;
  border-bottom: 1px solid var(--gris-linea, #E4DEE0);
}
.woocommerce-table--order-details thead th {
  font-size: .72rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--gris, #7B7176);
  font-weight: 500;
  background: var(--hueso, #F4F1F2);
}
/* La columna del dinero, a la derecha y sin partirse */
.woocommerce-table--order-details td:last-child,
.woocommerce-table--order-details th:last-child { text-align: right; }
.woocommerce-table--order-details tfoot th { font-weight: 500; color: var(--gris, #7B7176); }
.woocommerce-table--order-details tfoot tr:last-child th,
.woocommerce-table--order-details tfoot tr:last-child td { font-weight: 600; color: var(--negro, #1A1A1A); }
.woocommerce-table--order-details tr:last-child td,
.woocommerce-table--order-details tr:last-child th { border-bottom: 0; }

/*
 * ⚠️ EL PRECIO NO SE PARTE EN DOS RENGLONES.
 *
 * `get_formatted_order_total()` envuelve el símbolo en su propio `<span>`, así
 * que en una celda angosta el navegador corta entre el «$» y la cifra: en la
 * pantalla de gracias el total salía como «$» arriba y «1,620» abajo. Se leyó
 * en la captura, no lo dijo ningún comprobador.
 */
.woocommerce-Price-amount { white-space: nowrap; }

.woocommerce-customer-details address {
  font-style: normal;
  font-size: .9rem;
  line-height: 1.75;
  color: var(--negro-suave, #3A3437);
  padding: 18px 20px;
  border: 1px solid var(--gris-linea, #E4DEE0);
  border-radius: 6px;
}
.woocommerce-customer-details .woocommerce-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 20px;
}

/* ------------------------------------------------------------------
   14 · El formulario de opinión

   ⚠️ TAMPOCO ESTÁ EN EL PROTOTIPO. Su botón «Escribir una opinión» apunta a
   `#`: la caja nunca se diseñó. Se vio cruda en la primera captura del sitio en
   vivo, en un paquete sin opiniones — WordPress puro en medio de la tienda.

   Se le da la ropa del resto de los formularios (`.f`, `.form-grid`, `.req`) en
   vez de inventar estilos nuevos. Cuando RV apruebe un diseño, se mide.
   ------------------------------------------------------------------ */
#respond-envoltorio {
  max-width: 640px;
  margin-inline: auto;
  padding: clamp(24px, 3vw, 36px);
  background: var(--blanco, #fff);
  border: 1px solid var(--gris-linea, #E4DEE0);
  border-radius: 6px;
}
.res-form textarea {
  width: 100%;
  font-family: var(--sans, 'Jost', sans-serif);
  font-size: .92rem;
  line-height: 1.6;
  padding: 12px 14px;
  border: 1px solid var(--gris-linea, #E4DEE0);
  border-radius: var(--radio, 2px);
  resize: vertical;
}
.res-form .form-grid { margin-top: 18px; }
.res-form .comment-form-cookies-consent { margin-top: 14px; }
.res-form .form-submit { margin-top: 22px; }

/*
 * Las estrellas que agrega WooCommerce. Su CSS vive en `woocommerce-general.css`,
 * que está quitado, así que salían como una fila de «★★★★★» de texto plano sin
 * poder distinguir cuál se está escogiendo.
 */
.comment-form-rating { margin-top: 4px; }
.comment-form-rating label { display: block; }
.comment-form-rating .stars { display: flex; gap: 4px; margin: 6px 0 0; }
.comment-form-rating .stars a {
  font-size: 0;
  width: 26px; height: 26px;
  display: grid; place-items: center;
  color: var(--gris-linea, #E4DEE0);
  transition: var(--trans, all .25s ease);
}
.comment-form-rating .stars a::before {
  content: "★";
  font-size: 22px;
  line-height: 1;
}
.comment-form-rating .stars:hover a::before,
.comment-form-rating .stars a.active::before,
.comment-form-rating .stars a.active ~ a::before { color: var(--gris-linea, #E4DEE0); }
.comment-form-rating .stars a:hover::before,
.comment-form-rating .stars a:hover ~ a::before { color: var(--gris-linea, #E4DEE0); }
.comment-form-rating .stars a.active::before { color: #E8B93C; }
.comment-form-rating .stars a:hover::before { color: #E8B93C; }
/* De izquierda a derecha: al pasar por la 4ª, se prenden las 4 primeras. */
.comment-form-rating .stars a { position: relative; }
.comment-form-rating .stars:has(a:hover) a::before { color: #E8B93C; }
.comment-form-rating .stars:has(a:hover) a:hover ~ a::before { color: var(--gris-linea, #E4DEE0); }

/* ------------------------------------------------------------------
   15 · Los filtros, ahora que son enlaces

   Eran `<label>` de adorno. Al volverlos `<a>` hay que devolverles la caja del
   prototipo: el CSS aprobado estiliza `.fopt` como etiqueta de formulario, no
   como enlace, así que heredaban el subrayado y el color de enlace.

   `.fopt--fijo` es «En existencia», que se enseña como dato y no se puede
   apagar: se le quita el cursor de mano para que no invite a picarlo.
   ------------------------------------------------------------------ */
a.fopt {
  text-decoration: none;
  color: var(--negro-suave, #3A3437);
}
a.fopt:hover { color: var(--magenta, #D6006E); }
a.fopt:hover .fbox { border-color: var(--magenta, #D6006E); }
a.fopt.fopt--on { color: var(--magenta, #D6006E); font-weight: 600; }
a.fopt.fopt--on .fbox {
  background: var(--magenta, #D6006E);
  border-color: var(--magenta, #D6006E);
  position: relative;
}
a.fopt.fopt--on .fbox::after {
  content: "";
  position: absolute;
  inset: 3px;
  background: #fff;
  clip-path: polygon(14% 47%, 0 60%, 40% 100%, 100% 22%, 86% 8%, 38% 70%);
}
.fopt--fijo { cursor: default; }

/* ------------------------------------------------------------------
   16 · El acordeón, ahora que es <details>

   Era `<button>` sin JavaScript: no abría, y tres de sus cuatro secciones no
   traían contenido. Con `<details>/<summary>` abre sin JavaScript, el navegador
   le pone su papel para lectores de pantalla y el contenido queda en el HTML —
   así Google lo lee y cuenta para la ficha.

   El `+` / `−` lo pone el CSS según `[open]`, para no tener que escribirlo en el
   marcado ni cambiarlo con JavaScript.
   ------------------------------------------------------------------ */
details.acc summary { cursor: pointer; list-style: none; }
details.acc summary::-webkit-details-marker { display: none; }
details.acc summary::marker { content: ""; }

/* El signo, a la derecha */
.acc__t span[aria-hidden]::after { content: "+"; }
details.acc[open] .acc__t span[aria-hidden]::after { content: "−"; }

.ficha-lista { list-style: none; margin: 0; padding: 0; }
.ficha-lista li {
  padding: 8px 0;
  border-bottom: 1px solid var(--gris-linea, #E4DEE0);
  font-size: .88rem;
  color: var(--negro-suave, #3A3437);
}
.ficha-lista li:last-child { border-bottom: 0; }
.ficha-lista b { font-weight: 600; color: var(--negro, #1A1A1A); }

.acc__c p + p { margin-top: 10px; }

/* ------------------------------------------------------------------
   17 · La lupa y el menú de móvil, ahora que son <details>

   Eran `<button>` de adorno en el encabezado de TODAS las páginas. Con
   `<details>` abren sin JavaScript.

   ⚠️ El `<summary>` tiene que heredar el tamaño y el color del icono que
   reemplaza, o el encabezado se descuadra en las quince páginas. Los valores
   son los de `.hdr__acc button` en el CSS aprobado.
   ------------------------------------------------------------------ */
.hdr__acc details { position: relative; display: flex; align-items: center; }
.hdr__acc details > summary {
  list-style: none;
  cursor: pointer;
  display: grid;
  place-items: center;
  line-height: 0;
  color: inherit;
}
.hdr__acc details > summary::-webkit-details-marker { display: none; }
.hdr__acc details > summary::marker { content: ""; }

/* El buscador: un panel que baja del encabezado */
.buscar__caja {
  position: absolute;
  top: calc(100% + 14px);
  right: 0;
  z-index: 60;
  display: flex;
  gap: 8px;
  padding: 14px;
  width: min(88vw, 420px);
  background: var(--blanco, #fff);
  border: 1px solid var(--gris-linea, #E4DEE0);
  border-radius: 6px;
  box-shadow: 0 12px 34px rgba(0, 0, 0, .10);
}
.buscar__caja input[type="search"] {
  flex: 1;
  min-width: 0;
  font-family: var(--sans, 'Jost', sans-serif);
  font-size: 16px;   /* ver el bloque 26: abajo de 16 el iPhone hace zoom */
  padding: 10px 12px;
  border: 1px solid var(--gris-linea, #E4DEE0);
  border-radius: var(--radio, 2px);
}
.buscar__caja .btn { white-space: nowrap; }

/* El menú de móvil */
.menu-movil__panel {
  position: absolute;
  top: calc(100% + 14px);
  left: 0;
  z-index: 60;
  display: grid;
  width: min(84vw, 320px);
  padding: 10px 0;
  background: var(--blanco, #fff);
  border: 1px solid var(--gris-linea, #E4DEE0);
  border-radius: 6px;
  box-shadow: 0 12px 34px rgba(0, 0, 0, .10);
}
.menu-movil__panel a {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 20px;
  font-size: .92rem;
  color: var(--negro-suave, #3A3437);
  transition: var(--trans, all .25s ease);
}
.menu-movil__panel a:hover { background: var(--hueso, #F4F1F2); color: var(--magenta, #D6006E); }
.menu-movil__panel em { font-style: normal; font-size: .78rem; color: var(--gris, #7B7176); }
.menu-movil__sep { display: block; height: 1px; margin: 8px 20px; background: var(--gris-linea, #E4DEE0); }

/*
 * En escritorio el menú de hamburguesa no va: ahí está la navegación completa.
 * `.hide-mov` era la clase del prototipo para lo contrario —esconder en móvil—
 * y la lupa la conserva.
 */
@media (min-width: 1001px) {
  .hdr__acc details.menu-movil { display: none; }
}

/* ------------------------------------------------------------------
   18 · El cupón del carrito

   No existía. El sitio anuncia el 10% por opinar en la portada y en las tres
   fichas, `rv-promos` lo genera y lo manda — y no había dónde escribirlo.

   Va cerrado: un campo de cupón abierto le recuerda a quien no tiene ninguno
   que existen, y se va a Google a buscar uno en vez de pagar.
   ------------------------------------------------------------------ */
.cart-cupon > summary {
  cursor: pointer;
  font-size: .86rem;
  color: var(--gris, #7B7176);
  text-decoration: underline;
  text-underline-offset: 3px;
  list-style: none;
}
.cart-cupon > summary::-webkit-details-marker { display: none; }
.cart-cupon > summary::marker { content: ""; }
.cart-cupon > summary:hover { color: var(--magenta, #D6006E); }
.cart-cupon__caja {
  display: flex;
  gap: 8px;
  margin-top: 12px;
  max-width: 420px;
}
.cart-cupon__caja input {
  flex: 1;
  min-width: 0;
  font-family: var(--sans, 'Jost', sans-serif);
  font-size: 16px;   /* ver el bloque 26: abajo de 16 el iPhone hace zoom */
  padding: 10px 12px;
  border: 1px solid var(--gris-linea, #E4DEE0);
  border-radius: var(--radio, 2px);
  text-transform: uppercase;
}

/* ------------------------------------------------------------------
   19 · El cajón de filtros en móvil

   ⚠️ MEDIDO: 1,084 px de encabezado y filtros ANTES del primer producto a
   390px de ancho. Quien entra al catálogo desde el teléfono ve puros filtros.

   En escritorio no cambia NADA: el cajón sólo existe abajo de 900px. Arriba, la
   barra lateral se queda como está y el botón «Filtros» no se pinta.
   ------------------------------------------------------------------ */
.cat-abrir,
.filtros__cab,
.cat-tapa,
.cat-cerrar,
.cat-ver { display: none; }

@media (max-width: 900px) {
  /* El botón que abre */
  .cat-abrir {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 12px 20px;
    margin-bottom: 20px;
    border: 1px solid var(--negro, #1A1A1A);
    border-radius: var(--radio, 2px);
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--negro, #1A1A1A);
  }
  .cat-abrir svg { width: 17px; height: 17px; stroke: currentColor; fill: none; stroke-width: 1.6; stroke-linecap: round; }
  .cat-abrir em {
    font-style: normal;
    display: grid;
    place-items: center;
    min-width: 20px; height: 20px;
    border-radius: 20px;
    background: var(--magenta, #D6006E);
    color: #fff;
    font-size: .68rem;
  }

  /*
   * El cajón. Cerrado por omisión y abierto con `:target`.
   *
   * `visibility:hidden` y no sólo `opacity`: con opacidad cero los enlaces de
   * adentro siguen recibiendo el foco del teclado, y quien navega con tabulador
   * se pierde dentro de un panel que no ve. `visibility` sí se hereda y un hijo
   * no la recupera solo.
   */
  .filtros {
    position: fixed;
    inset: 0;
    z-index: 130;              /* la burbuja de WhatsApp va en 95, el encabezado en 100 */
    display: flex;
    flex-direction: column;
    padding: 0;
    margin: 0;
    background: var(--blanco, #fff);
    overflow-y: auto;
    opacity: 0;
    visibility: hidden;
    transform: translateY(100%);
    transition: transform .25s ease, opacity .2s ease, visibility .2s;
  }
  .filtros:target {
    opacity: 1;
    visibility: visible;
    transform: none;
  }

  .filtros__cab {
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: sticky;
    top: 0;
    padding: 18px 22px;
    background: var(--blanco, #fff);
    border-bottom: 1px solid var(--gris-linea, #E4DEE0);
  }
  .filtros__cab b { font-size: .78rem; letter-spacing: .16em; text-transform: uppercase; }
  .cat-cerrar { display: block; font-size: 1.7rem; line-height: 1; color: var(--gris, #7B7176); padding: 0 6px; }

  .filtros .fgrupo { padding: 0 22px; }
  .filtros .fgrupo:first-of-type { padding-top: 18px; }

  /* El pie, pegado abajo */
  .cat-ver {
    display: block;
    position: sticky;
    bottom: 0;
    margin: 18px 22px 22px;
    width: auto;
  }

  /*
   * La tapa oscura va DENTRO del cajón, no como hermana: así no depende de un
   * selector de hermanos que se rompe el día que alguien mueva un div — y se
   * rompería sin avisar, porque no truena, sólo deja de cerrarse al tocar fuera.
   */
  .cat-tapa { display: block; position: fixed; inset: 0; z-index: -1; }
}

/* ==================================================================
   16 · LO QUE WOOCOMMERCE INYECTA EN EL CHECKOUT Y NADIE HABÍA VESTIDO
   ==================================================================

   ⚠️ EL PATRÓN QUE EXPLICA TODOS LOS HALLAZGOS DE ESTA SECCIÓN
   ------------------------------------------------------------------
   El CSS aprobado viste el marcado DEL PROTOTIPO: `.f input`, `.radio`,
   `.btn`. Los campos de facturación se ven bien porque hay un
   `checkout/form-billing.php` propio que usa esas clases.

   Pero WooCommerce inyecta marcado suyo que nunca pasa por esas plantillas:
   el textarea de referencias, los radios de envío y de pago, y el botón que
   cobra. Ésos llegaron DESNUDOS a producción y nadie lo notó porque el
   comparador visual sólo mira las páginas que ya tenían línea base, y el de
   controles comprueba que SIRVAN, no que se vean.

   Lo vio Fer: «el checkout algunas cosas se ven mal».

   Regla para lo que venga: cada vez que se conserve un hook de Woo —y se
   conservan todos, a propósito— hay que vestir lo que ese hook imprime.
   ------------------------------------------------------------------ */

/* ------------------------------------------------------------------
   16.1 · EL BOTÓN QUE COBRA
   ------------------------------------------------------------------
   ⚠️ ESTE ERA EL GRAVE. Medido en el DOM:

       #place_order → 123×26 px, fondo transparente, padding 0, borde none

   O sea que el único botón que completa la compra se veía como un renglón
   de texto suelto, alineado a la derecha, debajo del aviso de privacidad.
   En teléfono parecía un pie de foto.

   La causa: `functions.php` quita `woocommerce-general` —que es la hoja que
   estiliza `.button`— para que Woo no pelee con el diseño aprobado. Correcto.
   Lo que faltó fue reponer el botón, y es justo el que no se puede perder.

   Se le da la misma forma que al «Agregar al carrito» de la ficha, que es el
   botón principal del prototipo: negro, ancho completo, versalitas.
   ------------------------------------------------------------------ */
.woocommerce-checkout #place_order,
.woocommerce-checkout button[name="woocommerce_checkout_place_order"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin-top: 18px;
  padding: 18px 30px;
  border: 1px solid var(--negro, #1A1A1A);
  border-radius: var(--radio, 2px);
  background: var(--negro, #1A1A1A);
  color: var(--blanco, #fff);
  font-family: var(--sans, 'Jost', sans-serif);
  font-size: .74rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: var(--trans, all .25s ease);
  float: none;
}
.woocommerce-checkout #place_order:hover {
  background: var(--magenta, #D6006E);
  border-color: var(--magenta, #D6006E);
}
/* Mientras Woo valida, el botón se apaga solo. Que se note. */
.woocommerce-checkout.processing #place_order,
.woocommerce-checkout #place_order:disabled { opacity: .55; cursor: progress; }

/*
 * El aviso de privacidad va ARRIBA del botón y separado, no pegado.
 * Woo lo imprime justo antes y sin margen: se leía como parte del botón.
 */
.woocommerce-privacy-policy-text { margin-bottom: 6px; }

/* ------------------------------------------------------------------
   16.2 · LOS DOS AVISOS AZULES DE ARRIBA, DE LADO A LADO
   ------------------------------------------------------------------
   Medido: ancho 1440 px, borde izquierdo en 0 — el ancho COMPLETO de la
   ventana, mientras todo lo demás vive dentro de `.wrap`.

   La causa es de plantilla, no de CSS: `do_action( 'woocommerce_before_
   checkout_form' )` corre en la línea 16 de `form-checkout.php`, antes de que
   se abra la `<section class="wrap">`. Se resuelve allá metiéndolo en su
   propio `.wrap`; aquí sólo se les quita el aire de más y se les da la forma
   de la marca en vez de la caja azul de Woo.
   ------------------------------------------------------------------ */
.woocommerce-form-login-toggle,
.woocommerce-form-coupon-toggle { margin-bottom: 10px; }
.woocommerce-form-login-toggle .woocommerce-info,
.woocommerce-form-coupon-toggle .woocommerce-info { margin: 0; }

/* ------------------------------------------------------------------
   16.3 · LOS CAMPOS QUE NO PASAN POR `form-billing.php`
   ------------------------------------------------------------------
   El textarea de «Referencias» sale de los campos adicionales de Woo, con
   `<p class="form-row">` y `class="input-text"` — nunca entra en `.f`, así
   que salía con el borde gris del navegador (118,118,118), esquinas cuadradas
   y padding 0, al lado de campos con borde (228,223,221) y radio 2px.

   Se viste `.form-row` con los MISMOS valores de `.f input` en styles.css.
   Si aquéllos cambian, éstos hay que moverlos: son el mismo campo a los ojos
   de quien compra.
   ------------------------------------------------------------------ */
.woocommerce-checkout .form-row { margin: 0 0 16px; }
.woocommerce-checkout .form-row > label {
  display: block;
  font-size: .68rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  font-weight: 700;
  margin-bottom: 7px;
  color: var(--negro-suave, #2A2A2A);
}
.woocommerce-checkout .form-row .input-text,
.woocommerce-checkout .form-row select,
.woocommerce-checkout textarea.input-text {
  width: 100%;
  border: 1px solid var(--gris-linea, #E4DEE0);
  padding: 13px 15px;
  background: var(--blanco, #fff);
  border-radius: var(--radio, 2px);
  font-family: inherit;
  font-size: .92rem;
  transition: var(--trans, all .25s ease);
}
.woocommerce-checkout .form-row .input-text:focus,
.woocommerce-checkout .form-row select:focus,
.woocommerce-checkout textarea.input-text:focus {
  outline: none;
  border-color: var(--magenta, #D6006E);
}
.woocommerce-checkout textarea.input-text { min-height: 92px; resize: vertical; }
.woocommerce-checkout .form-row .input-text::placeholder { color: #B8B1B3; }
/* El asterisco de obligatorio, en el magenta de la marca y sin subrayado. */
.woocommerce-checkout .required { color: var(--magenta, #D6006E); text-decoration: none; border: 0; }

/* ------------------------------------------------------------------
   16.4 · LAS CASILLAS, CON AIRE
   ------------------------------------------------------------------
   «¿Enviar a una dirección diferente?» y «Necesito factura (CFDI)» salían
   pegadas a su texto y con la tipografía de título, encimadas con el campo
   de abajo. Son casillas, no encabezados.
   ------------------------------------------------------------------ */
.woocommerce-checkout .woocommerce-shipping-fields > h3,
.woocommerce-checkout #ship-to-different-address {
  margin: 26px 0 14px;
  font-size: .82rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}
.woocommerce-checkout #ship-to-different-address label,
.woocommerce-checkout .form-row.rv-casilla label {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--sans, 'Jost', sans-serif);
  cursor: pointer;
}
.woocommerce-checkout input[type="checkbox"],
.woocommerce-checkout input[type="radio"] {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  accent-color: var(--magenta, #D6006E);
  margin: 0;
  cursor: pointer;
}

/* ------------------------------------------------------------------
   16.5 · LOS RADIOS DE ENVÍO Y DE PAGO
   ------------------------------------------------------------------
   El prototipo los dibuja como tarjetas (`.radio` en styles.css). Woo los
   imprime como `<ul>` con radios crudos del navegador, pegados al texto y sin
   separación entre opciones — se leían como una lista de viñetas rota.

   Se les da la forma de `.radio` sin tocar el marcado, que es lo que mantiene
   viva la pasarela: Mercado Pago se engancha a estos `<li>` por su id.
   ------------------------------------------------------------------ */
.woocommerce-checkout ul.woocommerce-shipping-methods,
.woocommerce-checkout ul.wc_payment_methods {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 11px;
}
.woocommerce-checkout ul.woocommerce-shipping-methods > li,
.woocommerce-checkout ul.wc_payment_methods > li.wc_payment_method {
  list-style: none;
  border: 1px solid var(--gris-linea, #E4DEE0);
  background: var(--blanco, #fff);
  padding: 16px 18px;
  transition: var(--trans, all .25s ease);
}
.woocommerce-checkout ul.woocommerce-shipping-methods > li:hover,
.woocommerce-checkout ul.wc_payment_methods > li.wc_payment_method:hover {
  border-color: var(--negro, #1A1A1A);
}
.woocommerce-checkout ul.woocommerce-shipping-methods > li label,
.woocommerce-checkout ul.wc_payment_methods > li label {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: .9rem;
  cursor: pointer;
  margin: 0;
}
/*
 * La descripción de la pasarela —«Te enviamos la CLABE por correo»— salía
 * suelta y pegada al margen izquierdo, como si fuera otro renglón del
 * formulario. Va sangrada bajo su opción, que es a lo que pertenece.
 */
.woocommerce-checkout ul.wc_payment_methods .payment_box {
  margin: 10px 0 0 29px;
  padding: 12px 14px;
  background: var(--hueso, #F7F4F2);
  border-radius: var(--radio, 2px);
  font-size: .84rem;
  line-height: 1.55;
  color: var(--negro-suave, #2A2A2A);
}
.woocommerce-checkout ul.wc_payment_methods .payment_box p:last-child { margin-bottom: 0; }
/* La opción elegida, marcada — como `.radio--on` del prototipo. */
.woocommerce-checkout ul.wc_payment_methods > li.wc_payment_method:has(input:checked),
.woocommerce-checkout ul.woocommerce-shipping-methods > li:has(input:checked) {
  border-color: var(--magenta, #D6006E);
  background: var(--magenta-luz, #FDF0F6);
}
/*
 * El título suelto «Envío» que Woo imprime sobre los métodos. El bloque ya
 * tiene su encabezado «MÉTODO DE ENVÍO» en la plantilla: repetirlo es ruido.
 */
.woocommerce-checkout .radio-lista .shipping__list__label,
.woocommerce-checkout .radio-lista th { display: none; }

/* ------------------------------------------------------------------
   16.6 · EN TELÉFONO, EL RESUMEN VA ARRIBA
   ------------------------------------------------------------------
   ⚠️ HALLAZGO DE MÓVIL, NO DE ESCRITORIO.

   `.ck-lay` es una retícula de dos columnas; en teléfono se apila y el
   resumen —que es la segunda columna— cae HASTA ABAJO, después del aviso de
   zona. Medido: el total quedaba en el píxel 2,900 de una página de 3,383.

   O sea que en un teléfono llenas quince campos, eliges envío y eliges pago
   sin haber visto nunca cuánto vas a pagar. Es el orden inverso al de
   cualquier tienda, y es exactamente donde se abandonan los carritos.

   `order` lo sube sin tocar el HTML ni el escritorio.
   ------------------------------------------------------------------ */
@media (max-width: 900px) {
  .ck-lay { display: flex; flex-direction: column; }
  .ck-lay > .ck-res { order: -1; margin-bottom: 26px; }
}

/* ==================================================================
   17 · EL CARRITO LATERAL
   ==================================================================
   Abre con `:target`, igual que el cajón de filtros del catálogo. Sin
   JavaScript: el icono del encabezado es un enlace a `#carrito-lateral` y,
   después de agregar, la redirección trae esa ancla puesta.

   Ver `template-parts/carrito-lateral.php` para el porqué.
   ================================================================== */
.sidecart {
  position: fixed;
  inset: 0;
  z-index: 120;
  /*
   * Cerrado se apaga con `visibility`, no sólo con opacidad: con
   * `opacity:0` a secas el panel sigue estando ahí y se traga los clics de
   * media pantalla. Es el bug clásico de los paneles que "no se ven" pero
   * dejan la página muerta al tacto.
   */
  visibility: hidden;
  opacity: 0;
  transition: opacity .25s ease, visibility 0s linear .25s;
}
/*
 * Dos maneras de estar abierto, y hacen falta las dos.
 *
 * `:target` es el camino sin JavaScript. `.rv-abierto` la pone `carrito.js`,
 * y es la que manda cuando hay JavaScript: `wc-cart-fragments` SUSTITUYE este
 * elemento al refrescar el carrito, y al sustituirlo el navegador ya no le
 * aplica `:target` al nuevo aunque tenga el mismo id. Ver el comentario largo
 * de `assets/js/carrito.js`.
 */
.sidecart:target,
.sidecart.rv-abierto { visibility: visible; opacity: 1; transition-delay: 0s; }

.sidecart__tapa {
  position: absolute;
  inset: 0;
  background: rgba(26, 26, 26, .42);
  display: block;
}

.sidecart__panel {
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  width: min(400px, 100vw);
  display: flex;
  flex-direction: column;
  background: var(--blanco, #fff);
  box-shadow: -8px 0 34px rgba(0, 0, 0, .13);
  transform: translateX(100%);
  transition: transform .28s cubic-bezier(.4, 0, .2, 1);
}
.sidecart:target .sidecart__panel,
.sidecart.rv-abierto .sidecart__panel { transform: translateX(0); }

.sidecart__cab {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 20px 22px;
  border-bottom: 1px solid var(--gris-linea, #E4DEE0);
}
.sidecart__cab b { font-size: .74rem; letter-spacing: .15em; text-transform: uppercase; }
.sidecart__x { font-size: 1.7rem; line-height: 1; color: var(--gris, #7B7176); padding: 0 4px; }
.sidecart__x:hover { color: var(--negro, #1A1A1A); }

/* Las líneas: lo único que crece, así que es lo único que se desplaza. */
.sidecart__lineas { flex: 1; overflow-y: auto; padding: 6px 22px; }

.sidecart__linea {
  display: grid;
  grid-template-columns: 56px 1fr auto auto;
  gap: 12px;
  align-items: center;
  padding: 15px 0;
  border-bottom: 1px solid var(--gris-linea, #E4DEE0);
}
.sidecart__linea:last-child { border-bottom: 0; }
.sidecart__foto img { width: 56px; height: 56px; object-fit: cover; border-radius: var(--radio, 2px); display: block; }
.sidecart__nom { display: block; font-size: .86rem; font-weight: 600; line-height: 1.3; }
.sidecart__nom:hover { color: var(--magenta, #D6006E); }
.sidecart__uni { display: block; font-size: .76rem; color: var(--gris, #7B7176); margin-top: 3px; }
.sidecart__imp { font-size: .86rem; white-space: nowrap; }
.sidecart__quitar { font-size: 1.15rem; line-height: 1; color: #B8B1B3; padding: 0 2px; }
.sidecart__quitar:hover { color: var(--magenta, #D6006E); }

.sidecart__pie {
  border-top: 1px solid var(--gris-linea, #E4DEE0);
  padding: 18px 22px 22px;
  background: var(--hueso, #F7F4F2);
}
/* El empujón al siguiente escalón — la razón de ser de esta tienda. */
.sidecart__meta {
  font-size: .78rem;
  color: #7A5400;
  background: #FFF8EC;
  border: 1px solid #F0DDB8;
  border-radius: var(--radio, 2px);
  padding: 9px 12px;
  margin-bottom: 14px;
}
.sidecart__tot { display: flex; justify-content: space-between; align-items: baseline; }
.sidecart__tot span { font-size: .78rem; letter-spacing: .14em; text-transform: uppercase; }
.sidecart__tot b { font-size: 1.15rem; }
.sidecart__nota { font-size: .74rem; color: var(--gris, #7B7176); margin: 3px 0 14px; }
/*
 * El segundo botón del pie, no un enlace escondido.
 * Ver el comentario de `template-parts/carrito-lateral.php`.
 */
.sidecart__ver { margin-top: 10px; }
/* Los dos botones del pie, del mismo alto: si no, el de abajo se lee como
   secundario de adorno en vez de secundario de verdad. */
.sidecart__pie .btn { padding-block: 15px; }

.sidecart__vacio { flex: 1; display: grid; place-content: center; text-align: center; gap: 16px; padding: 30px 26px; }
.sidecart__vacio p { color: var(--gris, #7B7176); }

/*
 * Quien pidió que no le muevan la pantalla, no se la movemos.
 * (El panel entra de golpe en vez de deslizarse.)
 */
@media (prefers-reduced-motion: reduce) {
  .sidecart, .sidecart__panel { transition: none; }
}

/* ==================================================================
   18 · LOS AVISOS, EN SU SITIO
   ==================================================================
   `.woocommerce-notices-wrapper` lo mete WooCommerce solo, colgado
   directamente de <main> y sin retícula: medido en 1440 px de ancho con el
   borde izquierdo en 0, cruzando la pantalla de lado a lado mientras el resto
   del contenido vive dentro de `.wrap`.
   ================================================================== */
main > .woocommerce > .woocommerce-notices-wrapper,
main > .woocommerce-notices-wrapper {
  max-width: var(--max, 1300px);
  margin-inline: auto;
  padding-inline: var(--gutter, 24px);
}
.rv-avisos:empty, .rv-avisos-checkout:empty { display: none; }

/* ==================================================================
   19 · LA FOTO EN GRANDE (el zoom que no existía)
   ==================================================================
   Con `:target`, igual que el carrito lateral. Sin JavaScript.
   Ver el comentario largo de `woocommerce/single-product.php`.
   ================================================================== */

/* Con una sola foto no hay tira de miniaturas: la foto toma la columna. */
.pdp__gal--sola { grid-template-columns: 1fr; }

/* La foto grande es un enlace; que se note que se puede abrir. */
.pdp__lupa { position: relative; display: block; }
.pdp__lupa-ico {
  position: absolute;
  right: 14px;
  bottom: 14px;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, .93);
  color: var(--negro, #1A1A1A);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .14);
  transition: var(--trans, all .25s ease);
}
.pdp__lupa:hover .pdp__lupa-ico { background: var(--negro, #1A1A1A); color: #fff; }

.rv-visor {
  position: fixed;
  inset: 0;
  z-index: 130;
  display: grid;
  place-items: center;
  padding: 34px;
  /* Igual que el carrito lateral: `visibility`, no sólo opacidad, o la capa
     apagada se traga los clics de toda la ficha. */
  visibility: hidden;
  opacity: 0;
  transition: opacity .2s ease, visibility 0s linear .2s;
}
.rv-visor:target { visibility: visible; opacity: 1; transition-delay: 0s; }
.rv-visor__tapa { position: absolute; inset: 0; background: rgba(26, 26, 26, .9); }
/* ═══════════════════════════════════════════════════════════════════════════
   8 · EL ZOOM QUE NO AMPLIABA
   ═══════════════════════════════════════════════════════════════════════════
   Fer: «las imágenes de single product no me dejan hacer zoom». Y era cierto,
   aunque el visor SÍ abría — por eso mi primer comprobador lo dio por bueno:
   preguntaba «¿abrió la ventana?» en vez de «¿se ve más grande?».

   Medido en producción antes de tocar nada:

       en la ficha:  600 px de ancho
       en el visor:  527 px          ⇒ 0.88x

   O sea que picar la foto para «ampliarla» la dejaba MÁS CHICA que en la
   página. La culpa era de `max-height: 88vh` con `object-fit: contain`: la
   foto es vertical (931 × 1400), así que la ventana la ajustaba por el ALTO y
   el ancho salía sobrando.

   ⚠️ La lección para el arnés: «se abrió el visor» no es «hace zoom». Medir
   que algo aparezca no es medir que sirva.

   Ahora el visor abre encajado y un clic más lo lleva a tamaño real, con
   arrastre para pasear la foto. El JS vive en `assets/js/zoom.js`.
   ═══════════════════════════════════════════════════════════════════════════ */
.rv-visor__lienzo {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: auto;
  display: grid;
  place-items: center;
  /* En el teléfono esto es lo que deja pellizcar para acercar: sin
     `touch-action: pinch-zoom` el navegador se queda con el gesto y el visor
     no responde. */
  touch-action: pinch-zoom;
  overscroll-behavior: contain;
  scrollbar-width: none;
}
.rv-visor__lienzo::-webkit-scrollbar { display: none; }

.rv-visor img {
  position: relative;
  display: block;
  max-width: min(1100px, 92vw);
  max-height: 88vh;
  width: auto;
  object-fit: contain;
  cursor: zoom-in;
  transition: none;
}

/* Con zoom: la foto se sale del encaje y se pasea arrastrando. */
.rv-visor.rv-visor--zoom img {
  max-width: none;
  max-height: none;
  width: auto;
  height: auto;
  cursor: grab;
}
.rv-visor.rv-visor--zoom.rv-visor--arrastrando img { cursor: grabbing; }

/* La pista de que se puede ampliar. Sin esto nadie descubre el zoom: una foto
   que se puede agrandar y no lo dice es una foto que nadie agranda. */
.rv-visor__pista {
  position: absolute; left: 50%; bottom: 22px; transform: translateX(-50%);
  z-index: 4; pointer-events: none;
  background: rgba(255,255,255,.92); color: #1A1A1A;
  padding: 7px 14px; border-radius: 20px;
  /* .78rem = 12.5 px. Lo puse en .68rem (10.88) y el arnés lo marcó: es el
     mismo piso de 12 px que se acaba de imponer en toda la tienda. Un aviso que
     enseña cómo usar el zoom, ilegible, no enseña nada. */
  font-size: .78rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  transition: opacity .25s ease;
}
.rv-visor--zoom .rv-visor__pista { opacity: 0; }
.rv-visor__x,
.rv-visor__ant,
.rv-visor__sig {
  position: absolute;
  color: #fff;
  line-height: 1;
  display: grid;
  place-items: center;
  transition: var(--trans, all .25s ease);
}
.rv-visor__x { top: 18px; right: 22px; font-size: 2.3rem; width: 44px; height: 44px; }
.rv-visor__ant, .rv-visor__sig { top: 50%; transform: translateY(-50%); font-size: 3rem; width: 54px; height: 54px; }
.rv-visor__ant { left: 10px; }
.rv-visor__sig { right: 10px; }
.rv-visor__x:hover, .rv-visor__ant:hover, .rv-visor__sig:hover { color: var(--magenta, #D6006E); }

@media (max-width: 520px) {
  .rv-visor { padding: 14px; }
  .rv-visor__ant, .rv-visor__sig { font-size: 2.2rem; width: 42px; height: 42px; }
}
@media (prefers-reduced-motion: reduce) { .rv-visor { transition: none; } }

/* ==================================================================
   20 · LA CAJA DE BÚSQUEDA DE LA PÁGINA DE RESULTADOS
   ==================================================================
   Va en la página, no sólo en el encabezado: quien no encontró lo que buscaba
   tiene que poder corregir el término SIN volver a abrir la lupa de arriba.
   ================================================================== */
.cat-busca { display: flex; gap: 8px; max-width: 460px; margin-top: 18px; }
.cat-busca input[type="search"] {
  flex: 1;
  border: 1px solid var(--gris-linea, #E4DEE0);
  padding: 12px 15px;
  background: var(--blanco, #fff);
  border-radius: var(--radio, 2px);
  font-family: inherit;
  font-size: .9rem;
}
.cat-busca input[type="search"]:focus { outline: none; border-color: var(--magenta, #D6006E); }

/* ==================================================================
   21 · EL CARRITO MIENTRAS SE ACTUALIZA
   ==================================================================
   Medio segundo en el que los números todavía son los de antes. Si no se
   marca, la clienta pica «+» dos veces creyendo que no pasó nada — que es
   justo el problema que el AJAX viene a resolver.

   Se atenúa y se bloquea el ratón, pero NO se esconde: ver un total
   desvanecido un instante se lee como «está calculando»; ver un hueco se lee
   como que se rompió.
   ================================================================== */
.cart-lay { transition: opacity .18s ease; }
.cart-lay--cargando { opacity: .45; pointer-events: none; }

/*
 * Quien pidió que no le muevan la pantalla no ve el desvanecido; el bloqueo
 * del ratón se queda, porque ése no es decoración: evita dobles envíos.
 */
@media (prefers-reduced-motion: reduce) {
  .cart-lay { transition: none; }
  .cart-lay--cargando { opacity: 1; }
}

/* ------------------------------------------------------------------
   21.1 · `hidden` TIENE QUE GANARLE A `.btn`
   ------------------------------------------------------------------
   ⚠️ `elemento.hidden = true` NO ALCANZA CUANDO EL CSS DECLARA `display`.

   `carrito-ajax.js` esconde el botón «Actualizar carrito» con la propiedad
   `hidden`, que se apoya en la regla del navegador `[hidden]{display:none}`.
   Pero esa regla es de la hoja del navegador y pierde contra CUALQUIER regla
   del tema: `.btn` declara `display:inline-flex`, así que el botón quedaba
   marcado como oculto y se seguía viendo.

   Costó una vuelta de diagnóstico: leyendo el DOM, `hidden` salía `true` y
   parecía correcto; el arnés —que mide VISIBILIDAD real, no el atributo—
   decía que seguía a la vista. El arnés tenía razón.

   Es la misma lección que `:target` con `replaceWith`: la propiedad puesta no
   es lo mismo que el efecto conseguido. Lo que cuenta es lo que se ve.
   ------------------------------------------------------------------ */
.woocommerce-cart-form [name="update_cart"][hidden] { display: none; }

/* ==================================================================
   22 · LO QUE SE TOCA CON EL PULGAR MIDE 44 px
   ==================================================================

   ⚠️ LOS TRES CONTROLES DEL ENCABEZADO MEDÍAN 22×22 px EN EL TELÉFONO.

   El menú, la lupa y el carrito: los tres más usados del sitio, en TODAS las
   páginas, y en el aparato desde el que se compra. 22 px es la mitad de los 44
   que recomienda Apple y menos de la mitad de la yema de un pulgar. Se falla el
   toque, se pica otra cosa, y el que se equivoca cree que el sitio va mal.

   ⚠️ SE AGRANDA EL ÁREA, NO EL ICONO.

   El icono se queda en 22 px, que es el diseño aprobado. Lo que crece es la
   zona sensible, con `padding` — así el sitio se ve idéntico y se toca bien. Al
   revés, agrandando el dibujo, se cambiaría el diseño para arreglar un problema
   de ergonomía.

   Y el margen negativo compensa el padding para que el encabezado no se estire:
   el diseño aprobado tiene su altura y esto no la puede mover.

   ⚠️ `pointer: coarse`, NO un ancho de pantalla.

   Es la lección de Dielec: el tamaño táctil atado al ANCHO dejaba una tableta
   —810 px, cruza el corte de `md:`— con enlaces de 28 px en una pantalla que se
   toca con el dedo. La medida no es el ancho, es el puntero.

   ────────────────────────────────────────────────────────────────────
   LO QUE **NO** SE TOCA, y por qué:

   · `.link-sub` («Solicitar condiciones →», «Abrir WhatsApp →») — son enlaces
     de texto DENTRO de un párrafo. Agrandarlos partiría el renglón.
   · `h3.paq__nom > a` (el nombre del paquete) y `@rveyelashesmx` — enlaces
     dentro de un título, y la tarjeta entera ya es clicable.
   · Los textos de 9 a 11 px (`eyebrow`, `paq__cinta`, `look__tag`, `badge`) —
     son las versalitas con letterspacing del diseño aprobado, no descuido.

   Medir sin mirar habría reportado 63 «hallazgos» en la portada. Mirando, es
   uno.
   ================================================================== */
@media (pointer: coarse) {
  .hdr__acc .menu-btn,
  .hdr__acc details.buscar > summary,
  .hdr__acc .carrito-btn {
    /*
     * `border-box` y no `content-box`: con content-box el mínimo se SUMA al
     * padding y los tres botones salieron de 66×66 —más grandes de lo que
     * hace falta, empujándose entre ellos—. Medido antes de dejarlo.
     */
    box-sizing: border-box;
    padding: 11px;
    /*
     * ⚠️ EL MARGEN NEGATIVO SÓLO ARRIBA Y ABAJO.
     *
     * Con `margin: -11px` a los cuatro lados los tres botones se ENCIMABAN: el
     * `gap` del encabezado es de 18 px y los márgenes se comían 22, así que las
     * zonas sensibles se traslapaban 4 px. Tocar entre dos abría el de al lado
     * — el mismo problema que esto vino a arreglar, entrando por otra puerta.
     * Lo cazó una prueba que TOCA la esquina de cada uno.
     *
     * En vertical sí se compensa, para que el encabezado no crezca de alto.
     * En horizontal no: tres zonas de 44 px necesitan 44 px cada una, y en un
     * teléfono de 390 sobran. Los iconos quedan un poco más separados al tacto,
     * y con ratón no cambia nada.
     */
    margin: -11px 0;
    min-width: 44px;
    min-height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  /*
   * La insignia va pegada al icono, no al área nueva: con el padding de por
   * medio se despegaría del carrito y quedaría flotando en el aire.
   */
  .hdr__acc .carrito-btn .carrito-num { top: 8px; right: 6px; }
}

/*
 * Los chips de «Otros modelos de esta línea», a 44 px al tacto.
 *
 * Medían 50×42: dos píxeles por debajo, y son once juntos en la ficha —donde la
 * clienta escoge modelo—. Once blancos chicos pegados uno a otro es donde más
 * se falla el toque.
 *
 * Sólo al tacto, para no mover el diseño aprobado en escritorio.
 */
@media (pointer: coarse) {
  .pdp__info .opciones .opt { min-height: 44px; display: inline-flex; align-items: center; }

  /* El enlace a Instagram del encabezado del bloque: 142×26 → 44 de alto. */
  .ig-cab > a { min-height: 44px; display: inline-flex; align-items: center; }
}

/*
 * ────────────────────────────────────────────────────────────────────
 * LO QUE SE MIDIÓ, SE MIRÓ Y **NO** SE TOCÓ
 * ────────────────────────────────────────────────────────────────────
 * «Proveedor de maquilladores en México» sale a 11.52 px en el bloque de datos
 * de marca de la portada (`.marca-datos .dato span`). Es una frase completa, no
 * una versalita de una palabra, así que el arnés la reporta con razón.
 *
 * NO se cambia: es el diseño aprobado, y subirle el tamaño movería el bloque
 * entero. Queda anotado para que lo decida Fer — la diferencia entre un
 * hallazgo y una alarma es que el hallazgo dice quién decide.
 * ────────────────────────────────────────────────────────────────────
 */

/* ==================================================================
   23 · LO QUE FER VIO EN EL CHECKOUT
   ================================================================== */

/* ------------------------------------------------------------------
   23.1 · LOS CAMPOS DE FACTURA, ESCONDIDOS HASTA QUE SE PIDEN
   ------------------------------------------------------------------
   La casilla «Necesito factura (CFDI)» no escondía nada: los campos salían
   desplegados para todo el mundo. La mayoría de las clientas de RV no
   factura, y cinco campos de más en la pantalla de pago es de las cosas que
   hacen que alguien la deje a medias.

   ⚠️ SIN JAVASCRIPT. `:has()` lo resuelve en CSS y funciona en todos los
   navegadores actuales — es el mismo criterio del resto del tema, donde los
   paneles abren con `:target` y los acordeones con `<details>`.

   El navegador que no entienda `:has()` los deja SIEMPRE VISIBLES, que es como
   estaban antes: se degrada a lo de hoy, nunca a un formulario roto.
   ------------------------------------------------------------------ */
.rv-cfdi .rv-cfdi-campos {
  display: grid;
  margin-top: 18px;
}
@supports selector(:has(*)) {
  .rv-cfdi:not(:has(#rv_cfdi:checked)) .rv-cfdi-campos { display: none; }
}
.rv-cfdi-nota {
  font-size: .82rem;
  line-height: 1.55;
  color: #7A5400;
  background: #FFF8EC;
  border: 1px solid #F0DDB8;
  border-radius: var(--radio, 2px);
  padding: 10px 13px;
  margin: 0 0 4px;
}

/* ------------------------------------------------------------------
   23.2 · EL DESPLEGABLE DE «ESTADO»
   ------------------------------------------------------------------
   ⚠️ SE VEÍA MAL PORQUE NO ES UN `<select>`.

   WooCommerce le pone Select2 al campo de Estado: el `<select>` de verdad
   queda de **1×1 px** —medido— y lo que se ve es un `<span class="select2">`
   que construye su propio marcado y NO hereda nada del diseño del tema. Por
   eso desentonaba con los campos de al lado.

   Se viste el `<span>` con los mismos valores que `.f input`: mismo borde,
   mismo alto, mismo radio, mismo magenta al enfocar. Y el desplegable que se
   abre también, que es la mitad que nadie estiliza.
   ------------------------------------------------------------------ */
.woocommerce-checkout .select2-container { width: 100% !important; }
.woocommerce-checkout .select2-container--default .select2-selection--single {
  height: auto;
  /*
   * 52 px y no 47: es el alto exacto de `.f input` (13 px de relleno arriba y
   * abajo más el renglón). Medido lado a lado — con 47 el Estado quedaba cinco
   * píxeles más bajo que Ciudad, que es justo el desajuste que se veía.
   */
  min-height: 52px;
  border: 1px solid var(--gris-linea, #E4DEE0);
  border-radius: var(--radio, 2px);
  background: var(--blanco, #fff);
  display: flex;
  align-items: center;
  padding: 0 15px;
  transition: var(--trans, all .25s ease);
}
.woocommerce-checkout .select2-container--default .select2-selection--single .select2-selection__rendered {
  line-height: 1.4;
  padding: 0;
  color: var(--negro, #1A1A1A);
  font-size: .92rem;
}
.woocommerce-checkout .select2-container--default .select2-selection--single .select2-selection__placeholder { color: #B8B1B3; }
.woocommerce-checkout .select2-container--default .select2-selection--single .select2-selection__arrow {
  height: 100%;
  right: 12px;
}
/* Enfocado y abierto, en el magenta de la marca — no en el azul del navegador. */
.woocommerce-checkout .select2-container--default.select2-container--focus .select2-selection--single,
.woocommerce-checkout .select2-container--default.select2-container--open .select2-selection--single {
  border-color: var(--magenta, #D6006E);
}
/* La lista que baja: vive fuera del formulario, colgada del <body>. */
.select2-dropdown {
  border-color: var(--gris-linea, #E4DEE0);
  border-radius: var(--radio, 2px);
  box-shadow: 0 8px 26px rgba(0, 0, 0, .1);
}
.select2-container--default .select2-search--dropdown .select2-search__field {
  border: 1px solid var(--gris-linea, #E4DEE0);
  border-radius: var(--radio, 2px);
  padding: 9px 11px;
}
.select2-container--default .select2-results__option--highlighted[aria-selected] {
  background: var(--magenta, #D6006E);
}
.select2-container--default .select2-results__option { padding: 9px 14px; font-size: .9rem; }

/* Nuestros propios `<select>` (régimen, uso del CFDI): sin Select2 de por medio. */
.woocommerce-checkout select.rv-select {
  min-height: 52px;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 4.5l4 4 4-4' fill='none' stroke='%231A1A1A' stroke-width='1.3'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 12px;
  padding-right: 36px;
}

/* ------------------------------------------------------------------
   23.3 · LA CAJA ENTERA SE PICA, NO SÓLO EL PUNTITO
   ------------------------------------------------------------------
   ⚠️ ERAN DOS PROBLEMAS EN UNO, Y FER LOS VIO JUNTOS.

   1 · El círculo iba PEGADO al texto, sin aire.
   2 · Y sólo el círculo y las palabras respondían: el resto de la tarjeta
       —que mide todo el ancho— no hacía nada. Se pica al lado del texto,
       parece que la opción no se puede elegir, y en un teléfono eso es la
       mitad de los intentos.

   La caja entera se vuelve la etiqueta: el `<label>` ocupa todo el `<li>`, así
   que cualquier punto de la tarjeta elige la opción.
   ------------------------------------------------------------------ */
.woocommerce-checkout ul.woocommerce-shipping-methods > li,
.woocommerce-checkout ul.wc_payment_methods > li.wc_payment_method {
  padding: 0;                     /* el aire lo pone la etiqueta, que es la que se pica */
  cursor: pointer;
}
.woocommerce-checkout ul.woocommerce-shipping-methods > li > label,
.woocommerce-checkout ul.wc_payment_methods > li > label {
  display: flex;
  align-items: center;
  gap: 14px;                      /* el aire que faltaba entre el círculo y el texto */
  width: 100%;
  padding: 16px 18px;
  margin: 0;
  cursor: pointer;
}
/*
 * Los radios de Woo van ANTES del label, fuera de él. Se meten dentro del área
 * de la etiqueta con un desplazamiento, para que la caja entera sea una sola
 * zona clicable y no dos pedazos pegados.
 */
.woocommerce-checkout ul.woocommerce-shipping-methods > li > input[type="radio"],
.woocommerce-checkout ul.wc_payment_methods > li > input[type="radio"] {
  position: absolute;
  margin: 18px 0 0 18px;
  z-index: 1;
}
.woocommerce-checkout ul.woocommerce-shipping-methods > li,
.woocommerce-checkout ul.wc_payment_methods > li.wc_payment_method { position: relative; }
.woocommerce-checkout ul.woocommerce-shipping-methods > li > label,
.woocommerce-checkout ul.wc_payment_methods > li > label { padding-left: 49px; }
/* Y el foco del teclado se ve en la caja, no en el puntito de 13 px. */
.woocommerce-checkout ul.woocommerce-shipping-methods > li:focus-within,
.woocommerce-checkout ul.wc_payment_methods > li.wc_payment_method:focus-within {
  border-color: var(--magenta, #D6006E);
  box-shadow: 0 0 0 3px var(--magenta-luz, #FDF0F6);
}
/* La descripción de la pasarela se alinea con el texto, no con el radio. */
.woocommerce-checkout ul.wc_payment_methods .payment_box { margin: 0 18px 16px 49px; }

/* ------------------------------------------------------------------
   23.4 · LAS DIRECCIONES DE LA PANTALLA DE GRACIAS
   ------------------------------------------------------------------
   Salían como dos `<address>` de fábrica: una columna angosta con cada dato en
   su propio renglón —«Prueba Ad / Center / Blvd. Lola / Beltrán 4050»— porque
   el ancho no daba y el texto se partía a media palabra.

   Se les da el ancho y la forma de las cajas del resto del sitio.
   ------------------------------------------------------------------ */
.woocommerce-order .woocommerce-columns--addresses {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 20px;
  margin-top: clamp(28px, 4vw, 44px);
}
.woocommerce-order .woocommerce-columns--addresses .woocommerce-column { width: auto; float: none; }
.woocommerce-order .woocommerce-columns--addresses h2 {
  font-size: .74rem;
  letter-spacing: .15em;
  text-transform: uppercase;
  font-weight: 700;
  font-family: var(--sans, 'Jost', sans-serif);
  padding-bottom: 12px;
  border-bottom: 1px solid var(--gris-linea, #E4DEE0);
  margin-bottom: 14px;
}
.woocommerce-order .woocommerce-columns--addresses address {
  font-style: normal;
  border: 0;
  padding: 0;
  line-height: 1.7;
  font-size: .92rem;
  color: var(--negro-suave, #2A2A2A);
}
.woocommerce-order .woocommerce-columns--addresses address .woocommerce-customer-details--phone,
.woocommerce-order .woocommerce-columns--addresses address .woocommerce-customer-details--email {
  margin: 6px 0 0;
  font-size: .86rem;
}

/* ==================================================================
   24 · EL EMERGENTE PARA ESCRIBIR UNA OPINIÓN
   ==================================================================
   Monta sobre `.rv-visor`, el mismo emergente del zoom de la foto: `:target`,
   cero JavaScript. Aquí sólo van las diferencias entre «una ventana con una
   foto» y «una ventana con un formulario».
   ================================================================== */

/*
 * ⚠️ ARRIBA, NO AL CENTRO.
 *
 * `.rv-visor` centra con `place-items:center`, que es correcto para una foto
 * —nunca es más alta que la pantalla, la limita `max-height:88vh`— y peligroso
 * para un formulario: si crece más que la ventana, centrarlo deja la mitad de
 * arriba FUERA y sin manera de llegar a ella. Con `start` + `margin:auto 0`
 * queda centrado cuando cabe y pegado arriba —con barra— cuando no.
 */
.rv-opinar { place-items: start center; overflow-y: auto; }
.rv-opinar__caja {
  position: relative;
  width: 100%;
  max-width: min(620px, 92vw);
  margin: auto 0;
  background: var(--blanco, #fff);
  border-radius: 14px;
  padding: 30px 34px 32px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .5);
  text-align: left;
}
/* De qué modelo se está hablando: dato de apoyo, no compite con el título. */
.rv-opinar__prod { font-size: .82rem; color: var(--gris, #7B7176); margin: 0 0 4px; }
.rv-opinar__prod b { color: var(--negro, #1A1A1A); font-weight: 600; }
.rv-opinar .comment-reply-title { margin-top: 2px; }
.rv-opinar .res-form { margin: 0; }
/* El textarea se había quedado con el contorno azul del navegador al enfocar. */
.rv-opinar textarea:focus { outline: 0; border-color: var(--magenta, #D6006E); }
/* Cerrar tapaba la esquina del formulario en pantallas chicas. */
@media (max-width: 640px) {
  .rv-opinar { padding: 14px; }
  .rv-opinar__caja { margin-top: 58px; padding: 24px 20px 26px; }
}

/* ------------------------------------------------------------------
   24.1 · EL ESTADO VACÍO, CENTRADO
   ------------------------------------------------------------------
   «Este modelo todavía no tiene opiniones» salía alineado a la izquierda
   dentro de una caja centrada, así que se leía como si se hubiera desacomodado.
   Lo vio Fer.
   ------------------------------------------------------------------ */
.res-vacio { text-align: center; }
.res-vacio p { margin-inline: auto; max-width: 46ch; }

/* ------------------------------------------------------------------
   24.2 · LAS CINCO ESTRELLAS, CLICABLES Y SIN JAVASCRIPT
   ------------------------------------------------------------------
   Radios de verdad con la estrella dibujada por el `<label>`.

   ⚠️ LOS RADIOS VAN TRANSPARENTES, NO `display:none`.
   Con `display:none` Chrome no los puede enfocar y el `required` del navegador
   traba el envío EN SILENCIO: se pica «Publicar» y no pasa nada, sin decir por
   qué. Transparentes siguen existiendo para el teclado y para la validación.

   ⚠️ Y `row-reverse`: en el HTML van del 5 al 1 porque `~` sólo alcanza a los
   hermanos SIGUIENTES — ver el comentario de la plantilla.
   ------------------------------------------------------------------ */
.rv-cal__estrellas {
  display: flex;
  flex-direction: row-reverse;
  justify-content: flex-end;
  gap: 4px;
}
.rv-cal__estrellas input {
  position: absolute;
  width: 30px;
  height: 30px;
  opacity: 0;
  cursor: pointer;
  margin: 0;
}
.rv-cal__estrellas label {
  width: 32px;
  height: 32px;
  cursor: pointer;
  color: #DCD5D7;
  transition: color .12s ease;
  /* La estrella, en el CSS: una imagen más que no se descarga. */
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z'/%3E%3C/svg%3E") center/26px no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z'/%3E%3C/svg%3E") center/26px no-repeat;
  margin: 0;
}
/* La escogida y todas las de su izquierda —que en el HTML son las siguientes. */
.rv-cal__estrellas input:checked,
.rv-cal__estrellas input:checked ~ label,
.rv-cal__estrellas label:hover,
.rv-cal__estrellas label:hover ~ label { color: #E8A21E; }
.rv-cal__estrellas:hover input:checked ~ label { color: #DCD5D7; }
.rv-cal__estrellas:hover label:hover,
.rv-cal__estrellas:hover label:hover ~ label { color: #E8A21E; }
/* El foco del teclado se ve en la estrella, no en un contorno invisible. */
.rv-cal__estrellas input:focus-visible + label { outline: 2px solid var(--magenta, #D6006E); outline-offset: 3px; }
.rv-cal { margin-bottom: 20px; }

/* ==================================================================
   25 · EL MENÚ DEL TELÉFONO: UN CAJÓN, NO UN DESPLEGABLE
   ==================================================================
   Ver `template-parts/menu-movil.php` para el porqué y para la trampa del
   fondo invisible que en Kevstore dejó la tienda sin poder comprar.
   ================================================================== */

/* ① Cerrado SIEMPRE, sin condición. Es la primera defensa: el cajón sólo
      existe cuando `:target` lo enciende, y eso sólo pasa si alguien pica el
      botón. */
.rvmm { display: none; }

/* ② Sólo en teléfono y tableta, y sólo cuando el botón lo señaló. */
@media (max-width: 900px) {
  .rvmm:target { display: block; }

  .rvmm__fondo {
    position: fixed;
    inset: 0;
    z-index: 190;
    background: rgba(26, 26, 26, .62);
    backdrop-filter: blur(2px);
  }

  .rvmm__caja {
    position: fixed;
    top: 0; right: 0; bottom: 0;
    z-index: 200;
    width: min(340px, 88vw);
    background: var(--blanco, #fff);
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    box-shadow: -18px 0 44px rgba(0, 0, 0, .3);
    /* `:target` no tiene estado «saliendo», así que sólo se anima la entrada.
       Cerrar es instantáneo y está bien: nadie espera una animación al salir. */
    animation: rvmm-entra .22s ease-out both;
  }
}
@keyframes rvmm-entra { from { transform: translateX(102%); } to { transform: none; } }
@media (prefers-reduced-motion: reduce) { .rvmm__caja { animation: none; } }

/* ③ De 901 px para arriba NO EXISTE, pase lo que pase con el ancla.
      Sin esto, girar el teléfono con el menú abierto deja el cajón encima del
      sitio de escritorio. */
@media (min-width: 901px) { .rvmm, .rvmm:target { display: none !important; } }

/* ④ Con el cajón abierto, la página de atrás no se mueve.
      Sin esto el dedo arrastra el fondo mientras el menú está encima, y al
      cerrarlo la clienta aparece en otra parte de la página sin saber por qué.
      Donde `:has()` no exista, simplemente no se bloquea y el menú sigue
      funcionando igual. */
@media (max-width: 900px) {
  html:has(.rvmm:target) { overflow: hidden; }
}

.rvmm__cab {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 22px 16px;
  border-bottom: 1px solid var(--gris-linea, #E4DEE0);
  flex: 0 0 auto;
}
.rvmm__logo { height: 30px; width: auto; }
.rvmm__x {
  font-size: 2rem;
  line-height: 1;
  color: var(--gris, #7B7176);
  /* 44 px de zona sensible, como el resto de los controles al tacto. */
  width: 44px; height: 44px;
  display: grid; place-items: center;
  margin-right: -10px;
}

.rvmm__busca { display: flex; gap: 0; margin: 18px 22px 4px; flex: 0 0 auto; }
.rvmm__busca input {
  flex: 1;
  min-width: 0;
  border: 1px solid var(--gris-linea, #E4DEE0);
  border-right: 0;
  padding: 13px 15px;
  font-family: inherit;
  font-size: .92rem;
  border-radius: var(--radio, 2px) 0 0 var(--radio, 2px);
}
.rvmm__busca input:focus { outline: 0; border-color: var(--magenta, #D6006E); }
.rvmm__busca button {
  width: 50px;
  display: grid;
  place-items: center;
  background: var(--negro, #1A1A1A);
  border: 0;
  border-radius: 0 var(--radio, 2px) var(--radio, 2px) 0;
  cursor: pointer;
}
.rvmm__busca button svg { width: 19px; height: 19px; stroke: #fff; fill: none; stroke-width: 1.8; }

.rvmm__grupo { padding: 16px 0 4px; }
.rvmm__eti {
  display: block;
  padding: 0 22px 8px;
  font-size: .64rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--gris, #7B7176);
}
.rvmm__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  /* 52 px de alto: son los blancos que más se tocan de todo el sitio. */
  min-height: 52px;
  padding: 8px 22px;
  font-size: .98rem;
  color: var(--negro, #1A1A1A);
}
.rvmm__link:active { background: var(--hueso, #F7F4F2); }
.rvmm__link em {
  font-style: normal;
  font-size: .74rem;
  color: var(--gris, #7B7176);
}
.rvmm__flag {
  background: var(--magenta-luz, #FDF0F6);
  color: var(--magenta, #D6006E) !important;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 20px;
}
.rvmm__grupo + .rvmm__grupo { border-top: 1px solid var(--gris-linea, #E4DEE0); }

/* El pie se queda abajo aunque la lista sea corta. */
.rvmm__pie { margin-top: auto; padding: 18px 22px 24px; }
.rvmm__wa {
  display: flex;
  align-items: center;
  gap: 13px;
  background: #1D7A54;
  color: #fff;
  padding: 14px 18px;
  border-radius: var(--radio, 2px);
}
.rvmm__wa svg { width: 24px; height: 24px; fill: currentColor; flex-shrink: 0; }
.rvmm__wa b { display: block; font-size: .82rem; letter-spacing: .04em; }
.rvmm__wa em { display: block; font-style: normal; font-size: .78rem; opacity: .85; margin-top: 1px; }

/* ------------------------------------------------------------------
   25.1 · LA LUPA DEL ENCABEZADO, EN EL TELÉFONO
   ------------------------------------------------------------------
   ⚠️ SE SALÍA DE LA PANTALLA. Medido a 390 px: el panel empezaba en x = −55,
   o sea 55 píxeles fuera por la izquierda. Está anclado a la lupa, que vive
   pegada al borde derecho, y su ancho no cabía.

   En el teléfono se apaga: el buscador vive DENTRO del cajón del menú, que es
   como lo resuelve Kevstore. Un solo lugar para buscar en vez de dos, y
   ninguno se sale. En escritorio la lupa se queda igual.
   ------------------------------------------------------------------ */
@media (max-width: 900px) {
  .hdr__acc details.buscar { display: none; }
}

/* ==================================================================
   26 · LOS CAMPOS, A 16 px — NO ES ESTÉTICA, ES UN DEFECTO DE iPHONE
   ==================================================================

   ⚠️ SAFARI EN iPHONE HACE ZOOM AL TOCAR UN CAMPO DE MENOS DE 16 px.

   No es opinable ni configurable: es comportamiento del sistema. La página se
   agranda sola, se sale de cuadro, y la clienta tiene que pellizcar para
   regresar — en la pantalla de pago, campo por campo.

   Medido en producción: los campos del checkout salían a **14.4 px**.

   ⚠️ SE TOCA SÓLO EL TEXTO DE LOS CAMPOS, no el diseño. El alto, el relleno y
   los bordes no se mueven, así que la retícula del prototipo queda igual: lo
   único que cambia es que lo que la clienta ESCRIBE se lee un poco más grande.
   Y de paso se lee mejor, que en un formulario de dirección no sobra.

   Va sin `@media`: un campo de 16 px en escritorio es lo normal, y limitarlo a
   `pointer:coarse` dejaría el iPad con ratón fuera —que es justo el borde que
   nos mordió con las áreas táctiles—.
   ================================================================== */
.f input,
.f select,
.f textarea,
.woocommerce-checkout .form-row .input-text,
.woocommerce-checkout .form-row select,
.woocommerce-checkout textarea.input-text,
.woocommerce-checkout select.rv-select,
.woocommerce-checkout .select2-container--default .select2-selection--single .select2-selection__rendered,
.rvmm__busca input,
.cat-busca input[type="search"],
.buscar__caja input,
.res-form input,
.res-form textarea,
input.qty {
  font-size: 16px;
}

/* ==================================================================
   27 · LA TIPOGRAFÍA, UN ESCALÓN ARRIBA  ·  APAGADO POR OMISIÓN
   ==================================================================

   LO QUE SE MIDIÓ, antes de proponer nada:

   El CSS del tema y el del prototipo aprobado son IDÉNTICOS, línea por línea.
   Así que la letra chica no es un error de traducción: es el diseño tal cual
   se aprobó. Eso descarta «arreglarlo» y lo convierte en una decisión.

   Y el dato que la sostiene, contando CARACTERES de prosa —no elementos— en
   cinco páginas, a 1440 y a 390 px:

       74% del texto corrido del sitio va por DEBAJO de 16 px
       los dos escalones más pesados son 15 px (17%) y 14.4 px (16%)

   16 px es el tamaño por omisión de todos los navegadores desde hace veinte
   años, y es el punto en el que se calibró la letra que la gente lee sin
   esfuerzo. Tres cuartas partes del sitio van abajo de ahí.

   ⚠️ NO SE TOCAN LAS VERSALITAS. Los `eyebrow`, las cintas y las etiquetas de
   9 a 11 px se quedan: son rótulos de una o dos palabras con letterspacing, y
   subirlos rompería el ritmo del diseño. Lo que sube es lo que alguien LEE.

   ───────────────────────────────────────────────────────────────────
   CÓMO SE PRENDE
   ───────────────────────────────────────────────────────────────────
   Se le agrega la clase `rv-texto-mas` al `<html>` — una línea en
   `functions.php`. Así se puede comparar lado a lado y volver atrás sin
   deshacer nada.
   ================================================================== */
html.rv-texto-mas {
  /* La prosa larga: párrafos de contenido, políticas, «Nosotros». */
  --rv-cuerpo: 1.0625rem;   /* 17 px */
}
html.rv-texto-mas body { font-size: 17px; }
/* `.small` es el escalón que más pesa: 13.1 → 14.4 px. */
html.rv-texto-mas .small { font-size: .85rem; }
/* Y la descripción de producto, la ficha técnica y el texto de políticas. */
html.rv-texto-mas .acc__c,
html.rv-texto-mas .acc__c p,
html.rv-texto-mas .acc__c li,
html.rv-texto-mas .pol p,
html.rv-texto-mas .pol li,
html.rv-texto-mas .tarjeta p { font-size: 1rem; line-height: 1.7; }
/* La tabla del tabulador: es EL dato del negocio, y se lee número por número. */
html.rv-texto-mas .tabla-vol td { font-size: .95rem; }

/* ==================================================================
   28 · MICRO-INTERACCIONES DE LAS TARJETAS
   ==================================================================
   Las cuatro tarjetas debajo del hero tenían un `hover` de dos líneas: cambio
   de borde y 2 px de subida. Fer pidió que tuvieran vida.

   ⚠️ LA REGLA QUE MANDA AQUÍ: SIN JAVASCRIPT, NADA QUEDA INVISIBLE.

   La forma fácil de animar una entrada es poner `opacity:0` en el CSS y
   subirlo con JS al entrar en pantalla. Y es la forma de que, el día que el
   script no cargue —un error de red, un bloqueador, un `defer` mal puesto—,
   la sección quede EN BLANCO para siempre y nadie lo note desde el escritorio.

   Aquí es al revés: el CSS deja todo VISIBLE, y el JavaScript AGREGA la clase
   `rv-anim` al `<html>` sólo cuando existe y puede observar. Si no corre, la
   página se ve completa — sin animación, que es exactamente lo que pasaba
   antes.
   ================================================================== */

/* ---- El hover, con más presencia ---- */
.promo {
  position: relative;
  overflow: hidden;
  transition: transform .28s cubic-bezier(.2, .7, .3, 1),
              border-color .28s ease,
              box-shadow .28s ease;
}
.promo:hover,
.promo:focus-within {
  transform: translateY(-5px);
  border-color: rgba(214, 0, 110, .5);
  box-shadow: 0 14px 34px rgba(0, 0, 0, .35);
}
/*
 * Un barrido de luz que cruza la tarjeta. Va con `transform` y no con
 * `background-position`: `transform` lo resuelve la tarjeta gráfica y no
 * obliga al navegador a repintar la tarjeta entera en cada cuadro.
 */
.promo::after {
  content: "";
  position: absolute;
  top: 0;
  left: -60%;
  width: 45%;
  height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .05), transparent);
  transform: translateX(0);
  transition: transform .7s ease;
  pointer-events: none;   /* no puede tapar el texto ni robarse un clic */
}
.promo:hover::after { transform: translateX(340%); }

/* El icono responde: crece un poco y se llena. */
.promo__ico { transition: transform .3s cubic-bezier(.2, .7, .3, 1), background-color .3s ease; }
.promo:hover .promo__ico { transform: scale(1.09) rotate(-4deg); background: rgba(214, 0, 110, .16); }
.promo__ico svg { transition: stroke .3s ease; }

/* Y la píldora se despega. */
.promo__pill { transition: transform .3s ease, background-color .3s ease; }
.promo:hover .promo__pill { transform: translateX(3px); }

/* ---- La entrada, escalonada ---- */
/*
 * ⚠️ TODO ESTO CUELGA DE `html.rv-anim`. Sin esa clase —o sea sin JavaScript—
 * ninguna de estas reglas aplica y las tarjetas se ven normales.
 */
html.rv-anim .promo,
html.rv-anim .paq__card,
html.rv-anim .look {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .5s ease, transform .5s cubic-bezier(.2, .7, .3, 1);
}
html.rv-anim .promo.rv-visible,
html.rv-anim .paq__card.rv-visible,
html.rv-anim .look.rv-visible {
  opacity: 1;
  transform: none;
}
/*
 * El escalonado va por variable y no por `:nth-child` con retardos escritos:
 * así funciona con cuatro tarjetas o con siete, sin tocar el CSS.
 */
html.rv-anim .rv-visible { transition-delay: calc(var(--rv-i, 0) * 70ms); }

/*
 * Quien pidió que no le muevan la pantalla no ve nada de esto: ni la entrada
 * ni el barrido. El hover de borde se queda, que no es movimiento.
 */
@media (prefers-reduced-motion: reduce) {
  html.rv-anim .promo,
  html.rv-anim .paq__card,
  html.rv-anim .look { opacity: 1; transform: none; transition: none; }
  .promo, .promo__ico, .promo__pill, .promo::after { transition: none; }
  .promo:hover { transform: none; }
  .promo:hover::after { transform: translateX(0); }
}

/* ==================================================================
   29 · «EL RESULTADO, EN USO» · REELS CON FACHADA
   ==================================================================
   La tarjeta enseña una foto; el reel de Instagram entra al picarla. El
   porqué —y los 1,270 kB por reel que lo decidieron— está en
   `assets/js/reels.js`.
   ================================================================== */

/* La foto es un `<button>`, así que hay que quitarle lo de botón. */
.look__media {
  display: block;
  position: relative;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  overflow: hidden;
  /* 9:16, la proporción de un reel. Reservado ANTES de que cargue la foto:
     sin esto la página salta cuando entra cada imagen. */
  aspect-ratio: 9 / 16;
}
.look__foto { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .7s ease; }
.look__media:hover .look__foto { transform: scale(1.04); }
.look__media:focus-visible { outline: 2px solid var(--magenta, #D6006E); outline-offset: 2px; }

/* El play, más presente: es lo que dice que ahí hay video. */
.look__play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 54px;
  height: 54px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, .92);
  box-shadow: 0 4px 18px rgba(0, 0, 0, .25);
  transition: transform .25s cubic-bezier(.2, .7, .3, 1), background-color .25s ease;
}
.look__play svg { width: 17px; height: 17px; fill: var(--negro, #1A1A1A); margin-left: 3px; }
.look__media:hover .look__play { transform: scale(1.1); background: #fff; }

/* ---- La ventana del reel ----
   ⚠️ El reel NO va dentro de la tarjeta. Medido: el hueco da 218×387 px y el
   contenido de Instagram mide 708 de alto, así que salía cortado a la mitad —
   se veía el perfil y media imagen, y el video quedaba fuera. Agrandar la
   tarjeta tampoco: son cuatro en fila y una al doble desacomoda la sección. */
.rv-reel-visor {
  position: fixed;
  inset: 0;
  z-index: 140;
  display: grid;
  place-items: center;
  padding: 24px;
  visibility: hidden;
  opacity: 0;
  transition: opacity .2s ease, visibility 0s linear .2s;
}
.rv-reel-visor--abierto { visibility: visible; opacity: 1; transition-delay: 0s; }
.rv-reel-visor__tapa {
  position: absolute;
  inset: 0;
  border: 0;
  padding: 0;
  background: rgba(26, 26, 26, .9);
  backdrop-filter: blur(3px);
  cursor: pointer;
}
.rv-reel-visor__caja {
  position: relative;
  width: min(400px, 92vw);
  /* 720 px es lo que mide el embebido de Instagram: menos, y vuelve a cortar. */
  height: min(720px, 88vh);
  background: #000;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .55);
}
.rv-reel-visor__caja iframe { width: 100%; height: 100%; border: 0; display: block; }
.rv-reel-visor__x {
  position: absolute;
  top: 16px;
  right: 20px;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .14);
  color: #fff;
  font-size: 2rem;
  line-height: 1;
  cursor: pointer;
}
.rv-reel-visor__x:hover { background: rgba(255, 255, 255, .26); }
/* Si no cargó a los siete segundos, se dice. Un hueco negro es
   indistinguible de uno cargando. */
.rv-reel-visor--falla .rv-reel-visor__caja::after {
  content: "No se pudo cargar el video. Puede que tu navegador bloquee Instagram.";
  position: absolute;
  inset: auto 0 0 0;
  padding: 14px 16px;
  font-size: .84rem;
  line-height: 1.5;
  color: #7A5400;
  background: #FFF8EC;
}
@media (prefers-reduced-motion: reduce) { .rv-reel-visor { transition: none; } }

/* El producto del que habla, debajo — como lo pidió Fer. */
.look__prod {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 12px 13px;
  background: var(--blanco, #fff);
  border-top: 1px solid var(--gris-linea, #E4DEE0);
  transition: background-color .2s ease;
}
.look__prod:hover { background: var(--hueso, #F7F4F2); }
.look__prod img { width: 42px; height: 42px; object-fit: cover; border-radius: var(--radio, 2px); flex-shrink: 0; }
.look__prod b { display: block; font-size: .84rem; line-height: 1.25; }
.look__prod i { display: block; font-style: normal; font-size: .8rem; color: var(--magenta, #D6006E); font-weight: 600; margin-top: 2px; }

/* ==================================================================
   30 · LA GUÍA DE ENVÍO EN «MIS PEDIDOS»
   ==================================================================
   Para que la clienta no tenga que buscar el correo. Ver
   `plugins/rv-panel/guias.php`.
   ================================================================== */
.rv-guia-cliente {
  background: #F0F9F3;
  border: 1px solid #B7DFC4;
  border-radius: 10px;
  padding: 18px 20px;
  margin: 0 0 clamp(24px, 3vw, 34px);
}
.rv-guia-cliente b { display: block; font-size: .74rem; letter-spacing: .15em; text-transform: uppercase; color: #155E3F; }
.rv-guia-cliente p { margin: 6px 0 12px; font-size: .95rem; color: #2C6B4F; }
.rv-guia-cliente p b { display: inline; font-size: 1.05rem; letter-spacing: .04em; text-transform: none; color: var(--negro, #1A1A1A); }

/* ==================================================================
   31 · LAS FOTOS DE INSTAGRAM, CUADRADAS SIEMPRE
   ==================================================================
   ⚠️ LA CUADRATURA LA IMPONE EL CSS, NO LA FOTO QUE SUBAN.

   Fer preguntó si «permanecen en tamaño cuadrado». Sí: `aspect-ratio:1` más
   `object-fit:cover`. Rocío sube la vertical de Instagram tal cual y se
   recorta al centro.

   Pedirle fotos ya cuadradas sería pedirle abrir un editor cada vez — y la
   primera vez que se le olvide, la retícula se desacomoda sin que nadie lo
   note hasta que un cliente lo vea.
   ================================================================== */
.ig-grid .ig-item { aspect-ratio: 1; overflow: hidden; display: block; position: relative; }
.ig-grid .ig-item img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ─── Formulario de contacto ────────────────────────────────────────────────
   La trampa para robots se esconde SIN `display:none`: hay robots que leen el
   CSS y saltan lo que está oculto de la forma obvia. Sacarla de la pantalla la
   esconde igual de bien para la gente y no la delata. */
.rv-trampa {
  position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden;
}

/* El aviso de «ya llegó tu mensaje». Sin esto el formulario funciona y aun así
   se siente roto: manda el correo y no dice nada. */
.rv-aviso {
  padding: 14px 16px; border-radius: 10px; margin-bottom: 18px;
  font-size: .95rem; line-height: 1.45; border: 1px solid;
}
.rv-aviso--exito  { background: #F0FAF5; border-color: #1D7A54; color: #14573C; }
.rv-aviso--alerta { background: #FFF6E8; border-color: #B8791A; color: #7A4E08; }

/* ═══════════════════════════════════════════════════════════════════════════
   CASILLAS Y BOTONES REDONDOS: QUE NINGUNA REGLA DE CAMPO LOS ESTIRE
   ═══════════════════════════════════════════════════════════════════════════

   🚨 EL DEFECTO QUE REPORTÓ FER, Y POR QUÉ SE REPITE EN VARIOS LADOS

   Medido en el emergente de opinar: la casilla de «Guarda mi nombre…» medía
   478 x 13 px. Una casilla de 478 px de ancho, encimada con su propio texto.

   La causa es una regla que parece inofensiva:

       .f input, .f select, .f textarea { width: 100%; padding: 13px 15px; ... }

   Está pensada para cajas de texto, pero `input` incluye TAMBIÉN
   `type="checkbox"` y `type="radio"`. Y como esa regla vive en el tema y
   WooCommerce/WordPress meten sus propios formularios dentro de esos
   contenedores —el de opinar, el de acceder del checkout—, cada formulario
   nuevo que aparece hereda el defecto. Por eso no basta arreglar el de
   opiniones: hay que cortarlo de raíz.

   ⚠️ Va con `!important` a propósito, que casi nunca es la respuesta. Aquí sí:
   estas reglas tienen que ganarle a `width:100%` de tres orígenes distintos
   (el tema, WooCommerce y el CSS de comentarios de WordPress) sin tener que
   perseguir cada selector. Y lo que imponen es lo que una casilla mide
   SIEMPRE, en cualquier formulario: no hay caso legítimo donde una casilla
   deba medir 478 px.
   ═══════════════════════════════════════════════════════════════════════════ */
input[type="checkbox"],
input[type="radio"] {
  width: 18px !important;
  height: 18px !important;
  min-width: 18px;
  flex: 0 0 18px;
  padding: 0 !important;
  margin: 0 8px 0 0;
  border-radius: 4px;
  vertical-align: middle;
  accent-color: var(--magenta, #D6006E);
  cursor: pointer;
}
input[type="radio"] { border-radius: 50%; }

/* El texto que acompaña a la casilla se alinea con ella en vez de quedar en
   otro renglón. `align-items:flex-start` y no `center`: cuando el texto ocupa
   dos renglones —el de las cookies de WordPress los ocupa— centrarlo deja la
   casilla flotando a media altura. */
.comment-form-cookies-consent,
.woocommerce-form-login__rememberme,
p.form-row label.woocommerce-form__label-for-checkbox {
  display: flex !important;
  align-items: flex-start;
  gap: 9px;
  font-size: .9rem;
  line-height: 1.4;
  margin: 14px 0;
}
.comment-form-cookies-consent label,
.woocommerce-form-login__rememberme span {
  margin: 0;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  font-size: .88rem;
  color: var(--negro-suave, #6B6265);
  cursor: pointer;
}
/* La casilla trae un pelín de margen arriba para que su centro coincida con la
   primera línea del texto, no con el borde de arriba de la caja. */
.comment-form-cookies-consent input[type="checkbox"],
.woocommerce-form-login__rememberme input[type="checkbox"] { margin-top: 2px; }

/* ─── «¿Ya eres cliente?» del checkout ──────────────────────────────────────
   Al abrirlo, el formulario de acceder de WooCommerce salía crudo: la casilla
   de Recuérdame estirada, el botón «Acceder» sin fondo —se veía como un
   renglón de texto— y los campos sin el mismo tratamiento que el resto del
   checkout.

   Es el mismo patrón que ya nos había mordido con `#place_order`: el CSS del
   prototipo viste el marcado DEL PROTOTIPO, y todo lo que inyecta WooCommerce
   llega desnudo. Cada bloque de Woo que se conserve hay que vestirlo. */
.woocommerce-form-login-toggle .woocommerce-info {
  background: #F7F5F6;
  border: 1px solid var(--gris-linea, #E5E0E2);
  border-radius: 12px;
  padding: 14px 18px;
  font-size: .92rem;
  margin-bottom: 18px;
}
.woocommerce-form-login {
  border: 1px solid var(--gris-linea, #E5E0E2);
  border-radius: 12px;
  padding: 22px;
  margin-bottom: 26px;
  background: var(--blanco, #fff);
}
.woocommerce-form-login > p:first-child { margin-top: 0; font-size: .92rem; }
.woocommerce-form-login .form-row { margin-bottom: 14px; }
.woocommerce-form-login label {
  display: block; margin-bottom: 6px;
  font-size: .68rem; letter-spacing: .14em; text-transform: uppercase;
  font-weight: 700; color: var(--negro-suave, #6B6265);
}
/* ⚠️ 16px como piso, no 14: por debajo de eso Safari en iPhone hace zoom solo
   al tocar el campo y deja el checkout descuadrado. Ya nos pasó con los otros
   campos del checkout. */
.woocommerce-form-login input[type="text"],
.woocommerce-form-login input[type="password"] {
  width: 100%; font-size: 16px;
  padding: 13px 15px;
  border: 1px solid var(--gris-linea, #E5E0E2);
  border-radius: var(--radio, 10px);
  background: var(--blanco, #fff);
}
.woocommerce-form-login input:focus { outline: none; border-color: var(--magenta, #D6006E); }
/* El botón «Acceder» sin esto es texto suelto: se lee como una etiqueta, no
   como algo que se pica. */
.woocommerce-form-login button[name="login"] {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 46px; padding: 0 26px;
  background: var(--negro, #14100F); color: #fff;
  border-radius: var(--radio, 10px);
  font-size: .8rem; letter-spacing: .1em; text-transform: uppercase; font-weight: 700;
}
.woocommerce-form-login button[name="login"]:hover { background: var(--magenta, #D6006E); }
.woocommerce-form-login .lost_password { margin: 12px 0 0; font-size: .88rem; }
.woocommerce-form-login .lost_password a { text-decoration: underline; }

/* ═══════════════════════════════════════════════════════════════════════════
   13 · EL CARRUSEL SE ARRASTRA CON EL DEDO (y con el ratón)
   ═══════════════════════════════════════════════════════════════════════════

   Antes era un carrusel de puro CSS: cinco `<input type=radio>` y reglas
   `#h1:checked ~ .ed__track .ed__slide:nth-child(1)`. Elegante y sin JS, pero
   sólo se podía cambiar picando los numeritos — arrastrar no hacía nada, que
   es justo como la gente usa un carrusel en el teléfono.

   🚨 Y traía un defecto callado: había CINCO diapositivas y CINCO numeritos,
   pero las reglas sólo llegaban hasta `nth-child(4)`. Picar el «05» dejaba el
   carrusel EN NEGRO. Nadie lo reportó porque el 05 es el último y casi nadie
   llega.

   Ahora es una tira que se desplaza de verdad: el arrastre con el dedo lo hace
   el navegador solo —sin JavaScript— y `scroll-snap` la deja cuadrada en cada
   foto. El JS sólo agrega el arrastre con el ratón en escritorio y mantiene
   sincronizados los numeritos.

   ⚠️ Los `<input type=radio>` SE QUEDAN. Sin JavaScript los numeritos siguen
   sirviendo (`label for=`), así que el carrusel nunca queda muerto. */
.ed__track {
  position: relative;
  height: clamp(560px, 86vh, 860px);
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* Sin esto, en iPhone el arrastre horizontal se pelea con el desplazamiento
     de la página y el carrusel se siente trabado. */
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.ed__track::-webkit-scrollbar { display: none; }

.ed__slide {
  position: relative;
  inset: auto;
  flex: 0 0 100%;
  width: 100%;
  opacity: 1;
  visibility: visible;
  scroll-snap-align: center;
  scroll-snap-stop: always;   /* que no se salte dos fotos de un manotazo */
}
.ed__slide img { transform: none; }

/* Mientras se arrastra con el ratón: sin animación de desplazamiento (se
   sentiría elástico y con retraso) y sin seleccionar texto sin querer. */
.ed__track.rv-arrastrando {
  /* 🚨 `scroll-snap-type: none` MIENTRAS SE ARRASTRA, y sin esto no funciona.
     Con el imán en `mandatory`, cada vez que el JavaScript mueve `scrollLeft`
     el navegador lo REGRESA de inmediato al punto de anclaje más cercano. El
     arrastre se detectaba —la clase se ponía, los eventos llegaban— y la tira
     se quedaba clavada en 0. Se veía como si el JS no sirviera, y el JS estaba
     bien: era el imán ganándole en cada paso. El dedo no sufre esto porque el
     desplazamiento táctil es del navegador y sí coopera con el imán. */
  scroll-snap-type: none;
  scroll-behavior: auto;
  cursor: grabbing;
  user-select: none;
}
.ed__track.rv-arrastrando img { pointer-events: none; }

@media (hover: hover) and (pointer: fine) {
  .ed__track { cursor: grab; }
}

/* El numerito de la foto en la que estás. La clase la pone el JS al
   desplazarse; las reglas viejas de `:checked` se quedan como respaldo. */
.ed__indice label.rv-activo { color: #fff; }
.ed__indice label.rv-activo em { background: #fff; width: 30px; }

/* Quien pidió menos movimiento no tiene por qué aguantar el deslizamiento
   suave: se cambia de golpe. */
@media (prefers-reduced-motion: reduce) {
  .ed__track { scroll-behavior: auto; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   7 · LA BARRA DE COMPRA PEGADA ABAJO
   ═══════════════════════════════════════════════════════════════════════════
   Fer la pidió «sticky to bottom de forma dinámica: si no está en pantalla que
   aparezca, si ya se ve que no salga».

   ⚠️ Arranca ESCONDIDA por CSS y la enciende el JavaScript. Al revés —visible
   por omisión y que el JS la esconda— deja una barra tapando el pie de página
   en cuanto el JS tarde o falle, justo encima del botón de pagar. Lo que se
   rompe en el camino no debe estorbar.

   ⚠️ Y `transform`, no `bottom`: animar `bottom` obliga al navegador a
   recalcular el diseño en cada cuadro y se siente a tirones en el teléfono,
   que es donde más se usa. `transform` no toca el diseño. */
.rv-compra-fija {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 90;
  display: none;
  gap: 10px;
  align-items: center;
  padding: 11px 14px;
  /* El respiro de la franja del iPhone: sin esto el botón queda debajo de la
     barra del sistema y no se puede picar. */
  padding-bottom: calc(11px + env(safe-area-inset-bottom, 0px));
  background: rgba(255, 255, 255, .97);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--gris-linea, #E5E0E2);
  box-shadow: 0 -6px 24px rgba(0, 0, 0, .07);
  transform: translateY(110%);
  transition: transform .28s cubic-bezier(.4, 0, .2, 1);
}
.rv-compra-fija--puesta { display: flex; }
.rv-compra-fija--vista  { transform: translateY(0); }

.rv-compra-fija__info { flex: 1 1 auto; min-width: 0; }
.rv-compra-fija__nom {
  display: block; font-size: .78rem; line-height: 1.2; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rv-compra-fija__precio { display: block; font-size: .95rem; font-weight: 700; color: var(--magenta, #D6006E); }

.rv-compra-fija__qty {
  display: flex; align-items: center;
  border: 1px solid var(--gris-linea, #E5E0E2); border-radius: var(--radio, 10px);
  overflow: hidden; flex: 0 0 auto;
}
/* 44 px: el mínimo que se puede picar con el pulgar sin fallar. Ya nos costó
   una ronda de arreglos en los controles del encabezado. */
/* 🚨 44 × 44, no 40 × 44. Lo escribí en 40 y el arnés móvil lo cazó a la
   primera corrida — con el mismo piso de 44 px que yo mismo puse después de la
   ronda de los controles del encabezado. Cuatro píxeles de menos en el botón
   de «uno más» es el botón que más se pica en una tienda de mayoreo. */
.rv-compra-fija__qty button {
  width: 44px; height: 44px; font-size: 1.1rem; line-height: 1;
  background: none; color: var(--negro, #14100F);
}
.rv-compra-fija__qty span {
  min-width: 34px; text-align: center; font-size: .95rem; font-weight: 700;
  border-inline: 1px solid var(--gris-linea, #E5E0E2); height: 44px;
  display: grid; place-items: center;
}
.rv-compra-fija__add {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 20px;
  background: var(--negro, #14100F); color: #fff;
  border-radius: var(--radio, 10px);
  font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; font-weight: 700;
  white-space: nowrap;
}
.rv-compra-fija__add:hover { background: var(--magenta, #D6006E); }

/* En escritorio se centra y no ocupa todo el ancho: una barra de 1440 px de
   borde a borde para un botón se ve como un anuncio, no como parte de la ficha. */
@media (min-width: 861px) {
  .rv-compra-fija {
    left: 50%; right: auto; bottom: 22px;
    transform: translate(-50%, 160%);
    width: min(560px, 92vw);
    border: 1px solid var(--gris-linea, #E5E0E2);
    border-radius: 14px;
    padding-bottom: 11px;
  }
  .rv-compra-fija--vista { transform: translate(-50%, 0); }
}

/* Quien pidió menos movimiento la ve aparecer sin deslizamiento. */
@media (prefers-reduced-motion: reduce) {
  .rv-compra-fija { transition: none; }
}

/* ─── 12 · Las tiras con foto del menú del teléfono ─────────────────────────
   El megamenú de escritorio enseña los más vendidos con su foto; el del
   teléfono los tenía en texto pelón. Con nombres como «Blíster 27» y «Blíster
   113» la foto no es adorno: es lo único que los distingue. */
.rvmm__tiras { display: grid; gap: 8px; margin-top: 4px; }
.rvmm__tira {
  display: flex; align-items: center; gap: 11px;
  padding: 8px; border-radius: 10px;
  background: #F7F5F6;
  /* 56 px de alto mínimo: el pulgar necesita blanco donde caer. */
  min-height: 56px;
}
.rvmm__tira img {
  width: 42px; height: 42px; border-radius: 7px; object-fit: cover;
  flex: 0 0 42px; background: #fff;
}
.rvmm__tira span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.rvmm__tira b {
  font-size: .82rem; font-weight: 500; line-height: 1.2;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rvmm__tira i { font-style: normal; font-size: .82rem; font-weight: 700; color: var(--magenta, #D6006E); }

/* ═══════════════════════════════════════════════════════════════════════════
   9 (bis) · EL «RECUÉRDAME» ENCIMADO — LO QUE NO VI A LA PRIMERA
   ═══════════════════════════════════════════════════════════════════════════
   Fer lo volvió a reportar sobre MI PROPIA captura del «después»: la casilla
   seguía encimada sobre la etiqueta de CONTRASEÑA.

   ⚠️ Y el error de método es peor que el defecto: yo había medido «casilla
   18×18» y lo di por arreglado. El tamaño SÍ estaba corregido — el problema
   nunca fue el tamaño, era la POSICIÓN. Medí el número que andaba buscando en
   vez de la cosa que estaba rota, y la prueba pasó sobre una pantalla que se
   veía mal en la foto que yo mismo generé.

   La causa, medida: WooCommerce flota `.form-row-first` a la izquierda y
   `.form-row-last` a la derecha, y separa con un `<div class="clear">`. Ese
   div mide 0 px de alto y NO lleva `clear:both` en este contexto, así que la
   fila de «Recuérdame» arrancaba en y=96 — la MISMA altura que las dos
   columnas— y se pintaba encima.

   Se quitan los flotados y se usa rejilla. Un flotado se apoya en que alguien
   más lo limpie; una rejilla no puede encimarse consigo misma.
   ═══════════════════════════════════════════════════════════════════════════ */
/* 🚨 ACOTADO A `.woocommerce-checkout`, Y ESO LO CAZÓ EL COMPROBADOR NUEVO.
 *
 * La primera versión aplicaba la rejilla a `.woocommerce-form-login` a secas —
 * y ROMPÍ `/mi-cuenta/` en el intento. Ese formulario es del tema y sus hijos
 * directos son `<label>`, `<input>`, `<div class="recuerdame">` y `<button>`,
 * sin `.form-row` de por medio. Con dos columnas, cada etiqueta se fue A UN
 * LADO de su campo:
 *
 *     <label> y=537 x=200      <input> y=537 x=424
 *
 * O sea que arreglando el checkout descompuse la pantalla de acceder. No lo vi
 * yo: lo encontró `bin/verificar/filas-encimadas.mjs` en la corrida siguiente,
 * un minuto después de escribirlo.
 *
 * ⚠️ Un `.woocommerce-*` sin acotar le pega a TODAS las pantallas de
 * WooCommerce, y cada una trae su propio marcado. */
.woocommerce-checkout .woocommerce-form-login {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 18px;
  align-items: start;
}
.woocommerce-checkout .woocommerce-form-login > p:first-of-type { grid-column: 1 / -1; }

.woocommerce-checkout .woocommerce-form-login .form-row-first,
.woocommerce-checkout .woocommerce-form-login .form-row-last {
  /* `!important` porque hay que ganarle a `woocommerce-layout.css`, que trae
     el float y un `width:47%` en porcentaje sobre un contenedor que ya no
     manda el ancho. */
  float: none !important;
  width: auto !important;
  margin: 0 0 14px !important;
}
.woocommerce-checkout .woocommerce-form-login .form-row-first { grid-column: 1; }
.woocommerce-checkout .woocommerce-form-login .form-row-last  { grid-column: 2; }

/* La fila de Recuérdame + Acceder, y la de contraseña olvidada, a todo lo
   ancho y DEBAJO. */
.woocommerce-checkout .woocommerce-form-login > .form-row:not(.form-row-first):not(.form-row-last),
.woocommerce-checkout .woocommerce-form-login .lost_password {
  grid-column: 1 / -1;
  margin: 0;
}

/* El `<div class="clear">` de WooCommerce ya no pinta nada: en una rejilla es
   una celda vacía que empuja el resto un renglón. */
.woocommerce-checkout .woocommerce-form-login .clear { display: none; }

/* Dentro de esa fila, la casilla arriba y el botón abajo, sin encimarse. */
.woocommerce-checkout .woocommerce-form-login > .form-row:not(.form-row-first):not(.form-row-last) {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  padding-top: 4px;
}
.woocommerce-checkout .woocommerce-form-login .woocommerce-checkout .woocommerce-form-login__rememberme {
  order: -1;          /* la casilla antes del botón, se pinte como se pinte */
  margin: 0 !important;
}

/* En el teléfono, una sola columna: dos campos de 47% en 390 px quedan de
   170 px y no cabe ni un correo. */
@media (max-width: 860px) {
  .woocommerce-checkout .woocommerce-form-login { grid-template-columns: 1fr; }
  .woocommerce-checkout .woocommerce-form-login .form-row-first,
  .woocommerce-checkout .woocommerce-form-login .form-row-last { grid-column: 1; }
}

/* ─── 🚨 LA BARRA PEGADA SE SALÍA DE LA PANTALLA EN EL TELÉFONO ─────────────
   Fer lo vio: el precio encimado con el nombre. Medido en 390 px:

       info    x=14..14     ← CERO px de ancho, aplastado
       qty     x=24..148
       add     x=158..401   ← se sale 11 px de la pantalla

   La suma de la cantidad (124 px) más el botón «Agregar al carrito — $135»
   (243 px) más los márgenes ya no cabía. Como `.info` llevaba `min-width:0`
   —puesto para que el nombre largo se recortara con puntos suspensivos— fue lo
   único que podía encogerse, y se encogió hasta desaparecer: el texto se salió
   de su caja y se encimó con el precio.

   ⚠️ `min-width:0` no es el culpable: sin él, el nombre largo empujaría el
   botón todavía más lejos. El problema es que en 390 px no caben las tres
   cosas.

   En el teléfono se quita el nombre y el precio de la barra. No se pierde
   nada: estás EN la ficha de ese producto, con su nombre y su precio a la
   vista arriba, y el botón ya trae el precio en su propio texto («Agregar al
   carrito — $135»). En escritorio sí caben las tres y se quedan. */
@media (max-width: 560px) {
  .rv-compra-fija__info { display: none; }
  .rv-compra-fija__add {
    flex: 1 1 auto;
    min-width: 0;
    padding: 0 12px;
    /* Con el ancho justo, un nombre de botón largo tiene que poder recortarse
       en vez de empujar la barra fuera de la pantalla otra vez. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: block;
    line-height: 44px;
    text-align: center;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   ÁREAS TÁCTILES QUE NO LE CABÍAN AL DEDO
   ═══════════════════════════════════════════════════════════════════════════
   Medido con el QA de los 1,485 controles: en teléfono y tableta salieron tres
   grupos por debajo de los 44 px que necesita un pulgar.

   ⚠️ La medida es el PUNTERO, no el ancho de pantalla. Es la lección de Dielec:
   ahí el tamaño táctil estaba atado a un corte de ancho, y un iPad —810 px—
   cruzaba el corte y volvía a los blancos de ratón en una pantalla que se toca
   con el dedo. `@media (pointer: coarse)` es verdadero en teléfono Y tableta,
   y falso con ratón. */
@media (pointer: coarse) {

  /* 1 · Los iconos del pie medían 38×38. Y no se agranda el círculo —se vería
     desproporcionado en el pie— sino el área que recibe el toque, con un
     pseudo-elemento invisible centrado. Se ve igual, se toca mejor. */
  .social a { position: relative; }
  .social a::after {
    content: ""; position: absolute;
    top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: 44px; height: 44px;
  }

  /* 2 · Los numeritos del carrusel medían 15×17. Son el único control del
     carrusel además del arrastre: si no se pueden picar, la única forma de
     llegar a la quinta foto es arrastrar cuatro veces. */
  .ed__indice label { position: relative; }
  .ed__indice label::after {
    content: ""; position: absolute;
    top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: 44px; height: 44px;
  }

  /* 3 · El desplegable de orden del catálogo quedaba en 42 px por dos. */
  .cat-orden select,
  .woocommerce-ordering select { min-height: 44px; }
}

/* ─── 🚨 LA BARRA DE COMPRA TAPABA EL WHATSAPP DE MAYOREO ───────────────────
   El QA de los 1,485 controles lo cazó en teléfono y en tableta: al preguntar
   quién recibe el clic en el centro de «¿Pedido de mayoreo? Escríbenos», la
   respuesta era `rv-compra-fija__add`. O sea que el enlace para pedidos
   grandes —los de $1,600 para arriba— no se podía tocar desde el celular.

   Y el defecto es MÍO, de la barra que agregué el mismo día.

   ⚠️ EL ARREGLO ES GENERAL, NO PARA ESE ENLACE. Subir sólo el bloque de
   WhatsApp dejaría tapado lo siguiente que alguien ponga al final de la ficha,
   y ese defecto se descubriría meses después. La barra mide 69 px de alto en
   el teléfono: se le reserva ese espacio al final del documento, para que
   TODO se pueda subir por encima de ella.

   Va con `:has()` para que sólo aplique donde la barra existe. Si el navegador
   no lo soporta, el respaldo del `@supports not` reserva el espacio en todas
   las fichas — que es de más, pero nunca de menos. */
@media (pointer: coarse) {
  body.single-product { padding-bottom: 88px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   🚨 LA BARRA DE COMPRA TAPABA LA BURBUJA DE WHATSAPP
   ═══════════════════════════════════════════════════════════════════════════
   Medido por el QA de los 1,449 controles, preguntándole al navegador quién
   recibe el clic en el centro de cada cosa:

       burbuja .wa          y=764..822  (58×58, bottom:22)
       .rv-compra-fija      y=775..844  (todo el ancho, alto 69)
       quien recibe el clic: rv-compra-fija__add

   O sea que en la ficha de producto, desde el teléfono y la tableta, el
   WhatsApp de RV NO SE PODÍA TOCAR. Y el defecto es mío: la barra la agregué
   hoy, y aunque medí la burbuja para colocar el botón del editor, nunca la
   comparé contra mi propia barra.

   Es exactamente el defecto de Kevstore, al revés: allá el WhatsApp tapaba un
   «Agregar»; aquí un «Agregar» tapa el WhatsApp.

   ⚠️ La burbuja se SUBE, no se esconde: es el canal principal de RV y en la
   ficha es donde más se usa —«¿tienen este modelo?»—. Se sube sólo cuando la
   barra está puesta, con `:has()`. El respaldo de abajo cubre los navegadores
   sin `:has()` subiéndola en toda la ficha: de más, pero nunca tapada.

   La cuenta: la barra mide 69 px desde el borde, más 12 de aire = 81. */
@media (pointer: coarse) {
  body:has( .rv-compra-fija--vista ) .wa { bottom: 81px; }

  @supports not selector(:has(*)) {
    body.single-product .wa { bottom: 81px; }
  }
}

/* En escritorio la barra va centrada y de 560 px, así que no llega a la
   esquina donde vive la burbuja. Comprobado: ahí no se tapan. */

/* ─── La etiqueta «natural y corta» de la ficha ──────────────────────────────
   Debajo del título, arriba del precio. Va en versalitas y en magenta porque
   tiene que leerse de un vistazo —es lo que Rocío dijo que la gente pregunta—
   pero sin competir con el precio, que es lo que decide la compra.

   `::first-letter` en mayúscula en vez de `text-transform: capitalize`: con
   `capitalize` saldría «Natural Y Corta», con la «y» en mayúscula. */
.pdp__rasgos {
  margin: 8px 0 0;
  font-size: .92rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--magenta);
}

/* La aclaración debajo del título de un grupo de filtros. Sólo la usa «Largo
   del cabello», y es la frase que Rocío pidió que quedara clara. */
.fgrupo__nota {
  margin: -4px 0 10px;
  font-size: .8rem;
  line-height: 1.45;
  color: var(--gris);
}

/* ─── «Si lo pides hoy, te llega entre el…» ──────────────────────────────────
   Va debajo del botón de comprar, no arriba: arriba empuja el botón fuera de
   la primera pantalla en el teléfono, y el botón es lo que vende.

   ⚠️ EN ROSA, NO EN VERDE — Fer, 26-ago-2026.

   Antes era verde «porque es una promesa de servicio, como el bloque de
   WhatsApp». El razonamiento sonaba bien y en pantalla salió mal: los dos
   recuadros quedaban uno debajo del otro, los dos verdes, los dos con un icono
   de línea. Se leían como el mismo aviso repetido y el ojo se saltaba los dos.

   Dos avisos distintos necesitan verse distintos. El verde se queda para
   WhatsApp —que es un canal— y la fecha de entrega toma el rosa de la marca.

   Y las fechas van en NEGRO y en negritas dentro del recuadro rosa: es el dato
   que la clienta busca. `rv_frase_entrega_html()` las manda envueltas en `<b>`. */
.pdp__entrega {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 14px 0 0;
  padding: 11px 14px;
  border: 1px solid rgba(214,0,110,.22);
  border-radius: 10px;
  background: var(--magenta-luz, #FDEBF3);
  color: #7A2050;
  font-size: .93rem;
  line-height: 1.45;
}
.pdp__entrega b {
  color: var(--negro, #1A1A1A);
  font-weight: 700;
}
.pdp__entrega svg {
  width: 20px; height: 20px; flex-shrink: 0;
  stroke: var(--magenta, #D6006E); fill: none; stroke-width: 1.5;
}

/* ─── Las fotos de las sombras líquidas ──────────────────────────────────────
   ⚠️ `contain`, no `cover`. Y la razón no es de gusto.

   Las 36 fotos de pestañas son verticales y de encuadre cerrado: `cover` las
   llena sin perder nada. Las 19 de sombras son CUADRADAS y traen un frasco
   chiquito centrado sobre fondo blanco — `cover` las recorta al centro y deja
   una pantalla de blanco con el frasco fuera de cuadro. Se veía como si la
   foto no hubiera cargado.

   Con `contain` cabe completa; el fondo blanco de la foto se funde con el de
   la caja y no se nota el cambio de proporción. */
.rv-linea-sombras-liquidas .pdp__gal img,
.rv-linea-sombras-liquidas .rv-visor__lienzo img,
.rv-linea-sombras-liquidas .pdp__thumbs img,
.rv-linea-sombras-liquidas.tarjeta img,
.rv-linea-sombras-liquidas .foto {
  object-fit: contain;
  background: #fff;
}

/* ─── El precio de antes, tachado ────────────────────────────────────────────
   Lo pidió RV para las sombras: «$310 tachado, $280 de promoción».

   El tachado va ANTES y más chico: si fuera del mismo tamaño competiría con el
   precio real y la clienta tendría que leer dos veces cuál paga. El grande
   siempre es el que se cobra. */
.precio-antes {
  font-size: .78em;
  color: var(--gris);
  text-decoration: line-through;
  margin-right: 9px;
  font-weight: 500;
}
.precio-promo {
  display: inline-block;
  margin-left: 9px;
  padding: 3px 9px;
  border-radius: 99px;
  background: var(--magenta);
  color: #fff;
  font-size: .72em;
  font-weight: 700;
  letter-spacing: .04em;
  vertical-align: middle;
}

/* ───────────────────────────────────────────────────────────────────────────
   LA PAGINACIÓN DEL CATÁLOGO — 26-ago-2026
   ───────────────────────────────────────────────────────────────────────────
   Estaba SIN ESTILAR. WooCommerce la pinta con su marcado pelón y el tema
   nunca la tocó, así que al pie del catálogo quedaba un «1 2 →» en texto
   suelto, alineado a la izquierda, que no parece un control: parece un
   sobrante. Y son los enlaces que llevan a la segunda mitad del catálogo —
   48 modelos, la mitad viven en la página 2.

   Medido: `a.page-numbers` daba 10×24 px y la flecha 17×24. La yema de un dedo
   son 44. No es que estuviera «apretado»: es que había que atinarle.

   Lo cazó `bin/verificar/responsive.mjs`, no la vista: en el escritorio se
   pica con el ratón y once revisiones pasaron por encima sin verlo.
   ─────────────────────────────────────────────────────────────────────────── */
.woocommerce-pagination { margin: 34px 0 8px; }

.woocommerce-pagination ul.page-numbers {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  list-style: none;
  margin: 0;
  padding: 0;
  border: 0;
}
.woocommerce-pagination ul.page-numbers li { margin: 0; border: 0; }

.woocommerce-pagination .page-numbers {
  /* 44×44 es la medida del dedo, y va en `min-` para que un «12» no lo apriete. */
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 12px;
  font-size: .82rem;
  letter-spacing: .1em;
  color: var(--negro, #1A1A1A);
  text-decoration: none;
  border: 1px solid var(--gris-linea, #E4DFDD);
  background: var(--blanco, #fff);
  transition: var(--trans, .35s cubic-bezier(.22,.61,.36,1));
}
.woocommerce-pagination a.page-numbers:hover,
.woocommerce-pagination a.page-numbers:focus-visible {
  border-color: var(--negro, #1A1A1A);
  background: var(--negro, #1A1A1A);
  color: #fff;
}
.woocommerce-pagination .page-numbers.current {
  background: var(--negro, #1A1A1A);
  border-color: var(--negro, #1A1A1A);
  color: #fff;
  font-weight: 700;
}
/* Las flechas: el mismo cuadro, sin el letter-spacing que las descentra. */
.woocommerce-pagination .page-numbers.next,
.woocommerce-pagination .page-numbers.prev { letter-spacing: 0; font-size: 1rem; }

/* ==================================================================
   24 · LO QUE FALTABA DE LA PASADA TÁCTIL — 26-ago-2026
   ==================================================================
   La pasada anterior (bloque de arriba) dejó a 44 px los botones del
   encabezado, los chips de modelo de la ficha y el enlace de Instagram. Se
   midió con `movil.mjs`: 390 px, seis páginas.

   `bin/verificar/responsive.mjs` recorre catorce anchos y once páginas, y
   encontró lo que aquella no alcanzó — todo lo de ABAJO del sitio:

     · el menú del pie completo, en enlaces de 20 px de alto
     · el icono de Instagram del pie, 38×38
     · el índice de los banners de la portada («01 02 03 04 05»), 15×17
     · el botón «Ver carrito» del aviso de WooCommerce, 125×37
     · «Ver el video en Instagram ↗» de los looks, 330×40

   El pie no es decoración: ahí están «Catálogo completo», «Política de
   envíos», «Garantía y cambios» y el teléfono de WhatsApp. Es la navegación
   que usa quien ya bajó buscando algo concreto.

   ⚠️ MISMO CRITERIO QUE ARRIBA, Y NO SE REPITE POR GUSTO:
   `pointer: coarse` y no un ancho, `padding` y no tamaño de letra, y sólo lo
   que existe PARA picarse. Lo que `woo.css` ya declaró intocable —`.link-sub`,
   `h3.paq__nom > a`, y las versalitas de 9 a 11 px— sigue intocable: esas ya
   se midieron, se miraron y se decidieron.
   ================================================================== */
@media (pointer: coarse) {

  /*
   * El menú del pie: 20 px de alto → 44.
   *
   * ⚠️ EL SELECTOR SE SACÓ DEL MARCADO, NO DE LA CABEZA. La primera versión
   * decía `.pie-nav a, .pie-col ul a, footer nav a, .site-footer ul a` —cuatro
   * nombres razonables y ninguno existe—. El CSS subió, no dio error, y los
   * enlaces siguieron midiendo 110×20. La clase de verdad es `.ftr`, y se supo
   * volviendo a medir en producción: un selector que no engancha se ve
   * exactamente igual que uno que sí, hasta que se mide.
   */
  .ftr ul a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /*
   * El icono de Instagram del pie: 38×38 → 44×44. El dibujo del SVG se queda
   * en 17 px; lo que crece es la zona sensible.
   */
  .social a {
    box-sizing: border-box;
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /*
   * El índice de los banners de la portada. Son cinco etiquetas de 15×17 px
   * pegadas una debajo de otra, y son el ÚNICO control para cambiar de banner:
   * fallarle al toque manda al banner de al lado. El margen negativo en
   * vertical evita que la columna crezca y despegue el índice de su sitio.
   */
  .ed__indice label {
    box-sizing: border-box;
    min-width: 44px;
    min-height: 44px;
    margin-block: -4px;
    display: inline-flex;
    align-items: center;
    justify-content: flex-end;
  }

  /* «Ver carrito» del aviso de Woo, y el enlace del reel: 37 y 40 → 44. */
  .woocommerce-message .button,
  .woocommerce-info .button,
  .look__ig {
    box-sizing: border-box;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}

/*
 * Y los botones que quedaban dos o tres píxeles cortos.
 *
 * `.btn` y `.button` salían de 41 y 42 px de alto en la ficha, en políticas y
 * en el carrito. No es que se fallara el toque: es que la norma son 44 y estos
 * están a un `padding` de distancia. Se pone el mínimo, no se cambia el
 * `padding` — así el botón que ya mide más no se mueve ni un pixel.
 *
 * Sólo al tacto. Con ratón, 41 px sobran.
 */
@media (pointer: coarse) {
  .btn, .button, .wp-element-button {
    box-sizing: border-box;
    min-height: 44px;
  }
}

/*
 * El índice de la página de políticas (`.pol-nav`): 42 px → 44.
 *
 * Son siete enlaces pegados uno debajo de otro y es la única navegación de esa
 * página —«Política de envíos», «Cambios y garantía», «Condiciones de
 * mayoreo»—. Dos píxeles de nada, pero siete blancos chicos en columna es
 * justo donde se le pica al de al lado.
 */
@media (pointer: coarse) {
  .pol-nav a { box-sizing: border-box; min-height: 44px; display: flex; align-items: center; }
}

/*
 * El botón de «Atención a mayoreo» del recuadro de corte.
 *
 * Antes era un enlace subrayado («Solicitar condiciones →») del mismo tamaño
 * que el texto de al lado, así que no se leía como algo que se pica. Ahora es
 * un botón con el logo de WhatsApp: la gente lo reconoce sin leer la etiqueta.
 *
 * Verde de WhatsApp y no el magenta de la marca — es un canal externo, y
 * pintarlo del color de la tienda haría creer que abre algo de la tienda.
 */
.corte__wa {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding: 10px 16px;
  min-height: 44px;
  box-sizing: border-box;
  background: #1D7A54;
  color: #fff;
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-decoration: none;
  border-radius: 2px;
  transition: var(--trans, .35s cubic-bezier(.22,.61,.36,1));
}
.corte__wa svg { width: 17px; height: 17px; fill: currentColor; flex-shrink: 0; }
.corte__wa:hover,
.corte__wa:focus-visible { background: #14573C; color: #fff; }

/*
 * El renglón de «te faltan N para bajar a $X», con su flecha.
 *
 * La flecha apunta hacia abajo y descansa sobre una línea: es «el precio baja
 * hasta aquí», no «descarga» ni «siguiente». Va en magenta porque el dato que
 * acompaña —las piezas que faltan— ya está en magenta, y así el renglón entero
 * se lee como una sola cosa en vez de como letra chica con un adorno.
 */
.progreso__txt {
  display: flex;
  align-items: flex-start;
  gap: 7px;
}
.progreso__ico {
  width: 15px; height: 15px; flex-shrink: 0;
  margin-top: 1px;
  stroke: var(--magenta, #D6006E);
  fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}

/* ───────────────────────────────────────────────────────────────────────────
   EL CARRITO EN EL TELÉFONO: PRIMERO EL RESUMEN — 26-ago-2026
   ───────────────────────────────────────────────────────────────────────────
   Lo pidió Fer: «el resumen del carrito, no sé si lo puedes voltear, para que
   arriba quede el resumen y abajo los productos, y que sea sticky».

   Por qué tiene razón: en el escritorio el resumen va en la columna derecha y
   se ve al mismo tiempo que los productos. En el teléfono, la rejilla se
   apila y el resumen queda DESPUÉS de todas las líneas — con tres o cuatro
   modelos hay que hacer scroll a ciegas para ver cuánto va, y el botón de
   pagar vive hasta abajo. La clienta pierde de vista el total justo mientras
   decide si agrega una pieza más para bajar de escalón.

   ⚠️ SÓLO EN EL TELÉFONO. En el escritorio ya está bien y voltearlo pondría el
   resumen encima del catálogo de su propio carrito.

   ⚠️ Y `order` NO BASTA: el sticky necesita que el elemento tenga a dónde
   pegarse. En una rejilla de una sola columna, el `aside` ocupa su propia fila
   y `position:sticky` no hace nada porque la fila entera se va con el scroll.
   Por eso el `.cart-lay` pasa a ser un bloque normal en móvil: ahí el sticky
   sí tiene contra qué medir.
   ─────────────────────────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  .cart-lay { display: flex; flex-direction: column; }

  /* El resumen sube; las líneas del carrito bajan. */
  .cart-lay > aside.resumen { order: -1; }

  .cart-lay > aside.resumen {
    position: sticky;
    /* 72 px es el alto del encabezado pegajoso: sin esto el resumen se mete
       debajo del logo y el total queda tapado. */
    top: 72px;
    z-index: 4;
    /* La sombra sólo aparece cuando ya se pegó, para que en reposo el bloque
       siga siendo plano como el resto del diseño. */
    box-shadow: 0 6px 22px rgba(26,26,26,.07);
  }
}

/*
 * ⚠️ En pantallas MUY bajas el resumen completo no cabe pegado arriba: se
 * comería la pantalla y no se verían los productos. Ahí deja de ser sticky y
 * simplemente va primero, que sigue siendo mejor que ir hasta el final.
 */
@media (max-width: 900px) and (max-height: 680px) {
  .cart-lay > aside.resumen { position: static; box-shadow: none; }
}

/*
 * El pie del catálogo infinito: la señal de «viene más» y el botón de rescate.
 *
 * Los tres puntos NO son un spinner que gira. En una lista que se va llenando,
 * algo girando compite con las fotos que están entrando; tres puntos que
 * laten dicen lo mismo y se quedan quietos en la periferia.
 */
.cat-infinito {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 56px;
  margin: 30px 0 6px;
}
.cat-infinito__cargando { display: inline-flex; gap: 6px; }
.cat-infinito__cargando i {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--gris, #6E686A);
  animation: rv-latido 1.1s ease-in-out infinite;
}
.cat-infinito__cargando i:nth-child(2) { animation-delay: .15s; }
.cat-infinito__cargando i:nth-child(3) { animation-delay: .3s; }
@keyframes rv-latido {
  0%, 80%, 100% { opacity: .25; transform: translateY(0); }
  40%           { opacity: 1;   transform: translateY(-3px); }
}
/* Quien pidió menos movimiento ve los puntos, pero quietos. */
@media (prefers-reduced-motion: reduce) {
  .cat-infinito__cargando i { animation: none; opacity: .55; }
}

/* ───────────────────────────────────────────────────────────────────────────
   EL CAJÓN DE FILTROS DEL TELÉFONO — 26-ago-2026
   ───────────────────────────────────────────────────────────────────────────
   Fer: «los filtros están muy grandes y luego no me permite hacer scroll; eso
   hace que quede un poquito incómodo».

   Medido antes de tocar nada: el cajón mide 844 px y su contenido 1,095. O sea
   que SÍ scrollea — pero sólo 251 px, y ahí está la sensación de atorado:

   1 · **El scroll se encadenaba con la página de atrás.** `position:fixed` no
       impide que, al llegar al final del cajón, el dedo siga arrastrando el
       catálogo que está debajo. La lista se queda quieta, el fondo se mueve, y
       se lee como «no me deja hacer scroll». `overscroll-behavior: contain` lo
       corta: el gesto muere dentro del cajón.

   2 · **Seis grupos con su aire de escritorio.** El `gap` de 26 px y los
       márgenes de los títulos suman más de 200 px de puro espacio en una
       pantalla de 844. Se aprietan SÓLO aquí.

   ⚠️ LO QUE NO SE TOCA: la altura de cada opción. Están en 35 px y la norma
   son 44 — apretarlas para que quepan más sería arreglar la incomodidad de
   scroll creando una de puntería, que es peor. El aire que sobra está entre
   los grupos, no dentro de ellos.
   ─────────────────────────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  .filtros {
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    gap: 0;
  }
  .filtros .fgrupo { padding-bottom: 4px; }
  .filtros .fgrupo + .fgrupo { margin-top: 16px; }
  .filtros .fgrupo h4 { margin-bottom: 6px; }
  .filtros .fnota { margin-top: 2px; }

  /* Un filete entre grupos: al apretarlos, sin línea se leen como una sola
     lista larga y se pierde qué opción pertenece a qué. */
  .filtros .fgrupo + .fgrupo { border-top: 1px solid var(--gris-linea, #E4DEE0); padding-top: 14px; }
}

/*
 * El beneficiario y el banco en el recuadro de transferencia: mismo formato de
 * renglón que la CLABE, pero el texto no lleva el tracking ancho de los
 * números — un nombre con letter-spacing de cifra se lee robótico.
 */
.ty-clabe + .ty-clabe { margin-top: 8px; }
.ty-dato-txt { font-size: 1rem; letter-spacing: 0; font-weight: 700; }

/*
 * Los chips de volumen y largo, hermanos del chip de estilo (.pdp__flag) pero
 * contorneados: mismo óvalo, distinta jerarquía. El estilo identifica al
 * modelo; estos dos lo describen.
 */
.pdp__chips { margin: 10px 0 0; display: flex; gap: 7px; flex-wrap: wrap; }
.pdp__chip {
  display: inline-block;
  border: 1.4px solid var(--magenta, #D6006E);
  color: var(--magenta, #D6006E);
  border-radius: 999px;
  padding: 4px 13px;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
}

/*
 * El campo de «¿Qué modelos quieres?» del paquete. Va antes del botón de
 * comprar, con el mismo lenguaje de formulario del checkout.
 */
.paq-modelos { margin: 18px 0 4px; }
.paq-modelos__l {
  display: block;
  font-size: .68rem; letter-spacing: .14em; text-transform: uppercase;
  font-weight: 700; color: var(--negro-suave, #2E2A2B); margin-bottom: 7px;
}
.paq-modelos__l span { font-weight: 500; color: var(--gris, #6E686A); text-transform: none; letter-spacing: 0; }
.paq-modelos textarea {
  width: 100%; border: 1px solid var(--gris-linea, #E4DFDD);
  padding: 12px 14px; font-size: .92rem; font-family: inherit;
  border-radius: var(--radio, 2px); background: var(--blanco, #fff);
  resize: vertical; min-height: 58px;
}
.paq-modelos textarea:focus { outline: 2px solid var(--magenta, #D6006E); outline-offset: 1px; border-color: transparent; }
.paq-modelos__nota { margin: 7px 0 0; font-size: .78rem; line-height: 1.5; color: var(--gris, #6E686A); }

/* La nota de modelos dentro del carrito y el resumen: letra chica, sin pelear
   con el precio. El dt/dd de Woo se aplana a un renglón. */
.cart-linea .variation, .res-prod .variation { margin: 4px 0 0; font-size: .78rem; color: var(--gris, #6E686A); }
.cart-linea .variation dt, .res-prod .variation dt { display: inline; font-weight: 700; margin: 0; }
.cart-linea .variation dd, .res-prod .variation dd { display: inline; margin: 0 0 0 4px; }
.cart-linea .variation dd p, .res-prod .variation dd p { display: inline; margin: 0; }

/* ── Openpay (plugin openpay-cards) ─────────────────────────────────────
   El campo CVV trae una tarjetita de fondo desde el CSS del plugin, pensada
   para un input angosto; con nuestro `.f input{width:100%}` se repetía en
   mosaico (visto en la compra sandbox del 2-sep). Fuera el fondo: el campo
   ya dice «CVV» y basta. */
#openpay-card-cvc{background-image:none!important}
.payment_box.payment_method_wc_openpay_gateway .form-row{margin-bottom:12px}
