/* Services/Features Grid (Design Brief §5).
 * Equal-height cards (non-negotiable), a coherent icon treatment, a
 * subtle deliberate hover, and the accent lead-in on the section heading. */

.zerodigital-services-grid {
	padding: clamp(var(--wp--preset--spacing--xl, 3rem), 5vw, var(--wp--preset--spacing--2-xl, 4rem)) var(--zd-section-gutter, var(--wp--preset--spacing--md, 1.5rem));
}

/* The section is the band — its width follows the block's alignment, and any
 * background runs across it. The content column sits on one edge site-wide
 * (--zd-content-max, the header's edge) whatever that alignment is. */
.zerodigital-services-grid__container {
	max-width: var(--zd-content-max, calc(var(--wp--style--global--wide-size, 1600px) - 2 * var(--wp--preset--spacing--md, 1.5rem)));
	margin-inline: auto;
}

/* Accent lead-in bar — the recurring signature mark on section headings. */
.zerodigital-services-grid__heading {
	font-family: var(--wp--preset--font-family--heading, inherit);
	font-size: var(--zd-step-h2, clamp(1.9rem, 1.35rem + 2.2vw, 2.9rem));
	line-height: 1.1;
	letter-spacing: -0.015em;
	text-wrap: balance;
	margin: 0 0 var(--wp--preset--spacing--sm, 1rem);
}

.zerodigital-services-grid__intro {
	max-width: 60ch;
	margin: 0 0 var(--wp--preset--spacing--xl, 2.5rem);
	font-size: var(--zd-step-lede, clamp(1.0625rem, 1rem + 0.45vw, 1.25rem));
	line-height: 1.6;
	color: var(--wp--preset--color--muted, #565b62);
}

.zerodigital-services-grid__items {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--wp--preset--spacing--md, 1.5rem);
	grid-template-columns: repeat(3, 1fr);
}

.zerodigital-services-grid--cols-4 .zerodigital-services-grid__items {
	grid-template-columns: repeat(4, 1fr);
}

.zerodigital-services-grid--cols-2 .zerodigital-services-grid__items {
	grid-template-columns: repeat(2, 1fr);
}

/* Card. Grid rows stretch, so cards are equal height by construction; the
 * link is pinned to the bottom of the body so bottoms never go ragged. */
