/* ==========================================================================
   Avarida Group — staggered title reveal (site-wide, titles only).

   CSS half of the vanilla <TextEffect /> port. Each segment carries its index
   as --ate-i; the per-segment delay is index * stagger + the element's delay,
   which is exactly how framer-motion's staggerChildren + delayChildren behave.
   ========================================================================== */

.ate {
	/* Fallbacks so a segment is never stuck invisible if JS set nothing. */
	--ate-stagger: 50ms;
	--ate-delay: 0ms;
}

.ate .ate__seg {
	display: inline-block;
	white-space: pre-wrap;
	will-change: opacity, transform, filter;
	animation-duration: 620ms;
	animation-timing-function: cubic-bezier( 0.22, 0.61, 0.36, 1 );
	animation-fill-mode: both;
	animation-play-state: paused;
	animation-delay: calc( var( --ate-i ) * var( --ate-stagger ) + var( --ate-delay ) );
}

/* Nothing runs until the title scrolls into view. */
.ate.is-in .ate__seg { animation-play-state: running; }

/* Pre-animation resting state, per preset, so there's no flash of final text. */
.ate--blur  .ate__seg { opacity: 0; filter: blur( 12px ); }
.ate--fade  .ate__seg { opacity: 0; }
.ate--slide .ate__seg { opacity: 0; transform: translateY( 20px ); }
.ate--scale .ate__seg { opacity: 0; transform: scale( 0 ); }
.ate--shake .ate__seg { opacity: 1; }

.ate--blur.is-in  .ate__seg { animation-name: ate-blur; }
.ate--fade.is-in  .ate__seg { animation-name: ate-fade; }
.ate--slide.is-in .ate__seg { animation-name: ate-slide; }
.ate--scale.is-in .ate__seg { animation-name: ate-scale; }
.ate--shake.is-in .ate__seg { animation-name: ate-shake; animation-duration: 500ms; }

@keyframes ate-blur {
	from { opacity: 0; filter: blur( 12px ); }
	to   { opacity: 1; filter: blur( 0 ); }
}
@keyframes ate-fade {
	from { opacity: 0; }
	to   { opacity: 1; }
}
@keyframes ate-slide {
	from { opacity: 0; transform: translateY( 20px ); }
	to   { opacity: 1; transform: translateY( 0 ); }
}
@keyframes ate-scale {
	from { opacity: 0; transform: scale( 0 ); }
	to   { opacity: 1; transform: scale( 1 ); }
}
@keyframes ate-shake {
	0%   { transform: translateX( 0 ); }
	25%  { transform: translateX( -5px ); }
	50%  { transform: translateX( 5px ); }
	75%  { transform: translateX( -5px ); }
	100% { transform: translateX( 0 ); }
}

/* Atomic segments (the hero's gradient phrase) animate as a single unit and
   stay `display:inline`, so the gradient keeps one continuous painting box and
   the headline can still wrap mid-phrase on narrow screens. Transform-based
   presets don't apply to inline boxes, so those degrade to a clean fade —
   opacity and filter both animate on inline elements. */
.ate .ate__seg--atomic {
	display: inline;
	transform: none !important;
}

/* --------------------------------------------------------------------------
   Reduced motion — the script bails out too, this is the belt-and-braces half
   so text is never left mid-animation or invisible.
   -------------------------------------------------------------------------- */

@media ( prefers-reduced-motion: reduce ) {
	.ate .ate__seg {
		animation: none !important;
		opacity: 1 !important;
		filter: none !important;
		transform: none !important;
	}
}
