/*
 * AverionHair Product Card
 *
 * A port of the React storefront's ProductCard. Every colour, radius, crop and font here is a
 * custom property, so the settings screen can retune the card without touching this file - and
 * every one of them falls back to the AverionHair child theme's --avh-* token where there is one,
 * so a site running both never drifts.
 *
 * Scoped to .avh-pc. It restyles WooCommerce's own loop classes only from inside a card.
 */

:root {
	--avh-pc-ink: var(--avh-black, #191410);
	--avh-pc-accent: var(--avh-gold, #c29a4f);
	--avh-pc-surface: var(--avh-nude, #ece0cf);
	--avh-pc-chip: var(--avh-cream, #f7f1e6);

	--avh-pc-ratio: 4 / 5;
	--avh-pc-radius: 24px;
	--avh-pc-zoom: 1.05;

	--avh-pc-font-heading: var(--avh-font-heading, "Fraunces", Georgia, "Times New Roman", serif);
	--avh-pc-font-body: var(--avh-font-body, "Hanken Grotesk", ui-sans-serif, system-ui, -apple-system, sans-serif);

	/* The storefront's easing: a long, decelerating settle rather than a linear slide. */
	--avh-pc-ease: cubic-bezier(0.16, 1, 0.3, 1);
	--avh-pc-shadow-soft: 0 2px 10px rgba(25, 20, 16, 0.06);
	--avh-pc-shadow-lifted: 0 18px 40px rgba(25, 20, 16, 0.16);
}

/* --- The card ------------------------------------------------------------------------------- */

li.product.avh-pc,
.avh-pc {
	position: relative;
	margin: 0;
	padding: 0;
	list-style: none;
	text-align: left;
	font-family: var(--avh-pc-font-body);
}

/* WooCommerce's own float-based grid, undone. Themes lay the grid out; the card only owns itself. */
li.product.avh-pc::before,
li.product.avh-pc::after {
	content: none;
}

.avh-pc__inner {
	position: relative;
	display: flex;
	flex-direction: column;
	height: 100%;
}

/* --- Image well ----------------------------------------------------------------------------- */

/*
 * The well is the positioning box for the photograph and everything laid over it. The action
 * strip has to live outside the <a> (a button inside a link is invalid and swallows its clicks),
 * so both need a shared parent to be positioned against.
 */
.avh-pc__well {
	position: relative;
}

.avh-pc__media {
	position: relative;
	display: block;
	overflow: hidden;
	aspect-ratio: var(--avh-pc-ratio);
	border-radius: var(--avh-pc-radius);
	background: var(--avh-pc-surface);
	box-shadow: var(--avh-pc-shadow-soft);
	transition: box-shadow 300ms var(--avh-pc-ease);
}

.avh-pc:hover .avh-pc__media,
.avh-pc:focus-within .avh-pc__media {
	box-shadow: var(--avh-pc-shadow-lifted);
}

.avh-pc__media img,
.avh-pc__img {
	display: block;
	width: 100%;
	height: 100%;
	margin: 0;
	object-fit: cover;
	/* 700ms: the slow, expensive-feeling zoom, not a snap. */
	transition: transform 700ms var(--avh-pc-ease);
}

.avh-pc:hover .avh-pc__img,
.avh-pc:focus-within .avh-pc__img {
	transform: scale(var(--avh-pc-zoom));
}

/*
 * The second photograph, stacked exactly on the first and revealed on hover. Opacity rather than
 * display, so the crossfade is a fade and the browser is not asked to lay anything out.
 */
.avh-pc__img--alt {
	position: absolute;
	inset: 0;
	opacity: 0;
	transition: opacity 500ms var(--avh-pc-ease), transform 700ms var(--avh-pc-ease);
}

.avh-pc:hover .avh-pc__img--alt,
.avh-pc:focus-within .avh-pc__img--alt {
	opacity: 1;
}

/*
 * Elementor's `.elementor img { height: auto; max-width: 100% }` has the same specificity as the
 * rule above and loads later, so on any Elementor page the photo stopped filling its frame. The
 * sizing alone is restated one class higher; object-fit is left to the rules either side.
 */
.avh-pc .avh-pc__media img {
	width: 100%;
	max-width: none;
	height: 100%;
}

/* A placeholder is line art, not a photograph: contain it rather than crop it. */
.avh-pc__img--placeholder {
	object-fit: contain;
	padding: 15%;
	opacity: 0.35;
}

/* --- Badges --------------------------------------------------------------------------------- */

/*
 * A column, not a pile. Before v1.2 each badge positioned itself at the same corner, which was
 * invisible while only one could ever show and became a stack of overlapping pills the moment
 * "-20%" and "Only 3 left" could appear together.
 */
.avh-pc__badges {
	position: absolute;
	left: 0.75rem;
	top: 0.75rem;
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.3rem;
	pointer-events: none;
}

.avh-pc__badge {
	display: inline-flex;
	align-items: center;
	margin: 0;
	padding: 0.35em 0.7em;
	border-radius: 999px;
	background: color-mix(in srgb, var(--avh-pc-chip) 90%, transparent);
	color: var(--avh-pc-ink);
	font-size: 0.625rem;
	font-weight: 600;
	letter-spacing: 0.14em;
	line-height: 1;
	text-transform: uppercase;
	white-space: nowrap;
	min-height: 0;
	min-width: 0;
}

.avh-pc__badge--sale {
	background: var(--avh-pc-ink);
	color: var(--avh-pc-chip);
	/* "-20%" is a number: letter-spaced small caps make it harder to read, not more elegant. */
	letter-spacing: 0.06em;
	font-variant-numeric: tabular-nums;
}

/* WooCommerce's own price markup inside a "Save $40" badge must not carry its own styling. */
.avh-pc__badge .amount,
.avh-pc__badge .woocommerce-Price-amount {
	font-size: inherit;
	font-weight: inherit;
	color: inherit;
}

.avh-pc__badge--new {
	background: var(--avh-pc-accent);
	color: #fff;
}

.avh-pc__badge--low {
	background: color-mix(in srgb, var(--avh-pc-ink) 82%, transparent);
	color: var(--avh-pc-chip);
	letter-spacing: 0.08em;
}

/* WooCommerce's native sale flash would sit on top of ours; ours is the one that is positioned. */
.avh-pc .onsale {
	display: none;
}

/* --- Hover call to action -------------------------------------------------------------------- */

/*
 * One strip that rises together. The pill takes whatever width is left, so the card looks exactly
 * as it did before v1.2 when the quick-add button is off.
 */
.avh-pc__actions {
	position: absolute;
	right: 0.75rem;
	bottom: 0.75rem;
	left: 0.75rem;
	z-index: 2;
	display: flex;
	align-items: stretch;
	gap: 0.4rem;
	opacity: 0;
	transform: translateY(0.5rem);
	transition: opacity 300ms var(--avh-pc-ease), transform 300ms var(--avh-pc-ease);
}

.avh-pc:hover .avh-pc__actions,
.avh-pc:focus-within .avh-pc__actions {
	opacity: 1;
	transform: translateY(0);
}

.avh-pc__cta {
	flex: 1 1 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	min-width: 0;
	padding: 0.7rem 0.9rem;
	border-radius: 999px;
	background: color-mix(in srgb, var(--avh-pc-ink) 85%, transparent);
	color: #fff;
	font-size: 0.7rem;
	font-weight: 500;
	letter-spacing: 0.14em;
	line-height: 1;
	text-align: center;
	text-decoration: none;
	text-transform: uppercase;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	backdrop-filter: blur(4px);
	transition: background-color 200ms var(--avh-pc-ease);
}

.avh-pc__cta:hover {
	background: var(--avh-pc-ink);
	color: #fff;
}

/* --- Quick add ------------------------------------------------------------------------------ */

/*
 * Deliberately square-ish and icon-only: the pill beside it already carries the words, and two
 * competing labels in a strip this narrow would set them both in type too small to read.
 */
li.product.avh-pc .avh-pc__quick,
.avh-pc__quick {
	position: relative;
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.6rem;
	min-height: 0;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: var(--avh-pc-chip);
	color: var(--avh-pc-ink);
	font-size: 0;
	line-height: 1;
	text-decoration: none;
	backdrop-filter: blur(4px);
	transition: background-color 200ms var(--avh-pc-ease), color 200ms var(--avh-pc-ease);
}

li.product.avh-pc .avh-pc__quick:hover,
.avh-pc__quick:hover {
	background: var(--avh-pc-accent);
	color: #fff;
}

.avh-pc__quick svg {
	display: block;
}

/* The tick waits behind the cart until WooCommerce reports the item added. */
.avh-pc__quick-tick {
	position: absolute;
	opacity: 0;
	transform: scale(0.6);
	transition: opacity 200ms var(--avh-pc-ease), transform 200ms var(--avh-pc-ease);
}

/* WooCommerce's own add-to-cart.js owns both classes; we only dress them. */
.avh-pc__quick.loading {
	opacity: 0.55;
	pointer-events: none;
}

.avh-pc__quick.added {
	background: var(--avh-pc-accent);
	color: #fff;
}

.avh-pc__quick.added .avh-pc__quick-icon {
	opacity: 0;
	transform: scale(0.6);
}

.avh-pc__quick.added .avh-pc__quick-tick {
	opacity: 1;
	transform: scale(1);
}

.avh-pc__quick-icon {
	transition: opacity 200ms var(--avh-pc-ease), transform 200ms var(--avh-pc-ease);
}

/*
 * WooCommerce appends its own "View cart" link straight after the button. Inside a floating strip
 * over a photograph it is unreadable; the tick already says the add worked, and the site's cart
 * is one click away in the header.
 */
.avh-pc__actions .added_to_cart {
	display: none;
}

/* --- Wishlist ------------------------------------------------------------------------------- */

.avh-pc__wishlist {
	position: absolute;
	right: 0.75rem;
	top: 0.75rem;
	z-index: 3;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.25rem;
	height: 2.25rem;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: color-mix(in srgb, var(--avh-pc-chip) 90%, transparent);
	box-shadow: var(--avh-pc-shadow-soft);
	color: color-mix(in srgb, var(--avh-pc-ink) 70%, transparent);
	cursor: pointer;
	transition: color 200ms var(--avh-pc-ease), transform 200ms var(--avh-pc-ease);
}

.avh-pc__wishlist:hover {
	color: var(--avh-pc-accent);
	transform: scale(1.06);
}

.avh-pc__wishlist.is-active {
	color: var(--avh-pc-accent);
}

.avh-pc__wishlist.is-active svg {
	fill: currentColor;
}

/*
 * The icons state their own size and fill, one class above anything generic. Jeg Elementor Kit
 * ships `.elementor-element svg { width: 1em; fill: currentcolor }` on every Elementor page: inside
 * the quick-add button, whose font-size is 0 to hide its text, 1em is ZERO - the cart icon vanished
 * and left an empty pill - and the fill turns every outline icon into a solid shape, which on the
 * wishlist heart reads as "already saved". Same family as the gold-on-gold navbar icon: a control
 * in this suite never inherits its own appearance.
 */
.avh-pc .avh-pc__quick svg,
.avh-pc .avh-pc__wishlist svg {
	flex: none;
	width: 18px;
	height: 18px;
	fill: none;
}

.avh-pc .avh-pc__wishlist.is-active svg {
	fill: currentColor;
}

.avh-pc__wishlist.is-busy {
	opacity: 0.5;
	pointer-events: none;
}

/* --- Meta ----------------------------------------------------------------------------------- */

.avh-pc__body {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	gap: 0.25rem;
	margin-top: 1rem;
}

.avh-pc__eyebrow {
	color: color-mix(in srgb, var(--avh-pc-ink) 45%, transparent);
	font-size: 0.62rem;
	font-weight: 600;
	letter-spacing: 0.28em;
	line-height: 1.4;
	text-transform: uppercase;
}

li.product.avh-pc .avh-pc__title,
.avh-pc__title {
	margin: 0;
	padding: 0;
	font-family: var(--avh-pc-font-heading);
	font-size: 1.25rem;
	font-weight: 400;
	letter-spacing: -0.01em;
	line-height: 1.3;
}

.avh-pc__title a {
	color: var(--avh-pc-ink);
	text-decoration: none;
	transition: color 200ms var(--avh-pc-ease);
}

.avh-pc:hover .avh-pc__title a,
.avh-pc__title a:focus-visible {
	color: var(--avh-pc-accent);
}

li.product.avh-pc .avh-pc__price,
.avh-pc__price {
	margin-top: 0.125rem;
	color: color-mix(in srgb, var(--avh-pc-ink) 80%, transparent);
	font-size: 0.875rem;
	font-weight: 500;
	font-variant-numeric: tabular-nums;
	letter-spacing: -0.01em;
}

/* A sale price is the new number, with the old one quiet beside it. */
.avh-pc__price del {
	margin-right: 0.4em;
	opacity: 0.45;
	text-decoration: line-through;
}

.avh-pc__price ins {
	background: none;
	color: inherit;
	font-weight: 600;
	text-decoration: none;
}

.avh-pc__rating {
	display: block;
	margin: 0.15rem 0 0;
	font-size: 0.75rem;
}

.avh-pc__rating .star-rating {
	margin: 0;
	color: var(--avh-pc-accent);
	font-size: 0.7em;
}

/* --- Add to cart ---------------------------------------------------------------------------- */

.avh-pc__cart {
	margin-top: 0.75rem;
}

li.product.avh-pc .avh-pc__cart .button,
.avh-pc__cart .button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	margin: 0;
	padding: 0.7rem 1rem;
	border: 1px solid var(--avh-pc-ink);
	border-radius: 999px;
	background: transparent;
	color: var(--avh-pc-ink);
	font-family: var(--avh-pc-font-body);
	font-size: 0.72rem;
	font-weight: 600;
	letter-spacing: 0.14em;
	line-height: 1;
	text-transform: uppercase;
	transition: background-color 200ms var(--avh-pc-ease), color 200ms var(--avh-pc-ease);
}

li.product.avh-pc .avh-pc__cart .button:hover,
.avh-pc__cart .button:hover {
	background: var(--avh-pc-ink);
	color: var(--avh-pc-chip);
}

.avh-pc__cart .added_to_cart {
	display: block;
	margin-top: 0.5rem;
	color: var(--avh-pc-accent);
	font-size: 0.72rem;
	letter-spacing: 0.1em;
	text-align: center;
	text-transform: uppercase;
}

/* --- Focus ---------------------------------------------------------------------------------- */

.avh-pc a:focus-visible,
.avh-pc button:focus-visible {
	outline: 2px solid var(--avh-pc-accent);
	outline-offset: 3px;
}

/* --- Motion --------------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	.avh-pc__img,
	.avh-pc__img--alt,
	.avh-pc__actions,
	.avh-pc__cta,
	.avh-pc__quick,
	.avh-pc__quick-icon,
	.avh-pc__quick-tick,
	.avh-pc__media,
	.avh-pc__wishlist,
	.avh-pc__title a {
		transition: none;
	}
	.avh-pc:hover .avh-pc__img,
	.avh-pc:focus-within .avh-pc__img {
		transform: none;
	}
	.avh-pc__actions {
		transform: none;
	}
	/* The tick still has to arrive - it is the confirmation, not decoration. */
	.avh-pc__quick.added .avh-pc__quick-tick {
		transform: none;
	}
}

/* On a touch screen there is no hover, so the strip would never appear. Show it at rest instead of
   hiding the affordance behind an interaction that does not exist. The second photograph stays
   hidden: without a pointer there is nothing to reveal it, and nothing to put it away again. */
@media (hover: none) {
	.avh-pc__actions {
		opacity: 1;
		transform: none;
	}
	.avh-pc__img--alt {
		display: none;
	}
}

/* --- Inline message ------------------------------------------------------------------------- */

/* Used for "please sign in to save items" and for a failed save. Deliberately not an alert(): one
   sentence is never worth blocking the page for. */
.avh-pc__flash {
	margin: 0.5rem 0 0;
	padding: 0.5rem 0.7rem;
	border-radius: 10px;
	background: color-mix(in srgb, var(--avh-pc-surface) 60%, transparent);
	color: var(--avh-pc-ink);
	font-size: 0.75rem;
	line-height: 1.4;
}

/* --- Swatches ------------------------------------------------------------------------------- */

/*
 * A hair product is the same style in a dozen shades and lengths, and a grid showing one
 * photograph per product hides that entirely - the shopper opens six product pages to find out
 * which of them carry 22". These rows put the range back on the card, and each option links to
 * the product with that variation already selected.
 */
.avh-pc__swatches {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
	margin-top: 0.6rem;
}

.avh-pc__swatch-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.35rem;
}

/* A colour circle. The shade itself is printed inline as --avh-pc-dot. */
.avh-pc__dot {
	display: block;
	width: 1.05rem;
	height: 1.05rem;
	border-radius: 999px;
	background: var(--avh-pc-dot, var(--avh-pc-surface));
	box-shadow: 0 0 0 1px color-mix(in srgb, var(--avh-pc-ink) 14%, transparent);
	transition: transform 200ms var(--avh-pc-ease), box-shadow 200ms var(--avh-pc-ease);
}

.avh-pc__dot:hover {
	transform: scale(1.18);
	box-shadow: 0 0 0 2px var(--avh-pc-accent);
}

/* Platinum and silver vanish against ivory, so the light shades carry a firmer ring. */
.avh-pc__dot.is-light {
	box-shadow: 0 0 0 1px color-mix(in srgb, var(--avh-pc-ink) 32%, transparent);
}

/*
 * An unrecognised shade name gets its name printed rather than a guessed circle: a customer who
 * orders from the wrong colour was misled by us, and that is a return the shop pays for.
 */
.avh-pc__chip,
.avh-pc__pill {
	display: inline-flex;
	align-items: center;
	padding: 0.2rem 0.5rem;
	border: 1px solid color-mix(in srgb, var(--avh-pc-ink) 16%, transparent);
	border-radius: 999px;
	color: color-mix(in srgb, var(--avh-pc-ink) 70%, transparent);
	font-size: 0.66rem;
	font-weight: 500;
	letter-spacing: 0.02em;
	line-height: 1.4;
	text-decoration: none;
	white-space: nowrap;
	transition: border-color 200ms var(--avh-pc-ease), color 200ms var(--avh-pc-ease);
}

.avh-pc__pill {
	font-variant-numeric: tabular-nums;
}

.avh-pc__chip:hover,
.avh-pc__pill:hover {
	border-color: var(--avh-pc-accent);
	color: var(--avh-pc-accent);
}

.avh-pc__more {
	color: color-mix(in srgb, var(--avh-pc-ink) 45%, transparent);
	font-size: 0.66rem;
	font-variant-numeric: tabular-nums;
	letter-spacing: 0.02em;
}

/* --- Visually hidden ------------------------------------------------------------------------ */

/*
 * Defined here rather than assumed. Most themes ship .screen-reader-text, but this plugin is
 * meant to work on any of them, and the difference between a defined and an undefined rule is a
 * swatch row that reads "Natural Black 1B 613" in plain sight on the card.
 */
.avh-pc .screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}
