/*
 * Related links — ribbon heading over a two-up grid of authored link cards.
 * Card anatomy (image left, content right, arrow in the corner) matches
 * blocks/latest-news so the two sections read as one system.
 */

.related-links,
.related-links *,
.related-links *::before,
.related-links *::after {
	box-sizing: border-box;
}

.related-links {
	--related-links-border: #d4d4d8;
	/* Content caps at 1800px; the page gutters sit outside it. */
	--related-links-container: calc( 1800px + 2 * var(--page-gutter) );
	--related-links-arrow: 32px;
	/* The image is the taller half, so its ratio sets the card's height.
	   Without it the photo's own proportions do, and cards come out several
	   times taller than the comp. */
	--related-links-image-ratio: 1.9;
	/* Portrait framing — see .related-links__image img. */
	--related-links-image-zoom: 1.65;
	--related-links-image-shift: -6%;

	width: 100%;
	max-width: var(--related-links-container) !important;
	margin: 0 auto;
	padding-bottom: 4rem;
	display: grid;
	row-gap: 1.5rem;
}

/* Shape and typography live in src/components/section-ribbon.scss; only the
   properties this block differs on are set here. The negative margin bleeds
   the bar to the viewport's left edge, same as latest-news. */
.related-links .section-ribbon {
	--section-ribbon-justify: flex-end;
	--section-ribbon-padding-left: 0px;
	--section-ribbon-padding-right: 56px;
	justify-self: start;
	margin-left: calc( -1 * max( 0px, calc( ( 100vw - var(--related-links-container) ) / 2 ) ) );
}

/* Declared on the text element, where the component sets them. Matches the
   other blocks' ribbons: 20px on desktop, 18px from laptop down. */
.related-links .section-ribbon-text {
	--section-ribbon-font-family: var(--font-guildhall);
	--section-ribbon-font-weight: 500;
	--section-ribbon-font-size: 20px;
}

@media ( max-width: 1299px ) {
	.related-links .section-ribbon-text {
		--section-ribbon-font-size: 18px;
	}
}

.related-links__grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 24px;
	padding-inline: var(--page-gutter);
}

.related-links__card {
	position: relative;
	display: grid;
	grid-template-columns: minmax( 0, 49% ) 1fr;
	border: 1px solid var(--related-links-border);
	color: inherit;
	text-decoration: none;
}

.related-links__card--no-image {
	grid-template-columns: 1fr;
}

.related-links__image {
	position: relative;
	overflow: hidden;
	aspect-ratio: var(--related-links-image-ratio);
	background: var(--related-links-image-bg, var(--gray-2));
}

/* Same palette and tokens as the navigation/driver cards (blocks/card). */
.related-links__image--silver { --related-links-image-bg: var(--gray-2); }
.related-links__image--red { --related-links-image-bg: var(--red-1); }
.related-links__image--yellow { --related-links-image-bg: var(--gold-1); }
.related-links__image--gold { --related-links-image-bg: var(--true-gold-1); }
.related-links__image--charcoal { --related-links-image-bg: var(--gray-6); }

/* Full-length portraits in a shallow letterbox: `cover` would crop them to
   head-and-shoulders, so they're sized by height instead. --zoom is a multiple
   of the box height (1 fits the whole portrait), --shift slides it vertically. */
.related-links__image img {
	display: block;
	width: 100%;
	height: calc( 100% * var(--related-links-image-zoom) );
	object-fit: contain;
	object-position: 50% 0;
	translate: 0 var(--related-links-image-shift);
}

/* Landscape photos (render.php sets this) have no headroom to trim — they
   cover the panel rather than being scaled down inside it. */
.related-links__image--fill img {
	height: 100%;
	object-fit: cover;
	translate: none;
}

/* Wider than ~2.5:1 (render.php sets this): cover would crop most of it away,
   so it's shown whole, letterboxed on the panel colour. */
.related-links__image--wide img {
	object-fit: contain;
	object-position: center;
}

/*
 * Hover, matching the site navigation: the zoomed copy cross-fades in (the
 * scale never animates, only the blend), and the corner arrow goes red.
 */

