/**
 * CSL Homepage — product card.
 *
 * Two compositions, taken from the approved design:
 *
 *   SPLIT  (sm · lg) — coloured tile. Product image fills the right half and bleeds to the
 *          bottom edge; the copy sits bottom-left. Used by the feature grid and the
 *          recommendation row.
 *   STACK  (md)             — white card. Image centred on top, copy beneath, star rating shown.
 *          Used by the product rows.
 *
 * Badge and wishlist anchor to the card's own corners in both, not to the image well.
 * Colours come entirely from the scheme the card carries — no hex values here.
 */

.csl-card {
	--csl-card-pad: var( --csl-space-4 );
	--csl-card-title: calc( var( --csl-text-sm ) * 1.5 );
	--csl-card-min: 250px;
	--csl-card-img-h: 180px;

	position: relative;
	display: flex;
	flex-direction: column;
	background-color: var( --csl-ground );
	color: var( --csl-ink );
	overflow: hidden;
	transition: box-shadow var( --csl-transition );
}

/* ------------------------------------------------------------------ washed
 *
 * The scheme's diagonal wash — `--csl-ground-deep` in the top-left corner falling to white at the
 * bottom-right — instead of its flat `--csl-ground`. Switched on per card by the `washed` render
 * argument; the feature grid uses it on its small tiles and the recommendation row on all three.
 *
 * It is a *pair*, and that is the whole reason it is one class: every `--csl-ink-soft` was toned
 * to land barely over 4.5:1 on its own flat ground, so a tint behind that text fails AA unless the
 * `-wash` tone comes with it. `csl-schemes.css` documents how those were derived.
 *
 * Two classes deep on purpose: `--csl-ink-soft` is set by `.csl-scheme--*` at one class, and equal
 * specificity would leave this depending on stylesheet order.
 *
 * Kept here beside the base `.csl-card` rule it modifies rather than down among the size variants.
 * It lived there once and was deleted along with the variant it happened to sit next to.
 */
.csl-card.csl-card--washed {
	background-image: var( --csl-ground-gradient );

	--csl-ink-soft: var( --csl-ink-soft-wash );
}

/*
 * The reveal dim lays the flat ground over the tile at 0.72, which on a washed tile flattens the
 * gradient the moment it arrives. Give the dim the same wash so revealing only lightens the tile.
 */
.csl-card--washed:has( .csl-card__actions )::after {
	background-image: var( --csl-ground-gradient );
}

/* ------------------------------------------------------- badge / wishlist */

/* Positioning only — the flag's appearance is the shared .csl-badge in the token layer. */
.csl-card__badge {
	position: absolute;
	top: var( --csl-space-3 );
	left: var( --csl-space-3 );
	z-index: 4;
}

/*
 * Above the hover overlay (z-index 6) and its dim, not below them. Hit testing follows paint
 * order, so at 5 the overlay's full-tile `inset: 0` box sat over the heart and swallowed the
 * click the moment the card was hovered — the only pointer state in which the heart is visible
 * at all on desktop. Sitting on top, the heart also keeps its own contrast while the rest of the
 * tile recedes, which is what a live control should do.
 */
.csl-card__wishlist {
	position: absolute;
	top: var( --csl-space-3 );
	right: var( --csl-space-3 );
	z-index: 7;
	line-height: 0;
}

.csl-card__wishlist .tinv-wraper { margin: 0; line-height: 0; }

.csl-card__wishlist .tinvwl_add_to_wishlist_button {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 1.5rem;
	height: 1.5rem;
	margin: 0;
	padding: 0;
	background: none;
	border: 0;
	color: var( --csl-ink );
	font-size: var( --csl-text-base );
	transition: color var( --csl-transition ), transform var( --csl-transition );
}

.csl-card__wishlist .tinvwl_add_to_wishlist_button:hover,
.csl-card__wishlist .tinvwl_add_to_wishlist_button:focus-visible {
	color: var( --csl-accent );
	transform: scale( 1.12 );
}

