/* =====================================================================
   MOOD — hoja de estilo única
   ---------------------------------------------------------------------
   Escrita móvil primero: lo que ves sin media query es la versión de
   teléfono. Las media queries solo AÑADEN para pantallas más grandes.

   Una sola tipografía (Inter) en todos los pesos. Menos peso de descarga,
   más coherencia, y con el ajuste de espaciado correcto un titular en
   Inter 800 se ve tan editorial como una serif.
   ===================================================================== */

:root {
  /* ---------------------------------------------------------- color */
  /* Identidad de Mood, tomada del sitio actual */
  --morado: #2c0040;
  --morado-2: #47106a;
  --morado-3: #6a2f92;
  --morado-suave: #f5eefa;
  --morado-borde: #e4d6ee;

  --fucsia: #c9186b;
  --fucsia-2: #a8125a;
  --fucsia-suave: #fdeef5;

  /* Neutros con una pizca de morado: hacen juego en vez de competir */
  --lienzo: #f6f5f8;
  --papel: #ffffff;
  --papel-2: #faf9fc;
  --linea: #ebe8f0;
  --linea-2: #d8d3e0;

  --tinta: #191320;
  --tinta-2: #5d5568;
  --tinta-3: #8f889b;

  --ok: #12724a;
  --ok-fondo: #e7f6ee;
  --ok-borde: #b8e3cd;
  --alerta: #8a5a00;
  --alerta-fondo: #fdf4e3;
  --alerta-borde: #f0dcae;
  /* Un punto más oscuro que --alerta, para párrafos enteros sobre el fondo
     amarillo. En una etiqueta corta --alerta se lee bien; en cuatro líneas
     de texto seguido se queda justo de contraste. */
  --alerta-texto: #6f4800;
  --error: #b02318;
  --error-fondo: #fdeeec;
  --error-borde: #f3c9c4;
  --info: #1c4f8f;
  --info-fondo: #eaf2fc;
  --info-borde: #c6dcf5;

  /* ------------------------------------------------------ tipografía */
  --fuente: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
            "Helvetica Neue", Arial, sans-serif;

  --t-xs: 0.6875rem;   /* 11 */
  --t-sm: 0.75rem;     /* 12 */
  --t-md: 0.8125rem;   /* 13 */
  --t-base: 0.9375rem; /* 15 */
  --t-lg: 1.0625rem;   /* 17 */
  --t-xl: clamp(1.1875rem, 1rem + 1vw, 1.375rem);
  --t-2xl: clamp(1.375rem, 1.1rem + 1.6vw, 1.75rem);
  --t-3xl: clamp(1.625rem, 1.2rem + 2.4vw, 2.25rem);

  /* Titulares apretados; texto corrido con su aire natural */
  --track-titular: -0.022em;
  --track-titular-grande: -0.032em;
  --track-etiqueta: 0.07em;

  /* --------------------------------------------------------- ritmo */
  --e1: 4px;
  --e2: 8px;
  --e3: 12px;
  --e4: 16px;
  --e5: 24px;
  --e6: 32px;
  --e7: 48px;

  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 18px;
  --r-full: 999px;

  /* Sombras teñidas de morado: se integran, no ensucian */
  --sombra-1: 0 1px 2px rgba(30, 12, 45, .05);
  --sombra-2: 0 2px 4px rgba(30, 12, 45, .04), 0 6px 16px rgba(30, 12, 45, .06);
  --sombra-3: 0 4px 8px rgba(30, 12, 45, .06), 0 18px 44px rgba(30, 12, 45, .14);
  --anillo: 0 0 0 3px rgba(44, 0, 64, .12);

  --transicion: 160ms cubic-bezier(.4, 0, .2, 1);

  --barra: 54px;          /* alto de la fila del logo */
  --cabecera: 102px;      /* alto total del encabezado en móvil */
  --seguro-abajo: env(safe-area-inset-bottom, 0px);

  /* Ancho de los dos cajones laterales: el carrito (entra por la derecha) y
     los filtros del catálogo (entran por la izquierda). Es UN solo valor a
     propósito. Antes eran dos —84vw/430px el carrito y 88vw/350px los
     filtros—, así que abrir uno y abrir el otro se sentían como dos
     mecanismos distintos de la misma tienda. Con el mismo número, la franja
     de catálogo que queda oscurecida al lado es idéntica en los dos, y esa
     franja es la forma natural de cerrar: se toca fuera. */
  --ancho-cajon: min(80vw, 430px);
}

/* Los tonos derivados se calculan a partir de los tres colores base, que
   Emmanuel cambia desde el panel. Si cambia el morado, cambian con él el
   morado oscuro del hover, el suave de los fondos y el del borde: no hay
   que tocar seis valores a mano ni queda ninguno desparejado.

   Los valores literales de arriba quedan como red de seguridad para el
   navegador que no entienda color-mix. */
@supports (color: color-mix(in srgb, red 50%, blue)) {
  :root {
    --morado-2:      color-mix(in srgb, var(--morado) 84%, #ffffff);
    --morado-3:      color-mix(in srgb, var(--morado) 62%, #ffffff);
    --morado-suave:  color-mix(in srgb, var(--morado) 7%,  #ffffff);
    --morado-borde:  color-mix(in srgb, var(--morado) 18%, #ffffff);
    --fucsia-2:      color-mix(in srgb, var(--fucsia) 86%, #000000);
    --fucsia-suave:  color-mix(in srgb, var(--fucsia) 8%,  #ffffff);
    --papel-2:       color-mix(in srgb, var(--lienzo) 55%, #ffffff);
    --anillo: 0 0 0 3px color-mix(in srgb, var(--morado) 16%, transparent);
  }
}

/* ---------------------------------------------------------------- base */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--cabecera) + 12px);
}

body {
  margin: 0;
  /* El pie se pega abajo aunque la página tenga poco contenido. Sin esto,
     en el carrito vacío quedaba una franja gris entre el pie y el borde
     de la pantalla, como si la página se hubiera cortado. */
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  font-family: var(--fuente);
  font-size: var(--t-base);
  font-weight: 400;
  line-height: 1.55;
  letter-spacing: -0.006em;
  color: var(--tinta);
  background: var(--lienzo);
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-wrap: break-word;
  text-rendering: optimizeLegibility;
}

body.sin-scroll { overflow: hidden; }

h1, h2, h3, h4 {
  margin: 0 0 var(--e2);
  color: var(--morado);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: var(--track-titular);
  text-wrap: balance;
}
h1 { font-size: var(--t-2xl); letter-spacing: var(--track-titular-grande); }
h2 { font-size: var(--t-xl); }
h3 { font-size: var(--t-lg); font-weight: 700; }
h4 { font-size: var(--t-base); font-weight: 700; }

p { margin: 0 0 var(--e3); }
p:last-child { margin-bottom: 0; }

a {
  color: var(--morado);
  text-decoration: none;
  text-underline-offset: 3px;
  text-decoration-thickness: 1.5px;
}
a:hover { text-decoration: underline; }

img { max-width: 100%; display: block; }

strong, b { font-weight: 700; }

/* Los números de dinero, alineados: 111 y 999 ocupan lo mismo */
.precio, .total, .cifra, .monto, .num, .factura-tabla td.num,
.resumen-linea strong, .tarjeta-producto .precio, .producto-precio {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "cv05" 1;
}

/* Foco visible siempre: navegar con teclado tiene que ser posible */
:focus-visible {
  outline: 2.5px solid var(--fucsia);
  outline-offset: 2px;
  border-radius: 5px;
}

/* El atributo `hidden` le gana a cualquier `display` que pongamos más
   abajo. Sin esto, esconder algo desde JavaScript no surtía efecto. */
[hidden] { display: none !important; }

.oculto { display: none !important; }
.solo-lectores {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.envoltorio {
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;
  padding: 0 var(--e4);
}

::selection { background: var(--morado); color: #fff; }

/* Barras de scroll discretas donde hacen falta */
.miniaturas, .cajon-cuerpo, .resumen-items, .panel-filtros-cuerpo,
.tabla-envoltorio, .sugerencias {
  scrollbar-width: thin;
  scrollbar-color: var(--linea-2) transparent;
}

/* Franja de aviso: una línea, arriba del todo, y solo si Emmanuel la
   enciende desde el panel. No es sticky a propósito: se lee una vez al
   entrar y después no vuelve a estorbar. */
.franja-aviso {
  background: var(--morado);
  color: #fff;
  text-align: center;
  padding: 7px var(--e4);
  font-size: var(--t-sm);
  font-weight: 550;
  letter-spacing: 0.01em;
}

/* ---------------------------------------------------------- encabezado */
.cabecera {
  position: sticky;
  top: 0;
  z-index: 60;
  background: rgba(255, 255, 255, .88);
  backdrop-filter: saturate(1.6) blur(14px);
  -webkit-backdrop-filter: saturate(1.6) blur(14px);
  border-bottom: 1px solid var(--linea);
}

.cabecera-fila {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e2);
  min-height: var(--barra);
}

.logo {
  font-weight: 900;
  font-size: 1.375rem;
  letter-spacing: 0.02em;
  color: var(--morado);
  text-decoration: none;
  flex: 0 0 auto;
  line-height: 1;
  padding: var(--e1) 0;
}
.logo:hover { text-decoration: none; color: var(--morado-2); }

.cabecera-acciones {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--e1);
}

/* Los iconos del encabezado son la navegación principal en teléfono: si
   se ven pequeños y sueltos en una esquina, la tienda parece a medio
   hacer. Van a 46 px, con su fondo al pasar por encima. */
.icono-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border: 0;
  background: transparent;
  color: var(--morado);
  border-radius: var(--r-full);
  cursor: pointer;
  transition: background var(--transicion), color var(--transicion),
              transform var(--transicion);
}
.icono-btn:hover { background: var(--morado-suave); text-decoration: none; }
.icono-btn:active { background: var(--morado-borde); transform: scale(.94); }
.cabecera-acciones .icono-btn svg {
  width: 25px; height: 25px;
  stroke-width: 1.7;
}
.icono-btn svg { width: 22px; height: 22px; stroke-width: 1.6; }

/* El nombre del icono. En TELÉFONO no se dibuja —no cabe, y la barra de
   abajo ya los nombra—; de tableta para arriba vuelve, en la media query
   del final del archivo. */
.rotulo-accion { display: none; }

.contador {
  position: absolute;
  top: 3px; right: 2px;
  min-width: 18px; height: 18px;
  padding: 0 5px;
  background: var(--fucsia);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  line-height: 18px;
  letter-spacing: 0;
  text-align: center;
  border-radius: var(--r-full);
  box-shadow: 0 0 0 2px var(--papel);
}

/* Menú principal: en móvil se esconde, en escritorio se muestra */
.menu-principal { display: none; }

/* En teléfono el buscador baja a su propia fila: junto al logo y los
   iconos quedaba de 60px y no se leía ni lo que uno escribía. */
.buscador {
  order: 3;
  flex: 0 0 100%;
  min-width: 0;
  position: relative;
  padding-bottom: var(--e3);
}

.buscador-campo {
  display: flex;
  align-items: center;
  background: var(--papel-2);
  /* Rectángulo redondeado, no pastilla. Con la pastilla, el extremo
     izquierdo era un semicírculo y el derecho lo ocupaba el botón: dos
     formas distintas pegadas, y se leía como «una cápsula con un trozo
     dentro». Con las cuatro esquinas iguales, el campo y el botón se leen
     como UNA pieza partida en dos.
     Es el mismo radio que las fotos de producto, así que el buscador
     pertenece al mismo sistema visual que el resto de la tienda. */
  border-radius: var(--r-md);
  height: 46px;
  /* El recorte hace que el botón encaje solo: en vez de darle un radio
     propio —que nunca coincide del todo—, el campo lo recorta con su
     propia curva. Encajan siempre, aunque mañana cambie el radio. */
  overflow: hidden;
  /* El contorno va por dentro y NO como `border`. Un borde de verdad se
     dibuja por fuera de todo, así que le daba la vuelta al botón morado y
     dejaba una costura gris rodeándolo. Así, el botón se pinta encima del
     contorno y el encuentro queda limpio. */
  box-shadow: inset 0 0 0 1px var(--linea);
  transition: box-shadow var(--transicion), background var(--transicion);
}
.buscador-campo:hover { box-shadow: inset 0 0 0 1px var(--linea-2); }
/* Al escribir NO se dibuja ninguna línea de color. Ni el halo de fuera ni el
   contorno morado de dentro: las dos cosas se leían como rayas pegadas encima
   de la barra justo cuando la clienta está mirando lo que teclea.

   El foco se sigue notando, con dos señales que no son una raya: el fondo
   pasa a blanco y, sobre todo, se despliega el panel de sugerencias —que en
   teléfono ocupa la pantalla entera—. Es imposible no darse cuenta de que el
   buscador está activo, así que un contorno de aviso encima sobra. */
.buscador-campo:focus-within {
  box-shadow: inset 0 0 0 1px var(--linea-2);
  background: var(--papel);
}
.buscador-campo input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: transparent;
  padding: 0 var(--e2) 0 var(--e4);
  font-size: 15px;
  font-family: inherit;
  color: var(--tinta);
}
.buscador-campo input::placeholder { color: var(--tinta-3); }
.buscador-campo input:focus { outline: none; }
/* Fuera los adornos que el navegador le mete por su cuenta a un campo de
   búsqueda: la flechita del desplegable de búsquedas anteriores, la lupa
   nativa y la equis de borrar. Aparecían al hacer clic, encima de nuestro
   propio panel de sugerencias, y se veían como un control roto pegado al
   campo. El buscador ya tiene su lupa y su panel; los del navegador sobran. */
.buscador-campo input::-webkit-search-decoration,
.buscador-campo input::-webkit-search-cancel-button,
.buscador-campo input::-webkit-search-results-button,
.buscador-campo input::-webkit-search-results-decoration,
.buscador-campo input::-webkit-calendar-picker-indicator {
  display: none;
  -webkit-appearance: none;
  appearance: none;
}
/* Botón de buscar. Antes era un círculo flotando con 4 px de aire dentro de
   la pastilla: dos curvas distintas que no encajaban y se leía como «un
   círculo metido en una caja». Ahora ocupa el alto completo y llega hasta
   el borde, así que su lado derecho ES la curva de la pastilla y su lado
   izquierdo es una línea recta limpia. */
.buscador-campo button {
  flex: 0 0 auto;
  width: 52px;
  align-self: stretch;
  margin: 0;
  border: 0;
  border-radius: 0;
  background: var(--morado);
  color: #fff;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: background var(--transicion);
}
.buscador-campo button:hover { background: var(--morado-2); }
/* Sin el encogido de antes: al ocupar todo el alto, achicarlo dejaba ver
   el fondo por las esquinas y parecía un fallo de dibujo. */
.buscador-campo button:active { background: var(--morado-3); }
.buscador-campo button svg { width: 19px; height: 19px; stroke-width: 2; }

.sugerencias {
  position: absolute;
  top: 100%;
  left: 0; right: 0;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--r-md);
  box-shadow: var(--sombra-3);
  z-index: 70;
  overflow: hidden;
  max-height: 68vh;
  overflow-y: auto;
}

/* ---------------------------------------------------------------
   El campo y el panel son UNA sola pieza mientras está desplegado.

   Antes se veían chocar dos contornos en la unión: el borde de abajo
   del campo y el de arriba del panel, uno encima del otro, y encima
   cada uno con su propia curva. Ahora la unión es lisa y las esquinas
   redondeadas quedan solo en los extremos de fuera.

   El contorno del campo se dibuja con `box-shadow: inset`, que no
   tiene lados; se apaña con tres sombras (arriba, izquierda, derecha)
   para dejar el lado de abajo sin línea.
   --------------------------------------------------------------- */
.buscador.abierto .buscador-campo {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  box-shadow: inset 0 1px 0 0 var(--linea-2),
              inset 1px 0 0 0 var(--linea-2),
              inset -1px 0 0 0 var(--linea-2);
}
.buscador.abierto .sugerencias {
  border-top: 0;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}
.sugerencias-pestanas {
  display: flex;
  gap: var(--e1);
  padding: var(--e2);
  border-bottom: 1px solid var(--linea);
}
.sugerencias-pestanas button {
  flex: 1;
  padding: 9px 8px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  font: inherit;
  font-weight: 600;
  font-size: var(--t-md);
  color: var(--tinta-2);
  cursor: pointer;
  transition: background var(--transicion), color var(--transicion);
}
.sugerencias-pestanas button:hover { background: var(--papel-2); }
.sugerencias-pestanas button[aria-selected="true"] {
  background: var(--morado);
  color: #fff;
}
.sugerencias-lista {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--e2);
  padding: var(--e3);
}
.sugerencia { display: block; border-radius: var(--r-sm); overflow: hidden; }
.sugerencia:hover { text-decoration: none; }
.sugerencia img {
  width: 100%; aspect-ratio: 3/4; object-fit: cover;
  background: var(--papel-2);
  border-radius: var(--r-sm);
  transition: transform var(--transicion);
}
.sugerencia:hover img { transform: scale(1.03); }
.sugerencia .nom {
  font-size: var(--t-sm); font-weight: 600; color: var(--tinta);
  padding: 6px 2px 0; line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sugerencia .pre {
  font-size: var(--t-sm); color: var(--morado);
  padding: 1px 2px 4px; font-weight: 700;
}
.sugerencias-vacio {
  padding: var(--e6) var(--e4); text-align: center;
  color: var(--tinta-2); font-size: var(--t-base);
}

/* -------------------------------------------------- barra inferior móvil
   Los pulgares llegan abajo, no arriba. En teléfono la navegación
   principal vive aquí. */
.barra-inferior {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 65;
  display: flex;
  background: rgba(255, 255, 255, .94);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--linea);
  padding-bottom: var(--seguro-abajo);
}
.barra-inferior a {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 8px 2px 7px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--tinta-3);
  position: relative;
  transition: color var(--transicion);
}
.barra-inferior a:hover { text-decoration: none; color: var(--tinta-2); }
/* El globo con las unidades del carrito se pega AL ICONO, no al borde de la
   pestaña: cada pestaña ocupa un cuarto de la pantalla, así que con la
   posición de siempre (arriba a la derecha) el número quedaba flotando en una
   esquina vacía, lejos del carrito al que se refiere. */
