/* ============================================================
   Capa de movimiento — martallorentepsicologia.com
   ------------------------------------------------------------
   Criterio: el movimiento debe leerse como calma, no como
   animación. Todo es lento, suave y ocurre una sola vez, al
   llegar. Nada se repite en bucle salvo la respiración del
   hero, que es deliberada y casi imperceptible.

   Toda la capa se desactiva por completo si el sistema pide
   reducir el movimiento. En una web de salud mental eso no es
   opcional: hay personas con trastornos vestibulares y con
   ansiedad para quienes el movimiento es un síntoma, no un
   adorno.
   ============================================================ */

:root{
  --ml-ease: cubic-bezier(.22,.61,.36,1);   /* salida suave, como un suspiro */
  --ml-dur: .75s;
  --ml-rise: 18px;
}

/* ---------- 1. Revelado al entrar en pantalla ----------
   La lista de selectores vive aquí, no en el JS, y es
   deliberado: si se ocultara desde JavaScript, el navegador ya
   habría pintado el contenido visible y se vería un parpadeo al
   ocultarlo. En CSS aplica desde el primer pintado.

   Sin JS no se oculta nada: la clase .ml-js la pone el propio
   script y solo si va a poder revelar. Si falla o si el sistema
   pide reducir movimiento, todo se ve normal. */
.ml-js .elementor-widget-heading,
.ml-js .elementor-widget-text-editor,
.ml-js .elementor-widget-button,
.ml-js .elementor-widget-html,
.ml-js .elementor-widget-google_maps,
.ml-js .ml-reveal,
.ml-js [data-ml-reveal]{
  opacity:0;
  transform:translate3d(0,var(--ml-rise),0);
  will-change:opacity,transform;
}
.ml-js .elementor-widget-heading.ml-in,
.ml-js .elementor-widget-text-editor.ml-in,
.ml-js .elementor-widget-button.ml-in,
.ml-js .elementor-widget-html.ml-in,
.ml-js .elementor-widget-google_maps.ml-in,
.ml-js .ml-reveal.ml-in,
.ml-js [data-ml-reveal].ml-in{
  opacity:1;
  transform:none;
  transition:opacity var(--ml-dur) var(--ml-ease),
             transform var(--ml-dur) var(--ml-ease);
  transition-delay:var(--ml-delay,0ms);
}

/* Las imágenes entran además desde un desenfoque muy leve.
   Da sensación de que la imagen «se asienta» en vez de aparecer. */
.ml-js .elementor-widget-image,
.ml-js [data-ml-reveal="image"]{
  opacity:0;
  filter:blur(8px);
  transform:translate3d(0,var(--ml-rise),0) scale(1.03);
  will-change:opacity,transform,filter;
}
.ml-js .elementor-widget-image.ml-in,
.ml-js [data-ml-reveal="image"].ml-in{
  opacity:1;
  filter:blur(0);
  transform:none;
  transition:opacity 1s var(--ml-ease),
             transform 1.1s var(--ml-ease),
             filter 1.1s var(--ml-ease);
  transition-delay:var(--ml-delay,0ms);
}

/* Red de seguridad: si por lo que sea el observador no llega a
   procesar un elemento, a los 3 segundos se muestra igualmente.
   Nunca debe quedar contenido invisible por un fallo de script. */
.ml-js.ml-failsafe .elementor-widget-heading,
.ml-js.ml-failsafe .elementor-widget-text-editor,
.ml-js.ml-failsafe .elementor-widget-button,
.ml-js.ml-failsafe .elementor-widget-html,
.ml-js.ml-failsafe .elementor-widget-image,
.ml-js.ml-failsafe .elementor-widget-google_maps,
.ml-js.ml-failsafe .ml-reveal,
.ml-js.ml-failsafe [data-ml-reveal]{
  opacity:1 !important;
  filter:none !important;
  transform:none !important;
}

/* ---------- 2. Respiración del hero ----------
   Un halo cálido detrás del contenido que se expande y se
   recoge a unas 6 veces por minuto: el ritmo de la respiración
   pausada que se usa en el trabajo con ansiedad. No es un
   adorno cualquiera, es el propio instrumento de la consulta.
   Amplitud mínima a propósito: se percibe sin llegar a verse. */
