/**
 * Project Spotlight — the coloured band with a text column instead of a
 * preview thumbnail.
 *
 * Every value a control touches is a custom property set on `.wcps`, so
 * Elementor's generated CSS is one declaration per control rather than a
 * selector fighting this file for specificity.
 *
 * Three shapes share one grid rather than getting a layout each. `.wcps__grid`
 * is always two columns and two rows; `split` uses all four cells, and the
 * other two collapse the first column away. That keeps the count and the dots
 * a sibling of the text column instead of a child of it, which is what lets
 * them stay put when the column is switched off, and what lets the whole thing
 * fold to one column on a phone without moving a single element in the markup.
 *
 * The arrows sit outside that grid entirely, in `.wcps__stage` — a three-part
 * row of arrow, carousel, arrow that occupies the cell `.wcps__main` used to.
 */

.wcps {
	--wcps-bg: #2f6136;
	--wcps-inner-w: 100%;

	--wcps-heading-color: #fff;
	--wcps-heading-align: center;
	--wcps-heading-gap: 48px;
	--wcps-intro-color: rgba(255, 255, 255, 0.82);
	--wcps-intro-w: 720px;

	--wcps-aside-w: 280px;
	--wcps-aside-gap: 40px;
	--wcps-aside-rule: rgba(255, 255, 255, 0.18);
	--wcps-aside-label-color: rgba(255, 255, 255, 0.55);
	--wcps-aside-title-color: rgba(255, 255, 255, 0.62);
	--wcps-aside-title-color-active: #fff;

	--wcps-slide-align: center;
	--wcps-slide-max-w: 100%;
	--wcps-body-w: 70%;
	--wcps-slide-min-h: 0px;

	--wcps-media-ratio: 61.2;
	--wcps-media-max-h: none;
	--wcps-media-radius: 0px;
	--wcps-body-pad: 40px;
	--wcps-scrim: rgba(0, 0, 0, 0.5);

	--wcps-title-color: #fff;
	--wcps-title-color-hover: #f3a03b;
	--wcps-excerpt-color: rgba(255, 255, 255, 0.86);
	--wcps-meta-color: #f3a03b;
	--wcps-link-color: #f3a03b;

	--wcps-arrow-size: 44px;
	--wcps-arrow-gap: 20px;
	--wcps-arrow-lane: 0px;
	--wcps-arrow-bg: transparent;
	--wcps-arrow-color: #fff;
	--wcps-arrow-border: rgba(255, 255, 255, 0.55);
	--wcps-arrow-color-hover: #2f6136;
	--wcps-arrow-bg-hover: #fff;

	--wcps-dot-color: rgba(255, 255, 255, 0.35);
	--wcps-dot-color-active: #f3a03b;

	position: relative;
	background: var(--wcps-bg);
	padding: 80px 0;
}

/**
 * A lane either side of the carousel, only when there is something to put in it.
 */
.wcps--arrows {
	--wcps-arrow-lane: calc(var(--wcps-arrow-size) + var(--wcps-arrow-gap));
}

/**
 * Run the colour past the container the widget sits in.
 *
 * The band is meant to be edge to edge while its text stays lined up with the
 * rest of the page. A full-width Elementor section does that on its own; this
 * is the escape hatch for when the widget is inside a boxed one instead.
 * `50vw` is measured from the element's own centre, so it only lands correctly
 * on a centred container — which is the only place this is worth switching on.
 */
.wcps--bleed::before {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	left: 50%;
	width: 100vw;
	margin-left: -50vw;
	background: var(--wcps-bg);
	z-index: 0;
}

.wcps__inner {
	position: relative;
	z-index: 1;
	width: 100%;
	max-width: var(--wcps-inner-w);
	margin: 0 auto;
}

/* Heading ------------------------------------------------------------------ */

.wcps__head {
	margin-bottom: var(--wcps-heading-gap);
	text-align: var(--wcps-heading-align);
}

