/* ─────────────────────────────────────────────────────────────
   GTD Desco — support equipment panels (#product_upsell_block).

   WHAT WAS WRONG

   Two boxes at `max-width: 49%` with an inline `margin-right: 1.5%`,
   the photograph as a background-image, 90px of padding and a fixed
   550px height with everything top-aligned — so a third of each
   panel was empty below its own button, and the button floated in
   the middle of a photograph with nothing under it.

   White type sat straight on the photograph. On the tracked carrier
   the copy ran over a red machine and a concrete wall; on the mud
   guzzler it ran over a yellow crane. The contrast was whatever the
   photograph happened to be that day.

   WHAT THIS DOES

   The content is anchored to the bottom of the frame and stands on
   a scrim, so it reads the same over any photograph. The top of the
   frame stays clear, which is where the machine actually is. The
   photograph is a real <img> now, so it can be moved inside a
   clipped frame rather than nudged with background-position.

   The moment is on hover and it is one thing arriving from three
   directions: the frame pushes in on the photograph, the rule under
   the title runs the width of the panel, and the ghost button fills.
   The rule is the same device the rig cards use for a spec group —
   one level up, doing the same job.

   Plain CSS in css/, for the same reason as the rest: the theme
   compiles through Compass and nobody has confirmed that build runs.
   ───────────────────────────────────────────────────────────── */

.gtd-upsell {
	--up-ink:    #ffffff;
	--up-quiet:  rgba(255, 255, 255, .82);
	--up-red:    #c60000;
	--up-ease:   cubic-bezier(.16, 1, .3, 1);

	max-width: 1800px;
	margin-inline: auto;
	padding-block: clamp(3rem, 7vw, 6rem) 0;
}

/* ── the lead ─────────────────────────────────────────────── */

/*
 * Held to a measure. It ran the full 1800px before, which put a
 * three-line sentence across a width no one reads a sentence at.
 */
/* Both IDs, because the theme's rule is `#product_upsell_block
   #produc-upsell-block-title { max-width: 80% }` — (2,0,0), which one ID plus
   a class does not reach. 80% of 1520px is not a measure anyone reads a
   sentence at. */
#product_upsell_block #produc-upsell-block-title.gtd-upsell__lead {
	max-width: 22ch;
	margin: 0 0 clamp(2rem, 4vw, 3.25rem);
	text-transform: uppercase;
	letter-spacing: -.015em;
	line-height: 1.06;
	text-wrap: balance;
}

/* ── the grid ─────────────────────────────────────────────── */

.gtd-upsell__grid {
	display: grid;
	/* Two, explicitly. auto-fit left a third, empty track in the row. */
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: clamp(1rem, 1.6vw, 1.75rem);
}

@media (max-width: 800px) {
	.gtd-upsell__grid { grid-template-columns: minmax(0, 1fr); }
}

/* ── a panel ──────────────────────────────────────────────── */

.gtd-upsell__panel {
	position: relative;
	isolation: isolate;
	overflow: clip;              /* the photograph is moved inside this */

	/* Proportion rather than a fixed height, with a floor so the frame never
	   gets shorter than its own content on a narrow screen. */
	aspect-ratio: 16 / 11;
	min-height: clamp(21rem, 52vw, 30rem);

	display: flex;
	align-items: flex-end;       /* the content stands on the bottom edge */
	background: #0e1919;         /* the ground behind a photograph that has
	                                not loaded yet — never white, so the type
	                                is legible before the image arrives */
}

/* ── the photograph ───────────────────────────────────────── */

.gtd-upsell__figure {
	position: absolute;
	inset: 0;
	z-index: 0;
	margin: 0;
}

.gtd-upsell__img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	max-width: none;             /* answers the theme's global img rule */
	display: block;
	transform: scale(1.001);     /* seeds the composite layer, so the first
	                                hover does not stutter */
	transition: transform 1.1s var(--up-ease);
}

/*
 * The scrim. Three stops rather than two: a linear ramp over a photograph
 * shows its own edge as a band, exactly as it does over a flat ground.
 */
