/**
 * Draper Services Grid
 *
 * Scoped under .dsg- prefixes so nothing here can reach into GeneratePress
 * or the Elementor widgets already on the page.
 */

/* ------------------------------------------------------------- section --- */

/*
 * A titled grid. Each one is its own Elementor section on the Services page, so
 * the gap between sections stays where the client can see it — in Elementor's
 * section padding — and only the title-to-grid gap is set here.
 */
/*
 * Matched to the "Our Story" heading on the home page, which is the site's
 * house style for a section title: Poppins 36/600 in #6EC1E4, sentence case.
 * Set here rather than as an Elementor heading widget so all three titles stay
 * identical, and two classes deep so GeneratePress's own h2 colour doesn't win.
 */
.dsg-section .dsg-section__title {
	margin: 0 0 1.5rem;
	color: #6ec1e4;
	font-family: Poppins, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
	font-size: clamp(1.75rem, 1.4rem + 1.1vw, 2.25rem);
	font-weight: 600;
	line-height: 1.1;
	text-transform: none;
	letter-spacing: normal;
}

.dsg-grid {
	--dsg-columns: 3;
	--dsg-gap: 1.5rem;
	--dsg-radius: 4px;

	display: grid;
	grid-template-columns: repeat(var(--dsg-columns), minmax(0, 1fr));
	gap: var(--dsg-gap);
	margin: 0;
	padding: 0;
	list-style: none;
}

@media (max-width: 1024px) {
	.dsg-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 600px) {
	.dsg-grid {
		grid-template-columns: 1fr;
	}
}

/* ---------------------------------------------------------------- card --- */

.dsg-card {
	--dsg-overlay: 0.55;

	position: relative;
	display: flex;
	align-items: flex-start;
	overflow: hidden;
	border-radius: var(--dsg-radius);
	background-color: #1c1c1c;
	aspect-ratio: 4 / 3;
	isolation: isolate;
}

/* Older Safari and any browser without aspect-ratio still gets a sane box. */
@supports not (aspect-ratio: 4 / 3) {
	.dsg-card {
		min-height: 320px;
	}
}

.dsg-card__media {
	position: absolute;
	inset: 0;
	z-index: 0;
}

/* Two classes deep on purpose: Elementor ships `.elementor img { height: auto }`
   at the same specificity and loads after this file, which defeats a plain
   `.dsg-card__image` height rule and leaves a strip of bare card below the photo.
   Video cards carry this class too, so they get the same cover treatment. */
.dsg-card .dsg-card__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: transform 450ms ease;
}

/*
 * Two layers: a flat wash set by the per-card ACF value, plus a gradient that
 * deepens toward the top where the text actually sits. The gradient is what
 * keeps white text legible over a bright sky or a polished metal cab wall
 * without having to crank the flat wash so high the photo disappears.
 */
.dsg-card__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		linear-gradient(
			to bottom,
			rgba(0, 0, 0, calc(var(--dsg-overlay) + 0.25)) 0%,
			rgba(0, 0, 0, calc(var(--dsg-overlay) * 0.55)) 65%,
			rgba(0, 0, 0, calc(var(--dsg-overlay) * 0.35)) 100%
		);
	transition: opacity 450ms ease;
}

.dsg-card--no-image {
	background-image: linear-gradient(145deg, #2f3a44 0%, #171c21 100%);
}

/* ---------------------------------------------------------------- body --- */

.dsg-card__body {
	position: relative;
	z-index: 1;
	width: 100%;
	padding: 1.5rem 1.5rem 1.75rem;
	color: #fff;
}

.dsg-card__title {
	margin: 0 0 0.5rem;
	color: #fff;
	font-size: clamp(1.125rem, 1rem + 0.6vw, 1.4rem);
	line-height: 1.25;
	font-weight: 700;
	text-wrap: balance;
	text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
}

.dsg-card__text {
	margin: 0;
	color: rgba(255, 255, 255, 0.92);
	font-size: 0.95rem;
	line-height: 1.5;
	text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);

	/* Keeps every card the same height no matter how long the blurb runs. */
	display: -webkit-box;
	-webkit-line-clamp: 3;
	line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.dsg-card__cta {
	display: inline-block;
	margin-top: 0.9rem;
	font-size: 0.8rem;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: #fff;
	border-bottom: 2px solid rgba(255, 255, 255, 0.55);
	padding-bottom: 2px;
}

/* --------------------------------------------------------- interaction --- */

/*
 * The anchor wraps only the title so screen readers announce a meaningful
 * link, then this stretches its hit area over the whole card for mouse users.
 */
/*
 * GeneratePress emits a global `a:hover, a:focus, a:active { color: #000 }`
 * (specificity 0,1,1). Without matching states here the card title turns black
 * against the dark photo on hover and on keyboard focus. Two classes deep beats it.
 */
.dsg-card__link,
.dsg-card .dsg-card__link:hover,
.dsg-card .dsg-card__link:focus,
.dsg-card .dsg-card__link:active {
	color: #fff;
	text-decoration: none;
}

.dsg-card__link::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 2;
}

/*
 * Every card gets the hover, linked or not, so a grid of cards reacts as one
 * surface rather than the linked ones feeling live and the rest feeling dead.
 *
 * Gated on (hover: hover) because a plain :hover sticks on touch: a tap sets it
 * and nothing clears it until the visitor taps elsewhere. That never showed on a
 * linked card — the tap navigates away — but an unlinked one would just sit
 * there zoomed for the rest of the visit.
 */
@media (hover: hover) {
	.dsg-card:hover .dsg-card__image {
		transform: scale(1.05);
	}

	/*
	 * Hover lifts the overlay rather than restyling any text, so the photo comes
	 * forward. Held at 0.7 because the text sits directly on this - going lighter
	 * starts to cost contrast on the brighter images.
	 */
	.dsg-card:hover .dsg-card__media::after {
		opacity: 0.7;
	}
}

/* Focus ring goes on the card, since the anchor itself is only the title. */
.dsg-card:has(.dsg-card__link:focus-visible) {
	outline: 3px solid #fff;
	outline-offset: -3px;
	box-shadow: 0 0 0 5px rgba(0, 0, 0, 0.65);
}

/* Fallback for browsers without :has() - ring the title link instead. */
@supports not selector(:has(*)) {
	.dsg-card__link:focus-visible {
		outline: 3px solid #fff;
		outline-offset: 3px;
	}
}

/*
 * A video is replaced-content like an img, but browsers give it a black
 * background and a baseline gap unless it is told otherwise.
 */
.dsg-card__video {
	background: transparent;
	pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
	.dsg-card__image,
	.dsg-card__media::after {
		transition: none;
	}

	.dsg-card:hover .dsg-card__image {
		transform: none;
	}
}

/* Forced-colors users lose the photo entirely; keep the text readable. */
@media (forced-colors: active) {
	.dsg-card__media::after {
		background: Canvas;
		opacity: 1;
	}

	.dsg-card__title,
	.dsg-card__text,
	.dsg-card__cta {
		color: CanvasText;
		text-shadow: none;
	}
}

.dsg-empty {
	padding: 1rem;
	border: 1px dashed #c3c4c7;
	color: #50575e;
}
