/* La tienda es solo catálogo: el carrito vive en el modal del menú (carrito-modal.js). */
.tienda-layout { display: block; }
.tienda-col { min-width: 0; }

.tienda-toolbar {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
}
.tienda-toolbar button.activo {
  border-color: var(--color-gold);
  background: var(--tint-gold-2);
  color: var(--color-gold-bright);
}

.producto-card-agotado {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  padding: var(--space-1) var(--space-2);
  background: rgba(5, 5, 5, .85);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  border-radius: var(--radius-sm);
}

.tienda-cantidad {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
}
.tienda-cantidad input {
  /* flex: 0 0 56px, no width: 56px — como ítem de flex el input se encoge por default,
     y en una tarjeta angosta desaparecía dejando solo los botones − y +. */
  flex: 0 0 56px;
  width: 56px;
  text-align: center;
  padding: 0;
}
.tienda-cantidad button {
  width: var(--control-h);
  height: var(--control-h);
  padding: 0;
  flex: 0 0 auto;
}

.tienda-resultado {
  text-align: center;
  max-width: 480px;
  margin-inline: auto;
}
.tienda-resultado .sitio-icono { width: 40px; height: 40px; color: var(--color-gold); margin-bottom: var(--space-3); }
.tienda-resultado .actions,
.tienda-resultado a { justify-content: center; }

/* ---------- Variantes: los estilos del selector viven en components.css (lo comparten
   la tienda, la reserva y el POS) ---------- */

/* ---------- Tarjetas de la tienda ---------- */
/* El contenedor exterior lleva [data-reveal] (su transform es de la animación de entrada);
   la elevación al pasar el cursor va en el <article class="pc"> hijo para no pisarse. */
/* La tarjeta ocupa todo el alto de su celda: así todas las de una fila terminan
   a la misma altura aunque a una le quepa una línea más de texto. */
.producto-card--tienda {
  display: flex;
  height: 100%;
  cursor: default;
  overflow: visible;
  border: 0;
  border-radius: var(--radius-lg);
  background: none;
}
/* Ancho propio: sin esto la tarjeta se encoge al contenido y un producto SIN foto
   quedaba como un cuadrito de 157px en medio de la rejilla (la foto era lo único
   que le daba ancho). El botón se estira porque la regla global de botones fija
   align-self: flex-start. */
.producto-card--tienda .pc { flex: 1 1 auto; width: 100%; }
.pc {
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  background: var(--color-surface-raised);
  transition:
    transform var(--duration-base) var(--ease-out),
    border-color var(--duration-base) var(--ease-out),
    box-shadow var(--duration-base) var(--ease-out);
}
.producto-card--tienda .pc-abrir {
  display: block;
  align-self: stretch;
  width: 100%;
  min-height: 0;
  height: auto;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  color: inherit;
  font: inherit;
  letter-spacing: normal;
  text-align: left;
  text-transform: none;
  transform: none;
}
button.pc-abrir { cursor: pointer; }
button.pc-abrir:focus-visible { outline: 2px solid var(--color-gold); outline-offset: -2px; }
.pc-foto {
  position: relative;
  display: block;
  overflow: hidden;
  /* Marco cuadrado, igual para todas las tarjetas. */
  aspect-ratio: 1;
  background: var(--color-surface-sunken);
}
.producto-card--tienda .pc-foto img,
.producto-card--tienda .pc-foto .producto-card-sin-foto {
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  object-fit: cover;
  transition: transform 700ms var(--ease-out);
}
/* Productos sin foto cargada: en vez del recuadro vacío con "No photo", el icono
   del set propio sobre un degradado tenue. Se ve intencional, no roto. */
.pc-sin-foto {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background:
    radial-gradient(120% 90% at 50% 0%, var(--tint-gold-1), transparent 72%),
    var(--color-surface-sunken);
}
.pc-sin-foto .sitio-icono { width: 38px; height: 38px; color: var(--color-gold); opacity: .5; }
.pc-foto::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 45%;
  background: linear-gradient(to top, rgba(12, 12, 12, .85), transparent);
  pointer-events: none;
}
.pc-etiqueta {
  position: absolute;
  z-index: 2;
  top: var(--space-3);
  left: var(--space-3);
  padding: 3px var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-full);
  background: rgba(5, 5, 5, .7);
  backdrop-filter: blur(6px);
  color: var(--color-gold-bright);
  font-size: var(--text-2xs);
  letter-spacing: .1em;
  text-transform: uppercase;
}
/* La pastilla de agotado va DEBAJO de la de categoría, no al otro extremo: en
   tarjetas angostas las dos no caben en el mismo renglón y se encimaban
   (se leía "STUD SOLD OUT"). Apiladas funcionan a cualquier ancho. */
