/* Strato animazioni condiviso dei blocchi zb-* (zb-anim.js lo pilota).
 * Regole: lo stato nascosto vale solo sotto html.zb-anim-ready (lo mette il JS),
 * a fine animazione l'elemento torna al suo stile statico (nessuna proprietà resta scritta).
 * Le animazioni di ingresso usano translate/scale/clip-path via Web Animations dal JS;
 * qui ci sono solo stati di partenza, effetti hover e marquee/parallax in CSS puro.
 * Default tarati sulle sorgenti di 7 reference (ANIMAZIONI.md): power4.out (.23,1,.32,1), 700 ms, stagger 100 ms (research/awwwards/motion/SINTESI.md).
 * Default: un template cambia il carattere di tutto ridefinendo queste variabili. */
:root {
  --zb-anim-duration: 700ms;
  --zb-anim-ease: cubic-bezier(.23, 1, .32, 1);
  --zb-anim-stagger: 100ms;
  --zb-anim-distance: 2.5rem;
  --zb-anim-fill: var(--z-ink, var(--b-text));
  --zb-anim-fill-ink: var(--z-bg, var(--b-bg))}

/* Prima dell'ingresso: nascosto solo se il JS è partito e l'elemento non è ancora entrato */
html.zb-anim-ready [data-anim]:not(.zb-in):not([data-anim^="hover"]):not([data-anim="marquee"]):not([data-anim="parallax"]):not([data-anim="counter"]):not([data-anim="cursor-follow"]):not([data-anim="menu-fullscreen"]):not([data-anim="sticky-header-hide"]) {
  opacity: 0}
/* Testo spezzato in maschere: la maschera taglia, il pezzo dentro sale (come SplitText lines+mask) */
.zb-m { display: inline-block; clip-path: inset(-.35em -.2em -.14em -.2em)}
.zb-p { display: inline-block}

/* Parallax con la timeline di scroll nativa dove c'è; altrimenti lo fa il JS */
@supports (animation-timeline: view()) {
  html.zb-anim-ready:not([data-anim-off]) [data-anim="parallax"] {
    animation: zb-parallax linear both;
    animation-timeline: view()}
}
@keyframes zb-parallax {
  from { translate: 0 calc(var(--zb-par, 12%) * -1); scale: var(--zb-par-s, 1)}
  to { translate: 0 var(--zb-par, 12%); scale: var(--zb-par-s, 1)}
}

/* Marquee: due copie dello stesso gruppo, la traccia scorre di metà */
.zb-mq { overflow: hidden}
.zb-mq-track { display: flex; width: max-content; animation: zb-marquee var(--zb-mq-dur, 30s) linear infinite}
.zb-mq-track[data-dir="right"] { animation-direction: reverse}
.zb-mq[data-anim-pause="hover"]:hover .zb-mq-track { animation-play-state: paused}
@keyframes zb-marquee { to { translate: -50% 0} }

/* Hover: durata/curva/ritardo da data-anim-* (il JS le mette in --zb-hd/--zb-he/--zb-hdl).
 * Solo con mouse vero, mai con reduced-motion o strato spento */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  html:not([data-anim-off]) [data-anim="hover-lift"] {
    transition: translate var(--zb-hd, .7s) var(--zb-he, var(--zb-anim-ease)) var(--zb-hdl, 0s), box-shadow var(--zb-hd, .7s) var(--zb-he, var(--zb-anim-ease)) var(--zb-hdl, 0s)}
  html:not([data-anim-off]) [data-anim="hover-lift"]:hover {
    translate: 0 calc(var(--zb-anim-distance) * -.2);
    box-shadow: var(--b-shadow-sm)}
  /* Linea che entra da sinistra ed esce a destra */
  html:not([data-anim-off]) [data-anim="hover-underline"] {
    background: linear-gradient(currentColor, currentColor) no-repeat 100% 100% / 0 1px;
    transition: background-size var(--zb-hd, .7s) var(--zb-he, var(--zb-anim-ease)) var(--zb-hdl, 0s)}
  html:not([data-anim-off]) [data-anim="hover-underline"]:hover {
    background-size: 100% 1px;
    background-position: 0 100%}
  /* Zoom dell'immagine senza toccare overflow del contenitore: il clip compensa la scala (1-1/1.06)/2 */
  html:not([data-anim-off]) [data-anim="hover-image-zoom"] img {
    transition: scale var(--zb-hd, 1s) var(--zb-he, var(--zb-anim-ease)) var(--zb-hdl, 0s), clip-path var(--zb-hd, 1s) var(--zb-he, var(--zb-anim-ease)) var(--zb-hdl, 0s)}
  html:not([data-anim-off]) [data-anim="hover-image-zoom"]:hover img {
    scale: 1.06;
    clip-path: inset(2.83%)}
  /* Riempimento dal basso: ombra interna sotto il testo, il testo cambia colore */
  html:not([data-anim-off]) [data-anim="hover-fill"] {
    transition: box-shadow var(--zb-hd, .7s) var(--zb-he, var(--zb-anim-ease)) var(--zb-hdl, 0s), color var(--zb-hd, .7s) var(--zb-he, var(--zb-anim-ease)) var(--zb-hdl, 0s)}
  html:not([data-anim-off]) [data-anim="hover-fill"]:hover {
    box-shadow: inset 0 -6em 0 0 var(--zb-anim-fill);
    color: var(--zb-anim-fill-ink)}
}

/* Cursore che segue (solo puntatore fine, lo crea il JS) */
.zb-cursor {
  position: fixed; left: 0; top: 0; z-index: 9999; pointer-events: none;
  width: 5.5rem; height: 5.5rem; margin: -2.75rem 0 0 -2.75rem; border-radius: 50%;
  display: grid; place-items: center; font:500 .8rem/1 var(--b-font-body);
  background: var(--zb-anim-fill); color: var(--zb-anim-fill-ink);
  scale: 0; transition: scale .45s var(--zb-anim-ease)}
.zb-cursor.on { scale: 1}

/* Header che si nasconde scendendo e torna risalendo */
[data-anim="sticky-header-hide"] { transition: translate var(--zb-hd, .6s) var(--zb-he, var(--zb-anim-ease)) var(--zb-hdl, 0s)}
[data-anim="sticky-header-hide"].zb-hide { translate: 0 -110%}

@media (prefers-reduced-motion: reduce) {
  .zb-mq-track { animation: none}
  [data-anim="sticky-header-hide"].zb-hide { translate: none}
}
