/* ══════════════════════════════════════════════════════════════════════
   MEGA MAYORISTA — mm-catalogo.css
   Listado (/productos · /tendencias · /novedades · /favoritos),
   detalle de producto (modal) y buscador del header.
   ══════════════════════════════════════════════════════════════════════
   Se carga DESPUES de tokens.css y mm-base.css. Todo el color, radio,
   sombra y espaciado sale de las variables de tokens.css.

   Las hojas legacy (design-system / cards / futuristic / ecommerce)
   quedan congeladas: acá se SOBRESCRIBEN, nunca se editan.
   ══════════════════════════════════════════════════════════════════════ */

/* ──────────────────────────────────────────────────────────────────────
   0 · RED DE SEGURIDAD — primitivos de mm-base.css (propiedad de T1)
   ──────────────────────────────────────────────────────────────────────
   Estas reglas van envueltas en :where() a propósito: especificidad 0.
   Cualquier definición real en mm-base.css (o en las hojas legacy) las
   pisa sin importar el orden de carga. Sólo actúan si el primitivo aún
   no existe, para que esta vista nunca quede sin layout.
   NO son la definición canónica de esos primitivos: no editar acá.      */

:where(.mm-container) {
  width: 100%;
  max-width: var(--mm-container);
  margin-inline: auto;
  padding-inline: var(--mm-gutter);
}
:where(.mm-section) { padding-block: var(--mm-section-y); }
:where(.mm-grid) {
  display: grid;
  gap: var(--mm-grid-gap);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--mm-card-min)), 1fr));
}
:where(.mm-btn-pill) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--mm-ctl-h);
  padding: 0 var(--mm-s-8);
  border: 1px solid var(--mm-line);
  border-radius: var(--mm-r-full);
  background: var(--mm-surface);
  color: var(--mm-ink);
  font: var(--mm-w-semi) var(--mm-t-sm)/1 var(--mm-font);
  cursor: pointer;
  transition: var(--mm-tr-color);
}
:where(.mm-btn-pill:hover) { background: var(--mm-band); }
:where(.mm-price) {
  font-family: var(--mm-font);
  font-weight: var(--mm-w-bold);
  color: var(--mm-ink);
  letter-spacing: var(--mm-ls-tight);
}
/* Las grillas del home (destacados/nuevos) y el buscador todavía piden
   .productos-grid, que vivía en el <style> de components/productos.html.
   Al vaciar ese componente quedarían sin grilla: acá tienen su piso. */
:where(.productos-grid) {
  display: grid;
  gap: var(--mm-grid-gap);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--mm-card-min)), 1fr));
}

/* ──────────────────────────────────────────────────────────────────────
   1 · SHELL DE LA VISTA DE LISTADO
   ────────────────────────────────────────────────────────────────────── */

.mm-listado {
  background: var(--mm-page);
  font-family: var(--mm-font);
  color: var(--mm-text);
  min-height: 60vh;
  padding-bottom: var(--mm-s-16);
}

.mm-listado-head { padding-top: var(--mm-s-8); }

.mm-listado-titulo {
  margin: 0;
  font-size: var(--mm-t-2xl);
  font-weight: var(--mm-w-black);
  line-height: var(--mm-lh-tight);
  letter-spacing: var(--mm-ls-tight);
  color: var(--mm-ink);
}
.mm-listado-titulo em {
  font-style: normal;
  color: var(--mm-red-accent);
}

/* ── Barra superior: contador + orden + filtros | paginación ─────────── */
.mm-listado-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--mm-s-4);
  flex-wrap: wrap;
  padding: var(--mm-s-4) 0;
}
.mm-listado-bar-izq {
  display: flex;
  align-items: center;
  gap: var(--mm-s-3);
  flex-wrap: wrap;
  width: 100%;              /* en móvil la fila izquierda ocupa todo el ancho */
  min-width: 0;
}
@media (min-width: 768px) {
  .mm-listado-bar { padding-top: var(--mm-s-5); }
  .mm-listado-bar-izq { gap: var(--mm-s-5); width: auto; }
}

.mm-listado-total {
  margin: 0;
  font-size: var(--mm-t-sm);
  font-weight: var(--mm-w-semi);
  color: var(--mm-text);
}
.mm-listado-total:empty { display: none; }

.mm-listado-orden {
  display: inline-flex;
  align-items: center;
  gap: var(--mm-s-2);
  margin-left: auto;        /* con la fila a ancho completo, el orden va al extremo */
  font-size: var(--mm-t-xs);
  font-weight: var(--mm-w-medium);
  color: var(--mm-text-soft);
  white-space: nowrap;
}
/* El rótulo "Ordenar por" se omite en móvil: el select ya se explica solo. */
.mm-listado-orden > span { display: none; }
@media (min-width: 768px) {
  .mm-listado-orden { margin-left: 0; }
  .mm-listado-orden > span { display: inline; }
}
.mm-listado-orden select {
  max-width: 100%;
  height: var(--mm-ctl-h);
  padding: 0 var(--mm-s-3);
  border: 1px solid var(--mm-line);
  border-radius: var(--mm-r-xs);
  background: var(--mm-surface);
  color: var(--mm-ink);
  font-family: var(--mm-font);
  font-size: var(--mm-t-sm);
  font-weight: var(--mm-w-medium);
  cursor: pointer;
  transition: var(--mm-tr-color);
}
.mm-listado-orden select:hover { border-color: var(--mm-text-faint); }

.mm-listado-filtros-btn {
  display: none;            /* sólo ≤1023px: en desktop el sidebar está fijo */
  align-items: center;
  gap: var(--mm-s-2);
  height: var(--mm-ctl-h-touch);
  padding: 0 var(--mm-s-4);
  border: 1px solid var(--mm-line);
  border-radius: var(--mm-r-xs);
  background: var(--mm-surface);
  color: var(--mm-ink);
  font-family: var(--mm-font);
  font-size: var(--mm-t-sm);
  font-weight: var(--mm-w-semi);
  cursor: pointer;
  transition: var(--mm-tr-color);
}
.mm-listado-filtros-btn svg { width: 16px; height: 16px; }
.mm-listado-filtros-btn:hover { background: var(--mm-band); }

/* ── Paginación (misma pieza arriba y abajo del grid) ────────────────── */
.mm-pag {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--mm-s-2);
  flex-wrap: wrap;
  width: 100%;
}
.mm-pag:empty { display: none; }
/* :not(.mm-pag-abajo) — la paginación inferior queda centrada en todos los
   anchos; la de la barra superior vuelve a su lugar a la derecha. */
@media (min-width: 768px) {
  .mm-pag:not(.mm-pag-abajo) { width: auto; justify-content: flex-start; }
}

.mm-pag-lbl {
  font-size: var(--mm-t-sm);
  font-style: italic;
  font-weight: var(--mm-w-medium);
  color: var(--mm-text);
  margin-right: var(--mm-s-1);
}
.mm-pag-num,
.mm-pag-flecha {
  width: 32px;
  height: 32px;
  display: inline-grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--mm-line);
  border-radius: var(--mm-r-xs);
  background: var(--mm-surface);
  color: var(--mm-text);
  font-family: var(--mm-font);
  font-size: var(--mm-t-xs);
  font-weight: var(--mm-w-semi);
  line-height: 1;
  cursor: pointer;
  transition: var(--mm-tr-color);
}
.mm-pag-num:hover:not(.is-active),
.mm-pag-flecha:hover:not(:disabled) {
  background: var(--mm-band);
  color: var(--mm-ink);
}
.mm-pag-num.is-active {
  background: var(--mm-red);
  border-color: var(--mm-red);
  color: var(--mm-on-red);
  font-weight: var(--mm-w-bold);
  cursor: default;
}
.mm-pag-flecha { font-size: var(--mm-t-base); }
.mm-pag-flecha:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.mm-pag-gap {
  padding: 0 var(--mm-s-1);
  color: var(--mm-text-faint);
  font-size: var(--mm-t-sm);
  letter-spacing: 0.1em;
}
.mm-pag-abajo {
  justify-content: center;
  margin-top: var(--mm-s-10);
}