.wcps__heading {
	margin: 0;
	color: var(--wcps-heading-color);
	font-size: 48px;
	font-weight: 700;
	line-height: 1.2;
}

/**
 * The standfirst is an inline block so that it lines up with the heading.
 *
 * A block with `margin-inline: auto` would stay centred when the heading was
 * moved left or right; an inline-block is placed by the parent's `text-align`,
 * which is the same custom property the heading already answers to, so the two
 * can never disagree.
 */
.wcps__intro {
	display: inline-block;
	max-width: var(--wcps-intro-w);
	margin: 16px 0 0;
	color: var(--wcps-intro-color);
	text-align: inherit;
}

.wcps__intro p {
	margin: 0 0 0.75em;
}

.wcps__intro p:last-child {
	margin-bottom: 0;
}

/**
 * Full width: the arrows come up to sit on the title's baseline.
 *
 * The heading's own alignment control is deliberately overridden here rather
 * than hidden in the panel — the two halves of this row have to start at
 * opposite edges or the arrows land in the middle of the sentence.
 */
.wcps--layout-stacked .wcps__head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 32px;
	text-align: left;
}

.wcps--layout-stacked .wcps__head-text {
	min-width: 0;
}

.wcps--layout-stacked .wcps__head .wcps__controls {
	flex: none;
	padding-top: 0;
}

/* Layout ------------------------------------------------------------------- */

.wcps__grid {
	display: grid;
	grid-template-columns: var(--wcps-aside-w) minmax(0, 1fr);
	grid-template-rows: auto 1fr;
	column-gap: var(--wcps-aside-gap);
	align-items: start;
}

.wcps--aside-none .wcps__grid,
.wcps--layout-simple .wcps__grid,
.wcps--layout-stacked .wcps__grid {
	grid-template-columns: minmax(0, 1fr);
}

.wcps__aside {
	grid-column: 1;
	grid-row: 1;
	min-width: 0;
	padding-right: var(--wcps-aside-gap);
	border-right: 1px solid var(--wcps-aside-rule);
}

/**
 * The cell the carousel used to fill, with a lane held open either side of it.
 *
 * Padding rather than a three-part flex row, because the arrows are not in the
 * flow: they are laid over the stage so that they can be given the picture's
 * height rather than the slide's. The padding is what stops the carousel
 * running underneath them.
 *
 */
.wcps__stage {
	position: relative;
	grid-column: 2;
	grid-row: 1 / span 2;
	padding-right: var(--wcps-arrow-lane);
	padding-left: var(--wcps-arrow-lane);
	min-width: 0;
}

/**
 * The width here is not belt-and-braces — without it the layout runs away.
 *
 * Swiper's own `.swiper` rule sets `margin-left: auto; margin-right: auto`, and
 * auto margins switch off the stretch a grid or flex item would otherwise get:
 * the item stops taking the track's width and sizes itself to its content
 * instead. Its content is `.swiper-wrapper` at `width: 100%` holding slides at
 * `width: 100%` that are told not to shrink, so each pass of layout multiplied
 * the last one and the container ended up hundreds of thousands of pixels wide.
 * This is the same trap Featured Projects fell into; the fix travels with the
 * pattern.
 *
 * Zeroing the margins is what actually breaks the cycle; the explicit width says
 * the same thing a second way, and survives anyone reinstating them.
 */
.wcps__main {
	width: 100%;
	min-width: 0;
	margin-left: 0;
	margin-right: 0;
}

