/**
 * Capability cards — the Services page's three grids (drilling methods, testing
 * and sampling services, San Diego support services).
 *
 * WHAT THEY REPLACED
 *
 * All three were bare <h3> + <p> pairs: the first six sat in a core grid layout,
 * the next three in a columns block, the last two simply stacked. Nothing marked
 * where one service ended and the next began except a blank line, so the page read
 * as an eight-screen wall of text — the longest page on the site and the one with
 * the least structure.
 *
 * ONE COMPONENT, TWO FILLS
 *
 * .pd-method is the card. The fill flips with the section behind it: white cards
 * on the cream bands, cream cards on the white ones (.pd-methods--on-white). That
 * is the same inversion the homepage already runs between its specialize section
 * (white on cream) and its process steps (cream on white), so the Services page
 * needs no new visual vocabulary — it just uses the one that exists.
 *
 * NO ICON BADGE — it was built and removed.
 *
 * Before the photography arrived, each card led with the same 52px primary circle
 * the process steps use, holding a line icon per service. With a photograph above
 * it the badge stopped earning its place: the photo already says which service
 * this is, faster and better, and a second symbol saying the same thing only
 * pushed the title down. Removed rather than shrunk, because the honest answer to
 * "what is this for" was "nothing the photo isn't already doing".
 *
 * Worth knowing if a service ever ships without a photograph: the icons existed,
 * and reinstating one is a badge div plus its path data — see .pd-step__badge in
 * process.css for the shape.
 */

.pd-methods__grid {
	display: grid;

	/* auto-fit rather than a fixed count: this file serves a six-card grid, a
	   three-card grid and a two-card pair, and each should fill its row without a
	   per-section override. The 300px floor is what stops the two-card pair from
	   splitting into skinny columns on a tablet. */
	grid-template-columns: repeat( auto-fit, minmax( min( 300px, 100% ), 1fr ) );
	gap: var( --wp--preset--spacing--40 );

	/* Equal heights, so a row of cards reads as a band rather than a stepped edge. */
	align-items: stretch;
}

/**
 * SPECIFICITY: child selector at (0,2,0). Core's flow layout emits
 * `:root :where(.is-layout-flow) > :where(*) { margin-block-start: … }` at
 * (0,1,0); a lone class ties it and loses on load order, leaving stray vertical
 * margins between grid rows.
 */
.pd-methods__grid > .pd-method {
	margin-top: 0;

	display: flex;
	flex-direction: column;

	/* No horizontal padding on the card itself — the photograph runs edge to edge
	   and the text below sets its own inline padding. */
	padding: 0 0 1.75rem;
	border-radius: 14px;

	/* Clips the photograph's square corners to the card radius. */
	overflow: hidden;

	background-color: var( --wp--preset--color--base );

	/* The standard two-layer lift used by every other card set on the site. */
	box-shadow:
		0 1px 3px rgba( 0, 0, 0, 0.05 ),
		0 10px 24px rgba( 0, 0, 0, 0.06 );
}

/**
 * Cream cards for the sections that sit on white.
 *
 * No shadow: a shadow needs a lighter surface behind it to read as lift, and on
 * white the cream fill is already doing the separating. Adding both made the
 * cards look like they were floating off the page rather than sitting on it.
 */
.pd-methods--on-white > .pd-methods__grid > .pd-method {
	background-color: var( --wp--preset--color--cream );
	box-shadow: none;
}

/**
 * Card photograph.
 *
 * The photographs are the client's own, lifted from the live site and paired with
 * the same service. Most were shot portrait, so they are cropped to a landscape
 * band rather than shown whole: a portrait photo at card width would push the
 * title most of a screen down, and the subject of every one of these is centred
 * machinery that survives the crop.
 *
 * SPECIFICITY: tag-qualified at (0,1,2). Core sets `.wp-block-image img { height:
 * auto }` at (0,1,1) — a class-only selector would tie, and core's block styles
 * load after the theme's, so aspect-ratio would never apply.
 */