/* Scoped under the panel to outrank `.related-links__image img`. */
.related-links__image .related-links__image-zoom {
	position: absolute;
	inset: 0;
	opacity: 0;
	/* Backed with the panel colour so it hides the original as it fades in —
	   otherwise a transparent cutout shows both copies. */
	background: var(--related-links-image-bg, var(--gray-2));
	transform: scale( 1.12 );
	/* A cutout runs --zoom times the panel's height, shifted up; zooming on its
	   own centre would push the head out of frame, so zoom on the panel's. */
	transform-origin: 50% calc( 100% / ( 2 * var(--related-links-image-zoom) ) - var(--related-links-image-shift) );
	transition: opacity .2s ease;
}

.related-links__image--fill .related-links__image-zoom {
	transform-origin: 50% 50%;
}

.related-links__card[href]:is( :hover, :focus-visible ) .related-links__image-zoom {
	opacity: 1;
}


/* Centred against the image, as in the comp. The arrow sits far enough right
   that it needs no clearance of its own. */
.related-links__content {
	display: flex;
	flex-direction: column;
	justify-content: center;
	padding: 1.5rem 2rem;
}

.related-links__title {
	margin: 0 0 0.5rem;
	color: var(--gray-8);
	font-family: var(--font-forma-djr-micro);
	font-size: 24px;
	font-weight: 700;
	line-height: 120%;
	letter-spacing: -0.02em;
}

.related-links__description {
	margin: 0;
	color: var(--gray-6);
	font-family: var(--font-forma-djr-micro);
	font-size: 18px;
	font-weight: 400;
	line-height: 120%;
}

/* Laptop and tablet share one step down. */
@media ( max-width: 1299px ) {
	.related-links__title { font-size: 20px; }
	.related-links__description { font-size: 16px; }
}

.related-links__arrow {
	position: absolute;
	right: -1px;
	bottom: -1px;
	display: flex;
	align-items: center;
	justify-content: center;
	width: var(--related-links-arrow);
	height: var(--related-links-arrow);
	background-color: var(--white);
	border: 1px solid var(--related-links-border);
	color: var(--gray-8);
	transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.related-links__card[href]:is( :hover, :focus-visible ) .related-links__arrow {
	background-color: var(--red-1);
	border-color: var(--red-1);
	color: var(--white);
}

@media ( prefers-reduced-motion: reduce ) {
	.related-links__image .related-links__image-zoom,
	.related-links__arrow { transition: none; }
}

/* TABLET — one card per row. The card is otherwise untouched: at full width it
   lands back at the same image/content proportions as a desktop card. */
@media ( max-width: 1024px ) {
	.related-links__grid {
		grid-template-columns: 1fr;
		/* Nothing above this block supplies a gutter below the container width,
		   so the cards would sit on both viewport edges. The ribbon stays out
		   of it — that one runs to the edge by design. */
		padding-inline: 4%;
	}

	.related-links .section-ribbon {
		/* Desktop zeroes this because the bar bleeds off the viewport's left
		   edge; here it doesn't, so the label needs a normal indent. */
		--section-ribbon-padding-left: 24px;
	}
}

/* PHONE — the card keeps its image/content split rather than stacking; the
   image column just narrows and deepens, and the type steps down with it. */
@media ( max-width: 640px ) {
	.related-links {
		--related-links-image-ratio: 1.3;
	}

	/* Stacked in one column, a desktop-sized gap reads as a break between them. */
	.related-links__grid {
		gap: 10px;
	}

	.related-links__card {
		grid-template-columns: minmax( 0, 47% ) 1fr;
	}

	.related-links__content {
		padding: 1rem;
	}

	.related-links__title {
		font-size: 18px;
	}

	/* The label can't wrap, so it has to fit the bar's 92vw cap — at 18px it
	   doesn't on a 320px phone. Set on the text element because the component
	   declares this property there, where an inherited value would lose to it. */
	.related-links .section-ribbon-text {
		--section-ribbon-font-size: clamp( 13px, 4.4vw, 16px );
	}

	/* Gives the label more of the bar's width. Still clears the 20px cut, so
	   the text never sits on the slope. */
	.related-links .section-ribbon {
		--section-ribbon-padding-right: 40px;
	}
}