/**
 * The arrows, laid over the picture — one against each of its edges.
 *
 * Simple now that the text sits *on* the photograph: a slide is the picture
 * and nothing else, so the stage's box is the picture's box, and a strip
 * stretched top to bottom across it centres the arrows on the picture's middle
 * by itself. Nothing has to reproduce the picture's height — an earlier version
 * did, back when the text stacked above and made the slide taller than the
 * photograph, and it needed a container query and a hand-written `calc` to do
 * it. That is all gone.
 *
 * The insets take the strip in by one lane at each end so its width matches the
 * carousel's, and the arrows are pushed back out into those lanes by a negative
 * margin each.
 *
 * `z-index` because Swiper puts `z-index: 1` on `.swiper`: without it the strip
 * paints underneath the carousel and no arrow is ever seen. `pointer-events` is
 * off on the box and back on for the buttons, or it would swallow every click
 * and drag meant for the slide beneath it.
 */
.wcps__arrows {
	position: absolute;
	z-index: 2;
	inset: 0 var(--wcps-arrow-lane);
	display: flex;
	align-items: center;
	justify-content: space-between;
	max-width: var(--wcps-slide-max-w);
	margin-right: auto;
	pointer-events: none;
}

/* The slide is centred on this shape, so the strip over it has to be too. */
.wcps--layout-simple .wcps__arrows {
	margin-left: auto;
}

.wcps__arrows .wcps__arrow {
	flex: none;
	pointer-events: auto;
}

.wcps__arrow--prev {
	margin-left: calc(-1 * var(--wcps-arrow-lane));
}

.wcps__arrow--next {
	margin-right: calc(-1 * var(--wcps-arrow-lane));
}

/**
 * With no text column the slide stops spanning both rows.
 *
 * Row 2 is where the count and the dots live. Left spanning, the slide would
 * sit on top of them in the same cell and the dots would be unclickable.
 */
.wcps--aside-none .wcps__stage,
.wcps--layout-simple .wcps__stage,
.wcps--layout-stacked .wcps__stage {
	grid-column: 1;
	grid-row: 1;
}

/**
 * Slider on the left, column on the right.
 *
 * `direction: rtl` would do this in one line and take the text with it, so the
 * two cells are placed by hand instead. Only the columns swap; everything
 * inside them still reads left to right.
 */
.wcps--layout-split.wcps--aside-right .wcps__aside {
	grid-column: 2;
	padding-right: 0;
	padding-left: var(--wcps-aside-gap);
	border-right: 0;
	border-left: 1px solid var(--wcps-aside-rule);
}

.wcps--layout-split.wcps--aside-right .wcps__stage {
	grid-column: 1;
}

.wcps--layout-split.wcps--aside-right .wcps__controls {
	grid-column: 2;
}

.wcps--layout-split.wcps--aside-right.wcps--aside-none .wcps__aside,
.wcps--layout-split.wcps--aside-right.wcps--aside-none .wcps__stage,
.wcps--layout-split.wcps--aside-right.wcps--aside-none .wcps__controls {
	grid-column: 1;
}

.wcps__controls {
	grid-column: 1;
	grid-row: 2;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 20px;
	padding-top: 32px;
}

.wcps--aside-none .wcps__controls,
.wcps--layout-simple .wcps__controls {
	justify-content: center;
	padding-top: 36px;
}

/* How wide the text runs --------------------------------------------------- */

/**
 * The measure is held on the slide's *contents*, never on `.swiper-slide`.
 *
 * Swiper writes an inline pixel width onto every slide in `updateSlides()` and
 * then steps the track by that number. A `max-width` on the slide itself would
 * shrink the box the reader sees without changing the number Swiper is
 * counting in, so each change would leave a strip of empty band the width of
 * the difference. Narrowing the picture inside a full-width slide gets the same
 * look and leaves Swiper's arithmetic alone.
 *
 * The words are not sized from here any more. They lie on the picture rather
 * than under it, so how wide the frame runs and how wide a line of type runs are
 * two different questions — `--wcps-body-w` answers the second, as a share of
 * the first.
 */
.wcps__media {
	max-width: var(--wcps-slide-max-w);
}

/**
 * One slide on its own is the shape that centres.
 *
 * The other two sit under a heading and beside a column that both start at the
 * left edge, so a narrowed slide has to start there too or nothing on the band
 * lines up.
 */