/* An item already saved shows a filled heart, per the design. */
.csl-card__wishlist .tinvwl-product-in-list .tinvwl_add_to_wishlist_button,
.csl-card__wishlist .tinvwl_add_to_wishlist_button.tinvwl-product-already-in {
	color: var( --csl-accent );
}

.csl-card__wishlist .tinvwl_add_to_wishlist-text,
.csl-card__wishlist .tinvwl-tooltip { display: none; }

/* -------------------------------------------------------------- image well */

.csl-card__media { position: relative; }
/*
 * Flex, so a fixed-height image can be parked centre or bottom inside the well. The padding that
 * used to sit on the image lives here now: with `width: auto` the image box tracks the packshot
 * itself, so padding on it would eat into the fixed height instead of insetting it.
 */
.csl-card__media-link {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
}

/*
 * `contain`, never `cover`. Catalogue aspect ratios run 0.08 to 1.23 — cropping to fill would
 * show a slice of barrel rather than a product.
 */
.csl-card__image {
	display: block;

	/*
	 * Fixed height, automatic width. Sizing by percentage gave every packshot a different visual
	 * size: `contain` fits the image inside its box, so a squat bottle hit the width limit and
	 * rendered far shorter than a tall one beside it. Pinning the height and letting width follow
	 * the intrinsic ratio gives every product the same weight in the grid.
	 *
	 * max-height is the guard for a tile shorter than the fixed height — the image scales down
	 * proportionally rather than spilling out of the well.
	 */
	height: var( --csl-card-img-h );
	width: auto;
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
	transition: transform var( --csl-transition );
}

@media ( hover: hover ) and ( pointer: fine ) {
	.csl-card:hover .csl-card__image { transform: scale( 1.03 ); }
}

.csl-card__placeholder {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var( --csl-space-2 );
	width: 100%;
	height: 100%;
	color: var( --csl-ink-soft );
}

.csl-card__placeholder-mark {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.4em;
	height: 2.4em;
	border: 1px solid var( --csl-rule );
	border-radius: var( --csl-radius-pill );
	font-size: var( --csl-text-lg );
	font-weight: var( --csl-weight-semibold );
	line-height: 1;
}

.csl-card__placeholder-text {
	font-size: var( --csl-text-2xs );
	letter-spacing: var( --csl-tracking-caps );
	text-transform: uppercase;
}

/* ------------------------------------------------------------------- copy */

.csl-card__body {
	display: flex;
	flex-direction: column;
	gap: 0.35em;
	padding: var( --csl-card-pad );
}

.csl-card__title {
	/*
	 * Divi's global heading rule adds `padding-bottom: 10px` to every h1-h6. Inside a clamped
	 * `-webkit-box` that padding is part of the overflow window, so the line after the ellipsis
	 * showed through as a cut-off sliver. Zero it out and the clamp ends where it says it does.
	 */
	margin: 0;
	padding: 0;
	font-size: var( --csl-card-title );
	font-weight: var( --csl-weight-semibold );
	line-height: 1.3;
	letter-spacing: 0.005em;
	text-transform: uppercase;
	color: var( --csl-ink );

	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.csl-card__title a { color: inherit; text-decoration: none; }

/* The title link covers the whole tile, so the entire card is one target. */
.csl-card__title a::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 2;
}

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

.csl-card:focus-within {
	outline: 2px solid var( --csl-accent );
	outline-offset: -2px;
}

.csl-card__brand {
	font-size: var( --csl-text-xs );
	font-weight: var( --csl-weight-regular );
	color: var( --csl-ink-soft );
}

.csl-card__price {
	display: flex;
	align-items: baseline;
	gap: 0.45em;
	margin: 0.25em 0 0;
	font-variant-numeric: tabular-nums;
}

.csl-card__price-now {
	font-size: var( --csl-text-base );
	font-weight: var( --csl-weight-bold );
	color: var( --csl-ink );
}