.gtd-upsell__panel::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	background: linear-gradient(0deg,
		rgba(8, 16, 16, .93) 0%,
		rgba(8, 16, 16, .86) 16%,
		rgba(8, 16, 16, .60) 38%,
		rgba(8, 16, 16, .22) 58%,
		rgba(8, 16, 16, .04) 76%,
		rgba(8, 16, 16, 0) 100%);
	transition: opacity .7s var(--up-ease);
}

/* ── the content ──────────────────────────────────────────── */

.gtd-upsell__body {
	position: relative;
	z-index: 2;
	width: 100%;
	padding: clamp(1.75rem, 3.4vw, 3.25rem);
	display: flex;
	flex-direction: column;
	align-items: flex-start;
}

/*
 * Bolder than the 65px it was, and tighter — and now it has a ground to stand
 * on, which is the thing that lets it be this size without shouting.
 */
.gtd-upsell__title {
	margin: 0;
	font-size: clamp(1.9rem, 1.1rem + 2.6vw, 4rem) !important;
	font-weight: 900;
	line-height: .95;
	letter-spacing: -.03em;
	text-transform: uppercase;
	color: var(--up-ink);
	text-wrap: balance;
	transition: transform .7s var(--up-ease);
}

/*
 * The rule. Short at rest, the full width of the panel on hover — the same
 * device and the same easing as a rig card's spec rule, so the two read as one
 * behaviour rather than two effects.
 */
.gtd-upsell__rule {
	display: block;
	width: 100%;
	height: 3px;
	margin: clamp(.9rem, 1.6vw, 1.35rem) 0 clamp(1rem, 1.8vw, 1.5rem);
	background: var(--up-red);
	transform: scaleX(.14);
	transform-origin: left;
	transition: transform .8s var(--up-ease);
}

/* The ID again: css/type.css sets `#product_upsell_block p { font-size:
   var(--t-body) !important }`, which is (1,0,1) and outranks a class even with
   !important on both sides. */
#product_upsell_block .gtd-upsell__text,
#product_upsell_block .gtd-upsell__text p {
	margin: 0;
	max-width: 46ch;
	font-size: clamp(.95rem, .88rem + .35vw, 1.1875rem) !important;
	line-height: 1.55;
	color: var(--up-quiet) !important;
	transition: color .5s var(--up-ease);
}

#product_upsell_block .gtd-upsell__text { margin-bottom: clamp(1.35rem, 2.4vw, 2rem); }
#product_upsell_block .gtd-upsell__text p + p { margin-top: .6em; }

/*
 * The button keeps .info-button's geometry — padding, tracking, the chevron
 * mask — and takes a ghost treatment over the photograph, because a white slab
 * on a photograph is a hole in it. It fills white on hover, which is the one
 * place on the panel where the brand arrives.
 *
 * Defined here rather than reused: css/buttons.css has no .gtd-on-dark variant
 * on disk, so leaning on one would have been a rule that quietly did nothing.
 */
.gtd-upsell__cta {
	margin-top: 0;
	background-color: rgba(255, 255, 255, .06);
	border-color: rgba(255, 255, 255, .38);
	color: #fff;
	-webkit-backdrop-filter: blur(3px);
	backdrop-filter: blur(3px);
}

/*
 * "More info" is the same words on both panels, so each carries the equipment
 * name after it for anyone listening rather than looking. The theme has no
 * screen-reader utility of its own, so it is defined here rather than assumed.
 */
.gtd-upsell__cta .screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* The whole panel is the link. One anchor, stretched — not a second duplicate
   link wrapping the tile for a screen reader to read out twice. */
.gtd-upsell__cta::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 3;
}

/* ── the moment ───────────────────────────────────────────── */

.gtd-upsell__panel:hover .gtd-upsell__img,
.gtd-upsell__panel:focus-within .gtd-upsell__img { transform: scale(1.055); }

.gtd-upsell__panel:hover::before,
.gtd-upsell__panel:focus-within::before { opacity: .88; }

