/* ============================================================================
   LB JEANS — COMPONENTES · «Taller Índigo»
   Fase 2 de 4. 2026-08-11
   ----------------------------------------------------------------------------
   Se carga DESPUÉS de lb-tokens.css. Todo sale de tokens: ni un hex ni un px
   suelto salvo los tres hairlines de 1px que no tienen token porque no deben
   escalar nunca.

   ESTRATEGIA: se rediseñan las clases QUE YA EXISTEN en el markup, no se
   inventan nuevas. Así el rediseño entra sin tocar una línea de PHP, y si algo
   sale mal se retira este fichero y la tienda vuelve exactamente a como estaba.
   Los componentes nuevos (esqueletos, estados vacíos, ficha de taller) son
   aditivos y se usan en la fase 3.
   ========================================================================== */

/* ============================================================================
   1. BOTONES
   Había 9 variantes sin sistema. Aquí hay una base y cuatro intenciones:
   primaria (cobra), contorno (secundaria), fantasma (terciaria) y WhatsApp
   (canal externo, conserva su verde de marca porque es reconocimiento, no
   decoración).
   ========================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--lb-e-2);
  min-height: var(--lb-toque);
  padding: var(--lb-e-3) var(--lb-e-5);
  border: 1px solid transparent;
  border-radius: var(--lb-r-md);
  font-family: var(--lb-fuente-texto);
  font-size: var(--lb-t-sm);
  font-weight: var(--lb-peso-fuerte);
  letter-spacing: 0.04em;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  /* Solo transform y opacity: son las dos que van en la GPU. */
  transition: transform var(--lb-dur-1) var(--lb-curva-entrada),
              opacity   var(--lb-dur-1) var(--lb-curva-entrada);
}
.btn:hover  { transform: translateY(-1px); }
.btn:active { transform: translateY(0) scale(0.985); }
.btn[disabled],
.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
}

/* La primaria es la que cobra. Es la única pieza de hilo macizo del sistema. */
.btn--primary {
  background: var(--lb-hilo);
  color: var(--lb-tinta);            /* 8.03:1 — medido */
  border-color: var(--lb-hilo);
}
.btn--outline,
.btn--secondary {
  background: transparent;
  color: var(--lb-texto);
  border-color: var(--lb-linea-fuerte);
}
.btn--ghost {
  background: transparent;
  color: var(--lb-texto-suave);
  border-color: transparent;
}
.btn--whatsapp {
  background: var(--whatsapp);
  color: #FFFFFF;                    /* el verde de marca pide blanco */
  border-color: var(--whatsapp);
}
.btn--sm  { min-height: var(--lb-toque); padding: var(--lb-e-2) var(--lb-e-4); font-size: var(--lb-t-xs); }
.btn--lg  { padding: var(--lb-e-4) var(--lb-e-6); font-size: var(--lb-t-md); }
.btn--full{ width: 100%; }

/* Sobre superficie oscura la primaria conserva el hilo, pero el contorno y el
   fantasma tienen que invertirse o desaparecen. */
.lb-inverso .btn--outline,
footer .btn--outline {
  color: var(--lb-texto-inverso);
  border-color: var(--lb-linea-inversa);
}

/* ============================================================================
   2. LA COSTURA APLICADA — el elemento firma
   Subraya los rótulos de sección. Es lo que hace que la tienda se reconozca
   sin leer el logo.
   ========================================================================== */
.lb-eyebrow,
.section__label {
  display: inline-block;
  font-family: var(--lb-fuente-texto);
  font-size: var(--lb-t-xs);
  font-weight: var(--lb-peso-medio);
  letter-spacing: var(--lb-track-rotulo);
  text-transform: uppercase;
  color: var(--lb-acento);
  padding-bottom: var(--lb-e-2);
  position: relative;
}
.lb-eyebrow::after,
.section__label::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--lb-costura-grosor);
  background-image: var(--lb-costura);
}

/* El filete que separaba secciones pasa a ser pespunte. */
.lb-rule {
  height: var(--lb-costura-grosor);
  border: 0;
  background-image: var(--lb-costura);
  opacity: 0.55;
  margin: var(--lb-e-5) 0;
}

