/* FlexBuild - animations.css
   Định nghĩa trạng thái "ẩn ban đầu" cho từng kiểu hiệu ứng và trạng thái
   "hiện" khi phần tử được scroll-animate.js gắn thêm class .is-visible
   (dùng IntersectionObserver, xem assets/js/scroll-animate.js). */

.flexbuild-animate {
	transition-property: opacity, transform;
	transition-duration: 0.6s;
	transition-timing-function: cubic-bezier( 0.25, 0.1, 0.25, 1 );
	transition-delay: var( --flexbuild-animate-delay, 0ms );
}

.flexbuild-animate:not( .is-visible ) {
	opacity: 0;
}

.flexbuild-animate[data-fb-animate="fade-up"]:not( .is-visible ) {
	transform: translateY( 32px );
}

.flexbuild-animate[data-fb-animate="slide-left"]:not( .is-visible ) {
	transform: translateX( -48px );
}

.flexbuild-animate[data-fb-animate="slide-right"]:not( .is-visible ) {
	transform: translateX( 48px );
}

.flexbuild-animate[data-fb-animate="zoom-in"]:not( .is-visible ) {
	transform: scale( 0.9 );
}

.flexbuild-animate.is-visible {
	opacity: 1;
	transform: none;
}

/* Tôn trọng prefers-reduced-motion (Part 9): hiện thẳng, không animate. */
@media (prefers-reduced-motion: reduce) {
	.flexbuild-animate,
	.flexbuild-animate:not( .is-visible ) {
		opacity: 1 !important;
		transform: none !important;
		transition: none !important;
	}
}