.barra-inferior .contador { top: 4px; right: auto; left: 50%; margin-left: 3px; }
.barra-inferior a.activo { color: var(--morado); }
.barra-inferior svg { width: 22px; height: 22px; stroke-width: 1.5; }
.barra-inferior a.activo svg { stroke-width: 1.9; }
/* Punto bajo el icono de la sección en la que estás: se ubica de un
   vistazo sin tener que leer la etiqueta. */
.barra-inferior a.activo::after {
  content: "";
  position: absolute;
  bottom: 3px;
  width: 4px; height: 4px;
  border-radius: var(--r-full);
  background: currentColor;
}
.barra-inferior .contador { top: 3px; right: calc(50% - 19px); }

body.con-barra-inferior { padding-bottom: calc(60px + var(--seguro-abajo)); }

/* ------------------------------------------------------------ botones */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e2);
  min-height: 46px;
  padding: 12px 22px;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  font-family: inherit;
  font-size: var(--t-base);
  font-weight: 600;
  letter-spacing: -0.008em;
  line-height: 1.25;
  text-align: center;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--transicion), border-color var(--transicion),
              color var(--transicion), box-shadow var(--transicion),
              transform 80ms ease;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn[disabled], .btn[aria-disabled="true"] {
  opacity: .45; cursor: not-allowed; transform: none;
}

.btn-primario {
  background: var(--morado);
  color: #fff;
  box-shadow: 0 1px 2px rgba(44, 0, 64, .2);
}
.btn-primario:hover { background: var(--morado-2); }

.btn-accion {
  background: var(--fucsia);
  color: #fff;
  box-shadow: 0 1px 2px rgba(201, 24, 107, .25);
}
.btn-accion:hover { background: var(--fucsia-2); }

.btn-contorno {
  background: var(--papel);
  color: var(--morado);
  border-color: var(--linea-2);
}
.btn-contorno:hover { background: var(--morado-suave); border-color: var(--morado-borde); }

.btn-suave { background: var(--papel-2); color: var(--tinta); border-color: var(--linea); }
.btn-suave:hover { background: var(--linea); }

.btn-peligro { background: var(--error); color: #fff; }
.btn-peligro:hover { background: #8d1c13; }

/* Alta de un color o una talla desde la ficha del producto. Va plegado:
   se usa de vez en cuando y no debe competir con las casillas. */
.agregar-valor { margin-top: var(--e2); }
.agregar-valor > summary {
  display: inline-block;
  cursor: pointer;
  font-size: var(--t-md);
  font-weight: 600;
  color: var(--morado);
  padding: 4px 0;
}
.agregar-valor > summary:hover { text-decoration: underline; text-underline-offset: 3px; }
.agregar-valor-campos {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e2);
  margin-top: var(--e2);
}
.agregar-valor-campos input[type="text"] { flex: 1 1 150px; min-width: 0; }
.agregar-valor-campos input[type="color"] {
  width: 44px; height: 38px; padding: 2px;
  border: 1px solid var(--linea-2); border-radius: var(--r-sm);
  background: var(--papel); cursor: pointer; flex: 0 0 auto;
}

/* «Cambiar» junto al color y la talla de cada línea del carrito. Discreto
   a propósito: es una corrección, no la acción principal. */
.btn-cambiar {
  border: 0;
  background: none;
  /* El alto mínimo es para el dedo, no para el diseño: con 15 px de alto
     había que apuntar. El relleno vertical no descoloca la línea porque el
     texto sigue centrado en su sitio. */
  min-height: 32px;
  padding: 0 4px 0 6px;
  margin-left: 2px;
  font-family: inherit;
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--morado);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.btn-cambiar:hover { color: var(--fucsia); }

/* ====================== VISTA RÁPIDA DEL PRODUCTO ====================== */
/* En teléfono sube desde abajo, como el cajón del carrito: el gesto ya lo
   conoce. En escritorio se centra. */
/* En teléfono ocupa la pantalla entera. Como hoja a media altura quedaba
   media ventana y medio catálogo detrás, y para elegir color y talla había
   que desplazarse dentro de un trozo pequeño. A partir de tablet vuelve a
   ser una ventana centrada (ver la consulta de 760 px), que ahí sí cabe. */
.vista-rapida {
  position: fixed;
  top: 0;
  left: 0; right: 0; bottom: 0;
  max-height: none;
  background: var(--papel);
  border-radius: 0;
  box-shadow: var(--sombra-3);
  z-index: 95;
  overflow-y: auto;
  overscroll-behavior: contain;
  transform: translateY(100%);
  transition: transform 220ms cubic-bezier(.22, .61, .36, 1);
  padding-bottom: calc(var(--e4) + var(--seguro-abajo, 0px));
}
.vista-rapida.abierta { transform: none; }
.vista-rapida[hidden] { display: none; }

.vista-rapida-cerrar {
  position: absolute;
  top: var(--e3); right: var(--e3);
  width: 36px; height: 36px;
  display: grid; place-items: center;
  border: 0;
  border-radius: var(--r-full);
  background: rgba(255, 255, 255, .9);
  backdrop-filter: blur(6px);
  color: var(--tinta);
  cursor: pointer;
  z-index: 2;
  box-shadow: var(--sombra-1);
}
.vista-rapida-cerrar svg { width: 18px; height: 18px; }

.vista-rapida-cuerpo { padding: var(--e4); }

.vr-foto {
  aspect-ratio: 3 / 4;
  max-height: 42vh;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--papel-2);
  box-shadow: inset 0 0 0 1px rgba(30, 12, 45, .055);
}
.vr-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }

.vr-miniaturas {
  display: flex; gap: var(--e2);
  margin-top: var(--e2);
  overflow-x: auto;
  scrollbar-width: none;
}
.vr-miniaturas::-webkit-scrollbar { display: none; }
.vr-miniaturas button {
  flex: 0 0 auto;
  width: 46px; height: 60px;
  padding: 0;
  border: 0;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--papel-2);
  cursor: pointer;
  box-shadow: inset 0 0 0 1px var(--linea);
}
.vr-miniaturas button[aria-current="true"] { box-shadow: inset 0 0 0 2px var(--morado); }
.vr-miniaturas img { width: 100%; height: 100%; object-fit: cover; display: block; }

.vr-nombre {
  margin: var(--e4) 0 2px;
  font-size: var(--t-xl);
  letter-spacing: var(--track-titular);
}
.vr-precio {
  font-size: var(--t-lg);
  font-weight: 650;
  letter-spacing: -0.014em;
  color: var(--tinta);
}
.vr-precio .antes {
  font-size: var(--t-md); font-weight: 500; color: var(--tinta-3);
  text-decoration: line-through; margin-left: 6px;
}
.vr-descripcion {
  margin: var(--e2) 0 var(--e4);
  font-size: var(--t-md);
  color: var(--tinta-2);
  line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.vr-grupo { margin-bottom: var(--e4); }
.vr-grupo .etiqueta { margin-bottom: 6px; }
.vr-cantidad { display: flex; align-items: center; gap: var(--e3); margin-bottom: var(--e4); }
.vr-cantidad .etiqueta { margin: 0; }
.vr-aviso {
  margin: 0 0 var(--e3);
  font-size: var(--t-md);
  color: var(--error);
  font-weight: 600;
}
/* «Comprar ahora» y «Añadir al carrito» iban pegados uno debajo del otro,
   los dos a todo el ancho: se leían como un solo botón partido por una
   línea, y no quedaba claro dónde tocar para cada cosa. */
#vr-agregar { margin-top: var(--e2); }

.vr-ficha {
  display: block;
  text-align: center;
  margin-top: var(--e3);
  font-size: var(--t-md);
}

@media (min-width: 760px) {
  .vista-rapida {
    top: 50%; left: 50%; right: auto; bottom: auto;
    width: min(94vw, 820px);
    height: auto;
    max-height: 88vh;
    border-radius: var(--r-lg);
    transform: translate(-50%, -46%);
    opacity: 0;
    transition: transform 200ms cubic-bezier(.22, .61, .36, 1), opacity 160ms;
  }
  .vista-rapida.abierta { transform: translate(-50%, -50%); opacity: 1; }
  .vista-rapida-cuerpo {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--e5);
    padding: var(--e5);
  }
  .vr-foto { max-height: none; }
  .vr-nombre { margin-top: 0; }
}

/* ------------------------------------------------- foto de la clienta */
.avatar {
  position: relative;
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  border-radius: var(--r-full);
  overflow: hidden;
  background: var(--morado-suave);
  color: var(--morado);
  font-weight: 700;
  letter-spacing: -0.01em;
  user-select: none;
}
.avatar-iniciales { line-height: 1; }
/* La foto tapa a las iniciales. Si no carga, no se dibuja nada y quedan
   ellas debajo, que es justo lo que queremos. */
.avatar img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}

