/* ==========================================================================
   Product grid and card. Supplier photos vary a lot, so every card sits on the
   same linen tile, and multiply lets white-background photos melt into it.
   The card itself is the link. A button appears only when it does something
   the link does not, such as adding a simple product straight to the cart.
   ========================================================================== */

/* The rows between cards come from each card's own bottom margin, because each card shares five row tracks
   with its neighbours (below), and a gap here would open between a card's own parts. */
.wc-block-product-template.mwh-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 0 clamp(12px, 2vw, 24px);
	margin: 0;
	padding: 0;
	list-style: none;
}

@media (min-width: 40rem) {
	.wc-block-product-template.mwh-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (min-width: 72rem) {
	.wc-block-product-template.mwh-grid {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

/* Each card is one container: the photo and its words inside the same white panel, at the owner's request
   (2026-11-09). Each card takes five rows of its row of cards, photo, name, price, rating, button, shared with
   the cards beside it (subgrid), so the names, prices and ratings line up whether a card has a saving or reviews
   or not, and the cards are the same height. */
.mwh-grid > .wc-block-product {
	position: relative;
	display: grid;
	grid-row: span 5;
	/* One column, never wider than the card, so a long saving tag cannot push the last line out. */
	grid-template-columns: minmax(0, 1fr);
	grid-template-rows: subgrid;
	row-gap: 0;
	align-content: start;
	width: auto !important;
	min-width: 0;
	margin: 0 0 clamp(28px, 3vw, 40px);
	padding: 8px 8px 16px;
	text-align: left;
	background: var(--mwh-paper);
	border: 1px solid var(--mwh-line);
	border-radius: 16px;
	transition: box-shadow var(--mwh-base) var(--mwh-ease), border-color var(--mwh-base) var(--mwh-ease);
}

.mwh-grid > .wc-block-product > * {
	margin-block: 0;
}

/* Each part keeps its own row, so a missing rating or button leaves its row empty rather than moving
   the parts below it. */
.mwh-grid > .wc-block-product > :first-child {
	grid-row: 1;
}

.mwh-grid > .wc-block-product > .mwh-card__title {
	grid-row: 2;
}

.mwh-grid > .wc-block-product > .mwh-card__price {
	grid-row: 3;
	align-self: start;
}

/* A button, where a card has one, comes before the last line. */
.mwh-grid > .wc-block-product > .mwh-card__cta {
	grid-row: 4;
	align-self: start;
}

/* The last line of every card, at its foot: the rating on the left, the free delivery van on the right (owner,
   2026-11-10), level with the cards beside it. */
.mwh-grid > .wc-block-product > .mwh-card__meta {
	grid-row: 5;
	align-self: end;
	/* Room between the price and saving above and the rating and van (owner, 2026-11-12: they touched). The rule
	   above that clears every part's margins would otherwise win over .mwh-card__meta's own. */
	margin-top: 12px;
}

/* The words sit a little further in than the photo, inside the panel's rounded corners. */
.mwh-grid > .wc-block-product > :not(.mwh-card__media):not(.wc-block-components-product-image) {
	padding-inline: 6px;
}

/* Phones: a little less inset, and a smaller van, so the rating and the van share one line even on a 320 px
   screen and in the sliding rows. */
@media (max-width: 47.99rem) {
	.mwh-grid > .wc-block-product > :not(.mwh-card__media):not(.wc-block-components-product-image) {
		padding-inline: 4px;
	}

	.mwh-grid .mwh-card__meta {
		gap: 6px;
	}

	.mwh-grid > .wc-block-product > .mwh-card__meta {
		margin-top: 10px;
	}

	/* Smaller again on the owner's word (2026-11-11): the van was "so huge" on phones. */
	.mwh-grid .mwh-card__delivery svg {
		width: 34px;
		height: 18px;
	}
}

/* The smallest phones, such as 320 px: a rating like "5.0 (100)" and the van still fit side by side, and
   "Save up to 68%" fits beside or under the price. */
@media (max-width: 22.49rem) {
	.mwh-grid .mwh-card__price .mwh-save {
		padding-inline: 7px;
	}

	.mwh-grid .mwh-card__meta {
		gap: 4px;
	}

	.mwh-grid .mwh-card__delivery svg {
		width: 32px;
		height: 17px;
	}
}

.mwh-card__media {
	position: relative;
}

.mwh-grid .wc-block-components-product-image {
	position: relative;
	margin: 0;
	overflow: hidden;
	aspect-ratio: 1;
	background: var(--mwh-linen);
	border-radius: 11px;
}

/* Pointing at a card lifts the whole panel a little and brings the photo closer. */
@media (hover: hover) {
	.mwh-grid > .wc-block-product:hover {
		border-color: var(--mwh-sand);
		box-shadow: 0 16px 32px -20px rgba(23, 26, 23, 0.4);
	}
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
	.mwh-grid .wc-block-components-product-image img {
		transition: transform 480ms var(--mwh-ease);
	}

	.mwh-grid > .wc-block-product:hover .wc-block-components-product-image img {
		transform: scale(1.04);
	}
}

.mwh-grid .wc-block-components-product-image a {
	display: block;
	width: 100%;
	height: 100%;
}

.mwh-grid .wc-block-components-product-image img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: contain;
	mix-blend-mode: multiply;
}

/*
 * The second photo replaces the first outright. These images blend into the tile, so fading one over
 * the other shows both at once as a double image.
 */
.mwh-card__hover {
	position: absolute;
	inset: 0;
	visibility: hidden;
}

.wc-block-product:hover .has-hover .mwh-card__hover {
	visibility: visible;
}

.wc-block-product:hover .has-hover img:not(.mwh-card__hover) {
	visibility: hidden;
}

/* WooCommerce's sale badge and our sold-out flag share one look. */
.mwh-grid .wc-block-components-product-sale-badge,
.mwh-card__flag {
	position: absolute;
	top: 8px;
	right: auto;
	bottom: auto;
	left: 8px;
	z-index: 2;
	margin: 0;
	padding: 3px 10px;
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--wp--preset--font-size--xs);
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0.01em;
	/* Solid, so the label holds on white photos as well as busy ones. */
	color: var(--mwh-paper);
	text-transform: none;
	background: var(--mwh-clay);
	border: 0;
	border-radius: 999px;
}

.mwh-card__flag {
	background: var(--mwh-ink);
}

/* The saving shows beside the price (mwh_price_saving()), so the photo carries no sale label. */
.mwh-grid .wc-block-components-product-sale-badge {
	display: none;
}

.outofstock .wc-block-components-product-image img {
	opacity: 0.55;
}

/* Titles always take two lines' room, so prices and ratings line up along a row. */
.mwh-grid .mwh-card__title {
	min-height: calc(2em * 1.35);
	margin-top: 12px;
	font-family: var(--wp--preset--font-family--sans);
	font-size: 0.9375rem;
	font-weight: 500;
	line-height: 1.35;
	letter-spacing: 0;
}

.mwh-grid .mwh-card__title a {
	display: -webkit-box;
	overflow: hidden;
	text-decoration: none;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
}

.mwh-grid .mwh-card__title a::after {
	/* The whole card behaves as one link, without a second link for screen readers to hear. */
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}

/* Pointing at a card colours its name; no underline (owner, 2026-11-09). */
.mwh-grid .mwh-card__title a:hover,
.mwh-grid > .wc-block-product:hover .mwh-card__title a {
	color: var(--mwh-evergreen);
	text-decoration: none;
}

.mwh-grid .mwh-card__title a:focus-visible {
	outline: none;
}

.mwh-grid .mwh-card__title a:focus-visible::after {
	outline: 2px solid var(--mwh-evergreen);
	outline-offset: 3px;
	border-radius: var(--mwh-radius);
}

.mwh-grid .mwh-card__price {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px 8px;
	margin-top: 8px;
	font-size: var(--wp--preset--font-size--md);
	font-weight: 600;
	line-height: 1.3;
	font-variant-numeric: lining-nums;
}

@media (min-width: 48rem) {
	.mwh-grid .mwh-card__price {
		font-size: 1.0625rem;
	}
}

/* What the shopper pays, "From $X" for options at different prices, never broken over two lines; the saving
   tag sits beside it, or under it on a narrow card (mwh_card_price()). */
.mwh-card-price {
	white-space: nowrap;
}

.mwh-card-price.is-sale {
	color: var(--mwh-clay);
}

.mwh-grid .mwh-card__price del {
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 400;
	color: var(--mwh-graphite);
}

.mwh-grid .mwh-card__price ins {
	color: var(--mwh-clay);
	text-decoration: none;
}

/* Real rating and how many colors or sizes. Absent when there is nothing true to say. */
.mwh-card__meta {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	gap: 6px 10px;
	min-width: 0;
	margin-top: 10px;
	font-size: var(--wp--preset--font-size--xs);
	line-height: 1.4;
	color: var(--mwh-graphite);
}

.mwh-card__rating {
	display: inline-flex;
	flex: none;
	white-space: nowrap;
	align-items: center;
	gap: 3px;
	color: var(--mwh-ink);
	font-variant-numeric: tabular-nums;
}

.mwh-card__star {
	flex: none;
	width: 13px;
	height: 13px;
	background: currentColor;
	-webkit-mask: var(--mwh-icon-star) center / contain no-repeat;
	mask: var(--mwh-icon-star) center / contain no-repeat;
}

.mwh-card__reviews {
	color: var(--mwh-graphite);
}

/* The free delivery van keeps to the right end of the rating line. */
.mwh-card__delivery {
	margin-left: auto;
}


.mwh-grid .mwh-card__cta,
.mwh-grid .mwh-card__cta.wp-block-button {
	position: relative;
	z-index: 2;
	display: flex;
	justify-content: flex-start;
	margin-top: auto;
	padding-top: 10px;
	text-align: left;
}

.mwh-grid .mwh-card__cta .wp-block-button__link,
.mwh-grid .mwh-card__cta .button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: auto;
	min-height: 40px;
	margin: 0;
	padding: 8px 14px;
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 600;
	color: var(--mwh-evergreen);
	text-decoration: none;
	background: var(--mwh-paper);
	border: 1px solid var(--mwh-evergreen);
	border-radius: var(--mwh-radius-sm);
}

