/* =============================================================================
   motion.css — animazioni, parallasse, reveal allo scroll
   Proprietario: agente A3 (round 2). Nessun altro agente scrive in questo file.
   Dipende da main.css (design system): usa i token, non ridefinirli.

   REGOLE STRUTTURALI (CONTRACT §12.3)
   1. Tutto quello che si muove sta dentro `prefers-reduced-motion: no-preference`.
      In fondo al file c'è comunque un blocco `reduce` che azzera ogni residuo.
   2. Si animano SOLO opacity, transform e clip-path: nessuna proprietà che
      rifluisca il layout, quindi CLS invariato.
   3. Lo stato iniziale nascosto vive sotto `.fg-motion-on`, classe messa da
      motion.js: senza JavaScript la pagina resta completa e leggibile.

   INDICE
   0. Contenimento orizzontale
   1. Reveal allo scroll
   2. Rivelazione a maschera (clip-path)
   3. Parallasse
   4. Ingresso della pagina
   5. Hover ricchi (estensione di main.css, non duplicazione)
   6. Movimento ridotto
   ============================================================================= */

/* -----------------------------------------------------------------------------
   0. Contenimento orizzontale

   I reveal laterali traslano di qualche rem: senza contenimento, per la frazione
   di secondo dell'animazione la pagina guadagnerebbe una barra di scorrimento
   orizzontale. `overflow-x: clip` (non `hidden`) non crea un contenitore di
   scorrimento, quindi gli elementi `sticky` interni continuano a funzionare.
   Si applica solo a <main>: la testata fissa e il menu mobile stanno fuori.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
	.fg-motion-on .fg-main {
		overflow-x: clip;
	}
}

/* -----------------------------------------------------------------------------
   1. Reveal allo scroll — data-fg-reveal="up|left|right|zoom"

   Lo stato di partenza è descritto da tre variabili locali, così esiste una sola
   dichiarazione di `transform` e le varianti si limitano a cambiare i numeri.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
	.fg-motion-on .fg-reveal {
		--fg-rv-x: 0;
		--fg-rv-y: 0;
		--fg-rv-s: 1;
		--fg-rv-dur: .7s;
		--fg-rv-delay: 0s;

		opacity: 0;
		transform: translate3d(var(--fg-rv-x), var(--fg-rv-y), 0) scale(var(--fg-rv-s));
		transition:
			opacity var(--fg-rv-dur) var(--fg-ease, ease) var(--fg-rv-delay),
			transform var(--fg-rv-dur) var(--fg-ease, ease) var(--fg-rv-delay),
			clip-path var(--fg-rv-dur) var(--fg-ease, ease) var(--fg-rv-delay);
		will-change: opacity, transform;
	}

	/* Ingresso dal basso: il movimento standard delle sezioni. */
	.fg-motion-on .fg-reveal[data-fg-reveal="up"] {
		--fg-rv-y: var(--fg-s4, 2rem);
	}

	/* Ingressi laterali: più ampi e più lenti, sono quelli che si notano. */
	.fg-motion-on .fg-reveal[data-fg-reveal="left"] {
		--fg-rv-x: calc(var(--fg-s5, 3rem) * -1);
		--fg-rv-dur: .85s;
	}

	.fg-motion-on .fg-reveal[data-fg-reveal="right"] {
		--fg-rv-x: var(--fg-s5, 3rem);
		--fg-rv-dur: .85s;
	}

	.fg-motion-on .fg-reveal[data-fg-reveal="zoom"] {
		--fg-rv-s: .92;
		--fg-rv-y: var(--fg-s2, 1rem);
		--fg-rv-dur: .9s;
	}

	/* Scaglionamento a cascata: data-fg-reveal-delay="1|2|3". */
	.fg-motion-on .fg-reveal[data-fg-reveal-delay="1"] { --fg-rv-delay: .12s; }
	.fg-motion-on .fg-reveal[data-fg-reveal-delay="2"] { --fg-rv-delay: .24s; }
	.fg-motion-on .fg-reveal[data-fg-reveal-delay="3"] { --fg-rv-delay: .36s; }

	/* Sotto i 600px gli spostamenti laterali si accorciano: su uno schermo
	   stretto un ingresso da 3rem sembra uno scatto, non un movimento. */
	@media (max-width: 599px) {
		.fg-motion-on .fg-reveal[data-fg-reveal="left"] {
			--fg-rv-x: calc(var(--fg-s3, 1.5rem) * -1);
		}

		.fg-motion-on .fg-reveal[data-fg-reveal="right"] {
			--fg-rv-x: var(--fg-s3, 1.5rem);
		}

		.fg-motion-on .fg-reveal[data-fg-reveal="up"] {
			--fg-rv-y: var(--fg-s3, 1.5rem);
		}
	}

	/* Rivelazione a maschera — vedi §2. Lo stato iniziale sta qui, prima dello
	   stato finale: `.fg-reveal--mask` e `.is-in` hanno la stessa specificità,
	   quindi vince chi è scritto dopo. Se questa regola stesse più in basso, le
	   immagini con maschera resterebbero tagliate per sempre. */
	.fg-motion-on .fg-reveal.fg-reveal--mask {
		--fg-rv-dur: 1s;

		opacity: 1;
		clip-path: inset(0 0 100% 0);
		will-change: opacity, transform, clip-path;
	}

	/* Stato finale. */
	.fg-motion-on .fg-reveal.is-in {
		opacity: 1;
		transform: translate3d(0, 0, 0) scale(1);
		clip-path: inset(0 0 0 0);
	}

	/* A transizione conclusa motion.js aggiunge questa classe: l'elemento torna
	   completamente "pulito", senza transform, clip-path né will-change. Evita di
	   lasciare 88 contesti di impilamento e altrettanti layer in memoria. */
	.fg-motion-on .fg-reveal.fg-reveal--done {
		opacity: 1;
		transform: none;
		clip-path: none;
		transition: none;
		will-change: auto;
	}
}