/* ── Banda de categoría (sólo con filtro de categoría activo) ────────── */
.mm-banda-cat {
  width: 100%;
  min-height: clamp(110px, 14vw, 150px);
  display: grid;
  place-items: center;
  padding: var(--mm-s-8) var(--mm-gutter);
  margin: var(--mm-s-4) 0 var(--mm-s-8);
  background: var(--mm-red);
  text-align: center;
}
.mm-banda-cat[hidden] { display: none; }
.mm-banda-cat-txt {
  color: var(--mm-on-red);
  font-size: var(--mm-t-3xl);
  font-weight: var(--mm-w-black);
  line-height: var(--mm-lh-tight);
  letter-spacing: var(--mm-ls-copy);
  text-transform: uppercase;
}

/* ──────────────────────────────────────────────────────────────────────
   2 · LAYOUT: sidebar de filtros + resultados
   ────────────────────────────────────────────────────────────────────── */

/* Una sola columna hasta 1024: debajo de ese ancho el sidebar es drawer
   (position: fixed) y no ocupa lugar en la grilla. */
.mm-listado-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--mm-s-6);
  align-items: start;
}
@media (min-width: 1024px) {
  .mm-listado-layout { grid-template-columns: 220px minmax(0, 1fr); }
}
@media (min-width: 1280px) {
  .mm-listado-layout {
    grid-template-columns: 260px minmax(0, 1fr);
    gap: var(--mm-s-8);
  }
}
.mm-listado-resultados { min-width: 0; }

/* ── Sidebar ─────────────────────────────────────────────────────────── */
.mm-filtros {
  background: var(--mm-surface);
  border: 1px solid var(--mm-line);
  border-radius: var(--mm-r-md);
  padding: var(--mm-s-5);
  position: sticky;
  top: calc(var(--mm-header-h, 132px) + var(--mm-s-4));
}
.mm-filtros-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--mm-s-3);
  margin-bottom: var(--mm-s-5);
}
.mm-filtros-head h2 {
  margin: 0;
  font-size: var(--mm-t-base);
  font-weight: var(--mm-w-bold);
  color: var(--mm-ink);
}
.mm-filtros-close {
  display: none;                 /* sólo en el drawer móvil */
  width: var(--mm-icon-btn);
  height: var(--mm-icon-btn);
  place-items: center;
  border: 0;
  background: none;
  color: var(--mm-text);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
}
.mm-filtros-grupo { margin-bottom: var(--mm-s-5); }
.mm-filtros-lbl {
  display: block;
  margin-bottom: var(--mm-s-2);
  font-size: var(--mm-t-eyebrow);
  font-weight: var(--mm-w-bold);
  text-transform: uppercase;
  letter-spacing: var(--mm-ls-wide);
  color: var(--mm-text-soft);
}
.mm-filtros-busca { position: relative; display: flex; align-items: center; }
.mm-filtros-busca svg {
  position: absolute;
  left: var(--mm-s-3);
  width: 16px;
  height: 16px;
  color: var(--mm-text-faint);
  pointer-events: none;
}

/* min-width: 0 — sin esto los input mantienen su ancho intrínseco (~150px) y
   los dos campos de precio desbordan el sidebar de 220px. */
.mm-filtros input,
.mm-filtros select {
  width: 100%;
  min-width: 0;
  height: var(--mm-ctl-h);
  padding: 0 var(--mm-s-3);
  border: 1px solid var(--mm-line);
  border-radius: var(--mm-r-xs);
  background: var(--mm-surface);
  color: var(--mm-ink);
  font-family: var(--mm-font);
  font-size: var(--mm-t-sm);
  transition: var(--mm-tr-color);
}
/* El hueco para la lupa va DESPUES de la regla generica de arriba: aquella
   usa el atajo `padding: 0 var(--mm-s-3)`, que reinicia el padding-left. Con
   la misma especificidad gana la ultima, asi que declarada antes se perdia y
   el icono quedaba encima del texto "Nombre o codigo...". */
.mm-filtros-busca input { padding-left: 34px; }

.mm-filtros input::placeholder { color: var(--mm-text-faint); }
.mm-filtros input:focus,
.mm-filtros select:focus {
  outline: none;
  border-color: var(--mm-red-accent);
  box-shadow: 0 0 0 3px var(--mm-red-tint);
}
.mm-filtros-precio {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--mm-s-2);
}
.mm-filtros-precio-sep { color: var(--mm-text-faint); }

.mm-filtros-acciones {
  display: flex;
  flex-direction: column;
  gap: var(--mm-s-2);
  margin-top: var(--mm-s-6);
}
.mm-filtros-aplicar {
  width: 100%;
  height: var(--mm-ctl-h-touch);
  border: 1px solid var(--mm-red);
  border-radius: var(--mm-r-xs);
  background: var(--mm-red);
  color: var(--mm-on-red);
  font-family: var(--mm-font);
  font-size: var(--mm-t-sm);
  font-weight: var(--mm-w-semi);
  cursor: pointer;
  transition: var(--mm-tr-color);
}
.mm-filtros-aplicar:hover { background: var(--mm-red-hover); border-color: var(--mm-red-hover); }
.mm-filtros-aplicar:active { background: var(--mm-red-active); }
.mm-filtros-limpiar {
  width: 100%;
  height: var(--mm-ctl-h);
  border: 0;
  background: transparent;
  color: var(--mm-text);
  font-family: var(--mm-font);
  font-size: var(--mm-t-sm);
  text-decoration: underline;
  cursor: pointer;
  transition: var(--mm-tr-color), transform var(--mm-dur-fast) var(--mm-ease);
}
@media (hover: hover) and (pointer: fine) {
  .mm-filtros-limpiar:hover { color: var(--mm-ink); }
}
.mm-filtros-limpiar:active { transform: scale(var(--mm-press, 0.97)); }

.mm-filtros-overlay {
  position: fixed;
  inset: 0;
  background: var(--mm-overlay);
  z-index: var(--mm-z-drawer);
  display: none;                 /* el drawer sólo existe ≤1023px */
}

/* ── Grilla ──────────────────────────────────────────────────────────── */
/* La cantidad de columnas la fija esta vista (la maqueta pide 4 en
   desktop). Es layout local del contenedor, no una redefinición de
   .mm-grid — el resto del sitio sigue con el auto-fill de mm-base.
   La cuarta columna entra recién en 1280: la maqueta dibuja 4 columnas a
   ancho completo, pero acá el sidebar de filtros (que la maqueta no tiene
   y el sitio sí) se lleva 260px. Entre 1024 y 1279 la cuarta columna
   dejaría tarjetas de ~160px, ilegibles; se usan 3. */