figure.pd-method__media {
	margin: 0;

	/* Placeholder while the photo loads. */
	background-color: var( --wp--preset--color--cream );
}

/**
 * The video card's figure is hand-written in a wp:html block, so it does not
 * carry core's `wp-block-image` class and gets none of the block's own resets.
 * Only the margin actually matters, and the rule above already sets it on the
 * class rather than the block class — this is here to say that is deliberate, and
 * that `figure.pd-method__media` must stay class-based rather than being narrowed
 * to `.wp-block-image.pd-method__media`.
 *
 * The dark ground shows for the moment between a tap and the first frame, where
 * cream would flash bright against a photograph-dark poster.
 */
figure.pd-method__media--video {
	background-color: var( --wp--preset--color--dark );

	/* Containing block for the play badge. */
	position: relative;
}

/**
 * THE PLAY BADGE.
 *
 * Covers the whole poster rather than sitting as a small target in the middle of
 * it: the entire picture is the thing you click, which is what people already
 * expect of a video thumbnail, and it gives a finger somewhere generous to land.
 * The badge itself is drawn with a pseudo-element, so the button stays a button
 * with nothing in it but an icon.
 *
 * Removed from the page by script the moment the clip starts, at which point the
 * real controls appear — see assets/js/video-card.js.
 */
.pd-method__play {
	position: absolute;
	inset: 0;

	display: grid;
	place-items: center;

	margin: 0;
	padding: 0;
	border: 0;
	background-color: transparent;
	cursor: pointer;

	/* The triangle and the ring both take their colour from here, so the hover and
	   focus states below only have to change one value. */
	color: var( --wp--preset--color--base );
}

/*
 * The disc and the triangle occupy THE SAME GRID CELL, which is what stacks them.
 * Without this they are two grid items in a single-column grid, so auto-flow put
 * the disc in row one and the triangle in row two — a ring above a small arrow,
 * both centred and neither meaning anything.
 */
.pd-method__play::before,
.pd-method__play svg {
	grid-area: 1 / 1;
}

/* The disc behind the triangle. Translucent dark rather than solid: the poster
   should still read through it as a photograph. */
.pd-method__play::before {
	content: "";
	width: 60px;
	height: 60px;
	border-radius: 50%;
	background-color: rgba( 36, 34, 45, 0.55 );
	border: 2px solid currentColor;

	/* Same softening the service-card panels use, for the same reason: an edge
	   drawn straight onto a busy photograph reads as a sticker. */
	-webkit-backdrop-filter: blur( 2px );
	backdrop-filter: blur( 2px );

	transition: transform 0.25s ease, background-color 0.25s ease;
}

.pd-method__play svg {
	/*
	 * Above the disc. Tree order alone is not enough to rely on here: the disc
	 * carries a backdrop-filter, which makes it a stacking context, and an explicit
	 * z-index on this side is what keeps the triangle out from behind it. Grid items
	 * take z-index without needing position.
	 */
	z-index: 1;

	width: 24px;
	height: 24px;
	fill: currentColor;

	/* Optical centring: a right-pointing triangle in a circle looks left-heavy
	   when its bounding box is centred. */
	margin-left: 3px;
}

/*
 * THE BADGE FADES WHILE THE CLIP PLAYS, and comes back on hover or keyboard
 * focus. That is what lets the card look like the photographs beside it while
 * something is moving in it, without removing the only way to stop the motion —
 * see the WCAG 2.2.2 note in video-card.js.
 *
 * `opacity`, deliberately, NOT `display: none` or the `hidden` attribute. The
 * button has to stay focusable while invisible so a keyboard reaches it, and
 * `pointer-events` stays on so a mouse can find it by hovering the poster.
 *
 * (`hidden` was the first attempt and did nothing at all: the `display: grid`
 * above is an author style, and author styles beat the UA stylesheet's
 * `[hidden] { display: none }` regardless of specificity. The badge simply stayed
 * put. Anything that needs to hide this button must go through this rule.)
 */