.ficha-cliente {
  display: flex;
  align-items: center;
  gap: var(--e3);
  margin: 0 0 var(--e4);
}
.ficha-cliente-datos { min-width: 0; }
.ficha-cliente-nombre {
  font-size: var(--t-lg);
  font-weight: 650;
  letter-spacing: var(--track-titular);
  color: var(--tinta);
  line-height: 1.2;
}
.ficha-cliente-correo {
  font-size: var(--t-md);
  color: var(--tinta-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Entrar con Google. Va en blanco con borde gris porque así lo pide Google
   en sus normas de marca, y porque en morado competiría con el botón de
   «Entrar», que es el camino principal. */
.btn-google {
  background: var(--papel);
  color: var(--tinta);
  border-color: var(--linea-2);
  font-weight: 550;
}
.btn-google:hover { background: var(--papel-2); border-color: var(--tinta-3); text-decoration: none; }
.btn-google svg { flex: 0 0 auto; }

/* Separador con la palabra «o» centrada sobre la línea. */
.separador-o {
  display: flex;
  align-items: center;
  gap: var(--e3);
  margin: var(--e4) 0;
  color: var(--tinta-3);
  font-size: var(--t-md);
}
.separador-o::before, .separador-o::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--linea);
}

.btn-bloque { width: 100%; }
.btn-chico { min-height: 38px; padding: 9px 15px; font-size: var(--t-md); }
.btn-texto {
  background: none; border: 0; padding: 3px 2px; min-height: 0;
  color: var(--morado); font-weight: 600; text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer; font-family: inherit; font-size: var(--t-md);
}

/* ----------------------------------------------------------- formulario */
.campo { margin-bottom: var(--e4); }
/* `.opcion-radio` también es un <label>, pero lleva texto normal dentro:
   no debe heredar el estilo de etiqueta en mayúsculas. */
.campo > label:not(.opcion-radio), .etiqueta {
  display: block;
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: var(--track-etiqueta);
  text-transform: uppercase;
  color: var(--tinta-2);
  margin-bottom: 6px;
}
.campo .ayuda { font-size: var(--t-sm); color: var(--tinta-3); margin: 5px 0 0; }
.campo .obligatorio { color: var(--fucsia); }

input[type="text"], input[type="email"], input[type="tel"], input[type="password"],
input[type="number"], input[type="search"], input[type="date"], select, textarea {
  width: 100%;
  min-height: 46px;
  padding: 12px 14px;
  border: 1px solid var(--linea-2);
  border-radius: var(--r-sm);
  background: var(--papel);
  color: var(--tinta);
  font-family: inherit;
  /* 16px es el mínimo que evita que iOS haga zoom al enfocar un campo */
  font-size: 16px;
  line-height: 1.4;
  transition: border-color var(--transicion), box-shadow var(--transicion);
}
/* El campo del buscador va DENTRO de su propia caja, que ya pone el fondo y
   el contorno. La regla de arriba le añadía borde, radio y fondo propios, y
   como está más abajo en el archivo le ganaba: por eso se veía un borde
   redondeado claro justo antes del botón morado, y el conjunto no parecía
   una sola pieza. Se anula aquí, después, para que gane esta. */
.buscador-campo input[type="search"] {
  min-height: 0;
  padding: 0 var(--e2) 0 var(--e4);
  border: 0;
  border-radius: 0;
  background: transparent;
  font-size: 16px;
}
/* Y al escribir, tampoco el halo morado de los campos normales.
   `input:focus` está más abajo en el archivo y le ganaba a la regla de
   arriba: el borde no se veía (aquí el borde es 0) pero el `box-shadow`
   sí, y dibujaba un rectángulo morado claro DENTRO de la barra, encima de
   las letras que la clienta está tecleando. El foco ya se nota por el
   fondo blanco y por el panel de sugerencias que se despliega. */
/* NINGUNA raya al escribir: ni el halo morado de `input:focus` ni contorno
   de foco. En un campo de texto `:focus-visible` también se activa al hacer
   clic —el navegador da por hecho que vas a teclear—, así que un contorno
   «solo para teclado» aquí se ve SIEMPRE, y era una raya de color pegada
   encima de lo que la clienta está escribiendo.

   El foco se nota igual, con dos señales que no son una raya: el fondo pasa
   a blanco y se despliega el panel de sugerencias, que en teléfono ocupa la
   pantalla entera. Es imposible no darse cuenta de que el buscador está
   activo. */
.buscador-campo input[type="search"]:focus,
.buscador-campo input[type="search"]:focus-visible {
  box-shadow: none;
  border-color: transparent;
  outline: none;
}

input::placeholder, textarea::placeholder { color: var(--tinta-3); }
textarea { min-height: 92px; resize: vertical; }
select {
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%235d5568' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1.5 2l4.5 4.5L10.5 2'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 11px;
  padding-right: 38px;
  cursor: pointer;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--morado);
  box-shadow: var(--anillo);
}
input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] {
  border-color: var(--error);
  box-shadow: 0 0 0 3px rgba(176, 35, 24, .1);
}
input[type="file"] {
  width: 100%;
  padding: 10px;
  border: 1px dashed var(--linea-2);
  border-radius: var(--r-sm);
  background: var(--papel-2);
  font-size: var(--t-md);
  font-family: inherit;
}
input[type="checkbox"], input[type="radio"] { accent-color: var(--morado); }
.campo-error { color: var(--error); font-size: var(--t-md); margin-top: 6px; font-weight: 600; }

.fila-campos { display: grid; gap: 0 var(--e3); }
@media (min-width: 480px) { .fila-campos { grid-template-columns: 1fr 1fr; } }

/* ------------------------------------------------------------- avisos */
.aviso {
  display: flex;
  gap: var(--e3);
  padding: var(--e3) var(--e4);
  border: 1px solid transparent;
  border-left-width: 3px;
  border-radius: var(--r-sm);
  font-size: var(--t-base);
  line-height: 1.5;
  margin-bottom: var(--e4);
}
.aviso strong { display: block; margin-bottom: 2px; }
.aviso-ok { background: var(--ok-fondo); color: #0c5b39; border-color: var(--ok-borde); border-left-color: var(--ok); }
.aviso-error { background: var(--error-fondo); color: #8d1c13; border-color: var(--error-borde); border-left-color: var(--error); }
.aviso-alerta { background: var(--alerta-fondo); color: var(--alerta-texto); border-color: var(--alerta-borde); border-left-color: var(--alerta); }
.aviso-info { background: var(--info-fondo); color: var(--info); border-color: var(--info-borde); border-left-color: #2f6dbd; }
.aviso > svg { flex: 0 0 auto; width: 20px; height: 20px; margin-top: 1px; }

/* Acción bloqueada por una regla del negocio. No es un error del sistema
   ni una advertencia: es «esto no se puede hacer todavía y por esto». */
.candado {
  display: flex;
  align-items: flex-start;
  gap: var(--e3);
  padding: var(--e3) var(--e4);
  border: 1px dashed var(--linea-2);
  border-radius: var(--r-sm);
  background: var(--papel-2);
  color: var(--tinta-2);
  font-size: var(--t-md);
  line-height: 1.55;
}
.candado svg { flex: 0 0 auto; width: 19px; height: 19px; color: var(--tinta-3); }
.candado strong { color: var(--tinta); }

/* El botón nativo de «examinar» es feo y distinto en cada navegador.
   No se puede rediseñar por dentro, pero sí darle forma de botón de Mood. */
input[type="file"]::file-selector-button {
  margin-right: var(--e3);
  padding: 8px 14px;
  border: 1px solid var(--linea-2);
  border-radius: var(--r-sm);
  background: var(--papel);
  color: var(--morado);
  font-family: inherit;
  font-size: var(--t-md);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--transicion), border-color var(--transicion);
}
input[type="file"]::file-selector-button:hover {
  background: var(--morado-suave);
  border-color: var(--morado-borde);
}

/* Selector de color del panel: la rueda y el código, uno al lado del otro */
.fila-color { display: flex; align-items: center; gap: var(--e2); }
.fila-color input[type="color"] {
  flex: 0 0 auto;
  width: 52px; height: 44px;
  padding: 4px;
  border: 1px solid var(--linea-2);
  border-radius: var(--r-sm);
  background: var(--papel);
  cursor: pointer;
}
.fila-color input[type="text"] {
  max-width: 140px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  text-transform: lowercase;
}

/* Vista previa de una imagen ya subida, con su casilla para quitarla */
.imagen-actual {
  display: flex; align-items: center; gap: var(--e4);
  flex-wrap: wrap;
  margin-bottom: var(--e2);
  padding: var(--e3);
  border: 1px solid var(--linea);
  border-radius: var(--r-sm);
  background: var(--papel-2);
}
.imagen-actual img {
  max-height: 56px; max-width: 200px;
  width: auto;
  border-radius: 4px;
}

/* ------------------------------------------------------------ tarjetas */
.tarjeta {
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--r-md);
  box-shadow: var(--sombra-1);
}
.tarjeta-cuerpo { padding: var(--e4); }
.tarjeta-titulo {
  display: flex; align-items: center; gap: var(--e3);
  margin: 0;
  padding: var(--e4);
  border-bottom: 1px solid var(--linea);
  font-size: var(--t-lg);
  font-weight: 700;
  letter-spacing: var(--track-titular);
  color: var(--morado);
}
.tarjeta-titulo .num {
  display: grid; place-items: center;
  width: 26px; height: 26px;
  border-radius: var(--r-full);
  background: var(--morado);
  color: #fff;
  font-size: var(--t-md);
  font-weight: 700;
  flex: 0 0 auto;
}

/* ------------------------------------------------------------ portada */
.portada {
  position: relative;
  margin: var(--e3) 0 var(--e2);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--morado-suave);
  min-height: 210px;
  display: flex;
  align-items: flex-end;
}
.portada-foto {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
/* Velo solo cuando hay foto: sin él, un título morado sobre una foto
   clara no se lee, y una foto oscura innecesariamente apagada tampoco
   luce. */
.portada.con-foto::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(to top,
    rgba(20, 6, 32, .72) 0%, rgba(20, 6, 32, .28) 55%, rgba(20, 6, 32, 0) 100%);
}
.portada-texto {
  position: relative;
  z-index: 1;
  padding: var(--e5) var(--e4);
  max-width: 46ch;
}
.portada-texto h1 { margin-bottom: 6px; font-size: var(--t-2xl); }
.portada-texto p { font-size: var(--t-base); margin-bottom: var(--e4); }
.portada.con-foto .portada-texto h1,
.portada.con-foto .portada-texto p { color: #fff; }

/* ============================== CATÁLOGO ============================== */
.catalogo { display: block; padding: var(--e3) 0 var(--e7); }

/* En móvil el orden vive en .filtros-movil; esta barra es la de escritorio. */
.barra-catalogo { display: none; }

.filtros-movil {
  position: sticky;
  top: var(--cabecera);
  z-index: 40;
  display: flex;
  gap: var(--e2);
  align-items: center;
  padding: var(--e3) 0;
  margin-bottom: var(--e1);
  background: var(--lienzo);
}
/* Los dos controles miden exactamente lo mismo: con 38 y 40 px la fila se
   veía descuadrada aunque nadie supiera decir por qué. */
.filtros-movil .btn,
.filtros-movil select {
  height: 40px;
  min-height: 40px;
  font-size: var(--t-md);
  line-height: 1;
}
.filtros-movil .btn { flex: 0 0 auto; padding: 0 15px; }
.filtros-movil select { max-width: 150px; padding: 0 32px 0 12px; }

/* Por debajo de 380 px —iPhone SE y Androids viejos— no caben las tres
   cosas: «Novedades» se cortaba a «Novedade». Se va el contador, que es
   informativo, y el desplegable se queda con el ancho que necesita. */
@media (max-width: 379px) {
  .filtros-movil .conteo-productos { display: none; }
  .filtros-movil select { max-width: none; flex: 1 1 auto; }
}
.conteo-productos {
  margin-left: auto;
  font-size: var(--t-md);
  color: var(--tinta-2);
  font-weight: 600;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Panel lateral de filtros: cajón en móvil, columna fija en escritorio */
.panel-filtros {
  position: fixed;
  inset: 0 auto 0 0;
  /* El mismo ancho que el carrito lateral, del mismo token. */
  width: var(--ancho-cajon);
  background: var(--papel);
  z-index: 90;
  transform: translateX(-100%);
  transition: transform 240ms cubic-bezier(.32, .72, 0, 1);
  display: flex;
  flex-direction: column;
  box-shadow: var(--sombra-3);
}
.panel-filtros.abierto { transform: translateX(0); }
.panel-filtros-cabeza {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--e3) var(--e4);
  border-bottom: 1px solid var(--linea);
  flex: 0 0 auto;
}
.panel-filtros-cuerpo { flex: 1 1 auto; overflow-y: auto; padding: var(--e1) var(--e4) var(--e4); }
/* Dentro del cajón, «Aplicar precio» sobra: el botón grande del pie envía
   el mismo formulario. Además quedaba justo contra el pie y la clienta
   creía estar tocándolo cuando en realidad tocaba «Ver N productos».
   En escritorio, donde no hay pie, sí se muestra. */
.btn-aplicar-precio { display: none; }

.panel-filtros-pie {
  flex: 0 0 auto;
  display: flex; gap: var(--e2);
  padding: var(--e3) var(--e4) calc(var(--e3) + var(--seguro-abajo));
  border-top: 1px solid var(--linea);
}

.velo {
  position: fixed; inset: 0;
  background: rgba(25, 10, 38, .42);
  backdrop-filter: blur(2px);
  z-index: 80;
  opacity: 0;
  pointer-events: none;
  transition: opacity 240ms ease;
}
.velo.visible { opacity: 1; pointer-events: auto; }

.grupo-filtro { border-bottom: 1px solid var(--linea); }
.grupo-filtro:last-child { border-bottom: 0; }
.grupo-filtro > summary {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--e3) 2px;
  font-size: var(--t-base);
  font-weight: 700;
  letter-spacing: var(--track-titular);
  color: var(--morado);
  cursor: pointer;
  list-style: none;
}
.grupo-filtro > summary::-webkit-details-marker { display: none; }
.grupo-filtro > summary::after {
  content: "";
  width: 11px; height: 11px;
  background: currentColor;
  color: var(--tinta-3);
  mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M5 0h2v12H5z'/%3E%3Cpath d='M0 5h12v2H0z'/%3E%3C/svg%3E") center/contain no-repeat;
  -webkit-mask: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M5 0h2v12H5z'/%3E%3Cpath d='M0 5h12v2H0z'/%3E%3C/svg%3E") center/contain no-repeat;
  transition: transform var(--transicion);
}
.grupo-filtro[open] > summary::after {
  mask-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M0 5h12v2H0z'/%3E%3C/svg%3E");
  -webkit-mask-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M0 5h12v2H0z'/%3E%3C/svg%3E");
}
.grupo-filtro-cuerpo { padding: 2px 2px var(--e4); }