#productosGrid {
  display: grid;
  gap: var(--mm-grid-gap);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 768px)  { #productosGrid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1280px) { #productosGrid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* ── Entrada de la grilla ──────────────────────────────────────────────
   Las dos grillas de producto del sitio: #productsGrid (catálogo del home)
   y #productosGrid (listado). Las dos reciben las mismas .mm-card por
   innerHTML.

   Con `animation` y JAMÁS con .reveal: el IntersectionObserver lee el DOM
   una sola vez al arrancar, así que una tarjeta inyectada después nunca se
   observa y con .reveal se quedaría en opacity 0 para siempre. La
   animación, en cambio, se dispara sola al insertarse el nodo.

   `backwards` y no `both`: con `both` la animación conserva el control de
   `transform` después de terminar y el hover de la tarjeta dejaría de
   transicionar (la animación le gana a la transición). Con `backwards`
   sólo cubre el retardo, que es lo único que hace falta.
   Los keyframes mm-in-up (opacity + 8px de subida) viven en tokens.css. */
:is(#productsGrid, #productosGrid) > .mm-card {
  animation: mm-in-up var(--mm-dur-slow) var(--mm-ease-out) backwards;
}

/* Escalonado con tope duro: el paso se aplica a las 10 primeras y ahí se
   congela. La página trae hasta 24 tarjetas y calcular el retardo con el
   índice real daría casi un segundo de espera para la última; así el grupo
   entero termina en 315ms, se vea una fila o se vean seis. */
:is(#productsGrid, #productosGrid) > .mm-card:nth-child(1)  { animation-delay: 0ms; }
:is(#productsGrid, #productosGrid) > .mm-card:nth-child(2)  { animation-delay: calc(1 * var(--mm-stagger-grid, 35ms)); }
:is(#productsGrid, #productosGrid) > .mm-card:nth-child(3)  { animation-delay: calc(2 * var(--mm-stagger-grid, 35ms)); }
:is(#productsGrid, #productosGrid) > .mm-card:nth-child(4)  { animation-delay: calc(3 * var(--mm-stagger-grid, 35ms)); }
:is(#productsGrid, #productosGrid) > .mm-card:nth-child(5)  { animation-delay: calc(4 * var(--mm-stagger-grid, 35ms)); }
:is(#productsGrid, #productosGrid) > .mm-card:nth-child(6)  { animation-delay: calc(5 * var(--mm-stagger-grid, 35ms)); }
:is(#productsGrid, #productosGrid) > .mm-card:nth-child(7)  { animation-delay: calc(6 * var(--mm-stagger-grid, 35ms)); }
:is(#productsGrid, #productosGrid) > .mm-card:nth-child(8)  { animation-delay: calc(7 * var(--mm-stagger-grid, 35ms)); }
:is(#productsGrid, #productosGrid) > .mm-card:nth-child(9)  { animation-delay: calc(8 * var(--mm-stagger-grid, 35ms)); }
:is(#productsGrid, #productosGrid) > .mm-card:nth-child(10) { animation-delay: calc(9 * var(--mm-stagger-grid, 35ms)); }
:is(#productsGrid, #productosGrid) > .mm-card:nth-child(n+11) { animation-delay: 0s; }

/* MEDIDO: la grilla no se repinta sólo al filtrar o al cambiar de página.
   agregarAlCarrito() y cambiarCantidad() (app.js) llaman a renderCatalogo()
   y renderProductosView(), que rehacen el innerHTML ENTERO. Sin esta
   válvula, sumar una unidad con el "+" volvería a animar las 24 tarjetas
   cada vez.
   Si el puntero está sobre la grilla, el repintado salió de una tarjeta y
   no de una navegación: el retardo negativo deja la animación terminada
   antes del primer cuadro, así que no se ve nada.
   Se tocan la DURACIÓN y el RETARDO, nunca animation-name: cambiar el
   nombre relanza la animación, y al salir el mouse entrarían de nuevo
   todas las tarjetas. Va después de los nth-child porque empata en
   especificidad con ellos. */
:is(#productsGrid, #productosGrid):hover > .mm-card {
  animation-duration: 1ms;
  animation-delay: -1s;
}

/* Los skeletons no entran escalonados: son el hueco que espera, no
   contenido que llega. Su brillo lo pone .mm-skel en cada barra. */
:is(#productsGrid, #productosGrid) > .mm-card-skel { animation: none; }

/* ── Estados que pinta app.js dentro del grid ────────────────────────── */
.productos-loading,
.productos-empty {
  grid-column: 1 / -1;
  text-align: center;
  font-family: var(--mm-font);
}
.productos-loading {
  padding: var(--mm-s-12) 0;
  color: var(--mm-text-soft);
  font-size: var(--mm-t-sm);
}
/* Entra una sola vez, igual que una tarjeta: es contenido que llega, no un
   aviso que haya que subrayar. Nada de rebotes ni de bucles. */
.productos-empty {
  padding: var(--mm-s-12) var(--mm-s-6);
  background: var(--mm-surface-2);
  border: 1px solid var(--mm-line-soft);
  border-radius: var(--mm-r-md);
  animation: mm-in-up var(--mm-dur-slow) var(--mm-ease-out) both;
}

/* cards.css hace flotar este cartel para siempre (noResultsBob, 2s
   infinite). Un "sin resultados" que se mueve solo es ruido: se apaga. */
.no-results-empty { animation: none; }
.productos-empty h3 {
  margin: var(--mm-s-3) 0 var(--mm-s-2);
  font-size: var(--mm-t-lg);
  font-weight: var(--mm-w-bold);
  color: var(--mm-ink);
}
.productos-empty p {
  margin: 0;
  color: var(--mm-text);
  font-size: var(--mm-t-sm);
  line-height: var(--mm-lh-body);
}
/* El botón de los estados vacíos: mismo look venga con .mm-empty-btn
   (renderProductosView) o con las clases legacy .ds-btn .ds-btn-red
   (renderFavoritosGateNoSesion, fuera del alcance de esta tarea). */
.productos-empty .mm-empty-btn,
.productos-empty .ds-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: var(--mm-ctl-h-touch);
  margin-top: var(--mm-s-4);
  padding: 0 var(--mm-ctl-pad-x);
  border: 1px solid var(--mm-red);
  border-radius: var(--mm-r-xs);
  background: var(--mm-red);
  color: var(--mm-on-red);
  font-family: var(--mm-font);
  font-size: var(--mm-t-sm);
  font-weight: var(--mm-w-semi);
  text-decoration: none;
  cursor: pointer;
  transition: var(--mm-tr-color), transform var(--mm-dur-fast) var(--mm-ease);
}
@media (hover: hover) and (pointer: fine) {
  .productos-empty .mm-empty-btn:hover,
  .productos-empty .ds-btn:hover { background: var(--mm-red-hover); border-color: var(--mm-red-hover); }
}
/* Es la única salida del callejón sin salida: que se note que respondió. */
.productos-empty .mm-empty-btn:active,
.productos-empty .ds-btn:active { transform: scale(var(--mm-press, 0.97)); }

/* ──────────────────────────────────────────────────────────────────────
   3 · PANEL "VER TODAS LAS CATEGORÍAS" + pill "Ver más productos"
   ────────────────────────────────────────────────────────────────────── */

.mm-cats {
  margin-top: var(--mm-s-16);
  padding-block: var(--mm-section-y);
  background: var(--mm-band);
}
.mm-cats[hidden] { display: none; }

.mm-cats-card {
  background: var(--mm-surface);
  border-radius: var(--mm-r-lg);
  padding: clamp(20px, 3vw, 36px);
  box-shadow: var(--mm-sh-card);
}
.mm-cats-titulo {
  margin: 0 0 var(--mm-s-6);
  font-size: var(--mm-t-2xl);
  font-weight: var(--mm-w-black);
  letter-spacing: var(--mm-ls-tight);
  color: var(--mm-ink);
}
/* Sin media queries de conteo: el ancho mínimo de la baldosa crece con la
   pantalla (20vw) y eso da 1 · 2 · 3 · 4 columnas solo. El clamp es
   necesario porque el contenedor salta de ~300px a 1416px: con un minmax
   fijo se obtienen 4 columnas en tablet o 7 en escritorio ancho. */
.mm-cats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, clamp(190px, 20vw, 320px)), 1fr));
  gap: var(--mm-s-4);
}

/* En telefono la rejilla se derrumbaba a una columna y 17 categorias se
   convertian en 17 filas: media pantalla de scroll para elegir una. Pasa a
   ser UNA SOLA FILA que se arrastra de lado, el mismo gesto que ya usan los
   carruseles del home. `auto-flow: column` con `grid-auto-columns` fija el
   ancho de la baldosa; sin el, todas se aplastarian en el ancho visible. */
@media (max-width: 767px) {
  .mm-cats-grid {
    grid-auto-flow: column;
    grid-auto-columns: 78%;
    grid-template-columns: none;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    /* El respiro lateral va en padding y no en margin para que la primera
       y la ultima baldosa no queden pegadas al borde al hacer scroll. */
    padding-bottom: var(--mm-s-2);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .mm-cats-grid::-webkit-scrollbar { display: none; }
  .mm-cats-grid .mm-cat-tile { scroll-snap-align: start; }
}
/* Selector descendiente a propósito: .mm-cat-tile y .mm-cat-tile-mono
   también los usa la banda de categorías del home (mm-home.css, T2). Como
   esta hoja carga después, sin acotar al panel le pisaba el layout a esa
   otra vista. */
.mm-cats-grid .mm-cat-tile {
  display: grid;
  grid-template-columns: clamp(64px, 9vw, 84px) minmax(0, 1fr);
  align-items: stretch;
  /* padding y gap en 0 a propósito: la regla `.mm-cat-tile` de mm-home.css
     (la baldosa del home, que es flex) les pone 16/20px y 12px de gap, y
     como acá no se redeclaraban se colaban por cascada y despegaban el
     monograma del borde. La baldosa del panel es a sangre. */
  padding: 0;
  gap: 0;
  min-height: clamp(72px, 9vw, 84px);
  border: 1px solid var(--mm-line-soft);
  border-radius: var(--mm-r-sm);
  background: var(--mm-surface);
  overflow: hidden;
  text-align: left;
  cursor: pointer;
  transition: var(--mm-tr-color), var(--mm-tr-motion);
}
.mm-cats-grid .mm-cat-tile:hover {
  border-color: var(--mm-red-border);
  box-shadow: var(--mm-sh-hover);
}
.mm-cats-grid .mm-cat-tile:focus-visible {
  outline: var(--mm-focus-ring);
  outline-offset: var(--mm-focus-offset);
}
/* Sin fotos de categoría en la base: la mitad izquierda es un monograma
   sobre fondo neutro, nunca una imagen de stock. */
.mm-cats-grid .mm-cat-tile-mono {
  display: grid;
  place-items: center;
  background: var(--mm-band);
  color: var(--mm-red);
  /* La fuente de emoji delante: si la categoría no tiene glifo, el
     respaldo es una letra y esa cae igual en Poppins por la propia
     cascada de la pila. */
  font-family: var(--mm-font-emoji), var(--mm-font);
  font-size: var(--mm-t-xl);
  font-weight: var(--mm-w-black);
  letter-spacing: var(--mm-ls-tight);
}
/* Los nombres de categoría del ERP vienen a veces como una sola ristra sin
   espacios: sin min-width/overflow-wrap ensanchan la columna y desbordan. */
.mm-cat-tile-nombre {
  display: flex;
  align-items: center;
  min-width: 0;
  overflow-wrap: break-word;
  padding: var(--mm-s-3) var(--mm-s-4);
  font-family: var(--mm-font);
  font-size: var(--mm-t-sm);
  font-weight: var(--mm-w-medium);
  line-height: var(--mm-lh-snug);
  color: var(--mm-ink);
}

.mm-cats-mas {
  display: flex;
  justify-content: center;
  margin-top: var(--mm-s-8);
}
/* Los primitivos .mm-btn-* traen su propio `display`, que gana al
   [hidden] de la hoja del navegador: hay que apagarlo a mano. */
.mm-cats-mas [hidden],
#productosVerMas[hidden] { display: none; }
#productosVerMas { min-height: var(--mm-ctl-h-touch); }

/* ──────────────────────────────────────────────────────────────────────
   4 · MODAL DE DETALLE DE PRODUCTO
   ────────────────────────────────────────────────────────────────────── */

/* El display del modal lo siguen manejando las utilidades hidden/flex que
   togglea app.js: acá no se toca `display`. */
.mm-detalle-modal {
  position: fixed;
  inset: 0;
  z-index: var(--mm-z-modal);
  background: var(--mm-overlay);
  padding: var(--mm-s-4);
  font-family: var(--mm-font);
}
.mm-detalle-caja {
  position: relative;
  width: 100%;
  max-width: 1040px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  background: var(--mm-surface);
  border-radius: var(--mm-r-lg);
  box-shadow: var(--mm-sh-modal);
  overflow: hidden;
}
.mm-detalle-cerrar {
  position: absolute;
  top: var(--mm-s-4);
  right: var(--mm-s-4);
  z-index: 2;
  width: var(--mm-icon-btn);
  height: var(--mm-icon-btn);
  display: grid;
  place-items: center;
  border: 1px solid var(--mm-line);
  border-radius: var(--mm-r-full);
  background: var(--mm-surface);
  color: var(--mm-text);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  transition: var(--mm-tr-color);
}
.mm-detalle-cerrar:hover { background: var(--mm-band); color: var(--mm-ink); }
.mm-detalle-scroll { overflow-y: auto; }

.mm-detalle {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}
.mm-detalle-media {
  min-width: 0;
  background: var(--mm-surface-2);
  padding: clamp(16px, 2.4vw, 28px);
  border-bottom: 1px solid var(--mm-line-soft);
}
.mm-detalle-info {
  min-width: 0;
  background: var(--mm-surface);
  padding: clamp(20px, 3vw, 36px);
}
.mm-detalle-info-inner {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
  max-width: 460px;
  margin-inline: auto;
}

/* ── Galería ─────────────────────────────────────────────────────────── */
.mm-detalle-galeria { height: 100%; }
.mm-detalle-galeria-col {
  display: flex;
  flex-direction: column;
  gap: var(--mm-s-3);
  height: 100%;
}
/* El alto del visor acompaña al ancho de pantalla: en una sola columna un
   mínimo fijo de 280px empuja el precio y el botón fuera del viewport. */
.mm-detalle-img-wrap {
  position: relative;
  flex: 1;
  min-height: clamp(200px, 30vw, 280px);
  display: grid;
  place-items: center;
  background: var(--mm-surface);
  border: 1px solid var(--mm-line-soft);
  border-radius: var(--mm-r-md);
  overflow: hidden;
}
.mm-detalle-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: clamp(12px, 2vw, 24px);
}
/* Hoy el catálogo no tiene fotos cargadas: el "sin imagen" es el estado
   habitual, así que se diseña a escala grande y no como excepción. */
.mm-detalle-sinimg {
  display: grid;
  place-items: center;
  gap: var(--mm-s-3);
  width: 100%;
  height: 100%;
  min-height: clamp(200px, 30vw, 280px);
  color: var(--mm-text-faint);
  text-align: center;
}
.mm-detalle-sinimg svg { width: clamp(52px, 9vw, 72px); height: clamp(52px, 9vw, 72px); stroke-width: 1.1; }
.mm-detalle-sinimg span {
  font-size: var(--mm-t-sm);
  font-weight: var(--mm-w-semi);
  letter-spacing: var(--mm-ls-copy);
  text-transform: uppercase;
}
.mm-detalle-thumbs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--mm-s-2);
  flex-shrink: 0;
}
.mm-detalle-thumb {
  width: clamp(56px, 8vw, 68px);
  height: clamp(56px, 8vw, 68px);
  padding: 0;
  border: 2px solid var(--mm-line-soft);
  border-radius: var(--mm-r-sm);
  background: var(--mm-surface);
  overflow: hidden;
  opacity: 0.75;
  cursor: pointer;
  transition: var(--mm-tr-color), opacity var(--mm-dur-fast) ease;
}
.mm-detalle-thumb:hover { opacity: 1; border-color: var(--mm-line); }
.mm-detalle-thumb.is-activa { opacity: 1; border-color: var(--mm-red); }
.mm-detalle-thumb img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 6px;
}

/* ── Panel derecho ───────────────────────────────────────────────────── */
.mm-detalle-eyebrow {
  margin: 0;
  padding-right: 48px;          /* deja libre la esquina del botón cerrar */
  font-size: var(--mm-t-eyebrow);
  font-weight: var(--mm-w-bold);
  text-transform: uppercase;
  letter-spacing: var(--mm-ls-eyebrow);
  color: var(--mm-red-accent);
}
.mm-detalle-codigo {
  display: block;
  margin-top: 2px;
  font-size: var(--mm-t-eyebrow);
  font-weight: var(--mm-w-medium);
  letter-spacing: var(--mm-ls-copy);
  text-transform: none;
  color: var(--mm-text-faint);
}
.mm-detalle-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--mm-s-3);
  margin-top: var(--mm-s-3);
  padding-right: 48px;
}
/* Los nombres del ERP llegan como códigos largos sin espacios: sin
   min-width/overflow-wrap estiran el flex y desbordan el modal. */
.mm-detalle-titulo {
  margin: 0;
  min-width: 0;
  overflow-wrap: break-word;
  font-family: var(--mm-font);   /* la maqueta usa Poppins, no serif */
  font-size: var(--mm-t-xl);
  font-weight: var(--mm-w-bold);
  line-height: var(--mm-lh-snug);
  letter-spacing: var(--mm-ls-tight);
  color: var(--mm-ink);
}
.mm-detalle-fav {
  flex-shrink: 0;
  width: var(--mm-icon-btn);
  height: var(--mm-icon-btn);
  display: grid;
  place-items: center;
  border: 1px solid var(--mm-line);
  border-radius: var(--mm-r-full);
  background: var(--mm-surface);
  color: var(--mm-text-faint);
  cursor: pointer;
  transition: var(--mm-tr-color);
}
.mm-detalle-fav svg { width: 18px; height: 18px; }
.mm-detalle-fav:hover { color: var(--mm-red-accent); border-color: var(--mm-red-border); }
.mm-detalle-fav.is-activo {
  color: var(--mm-red-accent);
  border-color: var(--mm-red-accent);
  background: var(--mm-red-tint);
}

/* Precio: negro en reposo (p06) y rojo sólo cuando el mayoreo YA aplica. */
.mm-detalle-precio-wrap { margin-top: var(--mm-s-5); }
.mm-detalle-precio {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: var(--mm-s-2);
}
/* El tamaño lo pone el detalle; el peso, el color y los centavos en
   superíndice los sigue mandando el primitivo .mm-price de mm-base.css. */
.mm-detalle-precio > .mm-price { font-size: var(--mm-t-3xl); }
.mm-detalle-precio.is-descuento > .mm-price { color: var(--mm-red-accent); }
.mm-detalle-precio-antes {
  margin-bottom: 4px;
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}
.mm-detalle-precio-antes .mm-price {
  font-size: var(--mm-t-lg);
  font-weight: var(--mm-w-medium);
  color: var(--mm-text-soft);
}
.mm-detalle-precio-badge {
  margin-bottom: 4px;
  padding: 2px 6px;
  border-radius: var(--mm-r-xs);
  background: var(--mm-red-tint);
  color: var(--mm-red);
  font-size: var(--mm-t-xs);
  font-weight: var(--mm-w-black);
  line-height: 1.4;
}
.mm-detalle-precio-nota {
  align-self: flex-end;
  margin-bottom: 4px;
  font-size: var(--mm-t-xs);
  color: var(--mm-text-soft);
}

/* Aviso de mayoreo — el ÚNICO descuento real del sitio. */
.mm-detalle-desc { margin-top: var(--mm-s-3); }
.mm-detalle-desc:empty { display: none; }
.mm-detalle-mayoreo {
  display: flex;
  align-items: center;
  gap: var(--mm-s-2);
  padding: var(--mm-s-2) var(--mm-s-3);
  border: 1px solid var(--mm-warn-border);
  border-radius: var(--mm-r-sm);
  background: var(--mm-warn-bg);
  color: var(--mm-warn-text);
}
.mm-detalle-mayoreo svg { width: 16px; height: 16px; flex-shrink: 0; color: var(--mm-warn); }
.mm-detalle-mayoreo p {
  margin: 0;
  font-size: var(--mm-t-xs);
  font-weight: var(--mm-w-medium);
  line-height: var(--mm-lh-snug);
}
.mm-detalle-mayoreo b { font-weight: var(--mm-w-bold); }
.mm-detalle-mayoreo-ok {
  margin: 0;
  font-size: var(--mm-t-xs);
  font-weight: var(--mm-w-semi);
  color: var(--mm-ok-text);
}

/* Stock / Estado */
.mm-detalle-meta {
  display: flex;
  gap: var(--mm-s-10);
  margin-top: var(--mm-s-6);
  padding: var(--mm-s-4) 0;
  border-top: 1px solid var(--mm-line-soft);
  border-bottom: 1px solid var(--mm-line-soft);
}
.mm-detalle-meta-lbl {
  margin: 0;
  font-size: var(--mm-t-eyebrow);
  font-weight: var(--mm-w-semi);
  text-transform: uppercase;
  letter-spacing: var(--mm-ls-wide);
  color: var(--mm-text-soft);
}
.mm-detalle-meta-val {
  margin: var(--mm-s-2) 0 0;
  font-size: var(--mm-t-lg);
  font-weight: var(--mm-w-bold);
  line-height: 1;
  color: var(--mm-ink);
}
.mm-badge-stock {
  display: inline-flex;
  align-items: center;
  margin-top: var(--mm-s-2);
  padding: 4px 10px;
  border-radius: var(--mm-r-full);
  font-size: var(--mm-t-eyebrow);
  font-weight: var(--mm-w-bold);
  line-height: 1.2;
}
.mm-badge-ok   { background: var(--mm-ok-bg);     color: var(--mm-ok-text); }
.mm-badge-warn { background: var(--mm-warn-bg);   color: var(--mm-warn-text); }
.mm-badge-bad  { background: var(--mm-danger-bg); color: var(--mm-danger-text); }

/* Descripción */
.mm-detalle-bloque { margin-top: var(--mm-s-5); }
.mm-detalle-lbl {
  margin: 0 0 var(--mm-s-2);
  font-size: var(--mm-t-eyebrow);
  font-weight: var(--mm-w-semi);
  text-transform: uppercase;
  letter-spacing: var(--mm-ls-wide);
  color: var(--mm-text-soft);
}
.mm-detalle-txt {
  margin: 0;
  overflow-wrap: break-word;
  font-size: var(--mm-t-sm);
  line-height: var(--mm-lh-body);
  color: var(--mm-text);
}

/* Features — se acomodan por ancho del panel (no del viewport): en el modal
   de una sola columna quedan apiladas y en el de dos, de a dos. */
.mm-detalle-features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  gap: var(--mm-s-3);
  margin-top: var(--mm-s-5);
  padding-top: var(--mm-s-5);
  border-top: 1px solid var(--mm-line-soft);
}
.mm-detalle-feature {
  display: flex;
  align-items: center;
  gap: var(--mm-s-3);
  min-width: 0;
}
.mm-detalle-feature-ico {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: var(--mm-r-sm);
  background: var(--mm-band);
  color: var(--mm-ink);
}
.mm-detalle-feature-ico svg { width: 18px; height: 18px; }
.mm-detalle-feature-txt p { margin: 0; }
.mm-detalle-feature-tit {
  font-size: var(--mm-t-xs);
  font-weight: var(--mm-w-bold);
  color: var(--mm-ink);
}
.mm-detalle-feature-sub {
  font-size: var(--mm-t-eyebrow);
  color: var(--mm-text-soft);
}

/* Cantidad + acciones */
.mm-detalle-acciones {
  margin-top: auto;
  padding-top: var(--mm-s-7);
  display: flex;
  flex-direction: column;
  gap: var(--mm-s-3);
}
.mm-detalle-cantidad {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--mm-s-3);
}
.mm-detalle-cantidad-lbl {
  font-size: var(--mm-t-eyebrow);
  font-weight: var(--mm-w-semi);
  text-transform: uppercase;
  letter-spacing: var(--mm-ls-wide);
  color: var(--mm-text-soft);
}
.mm-detalle-stepper {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--mm-line);
  border-radius: var(--mm-r-sm);
  overflow: hidden;
}
.mm-detalle-stepper button {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border: 0;
  background: var(--mm-surface);
  color: var(--mm-text);
  font-size: var(--mm-t-lg);
  line-height: 1;
  cursor: pointer;
  user-select: none;
  transition: var(--mm-tr-color);
}
.mm-detalle-stepper button:hover { background: var(--mm-band); color: var(--mm-ink); }
.mm-detalle-stepper input {
  width: 52px;
  height: 40px;
  border: 0;
  border-inline: 1px solid var(--mm-line);
  background: var(--mm-surface);
  color: var(--mm-ink);
  font-family: var(--mm-font);
  font-size: var(--mm-t-sm);
  font-weight: var(--mm-w-bold);
  text-align: center;
  outline: none;
}