.zerodigital-services-grid__item {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--sm, 1rem);
	padding: var(--wp--preset--spacing--lg, 2rem);
	background: var(--wp--preset--color--surface, #fff);
	border: var(--zd-border, 1px solid #e4e6e9);
	border-radius: var(--zd-card-radius, var(--wp--custom--radius--lg, 0.75rem));
	transition: border-color var(--zd-ease, 180ms ease);
}


.zerodigital-services-grid__item-body {
	display: flex;
	flex-direction: column;
	flex: 1;
}

/* Coherent icon set: uniform optical size in a tinted, radius-consistent
 * chip so mixed source icons still read as one family. */
.zerodigital-services-grid__item-icon {
	width: 1.5rem;
	height: 1.5rem;
	padding: 0.75rem;
	border-radius: var(--zd-btn-radius, var(--wp--custom--radius--md, 0.5rem));
	background: var(--zd-accent-tint, color-mix(in srgb, var(--wp--preset--color--accent, #c4263c) 8%, transparent));
	box-sizing: content-box;
}

.zerodigital-services-grid__item-title {
	font-size: var(--zd-step-h3, clamp(1.2rem, 1.05rem + 0.7vw, 1.5rem));
	line-height: 1.3;
	margin: 0 0 var(--wp--preset--spacing--2-xs, 0.5rem);
}

.zerodigital-services-grid__item-description {
	margin: 0;
	line-height: 1.55;
	color: var(--wp--preset--color--muted, #565b62);
}

.zerodigital-services-grid__item-link {
	margin-top: auto;
	padding-top: var(--wp--preset--spacing--sm, 1rem);
	font-weight: 600;
	color: var(--wp--preset--color--primary, #0e4b52);
	text-decoration: none;
}

.zerodigital-services-grid__item-link::after {
	content: "\2192";
	display: inline-block;
	margin-left: 0.35rem;
	transition: transform var(--zd-ease, 180ms ease);
}

.zerodigital-services-grid__item-link:hover {
	color: var(--zd-accent, var(--wp--preset--color--accent, #c4263c));
}

.zerodigital-services-grid__item-link:hover::after {
	transform: translateX(3px);
}

/* ---- icon-left variant: icon column beside the body ------------------- */
.zerodigital-services-grid--icon-left .zerodigital-services-grid__item {
	flex-direction: row;
	align-items: flex-start;
}

.zerodigital-services-grid--icon-left .zerodigital-services-grid__item-icon {
	flex-shrink: 0;
}

/* ---- responsive ------------------------------------------------------- */
@media (max-width: 960px) {
	.zerodigital-services-grid__items,
	.zerodigital-services-grid--cols-4 .zerodigital-services-grid__items {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 600px) {
	.zerodigital-services-grid__items,
	.zerodigital-services-grid--cols-2 .zerodigital-services-grid__items,
	.zerodigital-services-grid--cols-4 .zerodigital-services-grid__items {
		grid-template-columns: 1fr;
	}
}

/* ---- Image card: a media band across the top --------------------------- */
/* The media has to reach the card's edges, so the padding moves off the card
 * and onto the body, and overflow clips the image to the card's own corner. */
.zerodigital-services-grid--card-image .zerodigital-services-grid__item {
	padding: 0;
	gap: 0;
	overflow: hidden;
}

.zerodigital-services-grid--card-image .zerodigital-services-grid__item-body {
	padding: var(--wp--preset--spacing--lg, 2rem);
	gap: var(--wp--preset--spacing--2-xs, 0.5rem);
}

.zerodigital-services-grid__item-media {
	display: block;
}

/* A fixed ratio keeps a row of cards level however ragged the uploads are. */
.zerodigital-services-grid__item-media img {
	display: block;
	width: 100%;
	aspect-ratio: 16 / 10;
	object-fit: cover;
}

/* An icon-left image card would put the media in a column beside the copy,
 * which is not what "image on top" means — the image card ignores placement. */
.zerodigital-services-grid--card-image .zerodigital-services-grid__item {
	flex-direction: column;
}

/* ---- Carousel ---------------------------------------------------------- */
.zerodigital-services-grid--carousel .zerodigital-services-grid__slider-shell {
	position: relative;
}

/* Swiper gives .swiper overflow:hidden, which would clip a focus ring on a
 * card link. Pad the track and pull it back level — on the block axis only:
 * horizontal padding narrows the track and shifts it out of line with the
 * heading, and Swiper's own margin-inline:auto fights a margin shorthand at
 * the same specificity. */
.zerodigital-services-grid--carousel .zerodigital-services-grid__slider {
	width: 100%;
	padding-block: 0.5rem;
	margin-block: -0.5rem;
}

/* The track is a <ul> and Swiper resets neither padding nor margin on
 * .swiper-wrapper, so the browser's default list padding would push every
 * slide right and overflow the container. The grid never hit this because its
 * list reset rides on __items, which the carousel deliberately doesn't use. */
.zerodigital-services-grid--carousel .swiper-wrapper {
	list-style: none;
	margin: 0;
	padding: 0;
}

/* Slides stretch to the tallest card so ragged copy lengths keep the row even,
 * the same way the grid does.
 *
 * display is restated because Swiper's stylesheet sets `.swiper-slide
 * { display: block }` at the same weight as the card's own flex and loads after
 * it. Until 0.58.0 it won: a carousel card lost the gap between its icon and
 * copy, its link was no longer pinned to the bottom, and Icon position → Left
 * stacked. Two classes here outweigh Swiper's one. */
.zerodigital-services-grid--carousel .zerodigital-services-grid__item {
	display: flex;
	height: auto;
	box-sizing: border-box;
}


/* ---- Carousel on phones ------------------------------------------------ */
/* A grid everywhere but a phone. mobile.js turns the track, list and cards into
 * a Swiper carousel at 600px and below (the grid's own one-column breakpoint)
 * and back into this grid above it, so the rules here come in three states:
 * wider than a phone, a phone before Swiper has arrived, and a phone with it. */

/* Wider than a phone: the grid, exactly as a grid without the switch. The
 * controls are printed so they are there when the screen narrows. */
@media (min-width: 601px) {
	.zerodigital-services-grid--mobile-carousel .zerodigital-services-grid__controls,
	.zerodigital-services-grid--mobile-carousel .zerodigital-services-grid__pagination {
		display: none;
	}
}

@media (max-width: 600px) {
	/* The same focus-ring room the Carousel layout gives its track (see
	 * "Carousel" above), in every phone state, so the page does not move by
	 * that half-rem when Swiper arrives. */
	.zerodigital-services-grid--mobile-carousel .zerodigital-services-grid__track {
		padding-block: 0.5rem;
		margin-block: -0.5rem;
	}

	/* Before Swiper: a native scroll-snap row, one card wide, laid out like the
	 * carousel it is about to become so the switch-over does not shift the
	 * page. It is also what a phone gets if Swiper never loads — still one card
	 * at a time, still swipeable, where it would otherwise fall back to the
	 * long column this switch exists to avoid. */
	.zerodigital-services-grid--mobile-carousel .zerodigital-services-grid__items:not(.swiper-wrapper) {
		display: flex;
		gap: 24px;
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		overscroll-behavior-x: contain;
	}

	.zerodigital-services-grid--mobile-carousel .zerodigital-services-grid__items:not(.swiper-wrapper) > .zerodigital-services-grid__item {
		flex: 0 0 100%;
		scroll-snap-align: start;
	}

	/* The controls keep their row from the first paint and show once they work,
	 * so they neither push the page down nor sit there as dead buttons. The
	 * dots row holds one bullet's height for the same reason. */
	.zerodigital-services-grid--mobile-carousel .zerodigital-services-grid__slider-shell:not(.is-carousel) .zerodigital-services-grid__controls {
		visibility: hidden;
	}

	.zerodigital-services-grid--mobile-carousel .zerodigital-services-grid__pagination {
		min-height: var(--swiper-pagination-bullet-height, var(--swiper-pagination-bullet-size, 8px));
	}

	/* With Swiper: its track is a flex row it spaces with margins, so the grid's
	 * gap comes off, and cards stretch to the tallest as they do in the grid.
	 * display is restated for the reason the Carousel layout's card rule gives:
	 * Swiper's `.swiper-slide { display: block }` would otherwise flatten the
	 * card, and it came out 16px shorter than the row it replaced. */
	.zerodigital-services-grid--mobile-carousel .zerodigital-services-grid__items.swiper-wrapper {
		display: flex;
		gap: 0;
	}

	.zerodigital-services-grid--mobile-carousel .zerodigital-services-grid__item.swiper-slide {
		display: flex;
		height: auto;
		box-sizing: border-box;
	}
}

/* The editor's prompt for an empty block (zerodigital_editor_placeholder()).
   Printed only in the editor preview, never on the live page. */
.zerodigital-services-grid__empty {
	margin: 0;
	opacity: 0.7;
	font-style: italic;
}
