/* ══════════════════════════════════════════════════════════════════════
   MEGA MAYORISTA — mm-card.css
   La tarjeta de producto. UNA sola, compartida por home, listado,
   tendencias, novedades, favoritos y el buscador.
   ══════════════════════════════════════════════════════════════════════
   El markup lo genera crearTarjetaProducto() en js/ui/catalogo.js.

   NO lleva precio tachado, "% OFF", cuotas, cupón ni "envío gratis":
   nada de eso existe en el backend. El único descuento real es por
   volumen y a cantidad 1 no aplica, así que en la tarjeta sería
   publicidad engañosa. Se muestra en el detalle, donde los dos números
   son reales.
   ══════════════════════════════════════════════════════════════════════ */

.mm-card {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--mm-surface);
  border: 1px solid var(--mm-line);
  border-radius: var(--mm-r-md);
  box-shadow: var(--mm-sh-card);
  overflow: hidden;
  cursor: pointer;
  transition: var(--mm-tr-motion), var(--mm-tr-color);
}

/* El hover va SOLO con mouse: en táctil se queda pegado después del tap y
   la grilla entera queda con tarjetas levantadas. */
@media (hover: hover) and (pointer: fine) {
  .mm-card:hover {
    transform: translateY(var(--mm-lift, -2px));
    box-shadow: var(--mm-sh-hover);
    border-color: var(--mm-red-border);
  }
  .mm-card:hover .mm-card-media img { transform: scale(1.03); }
}

.mm-card:focus-visible {
  outline: var(--mm-focus-ring);
  outline-offset: var(--mm-focus-offset);
}

/* ── Imagen ────────────────────────────────────────────────────────── */
.mm-card-media {
  position: relative;
  aspect-ratio: 1 / 1;
  padding: var(--mm-card-pad);
  background: var(--mm-surface);
  overflow: hidden;
}

.mm-card-media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: transform var(--mm-dur-slow) var(--mm-ease-out);
}

/* Estado "Sin imagen": hoy NO hay una sola foto de producto cargada, así
   que este es el caso normal, no la excepción. Monograma sobre banda
   neutra, mismo 1:1 que la foto. */
.mm-card-ph {
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  border-radius: var(--mm-r-xs);
  background: var(--mm-band);
  color: var(--mm-text-faint);
  font-size: var(--mm-t-3xl);
  font-weight: var(--mm-w-black);
  line-height: var(--mm-lh-none);
  letter-spacing: var(--mm-ls-tight);
  user-select: none;
}

/* Fallback del onerror: el <img> se oculta y aparece este hermano. */
.mm-card-ph[hidden] { display: none; }

/* ── Favorito (marcador) ─────────────────────────────────────────────
   Sin `transform` en reposo A PROPÓSITO: al marcarlo, el JS le pone
   .mm-anim-pop (scale) y cualquier transform propio se lo comería. El
   cambio de color viaja por --mm-tr-color; el relleno del ícono es
   currentColor, así que acompaña solo. */
.mm-card-fav {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: var(--mm-z-base);
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  padding: 0;
  background: var(--mm-surface);
  border: none;
  border-radius: var(--mm-r-xs);
  color: var(--mm-text-soft);
  cursor: pointer;
  transition: var(--mm-tr-color);
}

/* Halo táctil: lleva el área activa a 44×44 sin mover un píxel de lo que se
   ve (el botón sigue midiendo 32 y el corazón 18). El botón ya es
   `position: absolute`, así que sirve de ancla. */
.mm-card-fav::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: max(100%, var(--mm-tap, 44px));
  height: max(100%, var(--mm-tap, 44px));
  transform: translate(-50%, -50%);
}

.mm-card-fav svg { width: 18px; height: 18px; }

/* En táctil el hover queda pegado tras el tap y el marcador se ve rojo
   como si estuviera guardado: sólo con mouse. */
@media (hover: hover) and (pointer: fine) {
  .mm-card-fav:hover { color: var(--mm-red-accent); }
}

.mm-card-fav.is-on { color: var(--mm-red-accent); }
.mm-card-fav.is-on svg { fill: currentColor; }

/* ── Badge NUEVO ───────────────────────────────────────────────────── */
.mm-card-badge {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: var(--mm-z-base);
  padding: 3px var(--mm-s-2);
  border-radius: var(--mm-r-xs);
  background: var(--mm-red-accent);
  color: var(--mm-on-red);
  font-size: var(--mm-t-eyebrow);
  font-weight: var(--mm-w-black);
  text-transform: uppercase;
  letter-spacing: var(--mm-ls-wide);
  line-height: 1.4;
}