/* Los dos botones se apilan solos cuando no entran de a dos (base 180px),
   sin necesidad de un breakpoint. */
.mm-detalle-btns {
  display: flex;
  flex-wrap: wrap;
  gap: var(--mm-s-3);
}
.mm-detalle-btn {
  flex: 1 1 180px;
  min-width: 0;
  min-height: var(--mm-ctl-h-lg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--mm-s-2);
  padding: 0 var(--mm-s-4);
  border: 1px solid transparent;
  border-radius: var(--mm-r-sm);
  font-family: var(--mm-font);
  font-size: var(--mm-t-sm);
  font-weight: var(--mm-w-semi);
  cursor: pointer;
  transition: var(--mm-tr-color);
}
.mm-detalle-btn-cart {
  background: var(--mm-red);
  border-color: var(--mm-red);
  color: var(--mm-on-red);
}
.mm-detalle-btn-cart:hover { background: var(--mm-red-hover); border-color: var(--mm-red-hover); }
.mm-detalle-btn-cart:disabled {
  background: var(--mm-disabled-bg);
  border-color: var(--mm-disabled-bg);
  color: var(--mm-disabled-text);
  cursor: not-allowed;
}
.mm-detalle-btn-wa {
  background: var(--mm-surface);
  border-color: var(--mm-wa);
  color: var(--mm-wa-deep);
}
.mm-detalle-btn-wa:hover { background: var(--mm-ok-bg); }
.mm-detalle-btn-wa svg { width: 16px; height: 16px; }
.mm-detalle-btn-video {
  width: 100%;
  min-height: var(--mm-ctl-h);
  border: 1px solid var(--mm-line);
  border-radius: var(--mm-r-sm);
  background: var(--mm-surface);
  color: var(--mm-text);
  font-family: var(--mm-font);
  font-size: var(--mm-t-xs);
  font-weight: var(--mm-w-medium);
  cursor: pointer;
  transition: var(--mm-tr-color);
}
.mm-detalle-btn-video:hover { background: var(--mm-band); color: var(--mm-ink); }

