/* ===========================================================================
   motion.css — movimiento de tienda que lee tokens. Aquí NO hay valores de
   marca: la personalidad sale de <html data-movimiento="…"> y de marca.css.

   Reglas (referencias/motion.md):
   · Todo dentro de prefers-reduced-motion: no-preference.
   · Solo transform/translate/scale/rotate y opacity.
   · El contenido nunca nace en opacity 0: el revelado parte de 0.65.
   · Revelado con propiedades individuales (translate) para que el hover, que
     usa transform, no choque con el fill del revelado.
   =========================================================================== */

/* --- Personalidades. :where() = especificidad 0 → marca.css siempre gana. -- */
:where(:root) { /* calida = por omisión  [Hilos y Encanto] */
  --mov-dur-corta: 140ms;
  --mov-dur-hover: 540ms;
  --mov-dur-larga: 520ms;
  --mov-ease-salida: cubic-bezier(.22, 1, .36, 1);
  --mov-ease-resorte: cubic-bezier(.34, 1.56, .64, 1);
  --mov-hover-y: -5px;
  --mov-hover-escala: 1.055;
  --mov-revelar-y: 16px;
  --mov-revelar-opacidad: .65;
  --mov-escalon: 34ms;
  --mov-hero-dur: 28s;
  --mov-hero-escala: 1.06;
  /* Aprendido de los reels (31-oct-2026) */
  --mov-ease-entrada: cubic-bezier(.4, 0, 1, 1);     /* salidas: aceleran y se van */
  --mov-ease-enmedio: cubic-bezier(.65, 0, .35, 1);  /* huecos que se abren en listas */
  --mov-dur-cajon: 420ms;                            /* entra despacio… */
  --mov-dur-cajon-sale: 220ms;                       /* …y sale rápido: asimetría */
  --mov-dur-indicador: 360ms;
  --mov-escalon-pasos: 80ms;
  --mov-enfoque: 0px;                                /* >0 = aparece enfocando, sin viajar */
}
:where(:root[data-movimiento="artesanal"]) { /* objetos con masa  [Ta'Pikín] */
  --mov-dur-hover: 180ms;
  --mov-dur-larga: 500ms;
  --mov-hover-y: -2px;
  --mov-hover-escala: 1.03;
  --mov-revelar-y: 14px;
}
:where(:root[data-movimiento="editorial"]) { /* lento y escaso  [García] */
  --mov-dur-hover: 900ms;
  --mov-ease-salida: cubic-bezier(.2, .75, .2, 1);
  --mov-hover-y: 0px;
  --mov-hover-escala: 1.045;
  --mov-revelar-y: 0px;
  --mov-revelar-opacidad: 1;           /* sin revelado: la página ya está ahí */
  --mov-hero-dur: 22s;
  --mov-hero-escala: 1.025;
}
:where(:root[data-movimiento="festiva"]) { /* flyer  [Vamos a la Playa] */
  --mov-dur-hover: 240ms;
  --mov-ease-salida: cubic-bezier(.2, .9, .3, 1.3);
  --mov-hover-y: -4px;
  --mov-hover-escala: 1.04;
  --mov-revelar-y: 20px;
}
:where(:root[data-movimiento="hospitalidad"]) { /* calma  [Hotel Plaza, propuesta] */
  --mov-dur-hover: 400ms;
  --mov-dur-larga: 800ms;
  --mov-ease-salida: cubic-bezier(.16, 1, .3, 1);
  --mov-hover-y: 0px;
  --mov-hover-escala: 1.03;
  --mov-revelar-y: 24px;
  --mov-revelar-opacidad: 1;           /* solo desplazamiento, como el hotel */
  --mov-hero-escala: 1.04;
  --mov-enfoque: 6px;
}
:where(:root[data-movimiento="sobria"]) { /* confianza clínica  [check-in de Transom] */
  --mov-enfoque: 6px;                  /* las cosas enfocan en su lugar, nada rebota */
  --mov-dur-hover: 150ms;
  --mov-ease-resorte: var(--mov-ease-salida);  /* nada rebota */
  --mov-hover-y: 0px;
  --mov-hover-escala: 1;
  --mov-revelar-y: 0px;
  --mov-revelar-opacidad: 1;
  --mov-hero-escala: 1;
}

