/* ============================================================
   MI ROPERITO — CAPA "PREMIUM"
   Pantalla de carga + animaciones de entrada (GSAP).

   REGLA DE ORO de este archivo: si el JavaScript no corre (bloqueado,
   error, navegador viejo), el sitio tiene que verse EXACTAMENTE igual que
   antes. Por eso nada se oculta desde el CSS "a secas": todo lo que se
   anima se esconde solo cuando <html> lleva la clase .gsap-listo, que la
   pone premium.js justo antes de animar. Sin JS, esa clase nunca llega y
   no se oculta nada.
   ============================================================ */

/* ---------- Pantalla de carga ---------- */
/* El velo se pinta desde el HTML (antes de que corra ningún script) para
   que no se alcance a ver el sitio a medio armar. */
.preloader {
  position: fixed; inset: 0; z-index: 9999;
  display: grid; place-items: center;
  background: var(--white);
  transition: opacity .55s ease, visibility .55s ease;
}
.preloader__in { display: grid; justify-items: center; gap: 22px; }
.preloader__logo {
  width: min(210px, 52vw); height: auto; display: block;
  animation: preLatido 1.8s ease-in-out infinite;
}
.preloader__bar {
  width: min(190px, 46vw); height: 3px; border-radius: 999px;
  background: var(--line); overflow: hidden;
}
.preloader__bar i {
  display: block; width: 100%; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--rosa-l), var(--marca));
  transform: scaleX(0); transform-origin: left;
  animation: preCarga 2s cubic-bezier(.4, 0, .2, 1) forwards;
}
@keyframes preLatido {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%      { transform: scale(1.045); opacity: .88; }
}
@keyframes preCarga {
  0%   { transform: scaleX(0); }
  62%  { transform: scaleX(.72); }
  100% { transform: scaleX(1); }
}
/* Al terminar: se desvanece y deja de estorbar */
.preloader.is-gone { opacity: 0; visibility: hidden; pointer-events: none; }

/* Mientras carga no se puede hacer scroll (si no, se ve el salto al final) */
html.is-cargando, html.is-cargando body { overflow: hidden; height: 100%; }

/* Red de seguridad: si premium.js no llega a correr (bloqueado por la CSP,
   error de red…), el velo se va solo a los 3s y el sitio queda usable. */
@media (scripting: none) {
  .preloader { display: none; }
}

/* Cinturón de seguridad contra el scroll horizontal: si alguna animación
   se sale por un costado, se recorta en vez de ensanchar la página. Se usa
   "clip" y no "hidden" porque hidden convierte a <html> en contenedor de
   scroll y eso rompe el position:sticky del encabezado. */
html { overflow-x: clip; }

/* ---------- Esqueletos mientras carga el catálogo ----------
   El catálogo llega de Supabase medio segundo después que la página. Sin
   esto, la rejilla pasa de un renglón de texto ("Cargando productos…") a
   veinte tarjetas de golpe: la página se estira y todo lo de abajo pega un
   brinco. Estas piezas ocupan de antemano el lugar que van a tener las
   tarjetas, así que cuando llegan no se mueve nada. */