/* -----------------------------------------------------------------------------
   2. Rivelazione a maschera

   motion.js aggiunge `.fg-reveal--mask` solo ai contenitori di immagini
   (figure, picture, *__media, *__foto). La foto si scopre dal basso verso l'alto
   mentre il blocco entra: è l'effetto più vistoso della pagina e non tocca il
   layout, perché clip-path non rifluisce nulla.

   Con la maschera l'opacità resta a 1: sfumare E scoprire insieme rende il
   movimento molle, si scopre e basta.

   ⚠️ La regola vive nel §1, subito prima dello stato finale, per ragioni di
   cascata: `.fg-reveal--mask` e `.is-in` hanno la stessa specificità e qui
   vincerebbe la maschera, lasciando le foto tagliate per sempre.
   -------------------------------------------------------------------------- */

/* -----------------------------------------------------------------------------
   3. Parallasse — data-fg-parallax="0.15"

   motion.js marca la cassa (`.fg-parallax`) e il soggetto da muovere
   (`.fg-parallax__target`), e scrive la sola variabile `--fg-py` dentro un
   requestAnimationFrame. Qui si dichiara la trasformazione, una volta sola.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
	.fg-motion-on .fg-parallax {
		overflow: hidden;
	}

	.fg-motion-on .fg-parallax__target {
		transform: translate3d(0, var(--fg-py, 0px), 0) scale(var(--fg-ps, 1));
		will-change: transform;
		backface-visibility: hidden;
	}

	/* Il margine di scorrimento.

	   Le casse in parallasse preparate dai fogli d'area (`.fg-chi-siamo-home__img`
	   al 112%, `.fg-stihl__foto` al 114%) hanno già l'immagine più alta del
	   contenitore, quindi restano a scala 1. L'immagine dell'hero invece è alta
	   esattamente quanto la sezione: le serve il 14% in più, altrimenti scorrendo
	   scoprirebbe una striscia vuota.

	   ⚠️ Il margine si prende con `scale`, non con height/top. Provato: ridefinire
	   l'immagine dell'hero come `position: absolute; height: 114%` la rendeva un
	   livello di pittura a sé che finiva dentro il riflusso da caricamento del
	   webfont, già presente nel round 1 — CLS della home da 0,015 a 0,041. Con la
	   sola `scale` l'immagine non partecipa mai al layout: CLS invariato e LCP
	   intatto, perché la foto viene decodificata e dipinta come sempre. */
	.fg-motion-on .fg-hero__media.fg-parallax .fg-parallax__target {
		--fg-ps: 1.14;
	}
}