.pc-foto .producto-card-agotado {
  z-index: 2;
  top: calc(var(--space-3) + 26px);
  left: var(--space-3);
  right: auto;
}
/* Agotado: se apaga la foto y el texto baja de intensidad, así se entiende antes
   de leer la pastilla. La tarjeta sigue abriendo el modal para ver el detalle. */
.pc--agotado .pc-foto img { filter: grayscale(.7) brightness(.62); }
.pc--agotado .pc-nombre,
.pc--agotado .pc-precio { color: var(--color-text-muted); }
.pc-vista {
  position: absolute;
  z-index: 2;
  left: 50%;
  bottom: var(--space-3);
  padding: 6px var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--color-bg) 78%, transparent);
  backdrop-filter: blur(6px);
  color: var(--color-gold);
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  white-space: nowrap;
  opacity: 0;
  transform: translate(-50%, 10px);
  transition: opacity var(--duration-base) var(--ease-out), transform var(--duration-base) var(--ease-out);
}
/* Cuerpo de la tarjeta: nombre, precio y la línea de contexto. */
.pc-cuerpo {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1 1 auto;
  padding: var(--space-4);
}
/* El nombre reserva sus dos renglones aunque ocupe uno: así el precio queda a la
   misma altura en toda la fila y la rejilla se ve como retícula, no como escalera. */
.pc-nombre {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: calc(2 * 1.3em);
  color: var(--color-text);
  font-size: var(--text-base);
  font-weight: 600;
  line-height: 1.3;
}
/* La clase nace en pos.css, que la tienda no carga: se define aquí también.
   (En la tienda ya no se usa — el precio público es solo en dólares — pero el modal
   y las pantallas que sí la comparten necesitan la definición.) */
.moneda-usd {
  display: block;
  font-size: var(--text-2xs);
  font-weight: 400;
  color: var(--color-text-faint);
  white-space: nowrap;
}

/* Una sola línea: el precio de la web va en dólares y no lleva segunda moneda.
   (Era flex en columna para apilar pesos + dólares; con el "From" delante, ese flex
   partía la línea en dos y unas tarjetas quedaban 24px más altas que el resto.) */
.pc-precio {
  display: block;
  color: var(--color-gold-bright);
  font-weight: 600;
  white-space: nowrap;
}
/* Siempre presente, aunque vaya vacía: reserva su renglón para que el alto de la
   tarjeta no dependa de si el producto tiene opciones o no. */
.pc-opciones {
  margin-top: auto;
  /* 1.5em clavado: una línea vacía mide lo mismo que una con texto (medido: 12px vs
     17px con min-height: 1.1em), así el alto no depende del contenido. */
  min-height: 1.5em;
  line-height: 1.5;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--color-text-muted);
  font-size: var(--text-2xs);
  letter-spacing: .04em;
}

/* La columna del catálogo es más angosta que una pantalla completa (el carrito vive
   al lado), así que la rejilla admite tarjetas más chicas: con el mínimo de 240px
   solo cabían dos columnas y sobraba ancho. */
.tienda-col .productos-grid {
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 212px), 1fr));
}

/* Solo donde hay cursor: la elevación, el brillo dorado, el zoom de la foto y "Quick view".
   En pantallas táctiles no hay hover, así que "Quick view" queda siempre visible. */
@media (hover: hover) {
  .pc:hover,
  .pc:focus-within {
    transform: translateY(-6px);
    border-color: var(--color-gold);
    box-shadow: var(--shadow-md), var(--glow-gold-md);
  }
  .pc:hover .pc-foto img,
  .pc:focus-within .pc-foto img { transform: scale(1.07); }
  .pc:hover .pc-vista,
  .pc:focus-within .pc-vista { opacity: 1; transform: translate(-50%, 0); }
}
@media (hover: none) {
  .pc-vista { opacity: 1; transform: translate(-50%, 0); }
}