/* ── Vista rápida ──────────────────────────────────────────────────────
   Botón que abre el detalle en el modal SIN salir de la grilla. Lo inyecta
   js/ui/vista-rapida.js al final de .mm-card-media (después del <img> y de
   su placeholder, para no romper el onerror que usa nextElementSibling).

   Va sobre la imagen y no arriba: las dos esquinas superiores ya están
   ocupadas por el badge "Nuevo" y el marcador de favoritos.

   Con mouse aparece al pasar por encima — es una ayuda, no una acción
   principal, y a la vista permanente le robaría peso al COMPRAR. Con
   teclado aparece en cuanto la tarjeta recibe el foco (:focus-within), y
   en táctil está siempre visible: ahí no hay hover que la revele.        */
.mm-card-quick {
  position: absolute;
  left: var(--mm-s-2);
  right: var(--mm-s-2);
  bottom: var(--mm-s-2);
  z-index: var(--mm-z-base);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 34px;
  padding: 0 var(--mm-s-2);
  background: var(--mm-surface);
  border: 1px solid var(--mm-line);
  border-radius: var(--mm-r-full);
  box-shadow: var(--mm-sh-card);
  color: var(--mm-text);
  font-family: var(--mm-font);
  font-size: var(--mm-t-xs);
  font-weight: var(--mm-w-bold);
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  /* Un solo `transform` compuesto de dos variables: la entrada (--vr-y) la
     manda el hover de la tarjeta y el hundimiento (--vr-scale) el :active.
     Escritas como declaraciones separadas se pisarían entre sí — el hover
     de la tarjeta tiene más especificidad que el :active del botón. */
  --vr-y: 0px;
  --vr-scale: 1;
  transform: translateY(var(--vr-y)) scale(var(--vr-scale));
  /* Sólo opacity y transform: no dispara layout ni paint de la grilla. */
  transition:
    opacity var(--mm-dur-base) var(--mm-ease),
    transform var(--mm-dur-base) var(--mm-ease),
    var(--mm-tr-color);
}

.mm-card-quick svg {
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
}

.mm-card-quick span {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Halo táctil: lleva el alto activo a 44 sin mover un píxel de lo que se ve
   (mismo recurso que .mm-card-fav). El ancho ya lo da el botón completo. */
.mm-card-quick::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: max(100%, var(--mm-tap, 44px));
  transform: translateY(-50%);
}

.mm-card-quick:focus-visible {
  outline: var(--mm-focus-ring);
  outline-offset: var(--mm-focus-offset);
}

.mm-card-quick:active { --vr-scale: var(--mm-press, 0.97); }

@media (hover: hover) and (pointer: fine) {
  .mm-card-quick {
    opacity: 0;
    --vr-y: 6px;
    /* Invisible no debe ser clicable, pero sí enfocable: pointer-events no
       afecta al foco por teclado, y la regla de :focus-visible lo devuelve. */
    pointer-events: none;
  }

  .mm-card:hover .mm-card-quick,
  .mm-card:focus-within .mm-card-quick,
  .mm-card-quick:focus-visible {
    opacity: 1;
    --vr-y: 0px;
    pointer-events: auto;
  }

  .mm-card-quick:hover {
    background: var(--mm-ink);
    border-color: var(--mm-ink);
    color: var(--mm-on-red);
  }
}

/* ── Cuerpo ────────────────────────────────────────────────────────── */
.mm-card-body {
  display: flex;
  flex-direction: column;
  gap: var(--mm-s-2);
  flex: 1 1 auto;
  padding: var(--mm-card-pad);
  padding-top: 0;
}

.mm-card-name {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin: 0;
  min-height: calc(2 * var(--mm-lh-snug) * 1em);
  color: var(--mm-text);
  font-size: var(--mm-t-lg);
  font-weight: var(--mm-w-regular);
  line-height: var(--mm-lh-snug);
  /* Muchas descripciones del ERP son ristras de códigos sin espacios: sin
     esto se salen de la tarjeta en vez de truncarse. */
  overflow-wrap: anywhere;
}

.mm-card-price { margin: 0; }

/* ── Meta: stock + categoría ───────────────────────────────────────────
   El poller de stock (actualizarStockEnVivo en app.js) parchea EN VIVO
   las clases Tailwind de color de .js-stock y .js-stock-dot sin
   re-renderizar la tarjeta. No se pueden quitar; se reasignan a colores
   del sistema con mayor especificidad para que la paleta siga siendo la
   de los tokens. */
/* Siempre UNA línea: el poller escribe textos de largo variable
   ("En stock (1993 disponibles)") y si envolviera, unas tarjetas
   quedarían más altas que otras y se rompería el ritmo de la grilla. */
.mm-card-meta {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  overflow: hidden;
  gap: var(--mm-s-2);
  margin: 0;
  font-size: var(--mm-t-xs);
  color: var(--mm-text-soft);
}