.lista-categorias { list-style: none; margin: 0; padding: 0; }
.lista-categorias a {
  position: relative;
  display: block;
  padding: 9px var(--e3);
  border-radius: var(--r-sm);
  font-size: var(--t-base);
  color: var(--tinta-2);
  transition: background var(--transicion), color var(--transicion);
}
.lista-categorias a:hover {
  background: var(--papel-2); color: var(--tinta); text-decoration: none;
}
/* La categoría activa se marca con color y una barrita, no con un bloque
   morado macizo: catorce categorías con un bloque relleno entre ellas
   pesaban más que las fotos. */
.lista-categorias a.activo {
  background: var(--morado-suave);
  color: var(--morado);
  font-weight: 650;
}
.lista-categorias a.activo::before {
  content: "";
  position: absolute;
  left: 0; top: 50%;
  width: 3px; height: 18px;
  margin-top: -9px;
  border-radius: 0 3px 3px 0;
  background: var(--morado);
}

.rejilla-colores {
  display: grid;
  grid-template-columns: repeat(auto-fill, 32px);
  gap: 10px;
}
/* Muestras de color.

   Antes eran círculos planos con el color crudo y una palomita blanca
   estampada encima: se veían hechos a mano. Tres cambios lo arreglan, y
   ninguno toca los colores de la marca:

   1. Un velo diagonal —claro arriba, oscuro abajo— le da materia al
      círculo. Deja de ser un disco pintado y parece una gota de pigmento.
   2. El aro interior es finísimo y translúcido, así el blanco y el crema
      tienen contorno sin que se les vea un borde gris encima.
   3. Al elegir uno, un aro fino POR FUERA con aire en medio, en vez de la
      palomita. Es como marcan la selección las tiendas de lujo: no se
      ensucia el color, se enmarca.

   El tono lo pone el atributo `background-color` de cada botón; aquí solo
   va el velo, para que no se pisen. */
.chip-color {
  /* 32px con área táctil ampliada: cómodo para el dedo sin ocupar media
     columna en la barra lateral. */
  width: 32px; height: 32px;
  border-radius: var(--r-full);
  border: 0;
  background-image: linear-gradient(155deg,
                    rgba(255, 255, 255, .34) 0%,
                    rgba(255, 255, 255, .06) 46%,
                    rgba(0, 0, 0, .10) 100%);
  box-shadow: inset 0 0 0 1px rgba(30, 12, 45, .10),
              inset 0 -2px 3px rgba(0, 0, 0, .05),
              0 1px 2px rgba(30, 12, 45, .07);
  cursor: pointer;
  padding: 0;
  position: relative;
  transition: transform 180ms cubic-bezier(.22, .61, .36, 1),
              box-shadow 180ms;
}
.chip-color:hover {
  transform: translateY(-1px);
  box-shadow: inset 0 0 0 1px rgba(30, 12, 45, .10),
              inset 0 -2px 3px rgba(0, 0, 0, .05),
              0 3px 7px rgba(30, 12, 45, .16);
}
.chip-color[aria-pressed="true"] {
  box-shadow: inset 0 0 0 1px rgba(30, 12, 45, .12),
              0 0 0 2px var(--papel),
              0 0 0 3px var(--morado);
}

.chips { display: flex; flex-wrap: wrap; gap: var(--e2); }
.chip {
  min-height: 38px;
  padding: 8px 15px;
  border: 1px solid var(--linea-2);
  background: var(--papel);
  border-radius: var(--r-full);
  font: inherit;
  font-size: var(--t-md);
  font-weight: 600;
  color: var(--tinta);
  cursor: pointer;
  transition: background var(--transicion), border-color var(--transicion),
              color var(--transicion);
}
.chip:hover { border-color: var(--morado-borde); background: var(--morado-suave); }
.chip[aria-pressed="true"] {
  background: var(--morado); color: #fff; border-color: var(--morado);
}

.filtros-activos { display: flex; flex-wrap: wrap; gap: var(--e2); margin-bottom: var(--e3); }
.etiqueta-filtro {
  display: inline-flex; align-items: center; gap: var(--e2);
  padding: 5px 6px 5px 13px;
  background: var(--morado-suave);
  border: 1px solid var(--morado-borde);
  border-radius: var(--r-full);
  font-size: var(--t-md);
  font-weight: 600;
  color: var(--morado);
}
.etiqueta-filtro a {
  display: grid; place-items: center; width: 22px; height: 22px;
  border-radius: var(--r-full); background: var(--morado); color: #fff;
  font-size: 12px; line-height: 1;
  transition: background var(--transicion);
}
.etiqueta-filtro a:hover { text-decoration: none; background: var(--fucsia); }

/* Rejilla de productos: 2 columnas en teléfono, más en pantallas grandes */
.rejilla-productos {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--e3);
}

/* La tarjeta no es una caja: es una foto con su texto debajo. Sin borde,
   sin fondo y sin sombra, la rejilla deja de parecer un panel de fichas
   y pasa a parecer una tienda de ropa. */
.tarjeta-producto {
  position: relative;
  display: flex;
  flex-direction: column;
  background: transparent;
  border: 0;
}

.tarjeta-producto .foto {
  position: relative;
  display: block;
  aspect-ratio: 3 / 4;
  background: var(--papel-2);
  border-radius: var(--r-md);
  overflow: hidden;
  /* Un filo interior finísimo: separa la foto del lienzo cuando la prenda
     es blanca sobre fondo blanco, sin llegar a leerse como borde. */
  box-shadow: inset 0 0 0 1px rgba(30, 12, 45, .055);
}
.tarjeta-producto .foto img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 600ms cubic-bezier(.22, .61, .36, 1);
}
@media (hover: hover) {
  .tarjeta-producto:hover .foto img { transform: scale(1.04); }
}
.sin-foto {
  width: 100%; height: 100%;
  display: grid; place-items: center;
  color: var(--linea-2);
  background: linear-gradient(160deg, var(--papel-2) 0%, var(--morado-suave) 100%);
}
.sin-foto svg { width: 28px; height: 28px; }

/* Botón de vista rápida, DEBAJO de la foto. Encima tapaba justo lo que la
   clienta viene a mirar. Va discreto —contorno fino, sin relleno— porque
   se repite en cada tarjeta: con cien productos, cien botones llamativos
   convierten la rejilla en un panel de botones y la ropa desaparece. */
.tarjeta-producto .elegir {
  width: 100%;
  /* Pegado a la foto, sin borde ni caja: se lee como el pie de la prenda y
     no como un botón suelto encima de ella. Con cien productos, cien
     recuadros convertirían la rejilla en un panel de botones. */
  margin-top: 6px;
  padding: 9px 10px;
  border: 0;
  border-radius: var(--r-sm);
  background: var(--papel-2);
  color: var(--tinta-2);
  font-family: inherit;
  font-size: var(--t-md);
  font-weight: 600;
  letter-spacing: -0.004em;
  text-align: center;
  cursor: pointer;
  transition: background var(--transicion), color var(--transicion);
}
.tarjeta-producto .elegir:hover {
  background: var(--morado-suave);
  color: var(--morado);
}
.tarjeta-producto .elegir:active { background: var(--morado-borde); }

.corazon {
  position: absolute;
  top: var(--e2); right: var(--e2);
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border: 0;
  border-radius: var(--r-full);
  background: rgba(255, 255, 255, .92);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--morado);
  cursor: pointer;
  box-shadow: var(--sombra-1);
  z-index: 2;
  transition: transform var(--transicion), color var(--transicion),
              background var(--transicion);
}
.corazon:hover { transform: scale(1.1); background: #fff; }
.corazon:active { transform: scale(.94); }
.corazon svg {
  width: 18px; height: 18px;
  fill: none; stroke: currentColor; stroke-width: 1.9;
  stroke-linejoin: round;
}
.corazon[aria-pressed="true"] { color: var(--fucsia); }
.corazon[aria-pressed="true"] svg { fill: currentColor; stroke: currentColor; }

.insignia {
  position: absolute;
  top: var(--e2); left: var(--e2);
  padding: 4px 10px;
  border-radius: var(--r-full);
  background: var(--morado);
  color: #fff;
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  z-index: 2;
}
.insignia-agotado { background: var(--tinta-2); }
.insignia-oferta { background: var(--fucsia); }

/* Nombre y precio son UN bloque, no dos cosas compitiendo. Antes el nombre
   iba a 13px y el precio a 15px en negrita morada: en una rejilla de cien
   productos, el ojo veía cien precios gritando antes que la ropa. Igualados
   en tamaño y con el precio en tinta, la foto vuelve a mandar, que es lo que
   se compra. El morado se reserva para lo que se toca. */
.tarjeta-producto .info {
  padding: 12px 2px 0;
  display: flex;
  flex-direction: column;
  gap: 0;
}
.tarjeta-producto .nombre {
  font-size: var(--t-base);
  font-weight: 500;
  color: var(--tinta);
  line-height: 1.4;
  letter-spacing: -0.006em;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.tarjeta-producto .nombre:hover { text-decoration: none; color: var(--morado); }
.tarjeta-producto .precio {
  font-size: var(--t-base);
  font-weight: 600;
  letter-spacing: -0.014em;
  color: var(--tinta);
  margin-top: 4px;
}
.tarjeta-producto .precio .antes {
  font-size: var(--t-md); font-weight: 500; color: var(--tinta-3);
  text-decoration: line-through; margin-left: 6px; letter-spacing: 0;
}
.puntos-color { display: flex; gap: 6px; margin-top: 10px; align-items: center; }
/* El aro va más marcado a propósito: con el anterior, un punto blanco o
   crema sobre el fondo blanco de la tarjeta no se veía, y esos colores
   parecían no existir. Es justo la información que hace entrar al producto. */
/* Los puntitos de la tarjeta llevan el mismo tratamiento en pequeño: velo
   diagonal y aro finísimo. A 13 px no se «ve» el degradado, pero quita el
   aspecto de círculo pintado y los hace parecer piedras diminutas. */
.punto-color {
  width: 13px; height: 13px;
  border-radius: var(--r-full);
  background-image: linear-gradient(155deg,
                    rgba(255, 255, 255, .30) 0%,
                    rgba(255, 255, 255, .04) 50%,
                    rgba(0, 0, 0, .12) 100%);
  box-shadow: inset 0 0 0 1px rgba(30, 12, 45, .20),
              0 1px 1px rgba(30, 12, 45, .06);
  flex: 0 0 auto;
}
.punto-color.mas {
  /* El «+4» es texto, no una muestra: sin velo ni aro. */
  background-image: none;
  box-shadow: none; font-size: var(--t-xs); color: var(--tinta-2);
  width: auto; height: auto; font-weight: 600; margin-left: 1px;
}

/* Catálogo continuo: el aviso mientras llegan más productos y el final */
.cargando-mas {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--e3);
  padding: var(--e5) 0;
  color: var(--tinta-2);
  font-size: var(--t-md);
}
.giro {
  width: 18px; height: 18px;
  border: 2px solid var(--linea-2);
  border-top-color: var(--morado);
  border-radius: var(--r-full);
  animation: girar .7s linear infinite;
}
@keyframes girar { to { transform: rotate(360deg); } }
.fin-catalogo {
  text-align: center;
  color: var(--tinta-3);
  font-size: var(--t-md);
  padding: var(--e5) 0 0;
}

/* Estado vacío */
.vacio {
  text-align: center;
  padding: var(--e7) var(--e5);
  color: var(--tinta-2);
}
.vacio svg {
  width: 52px; height: 52px;
  color: var(--linea-2);
  margin: 0 auto var(--e3);
  fill: none; stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
}
.vacio h2 { margin-bottom: 6px; }
.vacio p { margin: 0 auto var(--e5); max-width: 36ch; font-size: var(--t-base); }

/* Esqueleto de carga */
.esqueleto {
  background: linear-gradient(90deg, var(--linea) 25%, var(--papel-2) 50%, var(--linea) 75%);
  background-size: 200% 100%;
  animation: brillo 1.4s infinite;
  border-radius: var(--r-sm);
}
@keyframes brillo { to { background-position: -200% 0; } }
.esqueleto-tarjeta { aspect-ratio: 3/4; border-radius: var(--r-md); }

/* ============================= PRODUCTO ============================== */
.producto { padding: var(--e3) 0 var(--e7); }
/* Alineado con la ficha de arriba, para que no bailen entre sí en
   pantallas anchas. */
.relacionados { margin-top: var(--e6); max-width: 1120px; margin-inline: auto; }
.producto-galeria { position: relative; }
.visor { position: relative; }
.producto-galeria .principal {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  background: var(--papel-2);
  border-radius: var(--r-md);
  display: block;
}
/* El vídeo se ve entero, sin recortar: una prenda cortada por la mitad
   no se entiende. El fondo rellena lo que sobra. */
#video-principal { object-fit: contain; background: #14061f; }

/* Miniatura de un vídeo: no hay fotograma que enseñar sin descargarlo
   entero, así que se marca con el triángulo de reproducir. */
.miniaturas button.mini-video,
.miniaturas .marca-video {
  display: grid;
  place-items: center;
  background: var(--morado);
  color: #fff;
  font-size: 15px;
  line-height: 1;
}
.miniaturas .marca-video { width: 100%; height: 100%; }
.miniaturas .marca-video svg { width: 15px; height: 15px; }
.miniaturas {
  display: flex;
  gap: var(--e2);
  margin-top: var(--e2);
  overflow-x: auto;
  padding-bottom: var(--e1);
  -webkit-overflow-scrolling: touch;
}
.miniaturas button {
  flex: 0 0 64px;
  width: 64px;
  aspect-ratio: 3/4;
  border: 2px solid transparent;
  border-radius: var(--r-sm);
  overflow: hidden;
  padding: 0;
  background: var(--papel-2);
  cursor: pointer;
  transition: border-color var(--transicion), opacity var(--transicion);
  opacity: .65;
}
.miniaturas button:hover { opacity: 1; }
.miniaturas button[aria-pressed="true"] { border-color: var(--morado); opacity: 1; }
.miniaturas img { width: 100%; height: 100%; object-fit: cover; }

.producto-info { padding-top: var(--e5); }
.producto-info h1 { font-size: var(--t-2xl); margin-bottom: var(--e2); }
.producto-precio {
  font-size: var(--t-3xl);
  font-weight: 800;
  letter-spacing: var(--track-titular-grande);
  color: var(--morado);
  line-height: 1.1;
  margin-bottom: 4px;
}
.producto-precio .antes {
  font-size: var(--t-lg); color: var(--tinta-3);
  text-decoration: line-through; margin-left: 10px; font-weight: 500;
  letter-spacing: 0;
}
.precio-bs { font-size: var(--t-md); color: var(--tinta-2); margin-bottom: var(--e5); }

.selector-grupo { margin-bottom: var(--e5); }
.selector-grupo .etiqueta {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--e3);
}
.selector-grupo .elegido {
  text-transform: none; letter-spacing: -0.008em;
  color: var(--tinta); font-weight: 600; font-size: var(--t-md);
}

