/*
 * Hero carousel — the featured-product showcase at the top of the home page.
 *
 * Composed as a packaging proof rather than a split hero: the packshot sits on
 * a lit plate inside registration marks, with a clinical specification grid
 * under the name and a vertical rail of dispensing data down the right edge.
 *
 * Every slide ships in the markup. Only the one carrying `data-active` is
 * displayed, so with JavaScript off the first slide simply stays put.
 */

.hero {
	position: relative;
	display: flex;
	min-height: 100svh;
	flex-direction: column;
	justify-content: center;
	overflow: hidden;
	background-color: var(--color-signal);
	color: #fff;
	padding-top: 7rem;
	padding-bottom: 2rem;
	/* Horizontal drags change slide; vertical ones must still scroll the page. */
	touch-action: pan-y;
}

@media (width >= 64rem) {
	.hero {
		padding-top: 8rem;
	}
}

/* ─────────────────────────────────────────────────────── backdrop ───── */

.hero__backdrop {
	pointer-events: none;
	position: absolute;
	inset: 0;
	overflow: hidden;
}

/* 1 — photographic texture */
.hero__texture {
	position: absolute;
	inset: 0;
	opacity: 0.22;
}

.hero__texture img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* 2 — per-slide colour bloom, taken from the packshot itself */
.hero-bloom {
	position: absolute;
	right: -15%;
	top: 50%;
	height: 42rem;
	width: 42rem;
	transform: translateY(-50%);
	filter: blur(110px);
	opacity: 0;
	transition: opacity 1200ms var(--ease-precise);
}

.hero-bloom[data-active] {
	opacity: 0.45;
}

.hero-bloom img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	filter: saturate(1.5);
}

@media (prefers-reduced-motion: no-preference) {
	.hero-bloom[data-active] {
		animation: pulse-dot 2.4s ease-in-out infinite;
	}
}

/* 3 — legibility wash */
.hero__wash {
	position: absolute;
	inset: 0;
	background-image: linear-gradient(
		to right,
		var(--color-signal-dark),
		rgb(4 27 18 / 0.9) 50%,
		rgb(7 42 29 / 0.7)
	);
}

.hero__wash--foot {
	background-image: linear-gradient(to top, rgb(4 27 18 / 0.8), transparent);
}