/* Vista dividida: el panel "Tu pedido" se abre al lado del modal, no
   encima. Sólo desktop; en móvil el carrito es overlay full-width.
   768 exacto: la contraparte de .cart-preview (mm-cuenta.css) usa
   max-width: 767.98px — el par no deja hueco ni solape en el píxel 768. */
@media (min-width: 768px) {
  body.modal-cart-split .mm-detalle-modal {
    background: transparent;
    /* El panel mide --mm-cart-panel-w; los 20px extra son el aire entre el
       modal y el panel. Antes acá había un 400 suelto que no se enteraba
       si el panel cambiaba de ancho. */
    padding-right: calc(var(--mm-cart-panel-w) + var(--mm-s-5));
    align-items: flex-start;
    padding-top: 84px;
    padding-bottom: var(--mm-s-6);
    /* AUDITORÍA: sin transición. Animar el padding de un overlay a pantalla
       completa relaquetea el modal entero (galería, ficha y stepper) en cada
       cuadro. Se corre de una vez, en el mismo gesto en que entra el panel
       —que sí se mueve con transform— y nadie percibe el corte. */
  }
  body.modal-cart-split .mm-detalle-caja { max-height: calc(100vh - 108px); }
  body.modal-cart-split #cartPreviewOverlay { display: none; }
}