.mm-card-stock {
  display: inline-flex;
  align-items: center;
  flex: 0 1 auto;
  min-width: 0;
  gap: 6px;
  font-weight: var(--mm-w-medium);
}

.mm-card-stock .js-stock-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mm-card-dot {
  width: 7px;
  height: 7px;
  flex: 0 0 auto;
  border-radius: var(--mm-r-full);
}

.mm-card .js-stock.text-green-700 { color: var(--mm-text-soft); }
.mm-card .js-stock.text-amber-700 { color: var(--mm-warn); }
.mm-card .js-stock.text-red-600   { color: var(--mm-red); }
.mm-card .js-stock-dot.bg-green-500 { background: var(--mm-ok); }
.mm-card .js-stock-dot.bg-amber-500 { background: var(--mm-warn); }
.mm-card .js-stock-dot.bg-red-500   { background: var(--mm-danger); }

.mm-card-cat {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── Acción ────────────────────────────────────────────────────────── */
.mm-card-action { margin-top: auto; padding-top: var(--mm-s-1); }

.mm-card-action .mm-btn {
  width: 100%;
  transition: var(--mm-tr-color), transform var(--mm-dur-fast) var(--mm-ease);
}

/* El botón cede bajo el dedo: confirma el toque en el punto exacto donde
   el comprador está mirando, sin tocar el layout. */
.mm-card-action .mm-btn:active:not(:disabled) {
  transform: scale(var(--mm-press, 0.97));
}

/* Variante de "La zona roja": el COMPRAR va negro. */
.mm-card--zona-roja .mm-card-action .mm-btn {
  background: var(--mm-ink);
  border-color: var(--mm-ink);
  color: var(--mm-on-red);
  text-transform: uppercase;
  letter-spacing: var(--mm-ls-wide);
}

@media (hover: hover) and (pointer: fine) {
  .mm-card--zona-roja .mm-card-action .mm-btn:hover {
    background: #000000;
    border-color: #000000;
  }
}

/* ── Stepper (producto ya en el carrito) ─────────────────────────────
   Los botones − y + miden 44 en TODO ancho (en móvil bajaban a 38, justo al
   revés de lo que corresponde en táctil). A dos columnas en 375px la tarjeta
   deja ~141px útiles: 44 + 44 y todavía sobran ~53 para el input. */
.mm-stepper {
  display: grid;
  grid-template-columns: var(--mm-tap, 44px) minmax(0, 1fr) var(--mm-tap, 44px);
  align-items: center;
  height: var(--mm-ctl-h-touch);
  border: 1px solid var(--mm-line);
  border-radius: var(--mm-r-sm);
  overflow: hidden;
  background: var(--mm-surface);
}

.mm-stepper button {
  height: 100%;
  border: none;
  background: transparent;
  color: var(--mm-text);
  font-family: var(--mm-font);
  font-size: var(--mm-t-lg);
  font-weight: var(--mm-w-bold);
  line-height: 1;
  cursor: pointer;
  transition: var(--mm-tr-color), transform var(--mm-dur-fast) var(--mm-ease);
}

@media (hover: hover) and (pointer: fine) {
  .mm-stepper button:hover { background: var(--mm-band); color: var(--mm-ink); }
}

/* Misma confirmación que el COMPRAR: en el stepper es el único acuse de
   recibo inmediato, porque la cifra la reescribe el re-render. */
.mm-stepper button:active { transform: scale(var(--mm-press, 0.97)); }

.mm-stepper input {
  width: 100%;
  min-width: 0;
  height: 100%;
  border: none;
  border-inline: 1px solid var(--mm-line-soft);
  background: transparent;
  text-align: center;
  color: var(--mm-red-accent);
  font-family: var(--mm-font);
  font-size: var(--mm-t-sm);
  font-weight: var(--mm-w-black);
  outline: none;
}

.mm-stepper input:focus-visible {
  outline: var(--mm-focus-ring);
  outline-offset: -2px;
}

/* ── Agotado ───────────────────────────────────────────────────────── */
/* Sin stock no hay nada que ofrecer: la tarjeta no se eleva ni hace zoom,
   se queda tal cual está. */
.mm-card--agotado { opacity: 0.6; }

@media (hover: hover) and (pointer: fine) {
  .mm-card--agotado:hover { transform: none; box-shadow: var(--mm-sh-card); }
  .mm-card--agotado:hover .mm-card-media img { transform: none; }
}

/* ── Móvil ─────────────────────────────────────────────────────────── */
@media (max-width: 767.98px) {
  .mm-card-media { padding: var(--mm-s-2); }
  .mm-card-body { padding: var(--mm-s-3); padding-top: 0; gap: 6px; }
  .mm-card-name { font-size: var(--mm-t-sm); }
  .mm-card-price { font-size: var(--mm-t-lg); }
  .mm-card .mm-price { font-size: var(--mm-t-lg); }
  /* Antes 4px. El halo de 44 sobresale 6px del botón de 32, y .mm-card
     recorta (overflow: hidden): a 4px del borde se lo comía justo en la
     esquina, que es donde cae el pulgar. A 8px entra completo. */
  .mm-card-fav { top: 8px; right: 8px; }
  /* A dos columnas no entran stock y categoría: manda el stock, que es
     el dato que cambia en vivo. */
  .mm-card-cat { display: none; }

  /* A dos columnas quedan ~141px útiles: el pill se achica para no comerse
     la imagen, pero el halo de 44 sigue dando el área táctil completa. */
  .mm-card-quick {
    height: 30px;
    gap: 4px;
    font-size: var(--mm-t-eyebrow);
    letter-spacing: 0;
  }
  .mm-card-quick svg { width: 13px; height: 13px; }
}

/* ── Skeleton de la grilla ─────────────────────────────────────────────
   Misma caja que .mm-card, hueco por hueco: cuando llegan los datos el
   alto de la fila no cambia y no hay salto (CLS).
   El brillo NO se define acá: cada barra lleva además .mm-skel
   (mm-base.css), que desplaza un pseudo-elemento con translateX. Es el
   único bucle del sitio y sólo vive mientras dura la carga.           */
.mm-card-skel {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--mm-surface);
  border: 1px solid var(--mm-line);
  border-radius: var(--mm-r-md);
  overflow: hidden;
}

