/* =====================================================================
   site-motion.css · capa de movimiento común de elcuadrante.es
   (portada, landings de sector, blog y FAQ). Vanilla, sin dependencias.
   Va en pareja con /assets/site-motion.js: el arranque, la API JS y las
   trampas están explicados en la cabecera de ese fichero.

   PRINCIPIO
   - Todo estado previo (oculto, sin sellar) vive bajo html.sm-js Y dentro
     de @media screen and (prefers-reduced-motion: no-preference).
     Sin esa clase (sin JS, JS bloqueado, 'reducir movimiento', imprimir)
     la página se ve EXACTAMENTE como hoy.
   - Solo se anima opacity y las propiedades individuales translate/scale/
     rotate, que se SUMAN al transform propio de cada elemento (un sello
     girado 8deg sigue a 8deg al terminar). Una sola vez; nada infinito.
   - Las animaciones usan fill 'backwards': al acabar no retienen nada y
     manda el CSS propio del elemento (su opacity .85, su giro, su hover).

   CLASES Y ATRIBUTOS (todo es opt-in)
     .sm-reveal         aparece como un papel que se asienta al verse
     html[data-sm-legacy-reveal]   trata igual los .reveal antiguos
     [data-sm-stagger]  sus hijos se reparten escalonados, 70 ms por hijo
                        (valor opcional N = el índice va en módulo N)
     .sm-stamp          sello que golpea (sm-thump) al entrar en pantalla
     .sm-thump          golpe de sello inmediato (para escenas en JS)
     .in                estado final (lo pone el JS; en el HTML = sin animar)
     .sm-play           transitoria: está animando (se quita a los 2,5 s)
     .sm-press          botón que se hunde con su sombra dura
                        vars: --sm-sh (sombra en reposo, 4px), --sm-push
                        (hundido, 2px), --sm-shc (color, var(--ink))
     html.sm-focus      :focus-visible con contorno discontinuo de tinta
     .sm-dark           dentro de fondos oscuros: foco en papel dorado
     html.sm-anchors    anclas bajo cabecera fija (--sm-header, 84px)
   Variables de escena: --i (índice → retardo) y --r (inclinación ±0.8deg);
   úsalas SIEMPRE con fallback: var(--i,0) y var(--r,0deg). OJO: se heredan.
   Tokens: --ease-paper (papel que se asienta), --ease-stamp (golpe).
   ===================================================================== */

:root{
  --ease-paper: cubic-bezier(.2,.9,.25,1.12);   /* papel que se asienta, micro rebote */
  --ease-stamp: cubic-bezier(.2,1.5,.35,1);     /* golpe de sello de goma */
}

/* Papel que llega: sube 18px, se endereza (--r) y se asienta.
   Sin 'to': termina en los valores propios del elemento. */
@keyframes sm-rise{
  from{ opacity: 0; translate: 0 18px; rotate: var(--r, 0deg); }
}

/* Golpe de sello. scale/rotate individuales: se suman al giro propio de
   cada sello en cada breakpoint. En navegadores sin estas propiedades
   (Chrome <104, Safari <14.1) solo se anima la opacidad. El 100% no fija
   opacity: el sello acaba con la suya (p. ej. .85). */
@keyframes sm-thump{
  0%  { opacity: 0; scale: 1.8;  rotate: 10deg; }
  55% { opacity: 1; scale: .94;  rotate: -2deg; }
  78% {             scale: 1.03; rotate: 0deg; }
  100%{             scale: 1;    rotate: 0deg; }
}

/* ---- 1 · Estados previos y animaciones (solo pantalla y sin 'reducir') ---- */
@media screen and (prefers-reduced-motion: no-preference){
  html.sm-js .sm-reveal:not(.in),
  html.sm-js[data-sm-legacy-reveal] .reveal:not(.in),
  html.sm-js [data-sm-stagger]:not(.in) > *,
  html.sm-js .sm-stamp:not(.in){ opacity: 0; }

  html.sm-js .sm-reveal.sm-play,
  html.sm-js[data-sm-legacy-reveal] .reveal.sm-play{
    animation: sm-rise .6s var(--ease-paper) calc(var(--i, 0) * 70ms) backwards;
  }
  html.sm-js [data-sm-stagger].sm-play > *{
    animation: sm-rise .5s var(--ease-paper) calc(var(--i, 0) * 70ms) backwards;
  }
  html.sm-js .sm-stamp.sm-play{
    animation: sm-thump .45s var(--ease-stamp) calc(.15s + var(--i, 0) * 120ms) backwards;
  }
  html.sm-js .sm-thump{
    animation: sm-thump .45s var(--ease-stamp) backwards;
  }
}

/* ---- 2 · Presión de botón: se hunde en el papel y la sombra se encoge ----
   translate (individual) se suma al transform propio. .sm-press manda en
   :hover/:active (!important): quita del botón tus reglas :hover/:active de
   transform y box-shadow y ajusta con --sm-sh / --sm-push / --sm-shc.
   Sin sombra en reposo (botón fantasma): --sm-shc: transparent. */
.sm-press{
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
html .sm-press{
  transition: translate .12s ease, transform .12s ease, box-shadow .12s ease,
              background-color .15s ease, color .15s ease;
}
@media (hover: hover){
  .sm-press:hover{
    translate: -1px -1px !important;
    box-shadow: calc(var(--sm-sh, 4px) + 1px) calc(var(--sm-sh, 4px) + 1px) 0 var(--sm-shc, var(--ink, #2c2416)) !important;
  }
}
.sm-press:active{
  translate: var(--sm-push, 2px) var(--sm-push, 2px) !important;
  box-shadow: calc(var(--sm-sh, 4px) - var(--sm-push, 2px)) calc(var(--sm-sh, 4px) - var(--sm-push, 2px)) 0 var(--sm-shc, var(--ink, #2c2416)) !important;
  transition-duration: .05s;
}

/* ---- 3 · Foco visible (opt-in: <html class="sm-focus">) ---- */
html.sm-focus :where(a, button, summary, iframe, [role="button"], [tabindex]:not([tabindex="-1"])):focus-visible{
  outline: 2px dashed var(--sm-focus, var(--ink, #2c2416));
  outline-offset: 3px;
}
html.sm-focus .sm-press:focus-visible{ outline-offset: 5px; }
.sm-dark{ --sm-focus: var(--gold-bg, #fff3cd); }

/* ---- 4 · Anclas bajo una cabecera fija (opt-in: <html class="sm-anchors">) ---- */
html.sm-anchors{ scroll-padding-top: var(--sm-header, 84px); }

/* ---- 5 · 'Reducir movimiento': la web de hoy, quieta ----
   Los estados previos ya no aplican (van en no-preference). Esto es la
   segunda red por si la preferencia cambia con la página abierta. */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior: auto !important; }
  html.sm-js *, html.sm-js *::before, html.sm-js *::after{
    animation: none !important;
    transition: none !important;
  }
  html .sm-press{ transition: none; }
}