.csl-card__price-was {
	font-size: var( --csl-text-xs );
	font-weight: var( --csl-weight-medium );
	color: var( --csl-ink-soft );
	text-decoration: line-through;
}

.csl-card__price .woocommerce-Price-amount { color: inherit; }

/* ----------------------------------------------------------------- rating */

.csl-card__rating {
	display: flex;
	align-items: center;
	gap: 0.4em;
	margin-top: 0.15em;
	font-size: var( --csl-text-xs );
	color: var( --csl-ink-soft );
}

.csl-card__stars {
	position: relative;
	display: inline-block;
	width: 4.6em;
	height: 0.92em;
	background: linear-gradient( to right, var( --csl-accent ) var( --csl-stars, 0% ), var( --csl-rule ) var( --csl-stars, 0% ) );
	-webkit-mask: repeat-x left center / 0.92em 0.92em
		url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 1.6l2.5 5.4 5.9.7-4.4 4 1.2 5.8L10 14.6 4.8 17.5 6 11.7 1.6 7.7l5.9-.7z'/%3E%3C/svg%3E" );
	mask: repeat-x left center / 0.92em 0.92em
		url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 1.6l2.5 5.4 5.9.7-4.4 4 1.2 5.8L10 14.6 4.8 17.5 6 11.7 1.6 7.7l5.9-.7z'/%3E%3C/svg%3E" );
}

/* ------------------------------------------------------------ stock state */

.csl-card__stock {
	position: absolute;
	left: var( --csl-space-3 );
	bottom: var( --csl-space-3 );
	z-index: 3;
	padding: 0.3em 0.55em;
	border-radius: var( --csl-radius-sm );
	background-color: var( --csl-ink );
	color: var( --csl-ground );
	font-size: var( --csl-text-2xs );
	font-weight: var( --csl-weight-semibold );
	letter-spacing: var( --csl-tracking-wide );
	text-transform: uppercase;
}

.csl-card.is-out-of-stock .csl-card__image { opacity: 0.55; }

/* ----------------------------------------------------------- hover actions */

/*
 * Stacked and centred over a dimmed tile, as drawn — not a row along the bottom.
 *
 * Hidden by default and revealed by two triggers: hover on a fine pointer, and `:focus-within` for
 * the keyboard. Hiding used to live *inside* `@media ( hover: hover ) and ( pointer: fine )`, with
 * a second block moving the buttons into the flow for `hover: none`. The two were not
 * complementary — a device reporting `hover: hover` with `pointer: coarse` matched neither and got
 * the overlay pinned on at full opacity. Hidden here as the base state, revealed per trigger, has
 * no such gap: a combination nobody thought of falls through to hidden rather than to visible.
 *
 * Hidden means `opacity: 0` plus `pointer-events: none`, not `visibility` or `display`: the buttons
 * must stay focusable for `:focus-within` to be able to reveal them at all. The `pointer-events`
 * half is what stops an invisible button from swallowing a click meant for the card.
 */
.csl-card__actions {
	position: absolute;
	inset: 0;
	z-index: 6;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var( --csl-space-2 );
	padding: var( --csl-space-4 );
	opacity: 0;
	pointer-events: none;
	transition: opacity var( --csl-transition );
}

.csl-card:focus-within .csl-card__actions {
	opacity: 1;
	pointer-events: auto;
}

/*
 * Dim the tile behind the buttons rather than darkening it — the ground stays the ground.
 * The tint belongs to the card, not the image well: on the split tiles the well is only column 2
 * and on the stacked card it stops above the copy, so anchoring it there dimmed the packshot
 * alone. Sitting on .csl-card it covers the whole tile, and it fades on the same curve as the
 * buttons instead of snapping.
 */
.csl-card:has( .csl-card__actions )::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 5;
	background-color: var( --csl-ground );
	opacity: 0;
	pointer-events: none;
	transition: opacity var( --csl-transition );
}

