:root {
  /* Emil-style ease-out: quick to start, gentle to settle. */
  --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ============================================================
   Scroll reveals
   Active ONLY once JS confirms motion is allowed (html.motion).
   No JS / reduced motion  ->  content stays fully visible.
   ============================================================ */
/* Hidden state applies instantly (no transition) so adding html.motion before
   paint never produces a fade-out flash; the transition lives on .is-visible,
   so only the reveal animates. */
html.motion [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
}

html.motion [data-reveal].is-visible {
  opacity: 1;
  transform: none;
  transition:
    opacity 0.62s var(--ease-out),
    transform 0.62s var(--ease-out);
  transition-delay: calc(var(--reveal-i, 0) * 60ms);
}

html.motion [data-image-reveal] {
  opacity: 0;
  transform: scale(1.035);
}

html.motion [data-image-reveal].is-visible {
  opacity: 1;
  transform: none;
  transition:
    opacity 0.8s ease,
    transform 0.9s var(--ease-out);
}

/* ============================================================
   Micro-interactions (skipped entirely under reduced motion)
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  * {
    -webkit-tap-highlight-color: transparent;
  }

  /* Buttons: settle on hover, press in on tap/click. */
  /* One curve for the whole gesture: the orange fill retracting, the colour
     swap and the lift all resolve together instead of at three speeds. */
  .button {
    transition:
      background-size 0.42s var(--ease-out),
      background-color 0.42s var(--ease-out),
      transform 0.28s var(--ease-out),
      color 0.28s ease,
      border-color 0.28s ease,
      box-shadow 0.28s ease;
  }

  .button::after {
    transition: opacity 0.3s var(--ease-out);
  }

  .button:active {
    transform: translateY(1px) scale(0.985);
  }

  /* Cards: a small, confident lift; a lighter one on press for touch. */
  .info-card,
  .related-card,
  .post-card,
  .cert-card,
  .step-card {
    transition:
      transform 0.24s var(--ease-out),
      box-shadow 0.24s var(--ease-out),
      border-color 0.24s ease;
  }

  .info-card:hover,
  .post-card:hover,
  .cert-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 18px 40px -24px rgba(0, 0, 0, 0.5);
  }

  .related-card:hover {
    transform: translateY(-3px);
  }

  .info-card:active,
  .post-card:active,
  .related-card:active {
    transform: translateY(-1px);
  }

  /* Text links: brief colour settle. */
  .text-link {
    transition: color 0.18s ease;
  }

  .text-link:hover {
    color: var(--signal);
  }

  /* Ambient hero grid drift — desktop only (see mobile override below). */
  .hero-grid {
    animation: servintecusaGridDrift 22s linear infinite;
  }
}

/* Kill continuous ambient motion on phones (battery + smoothness). */
@media (max-width: 767px) {
  .hero-grid {
    animation: none;
  }
}

@keyframes servintecusaGridDrift {
  from {
    background-position: 0 0, 0 0, 0 0;
  }
  to {
    background-position: 72px 72px, 72px 72px, 0 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-duration: 0.001ms !important;
  }
}
