/**
 * Block: What We Do (ACF layout `what_we_do`).
 *
 * Measured geometry (1920 canvas, section 4 = y 2538..4275, height 1737):
 *   Section padding-block 150. Label 150..182, +16, heading 198..271, +80 ->
 *   the list starts at 351.
 *   Rules measured at rel y 351 / 674 / 826 / 978 / 1130 / 1282 / 1434 / 1586,
 *   each spanning x 240..1680 exactly, so: ACTIVE row 323, INACTIVE rows 152.
 *   A vertical rule at x=1073 runs the whole list.
 *
 *   INACTIVE row: 48 pad-left + number (auto, ~65) + 80 gap + title (flex:1,
 *   padding-right 48) + body 607 = 1440. Everything vertically centred.
 *   Verified: 1392 available - 607 body = 785 of lead; 785 - 65 - 80 = 640 of
 *   title box, and 640 - 48 padding-right = 592 — the measured title width.
 *
 *   ACTIVE row: 40 pad-left + lead 230 + 80 gap + media 443x244 + 40 gap +
 *   body 607 = 1440.
 *
 * Every rule is an `inset` box-shadow, never a border, so it costs no layout
 * height and the measured rule positions hold exactly.
 *
 * THE BODY IS ALWAYS 607 WIDE WITH `margin-left: auto`. That is what makes
 * decision D2 work: items 02-07 have deliberately empty image fields, so when one
 * of them is active the 443px media slot simply is not rendered and the auto
 * margin re-absorbs the space — the body stays pinned at x=1073 on the vertical
 * rule instead of leaving a 443px hole. Verified both ways:
 *   with media: 230 + 80 + 443 + 607 = 1360, remainder 40  -> body at 1073
 *   no media:   230 + 607 = 837,            remainder 563 -> body at 1073
 *
 * The active row is min-height 323 and no child needs more than the 244px media,
 * so the row resolves to exactly 323 and every rule lands on its measured y.
 * That also means a medialess active row does not collapse and the list never
 * jumps height as the hover moves.
 *
 * @package lawncareknox
 */

.home-what-we-do {
	position: relative;
	padding-block: var(--sp-150);
	background-color: var(--color-bg-dark);
	background-repeat: no-repeat;
	background-position: center center;
	background-size: cover;
	overflow: hidden;
}

/* The section photo is measured at only ~3/255 visible through the flat colour,
   so the overlay is the token at 0.97 rather than a lighter wash. */