/* --- Formas estáticas (valen con o sin movimiento) ---------------------- */
.barra-envio { overflow: hidden; border-radius: 999px; background: var(--color-linea); height: 6px; }
.barra-envio > span {
  display: block; height: 100%; background: var(--color-exito);
  transform-origin: left center;
  transform: scaleX(var(--progreso, 0));   /* JS pone --progreso entre 0 y 1 */
}
.cajon-carrito { translate: 100% 0; visibility: hidden; }
.cajon-carrito.abierto { translate: 0 0; visibility: visible; }
/* Velo detrás del cajón: oscurece, NO desenfoca (backdrop-filter tira cuadros). */
.velo { position: fixed; inset: 0; background: rgb(15 23 42 / .3); opacity: 0; visibility: hidden; }
.velo.abierto { opacity: 1; visibility: visible; }

/* Cifras de ancho fijo: no bailan mientras cuentan. */
[data-contar], [data-tablero], [data-cifra], [data-pasos-cuenta] { font-variant-numeric: tabular-nums; }
[data-tablero] > span { display: inline-block; }

/* Segmentos / pestañas con indicador. Sin JS, el activo se pinta solo. */
[data-segmentos] { position: relative; isolation: isolate; }
[data-segmentos] > .indicador {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: var(--color-cta);
  clip-path: inset(0 100% 0 0 round 999px);
}
[data-segmentos] :is([aria-selected="true"], [aria-current="page"], [aria-current="true"], [aria-pressed="true"], [aria-checked="true"]) {
  background: var(--color-cta); color: var(--color-sobre-cta); border-radius: 999px;
}
[data-segmentos].con-indicador :is([aria-selected="true"], [aria-current="page"], [aria-current="true"], [aria-pressed="true"], [aria-checked="true"]) {
  background: transparent;
}

/* Barra de pasos: un <span> por paso; el CSS es el estado final. */
.barra-pasos { display: flex; gap: 4px; }
.barra-pasos > span { flex: 1; height: 6px; border-radius: 999px; background: var(--color-linea); }
.barra-pasos > span.lleno { background: var(--color-exito); }
[data-paso="falta"] { border: 1.5px solid var(--color-cta); border-radius: var(--radio-tarjeta, 12px); }