.contador-cantidad {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--linea-2);
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--papel);
}
.contador-cantidad button {
  width: 46px; height: 46px;
  border: 0;
  background: transparent;
  font-size: 19px;
  color: var(--morado);
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: background var(--transicion);
}
.contador-cantidad button:hover { background: var(--morado-suave); }
.contador-cantidad button[disabled] { color: var(--linea-2); cursor: not-allowed; }
.contador-cantidad input {
  width: 48px;
  min-height: 46px;
  border: 0;
  border-left: 1px solid var(--linea);
  border-right: 1px solid var(--linea);
  text-align: center;
  font-weight: 700;
  font-size: var(--t-base);
  font-variant-numeric: tabular-nums;
  padding: 0;
  border-radius: 0;
  -moz-appearance: textfield;
}
.contador-cantidad input::-webkit-outer-spin-button,
.contador-cantidad input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.acciones-producto { display: grid; gap: var(--e2); margin-top: var(--e5); }

/* Nota de confianza bajo los botones. Antes era un aviso azul, un color
   que no existe en la marca y que además grita «sistema». */
.nota-pago {
  display: flex;
  align-items: flex-start;
  gap: var(--e3);
  margin-top: var(--e5);
  padding: var(--e3) var(--e4);
  border-radius: var(--r-md);
  background: var(--morado-suave);
  color: var(--morado-2);
  font-size: var(--t-md);
  line-height: 1.55;
}
/* Va alineada a la izquierda aunque esté dentro de una tarjeta centrada:
   un párrafo de cuatro líneas centrado no hay quien lo lea. */
.nota-pago { text-align: left; }
.nota-pago svg { flex: 0 0 auto; width: 20px; height: 20px; margin-top: 2px; opacity: .8; }
.nota-pago strong { display: block; color: var(--morado); margin-bottom: 2px; }

/* ============================== CARRITO ============================== */
.cajon {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  /* Nunca ocupa el ancho completo: siempre queda una franja del catálogo
     oscurecida a la izquierda. Esa franja no es decoración, es la forma
     natural de cerrar —se toca fuera y se cierra— en vez de obligar a
     buscar la X. Con el cajón a pantalla completa no había dónde tocar.
     El valor vive en `--ancho-cajon` porque el panel de filtros usa el
     mismo: los dos cajones de la tienda miden igual. */
  width: var(--ancho-cajon);
  background: var(--papel);
  z-index: 90;
  transform: translateX(100%);
  transition: transform 260ms cubic-bezier(.32, .72, 0, 1);
  display: flex;
  flex-direction: column;
  box-shadow: var(--sombra-3);
}
.cajon.abierto { transform: translateX(0); }
.cajon-cabeza {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--e4);
  border-bottom: 1px solid var(--linea);
}
.cajon-cabeza h2 { margin: 0; font-size: var(--t-lg); }
.cajon-cuerpo { flex: 1 1 auto; overflow-y: auto; padding: var(--e2) var(--e4); }
.cajon-pie {
  flex: 0 0 auto;
  padding: var(--e4) var(--e4) calc(var(--e4) + var(--seguro-abajo));
  border-top: 1px solid var(--linea);
  background: var(--papel);
  box-shadow: 0 -6px 20px rgba(30, 12, 45, .05);
}

.linea-carrito {
  display: grid;
  grid-template-columns: 70px 1fr auto;
  gap: var(--e3);
  padding: var(--e3) 0;
  border-bottom: 1px solid var(--linea);
}
.linea-carrito:last-child { border-bottom: 0; }
.linea-carrito .foto {
  width: 70px; aspect-ratio: 3/4;
  object-fit: cover;
  border-radius: var(--r-sm);
  background: var(--papel-2);
}
.linea-carrito .nombre {
  font-weight: 600; font-size: var(--t-base); color: var(--tinta); line-height: 1.3;
}
.linea-carrito .variante { font-size: var(--t-md); color: var(--tinta-2); margin-top: 3px; }
.linea-carrito .precio {
  font-size: var(--t-md); color: var(--tinta-2); font-weight: 500; margin-top: 3px;
}
.linea-carrito .controles { display: flex; align-items: center; gap: var(--e2); margin-top: var(--e2); }
.linea-carrito .contador-cantidad button { width: 34px; height: 34px; font-size: 16px; }
.linea-carrito .contador-cantidad input { width: 38px; min-height: 34px; font-size: var(--t-md); }
.linea-carrito .derecha {
  display: flex; flex-direction: column; align-items: flex-end;
  justify-content: space-between; gap: var(--e2);
}
.linea-carrito .total {
  font-weight: 700; color: var(--morado); font-size: var(--t-base);
  white-space: nowrap; letter-spacing: -0.015em;
}
.icono-accion {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border: 0; background: transparent;
  color: var(--tinta-3);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background var(--transicion), color var(--transicion);
}
.icono-accion:hover { background: var(--error-fondo); color: var(--error); }
.icono-accion svg { width: 16px; height: 16px; }

.resumen-linea {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--e3);
  padding: 6px 0;
  font-size: var(--t-base);
  color: var(--tinta-2);
}
.resumen-linea strong { color: var(--tinta); font-weight: 600; white-space: nowrap; }
.resumen-linea.descuento { color: var(--ok); }
.resumen-linea.descuento strong { color: var(--ok); }
.resumen-linea.total {
  border-top: 1px solid var(--linea);
  margin-top: var(--e2);
  padding-top: var(--e3);
  font-size: var(--t-lg);
  color: var(--tinta);
  font-weight: 600;
}
.resumen-linea.total strong {
  color: var(--morado); font-size: var(--t-2xl); font-weight: 800;
  letter-spacing: var(--track-titular-grande); line-height: 1.1;
}

.bloque-bs {
  background: linear-gradient(140deg, var(--morado-suave), var(--fucsia-suave));
  border: 1px solid var(--morado-borde);
  border-radius: var(--r-md);
  padding: var(--e4);
  text-align: center;
  margin: var(--e4) 0;
}
.bloque-bs .rotulo {
  font-size: var(--t-xs); font-weight: 700; letter-spacing: var(--track-etiqueta);
  text-transform: uppercase; color: var(--morado); margin-bottom: 4px;
}
.bloque-bs .monto {
  font-size: var(--t-2xl); font-weight: 800; color: var(--morado);
  letter-spacing: var(--track-titular-grande); line-height: 1.1;
}
.bloque-bs .nota { font-size: var(--t-sm); color: var(--tinta-2); margin-top: 5px; }

/* ============================== CHECKOUT ============================= */
.checkout { padding: var(--e3) 0 var(--e7); }
.checkout-columnas { display: grid; gap: var(--e4); }
/* Los hijos de una rejilla llevan `min-width: auto`, así que NO encogen por
   debajo de su contenido mínimo. La tira de pestañas de entrega («Retiro en
   tienda» + «Delivery» + «Envío nacional», que no parten palabra) fijaba un
   suelo de 377 px para la página entera, y su propio `overflow-x` no servía
   de nada porque el suelo lo imponía el contenedor, no ella.
   Resultado: el checkout —la pantalla que cobra— se movía de lado en todo
   teléfono de 320, 360 y 375 px, que es el parque más común aquí. */
.checkout-columnas > * { min-width: 0; }

/* En teléfono las pestañas se deslizan de lado. Repartidas en columnas
   iguales, con seis pestañas cada una quedaba en 59 px y «Mensajes» se
   salía de la pantalla. */
.pestanas {
  display: flex;
  gap: var(--e1);
  background: var(--papel-2);
  border: 1px solid var(--linea);
  border-radius: var(--r-sm);
  padding: 4px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.pestanas::-webkit-scrollbar { display: none; }
.pestanas button {
  flex: 1 0 auto;
  min-height: 42px;
  padding: 9px 14px;
  white-space: nowrap;
  border: 0;
  border-radius: 7px;
  background: transparent;
  font-family: inherit;
  font-size: var(--t-md);
  font-weight: 600;
  color: var(--tinta-2);
  cursor: pointer;
  line-height: 1.25;
  transition: background var(--transicion), color var(--transicion),
              box-shadow var(--transicion);
}
.pestanas button:hover { color: var(--tinta); }
.pestanas button[aria-selected="true"] {
  background: var(--morado);
  color: #fff;
  box-shadow: 0 1px 2px rgba(44, 0, 64, .25);
}

.opcion-radio {
  display: flex;
  align-items: flex-start;
  gap: var(--e3);
  padding: var(--e3) var(--e4);
  border: 1px solid var(--linea-2);
  border-radius: var(--r-sm);
  cursor: pointer;
  margin-bottom: var(--e2);
  background: var(--papel);
  transition: border-color var(--transicion), background var(--transicion),
              box-shadow var(--transicion);
}
.opcion-radio:hover { border-color: var(--morado-borde); background: var(--papel-2); }
.opcion-radio input {
  margin-top: 2px; flex: 0 0 auto; width: 19px; height: 19px;
  accent-color: var(--morado); cursor: pointer;
}
.opcion-radio .titulo {
  display: block;
  font-weight: 600; font-size: var(--t-base); color: var(--tinta);
}
.opcion-radio .detalle {
  display: block;
  font-size: var(--t-md); color: var(--tinta-2); margin-top: 2px;
}
.opcion-radio .precio {
  margin-left: auto; font-weight: 700; color: var(--morado);
  white-space: nowrap; letter-spacing: -0.015em;
}
.opcion-radio:has(input:checked) {
  border-color: var(--morado);
  background: var(--morado-suave);
  box-shadow: inset 0 0 0 1px var(--morado);
}

.datos-pago {
  background: var(--papel-2);
  border: 1px solid var(--linea);
  border-radius: var(--r-sm);
  padding: var(--e2) var(--e4);
  margin: -2px 0 var(--e3);
}
.dato-copiable {
  display: flex; align-items: center; gap: var(--e3);
  padding: 10px 0;
  border-bottom: 1px solid var(--linea);
}
.dato-copiable:last-child { border-bottom: 0; }
.dato-copiable .rotulo {
  font-size: var(--t-xs); font-weight: 700; letter-spacing: var(--track-etiqueta);
  text-transform: uppercase; color: var(--tinta-2);
  flex: 0 0 auto; min-width: 72px;
}
.dato-copiable .valor {
  font-weight: 600; font-size: var(--t-base); color: var(--tinta);
  flex: 1 1 auto; word-break: break-all;
  font-variant-numeric: tabular-nums;
}
.dato-copiable button {
  flex: 0 0 auto;
  min-height: 34px; padding: 6px 12px;
  border: 1px solid var(--linea-2);
  border-radius: var(--r-sm);
  background: var(--papel);
  font: inherit; font-size: var(--t-sm); font-weight: 600;
  color: var(--morado); cursor: pointer;
  transition: background var(--transicion), color var(--transicion);
}
.dato-copiable button:hover { background: var(--morado); color: #fff; border-color: var(--morado); }

.zona-subida {
  display: block;
  border: 2px dashed var(--linea-2);
  border-radius: var(--r-md);
  padding: var(--e5) var(--e4);
  text-align: center;
  background: var(--papel-2);
  cursor: pointer;
  transition: border-color var(--transicion), background var(--transicion);
}
.zona-subida:hover, .zona-subida.encima {
  border-color: var(--morado); background: var(--morado-suave);
}
.zona-subida svg {
  display: block;
  width: 32px; height: 32px;
  color: var(--morado);
  margin: 0 auto var(--e2);
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
.zona-subida .titulo { font-weight: 600; color: var(--morado); font-size: var(--t-base); }
.zona-subida .detalle { font-size: var(--t-md); color: var(--tinta-2); margin-top: 3px; }
.zona-subida input[type="file"] { display: none; }
.vista-previa { margin-top: var(--e3); position: relative; display: block; text-align: center; }
.vista-previa img {
  max-width: 100%; max-height: 280px;
  margin: 0 auto;
  border-radius: var(--r-sm);
  border: 1px solid var(--linea);
}
.vista-previa .quitar {
  position: absolute; top: -10px; right: -6px;
  width: 34px; height: 34px;
  border-radius: var(--r-full);
  background: var(--error); color: #fff;
  border: 2px solid var(--papel);
  cursor: pointer;
  display: grid; place-items: center;
  font-size: 16px; line-height: 1;
  box-shadow: var(--sombra-1);
}

.resumen-pedido { position: relative; }
.resumen-items { max-height: 270px; overflow-y: auto; }

/* ============================ MIS PEDIDOS ============================ */
.pedido-tarjeta {
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--r-md);
  overflow: hidden;
  margin-bottom: var(--e4);
  box-shadow: var(--sombra-1);
}
.pedido-cabeza {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px var(--e3);
  padding: var(--e4) var(--e4) var(--e3);
}
.pedido-cabeza .numero {
  font-weight: 800; font-size: var(--t-lg); color: var(--morado);
  letter-spacing: var(--track-titular); font-variant-numeric: tabular-nums;
}
.pedido-cabeza .fecha { font-size: var(--t-md); color: var(--tinta-2); width: 100%; }
.pedido-cabeza .total {
  margin-left: auto; font-weight: 800; color: var(--morado);
  font-size: var(--t-lg); letter-spacing: -0.02em;
}

.pedido-estado {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 11px;
  border: 1px solid transparent;
  border-radius: var(--r-full);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: -0.005em;
}
.estado-por_verificar { background: var(--alerta-fondo); color: var(--alerta); border-color: var(--alerta-borde); }
.estado-pagado { background: var(--ok-fondo); color: var(--ok); border-color: var(--ok-borde); }
.estado-despachado { background: var(--info-fondo); color: var(--info); border-color: var(--info-borde); }
.estado-entregado { background: var(--ok-fondo); color: var(--ok); border-color: var(--ok-borde); }
.estado-rechazado, .estado-cancelado, .estado-vencido, .estado-rechazada {
  background: var(--error-fondo); color: var(--error); border-color: var(--error-borde);
}

/* Seguimiento del pedido: los pasos y los datos del envío */
.seguimiento {
  list-style: none;
  margin: 0 0 var(--e4);
  padding: 0;
  display: grid;
  gap: 0;
}
.seguimiento li {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--e3);
  padding: 9px 0;
  color: var(--tinta-3);
  font-size: var(--t-base);
}
/* La línea que une los pasos, dibujada desde el punto de cada uno */
.seguimiento li:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 6px; top: 26px; bottom: -4px;
  width: 2px;
  background: var(--linea);
}
.seguimiento li.hecho:not(:last-child)::before { background: var(--morado-borde); }
.seguimiento .punto {
  flex: 0 0 auto;
  width: 14px; height: 14px;
  border-radius: var(--r-full);
  background: var(--papel);
  box-shadow: inset 0 0 0 2px var(--linea-2);
}
.seguimiento li.hecho { color: var(--tinta); font-weight: 600; }
.seguimiento li.hecho .punto { background: var(--morado); box-shadow: none; }