.sk {
  border-radius: var(--r-s, 16px);
  background: linear-gradient(100deg, var(--blush-2, #FDF5F8) 30%, var(--blush, #FCE7EF) 50%, var(--blush-2, #FDF5F8) 70%);
  background-size: 220% 100%;
  animation: skBrillo 1.5s ease-in-out infinite;
}
.sk--card { aspect-ratio: 3 / 4; width: 100%; }
.sk--cat  { aspect-ratio: 1 / 1; width: 100%; }
/* Ficha de producto: foto grande + renglones de texto */
.sk--ficha { aspect-ratio: 4 / 5; width: 100%; border-radius: var(--r, 26px); }
.sk-info { display: flex; flex-direction: column; gap: 14px; padding-top: 6px; }
.sk--linea { height: 18px; border-radius: 999px; }
.sk--boton { height: 48px; width: 190px; border-radius: 999px; margin-top: 10px; }
@keyframes skBrillo {
  from { background-position: 180% 0; }
  to   { background-position: -60% 0; }
}
@media (prefers-reduced-motion: reduce) { .sk { animation: none; } }

/* ============================================================
   OJO — ESTO ES LO QUE HACÍA QUE NO SE VIERA NINGÚN EFECTO
   El sitio ya traía su propio sistema de entrada en CSS:
       .rv { animation: rise .6s ... both; }
   que store.js le pone a cada tarjeta al pintarla. Una animación de CSS
   se aplica en un origen que GANA sobre los estilos en línea, así que el
   opacity:0 y el transform que escribía GSAP no servían de nada: la
   tarjeta se quedaba puesta y la animación de scroll era invisible.
   Además esa animación de 0.6s corría al insertar la tarjeta, o sea
   detrás de la pantalla de carga, donde nadie la veía.
   Con GSAP activo se apaga y manda GSAP. Sin JavaScript, .rv sigue
   funcionando igual que siempre.
   ============================================================ */
html.gsap-listo .rv { animation: none !important; }

/* ---------- Estados iniciales de lo que se anima ----------
   OJO: solo aplican con .gsap-listo. Ver la nota de arriba. */
.gsap-listo [data-anim] { opacity: 0; will-change: transform, opacity; }
/* Ya animado: se le quita el will-change para no gastar memoria de GPU
   (en celulares con muchas tarjetas se nota). */
[data-anim].anim-fin { will-change: auto; }

/* Los títulos partidos en letras necesitan que cada trozo pueda moverse
   sin arrastrar el renglón de al lado. */
.split-linea { display: block; overflow: hidden; }
.split-char, .split-word { display: inline-block; will-change: transform; }

/* ---------- Scroll suave (solo en escritorio) ----------
   ScrollSmoother mueve el contenido con transform, y dentro de un elemento
   transformado el position:sticky del encabezado deja de funcionar. Por eso
   cuando el scroll suave está activo el encabezado pasa a fijo y el
   contenido recibe el hueco equivalente. En celular NO se activa nada de
   esto: ahí manda el scroll nativo del sistema, que es el que se siente
   bien y el que no da brincos en iPhone. */
#smooth-wrapper { overflow: hidden; }
html.tiene-smooth .hd { position: fixed; top: 0; left: 0; right: 0; }
html.tiene-smooth .announcement { position: fixed; top: 0; left: 0; right: 0; z-index: 61; }
html.tiene-smooth { scroll-behavior: auto; }

/* ============================================================
   ENCABEZADO SOBRE LA PORTADA
   Antes había una barra blanca entre el aviso y la foto, y la foto empezaba
   debajo. Ahora la foto sube hasta arriba y el encabezado va ENCIMA, sin
   fondo. Al scrollear recupera el fondo blanco para que se siga leyendo.
   Solo pasa donde hay portada (.hero), o sea el inicio.
   ============================================================ */
:root { --hd-h: 66px; }   /* premium.js lo mide y lo corrige */

body:has(.hero) .hd {
  background: transparent; backdrop-filter: none; border-bottom-color: transparent;
  transition: background .35s ease, border-color .35s ease, backdrop-filter .35s ease;
}
/* La portada sube y se mete debajo del encabezado */
body:has(.hero) .hero { margin-top: calc(-1 * var(--hd-h)); }
/* …y su contenido baja lo mismo, para no quedar tapado */
body:has(.hero) .hero__in { padding-top: var(--hd-h); }

/* Al bajar, el encabezado recupera fondo */
body:has(.hero) .hd.is-solid {
  background: rgba(255, 255, 255, .92);
  backdrop-filter: saturate(140%) blur(10px);
  border-bottom-color: var(--line);
}

/* Navegadores sin :has() (Firefox viejo): se queda como estaba, con la barra
   blanca. Es una diferencia estética, no un error. */

/* ---------- Botón "ver todo" bajo la muestra del catálogo ---------- */
.grid-more { display: flex; justify-content: center; margin-top: clamp(18px, 3vw, 30px); }

/* ---------- Barra de progreso de lectura ---------- */
.lee-progreso {
  position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 62;
  pointer-events: none;
}
.lee-progreso i {
  display: block; height: 100%; width: 100%; transform: scaleX(0); transform-origin: left;
  background: linear-gradient(90deg, var(--rosa-l), var(--marca));
}

/* Con el aviso de arriba, la barra va debajo de él para que no lo tape */
html.tiene-smooth .lee-progreso { top: 0; }

/* ---------- Detalles premium que no dependen de GSAP ---------- */
/* Las tarjetas de producto responden al puntero con un realce suave. Solo
   en dispositivos con ratón: en táctil un :hover se queda "pegado". */
@media (hover: hover) and (pointer: fine) {
  .card, .cats > *, .perk {
    transition: transform .45s cubic-bezier(.2, .7, .3, 1), box-shadow .45s;
  }
  .card:hover, .cats > *:hover { transform: translateY(-6px); }
  .perk:hover { transform: translateY(-3px); }
}

/* Respeto a quien pidió menos movimiento en su sistema operativo */
@media (prefers-reduced-motion: reduce) {
  .gsap-listo [data-anim] { opacity: 1 !important; transform: none !important; }
  .preloader__logo, .preloader__bar i { animation: none; }
  .preloader__bar i { transform: scaleX(1); }
}
