/*
 * On The Spot — the motion system.
 *
 * The entire animation vocabulary for the site is three things:
 *   1. the hero (one signature movement)
 *   2. .ots-reveal (the one repeating content reveal)
 *   3. one hover behaviour on cards
 *
 * Nothing else moves. Per §6.4 of the build directive: no parallax beyond the
 * hero, no counters, no auto-advancing carousels, no typing text, no cursor
 * followers, no page-transition libraries.
 *
 * Everything is native CSS scroll-driven animation, which runs on the
 * compositor thread. No JS scroll handlers, so no INP cost.
 *
 * TWO RULES THAT MUST NEVER BE BROKEN:
 *   - The default (no @supports) state is the FINISHED state. A browser
 *     without animation-timeline must see a complete page, never an
 *     invisible one.
 *   - Every animation is disabled under prefers-reduced-motion.
 */

/* ---------------------------------------------------------------------------
 * 1. Content reveal — the one repeating animation
 * ------------------------------------------------------------------------ */

/* Default: fully visible. This is what old browsers get, and it is correct. */
.ots-reveal {
	opacity: 1;
	transform: none;
}

@keyframes ots-rise {
	from {
		opacity: 0;
		transform: translateY(28px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

@supports (animation-timeline: view()) {
	.ots-reveal {
		animation: ots-rise linear both;
		animation-timeline: view();
		animation-range: entry 15% cover 35%;
	}
}

/* Stagger for grids — children reveal a beat apart, not all at once. */
@supports (animation-timeline: view()) {
	.ots-reveal-group > * {
		animation: ots-rise linear both;
		animation-timeline: view();
	}
	.ots-reveal-group > :nth-child(1) { animation-range: entry 10% cover 30%; }
	.ots-reveal-group > :nth-child(2) { animation-range: entry 14% cover 34%; }
	.ots-reveal-group > :nth-child(3) { animation-range: entry 18% cover 38%; }
	.ots-reveal-group > :nth-child(4) { animation-range: entry 22% cover 42%; }
	.ots-reveal-group > :nth-child(5) { animation-range: entry 26% cover 46%; }
	.ots-reveal-group > :nth-child(6) { animation-range: entry 30% cover 50%; }
}

/* ---------------------------------------------------------------------------
 * 2. The hero — the single signature movement
 *
 * As the visitor scrolls, the footage scales up slightly and dims while the
 * headline holds position. The kitchen sits behind everything.
 * ------------------------------------------------------------------------ */

.ots-hero {
	position: relative;
	isolation: isolate;
	overflow: clip;
}

.ots-hero__media {
	position: absolute;
	inset: 0;
	z-index: -1;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transform-origin: center 40%;
}

@keyframes ots-hero-scale {
	from {
		transform: scale(1);
		filter: brightness(1);
	}
	to {
		transform: scale(1.12);
		filter: brightness(0.55);
	}
}

@supports (animation-timeline: scroll()) {
	.ots-hero__media {
		animation: ots-hero-scale linear both;
		animation-timeline: scroll();
		animation-range: 0 60vh;
	}
}

/*
 * Text never sits directly on moving footage — contrast against video is
 * unmeasurable. This is the scrim that makes the headline legible and
 * WCAG-checkable.
 */
.ots-hero__scrim {
	position: absolute;
	inset: 0;
	z-index: -1;
	background: linear-gradient(
		to bottom,
		rgb(14 14 15 / 0.35) 0%,
		rgb(14 14 15 / 0.55) 45%,
		rgb(14 14 15 / 0.85) 100%
	);
}

.ots-hero__inner {
	position: relative;
	z-index: 1;
}

/* ---------------------------------------------------------------------------
 * 3. Card hover — the one hover behaviour
 * ------------------------------------------------------------------------ */

.ots-card {
	transition:
		transform var(--wp--custom--transition--base, 260ms cubic-bezier(.2, .7, .3, 1)),
		box-shadow var(--wp--custom--transition--base, 260ms cubic-bezier(.2, .7, .3, 1));
	will-change: transform;
}

@media (hover: hover) {
	.ots-card:hover,
	.ots-card:focus-within {
		transform: translateY(-4px);
		box-shadow: 0 12px 32px rgb(14 14 15 / 0.18);
	}
}

/* ---------------------------------------------------------------------------
 * 4. Reduced motion — not optional
 *
 * A meaningful share of this audience is older and vestibular sensitivity is
 * real. Everything above resolves to its finished state.
 * ------------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
	.ots-reveal,
	.ots-reveal-group > *,
	.ots-hero__media,
	.ots-card {
		animation: none !important;
		transition: none !important;
		opacity: 1 !important;
		transform: none !important;
		filter: none !important;
	}
}

/* ---------------------------------------------------------------------------
 * 5. Layout helpers the patterns rely on
 * ------------------------------------------------------------------------ */

/* The service ladder — six cards, ascending price. */
.ots-ladder {
	display: grid;
	gap: var(--wp--preset--spacing--30);
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
}

/* Sticky mobile call/enquire bar. Appears below the fold. */
.ots-stickybar {
	position: fixed;
	inset-inline: 0;
	bottom: 0;
	z-index: 90;
	display: grid;
	grid-template-columns: 1fr 1fr;
	background: var(--wp--preset--color--base);
	box-shadow: 0 -2px 20px rgb(14 14 15 / 0.35);
	padding-bottom: env(safe-area-inset-bottom, 0);
}

@media (min-width: 782px) {
	.ots-stickybar {
		display: none;
	}
}