.pd-method__media--video.is-playing .pd-method__play {
	opacity: 0;
	transition: opacity 0.3s ease;
}

.pd-method__media--video.is-playing .pd-method__play:hover,
.pd-method__media--video.is-playing .pd-method__play:focus-visible {
	opacity: 1;
}

/* Play triangle before it starts, pause bars while it runs. Both paths ship in
   the markup so nothing has to be redrawn or swapped in script. */
.pd-method__icon-pause,
.pd-method__media--video.is-playing .pd-method__icon-play {
	display: none;
}

.pd-method__media--video.is-playing .pd-method__icon-pause {
	display: inline;
}

/* Gold on interaction — the accent this theme uses for every other call to act. */
.pd-method__play:hover,
.pd-method__play:focus-visible {
	color: var( --wp--preset--color--gold );
}

.pd-method__play:hover::before {
	transform: scale( 1.08 );
	background-color: rgba( 36, 34, 45, 0.7 );
}

/* The ring is the focus indicator here; the site-wide outline would draw a
   rectangle around the whole poster, which says nothing about what is focused. */
.pd-method__play:focus-visible {
	outline: none;
}

.pd-method__play:focus-visible::before {
	transform: scale( 1.08 );
	box-shadow: 0 0 0 4px rgba( 36, 34, 45, 0.45 );
}

@media ( prefers-reduced-motion: reduce ) {
	.pd-method__play::before,
	.pd-method__media--video.is-playing .pd-method__play {
		transition: none;
	}
}

/**
 * ONE BOX, PHOTOGRAPH OR VIDEO.
 *
 * The Packer Testing card carries a <video> where the others carry an <img>, and
 * it gets the identical 4:3 cover-cropped frame — so at rest, showing its poster,
 * it sits in the grid as just another card rather than as a player bolted on.
 *
 * THE CLIP IS PHONE-VERTICAL (720x1280) and this box is landscape, which is the
 * one thing that needed deciding. Letterboxing a 9:16 clip into 4:3 leaves a 162px
 * sliver of picture in a 384px card, so the crop is baked into the file instead:
 * a 720x540 band from the middle of the frame, checked across the whole 30 seconds
 * before choosing it. The camera stays centred on the work — the rig head, the
 * sealed borehole, the barrel, the gauge — so the band holds the subject the whole
 * way through and nothing here has to correct for it.
 */
figure.pd-method__media img,
figure.pd-method__media video {
	display: block;
	width: 100%;

	/*
	 * `height: auto` IS LOAD-BEARING, and only for the <video>.
	 *
	 * aspect-ratio computes the missing dimension — it does nothing when BOTH are
	 * specified. Core ships `.wp-block-image img { height: auto }`, so every
	 * photograph here already had one side auto and cropped to 4:3 correctly. The
	 * video is hand-written markup in a wp:html block, so it gets none of that, and
	 * its `height="576"` attribute applied as a presentational hint: 384 wide by a
	 * hard 576 tall, in a row of 288px boxes. The row grew by 290px and left the two
	 * cards beside it half empty.
	 *
	 * The attribute stays on the element deliberately — it is what reserves the
	 * right space before the poster arrives, so the grid does not jump.
	 */
	height: auto;

	/*
	 * SQUARE, up from 4:3 (2026-09-03).
	 *
	 * Every source on this page is portrait — rigs are vertical subjects, and the
	 * Packer Testing clip is phone-vertical — so a landscape window was throwing
	 * away the axis the photographs actually have. Four client notes in a row were
	 * some version of "we cannot see the rig", each answered by nudging a focal
	 * point along a window that was too short to begin with. This is the answer to
	 * the underlying complaint: at 384px wide the box goes 288px -> 384px, and the
	 * visible window in the source becomes exactly the source's own width, so every
	 * card shows a third more of its subject.
	 *
	 * THE FOCAL POINTS IN patterns/services.php WERE ALL RE-DERIVED FOR THIS. The
	 * arithmetic changes: with a square box the offset is `focus x (height - width)`
	 * of the source, where before it was scaled through the 4:3 overflow. Do not
	 * change this ratio without re-checking them — the percentages are not portable
	 * between window shapes.
	 */
	aspect-ratio: 1 / 1;
	object-fit: cover;

	/* Rigs stand tall in frame, so a centred crop of a portrait source tends to
	   cut the mast. Biasing upward keeps the machinery and drops the foreground.
	
	   THIS IS THE DEFAULT, NOT THE RULE. It suits a rig standing in the middle of
	   its frame; where the machine sits low, it keeps sky and cuts the rig off at
	   the bottom edge instead. Those photographs carry a `focus` in the pattern's
	   array, which emits an inline object-position and overrides this — see the
	   note on the methods loop in patterns/services.php. */
	object-position: center 35%;
}

