/* ============================================
   ARC FALL - Animation Primitives
   Foundation classes for scroll-driven animations,
   counters, tilts and skill bar fills.
   ============================================ */

/* ---------- reveal-on-scroll ----------
   Element starts hidden, slides up when JS adds .is-visible. */
.reveal-on-scroll {
	opacity: 0;
	transform: translateY(20px);
	transition: opacity 0.6s ease-out, transform 0.6s ease-out;
	will-change: opacity, transform;
}

.reveal-on-scroll.is-visible {
	opacity: 1;
	transform: translateY(0);
}

/* ---------- stagger-children ----------
   Parent marker. The transition-delay on each direct child
   .reveal-on-scroll is applied by JS (index * 60ms).
   No CSS state needed beyond what reveal-on-scroll already provides. */
.stagger-children > .reveal-on-scroll {
	/* JS sets transition-delay inline; this rule documents the contract. */
}

/* ---------- count-up ----------
   No CSS state — JS animates innerText. The class is a marker only,
   but we define it for clarity and to optionally hide content prior to
   first paint if desired by an integrator. */
.count-up {
	display: inline-block;
	font-variant-numeric: tabular-nums;
}

/* ---------- tilt-card ----------
   Provides the 3D context. JS applies the rotation transform.
   Reset transition is smooth on mouseleave. */
.tilt-card {
	transform-style: preserve-3d;
	transform: perspective(800px) rotateX(0deg) rotateY(0deg);
	transition: transform 0.4s ease-out;
	will-change: transform;
}

.tilt-card.is-tilting {
	/* Active state during mousemove — JS overrides transition for snappy follow. */
	transition: transform 0.08s linear;
}

/* ---------- skill-bar-fill ----------
   The .skill-bar wrapper is provided by the integrator. The fill
   reads its target from inline `style="--target-width: 73%;"`.
   Animation uses width (intentional exception to compositor-friendly
   transform/opacity rule, since the fill effect requires width changes). */
.skill-bar {
	width: 100%;
	height: 8px;
	background: var(--bg-tertiary, #1c2128);
	border-radius: 999px;
	overflow: hidden;
	position: relative;
}

.skill-bar-fill {
	display: block;
	height: 100%;
	width: 0;
	background: var(--accent, #ff4500);
	border-radius: inherit;
	will-change: width;
	transition: width 1.2s ease-out;
}

.skill-bar.is-visible .skill-bar-fill {
	width: var(--target-width, 0%);
}

/* ---------- prefers-reduced-motion ----------
   Honor the user preference: skip transitions/transforms,
   jump directly to the final state. */
@media (prefers-reduced-motion: reduce) {
	.reveal-on-scroll,
	.reveal-on-scroll.is-visible {
		opacity: 1 !important;
		transform: none !important;
		transition: none !important;
	}

	.tilt-card,
	.tilt-card.is-tilting {
		transform: none !important;
		transition: none !important;
	}

	.skill-bar-fill {
		transition: none !important;
		width: var(--target-width, 0%) !important;
	}

	.count-up {
		/* JS detects reduced motion and writes the final value immediately. */
	}
}