.wcps--layout-simple .wcps__media {
	margin-left: auto;
	margin-right: auto;
}

/* The slide --------------------------------------------------------------- */

/**
 * `height: auto` undoes Swiper's `height: 100%` on the slide.
 *
 * Without it `autoHeight` has nothing to measure: every slide asks the wrapper
 * for its height and the wrapper asks the slides back, and the carousel settles
 * at whatever the first pass happened to produce.
 */
.wcps__slide {
	display: grid;
	grid-template-areas: "wcps-stack";
	height: auto;
	min-height: var(--wcps-slide-min-h);
	text-align: var(--wcps-slide-align);
}

/**
 * Picture and words in the same cell — this is the whole overlay.
 *
 * One named area both boxes are assigned to, rather than absolute positioning,
 * because a grid cell is as tall as the tallest thing in it: the slide takes the
 * picture's height normally, and if a long description needs more than the
 * picture's shape allows, the cell grows and the picture stretches with it
 * instead of the words spilling out the bottom.
 *
 * Writing the picture first in the template is *not* enough to put it underneath,
 * which cost a round of this: `.wcps__media` is `position: relative` so that the
 * shade and the `img` can be pinned inside it, and a positioned box paints above
 * in-flow content whatever the source order says. The words came out invisible.
 * `.wcps__body` is given a stacking position of its own below to answer that.
 */
.wcps__media,
.wcps__body {
	grid-area: wcps-stack;
}

/**
 * `aspect-ratio`, not the percentage `padding-top` hack, on purpose.
 *
 * The old version built the box's height from `padding-top: 61.2%` with an
 * absolutely-positioned `img` inside, so the box had zero *content* height —
 * everything visible came from padding. `max-height` cannot shrink padding;
 * it only clamps the auto-computed content height, which was already zero.
 * The result: every value the "Maximum height" control was set to (100px,
 * 250px, 400px, all tried) rendered identically, because the padding alone
 * always demanded its full ~716px on a 1170px-wide slide regardless of what
 * the clamp said. `aspect-ratio` computes its height as part of the normal
 * auto-sizing algorithm, which — unlike padding — genuinely participates in
 * min/max-height resolution, so the same clamp now actually does something.
 * `100 / var(--wcps-media-ratio)` turns the stored "N%" figure (height as a
 * percentage of width) into the width-over-height form `aspect-ratio` wants.
 */
.wcps__media {
	position: relative;
	display: block;
	width: 100%;
	aspect-ratio: 100 / var(--wcps-media-ratio);
	max-height: var(--wcps-media-max-h);
	/**
	 * ...but never shorter than the cell it shares with the words.
	 *
	 * `max-height` is a cap on the shape, not a refusal to back the text. Without
	 * this the two fight and the text wins: the cell grows to fit a long
	 * description, the picture stays clamped at the cap, and the last line or two
	 * hang off the bottom of the photograph onto the bare band. `min-height` beats
	 * `max-height` in the cascade, which is exactly the priority wanted here.
	 */
	min-height: 100%;
	overflow: hidden;
	border-radius: var(--wcps-media-radius);
	background: rgba(0, 0, 0, 0.14);
}

.wcps__media img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/**
 * The shade that makes white words legible on somebody else's photograph.
 *
 * A flat wash rather than a gradient, and at the same strength the banner slider
 * at the top of the page uses, so the two bands read as the same device. It is a
 * pseudo-element on the picture rather than a background on the text, because
 * the text box is only as big as the words and the shade has to cover the frame.
 */
.wcps__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--wcps-scrim);
}

/**
 * The words, centred on the picture.
 *
 * Middle rather than the foot: the block is a title and three or four lines of
 * description, not a one-line caption, and a block that size pinned to the bottom
 * edge reads as having slipped down rather than as having been placed. Sitting it
 * in the middle also keeps the same distance above and below however long a
 * particular project's description turns out to be, which a slider — where that
 * length changes under the reader every few seconds — needs more than a static
 * banner does.
 *
 * Held to `--wcps-body-w` of the picture's width, because a line running the full
 * span of a 1170px photograph is past the point where the eye can find the start
 * of the next one. `width: 100%` before the `max-width` because a grid item with
 * auto margins stops stretching, and without it the box would shrink to fit the
 * longest word rather than taking its share.
 */