/* Inline padding lives on the text, not the card, so the photo can run full
   bleed. Kept in one custom property so the two never drift apart. */
.pd-method {
	--pd-card-pad: 1.6rem;
}

/* Tag-qualified: theme.json sets `:root :where(h3) { font-size: large }` at
   (0,1,0), which a lone class would only tie. */
h3.pd-method__title {
	/* Was 0.9rem under the badge, which supplied its own optical gap. The title
	   now sits directly under the photograph and needs the full step itself. */
	margin: 1.35rem var( --pd-card-pad ) 0;
	font-size: 1.1875rem;
	line-height: 1.3;
	text-wrap: balance;
}

/* Child selector, same reason as the grid items above: core's flow layout puts a
   1.5rem block-gap between the title and this paragraph at (0,1,0). */
.pd-method > .pd-method__copy {
	margin: 0.65rem var( --pd-card-pad ) 0;
	font-size: 0.9375rem;
	line-height: 1.65;

	/* Recedes slightly so the titles carry the scan. */
	opacity: 0.85;
}

/* Stagger the reveal in reading order. Six is the largest grid this serves. */
.pd-methods__grid > .pd-method:nth-child( 2 ) { --pd-reveal-delay: 80ms; }
.pd-methods__grid > .pd-method:nth-child( 3 ) { --pd-reveal-delay: 160ms; }
.pd-methods__grid > .pd-method:nth-child( 4 ) { --pd-reveal-delay: 240ms; }
.pd-methods__grid > .pd-method:nth-child( 5 ) { --pd-reveal-delay: 320ms; }
.pd-methods__grid > .pd-method:nth-child( 6 ) { --pd-reveal-delay: 400ms; }

/**
 * Check list — used inside a card (Water & Vapor Sampling) and inside the soil
 * sampling panel.
 *
 * Bare <ul> markers were fine but generic; these are equipment a client scans for
 * a specific item, so each line gets a mark of its own. Drawn with ::before rather
 * than ::marker so the tick can be coloured and sized independently of the text —
 * ::marker only accepts a narrow set of properties.
 */
ul.pd-checklist {
	margin: 0.75rem 0 0;
	padding-left: 0;
	list-style: none;
}

/* Inside a card, the list has to clear the same inline padding as the text above
   it — the card itself has none, so the photo can run full bleed. */
.pd-method > ul.pd-checklist {
	margin-inline: var( --pd-card-pad );
}

ul.pd-checklist li {
	position: relative;
	padding-left: 1.6rem;
	margin-bottom: 0.4rem;
	font-size: 0.9375rem;
	line-height: 1.5;
}

ul.pd-checklist li:last-child {
	margin-bottom: 0;
}

ul.pd-checklist li::before {
	content: "✓";
	position: absolute;
	left: 0;

	/* Optical nudge: the glyph's ink sits high in its em box, so aligning the box
	   to the text baseline leaves the tick riding above the line. */
	top: 0.05em;

	color: var( --wp--preset--color--accent );
	font-weight: 700;
}
