/* ==========================================================================
   IntellActX — animations.css
   The ONLY file that defines motion. Structure/appearance lives elsewhere.

   Rules honoured here:
   - Only `transform` and `opacity` are animated (shadows fade via a
     pseudo-element, never by animating box-shadow itself).
   - Decorative motion sits behind `prefers-reduced-motion: no-preference`,
     so "reduce" users simply get the finished state.
   - Hover effects require `(hover: hover) and (pointer: fine)`; touch
     devices get `:active` feedback instead.
   - Scroll triggers use IntersectionObserver (see assets/js/main.js).
     There are no scroll listeners anywhere in this project.
   ========================================================================== */

/* -------------------------------------------------------------------------
   1. Reveal on scroll
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}

	/* Gated on html.js so that without JavaScript the content is simply
	   visible instead of stuck at opacity 0. */
	html.js .reveal {
		opacity: 0;
		transform: translateY(12px);
		transition:
			opacity var(--dur-reveal) var(--ease),
			transform var(--dur-reveal) var(--ease);
	}

	html.js .reveal.is-visible {
		opacity: 1;
		transform: none;
	}

	/* Page transition: a short fade + 8px slide on load. */
	.page-enter {
		animation: page-enter var(--dur-300) var(--ease) both;
	}

	@keyframes page-enter {
		from {
			opacity: 0;
			transform: translateY(8px);
		}
		to {
			opacity: 1;
			transform: none;
		}
	}
}

/* Mobile: fade only. Translation on small screens causes jank and
   contributes to motion sickness. */
@media (max-width: 47.99em) {
	@media (prefers-reduced-motion: no-preference) {
		html.js .reveal {
			transform: none;
		}
	}

	.stagger > .reveal {
		transition-delay: 0ms;
	}
}

/* -------------------------------------------------------------------------
   2. Stagger — set --i on children with JS (or inline style)
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
	@media (min-width: 48em) {
		.stagger > .reveal {
			transition-delay: calc(var(--i, 0) * var(--stagger-step));
		}
	}
}

/* -------------------------------------------------------------------------
   3. Ambient motion — slow, almost invisible
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
	@media (min-width: 48em) {
		.canvas::after {
			animation: ambient-drift var(--dur-ambient) var(--ease-in-out) infinite alternate;
		}
	}

	@keyframes ambient-drift {
		from {
			transform: translate3d(-1.5%, -1%, 0);
		}
		to {
			transform: translate3d(1.5%, 1%, 0);
		}
	}
}

/* -------------------------------------------------------------------------
   4. Buttons
   ------------------------------------------------------------------------- */
.btn {
	transition:
		background-color var(--dur-200) var(--ease),
		border-color var(--dur-200) var(--ease),
		color var(--dur-200) var(--ease),
		transform var(--dur-150) var(--ease);
}

.btn::after {
	transition: opacity var(--dur-200) var(--ease);
}

@media (hover: hover) and (pointer: fine) {
	.btn:hover {
		transform: translateY(-2px);
	}

	.btn:hover::after {
		opacity: 1;
	}

	.btn--primary:hover {
		background-color: var(--accent-700);
	}

	.btn--secondary:hover {
		border-color: var(--accent-600);
		color: var(--accent-700);
	}
}

@media (hover: none), (pointer: coarse) {
	.btn:active {
		transform: scale(0.98);
	}
}

/* -------------------------------------------------------------------------
   5. Cards & links
   ------------------------------------------------------------------------- */
.card,
.tile,
.campus-card,
.quote {
	transition:
		transform var(--dur-200) var(--ease),
		border-color var(--dur-200) var(--ease);
}

.card::after,
.tile::after {
	transition: opacity var(--dur-200) var(--ease);
}

.link-arrow__icon {
	transition: transform var(--dur-200) var(--ease);
}

@media (prefers-reduced-motion: no-preference) {
	.campus-card__media img,
	.media-frame img {
		transition: transform var(--dur-300) var(--ease);
	}
}

@media (hover: hover) and (pointer: fine) {
	.card:hover,
	.tile:hover,
	.campus-card:hover,
	.quote:hover {
		transform: translateY(-4px);
		border-color: var(--accent-200);
	}

	.card:hover::after,
	.tile:hover::after {
		opacity: 1;
	}

	.link-arrow:hover .link-arrow__icon {
		transform: translateX(3px);
	}

	.campus-card:hover .campus-card__media img,
	.media-frame:hover img {
		transform: scale(1.02);
	}

	.nav__link:hover {
		background-color: var(--surface-muted);
		color: var(--text);
	}

	.footer__link:hover {
		color: var(--white);
	}
}

@media (hover: none), (pointer: coarse) {
	.card:active,
	.tile:active,
	.campus-card:active {
		transform: scale(0.99);
	}
}

/* -------------------------------------------------------------------------
   6. Accordion (native <details>) — icon rotation only
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
	.faq__icon {
		transition: transform var(--dur-200) var(--ease);
	}
}

@media (hover: hover) and (pointer: fine) {
	.btn--inverse:hover {
		background-color: var(--white);
		border-color: var(--white);
		color: var(--ink-900);
	}
}

/* -------------------------------------------------------------------------
   7. Mobile bottom-sheet navigation (slides up in 200ms)
   ------------------------------------------------------------------------- */
@media (max-width: 63.99em) {
	.nav {
		transition:
			transform var(--dur-200) var(--ease),
			opacity var(--dur-200) var(--ease),
			visibility 0s linear var(--dur-200);
	}

	.nav.is-open {
		transition-delay: 0s;
	}

	.nav-backdrop {
		transition: opacity var(--dur-200) var(--ease);
	}
}

/* -------------------------------------------------------------------------
   8. Form feedback
   ------------------------------------------------------------------------- */
.form-status {
	transition: opacity var(--dur-200) var(--ease);
}

/* -------------------------------------------------------------------------
   9. Safety net — when a visitor asks for less motion, ship the end state.
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}

	.reveal,
	.page-enter {
		opacity: 1;
		transform: none;
	}
}
