/* ============================================================================
   fx/firma-summit.css · firma "cableado" (partitura: _motion-brief.md)
   Seis cordones sueltos se cierran y se tuercen en un solo cable que termina
   en la etiqueta de carga. Acero y tinta; el oro solo en la etiqueta y su atadura.
   - La escena .cab es HTML decorativo (aria-hidden) que inyecta _build/fxwire.py
     YA ARMADA: su maquetación no cuelga de .fx para que sin JS se vea el cable.
   - Todo pre-estado cuelga de .fx-live (lo pone fx/firma-summit.js). Sin JS, con la
     firma caída o con reduced-motion no hay pre-estado: estado base = estado final.
   - No toca el driver canónico (efectos.css/js).
   ========================================================================== */
.fx{
  --fx-dur-1:120ms;
  --fx-dur-2:260ms;
  --fx-dur-3:520ms;
  --fx-dur-exit:195ms;                          /* 75 % de --fx-dur-2 */
  --fx-ease-out:cubic-bezier(.23,1,.32,1);
  --fx-ease-out-expo:cubic-bezier(.16,1,.3,1);
  --fx-stagger:60ms;
}

/* ---------------------------------------------------------------------------
   1 · cableado — la escena (maquetación sin .fx: se ve igual sin JS)
   ------------------------------------------------------------------------- */
.cab{margin:0 0 var(--s7);position:relative}
.cab--caps{margin:var(--s5) 0 var(--s5)}
.cab__v{position:relative}
/* la variante compacta está dibujada para ~340-540 px: más ancha se ve tosca (el paso del trazado se nota) */
.cab__v--c{max-width:34rem}
.cab__stage{position:relative;aspect-ratio:var(--cab-ar)}
.cab__svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible;display:block}
.cab__back path{fill:var(--ink-mute);opacity:.5}
.cab__front path{fill:var(--brand-2)}
.cab__nodes circle{fill:var(--surface);stroke:var(--brand-2);stroke-width:1.5;vector-effect:non-scaling-stroke}
.cab__ferr{fill:var(--brand-1)}
.cab__tie{fill:none;stroke:var(--brand-4);stroke-width:1.5;vector-effect:non-scaling-stroke}

.cab__fams{list-style:none;margin:0;padding:0;position:absolute;inset:0;pointer-events:none}
.cab__fams li{position:absolute;left:0;display:flex;align-items:baseline;justify-content:flex-end;gap:.55rem;
  transform:translateY(-50%);white-space:nowrap;font-size:.84rem;line-height:1.2;color:var(--ink-soft)}
.cab__v--a .cab__fams li{width:calc(222 / 1200 * 100%)}
.cab__v--c .cab__fams li{width:calc(34 / 600 * 100%)}
.cab__fams b{font-family:var(--font-mono);font-size:.68rem;font-weight:500;letter-spacing:.06em;color:var(--accent-deep)}

/* la etiqueta: misma pieza que la del subhero (ojal, esquina cortada) */
.cab__tag{margin:0;max-width:none;font-family:var(--font-mono);background:var(--brand-1);
  border:1px solid rgba(198,161,91,.4);clip-path:polygon(0 0,calc(100% - 12px) 0,100% 12px,100% 100%,0 100%);
  position:relative;width:min(15rem,100%)}
.cab__tag::before{content:"";position:absolute;top:.8rem;right:1.1rem;width:9px;height:9px;border-radius:50%;
  border:1px solid rgba(198,161,91,.7);background:var(--brand-1)}
.cab__tag-hd{display:block;padding:.6rem 2.6rem .6rem 1rem;border-bottom:1px dashed rgba(198,161,91,.3);
  font-size:.7rem;letter-spacing:.12em;color:var(--brand-4)}
.cab__tag-t{display:block;padding:.6rem 1rem .75rem;font-family:var(--font-body);font-size:.92rem;font-weight:700;
  line-height:1.3;color:var(--on-dark)}
/* el ojal queda sobre el extremo de la atadura (x del casquillo en el viewBox) */
.cab__v--a .cab__tag{position:absolute;top:calc(204 / 320 * 100% - .8rem - 4.5px);
  right:calc(162 / 1200 * 100% - 1.1rem - 4.5px)}