.home-what-we-do__overlay {
    position: absolute;
    inset: 0;
    z-index: 0;
    background: -webkit-gradient(linear, left bottom, left top, from(rgb(38 73 45 / 90%)), to(rgb(38 73 45 / 90%))), -webkit-gradient(linear, left top, left bottom, from(rgba(38, 73, 45, 0)), color-stop(50%, #26492D));
    background: linear-gradient(0deg, rgb(38 73 45 / 90%), rgb(38 73 45 / 90%)), linear-gradient(180deg, rgba(38, 73, 45, 0) 0%, #26492D 50%);
}

.home-what-we-do__inner {
	position: relative;
	z-index: 1;
	display: -webkit-box;
	display: -ms-flexbox;
	display: flex;
	-webkit-box-orient: vertical;
	-webkit-box-direction: normal;
	    -ms-flex-direction: column;
	        flex-direction: column;
	gap: var(--sp-80);
}

/* --- Section head: scoped overrides of the shared classes. --- */
.home-what-we-do .section-label {
	color: var(--color-accent);
}

.home-what-we-do .section-title {
	color: var(--color-white);
}

/* ==========================================================================
   List
   ========================================================================== */

.wwd-list {
	width: 100%;
}

/* ==========================================================================
   Open / close animation
   ==========================================================================
   The transition is scoped to exactly the properties that differ between the
   inactive and active rules, rather than `all`:

     .wwd-item              min-height 152 <-> 323, padding-left 48 <-> 40
     .wwd-item__lead        gap 80 <-> 0, padding-block 0 <-> 40
     .wwd-item__lead title  padding-right 48 <-> 0

   NOTHING BELOW THE SECTION MOVES DURING THE ANIMATION. The row being opened
   and the row being closed are exactly complementary — one runs 152 -> 323
   while the other runs 323 -> 152 over the same duration and easing, so their
   sum is 152 + 323 = 475 at every frame and the list stays exactly 1235 tall
   throughout.

   THAT INVARIANT NEEDS `max-height`, NOT JUST `min-height`, and this was
   measured rather than assumed. With min-height alone a row's real height is
   max(min-height, content height), and the active layout's content height jumps
   DISCRETELY the instant `.is-active` lands — the button switches to
   display:block, so the body's min-content becomes 48 + description + button +
   48 = 214px. The opening row therefore snapped straight to 214 while the
   closing row was still eased at 323, and the list bulged 1235 -> 1297: a 62px
   downward shove of Service Areas and the whole footer, mid-animation. Measured
   list heights before this fix: 1297, 1267.8, 1235, 1235 ...

   Animating min-height AND max-height on the same curve pins the height to
   exactly 152 + 171t whatever the content does, and `overflow: hidden` turns the
   early content overhang into a clean progressive reveal of the button and photo
   instead of a spill over the next row. Both resting states are unaffected
   because content fits inside both (152 content in a 152 row, 214 in a 323 row).

   This is a genuine layout change (a row really does get taller), so it cannot
   be moved onto the compositor; the invariant list height is the mitigation.
   The properties that are NOT animated are the ones CSS cannot interpolate: the
   lead's flex-direction (row <-> column) and align-items. Those stay discrete.

   Resting geometry is untouched: 323 active / 152 inactive, list constant at
   1235, body 607 flush right at x=1680.
   ========================================================================== */

.wwd-item {
	position: relative;
	display: -webkit-box;
	display: -ms-flexbox;
	display: flex;
	-webkit-box-align: center;
	    -ms-flex-align: center;
	        align-items: center;
	min-height: 152px;
	max-height: 152px;
	overflow: hidden;
	padding-left: var(--sp-48);
	-webkit-box-shadow: inset 0 1px 0 0 var(--line-on-dark);
	        box-shadow: inset 0 1px 0 0 var(--line-on-dark);
	-webkit-transition:
		min-height 0.35s ease,
		max-height 0.35s ease,
		padding-left 0.35s ease;
	transition:
		min-height 0.35s ease,
		max-height 0.35s ease,
		padding-left 0.35s ease;
}

.wwd-item:last-child {
	-webkit-box-shadow:
		inset 0 1px 0 0 var(--line-on-dark),
		inset 0 -1px 0 0 var(--line-on-dark);
	        box-shadow:
		inset 0 1px 0 0 var(--line-on-dark),
		inset 0 -1px 0 0 var(--line-on-dark);
}

.wwd-item:focus {
	outline: none;
}

/* --- Lead: number + title. --- */
.wwd-item__lead {
	display: -webkit-box;
	display: -ms-flexbox;
	display: flex;
	-webkit-box-flex: 1;
	    -ms-flex: 1 1 auto;
	        flex: 1 1 auto;
	-webkit-box-align: center;
	    -ms-flex-align: center;
	        align-items: center;
	gap: var(--sp-80);
	min-width: 0;
	-webkit-transition:
		gap 0.35s ease,
		padding-block 0.35s ease;
	transition:
		gap 0.35s ease,
		padding-block 0.35s ease;
}

.wwd-item__lead .section-number {
	-webkit-box-flex: 0;
	    -ms-flex: 0 0 auto;
	        flex: 0 0 auto;
	color: var(--line-on-dark);
}

.wwd-item__lead .text-large {
	-webkit-box-flex: 1;
	    -ms-flex: 1 1 auto;
	        flex: 1 1 auto;
	min-width: 0;
	padding-right: var(--sp-48);
	color: var(--color-white);
	-webkit-transition: padding-right 0.35s ease;
	transition: padding-right 0.35s ease;
}

/* --- Media: only ever shown on the active row. --- */
.wwd-item__media {
	display: none;

	/*
	 * ELASTIC, BUT CAPPED AT THE DESIGNED 443.
	 *
	 * Every other track on the active row is non-shrinkable — lead 230, body 607
	 * — so the media is the only thing that can absorb a narrowing container, and
	 * until now it could not: `flex: 0 0 443px` made the row's minimum
	 * 40 + 230 + 80 + 443 + 607 = 1400, while the content box is only
	 * min(viewport - 15 scrollbar, 1470) - 30 gutters. That falls under 1400 at a
	 * 1445px viewport, so from 1444px down the row overflowed and the body — and
	 * with it the vertical rule — was shoved out of line with the inactive rows.
	 *
	 * `max-width` pins it to exactly 443 wherever there is room, so desktop is
	 * unchanged (1440 content = 1400 track + 40 declared gap, remainder 0), and
	 * the box only ever shrinks once the geometry genuinely cannot hold it. The
	 * aspect-ratio and `object-fit: cover` below are untouched, so the photo
	 * always fills the box completely — it is never letterboxed, only scaled.
	 *
	 * `min-width: 0` is REQUIRED, not defensive: the <img> inside is 4096px
	 * intrinsic, and a flex item's automatic minimum size is its min-content
	 * width, so without this the media would refuse to shrink by even a pixel.
	 */
	-webkit-box-flex: 1;
	    -ms-flex: 1 1 443px;
	        flex: 1 1 443px;
	max-width: 443px;
	min-width: 0;
	-ms-flex-item-align: center;
	    -ms-grid-row-align: center;
	    align-self: center;
	margin-left: var(--sp-80);

	/*
	 * THE GAP RIGHT OF THE IMAGE IS NOW DECLARED RATHER THAN LEFT OVER.
	 *
	 * On desktop this 40px was never a real value — it was whatever
	 * `margin-left: auto` on the body had failed to spend (1440 - 1400 = 40).
	 * An auto margin is the first thing to give when free space runs out, so the
	 * instant the container dropped below 1400 the gap went to exactly 0 and the
	 * photo sat flush against the body's rule. Declaring it holds it at the
	 * desktop 40 at every width — never 0, and never wider than desktop either,
	 * because the body's auto margin still absorbs any genuine surplus.
	 */
	margin-right: var(--sp-40);
	aspect-ratio: 443 / 244;
	border-radius: var(--radius);
	overflow: hidden;
}

/*
 * Same extractor error as the service cards: section-specs.json says
 * objectPosition "0% 0%", but _full-page.png (the source of truth) centre-crops.
 * Proof, re-deriving both crops from image-4.jpg (4096x2304) into the 443x244
 * media box, which drops 5px (mean abs diff, 8-bit luma):
 *   top-left crop vs reference 12.15 | vs our render  2.42
 *   centre   crop vs reference  4.65 | vs our render 11.00
 * and cross-correlation put the optimum at dy = -3, i.e. the (249-244)/2 = 2.5px
 * centre offset. Centre is the CSS default; written out to record the finding.
 */
.wwd-item__media img {
	width: 100%;
	height: 100%;
	-o-object-fit: cover;
	   object-fit: cover;
	-o-object-position: center center;
	   object-position: center center;
}

/* --- Body: always 607 and always flush right on the x=1073 rule. --- */
.wwd-item__body {
	display: -webkit-box;
	display: -ms-flexbox;
	display: flex;
	-webkit-box-flex: 0;
	    -ms-flex: 0 0 607px;
	        flex: 0 0 607px;
	-webkit-box-orient: vertical;
	-webkit-box-direction: normal;
	    -ms-flex-direction: column;
	        flex-direction: column;
	-webkit-box-pack: justify;
	    -ms-flex-pack: justify;
	        justify-content: space-between;
	-webkit-box-align: start;
	    -ms-flex-align: start;
	        align-items: flex-start;
	-ms-flex-item-align: stretch;
	    -ms-grid-row-align: stretch;
	    align-self: stretch;
	margin-left: auto;
	padding: var(--sp-48) var(--sp-40);
	-webkit-box-shadow: inset 1px 0 0 0 var(--line-on-dark);
	        box-shadow: inset 1px 0 0 0 var(--line-on-dark);
}

.wwd-item__body .section-description {
	color: var(--text-on-dark);
}

/* The button appears only on the active row. */
.wwd-item__action {
	display: none;
}

/* ==========================================================================
   Active row
   ========================================================================== */

.wwd-item.is-active {
	-webkit-box-align: stretch;
	    -ms-flex-align: stretch;
	        align-items: stretch;
	min-height: 323px;
	max-height: 323px;
	padding-left: var(--sp-40);
}

.wwd-item.is-active .wwd-item__lead {
	-webkit-box-flex: 0;
	    -ms-flex: 0 0 230px;
	        flex: 0 0 230px;
	-webkit-box-orient: vertical;
	-webkit-box-direction: normal;
	    -ms-flex-direction: column;
	        flex-direction: column;
	-webkit-box-pack: justify;
	    -ms-flex-pack: justify;
	        justify-content: space-between;
	-webkit-box-align: start;
	    -ms-flex-align: start;
	        align-items: flex-start;
	gap: 0;
	padding-block: var(--sp-40);
}

.wwd-item.is-active .wwd-item__lead .text-large {
	-webkit-box-flex: 0;
	    -ms-flex: 0 0 auto;
	        flex: 0 0 auto;
	padding-right: 0;
}

.wwd-item.is-active .wwd-item__media {
	display: block;
}

.wwd-item.is-active .wwd-item__action {
	display: block;
}

/* ==========================================================================
   Responsive
   ==========================================================================
   Per the brief: on tablet and mobile there is no hover at all. Every item is
   rendered fully expanded and stacked — image, title, description and button all
   visible on all seven. No accordion, no click-to-open. js/site.js stops binding
   the hover below 1000px and re-evaluates on resize via matchMedia.

   No tablet or mobile frames exist in the Figma file, so these values are
   derived. Spacing is all from the Figma scale.
   ========================================================================== */
@media (max-width: 1440px) {
.home-what-we-do {
    padding-block: 120px;
}
}

/*
 * SLACK IS RECLAIMED HERE BEFORE THE PHOTO IS ALLOWED TO GIVE UP ANY WIDTH.
 *
 * The photo is the active row's only elastic track, so without this it starts
 * shrinking the instant the content box passes under 1400 and is down to 358 by a
 * 1400px viewport. Two of the desktop values are pure breathing room, though, and
 * worth far less than the photo: the 80px margin between the lead and the photo,
 * and the 230px lead itself, whose stacked number and title need about 200.
 * Spending those two first buys back 70px and holds the photo at its full designed
 * 443 down to a 1370px content box — 229 rather than 159 at the bottom of the
 * band. Both numbers are exactly what the 1200px block below already steps down
 * to, so this only brings that step forward; it introduces no new value.
 *
 * ONCE THAT SLACK IS SPENT, THE BODY SHARES THE LOSS INSTEAD OF LETTING THE PHOTO
 * TAKE ALL OF IT. Holding the body at a fixed 607 meant every remaining pixel of
 * deficit came off the photo alone, so it fell to 229 by 1201 and 155 by 1000 —
 * correct, but far too small. The body is therefore fluid from here down, tracking
 * the deficit in the SAME 443:607 proportion the desktop design uses:
 *
 *   body  = min(607, 57.8vw - 211)
 *   photo = (content - 320 fixed) - body = 0.422vw - 154
 *
 * which yields 607/443 at a 1370 content box (viewport 1415, where the reclaim
 * above runs out), 483/353 at 1201 and 367/268 at 1000 — the photo never collapses,
 * and it also lands the body within a pixel of the old 480 step at 1200, so that
 * step disappears and the whole range 1484 -> 1000 is continuous.
 *
 * THE UNIT IS vw, NOT A PERCENTAGE, AND THAT IS THE WHOLE POINT. A percentage
 * flex-basis resolves against the flex container, and the active row's padding-left
 * is 40 while the inactive rows' is 48 — so the two would resolve to widths 4.6px
 * apart and the rule would sit crooked again, which is the exact bug being fixed.
 * vw is identical for every row, so active and inactive always compute the same
 * body and the rule always lines up. The trade is that vw includes the scrollbar,
 * so the split can be a pixel or two off the ideal ratio; the photo absorbs that,
 * and alignment — the thing that actually shows — is exact either way.
 *
 * WHY 1484 AND NOT 1440. The content box is min(viewport - scrollbar, 1470) - 30
 * gutters, so 1484 is precisely the widest viewport at which it stops being pinned
 * at its 1440 maximum and starts tracking the window. Reclaiming from exactly
 * there is what makes the handover seamless: `flex-grow` on the lead means the
 * lead and its margin together always take (content - 1130), which is 310 at a
 * 1440 content box — identical to the desktop 230 + 80 — and 309 one pixel below
 * it. Nothing jumps. Anchoring to 1440 instead left a 44px band where the photo
 * shrank to 399 and then popped back to 443, and put 25px of unspendable surplus
 * into the gap right of the photo, measuring 65 there instead of 40.
 *
 * The lead grows but never shrinks (flex-shrink stays 0 from the base rule), so
 * surplus lands in the lead while any deficit still comes off the photo — never
 * off the body, and never off the declared 40px gap.
 */
@media (max-width: 1484px) {
	.wwd-item.is-active .wwd-item__lead {
		-webkit-box-flex: 1;
		    -ms-flex-positive: 1;
		        flex-grow: 1;
		-ms-flex-preferred-size: 200px;
		    flex-basis: 200px;
	}

	.wwd-item.is-active .wwd-item__media {
		margin-left: var(--sp-40);
	}

	/* Every row, active and inactive alike — that is what keeps the rule straight. */
	.wwd-item__body {
		-ms-flex-preferred-size: min(607px, calc(57.8vw - 211px));
		    flex-basis: min(607px, calc(57.8vw - 211px));
	}
}

@media (max-width: 1200px) {
	/* --sp-150 / --sp-80 are the desktop rhythm; both step down from here. */
	.home-what-we-do {
		padding-block: var(--sp-80);
	}

	.home-what-we-do__inner {
		gap: var(--sp-48);
	}

	/*
	 * ONLY THE PADDING STEPS HERE NOW. This block used to carry the row's whole
	 * re-derived geometry — body 480, lead 200, media 320 — and all three are gone,
	 * because all three were single numbers derived against ONE width (a 1155px
	 * content box, i.e. a 1200px viewport) while the block itself runs down to
	 * 1000px, where the content box is only 955. The row needed 1080 and so
	 * overflowed by 125px at the bottom of the very band meant to fix it. Measured
	 * at 1050px: gap right of the photo 0, body 60px past the container, rule 75px
	 * out of line with the rows below.
	 *
	 * The 320px photo basis was also what put a 75px gap right of the photo at
	 * 1200px: capped at 320 it could not take the 35px of surplus, so the body's
	 * `margin-left: auto` swallowed it and the gap grew instead.
	 *
	 * The 1484 block above now handles all of it continuously — one fluid body, one
	 * elastic photo, one declared gap — so there is nothing left to step at 1200
	 * except the body's internal padding, which is not load-bearing on the layout.
	 */
	.wwd-item__body {
		padding: var(--sp-32) var(--sp-24);
	}

	.wwd-item__lead {
		gap: var(--sp-40);
	}
}

/* Anyone who has asked for less motion gets the instant state change. */
@media (prefers-reduced-motion: reduce) {
	.wwd-item,
	.wwd-item__lead,
	.wwd-item__lead .text-large {
		-webkit-transition: none;
		transition: none;
	}
}

@media (max-width: 999px) {
	.home-what-we-do {
		padding-block: var(--sp-64);
	}

	/*
	 * Below 1000px there is no hover at all and every row renders expanded, so
	 * no animated property ever differs between the two states. The transitions
	 * are switched off outright so the open/close animation is a guaranteed
	 * no-op here rather than merely an unused one.
	 */
	.wwd-item,
	.wwd-item.is-active,
	.wwd-item__lead,
	.wwd-item.is-active .wwd-item__lead,
	.wwd-item__lead .text-large,
	.wwd-item.is-active .wwd-item__lead .text-large {
		-webkit-transition: none;
		transition: none;
	}

	.home-what-we-do__inner {
		gap: var(--sp-40);
	}

	/*
	 * Every row renders in its expanded form, stacked — and the desktop height
	 * pinning is released so rows are purely content-sized again. Without
	 * `max-height: none` the 152px desktop cap would clip every stacked row.
	 */
	.wwd-item,
	.wwd-item.is-active {
		-webkit-box-orient: vertical;
		-webkit-box-direction: normal;
		    -ms-flex-direction: column;
		        flex-direction: column;
		-webkit-box-align: start;
		    -ms-flex-align: start;
		        align-items: flex-start;
		min-height: 0;
		max-height: none;
		overflow: visible;
		padding-left: 0;
		padding-block: var(--sp-40);
	}

	.wwd-item__lead,
	.wwd-item.is-active .wwd-item__lead {
		-webkit-box-flex: 0;
		    -ms-flex: 0 0 auto;
		        flex: 0 0 auto;
		-webkit-box-orient: horizontal;
		-webkit-box-direction: normal;
		    -ms-flex-direction: row;
		        flex-direction: row;
		-webkit-box-align: center;
		    -ms-flex-align: center;
		        align-items: center;
		gap: var(--sp-24);
		width: 100%;
		padding-block: 0;
	}

	.wwd-item__lead .text-large,
	.wwd-item.is-active .wwd-item__lead .text-large {
		-webkit-box-flex: 1;
		    -ms-flex: 1 1 auto;
		        flex: 1 1 auto;
		padding-right: 0;
	}

	/* The stacked photo is full-bleed, so the 443/320 cap and the 40px trailing
	   gap that the side-by-side rows need are both cancelled here — without the
	   reset the cap would hold the image at 443 instead of the column width, and
	   the trailing margin would push it 40px past the container. This block
	   renders exactly as it did before those two properties existed. */
	.wwd-item__media,
	.wwd-item.is-active .wwd-item__media {
		display: block;
		-webkit-box-flex: 0;
		    -ms-flex: 0 0 auto;
		        flex: 0 0 auto;
		width: 100%;
		max-width: none;
		margin-left: 0;
		margin-right: 0;
		margin-top: var(--sp-24);
	}

	/* An item with no image (D2) renders no media element at all, so nothing
	   here leaves a gap. */
	.wwd-item__body {
		-webkit-box-flex: 0;
		    -ms-flex: 0 0 auto;
		        flex: 0 0 auto;
		width: 100%;
		margin-left: 0;
		margin-top: var(--sp-24);
		padding: 0;
		-webkit-box-shadow: none;
		        box-shadow: none;
	}

	.wwd-item__action {
		display: block;
		margin-top: var(--sp-24);
	}
}

@media (max-width: 767px) {
	.home-what-we-do {
		padding-block: var(--sp-48);
	}

	.home-what-we-do__inner {
		gap: var(--sp-32);
	}

	.wwd-item,
	.wwd-item.is-active {
		padding-block: var(--sp-32);
	}

	.wwd-item__lead,
	.wwd-item.is-active .wwd-item__lead {
		gap: var(--sp-16);
	}

	.wwd-item__media,
	.wwd-item.is-active .wwd-item__media,
	.wwd-item__body,
	.wwd-item__action {
		margin-top: var(--sp-16);
	}
}

@media (max-width: 640px) {
	.home-what-we-do {
		padding-block: var(--sp-40);
	}

	.wwd-item,
	.wwd-item.is-active {
		padding-block: var(--sp-24);
	}
}