/*
 * petpartners/category-showcase
 *
 * An index, not a grid of cards.
 *
 * The catalogue is genuinely asymmetric: one root carries eight children and
 * the other three carry none. Same-size cards would flatten that into a lie
 * about the shape of the shop, and it is the one thing this section has to
 * communicate. So the branched root spans the full row and its children sit
 * under it in columns, while the leaf roots share the row below.
 *
 * Nothing here knows how many roots there are or which one branches — the
 * `is-branched` class is set at render time from the data.
 */

/*
 * The index's own stacking. Scoped away from the rail, which shares the block's
 * class and would otherwise inherit `display: grid` — it did, and the track
 * became a 419px grid item inside a 1320px column.
 */
.wp-block-petpartners-category-showcase:not( .is-layout-rail ) {
	display: grid;
	grid-template-columns: 1fr;
	gap: var( --wp--preset--spacing--lg );
}

.wp-block-petpartners-category-showcase__group {
	/*
	 * A hairline rule between entries, the way an index separates them. Not a
	 * card: no fill, no shadow, no radius — those would make four equal boxes
	 * out of four unequal things.
	 */
	padding-top: var( --wp--preset--spacing--sm );
	border-top: 1px solid var( --wp--preset--color--border );
}

.wp-block-petpartners-category-showcase__image {
	display: block;
	width: 100%;
	height: auto;
	margin-bottom: var( --wp--preset--spacing--sm );
	border-radius: var( --wp--preset--border-radius--lg );
}

.wp-block-petpartners-category-showcase__root {
	margin: 0 0 var( --wp--preset--spacing--xs );
}

/*
 * The heading is the link, so it is not underlined at rest.
 *
 * DESIGN.md requires an underline on a link whose only other signal is colour,
 * which is WCAG 1.4.1. That applies to a link inside running text. Here the
 * entire heading is the destination, at heading size, in a list of headings
 * that are all destinations — the same reasoning the header menu runs on. The
 * underline arrives on hover and on focus, where it confirms the target.
 */
.wp-block-petpartners-category-showcase__root a {
	color: inherit;
	text-decoration: none;
}