.datos-envio { border-top: 1px solid var(--linea); padding-top: var(--e3); }
.datos-envio .fila {
  display: flex;
  justify-content: space-between;
  gap: var(--e4);
  padding: 7px 0;
  font-size: var(--t-md);
  color: var(--tinta-2);
}
.datos-envio .fila strong { color: var(--tinta); text-align: right; }
.datos-envio .fila.destacada strong { color: var(--morado); font-size: var(--t-base); }
.nota-envio {
  margin: var(--e2) 0 0;
  padding: var(--e3);
  border-radius: var(--r-sm);
  background: var(--morado-suave);
  color: var(--morado-2);
  font-size: var(--t-md);
  line-height: 1.55;
}

/* El mensaje de la tienda dentro del pedido.
   Iba de punta a punta de la tarjeta, en morado pleno y centrado: se leía
   como una franja de sistema pegada al borde, no como un mensaje de la
   tienda. Ahora va metido hacia dentro, con esquinas redondeadas y una
   barra de acento a la izquierda que es lo que lo hace parecer un aviso
   escrito por alguien y no un cintillo. */
/* El recado que la tienda le deja a la clienta en su pedido («retira a
   partir de las 3 pm», «tu talla entra el jueves»). Va en el MISMO amarillo
   que la etiqueta «Verificando tu pago», que es el color con el que esta
   tienda dice «esto es para ti, léelo». En morado sobre blanco competía con
   los botones de acción y se leía como decoración de la tarjeta. */
.mensaje-tienda {
  margin: var(--e3);
  border-radius: 12px;
  border-left: 4px solid var(--alerta);
  background: var(--alerta-fondo);
  color: var(--alerta-texto);
  padding: 12px 14px;
  font-size: var(--t-md);
  font-weight: 600;
  letter-spacing: -0.005em;
  text-align: left;
  line-height: 1.45;
}

.pedido-lineas { padding: var(--e1) var(--e4) var(--e4); }
.pedido-linea {
  display: grid;
  grid-template-columns: 66px 1fr;
  gap: var(--e3);
  padding: var(--e3) 0;
  border-bottom: 1px solid var(--linea);
}
.pedido-linea:last-child { border-bottom: 0; }
.pedido-linea img {
  width: 66px; aspect-ratio: 3/4; object-fit: cover;
  border-radius: var(--r-sm); background: var(--papel-2);
}
.pedido-linea .nombre { font-weight: 600; font-size: var(--t-base); }
.pedido-linea .meta { font-size: var(--t-md); color: var(--tinta-2); line-height: 1.55; }
.pedido-acciones {
  display: flex; flex-wrap: wrap; gap: var(--e2);
  padding: 0 var(--e4) var(--e4);
}
.pedido-acciones .btn { flex: 1 1 auto; min-width: 140px; }

/* ------------------------------------------------- Mis pedidos, como Amazon
   Los productos a la izquierda y los botones en su PROPIA columna a la
   derecha, uno encima de otro.

   Lado a lado, dos botones del mismo tamaño compiten entre ellos y hacen
   dudar; y al ir debajo de las fotos quedaban lejos de donde se está
   mirando. Apilados a la derecha hay uno principal y el resto debajo, que
   es como se lee una lista de pedidos.

   En TELÉFONO no se aplica nada de esto: ahí los dos botones lado a lado
   ocupan el ancho justo y se ven bien, y una columna estrecha a la derecha
   no cabe. Decisión de Emmanuel.

   Esto NO toca `.pedido-acciones` a secas, que la usan también las tres
   colas del panel: ahí los botones son otros y van a lo ancho. */
@media (min-width: 760px) {
  .pedido-cuerpo {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 240px;
    align-items: start;
  }
  /* La columna respira por su lado y no arrastra el relleno de abajo de la
     lista de productos, que la dejaba descolgada. */
  .pedido-acciones-columna {
    flex-direction: column;
    padding: var(--e4) var(--e4) var(--e4) 0;
  }
  .pedido-acciones-columna .btn { flex: 0 0 auto; width: 100%; min-width: 0; }
}

/* ============================== FACTURA ============================== */
.factura {
  background: #fff;
  padding: var(--e5) var(--e4);
  border-radius: var(--r-md);
  border: 1px solid var(--linea);
}
.factura-cabeza {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: var(--e4); flex-wrap: wrap;
  border-bottom: 2px solid var(--morado);
  padding-bottom: var(--e4); margin-bottom: var(--e5);
}
.factura-tabla { width: 100%; border-collapse: collapse; font-size: var(--t-base); }
.factura-tabla th {
  text-align: left; font-size: var(--t-xs); text-transform: uppercase;
  letter-spacing: var(--track-etiqueta); color: var(--tinta-2);
  padding: var(--e2) 6px; border-bottom: 1px solid var(--linea);
}
.factura-tabla td { padding: var(--e3) 6px; border-bottom: 1px solid var(--linea); vertical-align: top; }
.factura-tabla td.num, .factura-tabla th.num { text-align: right; white-space: nowrap; }

@media print {
  .cabecera, .barra-inferior, .pedido-acciones, .no-imprimir, .brindis,
  .cajon, .velo { display: none !important; }
  body { background: #fff; padding: 0; }
  .factura { border: 0; padding: 0; }
}

/* =============================== PANEL =============================== */
.panel { padding: var(--e3) 0 var(--e7); }
.panel-resumen {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--e2);
  margin-bottom: var(--e4);
}
.ficha-resumen {
  display: block;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--r-md);
  padding: var(--e3) var(--e4);
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  transition: border-color var(--transicion), box-shadow var(--transicion),
              transform var(--transicion);
}
.ficha-resumen:hover {
  border-color: var(--morado-borde); box-shadow: var(--sombra-2);
  text-decoration: none; transform: translateY(-1px);
}
.ficha-resumen[aria-selected="true"], .ficha-resumen[aria-current="page"] {
  border-color: var(--morado);
  box-shadow: inset 0 0 0 1px var(--morado);
  background: var(--morado-suave);
}
.ficha-resumen .cifra {
  font-size: 1.75rem; font-weight: 800; color: var(--morado);
  line-height: 1; letter-spacing: var(--track-titular-grande);
  font-variant-numeric: tabular-nums;
}
.ficha-resumen .rotulo {
  font-size: var(--t-sm); color: var(--tinta-2); font-weight: 600;
  margin-top: 4px; line-height: 1.3;
}
.ficha-resumen.urgente .cifra { color: var(--fucsia); }

.tabla-panel { width: 100%; border-collapse: collapse; font-size: var(--t-base); }
.tabla-panel th {
  text-align: left; padding: var(--e3) var(--e2);
  font-size: var(--t-xs); text-transform: uppercase;
  letter-spacing: var(--track-etiqueta);
  color: var(--tinta-2); border-bottom: 1px solid var(--linea);
  white-space: nowrap;
  font-weight: 700;
}
.tabla-panel td { padding: var(--e3) var(--e2); border-bottom: 1px solid var(--linea); vertical-align: middle; }
.tabla-panel tr:hover td { background: var(--papel-2); }
/* La tabla se desplaza por dentro de su caja, nunca ensancha la página.
   `max-width` y `min-width: 0` son los que lo garantizan: sin ellos, dentro
   de una rejilla o de un flex la caja crece hasta el ancho de la tabla y el
   desbordamiento se lo come el `<body>`, que es cuando aparece la barra de
   scroll horizontal en toda la pantalla. */
.tabla-envoltorio {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  max-width: 100%;
  min-width: 0;
}

/* -------------------------------------------------- filtros del panel
   La fila de filtros de la Bitácora (Acción, Quién, Desde, Hasta…).

   Antes era un `flex` con las medidas escritas a mano en el atributo
   `style` de la plantilla, y en el teléfono se salía de la tarjeta: un
   campo de fecha tiene un ancho mínimo propio que el navegador NO encoge,
   así que dos de ellos juntos empujaban la fila más allá del borde. Encima
   el formulario era una `.tarjeta` sin relleno, así que los campos nacían
   pegados al borde y las etiquetas parecían desalineadas.

   Con una rejilla de columnas elásticas cada campo se baja de línea solo
   cuando no cabe. La clave es `min(100%, 170px)`: le dice a la columna que
   nunca pida más ancho del que hay en pantalla. */
.filtros-panel {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 170px), 1fr));
  gap: var(--e3);
  align-items: end;
  padding: var(--e4);
  margin-bottom: var(--e4);
}
.filtros-panel label {
  display: grid;
  gap: 5px;
  min-width: 0;
  font-size: var(--t-md);
  font-weight: 600;
  color: var(--tinta-2);
}
.filtros-panel input, .filtros-panel select { min-width: 0; max-width: 100%; }
/* La casilla de verificación no lleva su texto encima sino al lado. */
.filtros-panel .casilla {
  display: flex;
  align-items: center;
  gap: var(--e2);
  min-height: 46px;
  font-weight: 500;
}
.filtros-panel .casilla input { width: auto; min-height: 0; }
/* Los botones son un hijo más de la rejilla, así que también necesitan
   `min-width: 0`: sin él, la fila de dos botones no encoge por debajo de su
   contenido, se sale de la tarjeta y arrastra a la página entera. Y si aun
   así no caben, se bajan de línea. */
.filtros-panel > * { min-width: 0; }
.filtros-panel-botones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2);
  align-items: center;
  min-width: 0;
}
.filtros-panel-botones .btn { flex: 1 1 120px; min-width: 0; }

/* ----------------------------------------------- ayuda con el pago
   La ventana de «Ayuda» de Mis pedidos. Se abre y se cierra con `:target`
   —el enlace apunta a su propio id— sin una línea de JavaScript: la abre
   alguien que cree que su dinero se perdió, y esa pantalla no puede
   depender de que un script haya cargado bien. */