@media (min-width: 1024px) {
  .mm-detalle {
    grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
    min-height: 520px;
  }
  .mm-detalle-media { border-bottom: 0; border-right: 1px solid var(--mm-line-soft); }
}

/* ──────────────────────────────────────────────────────────────────────
   5 · MODAL DEL BUSCADOR (sólo texto — no hay búsqueda por foto)
   ────────────────────────────────────────────────────────────────────── */

.mm-busc-modal {
  position: fixed;
  inset: 0;
  z-index: var(--mm-z-modal);
  font-family: var(--mm-font);
}
.mm-busc-backdrop {
  position: absolute;
  inset: 0;
  background: transparent;
  transition: background-color var(--mm-dur-base) var(--mm-ease);
}
.mm-busc-backdrop.is-atenuado { background: var(--mm-overlay); }
.mm-busc-panel {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  max-height: 92vh;
  background: var(--mm-surface);
  border-bottom: 1px solid var(--mm-line-soft);
  border-radius: 0 0 var(--mm-r-md) var(--mm-r-md);
  box-shadow: var(--mm-sh-pop);
}
.mm-busc-barra {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: var(--mm-s-3);
  padding: var(--mm-s-4);
  border-bottom: 1px solid var(--mm-line-soft);
}
@media (min-width: 768px) {
  .mm-busc-barra { padding-inline: var(--mm-gutter); }
}
.mm-busc-barra > svg {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  color: var(--mm-red-accent);
}
#buscadorModalInput {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: none;
  background: transparent;
  font-family: var(--mm-font);
  font-size: var(--mm-t-xl);
  font-weight: var(--mm-w-semi);
  color: var(--mm-ink);
}
#buscadorModalInput::placeholder { color: var(--mm-text-faint); font-weight: var(--mm-w-regular); }
#buscadorModalInput::-webkit-search-cancel-button,
#buscadorModalInput::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }
#buscadorModalInput::-ms-clear { display: none; width: 0; height: 0; }