.gtd-upsell__panel:hover .gtd-upsell__rule,
.gtd-upsell__panel:focus-within .gtd-upsell__rule { transform: scaleX(1); }

.gtd-upsell__panel:hover .gtd-upsell__title,
.gtd-upsell__panel:focus-within .gtd-upsell__title { transform: translateY(-3px); }

.gtd-upsell__panel:hover .gtd-upsell__text,
.gtd-upsell__panel:hover .gtd-upsell__text p,
.gtd-upsell__panel:focus-within .gtd-upsell__text,
.gtd-upsell__panel:focus-within .gtd-upsell__text p { color: #fff !important; }

/* Fills on panel hover, not only on its own — the tile is the target. */
.gtd-upsell__panel:hover .gtd-upsell__cta,
.gtd-upsell__panel:focus-within .gtd-upsell__cta {
	background-color: #fff;
	border-color: #fff;
	color: var(--up-red);
	transform: translateY(-2px);
	box-shadow: 0 10px 26px rgba(0, 0, 0, .32);
}

.gtd-upsell__cta:focus-visible {
	outline: 2px solid #fff;
	outline-offset: 3px;
}

/* ── the entrance ─────────────────────────────────────────────
   Scroll-driven, so it plays when the panel is actually reached
   rather than on load like the theme's .fadeInUp-animation, which
   fires whether or not the block is anywhere near the viewport.

   The timeline is on the CONTENT, never on the panel. Putting an
   `animation-timeline: view()` animation on the panel itself — the
   containing block of the photograph — stopped the <img> inside it
   rasterising in Chrome: both panels rendered as empty dark
   rectangles until some later paint forced them back. Reproduced
   with and without clip-path in the keyframes, and gone the moment
   the animation moved off the panel. A decorative entrance is not
   worth a block that sometimes has no photographs in it.

   Behind @supports and with no JavaScript: where view() timelines
   are unavailable the content is simply already in place, which is
   a correct page and not a broken animation.
   ───────────────────────────────────────────────────────────── */

@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {
		@keyframes gtdUpsellIn {
			from { opacity: 0; transform: translateY(38px); }
			to   { opacity: 1; transform: none; }
		}

		.gtd-upsell__body {
			animation: gtdUpsellIn linear both;
			animation-timeline: view();
			animation-range: entry 6% cover 30%;
		}

		/* A stagger measured in scroll rather than in time: the second panel
		   simply needs a little more of the page to have passed. */
		.gtd-upsell__panel:nth-child(2) .gtd-upsell__body {
			animation-range: entry 12% cover 38%;
		}
	}
}

/* ── small screens ────────────────────────────────────────── */

@media (max-width: 800px) {
	.gtd-upsell__lead { max-width: none; }

	.gtd-upsell__panel {
		aspect-ratio: 4 / 3;
		min-height: 24rem;
	}

	/* The scrim has to reach further up a shorter frame, or the title lands
	   on the clear part of the photograph. */
	.gtd-upsell__panel::before {
		background: linear-gradient(0deg,
			rgba(8, 16, 16, .94) 0%,
			rgba(8, 16, 16, .88) 24%,
			rgba(8, 16, 16, .66) 48%,
			rgba(8, 16, 16, .3) 70%,
			rgba(8, 16, 16, .06) 88%,
			rgba(8, 16, 16, 0) 100%);
	}
}

@media (prefers-reduced-motion: reduce) {
	.gtd-upsell__img,
	.gtd-upsell__rule,
	.gtd-upsell__title,
	.gtd-upsell__text,
	.gtd-upsell__cta,
	.gtd-upsell__panel::before { transition: none !important; }

	/* The rule still belongs, it just does not travel. */
	.gtd-upsell__rule { transform: scaleX(1); }
}

/*
 * Below 800px the theme hangs a 140px rule off the left of every heading in
 * this block, positioned at left: calc(-131px - 20px) — which on a phone is
 * 151px off the side of the screen.
 */
@media (max-width: 800px) {
	#product_upsell_block .gtd-upsell__lead::before { content: none; }
}
