/* Ruiang Industrial — firma de movimiento `indice-vivo`
   El índice sabe dónde estás parado y se sintoniza solo.
   Todo scoped bajo .fx: sin la clase en <html> este archivo no hace nada.
   Partitura: ../_motion-brief.md */

.fx{
  --fx-dur-1: 100ms;   /* celda mono, hover, filete */
  --fx-dur-2: 260ms;   /* asiento de fila/ficha */
  --fx-dur-3: 420ms;   /* sintonía del riel (set-piece firma) */
  --fx-ease-out:      cubic-bezier(.23,1,.32,1);
  --fx-ease-out-expo: cubic-bezier(.16,1,.3,1);
  --fx-stagger: 40ms;
}

/* ---------- idx-seat: la fila asienta y su filete traba ---------- */
/* Estado base = estado final. Solo con .js (y sin reduced-motion) se prepara la entrada. */
.fx.js [data-fx="idx-seat"]:not(.is-seated){
  opacity:.001;
  transform:translateY(10px);
}
.fx [data-fx="idx-seat"]{
  transition:opacity var(--fx-dur-2) var(--fx-ease-out),
             transform var(--fx-dur-2) var(--fx-ease-out);
  transition-delay:var(--fx-seat-delay,0ms);
}
.fx [data-fx="idx-seat"].is-seated{opacity:1;transform:none}

/* el filete: una regla que traba de izquierda a derecha (scaleX, no un trazo SVG) */
.fx [data-fx="idx-seat"]{position:relative}
.fx [data-fx="idx-seat"]::after{
  content:"";
  position:absolute;
  left:0;
  bottom:-1px;
  width:100%;
  height:1px;
  background:var(--red);
  transform:scaleX(0);
  transform-origin:left center;
  transition:transform var(--fx-dur-2) var(--fx-ease-out);
  transition-delay:calc(var(--fx-seat-delay,0ms) + var(--fx-dur-1));
  pointer-events:none;
}
.fx [data-fx="idx-seat"].is-seated::after{transform:scaleX(1)}
/* Exit = 75% del enter. Se aplica al soltar el hover de una ficha, que es la única
   salida real que tiene este sitio: el asiento por scroll no se revierte (una ficha
   que ya asentó se queda). Sin esto, la regla de salida era letra muerta. */
.fx .cc[data-fx="idx-seat"]:not(:hover)::after{
  transition-duration:calc(var(--fx-dur-2) * .75);
}
/* en las fichas del catálogo el filete vive en el borde inferior de la tarjeta */
.fx .cc[data-fx="idx-seat"]::after{bottom:0}

/* ---------- idx-rule: solo el filete ---------- */
/* Para lo que el micro-motion BASE ya revela (.will-reveal → .is-revealed): la firma
   no vuelve a mover opacidad ni posición, únicamente traba su filete. Así el Animador
   se suma al Nivel 1 del Constructor en vez de pelearle. */
.fx [data-fx="idx-rule"]{position:relative}
.fx [data-fx="idx-rule"]::after{
  content:"";
  position:absolute;
  left:0;
  bottom:0;
  width:100%;
  height:1px;
  background:var(--red);
  transform:scaleX(0);
  transform-origin:left center;
  transition:transform var(--fx-dur-2) var(--fx-ease-out) var(--fx-dur-1);
  pointer-events:none;
}
.fx [data-fx="idx-rule"].is-revealed::after{transform:scaleX(1)}
/* sin JS (o con failsafe) el reveal base nunca llega: el filete se muestra igual */
html:not(.js) [data-fx="idx-rule"]::after,
.fx-off [data-fx="idx-rule"]::after{transform:scaleX(1)}

/* ---------- idx-rail: el riel de códigos ---------- */
.fx [data-fx="idx-rail"]{
  position:sticky;
  top:var(--fx-rail-top,0px);
  z-index:60;
  background:#fff;
  transition:box-shadow var(--fx-dur-2) var(--fx-ease-out);
}
.fx [data-fx="idx-rail"].is-pinned{box-shadow:0 10px 24px rgba(17,19,24,.07)}

/* chip del riel: sintonizado / atenuado.
   Es el set-piece de la firma, así que usa la duración amplia (--fx-dur-3) con la
   curva amplia: el riel "busca" la sintonía, no parpadea. El resalte del chip que
   entra sí es corto (--fx-dur-1), para que el foco llegue seco. */