.mm-busc-cerrar {
  flex-shrink: 0;
  width: var(--mm-icon-btn);
  height: var(--mm-icon-btn);
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--mm-r-full);
  background: transparent;
  color: var(--mm-text);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  transition: var(--mm-tr-color);
}
.mm-busc-cerrar:hover { background: var(--mm-band); color: var(--mm-ink); }

.mm-busc-cuerpo {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--mm-s-5) var(--mm-s-4);
}
@media (min-width: 768px) {
  .mm-busc-cuerpo { padding-inline: var(--mm-gutter); }
}
.mm-busc-hist { margin-bottom: var(--mm-s-5); }
.mm-busc-hist-tit {
  margin: 0 0 var(--mm-s-3);
  font-size: var(--mm-t-eyebrow);
  font-weight: var(--mm-w-bold);
  text-transform: uppercase;
  letter-spacing: var(--mm-ls-eyebrow);
  color: var(--mm-text-soft);
}
.mm-busc-chip {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  gap: var(--mm-s-2);
  padding: 6px 8px 6px 14px;
  border: 1px solid var(--mm-line-soft);
  border-radius: var(--mm-r-full);
  background: var(--mm-surface-2);
  font-size: var(--mm-t-sm);
  font-weight: var(--mm-w-medium);
  color: var(--mm-text);
  transition: var(--mm-tr-color);
  scroll-snap-align: start;
}
.mm-busc-chip:hover { background: var(--mm-band); }
.mm-busc-chip button {
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  white-space: nowrap;
}
.mm-busc-chip button:hover { color: var(--mm-red-accent); }
.mm-busc-chip-x {
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  border-radius: var(--mm-r-full);
  color: var(--mm-text-faint);
}
.mm-busc-chip-x:hover { background: var(--mm-surface); color: var(--mm-red-accent); }

/* Flechas del carrusel de historial (clases que emite buscador.js y que
   hoy pinta ecommerce.css: acá se re-tematizan con los tokens). */
.buscador-hist-flecha {
  width: 28px;
  height: 28px;
  border: 1px solid var(--mm-line);
  border-radius: var(--mm-r-full);
  background: var(--mm-surface);
  color: var(--mm-text);
  box-shadow: var(--mm-sh-arrow);
}
.buscador-hist-flecha:hover { background: var(--mm-band); }
.buscador-hist-flecha.hidden { display: none; }

/* Mismo criterio que .productos-empty: una entrada y se queda quieto. */
.mm-busc-vacio {
  padding: var(--mm-s-10) var(--mm-s-4);
  text-align: center;
  color: var(--mm-text-soft);
  animation: mm-in-up var(--mm-dur-slow) var(--mm-ease-out) both;
}
.mm-busc-vacio.hidden { display: none; }
.mm-busc-vacio-ico { font-size: 44px; margin-bottom: var(--mm-s-3); }
.mm-busc-vacio h3 {
  margin: 0;
  font-size: var(--mm-t-lg);
  font-weight: var(--mm-w-bold);
  color: var(--mm-ink);
}
.mm-busc-vacio p {
  margin: var(--mm-s-2) 0 0;
  font-size: var(--mm-t-sm);
  color: var(--mm-text);
}

/* Escalera 2 · 3 · 4 · 5 columnas sin media queries: el panel es tan ancho
   como el viewport, así que el mínimo de la tarjeta puede crecer con él
   (15vw) y el auto-fit hace el resto. */
#buscadorResultados {
  display: grid;
  gap: var(--mm-grid-gap);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, clamp(150px, 15vw, 290px)), 1fr));
}
#buscadorResultados u { text-decoration-color: var(--mm-red-accent); text-underline-offset: 2px; }

.mm-busc-todos {
  flex-shrink: 0;
  width: 100%;
  min-height: var(--mm-ctl-h-lg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--mm-s-2);
  border: 0;
  border-top: 1px solid var(--mm-line-soft);
  background: var(--mm-red);
  color: var(--mm-on-red);
  font-family: var(--mm-font);
  font-size: var(--mm-t-sm);
  font-weight: var(--mm-w-bold);
  text-transform: uppercase;
  letter-spacing: var(--mm-ls-wide);
  cursor: pointer;
  transition: var(--mm-tr-color);
}
.mm-busc-todos:hover { background: var(--mm-red-hover); }
.mm-busc-todos.hidden { display: none; }
.mm-busc-todos svg { width: 16px; height: 16px; }

/* ──────────────────────────────────────────────────────────────────────
   6 · RESPONSIVE
   ────────────────────────────────────────────────────────────────────── */

/* El sidebar pasa a drawer y aparece el botón "Filtros".
   max-width legítimo: apaga una prestación exclusiva de escritorio.
   El .98 no es cosmético: con 1023 pelado, a 1023.5px de viewport (zoom del
   navegador o devicePixelRatio fraccionario) no aplica ni esta regla ni la
   de min-width: 1024px, y el sidebar se queda sin ser ni columna ni drawer. */
@media (max-width: 1023.98px) {
  .mm-listado-filtros-btn { display: inline-flex; }

  .mm-filtros {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: min(88vw, 340px);
    z-index: calc(var(--mm-z-drawer) + 1);
    border: 0;
    border-right: 1px solid var(--mm-line);
    border-radius: 0;
    padding: var(--mm-s-5) var(--mm-s-5) var(--mm-s-10);
    overflow-y: auto;
    transform: translateX(-100%);
    transition: transform var(--mm-dur-base) var(--mm-ease-out);
  }
  .mm-filtros.is-open { transform: translateX(0); }
  .mm-filtros-close { display: grid; }
  .mm-filtros-overlay { display: block; }
  .mm-filtros-overlay[hidden] { display: none; }
}

/* ──────────────────────────────────────────────────────────────────────
   7 · ÁREA TÁCTIL (táctil = todo lo que está debajo de 1024)
   ──────────────────────────────────────────────────────────────────────
   Meta: 44x44 de área activa con el ícono del mismo tamaño visual que en
   escritorio. Los controles sin fondo ni borde propio se agrandan de
   verdad (crecer la caja no se ve); los que sí tienen forma visible usan
   un halo con ::after. --mm-tap lo define tokens.css; 44px es el respaldo
   por si esta hoja se carga sin él.                                      */