.ml-breath{
  position:relative;
  isolation:isolate;
}
/* El resplandor no puede sobresalir por los lados.
   Con `inset:-10% -5%` se salía un 5 % por cada borde y la animación lo
   escalaba otro 7 %: en una tableta de 768 px eso son unos 60 px de más,
   suficiente para que la página entera pudiera desplazarse en horizontal.
   Un elemento decorativo no debe poder mover la página.
   Por eso: sin holgura lateral, y la respiración solo en vertical. El
   degradado es radial y se desvanece al 72 %, así que recortar en los
   bordes no se nota. */
.ml-breath::before{
  content:'';
  position:absolute;
  inset:-10% 0;
  z-index:-1;
  pointer-events:none;
  border-radius:50%;
  background:radial-gradient(closest-side,
             rgba(139,158,126,.16), rgba(139,158,126,0) 72%);
  animation:mlBreathe 10s ease-in-out infinite;
}
@keyframes mlBreathe{
  0%,100%{ transform:scaleY(1);    opacity:.55 }
  50%    { transform:scaleY(1.07); opacity:.85 }
}

/* ---------- 3. Cabecera que se aparta ----------
   Al bajar se adelgaza y se despega con una sombra mínima.
   Al subir vuelve. Nunca desaparece del todo: el botón de
   contacto tiene que seguir a mano. */
.ml-header{
  transition:padding .35s var(--ml-ease),
             box-shadow .35s var(--ml-ease),
             background-color .35s var(--ml-ease);
}
.ml-header.ml-scrolled{
  box-shadow:0 1px 24px rgba(37,43,32,.07);
}

/* ---------- 4. Micro-interacciones ---------- */

/* Botones: se levantan un poco y la sombra florece.
   200 ms es el punto donde se siente pero no se ve. */
.ml-btn,
.elementor-button{
  transition:transform .22s var(--ml-ease),
             box-shadow .22s var(--ml-ease),
             background-color .22s var(--ml-ease) !important;
}
.ml-btn:hover,
.elementor-button:hover{
  transform:translateY(-2px);
}
.ml-btn:active,
.elementor-button:active{
  transform:translateY(0);
  transition-duration:.08s;
}

/* Enlaces de navegación: el subrayado crece desde la izquierda. */
.ml-navlink{
  position:relative;
  text-decoration:none;
}
.ml-navlink::after{
  content:'';
  position:absolute;
  left:0; bottom:-3px;
  width:100%; height:1.5px;
  background:currentColor;
  transform:scaleX(0);
  transform-origin:left;
  transition:transform .3s var(--ml-ease);
}
.ml-navlink:hover::after,
.ml-navlink:focus-visible::after{ transform:scaleX(1) }

/* Tarjetas: elevación mínima. Nada de escalados grandes. */
.ml-card{
  transition:transform .3s var(--ml-ease), box-shadow .3s var(--ml-ease);
}
.ml-card:hover{
  transform:translateY(-3px);
  box-shadow:0 12px 32px rgba(37,43,32,.09);
}

/* ---------- 5. Foco visible ----------
   Obligatorio para navegación por teclado, y además queda bien. */
.ml-js :focus-visible{
  outline:2.5px solid #4F6245;
  outline-offset:3px;
  border-radius:3px;
}

/* ---------- 6. Barra de lectura del blog ---------- */
.ml-progress{
  position:fixed; top:0; left:0; right:0;
  height:2px; z-index:9998;
  background:transparent;
  pointer-events:none;
}
.ml-progress__bar{
  height:100%; width:0;
  background:#8B9E7E;
  transition:width .1s linear;
}

/* ---------- 7. Compensar la cabecera fija al saltar a un ancla ---------- */
html{ scroll-behavior:smooth }
[id]{ scroll-margin-top:96px }

/* ============================================================
   Desactivación total si el sistema pide reducir el movimiento
   ============================================================ */
@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto }
  .ml-js [data-ml-reveal],
  .ml-js [data-ml-reveal].ml-in{
    opacity:1 !important;
    transform:none !important;
    filter:none !important;
    transition:none !important;
  }
  .ml-breath::before{ animation:none; opacity:.6 }
  .ml-btn, .elementor-button, .ml-card, .ml-navlink::after,
  .ml-header, .ml-progress__bar{
    transition:none !important;
  }
  .ml-btn:hover, .elementor-button:hover, .ml-card:hover{
    transform:none !important;
  }
}