@media (pointer: coarse) {
	.mwh-grid .mwh-card__cta .wp-block-button__link,
	.mwh-grid .mwh-card__cta .button {
		min-height: 44px;
	}
}

.mwh-grid .mwh-card__cta .wp-block-button__link:hover,
.mwh-grid .mwh-card__cta .button:hover {
	color: var(--mwh-paper);
	background: var(--mwh-evergreen);
}

/* WooCommerce centres this wrapper. Everything else on the card is left-aligned. */
.mwh-grid .mwh-card__cta .wc-block-components-product-button,
.mwh-grid .wc-block-components-product-button {
	align-items: flex-start;
	justify-content: flex-start;
	margin: 0;
}

.mwh-grid .wc-block-components-product-button__button {
	margin: 0;
}

/* Placeholder for products with no image: quiet, and still a stable square. */
.mwh-grid .wc-block-components-product-image img[src*="woocommerce-placeholder"] {
	padding: 20%;
	opacity: 0.6;
}

/* Rails
   --------------------------------------------------------------------------
   Phones: one row that scrolls sideways with the next card peeking in, so a rail costs one
   screen's worth of height. It is native scrolling, and links scroll into view on focus. */
@media (max-width: 47.99rem) {
	/* One sliding row, laid out as a grid so its cards still share their rows. Every column is an equal sliding
	   column: the grid's two fixed columns would otherwise squeeze the first cards to nothing. */
	.mwh-rail .wc-block-product-template.mwh-grid {
		display: grid;
		grid-template-columns: none;
		grid-template-rows: repeat(5, auto);
		grid-auto-columns: clamp(140px, 42vw, 200px);
		grid-auto-flow: column;
		gap: 0 12px;
		width: calc(100% + 2 * var(--mwh-gutter));
		max-width: none;
		margin-inline: calc(var(--mwh-gutter) * -1);
		padding: 4px var(--mwh-gutter) 10px;
		overflow-x: auto;
		overscroll-behavior-x: contain;
		scroll-padding-inline: var(--mwh-gutter);
		scroll-snap-type: x proximity;
		scrollbar-width: none;
	}

	/* With a mouse, a card lifts with a shadow; the row keeps room for it so the shadow is not cut off. */
	@media (hover: hover) {
		.mwh-rail .wc-block-product-template.mwh-grid {
			padding-bottom: 28px;
		}
	}

	/* No scrollbar: a finger scrolls it, and header.js adds arrow buttons. */
	.mwh-rail .wc-block-product-template.mwh-grid::-webkit-scrollbar {
		display: none;
	}

	.mwh-rail .mwh-grid > .wc-block-product {
		margin-bottom: 0;
		scroll-snap-align: start;
	}
}