/* Comprobante tipo ticket. Sin JS ni movimiento: ya impreso y sellado. */
.ticket-ventana { overflow: clip; }
.ticket {
  --diente: 16px;
  position: relative;
  font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, monospace);
  background: var(--color-papel, #fbf8f1); color: var(--color-tinta-ticket, #1d1d1b);
  padding: 1rem 1rem calc(1rem + var(--diente) / 2);
  /* Borde dentado abajo: máscara estática, no se redibuja al moverse. */
  -webkit-mask:
    linear-gradient(#000 0 0) top / 100% calc(100% - var(--diente) / 2) no-repeat,
    conic-gradient(from -45deg at 50% 100%, #000 90deg, #0000 0) bottom / var(--diente) calc(var(--diente) / 2) repeat-x;
          mask:
    linear-gradient(#000 0 0) top / 100% calc(100% - var(--diente) / 2) no-repeat,
    conic-gradient(from -45deg at 50% 100%, #000 90deg, #0000 0) bottom / var(--diente) calc(var(--diente) / 2) repeat-x;
}
.ticket hr { border: 0; border-top: 1px dashed currentColor; opacity: .35; }
.ticket hr.total { border-top-style: solid; opacity: 1; }
.sello {
  position: absolute; rotate: var(--giro-sello, -12deg);
  padding: .3em .8em; border: 3px double currentColor; border-radius: 8px;
  color: var(--color-sello, var(--color-cta));
  font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  mix-blend-mode: multiply; pointer-events: none;
}
/* El sello dice la verdad: Recibido (pedido tomado) → Pagado (servidor confirmó con Mercado Pago). */
.sello[data-tono="recibido"] { color: var(--color-sello-recibido, var(--color-apagado, #6b6b6b)); }
.sello[data-tono="pagado"] { color: var(--color-sello-pagado, var(--color-exito)); }

/* SVG que se dibuja (palomita, ruta de un tour): <path pathLength="1" class="trazo">.
   Con dasharray 1 y offset 0 el trazo está COMPLETO: es el estado de reposo. */
.trazo { stroke-dasharray: 1; stroke-dashoffset: 0; }

/* --- Todo el movimiento ------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {

  /* Revelado, nivel 1: CSS nativo (corre en el compositor, cero JS). */
  @supports (animation-timeline: view()) {
    .revelar {
      animation: mov-revelar linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 100%;  /* NO «cover 24%»: deja a medias lo último de una página corta */
    }
  }
  /* Revelado, nivel 2: motion.js pone html.js-revelar solo si no hay view(),
     y antes ya marcó .es-visible a lo que está arriba del pliegue. */
  @supports not (animation-timeline: view()) {
    html.js-revelar .revelar {
      transition:
        opacity var(--mov-dur-larga) var(--mov-ease-salida),
        translate var(--mov-dur-larga) var(--mov-ease-salida);
      transition-delay: calc(min(var(--i, 0), 11) * var(--mov-escalon));
    }
    html.js-revelar .revelar:not(.es-visible) {
      opacity: var(--mov-revelar-opacidad);
      translate: 0 var(--mov-revelar-y);
    }
  }

  /* Hover de tarjeta: solo con puntero real (en el teléfono el hover se queda pegado). */
  @media (hover: hover) {
    .tarjeta-producto .tarjeta-foto img {
      transition: transform var(--mov-dur-hover) var(--mov-ease-salida);
    }
    .tarjeta-producto:hover .tarjeta-foto img,
    .tarjeta-producto:focus-visible .tarjeta-foto img {
      transform: translateY(var(--mov-hover-y)) scale(var(--mov-hover-escala));
    }
  }

  /* Hero sin video: respira (Ken Burns). */
  .hero-respira {
    animation: mov-respira var(--mov-hero-dur) ease-in-out infinite alternate;
  }
  @media (max-width: 720px) {
    :root[data-movimiento="editorial"] .hero-respira { animation: none; }
  }

  /* Festiva: la cinta «se pega» y aterriza en su propio giro (--giro). */
  .pegar {
    rotate: var(--giro, -2deg);
    animation: mov-pegar 700ms var(--mov-ease-salida) both;
  }

  .barra-envio > span { transition: transform var(--mov-dur-larga) var(--mov-ease-salida); }

  /* Cajón: entra en 420 ms frenando, sale en 220 ms acelerando [Transom]. */
  .cajon-carrito, .velo {
    transition:
      translate var(--mov-dur-cajon-sale) var(--mov-ease-entrada),
      opacity var(--mov-dur-cajon-sale) var(--mov-ease-entrada),
      visibility 0s linear var(--mov-dur-cajon-sale);   /* se oculta al terminar de salir */
  }
  .cajon-carrito.abierto, .velo.abierto {
    transition:
      translate var(--mov-dur-cajon) var(--mov-ease-salida),
      opacity var(--mov-dur-cajon) var(--mov-ease-salida),
      visibility 0s;
  }

  [data-segmentos] :is(button, a, [role=tab], [role=radio]) {
    transition: color var(--mov-dur-indicador) var(--mov-ease-salida);
  }

  /* Trazo al hacer scroll (ruta de un tour) o al cargar (.al-cargar: la palomita). */
  @supports (animation-timeline: view()) {
    .trazo:not(.al-cargar) {
      animation: mov-trazo linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 100%;
    }
  }
  .trazo.al-cargar { animation: mov-trazo 300ms var(--mov-ease-salida) both; }

  /* Skeleton: la franja se desplaza con transform, no con background-position. */
  .esqueleto { position: relative; overflow: hidden; background: var(--color-linea); }
  .esqueleto::after {
    content: ""; position: absolute; inset: 0;
    background: linear-gradient(90deg, transparent, rgb(255 255 255 / .45), transparent);
    translate: -100% 0;
    animation: mov-brillo 1.3s ease-in-out infinite;
  }

  /* Transiciones entre páginas del mismo sitio (estático, sin JS).
     APAGADA en Ta'Pikín (31-oct-2026): no estaba en lo aprobado y, en las
     pruebas, Chrome abortaba la transición de forma intermitente con
     «InvalidStateError: Transition was aborted because of invalid state» en
     consola. Las fichas además reciben motion.css por JS (tarde). Si se
     enciende algún día: @view-transition en styles.css (que sí está en el
     HTML de todas las páginas) y probar que la consola quede en cero.
  @view-transition { navigation: auto; } */
  /* En la tarjeta Y en la ficha, cada una única en su página:
     .ficha-foto, .tarjeta-foto.seleccionada { view-transition-name: producto-foto; } */
}

@keyframes mov-revelar {
  from { opacity: var(--mov-revelar-opacidad); translate: 0 var(--mov-revelar-y); }
}
@keyframes mov-respira {
  from { transform: scale(1); }
  to   { transform: scale(var(--mov-hero-escala)); }
}
@keyframes mov-pegar {
  from { scale: 1.18; rotate: -7deg; }
}
@keyframes mov-brillo {
  to { translate: 100% 0; }
}
@keyframes mov-trazo {
  from { stroke-dashoffset: 1; }
}

/* Impresión: todo visible, nada a medias. */
@media print {
  .revelar { animation: none !important; opacity: 1 !important; translate: none !important; }
}