.capa-ayuda {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 95;
  align-items: center;
  justify-content: center;
  padding: var(--e4);
}
.capa-ayuda:target { display: flex; }
.capa-ayuda-fondo {
  position: absolute;
  inset: 0;
  background: rgba(25, 10, 38, .48);
  backdrop-filter: blur(2px);
}
.capa-ayuda-caja {
  position: relative;
  width: min(100%, 440px);
  max-height: 88vh;
  overflow-y: auto;
  padding: var(--e4);
  background: var(--papel);
  border-radius: var(--r-lg);
  box-shadow: var(--sombra-3);
}
.capa-ayuda-cabeza {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--e3);
  margin-bottom: var(--e2);
}
.capa-ayuda-cabeza h2 { margin: 0; font-size: var(--t-lg); }
.capa-ayuda-cabeza .icono-btn { font-size: 24px; line-height: 1; text-decoration: none; }
.capa-ayuda-texto { margin: 0 0 var(--e4); font-size: var(--t-base); color: var(--tinta-2); }
.capa-ayuda-caja form { margin-bottom: var(--e3); }
.capa-ayuda-caja .ayuda { margin: 5px 0 0; font-size: var(--t-sm); color: var(--tinta-3); }
.aviso-margen-arriba { margin-top: var(--e4); }
/* Un aviso dentro de la tarjeta de un pedido, alineado con su contenido. */
.aviso-en-pedido { margin: var(--e3) var(--e4) 0; }
/* Un bloque suelto dentro de una tarjeta de las colas del panel, alineado
   con el resto del contenido de la tarjeta. */
.cola-bloque { padding: 0 var(--e4) 10px; }
.cola-bloque > .aviso { margin: 0; }
.campo-apretado { margin-bottom: var(--e2); }
/* La casilla de marcar de una lista del panel (telas, categorías, colores).
   Más grande que la del navegador, que a dedo no se acierta. */
.casilla-marca { width: 18px; height: 18px; accent-color: var(--morado); }

/* La caja de descarga de la bitácora: explicación a la izquierda, botón a la
   derecha. En el teléfono el botón se baja y ocupa el ancho. */
.descarga-bitacora {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--e3);
  padding: var(--e4);
  margin-bottom: var(--e4);
}
.descarga-bitacora > div { flex: 1 1 260px; min-width: 0; }
.descarga-bitacora p {
  margin: 4px 0 0;
  font-size: var(--t-md);
  color: var(--tinta-2);
  line-height: 1.55;
  max-width: 70ch;
}
.descarga-bitacora .btn { flex: 0 0 auto; }

/* Una aclaración debajo de la celda de una tabla. */
.nota-tabla { font-size: var(--t-sm); color: var(--tinta-2); margin-top: 3px; line-height: 1.5; }
.boton-ayuda-pago { margin-top: var(--e4); }
.estado-auditoria { margin: var(--e4) 0 0; text-align: center; }

/* «EN AUDITORÍA»: el pago incompleto con su captura ya subida. No es un
   botón apagado por error, es el estado en el que está el pedido. */
.btn[aria-disabled="true"].btn-auditoria {
  background: var(--alerta-fondo);
  color: var(--alerta-texto);
  border: 1px solid var(--alerta-borde);
  cursor: default;
  pointer-events: none;
  letter-spacing: var(--track-etiqueta);
}

.comprobante-vista {
  border: 1px solid var(--linea);
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--papel-2);
}
.comprobante-vista img { width: 100%; max-height: 420px; object-fit: contain; cursor: zoom-in; }

.lupa {
  position: fixed; inset: 0;
  background: rgba(15, 6, 22, .94);
  z-index: 120;
  display: grid;
  place-items: center;
  padding: var(--e4);
}
.lupa img { max-width: 100%; max-height: 92vh; object-fit: contain; border-radius: var(--r-sm); }
.lupa .cerrar {
  position: absolute; top: var(--e3); right: var(--e3);
  width: 44px; height: 44px;
  border-radius: var(--r-full);
  background: rgba(255,255,255,.16);
  color: #fff; border: 0; font-size: 22px; cursor: pointer;
}