.fx .refstrip__list span{
  transition:color var(--fx-dur-1) var(--fx-ease-out),
             border-color var(--fx-dur-1) var(--fx-ease-out),
             background-color var(--fx-dur-1) var(--fx-ease-out),
             opacity var(--fx-dur-3) var(--fx-ease-out-expo);
}
/* la sintonía existe solo en desktop: en táctil el riel no se toca (ver partitura §e) */
@media (min-width:769px){
  .fx .refstrip.is-tuned .refstrip__list span{opacity:.34}
  .fx .refstrip.is-tuned .refstrip__list span.is-tuned{
    opacity:1;
    color:var(--carbon);
    border-color:var(--red);
    background:var(--red-soft);
  }
}
/* la etiqueta del riel canta el sistema sintonizado */
.fx .refstrip__lbl [data-fx-tuned]{color:var(--red)}

/* celda mono: el glifo cambia con el clic seco de un contador mecánico (sin rebote) */
.fx .fx-cell{display:inline-block;will-change:transform,opacity}
.fx .fx-cell.is-flipping{
  animation:fx-cell-flip var(--fx-dur-1) var(--fx-ease-out) both;
}
@keyframes fx-cell-flip{
  0%  {transform:translateY(0);      opacity:1}
  49% {transform:translateY(-0.55em);opacity:0}
  50% {transform:translateY(0.55em); opacity:0}
  100%{transform:translateY(0);      opacity:1}
}

/* ---------- índice del catálogo: marca la familia en vista ---------- */
.fx .ix__f,.fx .ix__h{
  transition:color var(--fx-dur-1) var(--fx-ease-out),
             background-color var(--fx-dur-1) var(--fx-ease-out);
}
.fx .ix__f.is-current{color:var(--carbon);background:var(--red-soft)}
.fx .ix__f.is-current b{color:var(--red)}
.fx .ix__h.is-current .ix__n{color:var(--red)}

/* ---------- progress: el filete 01→04 de los cuatro puntos ---------- */
.fx [data-fx="idx-progress"]{position:relative}
.fx [data-fx="idx-progress"]::before{
  content:"";
  position:absolute;
  left:0;
  top:-1px;
  height:2px;
  width:100%;
  transform:scaleX(var(--fx-progress,0));
  transform-origin:left center;
  background:var(--red);
  transition:transform var(--fx-dur-1) linear;
  pointer-events:none;
}

/* ---------- degradación: la ley manda ---------- */
@media (prefers-reduced-motion: reduce){
  .fx [data-fx="idx-seat"],
  .fx.js [data-fx="idx-seat"]:not(.is-seated){opacity:1;transform:none;transition:none}
  .fx [data-fx="idx-seat"]::after,
  .fx [data-fx="idx-rule"]::after{transform:scaleX(1);transition:none}
  .fx .refstrip.is-tuned .refstrip__list span{opacity:1}
  .fx .fx-cell.is-flipping{animation:none}
  .fx [data-fx="idx-progress"]::before{transform:scaleX(1)}
  .fx [data-fx="idx-rail"]{position:static}
}

/* móvil: el riel no se sintoniza (los estilos de sintonía ni siquiera se declaran acá)
   y el escalonado se acorta: la lista completa de códigos queda visible y quieta */
@media (max-width:768px){
  .fx [data-fx="idx-rail"]{position:static;box-shadow:none}
  .fx [data-fx="idx-seat"]{transition-delay:calc(var(--fx-seat-delay,0ms) * .75)}
}

/* sin JS o con el failsafe activo: todo visible, nada preparado.
   Cubre también los reveal/stagger del driver canónico: si su JS no llega a marcar
   `.in`, el contenido tiene que verse igual (estado base = estado final). */
.fx-off [data-fx="idx-seat"],
html:not(.js) [data-fx="idx-seat"],
.fx-off [data-fx^="reveal"],
.fx-off [data-fx="stagger"],
.fx-off [data-fx="stagger"]>*,
.fx-off [data-fx^="text-"]{opacity:1!important;transform:none!important;filter:none!important;clip-path:none!important}
.fx-off [data-fx="idx-seat"]::after{transform:scaleX(1)}
