/* ============================================================
   GLOBI · firma de movimiento "asiento-de-carga"
   Partitura: _motion-brief.md

   Acá nada flota: los elementos bajan, apoyan y se asientan, como una
   máquina de 20 toneladas cuando la bajan del camión. Entrada rápida,
   salida lenta — al revés se siente liviano.

   Sin dependencias: transform + opacity, nada más. El estado BASE es el
   estado FINAL; la animación es la excepción que aplica el driver. Por eso
   sin JavaScript, o con reduced-motion, el sitio queda exactamente como está.
   ============================================================ */

:root {
  --fx-carga:     cubic-bezier(.16, 1.02, .30, 1);
  --fx-rebote:    cubic-bezier(.34, 1.28, .64, 1);
  --fx-dur-corta: .34s;
  --fx-dur-media: .62s;
  --fx-dur-larga: .9s;
  --fx-caida:     18px;
  --fx-stagger:   70ms;
}

/* En móvil la caída se acorta: 18px en una pantalla de 390 se lee como un salto. */
@media (max-width: 700px) {
  :root { --fx-caida: 10px; --fx-dur-media: .48s; --fx-dur-larga: .66s; }
}

/* ---------- asentamiento base ---------- */
/* html.fx es el interruptor: lo pone el driver sólo si va a animar de verdad.
   Sin él (sin JS, o con reduced-motion) no se oculta nada nunca. */
.fx [data-fx~="asiento"], .fx [data-fx~="reveal-up"] {
  opacity: 0;
  transform: translate3d(0, calc(var(--fx-caida) * -1), 0);
  transition: opacity var(--fx-dur-media) var(--fx-carga),
              transform var(--fx-dur-media) var(--fx-carga);
  will-change: transform, opacity;
}
.fx [data-fx~="asiento"].fx-vis {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* ---------- el peso: micro-compresión al apoyar ---------- */
/* El elemento no sólo llega: al tocar, se aplasta un pelo y se recupera. Es lo
   que separa "asentar" de "aparecer". */
.fx [data-fx~="peso"].fx-vis { animation: fx-apoyo var(--fx-dur-media) var(--fx-rebote) both; }
@keyframes fx-apoyo {
  0%   { transform: translate3d(0, calc(var(--fx-caida) * -1), 0) scaleY(1); }
  62%  { transform: translate3d(0, 0, 0) scaleY(.985); }
  100% { transform: none; }
}

/* ---------- filete que se comprime bajo la carga (set-piece del hero) ---------- */
.fx [data-fx~="apoyo"] { position: relative; }
.fx [data-fx~="apoyo"]::after {
  content: "";
  position: absolute; left: 6%; right: 6%; bottom: -10px; height: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: 50% 50%;
  opacity: .9;
  transition: transform var(--fx-dur-larga) var(--fx-carga);
}
.fx [data-fx~="apoyo"].fx-vis::after { transform: scaleX(1); }

/* ---------- stagger: una pieza tras otra, nunca en bloque ---------- */
/* El retardo lo escribe el driver en --fx-i para no fijar un tope en el CSS. */
.fx [data-fx~="asiento"][style*="--fx-i"] { transition-delay: calc(var(--fx-i) * var(--fx-stagger)); }
.fx [data-fx~="peso"][style*="--fx-i"]    { animation-delay: calc(var(--fx-i) * var(--fx-stagger)); }

/* ---------- H1 por líneas ---------- */
.fx [data-fx~="titular"] .fx-linea {
  display: block;
  opacity: 0;
  transform: translate3d(0, calc(var(--fx-caida) * -1), 0);
  transition: opacity var(--fx-dur-media) var(--fx-carga),
              transform var(--fx-dur-media) var(--fx-carga);
}
.fx [data-fx~="titular"].fx-vis .fx-linea { opacity: 1; transform: none; }
.fx [data-fx~="titular"].fx-vis .fx-linea:nth-child(2) { transition-delay: 90ms; }
.fx [data-fx~="titular"].fx-vis .fx-linea:nth-child(3) { transition-delay: 180ms; }

/* ---------- filas de tabla: la ficha se llena ---------- */
.fx [data-fx~="filas"] tbody tr {
  opacity: 0;
  transform: translate3d(0, -8px, 0);
  transition: opacity var(--fx-dur-corta) var(--fx-carga),
              transform var(--fx-dur-corta) var(--fx-carga);
}
.fx [data-fx~="filas"].fx-vis tbody tr { opacity: 1; transform: none; }
.fx [data-fx~="filas"].fx-vis tbody tr:nth-child(n+2)  { transition-delay: 55ms; }
.fx [data-fx~="filas"].fx-vis tbody tr:nth-child(n+3)  { transition-delay: 110ms; }
.fx [data-fx~="filas"].fx-vis tbody tr:nth-child(n+4)  { transition-delay: 165ms; }
.fx [data-fx~="filas"].fx-vis tbody tr:nth-child(n+5)  { transition-delay: 220ms; }
.fx [data-fx~="filas"].fx-vis tbody tr:nth-child(n+6)  { transition-delay: 275ms; }
.fx [data-fx~="filas"].fx-vis tbody tr:nth-child(n+7)  { transition-delay: 330ms; }
.fx [data-fx~="filas"].fx-vis tbody tr:nth-child(n+8)  { transition-delay: 385ms; }
.fx [data-fx~="filas"].fx-vis tbody tr:nth-child(n+9)  { transition-delay: 440ms; }

/* ---------- cifras: la balanza encuentra el equilibrio ---------- */
.fx [data-fx~="balanza"] { font-variant-numeric: tabular-nums; }

/* ---------- respeto duro por quien pide menos movimiento ---------- */
@media (prefers-reduced-motion: reduce) {
  .fx [data-fx],
  .fx [data-fx~="titular"] .fx-linea,
  .fx [data-fx~="filas"] tbody tr {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    animation: none !important;
  }
  .fx [data-fx~="apoyo"]::after { transform: scaleX(1) !important; transition: none !important; }
}

/* Palabra suelta durante la medición de líneas: no debe alterar el layout. */
.fx-w { font-style: inherit; }
