/* chacharaShop -- identidad visual del catalogo publico. Mobile-first (390px base). */

:root {
    --bg: #0f1115;
    --bg-card: #1a1d24;
    --accent: #e63946;
    --accent-2: #f4a261;
    --text: #f0f0f0;
    --text-secondary: #9aa0b0;
    --ok: #2ecc71;
    --warn: #f9c74f;
    --border: #2a2e37;
    --radius: 10px;
    --font: 'Inter', system-ui, -apple-system, "Segoe UI", sans-serif;
    --header-h: 60px;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font);
    -webkit-text-size-adjust: 100%;
}

body { padding-top: var(--header-h); }

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

a { color: inherit; text-decoration: none; }

h1, h2, h3 { margin: 0 0 0.5rem; line-height: 1.2; }

p { margin: 0 0 0.75rem; color: var(--text-secondary); }

.container {
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 1rem;
}

/* ---------- Buttons ---------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    border: none;
    border-radius: var(--radius);
    padding: 0.85rem 1.25rem;
    font-family: var(--font);
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    text-align: center;
}

.btn--primary { background: var(--accent); color: #fff; transition: background 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease; }
.btn--primary:hover { background: #d12836; }

/* CTA de preorder ("Lo aparto") -- mismo boton, naranja en vez de rojo. */
.btn--preorder { background: var(--accent-2); color: #1a1208; }
.btn--preorder:hover { background: #e0915a; }

.btn--secondary { background: transparent; color: var(--text); border: 1px solid var(--border); }
.btn--secondary:hover { border-color: var(--text-secondary); }

/* "Ver" (card de vitrina en el feed, Tarea 4) -- mismo naranja que preorder/afiliado, para que no se vea apagado junto a los CTA de producto. */
.btn--vitrina { background: var(--accent-2); color: #1a1208; }
.btn--vitrina:hover { background: #e0915a; }

/* "Lo consigo aqui" (afiliado ML) -- naranja para distinguirlo del contacto directo por WhatsApp. */
.btn--affiliate { background: var(--accent-2); color: #1a1208; }
.btn--affiliate:hover { background: #e0915a; }

/* "Ver en MercadoLibre" (ml_url) -- amarillo de marca ML, distinto del naranja de afiliado. */
.btn--ml { background: #ffe600; color: #1a1208; }
.btn--ml:hover { background: #e6cf00; }

.btn--block { width: 100%; }
.btn--sm { padding: 0.5rem 0.85rem; font-size: 0.85rem; }

/* ---------- Header (sticky, item 4) ---------- */

.site-header {
    position: fixed;
    top: 0; left: 0; right: 0;
    height: var(--header-h);
    background: rgba(15, 17, 21, 0.95);
    backdrop-filter: blur(6px);
    border-bottom: 1px solid var(--border);
    z-index: 100;
}

.site-header__inner {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    height: 100%;
}

.site-header__logo { display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0; }
/* Circulo + cover, object-position "top" en vez del center-center default --
   el logo es un dibujo vertical, centrado y con el default se cortaba parejo
   arriba y abajo (casco Y pies). Con "top" el recorte cae solo abajo (pies),
   el personaje completo (casco/cara) queda dentro del circulo. */
.site-header__logo img { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; object-position: center top; }
.site-header__logo span { font-weight: 700; font-size: 1rem; white-space: nowrap; }

/* Nav de texto del header -- solo desktop, en mobile se usa el hamburguesa (.mobile-menu). */
.site-header__nav { display: none; }
/* Tarea 3: Catalogo/Vitrina como pill en vez de texto plano -- mas
   contraste/tamano para que se noten y se usen (estaban poco visibles). */
.site-header__nav a {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 0.4rem 0.9rem;
    font-size: 0.95rem;
    font-weight: 700;
    white-space: nowrap;
}
.site-header__nav a:hover { border-color: var(--accent); color: var(--accent); }

.site-header__search { flex: 1; display: none; }
.site-header__search input {
    width: 100%;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text);
    padding: 0.55rem 0.9rem;
    font-family: var(--font);
    font-size: 0.9rem;
}

.icon-btn {
    background: none;
    border: none;
    color: var(--text);
    cursor: pointer;
    padding: 0.4rem;
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
}

.cart-badge {
    position: absolute;
    top: -2px; right: -2px;
    background: var(--accent);
    color: #fff;
    font-size: 0.65rem;
    font-weight: 700;
    border-radius: 50%;
    min-width: 16px;
    height: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 3px;
}

.header-actions { display: flex; align-items: center; gap: 0.25rem; margin-left: auto; }
/* Carrito: oculto en mobile -- el flotante (bottom-right, alcance de pulgar)
   ya cubre esto, este icono aqui solo era ruido junto al buscador. En
   desktop si se muestra junto al flotante (duplicado a proposito, ver media
   query 768px) -- el usuario pidio mantener ambos porque el icono del
   header es poco visible ahi. */
.header-cart { display: none; }

/* ---------- Feedback "agregado al carrito" (directo en el boton) ---------- */
/* Fases (desde el click): 1) 0-150ms scale(0.95); 2) 150-400ms fondo
   confirmado + pop; 3) 400-1200ms mantiene fondo confirmado (clases via JS,
   ver shop.js); 4) 1200-1500ms este transition hace el fade de vuelta. */

[data-action="add-to-cart"] {
    transition: transform 0.15s ease, background-color 0.3s ease, color 0.3s ease;
}
[data-action="add-to-cart"].is-pressed { transform: scale(0.95); }
[data-action="add-to-cart"].is-confirmed {
    background: var(--ok);
    color: #fff;
    animation: cart-pop 0.25s ease;
}
[data-action="add-to-cart"].is-confirmed.is-repeat { background: var(--accent-2); color: #1a1208; }
[data-action="add-to-cart"].is-unavailable { background: var(--text-secondary); color: #fff; }
[data-action="add-to-cart"].is-limit { background: var(--text-secondary); color: #fff; animation: cart-shake 0.4s ease; }
/* B2: estados de reposo segun qty_en_carrito vs stock_display (status=available
   -- mismos colores que sus equivalentes transitorios, pero sin pop/animacion,
   son un estado que se queda, no un evento que acaba de pasar). */
[data-action="add-to-cart"].is-owned { background: var(--ok); color: #fff; }
[data-action="add-to-cart"].is-more { background: var(--accent-2); color: #1a1208; }

@keyframes cart-shake {
    0%, 100% { transform: translateX(0); }
    20%      { transform: translateX(-6px); }
    40%      { transform: translateX(6px); }
    60%      { transform: translateX(-4px); }
    80%      { transform: translateX(4px); }
}

@keyframes cart-pop {
    0%   { transform: scale(1); }
    60%  { transform: scale(1.05); }
    100% { transform: scale(1); }
}

.cart-badge.is-bumped { animation: cart-badge-bump 0.4s ease; }
@keyframes cart-badge-bump {
    0%   { transform: scale(1); }
    50%  { transform: scale(1.3); }
    100% { transform: scale(1); }
}

/* ---------- Banner de ambiente de pruebas (solo dev, ver Config\Shop::showDevBanner) ----------
   Version larga para la tienda publica -- el cliente necesita el detalle
   completo (compra simulada, link a la tienda real), no solo un badge corto
   como en el admin (ver .dev-banner en admin.css). No es dismissible a
   proposito: debe seguir visible mientras el visitante navega dev-tienda. */

.dev-banner-full {
    position: sticky; top: var(--header-h); z-index: 99;
    background: #ffd400; color: #111;
    font-weight: 600; font-size: 0.85rem;
    text-align: center;
    padding: 0.6rem 1rem;
}
.dev-banner-full a { color: #111; text-decoration: underline; font-weight: 700; }

/* ---------- Marquesina de aviso (pago con tarjeta / Mercado Pago) ----------
   Corre bajo el header fijo, en flujo normal (se va con el scroll, NO sticky).
   Solo se renderiza si mpEnabled (ver layout.php). Dos copias identicas del
   texto + translateX(-50%) = loop sin costura. No pausa (ni hover ni focus);
   el clic abre #promoModal con el texto completo (ver shop.js). Sin animacion
   con prefers-reduced-motion (ahi se muestra centrado y estatico). */
.promo-marquee {
    overflow: hidden;
    background: var(--accent);
    color: #fff;
    font-size: 0.82rem;
    font-weight: 600;
    line-height: 1.1;
    padding: 0.5rem 0;
    cursor: pointer;
}
.promo-marquee__track {
    display: flex;
    width: max-content;
    animation: promo-marquee-scroll 26s linear infinite;
    will-change: transform;
}
.promo-marquee__item { flex-shrink: 0; padding: 0 2.5rem; white-space: nowrap; }
@keyframes promo-marquee-scroll {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
    .promo-marquee { white-space: normal; text-align: center; padding: 0.5rem 1rem; }
    .promo-marquee__track { animation: none; width: auto; justify-content: center; }
    .promo-marquee__item { white-space: normal; padding: 0; }
    .promo-marquee__item + .promo-marquee__item { display: none; }
}

/* ---------- WhatsApp + carrito flotantes (global, todas las paginas) ---------- */

.whatsapp-float, .cart-float {
    position: fixed;
    right: 1rem;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4);
    z-index: 150;
}
.whatsapp-float { bottom: 1rem; background: #25d366; }
.cart-float { bottom: calc(1rem + 52px + 0.75rem); background: var(--accent); font-size: 1.4rem; }

.whatsapp-float:hover { background: #1ebe57; }
.whatsapp-float svg { width: 26px; height: 26px; fill: #fff; }

/* mobile search: expands to cover the row when toggled */
.site-header.search-open .site-header__search { display: block; }
.site-header.search-open .site-header__logo span { display: none; }

/* ---------- Nav rapida movil (Catalogo/Vitrina/Mas categorias) ----------
   Solo mobile -- desktop ya las tiene inline en .site-header__nav (min-width:768px
   mas abajo la esconde). Flujo normal (no fixed): .site-header si es fixed y
   body ya reserva --header-h de espacio, asi que esta nav cae justo debajo del
   header y se desplaza con el scroll -- no hace falta position/z-index propios. */
.mobile-quicknav {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.6rem 1rem;
    border-bottom: 1px solid var(--border);
}
/* Tarea 3: Catalogo/Vitrina/Buscador como pills (mismo tratamiento que el
   nav de escritorio) -- antes eran texto plano, poco notorios. */
.mobile-quicknav a,
.mobile-quicknav > button {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 0.4rem 0.7rem;
    font-family: var(--font);
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--text);
    cursor: pointer;
    white-space: nowrap;
}
.mobile-quicknav a:active,
.mobile-quicknav > button:active { border-color: var(--accent); color: var(--accent); }
.mobile-quicknav__more { position: relative; margin-left: auto; }
.mobile-quicknav__more button {
    background: none; border: none; color: var(--text);
    font-family: var(--font); font-size: 0.9rem; font-weight: 600; cursor: pointer;
    padding: 0;
}
.mobile-quicknav__dropdown {
    display: none;
    position: absolute;
    top: calc(100% + 0.5rem); right: 0;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    min-width: 160px;
    max-height: 60vh;
    overflow-y: auto;
    z-index: 120;
}
.mobile-quicknav__dropdown.open { display: block; }
.mobile-quicknav__dropdown a {
    display: block;
    padding: 0.6rem 0.9rem;
    font-weight: 500;
    white-space: nowrap;
}
.mobile-quicknav__dropdown a:hover { background: var(--bg); }

/* ---------- Hero / tagline (home) ----------
   Oculto en mobile -- el header fijo + quicknav ya muestran el mismo logo y
   nombre de tienda (siempre visibles, en todas las paginas), repetirlos aqui
   es contenido identico sin informacion nueva, solo empuja el primer
   producto fuera de la pantalla inicial (encontrado en prod 2026-07-31, ver
   tambien .launch-promo/.raffle-promo/.search-bar abajo, mismo motivo).
   En desktop si funciona como un hero real (pantalla mas grande, momento de
   aterrizaje propio) -- version completa restaurada en la media query
   min-width: 768px de abajo. */

.hero { display: none; }

/* Promo temporal de lanzamiento -- ver comentario "ponytail" en home.php. */
.launch-promo {
    background: var(--accent-2); color: #1a1208;
    font-weight: 700; font-size: 0.8rem; text-align: center;
    padding: 0.45rem 0.8rem; border-radius: var(--radius);
    margin: 0 0 0.5rem;
}

/* Marquesina de sorteo mensual -- rojo de marca (--accent, ya usado en botones
   primarios/badges) en vez del naranja de .launch-promo, para no confundir
   ambos banners a simple vista. Toda el area es un <a>, no solo el texto. */
.raffle-promo {
    display: block;
    background: var(--accent); color: #fff;
    font-weight: 700; font-size: 0.8rem; text-align: center;
    padding: 0.45rem 0.8rem; border-radius: var(--radius);
    margin: 0 0 0.5rem;
    transition: background 0.15s ease;
}
.raffle-promo:hover { background: #d12836; }

/* ---------- Search bar (prominent, home) ----------
   Oculto siempre (mobile y desktop) -- redundante con el buscador del header
   (icono 🔍 en mobile, input inline siempre visible en desktop), mismo
   destino en ambos casos. */

.search-bar { display: none; padding: 0.5rem 0 1.25rem; }
.search-bar form { display: flex; gap: 0.5rem; }
.search-bar input {
    flex: 1;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text);
    padding: 0.85rem 1rem;
    font-family: var(--font);
    font-size: 1rem;
}
.search-bar input::placeholder { color: var(--text-secondary); }
/* Tarea 3: mas contraste al enfocar -- el buscador es de los 3 puntos de
   navegacion con poco uso, el input ya era grande pero se perdia visualmente. */
.search-bar input:focus,
.site-header__search input:focus { outline: none; border-color: var(--accent); }

/* ---------- Filter chips (line, home) ---------- */

.chips {
    display: flex;
    gap: 0.5rem;
    overflow-x: auto;
    padding: 0.25rem 0 0.75rem;
    scrollbar-width: none;
}
.chips::-webkit-scrollbar { display: none; }
.chip {
    flex-shrink: 0;
    background: var(--bg-card);
    border: 1px solid var(--border);
    color: var(--text);
    border-radius: 999px;
    padding: 0.45rem 1rem;
    font-size: 0.85rem;
    font-weight: 500;
    white-space: nowrap;
}
.chip.is-active,
.chip:hover { border-color: var(--accent); color: var(--accent); }

/* ---------- Section headings ---------- */

.section { padding: 1.5rem 0; }
.section__title { font-size: 1.15rem; margin-bottom: 0.9rem; }

/* Header de seccion con control a la derecha (home: "Productos" + "Ordenar
   por") -- wrap para no romper en mobile si no cabe en una fila, la
   .section__title de adentro no necesita su propio margen, el header ya
   lo pone. */
.section__header { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem 0.75rem; margin-bottom: 0.9rem; }
.section__header .section__title { margin-bottom: 0; }

/* Chips de linea (home): ocultos en mobile -- "Mas categorias" del quicknav
   ya cubre el acceso a filtrar por linea, y son un filtro secundario que no
   justifica el espacio vertical ahi. Clase propia (.home-chips), no .chips
   a secas -- esa la reusa /catalogo para sus chips de filtro, que si deben
   seguir visibles en mobile. */
.home-chips { display: none; }

/* Combobox de orden (home) -- ahora vive junto al titulo "Productos" (ver
   .section__header), mismo lugar en mobile y desktop. */
.home-order { display: flex; align-items: center; gap: 0.5rem; }
.home-order label { font-size: 0.85rem; color: var(--text-secondary); }
.home-order select {
    background: var(--bg-card);
    border: 1px solid var(--border);
    color: var(--text);
    border-radius: var(--radius);
    padding: 0.45rem 0.7rem;
    font-family: var(--font);
    font-size: 0.85rem;
}

/* Tarea 2: marcador invisible para el IntersectionObserver del scroll
   infinito (shop.js) -- sin contenido, solo necesita existir en el flujo. */
#homeMoreSentinel { height: 1px; }

/* ---------- Coleccion (detalle, /coleccion/{slug}) ---------- */

/* Reusa .gallery__main/thumbs/dots/arrow (product detail) para las N imagenes
   de la vitrina -- mismo carrusel+lightbox de shop.js, sin JS nuevo. Las
   imagenes propias de la vitrina son la protagonista de esta pagina (los
   productos ligados abajo son secundarios, ver .product-grid--compact).
   Contenedor centrado (mismo ancho que .container, no sangrado a todo el
   viewport) -- full-bleed + object-fit:contain se veia como una barra ancha
   con la imagen chiquita perdida en medio, nada centrado como bloque. */
.collection-hero { max-width: 1200px; margin: 0 auto; padding: 0 1rem; }
.collection-hero .gallery__main { aspect-ratio: 4 / 3; }
/* contain en vez de cover (herencia de producto) -- estas son imagenes
   curadas a mano (flyers, collages), recortarlas a la fuerza les corta texto
   y logos de las orillas. Mismo tratamiento que el lightbox: imagen completa,
   centrada, con el fondo de la card rellenando lo que sobre. */
.collection-hero .gallery__main img { object-fit: contain; }
/* Thumbs visibles tambien en mobile (a diferencia del producto, que en mobile
   depende solo del swipe) -- con hasta una docena de imagenes, sin esto no
   hay forma de saber que hay mas. Dots se ocultan, quedarian redundantes. */
.collection-hero .gallery__thumbs { display: flex; margin: 0.6rem 0 0; }
.collection-hero .gallery__dots { display: none; }
/* Protagonistas -- deben leerse claramente mas grandes que los productos
   ligados (ver .product-grid--compact, mas columnas = cards mas chicos). */
.collection-hero .gallery__thumbs img { width: 190px; height: 190px; }

/* ---------- Colecciones (home, cards) ---------- */

.collection-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.9rem;
}
.collection-card {
    position: relative;
    display: block;
    aspect-ratio: 1 / 1;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--bg-card);
}
.collection-card img { width: 100%; height: 100%; object-fit: cover; }
.collection-card__overlay {
    position: absolute; inset: 0;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0) 55%);
    display: flex; flex-direction: column; justify-content: flex-end;
    padding: 0.75rem;
    color: #fff;
}
.collection-card__title { font-weight: 700; font-size: 0.95rem; }
.collection-card__count { font-size: 0.75rem; color: rgba(255, 255, 255, 0.8); }

/* ---------- Product grid + card ---------- */

.product-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.9rem;
}

.product-card {
    background: var(--bg-card);
    border-radius: var(--radius);
    overflow: hidden;
    border: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    transition: box-shadow 0.15s ease, transform 0.15s ease;
}

/* Hover solo en dispositivos que de verdad tienen hover (evita el "hover pegado" al tocar en mobile). */
@media (hover: hover) {
    .product-card:hover { box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35); transform: translateY(-2px); }
    .btn--primary:hover { box-shadow: 0 4px 12px rgba(230, 57, 70, 0.4); transform: translateY(-1px); }
    .btn--preorder:hover { box-shadow: 0 4px 12px rgba(244, 162, 97, 0.4); transform: translateY(-1px); }
}

/* La imagen es la protagonista del card, no el texto -- aspect-ratio cuadrado
   mas un body compacto abajo le da a la imagen la mayor parte de la altura. */
.product-card__media { position: relative; aspect-ratio: 1 / 1; background: var(--bg-card); }
.product-card__media img { width: 100%; height: 100%; object-fit: cover; }

.placeholder-image {
    width: 100%; height: 100%;
    background: var(--bg-card);
    display: flex; align-items: center; justify-content: center;
}
.placeholder-image img { width: 100%; height: 100%; object-fit: cover; }

.badge {
    display: inline-block;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 0.25rem 0.55rem;
    border-radius: 999px;
}
.badge--available { background: rgba(46, 204, 113, 0.15); color: var(--ok); }
.badge--preorder { background: rgba(249, 199, 79, 0.15); color: var(--warn); }
.badge--sold { background: rgba(230, 57, 70, 0.15); color: var(--accent); }
/* Mismo amarillo que --preorder pero nombrado por lo que es en el card: poco stock, no "viene en camino". */
.badge--stock-low { background: rgba(249, 199, 79, 0.15); color: var(--warn); }
/* Agotado por el momento (stock oculto) / no esta en bodega pero hay afiliado -- ninguno de los dos es urgencia. */
.badge--muted { background: rgba(154, 160, 176, 0.15); color: var(--text-secondary); }
/* Ultima unidad: mismo rojo que --sold pero parpadeando, para no confundirlo con "ya se vendio". */
.badge--stock-last { background: rgba(230, 57, 70, 0.15); color: var(--accent); animation: badge-blink 1.5s ease infinite; }

@keyframes badge-blink {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.7; }
}

.product-card__body { padding: 0.6rem 0.7rem 0.75rem; display: flex; flex-direction: column; gap: 0.3rem; flex: 1; }
.product-card__stock-badge { align-self: flex-start; margin-top: 0.1rem; }
.product-card__name {
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1.25;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.product-card__price { font-size: 1.2rem; font-weight: 800; color: var(--accent-2); margin-top: auto; }

/* Tarea 4: card de vitrina mezclada en el feed de home -- mismo .product-card,
   sin precio/badge/CTA de compra, solo titulo + boton "Ver" al fondo. */
.product-card--vitrina .product-card__cta { margin-top: auto; }

/* Badge chico "tambien en ML" -- secundario a proposito, no debe competir con el CTA. */
.product-card__ml {
    display: inline-flex;
    align-self: flex-start;
    background: #ffe600;
    color: #1a1208;
    font-size: 0.68rem;
    font-weight: 700;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    text-decoration: none;
}
.product-card__ml:hover { background: #e6cf00; }

.product-card__cta { margin-top: 0.3rem; padding: 0.9rem 1rem; font-size: 1rem; font-weight: 700; }

/* Vitrina: los productos ligados van en segundo plano frente a las imagenes
   propias de la coleccion -- mismo .product-card/product_card.php de siempre
   (el boton "Mio" sigue funcionando igual), solo mas chico y mas denso.
   .product-grid.product-grid--compact (las dos clases, no solo una) a
   proposito en grid-template-columns -- el elemento trae ambas clases
   (product_grid + product-grid--compact) y .product-grid tiene sus propias
   reglas de columnas en los mismos breakpoints mas abajo en este archivo;
   con la misma especificidad (una sola clase cada una) gana la que aparece
   despues en el archivo, no esta, y el cambio de columnas no se reflejaba
   nunca. Con dos clases esta gana siempre, sin importar el orden. */
.product-grid--compact { gap: 0.3rem; }
/* 3 en vez de 4 en mobile -- +20% pedido sobre el ancho de 4 columnas no
   cabia comodo en anchos de telefono tipicos (390px: card actual ~86px,
   +20% son ~103px, y 4 de esas ya no caben en el content de ~358px). 3
   columnas si caben y dan ~116px de card (~35% mas que las 4 columnas
   anteriores) -- se prioriza que se vea bien sobre el numero exacto. */
.product-grid.product-grid--compact { grid-template-columns: repeat(3, 1fr); }
.product-grid--compact .product-card__body { padding: 0.4rem 0.5rem 0.5rem; gap: 0.15rem; }
.product-grid--compact .product-card__name { font-size: 0.7rem; }
.product-grid--compact .product-card__price { font-size: 0.85rem; }
.product-grid--compact .product-card__cta { padding: 0.5rem 0.6rem; font-size: 0.75rem; }
.product-grid--compact .badge { font-size: 0.6rem; padding: 0.15rem 0.4rem; }
.collection-products__label { font-weight: 600; color: var(--text-secondary); margin: 0 0 0.6rem; }
@media (min-width: 768px) {
    /* Base real (mientras el bug de especificidad estuvo vivo, esto siempre
       caia al .product-grid normal de 3 columnas, ~242px de card -- 30%
       menos es ~170px). */
    .product-grid.product-grid--compact { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
}
@media (min-width: 1024px) {
    /* Idem, la base real aqui era .product-grid normal de 4 columnas
       (~288px de card, no las ~93px de 12 columnas que yo asumia) -- 30%
       menos es ~200px. Se deja un poco por debajo (175px) para que sigan
       claramente mas chicas que los thumbs de la vitrina (190px). */
    .product-grid.product-grid--compact { grid-template-columns: repeat(auto-fill, minmax(175px, 1fr)); }
}

/* ---------- "Lo que se fue" (sold) ---------- */

.sold-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.6rem;
}
.sold-card { position: relative; border-radius: var(--radius); overflow: hidden; aspect-ratio: 1 / 1; }
.sold-overlay {
    position: absolute; inset: 0;
    background: rgba(230, 57, 70, 0.55);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 0.2rem; padding: 0.4rem; text-align: center;
    color: #fff;
}
.sold-card__name { font-size: 0.66rem; font-weight: 600; line-height: 1.2; }
.sold-card__label { font-weight: 800; font-size: 0.72rem; letter-spacing: 0.05em; text-transform: uppercase; }
.sold-note { color: var(--text-secondary); font-size: 0.9rem; margin-top: 0.75rem; }
.sold-note + .btn { margin-top: 0.75rem; }

/* ---------- Footer ---------- */

.site-footer { border-top: 1px solid var(--border); padding: 2rem 0; margin-top: 2rem; text-align: center; }
.footer-links { display: flex; justify-content: center; gap: 1.5rem; flex-wrap: wrap; margin-bottom: 1rem; }
.footer-links a { color: var(--text-secondary); font-weight: 600; font-size: 0.9rem; }
.footer-links a:hover { color: var(--accent); }
.site-footer .copy { color: var(--text-secondary); font-size: 0.75rem; }
.footer-legal { display: flex; justify-content: center; gap: 1rem; flex-wrap: wrap; margin-bottom: 0.75rem; font-size: 0.75rem; color: var(--text-secondary); }
.footer-legal a { color: var(--text-secondary); }
.footer-legal a:hover { color: var(--accent); }

.legal-page { max-width: 760px; }
.legal-content h2 { font-size: 1rem; margin-top: 1.5rem; }
.legal-content ul { color: var(--text-secondary); padding-left: 1.25rem; margin: 0 0 0.75rem; }
.legal-content li { margin-bottom: 0.3rem; }

/* ---------- Catalog: filters + pagination ---------- */

.catalog-layout { display: flex; flex-direction: column; gap: 1rem; padding-top: 1rem; }

.filters-toggle {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 0.7rem 1rem;
}

.filters-drawer {
    position: fixed;
    inset: 0;
    background: var(--bg);
    z-index: 110;
    padding: 1rem;
    overflow-y: auto;
    display: none;
}
.filters-drawer.open { display: block; }
.filters-drawer__header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; }

.filter-group { margin-bottom: 1.25rem; }
.filter-group__title { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-secondary); margin-bottom: 0.5rem; }
.filter-group select,
.filter-group .radio-row { width: 100%; }
.filter-group select {
    background: var(--bg-card);
    border: 1px solid var(--border);
    color: var(--text);
    border-radius: var(--radius);
    padding: 0.6rem 0.7rem;
    font-family: var(--font);
}
.filter-group label { display: flex; align-items: center; gap: 0.5rem; padding: 0.35rem 0; font-size: 0.9rem; }
.filter-group__links { display: flex; flex-direction: column; gap: 0.3rem; }
.filter-group__links a { font-size: 0.9rem; padding: 0.2rem 0; }
.filter-group__links a:hover { color: var(--accent); }

.results-count { color: var(--text-secondary); font-size: 0.9rem; margin-bottom: 0.75rem; }

.pagination { display: flex; justify-content: center; gap: 0.4rem; padding: 1.5rem 0; flex-wrap: wrap; }
.pagination a, .pagination span {
    min-width: 36px; height: 36px;
    display: flex; align-items: center; justify-content: center;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    font-size: 0.85rem;
}
.pagination a:hover { border-color: var(--accent); }
.pagination .is-current { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ---------- Product detail ---------- */

/* Mobile: swipe nativo (scroll-snap, sin JS) entre todas las imagenes.
   Desktop: una sola imagen fija, los thumbnails le cambian el src (JS minimo). */
.gallery { position: relative; }
.gallery__main {
    position: relative;
    aspect-ratio: 1 / 1;
    border-radius: var(--radius);
    background: var(--bg-card);
    display: flex;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
}
.gallery__main img {
    flex: 0 0 100%;
    width: 100%; height: 100%;
    object-fit: cover;
    scroll-snap-align: center;
    cursor: zoom-in;
}
.gallery__thumbs { display: none; gap: 0.5rem; margin-top: 0.6rem; overflow-x: auto; }
.gallery__thumbs img {
    width: 60px; height: 60px; object-fit: cover; border-radius: 6px;
    border: 1px solid var(--border); cursor: pointer; opacity: 0.6;
}
.gallery__thumbs img.is-active { opacity: 1; border-color: var(--accent); }

/* Dots (mobile, sigue el swipe nativo) / flechas (desktop, click) -- MEJORA 1A. */
.gallery__dots { display: flex; justify-content: center; gap: 0.4rem; margin-top: 0.6rem; }
.gallery__dot {
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--border); border: none; padding: 0; cursor: pointer;
}
.gallery__dot.is-active { background: var(--accent); }

.gallery__arrow {
    display: none;
    position: absolute; top: 50%; transform: translateY(-50%);
    width: 34px; height: 34px; border-radius: 50%;
    background: rgba(0, 0, 0, 0.55); color: #fff; border: none;
    font-size: 1.3rem; line-height: 1; cursor: pointer; z-index: 2;
    align-items: center; justify-content: center;
}
.gallery__arrow--prev { left: 0.5rem; }
.gallery__arrow--next { right: 0.5rem; }

/* ---------- Lightbox (MEJORA 1B) -- CSS + JS vanilla, sin librerias ---------- */
.lightbox {
    position: fixed; inset: 0;
    background: rgba(0, 0, 0, 0.9);
    display: none;
    align-items: center; justify-content: center;
    z-index: 300;
}
.lightbox.open { display: flex; }
.lightbox img { max-width: 92vw; max-height: 85vh; object-fit: contain; }
.lightbox__close {
    position: absolute; top: 1rem; right: 1rem;
    background: none; border: none; color: #fff;
    font-size: 2rem; line-height: 1; cursor: pointer; z-index: 2;
}
.lightbox__arrow {
    position: absolute; top: 50%; transform: translateY(-50%);
    width: 44px; height: 44px; border-radius: 50%;
    background: rgba(255, 255, 255, 0.15); color: #fff; border: none;
    font-size: 1.6rem; line-height: 1; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
}
.lightbox__arrow--prev { left: 1rem; }
.lightbox__arrow--next { right: 1rem; }

.detail-body { padding: 1.25rem 0; }
.detail-body .badge { margin-bottom: 0.6rem; }
.detail-body h1 { font-size: 1.3rem; }
/* Precio justo despues del nombre -- lo primero que se ve, antes que marca/año. */
.detail-price { font-size: 2.1rem; font-weight: 800; color: var(--accent-2); margin: 0.15rem 0 0.6rem; }

/* Comparacion con precio de ML (MEJORA 2) -- producto propio: badge de ahorro. */
.ml-price-compare { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.3rem; }
.badge--savings { background: rgba(46, 204, 113, 0.15); color: var(--ok); }

/* Producto de tercero con precio de ML (MEJORA 2). */
.ml-price-thirdparty { margin-bottom: 0.6rem; }
.ml-price-thirdparty__label { font-size: 1rem; }
.ml-price-thirdparty__note { color: var(--text-secondary); font-size: 0.8rem; }
.detail-meta { color: var(--text-secondary); font-size: 0.9rem; margin-bottom: 0.75rem; }
.detail-meta a { color: inherit; text-decoration: underline; }
.detail-description { color: var(--text-secondary); font-size: 0.95rem; line-height: 1.6; margin-bottom: 1rem; }
/* Condiciones de la pieza: mismo tamano que la descripcion pero a contraste
   pleno y con acento -- para vintage/usado importa mas que el blurb generico. */
.detail-conditions { color: var(--text); font-size: 0.95rem; line-height: 1.6; margin-bottom: 1rem; padding-left: 0.85rem; border-left: 3px solid var(--accent); }
.detail-conditions strong { display: block; margin-bottom: 0.15rem; }

.preorder-note {
    background: rgba(249, 199, 79, 0.1);
    border: 1px solid rgba(249, 199, 79, 0.3);
    color: var(--warn);
    border-radius: var(--radius);
    padding: 0.75rem 1rem;
    font-size: 0.88rem;
    margin-bottom: 1rem;
}

.gone-note {
    background: rgba(230, 57, 70, 0.1);
    border: 1px solid rgba(230, 57, 70, 0.3);
    color: var(--accent);
    border-radius: var(--radius);
    padding: 0.75rem 1rem;
    font-size: 0.88rem;
    margin-bottom: 1rem;
}

/* Agotado por el momento (hidden) / no esta en bodega pero hay afiliado -- informativo, sin urgencia. */
.muted-note {
    background: rgba(154, 160, 176, 0.1);
    border: 1px solid rgba(154, 160, 176, 0.3);
    color: var(--text-secondary);
    border-radius: var(--radius);
    padding: 0.75rem 1rem;
    font-size: 0.88rem;
    margin-bottom: 1rem;
}

.detail-cta { display: flex; flex-direction: column; gap: 0.6rem; margin-bottom: 0.5rem; }

/* Compartir -- chip flotante sobre la imagen del producto (esquina sup. der.). */
.gallery__share {
    position: absolute; top: 0.6rem; right: 0.6rem; z-index: 3;
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.45rem 0.75rem;
    background: rgba(0, 0, 0, 0.62); color: #fff;
    border: none; border-radius: 999px;
    font-size: 0.8rem; font-weight: 600; line-height: 1; cursor: pointer;
    -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
.gallery__share:hover { background: rgba(0, 0, 0, 0.8); }
.gallery__share svg { flex-shrink: 0; }
.detail-note { color: var(--text-secondary); font-size: 0.78rem; margin-top: 0.25rem; }

/* CTA principal del detalle ("Mio"/"Lo aparto") -- el elemento mas dominante
   despues del precio; entra con un delay para que el ojo pase por el precio
   primero. */
.btn--cta {
    padding: 1.1rem 1.5rem;
    font-size: 1.1rem;
    font-weight: 700;
    animation: ctaEntrance 0.4s ease 0.3s both;
}
@keyframes ctaEntrance {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ---------- Carrito (/carrito) ---------- */

.cart-empty { text-align: center; padding: 3rem 1rem; }
.cart-empty .btn { display: inline-flex; margin-top: 1rem; }

.cart-layout { display: flex; flex-direction: column; gap: 1.5rem; padding-bottom: 2rem; }

.cart-items { display: flex; flex-direction: column; gap: 0.75rem; }
.cart-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 0.6rem;
}
.cart-item__thumb { width: 56px; height: 56px; object-fit: cover; border-radius: 8px; flex-shrink: 0; }
.cart-item__info { flex: 1; min-width: 0; }
.cart-item__name { font-size: 0.88rem; font-weight: 600; }
.cart-item__price { font-size: 0.8rem; color: var(--text-secondary); }
.cart-item__qty { display: flex; align-items: center; gap: 0.4rem; flex-shrink: 0; }
.qty-btn {
    width: 28px; height: 28px;
    border-radius: 50%;
    border: 1px solid var(--border);
    background: var(--bg);
    color: var(--text);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}
.qty-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.qty-value { min-width: 1.5rem; text-align: center; font-weight: 700; }
.cart-item__remove {
    background: none; border: none; color: var(--text-secondary);
    font-size: 1.3rem; line-height: 1; cursor: pointer; flex-shrink: 0; padding: 0.2rem 0.4rem;
}
.cart-item__remove:hover { color: var(--accent); }

.cart-summary {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 1rem;
}
.cart-summary__row { display: flex; justify-content: space-between; padding: 0.4rem 0; }
.cart-summary__row--total { font-size: 1.2rem; font-weight: 800; border-top: 1px solid var(--border); margin-top: 0.4rem; padding-top: 0.75rem; }

.cart-summary__shipping { margin: 0.5rem 0 1rem; }
.field__title { font-size: 0.85rem; color: var(--text-secondary); margin-bottom: 0.5rem; }
.shipping-option {
    display: flex; align-items: center; gap: 0.6rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 0.6rem 0.75rem;
    margin-bottom: 0.5rem;
    cursor: pointer;
}
.shipping-option:has(input:checked) { border-color: var(--accent); background: rgba(230, 57, 70, 0.06); }
.shipping-option__body { flex: 1; display: flex; flex-direction: column; }
.shipping-option__body small { color: var(--text-secondary); }
.shipping-option__price.is-free { color: var(--ok); }

/* Metodo de pago en un solo row (a diferencia de shipping-option, que es una
   lista vertical) -- cada una es una tarjeta compacta con el nombre y el
   total ya calculado para ese metodo (ver renderMetodoPagoTotals() en
   shop.js), el radio real se oculta visualmente, toda la tarjeta es el control.
   Selectores calificados con .payment-options (dos clases) a proposito -- estos
   labels/inputs viven dentro de .field, y .field label/.field input (mas
   especificos que un solo .payment-option/.payment-option input, y mas abajo
   en este archivo) pisaban el display:flex y el ocultamiento del radio. */
.payment-options { display: flex; gap: 0.5rem; }
.payment-options .payment-option {
    flex: 1; display: flex; flex-direction: column; align-items: center; gap: 0.2rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 0.6rem 0.4rem;
    cursor: pointer;
    text-align: center;
    margin-bottom: 0;
    font-size: 1rem;
    color: var(--text);
}
.payment-options .payment-option:has(input:checked) { border-color: var(--accent); background: rgba(230, 57, 70, 0.06); }
.payment-options .payment-option input { position: absolute; opacity: 0; width: 0; height: 0; }
.payment-option__total { font-weight: 700; }
.payment-option small { color: var(--text-secondary); }
/* Iconos de marca del metodo de pago (SPEI/OXXO, Mastercard/Visa/MercadoPago) --
   SVG inline, fila compacta arriba del nombre. Alto fijo 15px para no alterar
   la proporcion de la tarjeta (ver nota arriba). Dos clases para ganarle a .field. */
.payment-options .payment-option__icons { display: flex; gap: 3px; align-items: center; justify-content: center; flex-wrap: wrap; }
.payment-options .payment-option__icons .pay-ico { width: 24px; height: 15px; display: block; flex-shrink: 0; }

/* Pastilla compacta y SIEMPRE visible (nunca display:none, ni con el carrito
   vacio -- se queda en 0%) de envio gratis, ver shop/partials/shipping_bar.php
   -- a proposito chica (NO barra de ancho completo). Actualizada por
   renderShippingBars() en shop.js.

   En mobile estorbaba: fixed en la esquina superior derecha tapaba el buscador/
   carrito del header al expandirse. Ahora vive en flujo normal justo debajo del
   menu (shipping_bar.php se incluye entre .mobile-quicknav y <main> en
   layout.php) con position:sticky -- se queda ahi mientras la pagina esta
   arriba del todo, y al hacer scroll se pega debajo del header (mismo lugar
   visual que antes) hasta que vuelves arriba, donde regresa sola a su posicion
   original. Desktop no tenia el problema -- se restaura el fixed de esquina de
   siempre.

   .shipping-bar-slot es SIEMPRE display:contents (no genera caja propia) --
   sticky necesita que su contenedor real (aqui <body>, todo el alto de la
   pagina) sea mas alto que el propio elemento para tener "recorrido"; un
   wrapper ajustado al tamano de la pastilla (ej. flex solo para alinearla a
   la derecha) le da cero recorrido y sticky no pega nada, se comporta como si
   no existiera. La alineacion a la derecha se hace con margin-left:auto en la
   pastilla misma, no con flex del wrapper. */
.shipping-bar-slot { display: contents; }
.shipping-bar {
    position: sticky;
    top: calc(var(--header-h) + 10px);
    z-index: 130;
    width: 176px;
    margin: 0.6rem 1rem 0 auto;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 0.65rem 0.75rem 0.55rem;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
}
@media (min-width: 768px) {
    /* Desktop nunca tuvo el problema de mobile -- header mas ancho, el buscador
       no se expande a pantalla completa. Se mantiene el pill flotante de siempre. */
    .shipping-bar { position: fixed; right: 10px; margin: 0; }
}
.shipping-bar__caption { font-size: 0.7rem; font-weight: 700; color: var(--text-secondary); margin-bottom: 0.5rem; white-space: nowrap; }
.shipping-bar__track { position: relative; height: 8px; margin: 0 10px; background: var(--border); border-radius: 4px; }
.shipping-bar__fill {
    position: absolute;
    left: 0; top: 0; height: 100%;
    width: 0%;
    background: linear-gradient(90deg, var(--accent-2), var(--ok));
    border-radius: 4px;
    transition: width 0.5s ease;
}
.shipping-bar__marker {
    position: absolute;
    top: 50%;
    left: 0;
    transform: translate(-50%, -50%);
    width: 20px; height: 20px;
    border-radius: 50%;
    background: var(--bg);
    border: 2px solid var(--border);
    display: flex; align-items: center; justify-content: center;
    font-size: 0.68rem;
    transition: border-color 0.3s ease, background 0.3s ease, transform 0.3s ease;
}
.shipping-bar__marker--terrestre { left: 100%; transform: translate(-100%, -50%); }
.shipping-bar__marker.is-reached { border-color: var(--ok); background: rgba(46, 204, 113, 0.25); transform: translate(-50%, -50%) scale(1.2); }
.shipping-bar__marker--terrestre.is-reached { transform: translate(-100%, -50%) scale(1.2); }
.shipping-bar__marker.is-reached::after {
    content: '✓';
    position: absolute;
    top: -6px; right: -4px;
    width: 13px; height: 13px;
    background: var(--ok);
    color: #0f1115;
    border-radius: 50%;
    font-size: 9px; font-weight: 800;
    display: flex; align-items: center; justify-content: center;
}
@keyframes shipping-bar-pulse {
    0% { box-shadow: 0 0 0 0 rgba(46, 204, 113, 0.65); }
    70% { box-shadow: 0 0 0 9px rgba(46, 204, 113, 0); }
    100% { box-shadow: 0 0 0 0 rgba(46, 204, 113, 0); }
}
.shipping-bar__marker.is-just-reached { animation: shipping-bar-pulse 0.8s ease-out 2; }
.shipping-bar__labels { position: relative; height: 13px; margin: 4px 10px 0; }
.shipping-bar__labels span { position: absolute; top: 0; transform: translateX(-50%); font-size: 0.6rem; color: var(--text-secondary); white-space: nowrap; }
.shipping-bar__labels .shipping-bar__label--end { left: auto; right: 0; transform: none; }

/* Barras chicas por opcion dentro del carrito (Correos/Terrestre), su propio
   row debajo del texto de dias -- la barra y su leyenda van cada una en su
   propia linea (flex-direction:column), no lado a lado. */
.shipping-progress { display: none; margin-top: 0.4rem; }
.shipping-progress.is-active { display: flex; flex-direction: column; gap: 0.3rem; }
.shipping-progress__bar { height: 5px; border-radius: 3px; background: var(--border); overflow: hidden; }
.shipping-progress__fill { display: block; height: 100%; width: 0%; background: var(--ok); border-radius: 3px; transition: width 0.3s ease; }
.shipping-progress__label { font-size: 0.72rem; color: var(--text-secondary); white-space: nowrap; }
.shipping-progress.is-unlocked .shipping-progress__label { color: var(--ok); font-weight: 600; }

/* Toast de "desbloqueaste envio gratis" -- grande y con rebote a proposito
   (el primer intento, mas discreto, pasaba desapercibido). Sale pegado hasta
   abajo, centrado, y al ocultarse (is-leaving, ver showShippingToast en
   shop.js) flota casi hasta arriba de la pantalla mientras se desvanece --
   sin encoger, el tamano se queda igual todo el trayecto. UN SOLO transition
   (no @keyframes) -- la primera version mezclaba una animation en is-leaving
   con el transition base de .shop-toast (el que anima la entrada); ambos
   peleaban por transform/opacity al mismo tiempo y se veia como si la salida
   empezara apenas aparecia. Mobile-first: base chica (pantallas angostas se
   sentia enorme), se agranda de vuelta en desktop (min-width:768px mas
   abajo). */
.shop-toast {
    position: fixed;
    left: 50%;
    bottom: 1.1rem;
    transform: translate(-50%, 16px) scale(0.85);
    background: linear-gradient(135deg, var(--ok), #219150);
    color: #0b1a10;
    border: none;
    border-radius: 999px;
    padding: 0.55rem 0.9rem;
    font-size: 0.78rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    box-shadow: 0 14px 34px rgba(46, 204, 113, 0.5);
    opacity: 0;
    transition: opacity 0.35s ease, transform 0.4s cubic-bezier(.34, 1.56, .64, 1);
    z-index: 999;
    max-width: 90vw;
    cursor: pointer;
}
.shop-toast a { color: #0b1a10; text-decoration: underline; font-weight: 800; white-space: nowrap; }
.shop-toast.is-visible { opacity: 1; transform: translate(-50%, 0) scale(1); }
.shop-toast.is-leaving {
    opacity: 0;
    transform: translate(-50%, -85vh) scale(1);
    transition: opacity 4s ease-in, transform 4s ease-out;
}
@media (min-width: 768px) {
    .shop-toast { padding: 0.85rem 1.3rem; font-size: 0.95rem; gap: 0.5rem; }
}

.field { margin-bottom: 0.9rem; }
.field label { display: block; font-size: 0.85rem; color: var(--text-secondary); margin-bottom: 0.35rem; }
.field input,
.field select {
    width: 100%;
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text);
    border-radius: var(--radius);
    padding: 0.7rem 0.8rem;
    font-family: var(--font);
    font-size: 0.95rem;
}
.field input:invalid,
.field select:invalid { border-color: var(--accent); }
.btn--lg { padding: 1.05rem 1.5rem; font-size: 1.05rem; }
.btn--whatsapp-brand { background: #25d366; color: #fff; }
.btn--whatsapp-brand:hover { background: #1ebe5a; }

/* ---------- Waitlist modal ---------- */

.modal-overlay {
    position: fixed; inset: 0;
    background: rgba(0, 0, 0, 0.6);
    display: none;
    align-items: flex-end;
    justify-content: center;
    z-index: 200;
}
.modal-overlay.open { display: flex; }
.modal {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius) var(--radius) 0 0;
    padding: 1.5rem 1.25rem;
    width: 100%;
    max-width: 480px;
    max-height: 90vh;
    overflow-y: auto;
}
.modal__header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem; }
.modal__close { background: none; border: none; color: var(--text-secondary); font-size: 1.4rem; cursor: pointer; }
.modal .field { margin-bottom: 0.9rem; }
.modal label { display: block; font-size: 0.85rem; color: var(--text-secondary); margin-bottom: 0.35rem; }
.modal input {
    width: 100%;
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text);
    border-radius: var(--radius);
    padding: 0.7rem 0.8rem;
    font-family: var(--font);
}

/* ---------- Desktop (>= 768px) ---------- */

@media (min-width: 768px) {
    :root { --header-h: 68px; }

    .product-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .sold-grid { grid-template-columns: repeat(6, 1fr); }
    .collection-grid { grid-template-columns: repeat(4, 1fr); }

    .site-header__nav { display: flex; align-items: center; gap: 0.75rem; }
    .site-header__search { display: block; }
    .site-header .search-toggle { display: none; }
    .mobile-quicknav { display: none; }

    /* Hero/promos/chips: version completa -- la compactacion de arriba es
       solo para que el mobile no pierda toda la pantalla inicial en chrome,
       aqui sobra espacio y las convenciones son otras. */
    .hero { display: block; padding: 1.5rem 0 1rem; text-align: center; }
    .hero__logo { width: 88px; height: 88px; border-radius: 50%; object-fit: cover; object-position: center top; margin: 0 auto 0.75rem; }
    .hero h1 { font-size: 1.5rem; margin-bottom: 0.5rem; }
    .hero .tagline { display: block; font-size: 0.95rem; }
    .launch-promo, .raffle-promo { font-size: 0.9rem; padding: 0.6rem 1rem; margin: 0 0 1rem; }
    .home-chips { display: flex; }
    /* .search-bar sigue oculto en desktop -- redundante con el buscador
       inline del header (.site-header__search), siempre visible ahi. */
    /* Carrito: el usuario pidio mantener ambos pese a duplicar -- el icono
       del header es poco visible en desktop, el flotante refuerza el acceso. */
    .header-cart { display: inline-flex; }

    .catalog-layout { flex-direction: row; align-items: flex-start; }
    .filters-toggle { display: none; }
    /* B4: los filtros se aplican solos al cambiar (on-change) -- el boton
       submit solo tiene sentido como fallback en el drawer mobile. */
    .filters-submit { display: none; }
    .filters-drawer {
        position: static;
        display: block;
        background: transparent;
        padding: 0;
        width: 240px;
        flex-shrink: 0;
    }
    .filters-drawer__header { display: none; }
    .catalog-results { flex: 1; min-width: 0; }

    .gallery-and-body { display: flex; gap: 2rem; align-items: flex-start; }
    .gallery { width: 420px; flex-shrink: 0; }
    .detail-body { flex: 1; padding-top: 0; }
    .btn--cta { width: auto; min-width: 280px; }

    .gallery__main { overflow: hidden; }
    .gallery__main img { display: none; }
    .gallery__main img.is-active { display: block; }
    .gallery__thumbs { display: flex; }
    .gallery__dots { display: none; }
    .gallery__arrow { display: flex; }

    .cart-layout { flex-direction: row; align-items: flex-start; }
    .cart-items { flex: 1; }
    .cart-summary { width: 380px; flex-shrink: 0; position: sticky; top: calc(var(--header-h) + 1rem); }

    .modal-overlay { align-items: center; }
    .modal { border-radius: var(--radius); }
}

@media (min-width: 1024px) {
    .product-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