/* ============================== VARIOS =============================== */
.paginacion { display: flex; justify-content: center; gap: var(--e2); margin-top: var(--e5); flex-wrap: wrap; }
.paginacion a, .paginacion span {
  min-width: 42px; min-height: 42px;
  display: grid; place-items: center;
  padding: 0 var(--e3);
  border: 1px solid var(--linea-2);
  border-radius: var(--r-sm);
  font-size: var(--t-base); font-weight: 600;
  font-variant-numeric: tabular-nums;
  background: var(--papel);
  transition: border-color var(--transicion), background var(--transicion);
}
.paginacion a:hover { border-color: var(--morado); background: var(--morado-suave); text-decoration: none; }
.paginacion .actual { background: var(--morado); color: #fff; border-color: var(--morado); }

.migas { font-size: var(--t-md); color: var(--tinta-2); padding: var(--e3) 0 2px; }
.migas a { color: var(--tinta-2); }
.migas a:hover { color: var(--morado); }

/* `main` crece para empujar el pie hasta abajo; el resto no se estira. */
main { flex: 1 0 auto; }
.cabecera, .franja-aviso, .pie, .barra-inferior { flex: 0 0 auto; }

.pie {
  background: var(--morado);
  color: rgba(255,255,255,.78);
  padding: var(--e6) 0 var(--e5);
  margin-top: var(--e7);
  font-size: var(--t-base);
}
.pie a { color: rgba(255,255,255,.92); }
.pie a:hover { color: #fff; }
.pie h3 {
  color: #fff; font-size: var(--t-md); margin-bottom: var(--e3);
  text-transform: uppercase; letter-spacing: var(--track-etiqueta); font-weight: 700;
}
.pie .logo { color: #fff; }
/* La dirección del local, debajo del eslogan. Sin subrayado: decisión de
   Emmanuel. El enlace al mapa sigue funcionando igual, y se subraya al
   pasar por encima como todos los enlaces del pie. */
.pie-direccion { margin: 0 0 var(--e2); max-width: 34ch; line-height: 1.55; }
.pie-columnas { display: grid; gap: var(--e5); }
.pie ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--e2); }
.pie-legal {
  border-top: 1px solid rgba(255,255,255,.16);
  margin-top: var(--e5); padding-top: var(--e4);
  font-size: var(--t-md); color: rgba(255,255,255,.55);
}

.brindis {
  position: fixed;
  left: 50%;
  bottom: calc(76px + var(--seguro-abajo));
  transform: translate(-50%, 16px);
  z-index: 150;
  background: var(--tinta);
  color: #fff;
  padding: 12px 20px;
  border-radius: var(--r-full);
  font-size: var(--t-base);
  font-weight: 500;
  box-shadow: var(--sombra-3);
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms ease, transform 200ms ease;
  max-width: calc(100vw - 32px);
  text-align: center;
}
.brindis.visible { opacity: 1; transform: translate(-50%, 0); }
.brindis.error { background: var(--error); }

.cargando {
  display: inline-block;
  width: 15px; height: 15px;
  border: 2px solid rgba(255,255,255,.35);
  border-top-color: #fff;
  border-radius: 50%;
  animation: girar .7s linear infinite;
}
@keyframes girar { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* =====================================================================
   PANTALLAS MÁS GRANDES — solo añaden, nunca rehacen
   ===================================================================== */

/* Teléfono grande */
@media (min-width: 480px) {
  .panel-resumen { grid-template-columns: repeat(3, 1fr); }
  .rejilla-productos { gap: var(--e4); }
}

/* Tablet vertical */
@media (min-width: 640px) {
  .envoltorio { padding: 0 var(--e5); }
  .rejilla-productos { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .acciones-producto { grid-template-columns: 1fr 1fr; }
  /* Dos columnas, no tres: el pie tiene cuatro bloques y con tres el
     cuarto bajaba solo a una fila nueva dejando un hueco enorme. */
  .pie-columnas { grid-template-columns: repeat(2, 1fr); }
  .factura { padding: var(--e6); }
  .tarjeta-cuerpo { padding: var(--e5); }
  .tarjeta-titulo { padding: var(--e4) var(--e5); }
}

/* Tablet horizontal: aparece el menú, se va la barra inferior */
@media (min-width: 900px) {
  :root { --barra: 66px; --cabecera: 66px; }
  body { font-size: 1rem; }
  body.con-barra-inferior { padding-bottom: 0; }
  .barra-inferior { display: none; }

  .cabecera-fila { flex-wrap: nowrap; height: var(--barra); gap: var(--e4); }
  .logo { font-size: 1.5rem; }
  .buscador { order: 0; flex: 1 1 auto; max-width: 560px; padding-bottom: 0; }
  .buscador-campo { height: 44px; }

  /* De aquí para arriba, los iconos del encabezado llevan su nombre al
     lado: se leen de un vistazo y el encabezado deja de parecer tres
     puntitos en la esquina. En teléfono el rótulo no sale (ver arriba).

     Las tres piezas de la cabecera —menú, buscador y acciones— comparten
     la MISMA altura (44 px), el MISMO radio (--r-md, el del buscador) y la
     MISMA tipografía. Antes los rótulos «Favoritos / Carrito / Mi cuenta»
     iban a 13 px y los del menú a 15 px, y el menú no tenía altura fija:
     tres pastillas de tres tamaños distintos en una misma fila. La
     diferencia era pequeña pero se notaba, porque el ojo compara lo que
     está alineado. */
  .cabecera-acciones { gap: var(--e1); }
  .cabecera-acciones .icono-btn {
    width: auto;
    height: 44px;
    padding: 0 14px;
    gap: 9px;
    border-radius: var(--r-md);
  }
  .cabecera-acciones .icono-btn svg { width: 24px; height: 24px; }
  .rotulo-accion {
    display: inline;
    font-size: var(--t-base);
    font-weight: 600;
    letter-spacing: -0.008em;
    white-space: nowrap;
  }
  .cabecera-acciones .contador { top: 5px; right: 8px; }

  .menu-principal {
    display: flex;
    align-items: center;
    gap: 2px;
    margin-left: var(--e2);
  }
  .menu-principal a {
    display: inline-flex;
    align-items: center;
    height: 44px;
    padding: 0 14px;
    border-radius: var(--r-md);
    font-size: var(--t-base);
    font-weight: 600;
    color: var(--tinta-2);
    transition: background var(--transicion), color var(--transicion);
  }
  .menu-principal a:hover { background: var(--morado-suave); color: var(--morado); text-decoration: none; }
  .menu-principal a.activo { color: var(--morado); background: var(--morado-suave); }

  .filtros-movil { display: none; }

  /* Catálogo: menú a la izquierda, productos a la derecha */
  .catalogo {
    display: grid;
    grid-template-columns: 250px minmax(0, 1fr);
    gap: var(--e6);
    align-items: start;
    padding-top: var(--e5);
  }
  .panel-filtros {
    /* Baja contigo mientras haces scroll. Y si la lista de filtros es más
       alta que la pantalla, se desplaza por dentro en vez de quedarse
       con la mitad de abajo inalcanzable. */
    position: sticky;
    /* `inset: auto` va ANTES que `top`: puesto después lo borraba, y por
       eso el panel nunca llegó a quedarse pegado al hacer scroll. */
    inset: auto;
    top: calc(var(--cabecera) + var(--e4));
    /* En móvil este panel es un cajón que tapa la pantalla entera y por eso
       vive en la capa 90, por encima del velo. Aquí ya no es un cajón, es
       una columna más: si conserva esa capa se pinta ENCIMA de la cabecera
       —que está en la 60— al llegar al final de la página, cuando deja de
       estar pegada y sube con el contenido. */
    z-index: 1;
    max-height: calc(100vh - var(--cabecera) - var(--e5));
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: var(--linea-2) transparent;
    padding-right: 4px;
    width: auto;
    transform: none;
    box-shadow: none;
    background: transparent;
    border: 0;
    border-radius: 0;
  }
  .panel-filtros-cabeza, .panel-filtros-pie { display: none; }
  .panel-filtros-cuerpo { padding: 0; overflow: visible; }
  /* Aquí no hay pie que envíe el formulario, así que el botón vuelve. */
  .btn-aplicar-precio { display: flex; }
  .velo.solo-movil { display: none; }

  .barra-catalogo {
    display: flex;
    align-items: center;
    gap: var(--e4);
    margin-bottom: var(--e4);
  }
  .barra-catalogo .conteo-productos { margin-left: 0; font-size: var(--t-base); }
  .barra-catalogo .orden { margin-left: auto; max-width: 220px; }

  /* Producto: galería y datos lado a lado.
     La foto pesa un poco más que los datos —es lo que se compra— pero se
     le pone techo de alto: con una columna de 640 px de foto y otra de
     380 px de texto quedaba medio metro de blanco debajo del formulario. */
  .producto {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    gap: var(--e6);
    align-items: start;
    padding-top: var(--e4);
    /* El tope va en la rejilla y va centrado. Ponérselo a cada columna
       por separado dejaba las dos pegadas a la izquierda y un vacío de
       350 px a la derecha en pantallas de 1920. */
    max-width: 1120px;
    margin: 0 auto;
  }
  .producto-galeria {
    position: sticky;
    top: calc(var(--cabecera) + var(--e4));
  }
  .producto-info { padding-top: 0; }

  /* Checkout: formulario a la izquierda, resumen fijo a la derecha */
  .checkout-columnas {
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    gap: var(--e5);
    align-items: start;
  }
  .resumen-pedido { position: sticky; top: calc(var(--cabecera) + var(--e4)); }
  .resumen-items { max-height: 300px; }

  .pedido-cabeza .fecha { width: auto; }
  .panel-resumen { grid-template-columns: repeat(6, 1fr); }
  .pie-columnas { grid-template-columns: 2fr 1fr 1fr 1.2fr; gap: var(--e6); }
}

/* Escritorio */
@media (min-width: 1120px) {
  .rejilla-productos { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* Escritorio grande */
@media (min-width: 1440px) {
  .catalogo { grid-template-columns: 270px minmax(0, 1fr); }
  .rejilla-productos { gap: var(--e5); }
}

/* ========================= RECARGAR SALDO ==========================
   El saldo es dinero de la clienta: la cifra manda, y el botón de
   recargar va a su lado, no escondido en un menú. En teléfono la fila
   se parte para que el botón no empuje la cifra fuera de pantalla. */
.saldo-cabecera {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--e3);
}
.saldo-cabecera > div { min-width: 0; flex: 1 1 200px; }
.saldo-cifra {
  font-size: 2.1rem;
  font-weight: 800;
  color: var(--morado);
  line-height: 1;
  /* Las cifras de ancho fijo evitan que el número «baile» al cambiar. */
  font-variant-numeric: tabular-nums;
}
.saldo-cabecera .btn { flex: 0 0 auto; }

.recargas-pendientes {
  margin-top: 14px;
  display: grid;
  gap: 8px;
}
.recarga-fila {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  background: var(--papel-2);
  border-radius: var(--r-sm);
  box-shadow: inset 0 0 0 1px var(--linea);
  font-size: 13px;
}
.recarga-monto { font-weight: 700; font-variant-numeric: tabular-nums; }
.recarga-nota { color: var(--texto-suave); flex: 1 1 220px; min-width: 0; }

/* Los atajos de importe. Se leen como una fila de fichas, no como
   botones de acción: la acción es enviar la recarga, no elegir 30. */
.montos-recarga {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.chip-monto {
  flex: 0 0 auto;
  min-width: 74px;
  height: 44px;
  padding: 0 16px;
  border: 0;
  border-radius: var(--r-md);
  background: var(--papel-2);
  box-shadow: inset 0 0 0 1px var(--linea);
  color: var(--tinta);
  font-family: inherit;
  font-size: var(--t-base);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background var(--transicion), box-shadow var(--transicion),
              color var(--transicion);
}
.chip-monto:hover { box-shadow: inset 0 0 0 1px var(--linea-2); }
.chip-monto[aria-pressed="true"] {
  background: var(--morado);
  color: #fff;
  box-shadow: inset 0 0 0 1px var(--morado);
}

/* El recordatorio de que esto es crédito de tienda y no un depósito.
   Va junto al botón de enviar, que es donde la clienta decide. */
.aviso-recarga {
  margin: 0 0 14px;
  padding: 12px 14px;
  border-radius: var(--r-sm);
  background: var(--morado-suave);
  color: var(--morado);
  font-size: 13px;
  line-height: 1.5;
}

.estado-acreditada { background: var(--ok-fondo); color: var(--ok); border-color: var(--ok-borde); }

/* ---------------------------------------------------------------
   Buscador desplegado en teléfono y tablet

   Antes el panel era una cajita colgando del campo y por detrás se
   seguía viendo el catálogo: parecía que la pantalla estaba a medias.
   Ahora, al desplegarlo, todo lo que hay del encabezado para abajo es
   el buscador y nada más.

   La barra de navegación de abajo se queda visible a propósito: es la
   forma de salir de ahí sin buscar nada. Por eso el panel termina justo
   encima de ella en vez de taparla.

   `--sug-top` lo escribe el JavaScript con la posición real del borde
   inferior del encabezado. No se puede poner un número fijo: el
   encabezado cambia de alto según haya franja de aviso, según el largo
   del logo y según el ancho de la pantalla.
   --------------------------------------------------------------- */
@media (max-width: 899px) {
  .buscador.abierto .sugerencias {
    /* Sigue siendo `absolute`, no `fixed`. La cabecera lleva
       `backdrop-filter`, y eso convierte a la cabecera en el marco de
       referencia de todo lo que esté fijo dentro de ella: un `position:
       fixed` aquí se medía contra la cabecera y no contra la pantalla, y
       el panel salía con cero de alto. El alto va calculado. */
    /* De borde a borde de la PANTALLA, no de la caja del buscador.
       `.envoltorio` tiene 16 px de relleno a cada lado, así que con
       `left: 0; right: 0` quedaban dos franjas de 16 px por las que se
       seguía viendo el catálogo de fondo. Se sale de ese relleno con la
       misma medida, que es la misma variable: si cambia una, cambia la
       otra y siguen encajando.
       No desborda la página: el borde izquierdo cae justo en 0 y el
       derecho justo en el ancho de la pantalla. */
    left: calc(-1 * var(--e4));
    right: calc(-1 * var(--e4));
    height: var(--sug-alto, 60vh);
    max-height: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    /* Opaco de verdad: es lo que impide que se vea el catálogo detrás. */
    background: var(--papel);
  }

  /* A pantalla completa el campo recupera su forma: ya no hay ninguna
     unión que disimular, porque el panel es una superficie aparte que
     empieza donde termina el encabezado. */
  .buscador.abierto .buscador-campo {
    border-radius: var(--r-md);
    box-shadow: inset 0 0 0 1px var(--linea-2);
  }

  /* Las pestañas se quedan arriba al desplazar la lista de productos. */
  .buscador.abierto .sugerencias-pestanas {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--papel);
  }
}

/* ---------------------------------------------------------------
   La foto del producto en teléfono

   A 3/4 sobre una pantalla estrecha, la foto se comía casi todo el
   alto y había que desplazarse para descubrir que debajo estaban el
   color, la talla y el botón de comprar. Se recorta un poco el alto
   —solo un poco— para que asome lo que hay debajo y se entienda que
   la página sigue. El ancho no cambia: la foto se recorta, no se
   deforma.
   --------------------------------------------------------------- */
@media (max-width: 759px) {
  .producto-galeria .principal { max-height: 54vh; }
}

/* Categorías plegadas: solo asoman las primeras y un botón abre el resto.
   Lo que se gana es que el filtro de COLOR entre en la primera pantalla,
   sin desplazarse. Con veintitantas categorías desplegadas, los colores
   quedaban por debajo del borde inferior y había que bajar sin saber que
   estaban ahí, así que sencillamente no se usaban.
   Vale en TODAS las medidas: en escritorio y en tableta el panel de
   filtros es una columna con su propio alto máximo, y el problema es el
   mismo. */
.ver-mas-categorias {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 9px 12px;
  border: 0;
  border-radius: var(--r-sm);
  background: var(--papel-2);
  box-shadow: inset 0 0 0 1px var(--linea);
  color: var(--morado);
  font-family: inherit;
  font-size: var(--t-md);
  font-weight: 600;
  cursor: pointer;
}
.ver-mas-categorias:hover { background: var(--morado-suave); }

.lista-categorias .cat-extra { display: none; }
.lista-categorias.desplegada .cat-extra { display: list-item; }

/* Cliente con foto en las colas del panel. La cara es lo que permite
   reconocer un pedido de un vistazo cuando hay veinte nombres parecidos. */
.cliente-linea {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}
.cliente-linea .avatar { flex: 0 0 auto; }

/* La pantalla que obliga a releer un cupón antes de guardarlo. El repaso se
   lee como una ficha, no como un formulario: rótulo a la izquierda, lo que se
   va a guardar a la derecha y en negrita. En el teléfono se apilan. */
.repaso-cupon {
  display: grid;
  gap: 0;
  margin: 0 0 var(--e5);
}
.repaso-cupon dt {
  font-size: var(--t-md);
  color: var(--tinta-2);
  padding-top: 10px;
}
.repaso-cupon dd {
  margin: 0 0 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--linea);
  font-size: var(--t-base);
  font-weight: 600;
  overflow-wrap: anywhere;
}
@media (min-width: 560px) {
  .repaso-cupon { grid-template-columns: 190px 1fr; column-gap: var(--e4); }
  .repaso-cupon dt { border-bottom: 1px solid var(--linea); padding-bottom: 10px; }
}
.acciones-cupon { display: flex; flex-wrap: wrap; gap: var(--e3); }
.acciones-cupon .btn { flex: 1 1 auto; text-align: center; }

/* Un dato de la cuenta que se enseña pero no se escribe: el correo en el
   checkout. Se lee como el valor de un campo, no como texto suelto, pero sin
   el marco de una casilla que invita a escribir dentro. */
.dato-fijo {
  margin: 0;
  padding: 11px 0;
  font-size: var(--t-base);
  font-weight: 600;
  overflow-wrap: anywhere;
}

/* El SKU debajo del nombre del producto, en el panel. Se lee de un vistazo
   sin bajar hasta la tabla de inventario, y cuando falta lo dice con todas
   sus letras en vez de dejar un hueco. */
.sku-producto {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  margin: -6px 0 16px;
  font-size: var(--t-md);
  color: var(--tinta-2);
  line-height: 1.6;
}
.sku-producto .etiqueta { margin: 0; }
.sku-codigo {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-weight: 600;
  color: var(--tinta);
  overflow-wrap: anywhere;
}
.sku-nota { color: var(--tinta-3); }
.sku-producto-falta { color: var(--alerta-texto); }

/* «Cerrar sesión» en el pie. Desde que comprar exige cuenta, este botón está
   en todas las pantallas de la compra —checkout incluido—, así que necesita
   la misma zona de dedo que cualquier otro enlace del pie: un roce no puede
   sacar a la clienta de su cuenta mientras paga. */
.btn-texto-pie {
  color: rgba(255,255,255,.92);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 2px;
}
.btn-texto-pie:hover { color: #fff; }

/* Buscador de la pantalla de ajustes. Son seis pestañas y decenas de campos:
   sin esto había que saberse de memoria en cuál vive cada cosa, y el buscador
   del navegador no sirve porque las pestañas cerradas están ocultas. */
.buscar-ajuste { margin-bottom: var(--e4); max-width: 460px; }
.buscar-ajuste input { width: 100%; }
.buscar-ajuste .ayuda { margin: 6px 0 0; }

/* De qué pestaña es cada resultado. Sin este rótulo, la búsqueda deja una
   lista de tarjetas sueltas y no se sabe dónde vive lo que se encontró. */
.marca-pestana {
  margin: var(--e4) 0 6px;
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: var(--track-etiqueta);
  text-transform: uppercase;
  color: var(--morado);
}

/* La alarma del panel: «tu última acción no se guardó».
   Quien trabaja en el panel encadena acciones sin releer la pantalla, así que
   un error tiene que costar trabajo ignorarlo. El fondo oscurece pero NO
   bloquea el ratón a propósito: si el JavaScript fallara y el botón de cerrar
   no respondiera, nadie puede quedarse encerrado sin poder usar el panel. */
.alarma-panel {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--e4);
  background: rgba(20, 6, 31, .55);
  pointer-events: none;
}
.alarma-panel-caja {
  pointer-events: auto;
  max-width: 480px;
  width: 100%;
  background: var(--papel);
  border: 3px solid var(--error);
  border-radius: var(--r-md);
  box-shadow: 0 18px 50px rgba(20, 6, 31, .35);
  padding: var(--e5);
  text-align: center;
}
.alarma-panel-titulo {
  margin: 0 0 10px;
  font-size: var(--t-lg);
  font-weight: 800;
  color: var(--error);
  text-transform: uppercase;
  letter-spacing: .02em;
}
.alarma-panel-texto {
  margin: 0 0 12px;
  font-size: var(--t-base);
  font-weight: 600;
  overflow-wrap: anywhere;
}
.alarma-panel-pie {
  margin: 0 0 var(--e4);
  font-size: var(--t-md);
  color: var(--tinta-2);
  line-height: 1.55;
}

/* -------------------------------------------------- historial de ajustes
   La pantalla que dice qué se cambió, quién lo cambió y qué decía ANTES.
   De ahí sale el botón «Volver a este valor».

   Todo va en clases y nada en el atributo `style` de la plantilla (regla
   B6): el día que cambie un color de marca, esta pantalla cambia con él. */
.cabecera-pantalla { margin-bottom: var(--e2); }
.texto-guia {
  color: var(--tinta-2);
  font-size: var(--t-md);
  margin: 0 0 var(--e4);
  line-height: 1.55;
  max-width: 70ch;
}
.celda-fecha { white-space: nowrap; }
.celda-quien { min-width: 150px; overflow-wrap: anywhere; }
.celda-accion { min-width: 140px; }

/* El valor de un ajuste puede ser un párrafo entero o un color. Se enseña
   en letra de máquina para poder distinguir un espacio de más, que es
   justo el tipo de cambio que rompe algo sin que se vea. */
.valor-ajuste {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--t-sm);
  background: var(--papel-2);
  border: 1px solid var(--linea);
  border-radius: var(--r-sm, 6px);
  padding: 2px 6px;
  overflow-wrap: anywhere;
  display: inline-block;
  max-width: 34ch;
}
.valor-ajuste.vacio-ajuste { color: var(--tinta-2); font-style: italic; }
.valor-ajuste.valor-antes { color: var(--tinta-2); }
.flecha-cambio { color: var(--tinta-2); padding: 0 4px; }
.nota-fila {
  display: block;
  font-size: var(--t-xs);
  color: var(--tinta-2);
  margin-top: 4px;
  max-width: 30ch;
  line-height: 1.4;
}

/* -------------------------------------------------- cola de firmas
   «Esperando tu firma»: los movimientos que un operador pidió y que no
   mueven un centavo hasta que el administrador los firma. */
.firma-cuerpo { padding: 0 var(--e4) var(--e3); }
.firma-resumen {
  margin: 0 0 var(--e3);
  font-size: var(--t-md);
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.firma-botones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e3);
  align-items: flex-end;
  margin-top: var(--e3);
}
/* El motivo del rechazo y su botón, juntos y capaces de encoger: sin
   `min-width: 0` el campo de texto no baja de su ancho propio y en el
   teléfono empuja la tarjeta fuera de la pantalla. */
.firma-rechazo {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2);
  align-items: flex-end;
  flex: 1 1 260px;
  min-width: 0;
}
.firma-rechazo input[type="text"] { flex: 1 1 160px; min-width: 0; }