.cab__v--c .cab__tag{margin:calc(-.8rem - 4.5px) max(0px, calc(45 / 600 * 100% - 1.1rem - 4.5px)) 0 auto;
  width:min(17rem,100%)}

/* variante por ancho: con nombres de familia solo cuando entran */
.cab--home .cab__v--a{display:none}
@media (min-width:1100px){
  .cab--home .cab__v--a{display:block}
  .cab--home .cab__v--c{display:none}
}

/* scrub: casquillo, atadura y etiqueta entran cuando el cable llega (vars del JS).
   La etiqueta NO se funde (un panel oscuro a media opacidad sobre blanco se ve gris):
   la atadura baja y la etiqueta se descubre de arriba hacia abajo, como saliendo del troquel. */
.fx-live .cab.fx-scrub .cab__ferr{opacity:var(--cab-f,1)}
.fx-live .cab.fx-scrub .cab__tie{transform-box:fill-box;transform-origin:50% 0;transform:scaleY(var(--cab-e,1))}
.fx-live .cab.fx-scrub .cab__tag{
  -webkit-mask-image:linear-gradient(#000,#000);mask-image:linear-gradient(#000,#000);
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:0 0;mask-position:0 0;
  -webkit-mask-size:100% calc(var(--cab-t,1) * 100%);mask-size:100% calc(var(--cab-t,1) * 100%)}

/* ---------------------------------------------------------------------------
   2 · etiqueta — las cuatro reglas del catálogo se cuelgan (filo dorado + ojal)
   ------------------------------------------------------------------------- */
.fx [data-fx="etiqueta"] .tagband__i{position:relative}
.fx [data-fx="etiqueta"] .tagband__i h3{padding-right:1.6rem}
.fx [data-fx="etiqueta"] .tagband__i::before{content:"";position:absolute;left:0;right:0;top:0;height:2px;
  background:var(--brand-4);transform-origin:0 50%}
.fx [data-fx="etiqueta"] .tagband__i::after{content:"";position:absolute;top:1.05rem;right:1rem;width:9px;height:9px;
  border-radius:50%;border:1px solid rgba(198,161,91,.6)}
.fx [data-fx="etiqueta"] .tagband__i:nth-child(1){--fx-i:0}
.fx [data-fx="etiqueta"] .tagband__i:nth-child(2){--fx-i:1}
.fx [data-fx="etiqueta"] .tagband__i:nth-child(3){--fx-i:2}
.fx [data-fx="etiqueta"] .tagband__i:nth-child(4){--fx-i:3}

@media screen and (prefers-reduced-motion:no-preference){
  .fx-live [data-fx="etiqueta"] .tagband__i::before{
    transition:transform var(--fx-dur-3) var(--fx-ease-out-expo) calc(var(--fx-i,0) * 70ms)}
  .fx-live [data-fx="etiqueta"] .tagband__i > *{
    transition:opacity var(--fx-dur-2) var(--fx-ease-out) calc(var(--fx-i,0) * 70ms + 140ms),
               transform var(--fx-dur-2) var(--fx-ease-out) calc(var(--fx-i,0) * 70ms + 140ms)}
  .fx-live [data-fx="etiqueta"]:not(.fx-in) .tagband__i::before{transform:scaleX(0)}
  .fx-live [data-fx="etiqueta"]:not(.fx-in) .tagband__i > *{opacity:0;transform:translateY(8px)}
}

/* ---------------------------------------------------------------------------
   3 · carga-rail — el riel de los controles se llena con la lectura
   ------------------------------------------------------------------------- */
.fx [data-fx="carga-rail"]{position:relative}
.fx-live [data-fx="carga-rail"]{border-left-color:var(--line)}
.fx-live [data-fx="carga-rail"]::after{content:"";position:absolute;left:-2px;top:0;bottom:0;width:2px;
  background:var(--brand-4);transform-origin:50% 0;transform:scaleY(var(--rail,0))}
.fx-live [data-fx="carga-rail"] li::before{background:var(--surface);box-shadow:inset 0 0 0 2px var(--brand-4);
  transition:background-color var(--fx-dur-2) var(--fx-ease-out)}
.fx-live [data-fx="carga-rail"] li.fx-on::before{background:var(--brand-4)}

/* ---------------------------------------------------------------------------
   4 · pasos del pedido — stagger del driver + la regla dorada se traza en orden
   ------------------------------------------------------------------------- */
.fx .steps[data-fx="stagger"] > li{position:relative;border-top-color:transparent}
.fx .steps[data-fx="stagger"] > li::before{content:"";position:absolute;left:0;right:0;top:-2px;height:2px;
  background:var(--brand-4);transform-origin:0 50%;transform:scaleX(0);
  transition:transform var(--fx-dur-3) var(--fx-ease-out-expo)}
.fx .steps[data-fx="stagger"] > li{transform:translateY(8px)}
.fx .steps[data-fx="stagger"].in > li{transform:none}
.fx .steps[data-fx="stagger"].in > li::before{transform:none}
.fx .steps[data-fx="stagger"].in > li:nth-child(1)::before{transition-delay:60ms}
.fx .steps[data-fx="stagger"].in > li:nth-child(2)::before{transition-delay:120ms}
.fx .steps[data-fx="stagger"].in > li:nth-child(3)::before{transition-delay:180ms}
.fx .steps[data-fx="stagger"].in > li:nth-child(4)::before{transition-delay:240ms}
.fx .steps[data-fx="stagger"].in > li:nth-child(5)::before{transition-delay:300ms}
.fx .steps[data-fx="stagger"].in > li:nth-child(6)::before{transition-delay:360ms}

/* ---------------------------------------------------------------------------
   5 · indice — las seis filas del índice del hero entran en orden (una vez)
   ------------------------------------------------------------------------- */
@media screen and (prefers-reduced-motion:no-preference){
  .fx [data-fx="indice"] .idxrow{animation:fx-idx var(--fx-dur-2) var(--fx-ease-out) both}
  .fx [data-fx="indice"] .idxrow:nth-of-type(1){animation-delay:220ms}
  .fx [data-fx="indice"] .idxrow:nth-of-type(2){animation-delay:280ms}
  .fx [data-fx="indice"] .idxrow:nth-of-type(3){animation-delay:340ms}
  .fx [data-fx="indice"] .idxrow:nth-of-type(4){animation-delay:400ms}
  .fx [data-fx="indice"] .idxrow:nth-of-type(5){animation-delay:460ms}
  .fx [data-fx="indice"] .idxrow:nth-of-type(6){animation-delay:520ms}
  @keyframes fx-idx{from{opacity:0;transform:translateX(-8px)}}
}

/* ---------------------------------------------------------------------------
   6 · lista — feedback de «Add to list» y del contador del header
   ------------------------------------------------------------------------- */
.fx .addbtn{transition:background-color var(--fx-dur-1) var(--fx-ease-out),border-color var(--fx-dur-1) var(--fx-ease-out),
  color var(--fx-dur-1) var(--fx-ease-out),transform var(--fx-dur-1) var(--fx-ease-out)}
.fx .addbtn:active{transform:scale(.97)}
.fx [data-fx="lista"] [data-list-count]{display:inline-block}
@media screen and (prefers-reduced-motion:no-preference){
  .fx .fx-tick{animation:fx-tick 180ms var(--fx-ease-out)}
  @keyframes fx-tick{from{opacity:.2;transform:translateY(6px)}}
}

/* ---------------------------------------------------------------------------
   failsafe: si el driver o la firma no arrancan, el head pone .fx-off
   ------------------------------------------------------------------------- */
.fx-off [data-fx="stagger"] > *{opacity:1 !important;transform:none !important}
.fx-off .steps[data-fx="stagger"] > li::before{transform:none !important}

/* capabilities: la etiqueta solo lleva «6 → 1» (el texto ya está en el primer tick) */
.cab__tag--solo{width:auto;min-width:7.5rem}
.cab__tag--solo .cab__tag-hd{border-bottom:0}

/* ===========================================================================
   CAPA 2026 — movimiento ligado al scroll SIN JavaScript (`animation-timeline`).
   Soporte real (sep-2026): Chrome/Edge 115+, Safari 18+/26; Firefox sigue detrás
   de bandera. Por eso todo va dentro de @supports: donde no hay soporte, el
   contenido se ve quieto y completo (estado base = estado final).
   Nada de esto corre con prefers-reduced-motion.
   ========================================================================= */
@supports (animation-timeline: view()){
@media screen and (prefers-reduced-motion:no-preference){

  /* 1 · vista — una lista aparece como lista. El escalonado lo da la geometría:
        cada ítem tiene su propia línea de tiempo, así que entra cuando le toca. */
  .fx [data-fx~="vista"] > *,
  .fx [data-fx="vista-uno"]{
    animation:fx-vista linear both;
    animation-timeline:view();
    animation-range:entry 0% entry 70%}
  /* escalonado por columna: la fila entra de izquierda a derecha.
     2026-09-26: el rango termina DENTRO de `entry` (antes llegaba a cover 16–25 %): un ítem entero a la
     vista ya no queda a medio fundir si el visitante deja de scrollear (se veía en la fila 06 del índice
     y en las preguntas 04–06). */
  .fx [data-fx~="vista"] > :nth-child(4n+2){animation-range:entry 8% entry 78%}
  .fx [data-fx~="vista"] > :nth-child(4n+3){animation-range:entry 16% entry 86%}
  .fx [data-fx~="vista"] > :nth-child(4n+4){animation-range:entry 24% entry 94%}
  /* `translate`, no `transform`: asi la inclinacion (transform) no se pisa con la entrada */
  @keyframes fx-vista{from{opacity:0;translate:0 14px}to{opacity:1;translate:0 0}}

  /* 2 · foto — la imagen se descubre desde abajo y se asienta (sin mover la caja: CLS 0) */
  .fx [data-fx~="foto"]{overflow:clip}
  .fx [data-fx="foto"] img{
    animation:fx-foto linear both;
    animation-timeline:view();
    animation-range:entry 0% entry 90%}
  @keyframes fx-foto{
    from{clip-path:inset(0 0 16% 0);scale:1.045}
    to{clip-path:inset(0 0 0 0);scale:1}}
  /* con paralaje, la foto va un 9 % mas grande y solo se recorta (la escala la fija el paralaje) */
  .fx [data-fx~="foto"][data-fx~="paralaje"] img{
    scale:1.09;
    animation:fx-foto-clip linear both,fx-plx-img linear both;
    animation-timeline:view(),view();
    animation-range:entry 0% entry 90%,cover 0% cover 100%}
  @keyframes fx-foto-clip{from{clip-path:inset(0 0 16% 0)}to{clip-path:inset(0 0 0 0)}}
  @keyframes fx-plx-img{from{translate:0 calc(-1 * var(--plx,4%))}to{translate:0 var(--plx,4%)}}

  /* 8 - paralaje del hero y del subhero: dos velocidades, sin mover la caja (CLS 0).
        El fondo (video/poster) baja lento mientras la seccion sale; el texto sube un poco mas rapido. */
  /* el hero recorta con overflow:hidden, que lo vuelve contenedor de scroll y congela view();
     overflow:clip recorta igual y deja que la linea de tiempo sea la de la pagina */
  .fx .hero[data-fx~="paralaje"]{overflow:clip}
  /* el fondo escala desde su borde superior: lo que queda a la vista (la parte baja) se retrasa respecto
     de la pagina, que es el paralaje, y la capa nunca sale del hero (no pisa la franja del nav) */
  .fx .hero[data-fx~="paralaje"] .hero__media{
    transform-origin:50% 0;
    animation:fx-plx-back linear both;animation-timeline:view();animation-range:exit 0% exit 100%}
  .fx .opener[data-fx~="paralaje"]{overflow:clip}
  .fx .opener[data-fx~="paralaje"] .opener__media{
    transform-origin:50% 0;
    animation:fx-plx-back linear both;animation-timeline:view();animation-range:exit 0% exit 100%}
  .fx .opener[data-fx~="paralaje"] .opener__rail{
    animation:fx-plx-side linear both;animation-timeline:view();animation-range:exit 0% exit 100%}
  .fx .hero[data-fx~="paralaje"] .hero__grid,
  .fx .opener[data-fx~="paralaje"] .opener__in,
  .fx .subhero[data-fx~="paralaje"] .subhero__grid > :first-child{
    animation:fx-plx-front linear both;animation-timeline:view();animation-range:exit 0% exit 100%}
  .fx .subhero[data-fx~="paralaje"] .subhero__side{
    animation:fx-plx-side linear both;animation-timeline:view();animation-range:exit 0% exit 100%}
  @keyframes fx-plx-back{to{scale:var(--plx-back,1.14)}}
  @keyframes fx-plx-front{to{translate:0 calc(-1 * var(--plx-front,9%));opacity:.35}}
  @keyframes fx-plx-side{to{translate:0 calc(-1 * var(--plx-side,4%))}}
  @media (max-width:720px){ .fx{--plx:2%;--plx-back:1.07;--plx-front:5%;--plx-side:2%} }
  /* gama baja (lo marca el JS): sin paralaje */
  .fx.fx-low [data-fx~="paralaje"] *{animation-name:none !important}
  .fx.fx-low [data-fx~="foto"][data-fx~="paralaje"] img{animation-name:fx-foto-clip;scale:1}

  /* 3 · parrafo — la frase del concepto se enciende palabra por palabra mientras se lee */
  .fx [data-fx="parrafo"] .w{
    display:inline-block;            /* un span en línea no tiene caja propia: view() no lo mediría */
    color:var(--on-dark-mute);
    animation:fx-word linear both;
    animation-timeline:view();
    /* sobre `cover` (todo el tiempo que la frase está a la vista) el barrido se lee mientras se lee */
    animation-range:cover calc(14% + (var(--i) / var(--n)) * 30%) cover calc(26% + (var(--i) / var(--n)) * 30%)}
  @keyframes fx-word{to{color:var(--on-dark-soft)}}

  /* 4 · progreso — barra de lectura en las páginas largas (catálogo y familias) */
  .fx .prog{
    position:fixed;left:0;right:0;top:var(--hdr-h);height:2px;z-index:99;
    background:var(--brand-4);transform-origin:0 50%;transform:scaleX(0);
    animation:fx-prog linear both;
    animation-timeline:scroll(root)}
  @keyframes fx-prog{to{transform:scaleX(1)}}
}
}
/* sin soporte (Firefox hoy) la barra no existe: no se deja una línea muerta */
.prog{display:none}
@supports (animation-timeline: scroll(root)){ .fx .prog{display:block} }

/* ---------------------------------------------------------------------------
   5 · tabla — la fila que se está leyendo se resalta (dato que se compara)
   ------------------------------------------------------------------------- */
@media (hover:hover){
  .fx [data-fx="tabla"] .tbl tbody tr{transition:background-color var(--fx-dur-1) var(--fx-ease-out)}
  .fx [data-fx="tabla"] .tbl tbody tr:hover{background:var(--surface-3)}
  .fx .sec--dark [data-fx="tabla"] .tbl tbody tr:hover td{background:rgba(245,243,238,.09)}
  .fx .pcard__img{transition:transform var(--fx-dur-3) var(--fx-ease-out)}
  .fx .pcard:hover .pcard__img{transform:scale(1.03)}
  .fx .famrow__img{transition:transform var(--fx-dur-3) var(--fx-ease-out)}
  .fx .famrow:hover .famrow__img{transform:scale(1.03)}
}

/* ---------------------------------------------------------------------------
   6 · acordeón — el FAQ abre y cierra con altura animada (CSS nativo 2026)
   ------------------------------------------------------------------------- */
@supports (interpolate-size: allow-keywords){
  @media screen and (prefers-reduced-motion:no-preference){
    .fx [data-fx="acordeon"]{interpolate-size:allow-keywords}
    .fx [data-fx="acordeon"] details::details-content{
      block-size:0;overflow:clip;opacity:0;
      transition:block-size var(--fx-dur-2) var(--fx-ease-out),opacity var(--fx-dur-1) var(--fx-ease-out),
                 content-visibility var(--fx-dur-2) allow-discrete}
    .fx [data-fx="acordeon"] details[open]::details-content{block-size:auto;opacity:1}
    .fx [data-fx="acordeon"] summary::after{transition:transform var(--fx-dur-2) var(--fx-ease-out)}
    .fx [data-fx="acordeon"] details[open] summary::after{transform:rotate(45deg)}
  }
}

/* ---------------------------------------------------------------------------
   7 · filtro — al filtrar el catálogo, el resultado se confirma (no se recompone a ciegas)
   ------------------------------------------------------------------------- */
@media screen and (prefers-reduced-motion:no-preference){
  .fx [data-fx~="filtro"]{transition:opacity var(--fx-dur-1) var(--fx-ease-out)}
  .fx [data-fx~="filtro"].fx-swap{opacity:.45}
}


/* ===========================================================================
   RONDA 3 - profundidad, inclinacion y respuesta de los botones
   ========================================================================= */

/* 9 - hondo: la etiqueta del subhero se cuelga en perspectiva al cargar (una vez, 520 ms) */
@media screen and (prefers-reduced-motion:no-preference){
  .fx [data-fx="hondo"]{transform-origin:50% 0;animation:fx-hang var(--fx-dur-3) var(--fx-ease-out-expo) both 140ms}
  @keyframes fx-hang{from{opacity:0;transform:perspective(900px) rotateX(-16deg) translateY(-8px)}}
}

/* 10 - inclina: perspectiva bajo el puntero (solo con puntero fino; el JS pone --rx/--ry) */
@media (hover:hover) and (pointer:fine) and (prefers-reduced-motion:no-preference){
  .fx [data-fx~="inclina"] > *,
  .fx [data-fx="inclina-uno"]{
    transform:perspective(900px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));
    transform-style:preserve-3d;
    transition:transform var(--fx-dur-3) var(--fx-ease-out),box-shadow var(--fx-dur-3) var(--fx-ease-out)}
  .fx [data-fx~="inclina"] > *.fx-tilt,
  .fx [data-fx="inclina-uno"].fx-tilt{transition:transform 80ms linear,box-shadow var(--fx-dur-3) var(--fx-ease-out);
    box-shadow:0 18px 32px -24px rgba(11,18,32,.55);z-index:1;position:relative}
  /* la imagen flota unos milimetros delante del texto: profundidad real, no adorno */
  .fx [data-fx~="inclina"] > * .pcard__media,
  .fx [data-fx~="inclina"] > * .indcard__img{translate:0 0 var(--tz,0px);transition:translate var(--fx-dur-3) var(--fx-ease-out)}
  .fx [data-fx~="inclina"] > *.fx-tilt .pcard__media,
  .fx [data-fx~="inclina"] > *.fx-tilt .indcard__img{--tz:14px}
}