/* ---------- Modal de producto (quick view) ---------- */
body.vp-abierto { overflow: hidden; }
.vp {
  width: min(920px, calc(100vw - 2rem));
  max-height: min(86vh, 660px);
  max-height: min(86dvh, 660px);
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  background: #0c0c0c;
  color: var(--color-text);
  box-shadow: 0 30px 90px rgba(0, 0, 0, .8), var(--edge-top);
}
.vp::backdrop { background: rgba(0, 0, 0, .72); backdrop-filter: blur(6px); }
.vp-panel {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  max-height: min(86vh, 660px);
  max-height: min(86dvh, 660px);
}
.vp-cerrar {
  position: absolute;
  z-index: 3;
  top: var(--space-3);
  right: var(--space-3);
  width: 40px;
  height: 40px;
  min-height: 0;
  padding: 0;
  border-radius: 50%;
  font-size: var(--text-xl);
  line-height: 1;
}
.vp-galeria { position: relative; display: flex; flex-direction: column; min-width: 0; overflow-y: auto; background: var(--color-surface-sunken); }
.vp-tira {
  display: flex;
  /* Sin alto propio (antes: aspect-ratio 1 con tope de 62vh): se estira al alto de la
     columna del modal, así la foto la llena completa. Con el alto propio quedaba una
     franja del fondo debajo de la imagen cuando el producto trae variantes y la columna
     de la derecha es más alta que la foto. */
  flex: 1 1 auto;
  min-height: 0;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  /* Suavidad declarada aquí y no en cada scrollTo({behavior:'smooth'}): si el
     navegador no la soporta, degrada a salto instantáneo igual se mueve. Con la
     opción en JS, un navegador que no la anima dejaba el scroll en 0. */
  scroll-behavior: smooth;
}
.vp-tira::-webkit-scrollbar { display: none; }
/* El slide se estira al alto de la tira; si no, la foto queda más chica que el
   marco y aparece una franja negra debajo (height:100% no resuelve contra un
   contenedor sin alto propio). */
.vp-slide { background: var(--color-surface-sunken) center / cover no-repeat; flex: 0 0 100%; scroll-snap-align: center; display: flex; }
.vp-slide img { display: block; width: 100%; height: 100%; aspect-ratio: auto; object-fit: cover; }
/* Fotos muy alargadas (capturas, collages) se ven completas en vez de recortarse a una franja ampliada. */
.vp-slide img.vp-foto-larga { object-fit: contain; }
/* Sin foto: el icono del set propio centrado en el marco, igual que en la tarjeta. */
.vp-slide .producto-card-sin-foto {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  width: 100%;
  height: 100%;
}

/* Flechas para pasar de foto, solo cuando hay más de una. */
.vp-flecha {
  position: absolute;
  top: 50%;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  padding: 0;
  transform: translateY(-50%);
  border: 1px solid var(--color-border);
  border-radius: 50%;
  background: color-mix(in srgb, var(--color-bg) 82%, transparent);
  backdrop-filter: blur(6px);
  color: var(--color-gold);
  cursor: pointer;
  transition: background var(--duration-fast), border-color var(--duration-fast), color var(--duration-fast);
}
.vp-flecha[hidden] { display: none; }
.vp-flecha svg { width: 20px; height: 20px; }
.vp-flecha--prev { left: var(--space-3); }
.vp-flecha--next { right: var(--space-3); }
.vp-flecha:hover,
.vp-flecha:focus-visible,
.vp-flecha:active {
  background: var(--color-gold);
  border-color: var(--color-gold);
  color: var(--color-bg);
  /* La regla global de `button:hover` mete `transform: translateY(-2px)` y la de
     `:active` otro tanto. Como `button:hover` (0,1,1) gana a `.vp-flecha` (0,1,0), la
     flecha perdía el centrado y daba un brinco al pasar el cursor: hay que volver a
     fijar el translateY(-50%) en los tres estados. */
  transform: translateY(-50%);
}
/* Marco de la foto: contiene la tira y ancla las flechas y el contador a la IMAGEN.
   Se estira con la columna para que la tira (y la foto) llenen todo el alto. */
.vp-marco { position: relative; display: flex; flex: 1 1 auto; min-height: 0; }
/* Cuántas fotos hay y en cuál vas. Sustituye a la tira de miniaturas, que dejaba una
   franja fea debajo de la foto: ahora la navegación son las flechas (y el deslizar). */
.vp-contador {
  position: absolute;
  z-index: 2;
  right: var(--space-3);
  bottom: var(--space-3);
  padding: 3px var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--color-bg) 78%, transparent);
  backdrop-filter: blur(6px);
  color: var(--color-gold);
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: .08em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.vp-contador[hidden] { display: none; }
.vp-info {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
  padding: var(--space-6) var(--space-6) 0;
  overflow-y: auto;
}
/* Sin esto los bloques con scroll propio (las opciones) se encogen en vez de dejar que la
   información haga scroll. */