/* 4 — ruled column guides */
.hero__guides {
	position: absolute;
	inset: 0;
	opacity: 0.06;
	background-image: repeating-linear-gradient(to right, #fff 0 1px, transparent 1px 12.5%);
}

/* ──────────────────────────────────────────────── bled type marks ───── */

.hero__catalogue-number {
	pointer-events: none;
	position: absolute;
	left: -2.5rem;
	top: 3rem;
	user-select: none;
	font-family: var(--font-mono);
	font-size: 13rem;
	line-height: 1;
	color: rgb(255 255 255 / 0.05);
}

@media (width >= 64rem) {
	.hero__catalogue-number {
		font-size: 24rem;
	}
}

.hero__vertical-rail {
	pointer-events: none;
	display: none;
	position: absolute;
	right: 0.75rem;
	top: 50%;
	transform: translateY(-50%);
	writing-mode: vertical-rl;
	font-family: var(--font-mono);
	font-size: 0.625rem;
	text-transform: uppercase;
	letter-spacing: 0.32em;
	color: rgb(255 255 255 / 0.35);
}

@media (width >= 80rem) {
	.hero__vertical-rail {
		display: block;
	}
}

.hero__inner {
	position: relative;
}

/* ──────────────────────────────────────────────────────── slides ───── */

/*
 * Slides are stacked in one grid cell rather than hidden, so the section keeps
 * the height of its tallest slide and nothing jumps as they change.
 */
.hero__slides {
	display: grid;
	grid-template-areas: 'slide';
}

.hero-slide {
	grid-area: slide;
	visibility: hidden;
	opacity: 0;
	transition: opacity var(--duration-calm) var(--ease-linear-out);
}

.hero-slide[data-active] {
	visibility: visible;
	opacity: 1;
}

.hero-slide__grid {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	align-items: center;
	column-gap: 2rem;
	row-gap: 3rem;
}

.hero-slide__detail {
	grid-column: span 12;
	order: 2;
}

.hero-slide__packshot {
	grid-column: span 12;
	order: 1;
}

@media (width >= 64rem) {
	.hero-slide__detail {
		grid-column: span 6;
		order: 0;
	}

	.hero-slide__packshot {
		grid-column: 8 / span 5;
		order: 0;
	}
}

/*
 * Each element of the active slide rises in, one beat after the last. The
 * animation is re-triggered by js/slider.js, which removes and re-adds
 * `data-active`.
 */
.hero-slide[data-active] .hero-slide__eyebrow,
.hero-slide[data-active] .hero-slide__title,
.hero-slide[data-active] .hero-spec,
.hero-slide[data-active] .hero-slide__summary,
.hero-slide[data-active] .hero-slide__price {
	animation: rise-in 800ms var(--ease-precise) both;
}

.hero-slide[data-active] .hero-slide__title {
	animation-delay: 70ms;
}

.hero-slide[data-active] .hero-spec {
	animation-delay: 150ms;
}

.hero-slide[data-active] .hero-slide__summary {
	animation-delay: 210ms;
}

.hero-slide[data-active] .hero-slide__price {
	animation-delay: 270ms;
}

.hero-slide__title {
	margin-top: 1.5rem;
	color: #fff;
}

/* ─────────────────────────────────────────── specification grid ───── */

.hero-spec {
	margin-top: 2.25rem;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	border-top: 1px solid var(--paper-20);
}

@media (width >= 40rem) {
	.hero-spec {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

.hero-spec__cell {
	border-bottom: 1px solid var(--paper-12);
	border-right: 1px solid var(--paper-12);
	padding-block: 1rem;
	padding-right: 1rem;
}

.hero-spec__cell:last-child {
	border-right: 0;
}

.hero-spec__term {
	font-family: var(--font-mono);
	font-size: 0.5625rem;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	color: var(--color-accent);
}

.hero-spec__value {
	margin-top: 0.5rem;
	font-family: var(--font-mono);
	font-size: 0.75rem;
	line-height: 1.35;
	color: var(--paper-80);
}

.hero-slide__summary {
	margin-top: 1.75rem;
	max-width: 28rem;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: rgb(255 255 255 / 0.65);
}

/* ────────────────────────────────────────────── price and actions ───── */

.hero-slide__actions {
	margin-top: 2.25rem;
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	column-gap: 2rem;
	row-gap: 1.25rem;
}

.hero-slide__price-row {
	margin-top: 0.375rem;
	display: flex;
	align-items: baseline;
	gap: 0.75rem;
}

.hero-slide__price-value {
	font-family: var(--font-mono);
	font-size: 2.25rem;
	line-height: 1;
	color: #fff;
	font-variant-numeric: tabular-nums;
}

.hero-slide__price-compare {
	font-family: var(--font-mono);
	font-size: 0.9375rem;
	color: var(--paper-45);
	text-decoration: line-through;
	font-variant-numeric: tabular-nums;
}

/* ────────────────────────────────────────────────────── packshot ───── */

.hero-plate {
	position: relative;
	margin-inline: auto;
	max-width: 28rem;
}

.hero-plate__image {
	position: relative;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	background-color: #fff;
}

.hero-plate__image img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/*
 * Slice transition.
 *
 * On a slide change the incoming packshot is rebuilt from vertical strips that
 * drop in from alternating edges. js/slider.js builds the strips, sets the
 * column count and each strip's slot, delay and direction, then throws the
 * whole overlay away once they have landed — so at rest this is a single
 * seamless image with no extra nodes, exactly as it was before.
 *
 * Strips sit above the image and below the registration marks and the tag,
 * both of which are z-index 20.
 */
.hero-plate__slices {
	pointer-events: none;
	position: absolute;
	inset: 0;
	z-index: 10;
	display: grid;
	grid-template-columns: repeat(var(--slice-count, 7), 1fr);
}

.hero-plate__slice {
	position: relative;
	overflow: hidden;
	background-color: #fff;
}

/*
 * The strip itself. Every one carries the whole image, scaled so that exactly
 * one column's worth shows through, and offset to its own slot — so the strips
 * reassemble into the original picture rather than repeating it.
 */
.hero-plate__slice::after {
	content: '';
	position: absolute;
	inset: 0;
	background-image: var(--slice-image);
	background-repeat: no-repeat;
	background-size: calc(var(--slice-count, 7) * 100%) 100%;
	background-position: var(--slice-position, 0%) center;
	animation: hero-slice-in 780ms var(--ease-precise) var(--slice-delay, 0ms) both;
}

@keyframes hero-slice-in {
	from {
		transform: translateY(var(--slice-from, -101%));
	}

	to {
		transform: translateY(0);
	}
}

/* Registration marks at the four corners. */
.hero-plate__mark {
	pointer-events: none;
	position: absolute;
	z-index: 20;
	width: 1.25rem;
	height: 1.25rem;
	border-color: var(--color-accent);
	border-style: solid;
	border-width: 0;
}

.hero-plate__mark--tl {
	top: -0.75rem;
	left: -0.75rem;
	border-top-width: 1px;
	border-left-width: 1px;
}

.hero-plate__mark--tr {
	top: -0.75rem;
	right: -0.75rem;
	border-top-width: 1px;
	border-right-width: 1px;
}

.hero-plate__mark--bl {
	bottom: -0.75rem;
	left: -0.75rem;
	border-bottom-width: 1px;
	border-left-width: 1px;
}

.hero-plate__mark--br {
	bottom: -0.75rem;
	right: -0.75rem;
	border-bottom-width: 1px;
	border-right-width: 1px;
}

/*
 * The two tags sit on the wrapper rather than inside the plate: the plate clips
 * its own overflow, which would shear them at the edge.
 */
.hero-plate__tag {
	position: absolute;
	left: -1rem;
	bottom: 1.5rem;
	z-index: 20;
	background-color: var(--color-signal-dark);
	padding: 0.5rem 0.75rem;
	box-shadow: var(--shadow-raised);
}

.hero-plate__tag-text,
.hero-plate__advice {
	font-family: var(--font-mono);
	font-size: 0.5625rem;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	color: var(--color-accent);
}

.hero-plate__advice {
	position: absolute;
	right: -1rem;
	top: 1.5rem;
	z-index: 20;
	background-color: var(--color-signal-dark);
	padding: 0.5rem 0.75rem;
	letter-spacing: 0.14em;
	box-shadow: var(--shadow-raised);
}

/* ─────────────────────────────────────────────────── thumbnail rail ───── */

.hero-rail {
	margin-top: 3.5rem;
	border-top: 1px solid var(--paper-15);
	padding-top: 1.25rem;
}

.hero-rail__row {
	display: flex;
	align-items: center;
	gap: 1.5rem;
}

.hero-rail__counter {
	flex: none;
}

.hero-rail__list {
	display: flex;
	flex: 1;
	gap: 0.75rem;
}

.hero-rail__item {
	min-width: 0;
	flex: 1;
}

.hero-rail__button {
	display: block;
	width: 100%;
	text-align: left;
}

.hero-rail__track {
	position: relative;
	display: block;
	height: 2px;
	width: 100%;
	background-color: var(--paper-20);
}

/*
 * The progress bar. On the current slide it sweeps across over the autoplay
 * interval; on the others it is a hover affordance only.
 */
.hero-rail__progress {
	position: absolute;
	inset-block: 0;
	left: 0;
	display: block;
	width: 100%;
	transform-origin: left;
	transform: scaleX(0);
	background-color: var(--paper-60);
	transition: transform var(--duration-calm) var(--ease-linear-out);
}

.hero-rail__button:hover .hero-rail__progress {
	transform: scaleX(1);
}

.hero-rail__button[aria-current='true'] .hero-rail__progress {
	background-color: var(--color-accent);
	transition: none;
	animation: hero-progress var(--hero-interval, 7000ms) linear both;
}

/* Paused, or motion reduced: the bar simply sits full. */
.hero-rail[data-paused] .hero-rail__button[aria-current='true'] .hero-rail__progress {
	animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
	.hero-rail__button[aria-current='true'] .hero-rail__progress {
		animation: none;
		transform: scaleX(1);
	}
}

@keyframes hero-progress {
	from {
		transform: scaleX(0);
	}
	to {
		transform: scaleX(1);
	}
}

.hero-rail__name {
	display: none;
	margin-top: 0.75rem;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-family: var(--font-mono);
	font-size: 0.625rem;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--paper-45);
	transition: color var(--duration-calm) var(--ease-linear-out);
}

@media (width >= 40rem) {
	.hero-rail__name {
		display: block;
	}
}

.hero-rail__button:hover .hero-rail__name {
	color: var(--paper-80);
}

.hero-rail__button[aria-current='true'] .hero-rail__name {
	color: #fff;
}

.hero-rail__controls {
	display: none;
	align-items: center;
	gap: 0.25rem;
}

@media (width >= 40rem) {
	.hero-rail__controls {
		display: flex;
	}
}

.hero-rail__control {
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	color: var(--paper-55);
	transition: color var(--duration-swift) var(--ease-linear-out);
}

.hero-rail__control:hover {
	color: var(--color-accent);
}

.hero-rail__icon {
	width: 1rem;
	height: 1rem;
}