/* ============================================================================
   3. TARJETA DE PRODUCTO — UNA, aunque el markup traiga dos
   La portada usa `.lb-card` y la tienda `.product-card`. Se les da la misma
   forma, la misma escala y el mismo precio. El markup se unifica en la fase 3;
   esto ya hace que se vean iguales hoy.
   ========================================================================== */
.lb-card,
.product-card {
  display: flex;
  flex-direction: column;
  background: var(--lb-fondo-elevado);
  border: 1px solid var(--lb-linea);
  border-radius: var(--lb-r-lg);
  overflow: hidden;
  transition: transform var(--lb-dur-2) var(--lb-curva-entrada);
}
.lb-card:hover,
.product-card:hover { transform: translateY(-3px); }

.lb-card__media,
.product-card__image-wrap { border-radius: 0; }

/* El zoom de la foto era de 1,1 s. Baja al tramo medio del sistema. */
.lb-card__media img,
.product-card__image-wrap img {
  transition: transform var(--lb-dur-3) var(--lb-curva-entrada);
}
.lb-card:hover .lb-card__media img,
.product-card:hover .product-card__image-wrap img { transform: scale(1.04); }

.lb-card__body,
.product-card__info {
  display: flex;
  flex-direction: column;
  gap: var(--lb-e-1);
  padding: var(--lb-e-4);
  text-align: left;                 /* estaba centrado: se lee peor en rejilla */
}

.lb-card__cat,
.product-card__category {
  font-size: var(--lb-t-xs);
  font-weight: var(--lb-peso-medio);
  letter-spacing: var(--lb-track-rotulo);
  text-transform: uppercase;
  color: var(--lb-texto-suave);
}

.lb-card__name,
.product-card__name {
  font-family: var(--lb-fuente-titulo);
  font-size: var(--lb-t-md);
  font-weight: var(--lb-peso-fuerte);
  line-height: var(--lb-alto-titulo);
  letter-spacing: var(--lb-track-titulo);
  color: var(--lb-texto);
  margin: 0;
}
.lb-card__name a,
.product-card__name a { color: inherit; text-decoration: none; }

/* EL PRECIO. Antes tenía nueve clases distintas y una se llamaba `-cyan`.
   Aquí es una sola cosa, con cifras de ancho fijo para que la rejilla no baile. */
.lb-card__price,
.product-card__price,
.product-card__prices {
  font-family: var(--lb-fuente-texto);
  font-size: var(--lb-t-md);
  font-weight: var(--lb-peso-fuerte);
  color: var(--lb-texto);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  margin-top: var(--lb-e-1);
}
.lb-card__price .old,
.product-card__price-original {
  color: var(--lb-texto-suave);
  font-weight: var(--lb-peso-normal);
  font-size: var(--lb-t-sm);
  text-decoration: line-through;
  margin-right: var(--lb-e-2);
}

.product-card__actions { padding: 0 var(--lb-e-4) var(--lb-e-4); display: flex; gap: var(--lb-e-2); }

/* ============================================================================
   4. ETIQUETAS
   `.badge` tenía 22 variantes. Tres bastan: nueva, oferta y últimas unidades.
   Ninguna comunica por color solamente.
   ========================================================================== */