.vp-info > * { flex-shrink: 0; }
.vp-titulo { margin: 0; font-size: var(--text-2xl); }
.vp-precio { margin: 0; color: var(--color-gold-bright); font-size: var(--text-xl); font-weight: 700; }
/* Con muchas variantes los botones se acomodan en filas y esta zona hace scroll: el modal
   nunca crece más que la pantalla. */
.vp-opciones { max-height: 34vh; overflow-y: auto; padding-right: var(--space-1); }
.vp-pista { margin: 0; }
/* Texto libre que escribe el negocio: pre-line respeta sus saltos de línea. */
.vp-descripcion { margin: 0; color: var(--color-text-muted); font-size: var(--text-sm); white-space: pre-line; }
.vp-agotado { margin: 0; color: var(--color-text-muted); letter-spacing: .1em; text-transform: uppercase; }
/* La barra de compra se queda fija abajo mientras la información hace scroll por detrás. */
.vp-comprar {
  position: sticky;
  bottom: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-top: auto;
  padding: var(--space-3) 0 var(--space-6);
  background: #0c0c0c;
  /* Sombra hacia arriba: la barra queda pegada al fondo mientras las opciones pasan
     por debajo, y sin esto parecía el final del contenido. */
  box-shadow: 0 -16px 20px -14px rgba(0, 0, 0, .95);
}
.vp-cantidad { margin-top: 0; }
.vp-agregar { flex: 1 1 10rem; min-height: var(--control-h-lg); }

@media (prefers-reduced-motion: no-preference) {
  .vp[open] { animation: vp-entra var(--duration-slow) var(--ease-out); }
  .vp[open]::backdrop { animation: vp-fondo var(--duration-base) ease-out; }
}
@keyframes vp-entra { from { opacity: 0; transform: translateY(24px) scale(.97); } }
@keyframes vp-fondo { from { opacity: 0; } }

/* Escritorio: el panel tiene alto fijo. Sin esto medía lo que mide la columna de texto hasta que llegaba la
   foto y entonces se estiraba; ahora abre ya de su tamaño final y la foto se asienta dentro. */
@media (min-width: 721px) {
  .vp-panel { height: min(86dvh, 660px); }
}

/* Celular: tarjeta FLOTANTE, no pantalla completa. Se deja aire alrededor para que la
 * página siga viéndose detrás: se siente parte del sitio y no una pantalla aparte.
 * Dentro, todo el contenido se desplaza junto (foto, opciones y descripción) con la
 * botonera de compra pegada abajo. */