.wcps__body {
	position: relative;
	z-index: 1;
	align-self: center;
	width: 100%;
	max-width: var(--wcps-body-w);
	min-width: 0;
	margin-right: auto;
	margin-left: auto;
	padding: var(--wcps-body-pad);
}

/**
 * With no picture there is no frame to sit inside: the words go back to the
 * band's own left edge rather than floating a padding's width in from nothing.
 */
.wcps--no-image .wcps__body {
	padding-right: 0;
	padding-left: 0;
}

.wcps__meta {
	margin: 0 0 8px;
	color: var(--wcps-meta-color);
	font-size: 13px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.wcps__title {
	margin: 0;
	color: var(--wcps-title-color);
	font-size: 32px;
	font-weight: 700;
	line-height: 1.2;
}

.wcps__title a {
	color: inherit;
	text-decoration: none;
	transition: color 0.25s ease;
}

.wcps__title a:hover,
.wcps__title a:focus-visible {
	color: var(--wcps-title-color-hover);
}

/**
 * The description sits a little further off the title than a paragraph normally
 * would, because on the overlay the two are the same colour on the same picture
 * and the gap is the only thing separating them.
 */
.wcps__excerpt {
	margin: 20px 0 0;
	color: var(--wcps-excerpt-color);
	font-size: 16px;
	line-height: 1.55;
}

.wcps__more,
.wcps__all-link {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	color: var(--wcps-link-color);
	font-size: 14px;
	font-weight: 600;
	text-decoration: none;
}

.wcps__more {
	margin-top: 18px;
}

.wcps__more svg,
.wcps__all-link svg {
	width: 14px;
	height: 14px;
	transition: transform 0.25s ease;
}

.wcps__more:hover svg,
.wcps__all-link:hover svg {
	transform: translateX(4px);
}

.wcps__all {
	margin: 40px 0 0;
	text-align: center;
}

/* The text column ---------------------------------------------------------- */

.wcps__aside-label {
	margin: 0 0 14px;
	color: var(--wcps-aside-label-color);
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

.wcps__aside-meta {
	margin: 0 0 6px;
	color: var(--wcps-aside-label-color);
	font-size: 12px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.wcps__aside-title {
	display: block;
	margin: 0;
	color: var(--wcps-aside-title-color);
	font-size: 18px;
	font-weight: 600;
	line-height: 1.35;
}

.wcps__aside-title a {
	color: inherit;
	text-decoration: none;
	transition: color 0.25s ease;
}

.wcps__aside-title a:hover,
.wcps__aside-title a:focus-visible {
	color: var(--wcps-aside-title-color-active);
}

/**
 * "Up next": one line of text swapped for another, cross-fading in place.
 *
 * The entries are stacked in a single grid cell rather than scrolled, which
 * makes the cell as tall as the longest title and means the column holds still
 * as projects change instead of resizing under the reader. It is also the one
 * arrangement that cannot argue with itself the way a vertical Swiper does —
 * see the long note in wildcare-featured-projects.css for what that looked
 * like.
 */
.wcps__next {
	display: grid;
	width: 100%;
}

/**
 * With no JavaScript, the first project and nothing else.
 *
 * The alternative fallback is all six titles stacked one under the other in a
 * column meant to hold one.
 */
.wcps__next-item + .wcps__next-item {
	display: none;
}

/**
 * `visibility`, not `opacity` alone.
 *
 * The entries hold links, and a link at zero opacity is still in the tab
 * order: without this, tabbing through the band walks every project title in
 * turn while the reader sees one. `visibility: hidden` takes the whole subtree
 * out of the tab order, and unlike `display: none` it still animates — which is
 * why it is in the transition list rather than left to snap.
 */
.wcps__next.is-live .wcps__next-item {
	display: block;
	grid-area: 1 / 1;
	opacity: 0;
	visibility: hidden;
	transform: translateY(10px);
	transition: opacity 0.5s ease, transform 0.5s ease, visibility 0.5s;
	pointer-events: none;
}

.wcps__next.is-live .wcps__next-item.is-active {
	opacity: 1;
	visibility: visible;
	transform: none;
	pointer-events: auto;
}

/* The list ----------------------------------------------------------------- */

.wcps__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.wcps__list-item + .wcps__list-item {
	margin-top: 2px;
}

/**
 * A full-width button so the whole row is the target, not just the words.
 *
 * The left border is the active marker: it is painted transparent rather than
 * added on activation, so the text never shifts sideways as the slider moves.
 */
.wcps__list-button {
	display: flex;
	align-items: baseline;
	gap: 10px;
	width: 100%;
	padding: 8px 0 8px 12px;
	border: 0;
	border-left: 2px solid transparent;
	background: none;
	color: inherit;
	font: inherit;
	text-align: left;
	cursor: pointer;
	transition: border-color 0.25s ease;
	-webkit-appearance: none;
	appearance: none;
}

.wcps__list-index {
	flex: none;
	color: var(--wcps-aside-label-color);
	font-size: 12px;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	letter-spacing: 0.08em;
}

.wcps__list-button:hover .wcps__aside-title,
.wcps__list-button:focus-visible .wcps__aside-title {
	color: var(--wcps-aside-title-color-active);
}

.wcps__list-item.is-active .wcps__list-button {
	border-left-color: var(--wcps-aside-title-color-active);
}

.wcps__list-item.is-active .wcps__aside-title,
.wcps__list-item.is-active .wcps__list-index {
	color: var(--wcps-aside-title-color-active);
}

/* Arrows and dots ---------------------------------------------------------- */

.wcps__arrow {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--wcps-arrow-size);
	height: var(--wcps-arrow-size);
	padding: 0;
	border: 2px solid var(--wcps-arrow-border);
	border-radius: 50%;
	background: var(--wcps-arrow-bg);
	color: var(--wcps-arrow-color);
	cursor: pointer;
	transition: background-color 0.25s ease, color 0.25s ease, border-color 0.25s ease;
	-webkit-appearance: none;
	appearance: none;
}

.wcps__arrow svg {
	width: 42%;
	height: 42%;
}

.wcps__arrow:hover,
.wcps__arrow:focus-visible {
	background: var(--wcps-arrow-bg-hover);
	border-color: var(--wcps-arrow-bg-hover);
	color: var(--wcps-arrow-color-hover);
}

.wcps__counter {
	margin: 0;
	color: var(--wcps-aside-title-color);
	font-size: 14px;
	font-variant-numeric: tabular-nums;
	letter-spacing: 0.04em;
}

.wcps__counter-sep {
	margin: 0 4px;
	opacity: 0.6;
}

.wcps__dots {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
}

.wcps__dot {
	width: 8px;
	height: 8px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: var(--wcps-dot-color);
	cursor: pointer;
	transition: background-color 0.25s ease, width 0.25s ease;
	-webkit-appearance: none;
	appearance: none;
}

.wcps__dot.is-active {
	width: 22px;
	border-radius: 4px;
	background: var(--wcps-dot-color-active);
}

/* The editor's stand-in when nothing matches ------------------------------- */

.wcps--empty {
	padding: 40px 24px;
	border: 1px dashed rgba(255, 255, 255, 0.4);
	color: #fff;
	text-align: center;
}

/* Narrow screens ----------------------------------------------------------- */

@media (max-width: 991px) {
	.wcps__grid {
		grid-template-columns: minmax(0, 1fr);
		grid-template-rows: auto auto auto;
	}

	/**
	 * The column moves rather than going.
	 *
	 * Featured Projects hides its preview strip down here because the strip is
	 * a photograph, and a second copy of a picture the visitor is about to see
	 * is the first thing to lose on the screen with the least room. A line of
	 * text costs almost nothing, so it stays — under the slide, where the rule
	 * between the two becomes a rule above it.
	 */
	.wcps__aside,
	.wcps--layout-split.wcps--aside-right .wcps__aside {
		grid-column: 1;
		grid-row: 2;
		padding: 24px 0 0;
		border: 0;
		border-top: 1px solid var(--wcps-aside-rule);
		margin-top: 28px;
	}

	.wcps__stage,
	.wcps--aside-none .wcps__stage,
	.wcps--layout-split.wcps--aside-right .wcps__stage {
		grid-column: 1;
		grid-row: 1;
	}

	.wcps__controls,
	.wcps--aside-none .wcps__controls,
	.wcps--layout-split.wcps--aside-right .wcps__controls {
		grid-column: 1;
		grid-row: 3;
		justify-content: center;
		padding-top: 28px;
	}

	/**
	 * Two up, once the column is under the slide rather than beside it.
	 *
	 * The list is as long as the project count, and a twenty-item ladder pushes
	 * the "view all" link most of a screen down the page. Across the full width
	 * it costs half the height for the same reading order — `columns` fills the
	 * first column before the second, so 1, 2, 3 still runs top to bottom.
	 */
	.wcps__list {
		columns: 2;
		column-gap: 24px;
	}

	.wcps__list-item {
		break-inside: avoid;
	}

	.wcps--layout-stacked .wcps__head {
		flex-direction: column;
		align-items: flex-start;
		gap: 20px;
	}

	.wcps__heading {
		font-size: 34px;
	}

	.wcps__title {
		font-size: 24px;
	}
}

/**
 * Under about 768px there is no width left to hand the arrows.
 *
 * Two of them plus their lanes take the better part of a third of a phone
 * screen, all of it out of the picture they are pointing at. So the lane is
 * closed here and the arrows come inside the picture instead — still against
 * its left and right edges, and still on its centre line, because the strip
 * they sit in is measured the same way either side of this breakpoint.
 *
 * The fill goes on through `--wcps-arrow-bg` rather than `background` directly:
 * a rule here setting the property would be the same specificity as
 * `.wcps__arrow:hover` and later in the file, so it would beat hover on any
 * narrow window that does have a pointer. Setting the variable leaves those two
 * declarations in the order they were written.
 */
@media (max-width: 767px) {
	.wcps--arrows {
		--wcps-arrow-lane: 0px;
	}

	.wcps__arrows {
		--wcps-arrow-bg: rgba(0, 0, 0, 0.38);
	}

	.wcps__arrow--prev {
		margin-left: 10px;
	}

	.wcps__arrow--next {
		margin-right: 10px;
	}
}

@media (max-width: 600px) {
	.wcps__list {
		columns: 1;
	}

	.wcps__heading {
		font-size: 28px;
	}

	.wcps__title {
		font-size: 20px;
	}

	.wcps__excerpt {
		font-size: 15px;
	}
}

/**
 * Anyone who has asked for less motion gets the transitions off.
 *
 * The autoplay timer is already skipped in JavaScript; this covers the change
 * itself, which still happens when they press an arrow or pick from the list.
 */
@media (prefers-reduced-motion: reduce) {
	.wcps .swiper-wrapper {
		transition-duration: 1ms !important;
	}

	.wcps__arrow,
	.wcps__dot,
	.wcps__list-button,
	.wcps__title a,
	.wcps__aside-title a,
	.wcps__more svg,
	.wcps__all-link svg {
		transition: none;
	}

	/* The line still has to swap — it just does it without sliding up. */
	.wcps__next.is-live .wcps__next-item {
		transition: none;
		transform: none;
	}
}