/* 11 - boton: el boton responde (sube un pelo al pasar, se hunde al presionar, la flecha del enlace avanza) */
.fx .btn{transition:background var(--fx-dur-2) var(--fx-ease-out),color var(--fx-dur-2) var(--fx-ease-out),
  border-color var(--fx-dur-2) var(--fx-ease-out),transform var(--fx-dur-1) var(--fx-ease-out),
  translate var(--fx-dur-2) var(--fx-ease-out),box-shadow var(--fx-dur-2) var(--fx-ease-out)}
.fx .btn:active{transform:scale(.97)}
.fx .btn--primary:active{filter:brightness(.95)}
@media (hover:hover){
  .fx .btn:hover{translate:0 -1px;box-shadow:0 10px 18px -14px rgba(11,18,32,.6)}
  .fx .btn--primary:hover{box-shadow:0 10px 20px -12px rgba(198,161,91,.6)}
  .fx .btn--ghost-dark:hover{border-color:var(--brand-5)}
  .fx .alink:hover .ar{transform:translateX(4px)}
  .fx .famrow{transition:background-color var(--fx-dur-2) var(--fx-ease-out)}
  .fx .famrow:hover{background:var(--surface-2)}
  .fx .fbtn{transition:background-color var(--fx-dur-1) var(--fx-ease-out),color var(--fx-dur-1) var(--fx-ease-out)}
}
.fx .fbtn:active,.fx .addbtn:active,.fx .listbtn:active{scale:.985}
@media (prefers-reduced-motion:reduce){
  .fx .btn:hover{translate:0 0}
  .fx [data-fx="hondo"]{animation:none}
}