@media (max-width: 720px) {
  .vp {
    /* Ancho automático + tope: así el margen automático la centra de verdad. Con
       `width: 100vw` el aire salía desigual (el vw incluye la barra de scroll y el
       margen se calcula sobre el ancho útil). */
    width: auto;
    max-width: min(460px, calc(100% - var(--space-5) * 2));
    max-height: 82vh;
    max-height: 82dvh;
    /* Centrada: el `dialog` ya trae `inset: 0`, así que el margen automático la centra
       en las dos direcciones. Nada de animación de "sube desde abajo": ya no es una
       hoja pegada al borde, entra como en escritorio. */
    margin: auto;
  }
  /* El panel es el que scrollea (nada de posición estática aquí: el `dialog` se centra
     con el `position: fixed` que le pone el navegador, y tocarlo lo saca de la capa
     modal). La X se queda pegada arriba con sticky y el margen negativo la saca del
     flujo, para que la foto arranque arriba y la X flote encima. */
  .vp-panel {
    display: flex;
    flex-direction: column;
    max-height: 82vh;
    max-height: 82dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .vp-cerrar {
    position: sticky;
    top: var(--space-3);
    align-self: flex-end;
    margin: 0 var(--space-3) -40px 0;
  }
  .vp-galeria { flex: 0 0 auto; overflow: visible; }
  /* Marco CUADRADO, igual que la tarjeta del catálogo. Estaba en 4/3 con tope de 34vh:
     en un teléfono vertical eso da una franja apaisada de ~390×287 y las fotos del
     estudio son verticales (1778×2371) — `cover` recortaba una tira del centro. */
  .vp-tira { aspect-ratio: 1; max-height: none; }
  .vp-info { flex: 0 0 auto; min-height: 0; overflow: visible; padding: var(--space-4) var(--space-4) 0; }
  .vp-comprar { padding-bottom: calc(var(--space-4) + env(safe-area-inset-bottom)); }
  .vp-titulo { font-size: var(--text-xl); }
  .vp-opciones { max-height: none; overflow: visible; }
}
/* Celular acostado o pantalla muy baja: la foto se limita y se muestra completa
   (contain) en vez de recortarse a una franja. */
@media (max-width: 720px) and (max-height: 620px) {
  .vp-tira { max-height: 44vh; max-height: 44dvh; }
  .vp-slide img { object-fit: contain; }
}
/* Acostado y ancho (un teléfono en horizontal mide ~844×390 y ya no entra en el
   layout de celular): el modal se queda en dos columnas, pero la foto necesita más
   alto del que da el tope de escritorio y mostrarse completa, no recortada. */
@media (orientation: landscape) and (max-height: 620px) {
  .vp,
  .vp-panel { max-height: 92vh; max-height: 92dvh; }
  .vp-panel { height: 92dvh; }
  .vp-tira { max-height: 72vh; max-height: 72dvh; }
  .vp-slide img { object-fit: contain; }
}

/* ============================================================
   Líneas de tienda — portadas. Mismas bandas a sangre que Impacto Social: foto de ancho
   completo con parallax y degradado a negro, título grande con número dorado y texto
   centrado. Cada banda es un enlace entero hacia el catálogo de su línea.
   ============================================================ */
.tienda-col [hidden] { display: none !important; }

/* Cada portada respira: franjas de fondo negro entre una y otra, un filete dorado corto que
   las separa y un degradado más cerrado para que el texto se lea sobre la foto. */
.portadas-lineas {
  display: grid;
  gap: clamp(72px, 14vh, 140px);
  padding-block: clamp(72px, 12vh, 120px);
  background: var(--color-bg);
}
.portadas-lineas[hidden] { display: none; }
.portada-linea {
  min-height: clamp(280px, 42vh, 380px);
  color: inherit;
  text-decoration: none;
  background: var(--color-bg);
}
.portada-linea::after {
  background: linear-gradient(180deg, var(--color-bg) 0%, rgba(5, 5, 5, .72) 28%, rgba(5, 5, 5, .72) 72%, var(--color-bg) 100%);
}
.portada-linea + .portada-linea::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  width: 72px;
  height: 1px;
  background: var(--color-gold);
  transform: translateX(-50%);
}
.portada-linea-contenido {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
}
.portada-linea-numero {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  line-height: 1;
  color: var(--color-gold-bright);
}
.portada-linea-nombre {
  font-family: var(--font-display);
  font-size: clamp(2rem, 1.4rem + 2.4vw, 3.25rem);
  line-height: 1.08;
  letter-spacing: -.015em;
  text-wrap: balance;
}
.portada-linea-desc { color: var(--color-text-muted); max-width: 46ch; }
.portada-linea-meta {
  font-size: var(--text-xs);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--color-text-faint);
}
.portada-linea-ir {
  margin-top: var(--space-3);
  padding: var(--space-2) var(--space-5);
  border: 1px solid var(--color-gold);
  border-radius: var(--radius-full);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-gold-bright);
  transition: background var(--duration-fast) var(--ease-out);
}
.portada-linea-ir span { display: inline-block; transition: transform var(--duration-fast) var(--ease-out); }
.portada-linea:hover .portada-linea-ir { background: var(--tint-gold-2); }
.portada-linea:hover .portada-linea-ir span { transform: translateX(4px); }
.portada-linea:focus-visible { outline: 2px solid var(--color-gold); outline-offset: -4px; }
.lineas-todo { margin: 0; padding: var(--space-6) var(--space-5) 0; text-align: center; }

.tienda-linea-cab {
  display: grid;
  gap: var(--space-2);
  justify-items: start;
  margin-bottom: var(--space-4);
}
.tienda-linea-titulo { font-family: var(--font-display); font-size: var(--text-xl); }
.tienda-linea-desc { margin: 0; color: var(--color-text-muted); max-width: 52ch; }

@media (prefers-reduced-motion: reduce) {
  .portada-linea-ir span { transition: none; }
}

/* El punto de interés que marca el equipo en cada portada (foto_foco) manda sobre el centro. */
.portada-linea .sitio-banda-foto { background-position: var(--foco, 50% 50%); }