.csl-card:focus-within:has( .csl-card__actions )::after { opacity: 0.72; }

/*
 * Both buttons carry the navy outline the design draws, and they are set chunkier than the base
 * `.csl-btn` — they sit over a dimmed packshot rather than on a page, so the outline is what
 * separates them from whatever is behind, not just decoration. 2px is the same weight the rail
 * CTA, the discount flag and the amber section buttons already use.
 */
.csl-card__action {
	position: relative;
	z-index: 3;
	min-width: 10.5rem;
	padding: 0.85em 1.25em;
	border-color: var( --csl-brand-navy );
	font-size: var( --csl-text-2xs );
	box-shadow: var( --csl-shadow-sm );
}

/* The glyph before each label. Never shrinks — the label wraps first. */
.csl-card__action-icon {
	flex: 0 0 auto;
}

/* Learn more takes the orange fill, Add to Bag the pink — both drawn that way, both in white type. */
.csl-card__action--learn {
	background-color: var( --csl-brand-orange );
	color: #ffffff;
}

.csl-card__action--learn:hover,
.csl-card__action--learn:focus-visible {
	background-color: var( --csl-brand-yellow );
	color: #ffffff;
}

.csl-card__action--add {
	background-color: var( --csl-brand-pink-deep );
	color: #ffffff;
}