.wp-block-petpartners-category-showcase__root a:hover,
.wp-block-petpartners-category-showcase__root a:focus-visible {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.wp-block-petpartners-category-showcase__children {
	display: grid;
	grid-template-columns: 1fr;
	gap: var( --wp--preset--spacing--xs );
	margin: 0;
	padding: 0;
	list-style: none;
}

/*
 * The children are ordinary links in a content list, so they keep the
 * underline the headings drop.
 */
.wp-block-petpartners-category-showcase__children a {
	font-size: var( --wp--preset--font-size--base );
	line-height: var( --wp--custom--typography--base--line-height );
	text-underline-offset: 0.2em;
}

.wp-block-petpartners-category-showcase__children a:hover,
.wp-block-petpartners-category-showcase__children a:focus-visible {
	text-decoration-thickness: 2px;
}

/*
 * Touch sizing below the desktop breakpoint, for the same reason as the footer
 * columns: a 20px line stacked 12px apart passes WCAG 2.2 2.5.8 only through
 * the spacing exception, which is a pass on a technicality under a thumb.
 */
@media ( max-width: 899px ) {
	.wp-block-petpartners-category-showcase__children {
		gap: 0;
	}

	.wp-block-petpartners-category-showcase__children a {
		display: flex;
		align-items: center;
		min-height: var( --wp--custom--chrome--tap-target );
	}
}

@media ( min-width: 600px ) {
	/*
	 * Two columns from tablet width. Left at one, the three leaf roots each
	 * take a full row of their own and the section grows a column of dead
	 * space beside them.
	 */
	.wp-block-petpartners-category-showcase {
		grid-template-columns: repeat( 2, 1fr );
	}

	.wp-block-petpartners-category-showcase__group.is-branched {
		grid-column: 1 / -1;
	}

	.wp-block-petpartners-category-showcase__group.is-branched .wp-block-petpartners-category-showcase__children {
		grid-template-columns: repeat( 2, 1fr );
	}
}

@media ( min-width: 900px ) {
	.wp-block-petpartners-category-showcase {
		grid-template-columns: repeat( 3, 1fr );
		gap: var( --wp--preset--spacing--xl ) var( --wp--preset--spacing--lg );
	}

	/*
	 * At depth 1 there are no children to group under a root, so every entry is
	 * the same height and the row can take all four. At depth 2 the branched
	 * entry needs a full row of its own and three columns is the right shape
	 * for the leaves that follow it.
	 */
	.wp-block-petpartners-category-showcase.is-depth-1 {
		grid-template-columns: repeat( 4, 1fr );
	}

	/*
	 * The branched entry takes the full row and splits it: the root on the
	 * left, its children in the space beside it. Spreading eight children
	 * across the whole width under the root put 900px between the heading and
	 * the last link that belongs to it, and the grouping stopped reading.
	 */
	.wp-block-petpartners-category-showcase__group.is-branched {
		grid-column: 1 / -1;
		display: grid;
		grid-template-columns: 1fr 2fr;
		gap: var( --wp--preset--spacing--lg );
		align-items: start;
	}

	.wp-block-petpartners-category-showcase__group.is-branched .wp-block-petpartners-category-showcase__root {
		margin: 0;
	}

	.wp-block-petpartners-category-showcase__group.is-branched .wp-block-petpartners-category-showcase__children {
		grid-template-columns: repeat( 3, 1fr );
	}
}

/*
 * The rail layout.
 *
 * A different job from the index above, so a different shape. The index has to
 * show that the catalogue is asymmetric — one root carrying eight children and
 * three carrying none — and it uses rules rather than cards to say so.
 *
 * This one has the opposite job. Every cell here is a leaf: a place you can
 * actually shop, and none of them is above another. Equal tiles are the honest
 * drawing of that, and the icon is what makes a row of eleven scannable rather
 * than a wall of text.
 *
 * ONE ROW THAT SCROLLS, NOT A WRAPPING GRID
 *
 * Eleven equal tiles wrapped onto two rows put three of them alone on the
 * second, which reads as a leftover rather than a row. One rail keeps the set
 * reading as one set at every width, and it is the same gesture on a phone and
 * on a trackpad.
 *
 * The scrolling is the browser's, not ours: overflow-x plus scroll-snap. Drag,
 * swipe, wheel and tabbing through the links all work with no script at all.
 * view.js adds two arrows on top of that, and only when they would do
 * something — see its header.
 */

.wp-block-petpartners-category-showcase.is-layout-rail {
	position: relative;
	display: block;
}

.wp-block-petpartners-category-showcase__track {
	display: flex;
	gap: var( --wp--preset--spacing--sm );
	margin: 0;
	padding: 0;
	overflow-x: auto;
	list-style: none;
	scroll-snap-type: x proximity;
	/*
	 * The rail runs to the section edge, so a tile scrolled to the start should
	 * align with the heading above it rather than with the container's padding.
	 */
	scroll-padding-inline: 0;
	/*
	 * The scrollbar is hidden because the arrows and the fading edge already say
	 * "there is more", and a permanent horizontal bar under eleven tiles reads
	 * as a defect. Hiding it is safe HERE and would not be elsewhere: nothing in
	 * this rail is reachable only by scrolling it, since every tile is a link in
	 * the tab order.
	 */
	scrollbar-width: none;
}

.wp-block-petpartners-category-showcase__track::-webkit-scrollbar {
	display: none;
}

.wp-block-petpartners-category-showcase__cell {
	margin: 0;
	flex: 0 0 11.5rem;
	scroll-snap-align: start;
}

/*
 * The whole tile is the link, not the words inside it. A 44px target is the
 * floor WCAG 2.2 sets and this clears it by a wide margin, which matters more
 * here than anywhere else on the page: eleven adjacent targets is where a
 * near-miss becomes a wrong category rather than a nothing.
 */
.wp-block-petpartners-category-showcase__tile {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var( --wp--preset--spacing--sm );
	block-size: 100%;
	padding: var( --wp--preset--spacing--md ) var( --wp--preset--spacing--sm );
	/*
	 * Said here rather than relied on. This theme does not set border-box
	 * globally, and without it `block-size: 100%` resolves to 100% of the CONTENT
	 * box: the tile came out 162 + 40 of padding + 2 of border = 204px inside a
	 * 162px cell and overflowed it, so the second row of tiles started before the
	 * first row had finished. Measured, not guessed — the numbers add up exactly.
	 */
	box-sizing: border-box;
	border: 1px solid var( --wp--preset--color--border );
	border-radius: var( --wp--preset--border-radius--lg );
	color: var( --wp--preset--color--brown );
	text-align: center;
	text-decoration: none;
	transition:
		border-color var( --wp--custom--motion--duration--fast ) var( --wp--custom--motion--easing--standard ),
		background-color var( --wp--custom--motion--duration--fast ) var( --wp--custom--motion--easing--standard );
}

/*
 * Hover moves colour only. Section 7 allows transform and opacity and nothing
 * else, and a tile that lifts or grows would be the second kind — it would also
 * shift its neighbours' apparent alignment along a rail of eleven.
 */
.wp-block-petpartners-category-showcase__tile:hover,
.wp-block-petpartners-category-showcase__tile:focus-visible {
	border-color: var( --wp--preset--color--purple );
	background-color: var( --wp--preset--color--surface );
	color: var( --wp--preset--color--brown );
}

.wp-block-petpartners-category-showcase__tile:focus-visible {
	outline: 2px solid var( --wp--preset--color--purple );
	outline-offset: 2px;
}

/*
 * The icon takes its colour from the tile through currentColor, which is the
 * reason the SVGs carry no fill attribute. One drawing then serves brown on
 * white here and anything else a later call site needs.
 */
.wp-block-petpartners-category-showcase__icon {
	display: flex;
	color: var( --wp--preset--color--purple );
}

/*
 * The shield's insect is a hole in the shield, not a white shape drawn over it,
 * which is why that one file carries fill-rule="evenodd". A white fill would
 * have looked identical on this tile and become a white smear the first time an
 * icon was asked to sit on anything but white.
 */
.wp-block-petpartners-category-showcase__icon svg {
	display: block;
	fill: currentColor;
}

/*
 * Supplied artwork, painted rather than shown.
 *
 * The file is a single-colour line drawing on transparency. Used as an <img> it
 * would bring its own ink — #7521ED, where the palette's purple is #742EDF —
 * and sit a shade off beside a token-coloured icon in the next tile. As a mask
 * only the alpha survives; background-color supplies the colour, so it reads
 * currentColor exactly like the SVGs above and would follow the tile onto a
 * brown ground without anyone re-exporting anything.
 *
 * The box is square and the mask is `contain`, so an icon cropped to a wide
 * drawing and one cropped to a tall drawing occupy the same optical size. That
 * is the half of the normalisation CSS owns; the other half is the crop, in
 * scripts/make-category-icons.sh.
 *
 * -webkit- first: Safari carried the prefixed property alone for years and
 * still accepts only it in versions this store will meet.
 */
/*
 * Full-colour supplied artwork (ADR-050, Adendo 1). Unlike .is-mask this one
 * keeps its own ink — the 3D icon set carries shading and gradient that a
 * currentColor mask would flatten to a silhouette, which was the wrong call
 * once already (Joint & Mobility, before the client settled on this set).
 *
 * object-fit: contain is the raster equivalent of mask-size: contain above —
 * the box is fixed and square, and a wide crop or a tall one lands the same
 * optical size inside it.
 */
.wp-block-petpartners-category-showcase__icon.is-image {
	inline-size: 40px;
	block-size: 40px;
}

.wp-block-petpartners-category-showcase__icon.is-image img {
	display: block;
	inline-size: 100%;
	block-size: 100%;
	object-fit: contain;
}

.wp-block-petpartners-category-showcase__icon.is-mask {
	inline-size: 40px;
	block-size: 40px;
	background-color: currentColor;
	-webkit-mask-image: var( --petpartners-icon-mask );
	mask-image: var( --petpartners-icon-mask );
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
}

.wp-block-petpartners-category-showcase__label {
	font-size: var( --wp--preset--font-size--sm );
	font-weight: 600;
	line-height: var( --wp--custom--typography--sm--line-height );
}

/*
 * The arrows.
 *
 * Added by view.js, so these rules match nothing until it has run. They sit
 * over the rail's own ends rather than outside it, because outside costs width
 * at exactly the size where width is scarce.
 *
 * Hidden by default and revealed by the class the script sets, so an arrow is
 * on screen only while there is something in that direction. The transition is
 * opacity, which section 7 permits; visibility rides along so a hidden arrow
 * takes no clicks.
 */
.wp-block-petpartners-category-showcase__arrow {
	position: absolute;
	inset-block-start: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	inline-size: var( --wp--custom--chrome--tap-target );
	block-size: var( --wp--custom--chrome--tap-target );
	padding: 0;
	border: 1px solid var( --wp--preset--color--border );
	border-radius: var( --wp--preset--border-radius--pill );
	background-color: var( --wp--preset--color--white );
	color: var( --wp--preset--color--brown );
	cursor: pointer;
	opacity: 0;
	visibility: hidden;
	transform: translateY( -50% );
	transition:
		opacity var( --wp--custom--motion--duration--base ) var( --wp--custom--motion--easing--standard ),
		visibility var( --wp--custom--motion--duration--base ) var( --wp--custom--motion--easing--standard );
}

.wp-block-petpartners-category-showcase__arrow svg {
	display: block;
	fill: currentColor;
}

.wp-block-petpartners-category-showcase__arrow.is-previous {
	inset-inline-start: 0;
	transform: translate( -40%, -50% ) rotate( 180deg );
}

.wp-block-petpartners-category-showcase__arrow.is-next {
	inset-inline-end: 0;
	transform: translate( 40%, -50% );
}

.wp-block-petpartners-category-showcase__arrow:hover {
	border-color: var( --wp--preset--color--purple );
	color: var( --wp--preset--color--purple );
}

.is-layout-rail.has-previous .wp-block-petpartners-category-showcase__arrow.is-previous,
.is-layout-rail.has-next .wp-block-petpartners-category-showcase__arrow.is-next {
	opacity: 1;
	visibility: visible;
}

/*
 * A fading edge on the side that has more, so the rail says "there is more"
 * even before an arrow is noticed — and on a touch screen, where the arrows are
 * beside the point, this is the only thing that says it.
 *
 * mask rather than a gradient overlay: an overlay would be a white rectangle
 * that stops being white the day this section sits on anything else.
 */
.is-layout-rail.has-next .wp-block-petpartners-category-showcase__track {
	mask-image: linear-gradient( to right, #000 85%, transparent 100% );
}

.is-layout-rail.has-previous.has-next .wp-block-petpartners-category-showcase__track {
	mask-image: linear-gradient( to right, transparent 0, #000 6%, #000 85%, transparent 100% );
}

@media ( prefers-reduced-motion: reduce ) {

	.wp-block-petpartners-category-showcase__tile,
	.wp-block-petpartners-category-showcase__arrow {
		transition: none;
	}
}