/* -----------------------------------------------------------------------------
   4. Ingresso della pagina

   Una barra sottile arancio/verde attraversa il bordo alto della finestra e
   svanisce. È `position: fixed`, fuori dal flusso e `pointer-events: none`:
   non sposta un pixel, non copre niente, non intercetta clic. Discreta per
   scelta — una tendina a schermo pieno nasconderebbe il contenuto, che è
   esattamente ciò che il contratto vieta.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
	.fg-motion-sweep {
		position: fixed;
		top: 0;
		left: 0;
		z-index: 500;
		width: 100%;
		height: 3px;
		background: linear-gradient(
			90deg,
			var(--fg-orange, #EF731D) 0%,
			var(--fg-green, #45AD30) 55%,
			var(--fg-orange, #EF731D) 100%
		);
		transform-origin: left center;
		pointer-events: none;
		animation: fg-sweep .9s var(--fg-ease, ease) forwards;
	}

	@keyframes fg-sweep {
		0%   { transform: scaleX(0); opacity: 1; }
		70%  { transform: scaleX(1); opacity: 1; }
		100% { transform: scaleX(1); opacity: 0; }
	}
}

/* -----------------------------------------------------------------------------
   5. Hover ricchi

   main.css (A1) definisce già il sollevamento delle card, lo zoom della foto
   della card e il colore dei bottoni; chrome.css (A4) la sottolineatura animata
   della navigazione; brand-grid.php il sollevamento della cassa dei loghi.
   Qui si aggiunge solo ciò che manca, senza ridichiarare le regole altrui.
   -------------------------------------------------------------------------- */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {

	/* La freccia del link "fantasma" avanza quando si passa sulla CARD intera,
	   non solo sul link: la card si comporta come un unico bersaglio.
	   main.css muove la freccia solo su `.fg-btn--ghost:hover`; questa è
	   l'estensione al passaggio sulla card, non una riscrittura.
	   Le card servizio non compaiono qui: `.fg-service-card` ha già in
	   servizi.css sollevamento, zoom, velo e freccia. */
	.fg-card .fg-btn--ghost::after {
		transition: transform .3s var(--fg-ease, ease);
	}

	.fg-card:hover .fg-btn--ghost::after,
	.fg-card:focus-within .fg-btn--ghost::after {
		transform: translateX(.4rem);
	}

	/* Loghi dei marchi: la cassa si solleva già, qui il logo dentro cresce.
	   Serve un selettore a tre classi per battere lo <style> in linea del
	   template, che nel documento sta più avanti di questo foglio. */
	.fg-motion-on .fg-brands .fg-brand-item img,
	.fg-motion-on .fg-brands .fg-brand-item__wordmark {
		transition: transform .3s var(--fg-ease, ease);
	}

	.fg-motion-on .fg-brands .fg-brand-item:hover img,
	.fg-motion-on .fg-brands .fg-brand-item:focus-visible img,
	.fg-motion-on .fg-brands .fg-brand-item:hover .fg-brand-item__wordmark,
	.fg-motion-on .fg-brands .fg-brand-item:focus-visible .fg-brand-item__wordmark {
		transform: scale(1.07);
	}

	/* Le griglie di foto reagiscono come le card. */
	.fg-motion-on .fg-mosaico__item img {
		transition: transform .45s var(--fg-ease, ease);
	}

	.fg-motion-on .fg-mosaico__item:hover img {
		transform: scale(1.05);
	}
}

/* -----------------------------------------------------------------------------
   6. Movimento ridotto

   Cintura e bretelle: motion.js non mette nemmeno `.fg-motion-on` quando la
   preferenza è "reduce", ma se la preferenza cambia a pagina aperta prima che il
   JS smonti lo stato, queste regole garantiscono che tutto sia fermo e visibile.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	.fg-reveal,
	.fg-reveal.fg-reveal--mask {
		opacity: 1 !important;
		transform: none !important;
		clip-path: none !important;
		transition: none !important;
		will-change: auto !important;
	}

	.fg-parallax__target {
		transform: none !important;
		will-change: auto !important;
	}

	.fg-motion-sweep {
		display: none !important;
	}
}