/* ===========================================================================
   PASADA DEL ANIMADOR · 2026-09-20 (escenario v5 y libro de preguntas)
   ========================================================================= */

/* 12 - la etiqueta del ESCENARIO: un solo gesto. `hondo` la cuelga en perspectiva y el balanceo
   de site.css (`stage-sway`) la hacía oscilar; los dos animaban `transform` sobre el mismo
   elemento y el de site.css ganaba por especificidad, así que `hondo` quedaba declarado y sin
   ejercerse. Acá se componen en UNA animación: cae del gancho y se aquieta con un balanceo.
   Sin opacidad a propósito (20-sep): a media entrada la etiqueta dejaba ver el ovillo iluminado y
   el contraste del texto caía a 2,1:1 en el render K; una etiqueta física no se funde, cae. */
@media screen and (prefers-reduced-motion:no-preference){
  .fx .stage__plate.is-on [data-fx="hondo"]{
    transform-origin:50% 0;
    animation:fx-hang-sway 1.5s var(--fx-ease-out-expo) both 140ms}
  @keyframes fx-hang-sway{
    0%{transform:perspective(900px) rotateX(-16deg) translateY(-8px) rotate(0)}
    32%{transform:perspective(900px) rotateX(0) translateY(0) rotate(1.4deg)}
    60%{transform:perspective(900px) rotateX(0) rotate(-.7deg)}
    82%{transform:perspective(900px) rotateX(0) rotate(.25deg)}
    100%{transform:none}}
}
@media (prefers-reduced-motion:reduce){
  .fx .stage__plate.is-on [data-fx="hondo"]{animation:none}
}