/* El 1:1 se mide sobre el ancho MENOS los márgenes, así que el bloque
   ocupa exactamente lo mismo que .mm-card-media (1:1 a sangre + padding). */
.mm-card-skel-media {
  aspect-ratio: 1 / 1;
  margin: var(--mm-card-pad);
  border-radius: var(--mm-r-xs);
}

.mm-card-skel-body {
  display: flex;
  flex-direction: column;
  gap: var(--mm-s-2);
  padding: 0 var(--mm-card-pad) var(--mm-card-pad);
}

/* Las dos barras finas son el nombre a dos líneas (.mm-card-name reserva
   ese alto con min-height): entre las dos más el gap tienen que sumar lo
   mismo. */
.mm-card-skel-line {
  height: calc((2 * var(--mm-lh-snug) * var(--mm-t-lg) - var(--mm-s-2)) / 2);
}

/* La barra gruesa es el precio (.mm-price va en --mm-t-xl; los centavos en
   superíndice estiran algo la caja de línea). */
.mm-card-skel-line-lg {
  height: calc(var(--mm-lh-tight) * var(--mm-t-xl));
  width: 55%;
}

/* El markup no trae una barra para la línea de stock/categoría: su alto se
   reserva acá, junto con el padding-top de .mm-card-action. */
.mm-card-skel-btn {
  height: var(--mm-ctl-h-touch);
  margin-top: calc(var(--mm-lh-normal) * var(--mm-t-xs) + var(--mm-s-1));
  border-radius: var(--mm-r-sm);
}

/* Espejo de los paddings y tamaños móviles de .mm-card. */
@media (max-width: 767.98px) {
  .mm-card-skel-media { margin: var(--mm-s-2); }
  .mm-card-skel-body { padding: 0 var(--mm-s-3) var(--mm-s-3); gap: 6px; }
  .mm-card-skel-line { height: calc((2 * var(--mm-lh-snug) * var(--mm-t-sm) - 6px) / 2); }
  .mm-card-skel-line-lg { height: calc(var(--mm-lh-tight) * var(--mm-t-lg)); }
}

/* ── Movimiento reducido ───────────────────────────────────────────────
   Las duraciones ya las lleva a 0 tokens.css; acá se anulan además los
   desplazamientos y las escalas, que si no seguirían ocurriendo, sólo que
   de golpe. El color, el borde y la sombra del hover se conservan: no son
   movimiento y son la señal de que la tarjeta responde.                */
@media (prefers-reduced-motion: reduce) {
  .mm-card:hover,
  .mm-card:hover .mm-card-media img,
  .mm-card-action .mm-btn:active:not(:disabled),
  .mm-stepper button:active {
    transform: none;
  }

  /* La vista rápida entra sólo con opacidad: sin el desplazamiento de 6px
     ni el hundimiento al pulsar. Va DESPUÉS de esas reglas a propósito:
     misma especificidad, gana el orden. */
  .mm-card-quick { --vr-y: 0px; }
  .mm-card-quick:active { --vr-scale: 1; }
}