.csl-card__action--add:hover,
.csl-card__action--add:focus-visible { background-color: #ac265b; }

/*
 * Without hover there is no reveal, so the overlay is dropped rather than left in the page as two
 * invisible, unreachable buttons that still take a tab stop. Tapping the card opens the product,
 * where Add to Cart lives — one target, one outcome, which is what a card on a phone should be.
 *
 * `display: none` and not the opacity pair above, deliberately: a tap on the card *focuses* the
 * title link, and `:focus-within` would then reveal an overlay the shopper never asked for.
 */
@media ( hover: none ) {
	.csl-card__actions { display: none; }
}

/* Hover only counts where a pointer can actually rest on the tile. */
@media ( hover: hover ) and ( pointer: fine ) {
	.csl-card:hover .csl-card__actions {
		opacity: 1;
		pointer-events: auto;
	}

	.csl-card:hover:has( .csl-card__actions )::after { opacity: 0.72; }

	/* The packshot nudge and the overlay are alternatives, not a pair. */
	.csl-card:hover .csl-card__image,
	.csl-card:focus-within .csl-card__image { transform: none; }
}

/* =========================================================== SPLIT variants
 * Copy bottom-left, product image filling the right half and bleeding to the bottom edge.
 */

.csl-card--sm,
.csl-card--lg {
	display: grid;
	grid-template-columns: minmax( 0, 1fr ) minmax( 0, 1fr );
	grid-template-rows: minmax( 0, 1fr );
	align-items: end;
	min-height: var( --csl-card-min );
}

.csl-card--sm .csl-card__media,
.csl-card--lg .csl-card__media {
	grid-column: 2;
	grid-row: 1;
	align-self: stretch;
	min-height: 0;
}

/*
 * Copy sits on the bottom edge of the tile in both split sizes, as drawn. The large tile used to
 * override this to `center`, which floated its title beside the middle of the packshot.
 */
.csl-card--sm .csl-card__body,
.csl-card--lg .csl-card__body {
	grid-column: 1;
	grid-row: 1;
	align-self: end;
	z-index: 2;
}

/*
 * Split tiles centre their packshot in the well (the base rule's alignment) with an even inset on
 * all four sides, so the product never runs into the tile's edge.
 */
.csl-card--sm .csl-card__media-link {
	padding: var( --csl-space-5 ) var( --csl-space-3 );
}

/*
 * Hover actions centre on the tile, not on the packshot. The overlay lives inside the media well,
 * which is column 2 of an equal `1fr 1fr` card grid, so `inset: 0` centred it over the right half.
 * Stretching it one full media-width leftwards makes it span the whole tile.
 */
.csl-card--sm .csl-card__actions,
.csl-card--lg .csl-card__actions {
	left: -100%;
}

/* Three lines, like the feature tile beside it — the taller tile has the room, and two lines
 * ellipsised most catalogue names mid-variant ("...9.11 SILVER" with the shade lost). */
.csl-card--sm .csl-card__title { -webkit-line-clamp: 3; }

.csl-card--sm {
	--csl-card-pad: var( --csl-space-4 );
	--csl-card-title: calc( var( --csl-text-xs ) * 1.5 );
	--csl-card-min: 320px;
	--csl-card-img-h: 264px;
}

/* The 2x2 feature tile: taller, larger type, image given more room. */
.csl-card--lg {
	--csl-card-pad: var( --csl-space-6 );
	--csl-card-title: calc( var( --csl-text-base ) * 1.5 );
	--csl-card-min: 600px;
	--csl-card-img-h: 516px;
}

.csl-card--lg .csl-card__title { -webkit-line-clamp: 3; }
.csl-card--lg .csl-card__price-now { font-size: var( --csl-text-xl ); }
.csl-card--lg .csl-card__media-link { padding: var( --csl-space-8 ) var( --csl-space-4 ); }

/* ============================================================ STACK variant
 * White card, image on top, copy beneath, rating shown. Used by the product rows.
 */

.csl-card--md {
	--csl-card-pad: 0;
	--csl-card-title: calc( var( --csl-text-sm ) * 1.5 );
	/* 1.2x the 180px baseline — packshots read small against the square white well. */
	--csl-card-img-h: 216px;

	display: flex;
	min-height: 0;
	background-color: transparent;
	text-align: left;
}

.csl-card--md .csl-card__media {
	aspect-ratio: 1 / 1;
	background-color: var( --csl-ground );
}

.csl-card--md .csl-card__media-link { padding: var( --csl-space-6 ) var( --csl-space-4 ); }

.csl-card--md .csl-card__body { padding: var( --csl-space-4 ) 0 0; }
.csl-card--md .csl-card__badge { top: var( --csl-space-2 ); left: 0; }
.csl-card--md .csl-card__wishlist { top: var( --csl-space-2 ); right: 0; }
.csl-card--md:hover { box-shadow: none; }

/* --------------------------------------------------------------- responsive */

@media ( max-width: 700px ) {
	.csl-card {
		--csl-card-pad: var( --csl-space-3 );
	}

	.csl-card--lg {
		--csl-card-min: 440px;
		--csl-card-title: calc( var( --csl-text-sm ) * 1.5 );
		--csl-card-img-h: 360px;
	}

	.csl-card--sm { --csl-card-min: 290px; --csl-card-img-h: 216px; }

	/*
	 * One rung down the scale, like the two tiles above. The stacked card needs it for a different
	 * reason than they do: the product row lifts its two-line clamp below 780px, so the title stops
	 * being two tidy lines and becomes the whole catalogue name — and a name like "MAYBELLINE NEW
	 * YORK ... FIT ME DEWY & SMOOTH LUMINOUS LIQUID FOUNDATION - MOCHA 360 30ML" set at 21px in a
	 * half-width phone column runs ten lines and buries the packshot and the price under type.
	 */
	.csl-card--md { --csl-card-title: calc( var( --csl-text-xs ) * 1.5 ); }

	/*
	 * The overlay's buttons are sized for a full-width desktop tile. Narrow the window enough and
	 * the stacked card drops to ~160px — narrower than the 10.5rem floor, which then overflows the
	 * square well the overlay covers. Drop the floor and let both buttons take the width they get.
	 */
	.csl-card__actions { padding: var( --csl-space-2 ); gap: var( --csl-space-2 ); }

	.csl-card__action {
		min-width: 0;
		width: 100%;
		padding: 0.7em 0.6em;
	}
}
