/* -----------------------------------------------------------------------------
 * Reveal on scroll — v3
 *
 * Due sistemi indipendenti:
 *
 *   .reveal-type   scroll-linked. Le parole si scrivono con sfocatura mentre
 *                  scendi e si cancellano mentre risali. Reversibile.
 *
 *   .reveal        trigger-once. Il blocco compare una volta e resta.
 *   .reveal-group  trigger-once a cascata sui figli.
 *
 * Lo stato nascosto vale solo dentro .js-reveal (classe su <html> da PHP).
 * Senza JS, in editor Elementor o con reduced-motion, tutto resta visibile.
 * -------------------------------------------------------------------------- */

.js-reveal {
  --reveal-duration: 900ms;
  --reveal-shift: 12px;
  --reveal-ease: cubic-bezier(.16, 1, .3, 1);

  /* Effetto scrittura */
  --type-blur: 8px;   /* sfocatura massima della parola non ancora scritta */
  --type-lift: 6px;   /* quanto sale la parola mentre si mette a fuoco */
}

/* =============================================================================
 * 1. Effetto scrittura — .reveal-type
 *
 * Il JS scrive una sola variabile per parola, --rv-p (da 0 a 1).
 * Opacità, sfocatura e spostamento sono derivati qui in CSS: una sola
 * scrittura di stile per parola per frame invece di tre.
 *
 * Nessuna transition: il valore è agganciato allo scroll, non al tempo.
 * ========================================================================== */

.js-reveal .reveal-type .rv-w {
  display: inline-block;
  opacity: var(--rv-p, 0);
  filter: blur(calc((1 - var(--rv-p, 0)) * var(--type-blur)));
  transform: translateY(calc((1 - var(--rv-p, 0)) * var(--type-lift)));
}

/* Parola a fuoco: si toglie il filtro per liberare la GPU. */
.js-reveal .reveal-type .rv-w[data-rv-done="1"] {
  filter: none;
  transform: none;
  opacity: 1;
}

/* Varianti di intensità */
.js-reveal .reveal-type--soft  { --type-blur: 4px;  --type-lift: 3px; }
.js-reveal .reveal-type--hard  { --type-blur: 14px; --type-lift: 10px; }

/* Senza sollevamento: solo messa a fuoco */
.js-reveal .reveal-type--flat  { --type-lift: 0px; }

/* =============================================================================
 * 2. Reveal a blocco — .reveal (trigger-once)
 * ========================================================================== */

.js-reveal .reveal {
  opacity: 0;
  transform: translateY(var(--reveal-shift));
  will-change: opacity, transform;
}

.js-reveal .reveal.is-visible {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--reveal-duration) var(--reveal-ease),
    transform var(--reveal-duration) var(--reveal-ease);
  transition-delay: var(--reveal-delay, 0ms);
}

.js-reveal .reveal--fade   { transform: none; }
.js-reveal .reveal--up     { --reveal-shift: 24px; }
.js-reveal .reveal--left   { transform: translateX(-24px); }
.js-reveal .reveal--right  { transform: translateX(24px); }
.js-reveal .reveal--scale  { transform: scale(.97); }
.js-reveal .reveal--fast   { --reveal-duration: 550ms; }
.js-reveal .reveal--slow   { --reveal-duration: 1200ms; }

/* =============================================================================
 * 3. Accessibilità e stampa
 * ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .js-reveal .reveal,
  .js-reveal .reveal-type .rv-w {
    opacity: 1 !important;
    filter: none !important;
    transform: none !important;
    transition: none !important;
  }
}

@media print {
  .js-reveal .reveal,
  .js-reveal .reveal-type .rv-w {
    opacity: 1 !important;
    filter: none !important;
    transform: none !important;
  }
}