.badge,
.lb-card__flag {
  display: inline-flex;
  align-items: center;
  gap: var(--lb-e-1);
  padding: var(--lb-e-1) var(--lb-e-2);
  border-radius: var(--lb-r-sm);
  font-family: var(--lb-fuente-texto);
  font-size: var(--lb-t-xs);
  font-weight: var(--lb-peso-fuerte);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1.3;
  background: var(--lb-fondo-inverso);
  color: var(--lb-texto-inverso);
}
.badge--new  { background: var(--lb-fondo-inverso); color: var(--lb-acento-inverso); }
.badge--sale { background: var(--lb-error); color: #FFFFFF; }

/* «Últimas 3»: urgencia real, no inventada. El dato viene del stock. */
.lb-ultimas {
  display: inline-flex;
  align-items: center;
  gap: var(--lb-e-1);
  padding: var(--lb-e-1) var(--lb-e-2);
  border-radius: var(--lb-r-sm);
  background: var(--lb-alerta-bg);
  color: var(--lb-alerta);
  font-size: var(--lb-t-xs);
  font-weight: var(--lb-peso-fuerte);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* ============================================================================
   5. SELECTOR DE TALLA — el control que decide la compra
   Era lo que menos diseño tenía de toda la tienda y es la objeción número uno
   al comprar jeans en línea. La talla elegida se marca CON LA COSTURA, no solo
   con un color: el estado no puede depender del color.
   ========================================================================== */
.talla-opcion {
  position: relative;
  min-width: var(--lb-toque);
  min-height: var(--lb-toque);
  padding: var(--lb-e-2) var(--lb-e-4);
  border: 1px solid var(--lb-linea-fuerte);
  border-radius: var(--lb-r-md);
  background: var(--lb-fondo-elevado);
  color: var(--lb-texto);
  font-family: var(--lb-fuente-texto);
  font-size: var(--lb-t-base);
  font-weight: var(--lb-peso-fuerte);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: transform var(--lb-dur-1) var(--lb-curva-entrada);
}
.talla-opcion:hover { transform: translateY(-1px); }

.talla-opcion[aria-checked="true"],
.talla-opcion.is-active,
.talla-opcion.activa {
  background: var(--lb-fondo-inverso);
  color: var(--lb-texto-inverso);
  border-color: var(--lb-fondo-inverso);
}
/* La costura que cose la talla elegida. Es el gesto de marca del sistema. */
.talla-opcion[aria-checked="true"]::after,
.talla-opcion.is-active::after,
.talla-opcion.activa::after {
  content: "";
  position: absolute;
  left: var(--lb-e-2);
  right: var(--lb-e-2);
  bottom: 5px;
  height: var(--lb-costura-grosor);
  background-image: var(--lb-costura);
}
.talla-opcion[disabled],
.talla-opcion.agotada {
  opacity: 0.4;
  cursor: not-allowed;
  text-decoration: line-through;
}

/* El bloque completo de tallas. Antes iba maquetado con seis atributos `style`. */
.lb-tallas { margin-bottom: var(--lb-e-5); }
.lb-tallas__cabecera {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--lb-e-3);
  margin-bottom: var(--lb-e-3);
}
.lb-tallas__label { margin-bottom: 0; font-weight: var(--lb-peso-fuerte); }
.lb-tallas__obligatorio { color: var(--lb-error); }
.lb-tallas__opciones { display: flex; flex-wrap: wrap; gap: var(--lb-e-2); }
/* Oculto de salida; `carrito.js` lo muestra poniendo `display:block` en línea.
   Va con el padre delante a propósito: `.lb-campo-error` (que le da la forma de
   mensaje de error) declara `display:flex` MÁS ABAJO en este mismo fichero, y
   con la misma especificidad ganaba por orden. El resultado era que la ficha de
   producto abría con «Elige tu talla para continuar» en rojo antes de que nadie
   hubiera hecho nada. */
.lb-tallas .lb-tallas__aviso { display: none; }

/* Enlace de texto discreto («¿Cuál es mi talla?»). Subrayado siempre: un enlace
   que solo se distingue por el color no se distingue. */
.lb-enlace-sutil {
  background: none;
  border: 0;
  padding: 0;
  min-height: var(--lb-toque);
  font-family: var(--lb-fuente-texto);
  font-size: var(--lb-t-sm);
  color: var(--lb-acento);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

/* ============================================================================
   6. CAMPOS DE FORMULARIO
   Aquí estaban los cuatro `outline:none` que dejaban el checkout sin foco
   visible. El anillo lo pone lb-tokens.css; esto solo da forma y estados, y
   NO vuelve a tocar `outline`.
   ========================================================================== */
.form-input,
.form-select,
.form-textarea {
  width: 100%;
  min-height: var(--lb-toque);
  padding: var(--lb-e-3) var(--lb-e-4);
  border: 1px solid var(--lb-linea-fuerte);
  border-radius: var(--lb-r-md);
  background: var(--lb-fondo-elevado);
  color: var(--lb-texto);
  font-family: var(--lb-fuente-texto);
  font-size: var(--lb-t-base);
  transition: border-color var(--lb-dur-1) var(--lb-curva-entrada);
}
.form-input::placeholder,
.form-textarea::placeholder { color: var(--lb-texto-suave); }

.form-label {
  display: block;
  margin-bottom: var(--lb-e-2);
  font-size: var(--lb-t-sm);
  font-weight: var(--lb-peso-medio);
  color: var(--lb-texto);
}

/* Error en un campo: borde + icono + texto. Nunca solo color. */
.form-input[aria-invalid="true"],
.form-select[aria-invalid="true"],
.form-textarea[aria-invalid="true"] { border-color: var(--lb-error); border-width: 2px; }

.lb-campo-error {
  display: flex;
  align-items: center;
  gap: var(--lb-e-2);
  margin-top: var(--lb-e-2);
  font-size: var(--lb-t-sm);
  color: var(--lb-error);
}
.lb-campo-error::before { content: "\26A0"; font-size: var(--lb-t-base); }

/* ============================================================================
   7. ESQUELETOS DE CARGA
   No existía ni uno en todo el proyecto: las tarjetas aparecían de golpe.
   Reserva el mismo alto que la tarjeta real, así que no produce salto.
   Anima con `opacity`, no con `background-position`.
   ========================================================================== */
.lb-esqueleto {
  border: 1px solid var(--lb-linea);
  border-radius: var(--lb-r-lg);
  overflow: hidden;
  background: var(--lb-fondo-elevado);
}
.lb-esqueleto__media { aspect-ratio: 1 / 1; background: var(--lb-fondo-hundido); }
.lb-esqueleto__body  { padding: var(--lb-e-4); display: flex; flex-direction: column; gap: var(--lb-e-2); }
.lb-esqueleto__linea { height: var(--lb-e-3); border-radius: var(--lb-r-sm); background: var(--lb-fondo-hundido); }
.lb-esqueleto__linea--corta { width: 40%; }
.lb-esqueleto__linea--media { width: 75%; }
.lb-esqueleto__media,
.lb-esqueleto__linea { animation: lb-latir 1.4s var(--lb-curva-entrada) infinite; }

@keyframes lb-latir {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}

/* ============================================================================
   8. ESTADOS VACÍO Y ERROR
   7 de 13 pantallas no tenían ninguno.
   ========================================================================== */
.lb-estado {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--lb-e-3);
  max-width: var(--lb-ancho-texto);
  margin: var(--lb-e-8) auto;
  padding: var(--lb-e-6) var(--lb-e-4);
  text-align: center;
  border: 1px solid var(--lb-linea);
  border-radius: var(--lb-r-lg);
  background: var(--lb-fondo-elevado);
}
.lb-estado__icono { font-size: var(--lb-t-xl); color: var(--lb-texto-suave); line-height: 1; }
.lb-estado__titulo {
  font-family: var(--lb-fuente-titulo);
  font-size: var(--lb-t-lg);
  font-weight: var(--lb-peso-fuerte);
  letter-spacing: var(--lb-track-titulo);
  color: var(--lb-texto);
  margin: 0;
}
.lb-estado__texto { color: var(--lb-texto-suave); margin: 0; }
.lb-estado--error { border-color: var(--lb-error); }
.lb-estado--error .lb-estado__icono { color: var(--lb-error); }

/* ============================================================================
   9. FICHA DE TALLER — la pieza que hace memorable el producto
   Los datos de la prenda presentados como la etiqueta de papel que lleva
   grapada un jean en el taller. Es donde vive «Hecho en Colombia», que es EL
   activo del cliente y estaba enterrado en una tira de beneficios genérica.
   ========================================================================== */
.lb-ficha {
  border: 1px solid var(--lb-linea-fuerte);
  border-radius: var(--lb-r-md);
  background: var(--lb-fondo-elevado);
  padding: var(--lb-e-4);
}
.lb-ficha__titulo {
  display: block;
  margin-bottom: var(--lb-e-3);
  padding-bottom: var(--lb-e-2);
  font-size: var(--lb-t-xs);
  font-weight: var(--lb-peso-medio);
  letter-spacing: var(--lb-track-rotulo);
  text-transform: uppercase;
  color: var(--lb-acento);
  border-bottom: var(--lb-costura-grosor) solid transparent;
  background-image: var(--lb-costura);
  background-repeat: no-repeat;
  background-position: bottom left;
  background-size: 100% var(--lb-costura-grosor);
}
.lb-ficha__fila {
  display: flex;
  justify-content: space-between;
  gap: var(--lb-e-4);
  padding: var(--lb-e-2) 0;
  font-size: var(--lb-t-sm);
  border-bottom: 1px solid var(--lb-linea);
}
.lb-ficha__fila:last-child { border-bottom: 0; }
.lb-ficha__etiqueta { color: var(--lb-texto-suave); }
.lb-ficha__dato { color: var(--lb-texto); font-weight: var(--lb-peso-medio); text-align: right; }

/* ============================================================================
   10. PROGRESO A ENVÍO GRATIS
   El dato YA lo devuelve la API (`falta_envio_gratis`) y no se enseñaba en
   ninguna parte. Es la palanca de ticket medio más barata que hay.
   ========================================================================== */
.lb-envio-progreso {
  display: flex;
  flex-direction: column;
  gap: var(--lb-e-2);
  padding: var(--lb-e-3) var(--lb-e-4);
  border: 1px solid var(--lb-linea);
  border-radius: var(--lb-r-md);
  background: var(--lb-fondo-hundido);
  font-size: var(--lb-t-sm);
  color: var(--lb-texto);
}
.lb-envio-progreso__texto { line-height: var(--lb-alto-texto); }
.lb-envio-progreso__barra {
  height: var(--lb-e-2);
  border-radius: var(--lb-r-full);
  background: var(--lb-linea);
  overflow: hidden;
}
.lb-envio-progreso__relleno {
  height: 100%;
  border-radius: var(--lb-r-full);
  background: var(--lb-hilo);
  transform-origin: left center;
  transition: transform var(--lb-dur-3) var(--lb-curva-entrada);
}
.lb-envio-progreso--logrado { background: var(--lb-ok-bg); }
.lb-envio-progreso--logrado .lb-envio-progreso__relleno { background: var(--lb-ok); }

/* ============================================================================
   11. BARRA DE COMPRA FIJA EN MÓVIL
   La palanca de conversión más conocida del comercio móvil: el precio y el
   botón siempre a la vista. Se cierra por arriba con la costura.
   Solo en móvil, y solo si el markup la incluye (fase 3).
   ========================================================================== */
.lb-barra-compra {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: var(--lb-z-pegado);
  display: none;
  align-items: center;
  gap: var(--lb-e-4);
  padding: var(--lb-e-3) var(--lb-e-4);
  padding-bottom: max(var(--lb-e-3), env(safe-area-inset-bottom));
  background: var(--lb-fondo-elevado);
  border-top: var(--lb-costura-grosor) solid transparent;
  background-image: var(--lb-costura), none;
  background-repeat: no-repeat;
  background-position: top left;
  background-size: 100% var(--lb-costura-grosor);
  box-shadow: var(--lb-sombra-3);
}
.lb-barra-compra__precio {
  font-size: var(--lb-t-md);
  font-weight: var(--lb-peso-fuerte);
  font-variant-numeric: tabular-nums;
  color: var(--lb-texto);
  white-space: nowrap;
}
.lb-barra-compra .btn { flex: 1; }

@media (max-width: 767px) {
  .lb-barra-compra { display: flex; }
  /* Sitio para que la barra no tape el final del pie. Se resuelve con `:has()`
     para no tener que añadir una clase al `<body>` desde PHP: si el navegador
     no lo soporta, lo único que pasa es que la barra se superpone unos píxeles
     al final del pie. Degrada, no rompe. */
  body:has(.lb-barra-compra) { padding-bottom: calc(var(--lb-toque) + var(--lb-e-6)); }
  /* El botón flotante de WhatsApp sube para no quedar debajo de la barra. */
  body:has(.lb-barra-compra) .whatsapp-float { bottom: calc(var(--lb-toque) + var(--lb-e-6)); }
}

/* ============================================================================
   12. ARREGLOS DE HERENCIA
   Componentes viejos que daban por hecho que la página es clara. Son los dos
   que quedaban fallando AA al girar el tema en la fase 1.
   ========================================================================== */
.whatsapp-float__tooltip {
  background: var(--lb-fondo-inverso);
  color: var(--lb-texto-inverso);
}

/* `.lb-card__quick` («Ver pieza») aparecía al pasar el ratón sobre una tarjeta
   que YA es un enlace entero, y en táctil no existe. Es un control que no
   añade nada: se retira de la vista sin tocar el markup. */
.lb-card__quick { display: none; }
