/* ============================================================
   edusoftnet — Movimiento

   El scroll no se secuestra: el momentum de iOS es del sistema
   operativo y las librerías que lo imitan rompen el trackpad, el
   teclado y los lectores de pantalla.

   Las entradas las dirige reveal.js con IntersectionObserver, que
   funciona en todos los navegadores. La animación ligada a la
   posición del scroll queda solo para el paralaje, como extra.

   Regla que no se rompe: si el JS no corre, todo se ve.
   ============================================================ */

:root {
  /* Arranque decidido, frenada muy larga */
  --ease-out-soft: cubic-bezier(.16, 1, .3, 1);
  --ease-back: cubic-bezier(.34, 1.36, .64, 1);
  --t-reveal: .9s;
}

/* ============================================================
   ENTRADAS
   El estado oculto vive bajo .js-reveal, que solo añade reveal.js.
   ============================================================ */

@media (prefers-reduced-motion: no-preference) {

  .js-reveal .reveal {
    opacity: 0;
    transform: translateY(44px);
    transition: opacity var(--t-reveal) var(--ease-out-soft),
                transform var(--t-reveal) var(--ease-out-soft),
                filter var(--t-reveal) var(--ease-out-soft);
  }

  /* ---------- Direcciones ---------- */

  .js-reveal .reveal[data-reveal="left"]  { transform: translateX(-70px); }
  .js-reveal .reveal[data-reveal="right"] { transform: translateX(70px); }
  .js-reveal .reveal[data-reveal="up"]    { transform: translateY(60px); }
  .js-reveal .reveal[data-reveal="down"]  { transform: translateY(-40px); }

  .js-reveal .reveal[data-reveal="scale"] {
    transform: scale(.9);
    filter: blur(6px);
  }

  .js-reveal .reveal[data-reveal="rise"] {
    transform: translateY(70px) scale(.96);
    filter: blur(4px);
  }

  /* Entra desde el lado girando levemente: para los mockups */
  .js-reveal .reveal[data-reveal="tilt-left"] {
    transform: translateX(-60px) rotate(-2.5deg) scale(.95);
  }

  .js-reveal .reveal[data-reveal="tilt-right"] {
    transform: translateX(60px) rotate(2.5deg) scale(.95);
  }

  /* ---------- Estado final, común a todas ---------- */

  .js-reveal .reveal.is-visible {
    opacity: 1;
    transform: none;
    filter: none;
  }

  /* Las piezas que llevan rebote usan una curva con sobrepaso */
  .js-reveal .reveal[data-reveal^="tilt"],
  .js-reveal .reveal[data-reveal="scale"] {
    transition-timing-function: var(--ease-back);
    transition-duration: 1.05s;
  }

  /* ============================================================
     PARALAJE LIGADO AL SCROLL
     Extra donde el navegador lo soporta. No condiciona nada.
     ============================================================ */

  @supports (animation-timeline: view()) {
    @keyframes cover-drift {
      from { transform: none; opacity: 1; }
      to   { transform: translateY(-40px) scale(.95); opacity: .4; }
    }

    .hero__media {
      animation: cover-drift linear both;
      animation-timeline: view();
      animation-range: exit-crossing 0% exit 100%;
    }

    /* Las escenas de los bentos suben algo más lento que la página */
    @keyframes scene-float {
      from { transform: translateY(26px); }
      to   { transform: translateY(-14px); }
    }

    .scene .mock {
      animation: scene-float linear both;
      animation-timeline: view();
      animation-range: entry 20% exit 80%;
    }
  }

  /* ============================================================
     NAVBAR QUE SE CONDENSA
     ============================================================ */

  .nav {
    transition: background-color var(--t-med) var(--ease-out-soft),
                box-shadow var(--t-med) var(--ease-out-soft);
  }

  .nav__inner { transition: padding-block var(--t-med) var(--ease-out-soft); }
  .nav__brand img { transition: height var(--t-med) var(--ease-out-soft); }

  .nav.is-scrolled {
    background: rgba(255, 255, 255, .82);
    box-shadow: 0 1px 20px rgba(0, 0, 0, .07);
  }

  .nav.is-scrolled .nav__inner { padding-block: 7px; }
  .nav.is-scrolled .nav__brand img { height: 26px; }

  /* Con el menu abierto la cabecera es opaca: translucida dejaba ver
     la pagina de detras al mover el panel. */
  .nav.is-scrolled.has-menu-open {
    background: #fff;
    box-shadow: none;
  }

  /* ============================================================
     MICROINTERACCIONES
     ============================================================ */

  .btn {
    transition: background-color var(--t-fast) var(--ease),
                color var(--t-fast) var(--ease),
                border-color var(--t-fast) var(--ease),
                transform .25s var(--ease-out-soft),
                box-shadow .25s var(--ease-out-soft);
  }

  .btn--dark:hover,
  .btn--light:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 24px -8px rgba(0, 0, 0, .35);
  }

  .btn:active { transform: translateY(0); box-shadow: none; }

  a.card, .bento__cell {
    transition: transform .35s var(--ease-out-soft),
                box-shadow .35s var(--ease-out-soft);
  }

  a.card:hover {
    transform: translateY(-4px);
    box-shadow: 0 22px 44px -22px rgba(20, 46, 96, .45);
  }

  .mock {
    transition: transform .55s var(--ease-out-soft),
                box-shadow .55s var(--ease-out-soft);
  }

  .bento__cell:hover .mock,
  .split__media:hover .mock {
    transform: translateY(-6px);
    box-shadow: 0 30px 56px -20px rgba(0, 0, 0, .34),
                0 2px 6px rgba(0, 0, 0, .04);
  }
}

/* ============================================================
   TEXTO CON DEGRADADO ANIMADO
   Barrido continuo sobre el recorte del texto, con la identidad
   de edusoftnet: azul #264186 y rojo #CE153F.
   ============================================================ */

.gradient-text {
  color: transparent;
  background-image: linear-gradient(90deg,
      var(--brand-blue) 0%,
      var(--brand-red) 20%,
      #7b2f6b 38%,
      var(--brand-blue) 52%,
      var(--brand-red) 72%,
      var(--brand-blue) 100%);
  background-size: 220% 100%;
  background-position: 0 0;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  /* El degradado se dibuja sobre el trazo: si el recorte no se
     soporta, el color de respaldo evita texto invisible. */
  animation: brand-sweep 14s linear infinite;
}

/* Si el navegador no sabe recortar el fondo sobre el texto,
   se vuelve a tinta sólida de marca. */
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .gradient-text {
    color: var(--brand-blue);
    -webkit-text-fill-color: var(--brand-blue);
    background: none;
    animation: none;
  }
}

@keyframes brand-sweep {
  from { background-position: 0 0; }
  to   { background-position: -220% 0; }
}

/* ============================================================
   MOVIMIENTO REDUCIDO
   Todo quieto y visible. Sin excepciones.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  .js-reveal .reveal,
  .js-reveal .reveal[data-reveal],
  .scene .mock,
  .hero__media {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
  }

  .gradient-text { animation: none; background-position: 0 0; }
}