/* 14 - (2026-09-26) la etiqueta de la foto (OEM: «Your mark») se cuelga como la del escenario cuando la
   foto llega a la zona de lectura. El JS la arma solo si arranca bajo el pliegue; sin JS queda quieta. */
@media screen and (prefers-reduced-motion:no-preference){
  .fx .fig__tag.fx-armed{transform-origin:50% 0;transform:perspective(900px) rotateX(-16deg) translateY(-8px)}
  .fx .fig__tag.fx-armed.fx-in{transform:none;animation:fx-hang-sway 1.5s var(--fx-ease-out-expo) both 80ms}
}

/* 15 - (2026-09-26) cable → razón 01. La etiqueta del cable dice «One purchase order across six
   families», que es la primera razón de la lista de abajo: cuando la etiqueta se descubre, esa razón
   se ata con un filete dorado que se traza bajo el título. Reversible con el scroll, como el cable. */
.fx .rlist--dl > div:first-child h3{
  background:linear-gradient(var(--brand-4),var(--brand-4)) 0 100%/0 2px no-repeat;padding-bottom:.2rem}
.fx .rlist--dl > div:first-child .rlist__n--mark{transition:scale var(--fx-dur-2) var(--fx-ease-out)}
.fx .rlist--dl.fx-tied > div:first-child h3{background-size:100% 2px}
.fx .rlist--dl.fx-tied > div:first-child .rlist__n--mark{scale:1.5}
@media screen and (prefers-reduced-motion:no-preference){
  .fx .rlist--dl > div:first-child h3{transition:background-size var(--fx-dur-3) var(--fx-ease-out-expo)}
}

/* 13 - libro de preguntas: la pregunta elegida marca su filete dorado trazándolo de arriba a
   abajo (feedback, 260 ms). Las seis preguntas entran como lista con `vista` (fxwire). */
@media screen and (prefers-reduced-motion:no-preference){
  .fx .qabtn[aria-selected="true"]::after{
    transform-origin:50% 0;
    animation:fx-filete var(--fx-dur-2) var(--fx-ease-out) both}
  @keyframes fx-filete{from{transform:scaleY(0)}}
}