/* Three columns would strand a fourth product on its own row. */
@media (min-width: 48rem) and (max-width: 71.99rem) {
	.mwh-rail .mwh-grid > .wc-block-product:nth-child(n + 4) {
		display: none;
	}
}

/* Feature rail: the category's own image takes the first column of the same four-column grid, so
   the shape interrupts the rhythm while the cards still line up with every other rail. */
.mwh-rail__visual {
	display: none;
	color: inherit;
}

.mwh-rail__visual .mwh-drop {
	width: 100%;
}

.mwh-rail__visual img {
	transition: transform var(--mwh-slow) var(--mwh-ease);
}

.mwh-rail__visual:hover img {
	transform: scale(1.03);
}

@media (min-width: 64rem) {
	.mwh-rail__visual {
		display: block;
	}

	.mwh-rail--feature:has(.mwh-rail__visual) {
		--mwh-rail-gap: clamp(12px, 2vw, 24px);
		--mwh-rail-col: calc((100% - 3 * var(--mwh-rail-gap)) / 4);
		display: grid;
		grid-template-columns: var(--mwh-rail-col) minmax(0, 1fr);
		column-gap: var(--mwh-rail-gap);
		align-items: start;
	}

	/* Every child is placed by hand, because WooCommerce adds a notices element as the first child.
	   It keeps a full-width first row of its own, which takes no height while it is empty. */
	.mwh-rail--feature:has(.mwh-rail__visual) > * {
		grid-column: 1 / -1;
		grid-row: 1;
	}

	.mwh-rail--feature:has(.mwh-rail__visual) > .mwh-section__head {
		grid-row: 2;
	}

	.mwh-rail--feature:has(.mwh-rail__visual) > .mwh-rail__visual {
		grid-area: 3 / 1;
	}

	.mwh-rail--feature:has(.mwh-rail__visual) > .mwh-grid {
		grid-area: 3 / 2;
	}

	.mwh-rail--feature:has(.mwh-rail__visual) .wc-block-product-template.mwh-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}

	.mwh-rail--feature:has(.mwh-rail__visual) .mwh-grid > .wc-block-product:nth-child(n + 4) {
		display: none;
	}

	.mwh-rail--flip:has(.mwh-rail__visual) {
		grid-template-columns: minmax(0, 1fr) var(--mwh-rail-col);
	}

	.mwh-rail--flip:has(.mwh-rail__visual) > .mwh-rail__visual {
		grid-area: 3 / 2;
	}

	.mwh-rail--flip:has(.mwh-rail__visual) > .mwh-grid {
		grid-area: 3 / 1;
	}
}