@media (max-width: 1023.98px) {

  .mm-listado-orden select { height: var(--mm-tap, 44px); }

  /* Paginación: dos halos contiguos se pisarían (32 + 6 + 6 de desborde
     contra un gap de 8px), así que acá crece la caja, no un pseudo. */
  .mm-pag-num,
  .mm-pag-flecha {
    width: var(--mm-tap, 44px);
    height: var(--mm-tap, 44px);
  }

  /* Drawer de filtros: campos a lo ancho, sin vecinos que estorben. */
  .mm-filtros input,
  .mm-filtros select { height: var(--mm-tap, 44px); }
  .mm-filtros-limpiar { height: auto; min-height: var(--mm-tap, 44px); }
  .mm-filtros-close {
    width: var(--mm-tap, 44px);
    height: var(--mm-tap, 44px);
  }

  /* Halos. .mm-detalle-cerrar ya es position: absolute y ancla solo. */
  .mm-detalle-fav,
  .mm-busc-cerrar { position: relative; }
  .mm-detalle-cerrar::after,
  .mm-detalle-fav::after,
  .mm-busc-cerrar::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%);
  }

  /* Stepper: el contenedor tiene overflow: hidden (recortaría el halo) y
     los botones están pegados al input, así que crece la fila entera. */
  .mm-detalle-stepper button {
    width: var(--mm-tap, 44px);
    height: var(--mm-tap, 44px);
  }
  .mm-detalle-stepper input { height: var(--mm-tap, 44px); }

  .mm-detalle-btn-video { min-height: var(--mm-tap, 44px); }

  /* El input del buscador no tiene borde ni fondo: crecer no se ve, pero
     el área para enfocarlo pasa de ~30px a 44. */
  #buscadorModalInput { min-height: var(--mm-tap, 44px); }

  /* Chips del historial. El ✕ mide 20px y el botón del texto le queda a
     8px: un halo centrado le robaría el borde. Se estira el chip a 44 de
     alto y el halo del ✕ crece SÓLO hacia afuera —los 8px de padding del
     chip más 4 del hueco del carril—, nunca hacia el texto. */
  .mm-busc-chip {
    min-height: var(--mm-tap, 44px);
    padding-block: 0;
  }
  .mm-busc-chip > button { align-self: stretch; }
  .mm-busc-chip-x { position: relative; }
  .mm-busc-chip-x::after {
    content: "";
    position: absolute;
    top: 50%;
    right: -12px;
    transform: translateY(-50%);
    width: 40px;
    height: var(--mm-tap, 44px);
  }

  /* Las flechas del carril ya son absolutas (ecommerce.css): el halo se
     ancla en ellas sin tocar su posición. Entra en el margen de 36px del
     wrapper .px-9, así que no se monta sobre el primer chip. */
  .buscador-hist-flecha::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: var(--mm-tap, 44px);
    height: var(--mm-tap, 44px);
    transform: translate(-50%, -50%);
  }
}

/* Aviso de por que aparecen estos resultados (tipeo corregido o sinonimo).
   Va junto al contador, en tono secundario: informa sin gritar. */
.productos-aviso-origen {
  color: var(--mm-texto-legible, #767676);
  font-weight: var(--mm-w-regular, 400);
  font-style: italic;
}

/* ──────────────────────────────────────────────────────────────────────
   7.b · FILTROS INSTANTÁNEOS — chips de filtros activos
   ──────────────────────────────────────────────────────────────────────
   Los filtros se aplican solos al cambiarlos, así que el usuario necesita
   ver en todo momento QUÉ está filtrando y poder deshacerlo de un gesto.
   Los chips van arriba de la grilla, no dentro del sidebar: en móvil el
   sidebar es un drawer cerrado y ahí no se verían.
   El contenedor #productosChips lo crea app.js en runtime.              */
.mm-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--mm-s-2);
  margin-bottom: var(--mm-s-4);
}
.mm-chips[hidden] { display: none; }

.mm-chips-lbl {
  font-size: var(--mm-t-eyebrow);
  font-weight: var(--mm-w-bold);
  text-transform: uppercase;
  letter-spacing: var(--mm-ls-wide);
  color: var(--mm-text-soft);
}

/* Cada chip es un <button>: foco, Enter y Espacio salen gratis del
   navegador. app.js añade Supr/Retroceso y flechas para moverse entre
   ellos. La "×" es decorativa (aria-hidden): el nombre accesible del
   botón es "Quitar filtro Categoría: Ferretería". */
.mm-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--mm-s-2);
  min-height: 32px;
  padding: 0 var(--mm-s-2) 0 var(--mm-s-3);
  border: 1px solid var(--mm-line);
  border-radius: var(--mm-r-full);
  background: var(--mm-surface);
  color: var(--mm-ink);
  font-family: var(--mm-font);
  font-size: var(--mm-t-xs);
  line-height: 1;
  cursor: pointer;
  max-width: 100%;
  transition: var(--mm-tr-color);
}
.mm-chip-k {
  font-weight: var(--mm-w-bold);
  text-transform: uppercase;
  letter-spacing: var(--mm-ls-wide);
  color: var(--mm-text-soft);
  white-space: nowrap;
}
.mm-chip-v {
  font-weight: var(--mm-w-semi);
  color: var(--mm-ink);
  /* Un término de búsqueda largo no puede empujar la fila fuera del ancho. */
  max-width: 18ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mm-chip-x {
  display: inline-grid;
  place-items: center;
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  border-radius: var(--mm-r-full);
  background: var(--mm-band);
  color: var(--mm-text);
  font-size: 15px;
  line-height: 1;
  transition: var(--mm-tr-color);
}
@media (hover: hover) and (pointer: fine) {
  .mm-chip:hover {
    border-color: var(--mm-red);
    background: var(--mm-red-tint);
  }
  .mm-chip:hover .mm-chip-x {
    background: var(--mm-red);
    color: var(--mm-on-red);
  }
  .mm-chip:hover .mm-chip-k { color: var(--mm-red); }
}
.mm-chip:active { transform: scale(var(--mm-press, 0.97)); }

/* "Quitar todos": mismo alto, sin la caja de la ×, en tono de enlace. */
.mm-chip-todo {
  padding-inline: var(--mm-s-3);
  border-style: dashed;
  color: var(--mm-text);
  font-weight: var(--mm-w-semi);
  text-decoration: underline;
}

/* Contador de filtros activos sobre el botón "Filtros" de la barra: en
   móvil el sidebar está cerrado y es el único sitio donde se ve. */
.mm-listado-filtros-n {
  display: inline-grid;
  place-items: center;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border-radius: var(--mm-r-full);
  background: var(--mm-red);
  color: var(--mm-on-red);
  font-size: var(--mm-t-eyebrow);
  font-weight: var(--mm-w-bold);
  line-height: 1;
}

/* Ya no existe "Aplicar" — los filtros se aplican solos. Ese botón sobrevive
   solo como el "Ver N resultados" del drawer móvil (cierra el panel y lleva
   a la grilla). En escritorio el sidebar está siempre a la vista y no hay
   nada que cerrar: sobra. */
@media (min-width: 1024px) {
  .mm-filtros-aplicar { display: none; }
  .mm-filtros-acciones { margin-top: var(--mm-s-5); }
}
@media (max-width: 1023.98px) {
  /* Área táctil: los chips son objetivos pequeños y se tocan con el pulgar. */
  .mm-chip { min-height: var(--mm-tap, 44px); padding-inline: var(--mm-s-4) var(--mm-s-3); }
  .mm-chip-x { width: 24px; height: 24px; font-size: 17px; }
  .mm-chip-v { max-width: 14ch; }
}

/* ──────────────────────────────────────────────────────────────────────
   8 · MOVIMIENTO REDUCIDO
   ──────────────────────────────────────────────────────────────────────
   tokens.css ya lleva las duraciones a 0; acá se apagan las animaciones
   de entrada (que si no se ejecutarían igual, sólo que de golpe) y las
   escalas de :active. Los cambios de color y de borde se conservan: no
   son movimiento y son la respuesta al clic.                            */
@media (prefers-reduced-motion: reduce) {
  :is(#productsGrid, #productosGrid) > .mm-card,
  .productos-empty,
  .mm-busc-vacio {
    animation: none;
  }

  .productos-empty .mm-empty-btn:active,
  .productos-empty .ds-btn:active,
  .mm-filtros-limpiar:active,
  .mm-chip:active {
    transform: none;
  }
}
