/*
 * Fivany shop surfaces — product cards, listing, PDP, cart, checkout.
 * Ported from Opnar's `.pcard` family in components/home/home.css.
 */

/* ══════════════════════════════════════════════════════════════
   PRODUCT GRID
   ══════════════════════════════════════════════════════════════ */

.woocommerce ul.products {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 16px;
	margin: 0 0 24px;
	padding: 0;
}

.woocommerce ul.products::before,
.woocommerce ul.products::after {
	content: none;
}

@media (max-width: 1023px) {
	.woocommerce ul.products {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (max-width: 767px) {
	.woocommerce ul.products {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 12px;
	}
}

/* ── The card ──────────────────────────────────────────────────── */

.woocommerce ul.products li.product {
	background: var(--fv-cream);
	border: 0;
	border-radius: var(--fv-radius-lg);
	overflow: hidden;
	display: flex;
	flex-direction: column;
	position: relative;
	box-shadow: var(--fv-shadow-sm);
	transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
	/* Storefront lays the loop out with floats + percentage widths. */
	width: auto !important;
	float: none !important;
	margin: 0 !important;
	padding: 0;
	clear: none !important;
}

.woocommerce ul.products li.product:hover {
	transform: translateY(-2px);
	box-shadow: var(--fv-shadow-md);
	background: var(--fv-cream-hover);
}

.woocommerce ul.products li.product a.woocommerce-loop-product__link {
	display: flex;
	flex-direction: column;
	flex: 1;
	color: inherit;
	text-decoration: none;
}

/* ── Image slot — white inside the cream card ──────────────────── */

.woocommerce ul.products li.product img {
	background: var(--fv-surface);
	aspect-ratio: 1 / 1;
	object-fit: cover;
	width: 100%;
	height: auto;
	margin: 0;
	border-radius: 0;
	transition: transform 0.5s ease;
	display: block;
}

.woocommerce ul.products li.product:hover img {
	transform: scale(1.04);
}

/* The image needs its own clipping box for the zoom to stay inside. */
.woocommerce ul.products li.product a.woocommerce-loop-product__link > img {
	overflow: hidden;
}

/* ── Ribbon ────────────────────────────────────────────────────── */

.woocommerce ul.products li.product .onsale,
.woocommerce span.onsale {
	position: absolute;
	top: 8px;
	left: 8px;
	right: auto;
	margin: 0;
	padding: 3px 7px;
	min-height: 0;
	min-width: 0;
	line-height: 1.4;
	border-radius: var(--fv-radius-md);
	font-size: 10px;
	font-weight: 700;
	font-family: var(--fv-mono);
	letter-spacing: 0.04em;
	text-transform: uppercase;
	background: var(--fv-hot);
	color: #fff;
	z-index: 2;
}

/*
 * The single-product badge is a size up from the card ribbon, matching
 * Opnar's `.gal-badge.disc` (11px / 4px 7px / 10px inset) against its
 * `.ribbon` (10px / 3px 7px / 8px). A badge calibrated for a 260px card
 * reads as a speck on a 570px gallery.
 */
.single-product div.product > .onsale {
	top: 10px;
	left: 10px;
	font-size: 11px;
	padding: 4px 7px;
}

@media (max-width: 767px) {
	/* Below 768 the card is not a grid, so the badge resolves against the
	 * card's padding box instead of the gallery. Offsetting by the card's
	 * own 12px padding puts it back on the image corner. */
	.single-product div.product > .onsale {
		top: 22px;
		left: 22px;
	}
}

.woocommerce ul.products li.product .fv-ribbon-stock {
	position: absolute;
	top: 8px;
	right: 8px;
	padding: 3px 7px;
	border-radius: var(--fv-radius-md);
	font-size: 10px;
	font-weight: 700;
	font-family: var(--fv-mono);
	letter-spacing: 0.04em;
	text-transform: uppercase;
	background: var(--fv-ink);
	color: #fff;
	z-index: 2;
}

/* ── Card body ─────────────────────────────────────────────────── */

.woocommerce ul.products li.product .woocommerce-loop-product__title {
	font-size: 12.5px;
	font-weight: 600;
	line-height: 1.35;
	letter-spacing: -0.005em;
	color: var(--fv-ink);
	padding: 10px 12px 0;
	margin: 0;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	transition: color 0.15s ease;
}

.woocommerce ul.products li.product:hover .woocommerce-loop-product__title {
	color: var(--fv-accent);
}

.woocommerce ul.products li.product .fv-card-meta {
	padding: 2px 12px 0;
	font-size: 10.5px;
	color: var(--fv-ink-3);
	font-family: var(--fv-mono);
	letter-spacing: 0.02em;
	text-transform: uppercase;
}

.woocommerce ul.products li.product .price {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 6px;
	/* Bottom padding raised from 12px: the add-to-cart button used to sit
	 * under the price and give the card its lower breathing room. */
	padding: 6px 12px 16px;
	margin: auto 0 0;
	font-family: var(--fv-mono);
	color: var(--fv-ink);
	font-size: 14px;
	font-weight: 800;
	line-height: 1.3;
}

.woocommerce ul.products li.product .price ins,
.woocommerce ul.products li.product .price > .woocommerce-Price-amount {
	color: var(--fv-hot);
	font-weight: 800;
	font-size: 14px;
	text-decoration: none;
	background: transparent;
	order: 1;
}

.woocommerce ul.products li.product .price del {
	color: var(--fv-ink-3);
	font-size: 11px;
	font-weight: 400;
	text-decoration: line-through;
	opacity: 1;
	order: 2;
}

/* Price ranges on variable products read as one unit, not a sale. */
.woocommerce ul.products li.product .price .from {
	font-size: 10px;
	color: var(--fv-ink-3);
	font-weight: 500;
}

/* ── Add to cart ───────────────────────────────────────────────── */

/* ── Listing chrome ────────────────────────────────────────────── */

.woocommerce .woocommerce-result-count,
.woocommerce .woocommerce-ordering select {
	font-size: 12px;
	color: var(--fv-ink-3);
}

.woocommerce .woocommerce-ordering select {
	font-family: var(--fv-font);
}

.storefront-sorting {
	padding-bottom: 12px;
	border-bottom: 1px solid var(--fv-line);
	margin-bottom: 20px;
}

.woocommerce nav.woocommerce-pagination ul {
	border: 0;
	gap: 6px;
	display: flex;
	justify-content: center;
}

.woocommerce nav.woocommerce-pagination ul li {
	border: 0;
	margin: 0;
}

.woocommerce nav.woocommerce-pagination ul li a,
.woocommerce nav.woocommerce-pagination ul li span {
	border: 1px solid var(--fv-line);
	border-radius: var(--fv-radius-md);
	background: var(--fv-surface);
	font-family: var(--fv-mono);
	font-size: 12px;
	padding: 7px 12px;
	color: var(--fv-ink-2);
}

.woocommerce nav.woocommerce-pagination ul li span.current,
.woocommerce nav.woocommerce-pagination ul li a:hover {
	background: var(--fv-accent);
	border-color: var(--fv-accent);
	color: #fff;
}

/* ══════════════════════════════════════════════════════════════
   PRODUCT PAGE
   ══════════════════════════════════════════════════════════════ */

.single-product div.product {
	background: var(--fv-cream);
	border-radius: var(--fv-radius-xl);
	padding: 16px;
	box-shadow: var(--fv-shadow-sm);
}

/*
 * Grid, not Storefront's floats.
 *
 * Floated columns leave the taller one dictating where everything after
 * it can start: the gallery ran ~550px against a ~420px summary, so the
 * description had to clear the float and opened ~190px of dead cream
 * between the two. Opnar avoids this with a real grid
 * (`grid-template-columns: minmax(0,1.05fr) minmax(0,1fr) 320px`), and the
 * ratio here lands the gallery at ~525px — the same width Opnar's gallery
 * column resolves to at 1440.
 *
 * `align-items: start` stops the short column stretching to match the
 * tall one, and everything after the summary spans both tracks, so the
 * description begins directly under whichever column is shorter.
 */
@media (min-width: 768px) {
	.single-product div.product {
		display: grid;
		grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
		gap: 24px;
		align-items: start;
	}

	.single-product div.product > .images {
		grid-column: 1;
		grid-row: 1;
	}

	.single-product div.product > .summary {
		grid-column: 2;
		grid-row: 1;
	}

	/*
	 * Placing the badge in the gallery's grid area is what anchors it to
	 * the image. An absolutely-positioned child of a positioned grid
	 * container resolves its offsets against its GRID AREA, not the
	 * container — so `top/left` here measure from the gallery's corner
	 * rather than the card's, without the badge having to be a descendant
	 * of the gallery in the markup (WooCommerce emits it as a sibling).
	 */
	.single-product div.product > .onsale {
		grid-column: 1;
		grid-row: 1;
	}

	/* Description, related products and anything else hooked after the
	 * summary run the full width beneath both columns. */
	.single-product div.product > *:not(.images):not(.summary):not(.onsale) {
		grid-column: 1 / -1;
	}

	/*
	 * Float and percentage widths are Storefront's; the grid owns both now.
	 *
	 * The `.storefront-full-width-content` variant has to be named
	 * explicitly. Storefront ships
	 *   .storefront-full-width-content.single-product div.product .images
	 * at (0,4,2), which outranks a plain `.single-product div.product
	 * .images`, so the shorter selector alone left the widths in place —
	 * and inside a grid those percentages resolve against the TRACK rather
	 * than the parent, so `39.13%` of a 568px track rendered the gallery at
	 * 222px inside its own column. The layout looked broken; the widths
	 * were simply being measured against a new containing block.
	 */
	.single-product div.product > .images,
	.single-product div.product > .summary,
	.storefront-full-width-content.single-product div.product > .images,
	.storefront-full-width-content.single-product div.product > .summary {
		float: none;
		width: auto;
		margin: 0;
	}
}

@media (max-width: 767px) {
	.single-product div.product {
		padding: 12px;
	}
}

/*
 * The gallery image was rendering at its intrinsic 416px (the
 * `woocommerce_single` size) inside a 529px column, so it sat undersized
 * in an oversized white box. Forcing it to fill the column lets the
 * browser pick a larger candidate from the srcset WooCommerce already
 * emits, and the box then hugs the picture instead of framing it.
 */
.single-product div.product .images {
	background: var(--fv-surface);
	border-radius: var(--fv-radius-lg);
	overflow: hidden;
	/* Storefront gives both columns `margin-bottom: 3.41575em` (~48px).
	 * Above 768px the grid's `gap` handles separation; this is the
	 * stacked-layout value. */
	margin-bottom: 16px;
}

.single-product div.product .images img {
	display: block;
	width: 100%;
	height: auto;
}

/*
 * A real photo fills the frame; the placeholder is a logo, so cropping it
 * would cut the mark. WooCommerce labels its own placeholder, which is
 * exactly the hook needed to treat the two differently.
 */
.single-product div.product .images img.woocommerce-placeholder {
	object-fit: contain;
}

.single-product div.product .summary {
	padding-left: 4px;
	margin-bottom: 16px;
}

/*
 * No thumbnail strip, even on a multi-image product. Note this is the
 * flexslider CONTROL, so hiding it removes the only desktop way to reach
 * the other images — swipe still works on touch. The gallery itself is
 * left intact so the extra images stay attached to the product and in the
 * page source.
 */
.single-product .flex-control-thumbs,
.single-product .flex-control-nav {
	display: none;
}

.single-product div.product .product_title {
	font-size: 22px;
	font-weight: 700;
	letter-spacing: -0.015em;
	line-height: 1.25;
	margin-bottom: 6px;
}

.single-product div.product .summary .price {
	font-family: var(--fv-mono);
	display: flex;
	align-items: baseline;
	gap: 10px;
	flex-wrap: wrap;
	/* Storefront opens the price with `margin-top: 1.618em` (~26px), which
	 * was the single largest gap in the column — the title already carries
	 * its own bottom margin, so this one only compounded it. */
	margin-top: 0;
	margin-bottom: 12px;
}

.single-product div.product .summary .price ins,
.single-product div.product .summary .price > .woocommerce-Price-amount {
	color: var(--fv-hot);
	font-size: 24px;
	font-weight: 800;
	text-decoration: none;
	background: transparent;
}

.single-product div.product .summary .price del {
	color: var(--fv-ink-3);
	font-size: 14px;
	text-decoration: line-through;
	opacity: 1;
}

.single-product div.product .woocommerce-product-details__short-description {
	font-size: 13px;
	color: var(--fv-ink-2);
	line-height: 1.65;
	margin-bottom: 16px;
}

/* ── Variation selector ────────────────────────────────────────── */

.single-product table.variations {
	margin-bottom: 10px;
	border: 0;
}

.single-product table.variations th,
.single-product table.variations td {
	border: 0;
	padding: 3px 0;
	background: transparent;
}

.single-product table.variations th.label label {
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	font-family: var(--fv-mono);
	color: var(--fv-ink-2);
}

/*
 * The select is hidden but kept in the layout, not `display: none`.
 * WooCommerce's variation script reads and writes it, and a display-none
 * control cannot receive focus — the clip-rect pattern keeps it reachable
 * for anyone tabbing or using a screen reader while the chips carry the
 * visual job. If the chip script fails to load, `.fv-chip-source` is never
 * applied and the plain select stays visible, so the product is still
 * buyable.
 */
.single-product table.variations select {
	min-width: 180px;
	background: var(--fv-surface);
}

.single-product table.variations select.fv-chip-source {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
	min-width: 0;
}

.fv-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
}

.fv-chip {
	min-width: 44px;
	height: 36px;
	padding: 0 12px;
	background: var(--fv-surface);
	border: 1.5px solid var(--fv-line-2);
	border-radius: var(--fv-radius-md);
	font-family: var(--fv-mono);
	font-size: 12px;
	font-weight: 600;
	line-height: 1;
	color: var(--fv-ink-2);
	cursor: pointer;
	transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}

.fv-chip:hover:not(:disabled) {
	border-color: var(--fv-accent);
	color: var(--fv-accent);
	background: var(--fv-surface);
}

.fv-chip.is-active {
	border-color: var(--fv-accent);
	background: var(--fv-accent);
	color: #fff;
}

/* ── Colour swatches ───────────────────────────────────────────────
 * A swatch is the same chip with a colour disc instead of a label. The
 * ring is drawn on the button, never on the disc, so a white swatch
 * still has a visible edge against a white card.
 */
.fv-chip.fv-swatch {
	min-width: 0;
	width: 36px;
	padding: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

/*
 * Square, not a disc. The rest of the theme sits on a near-square radius
 * scale (--fv-radius-sm is 1px), so a full circle here was the one shape
 * on the page that belonged to a different design language. A square also
 * shows more of the colour at the same dimension, which is the swatch's
 * whole job.
 */
.fv-swatch-dot {
	width: 20px;
	height: 20px;
	border-radius: var(--fv-radius-sm);
	/* The swatch's own hairline keeps a light colour readable on the white
	 * chip; the chip's border is the selection state, not the edge. */
	box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.16);
	display: block;
}

.fv-chip.fv-swatch.is-active {
	background: var(--fv-surface);
	border-color: var(--fv-accent);
	box-shadow: 0 0 0 2px var(--fv-accent-soft);
}

.fv-chip.fv-swatch:disabled .fv-swatch-dot {
	opacity: 0.3;
}

/* Struck-through text is meaningless on a swatch — a diagonal bar across
 * the colour carries the same "not available" reading. */
.fv-chip.fv-swatch:disabled {
	position: relative;
	text-decoration: none;
}

.fv-chip.fv-swatch:disabled::after {
	content: '';
	position: absolute;
	left: 6px;
	right: 6px;
	top: 50%;
	height: 1.5px;
	background: var(--fv-ink-3);
	transform: rotate(-45deg);
}

/*
 * A size that exists but is unavailable in the chosen combination stays on
 * screen, struck through — removing it would shift the row and hide the
 * fact that the size is made at all.
 */
.fv-chip:disabled {
	color: var(--fv-ink-soft);
	border-color: var(--fv-line);
	background: var(--fv-muted);
	cursor: not-allowed;
	text-decoration: line-through;
}

.single-product .reset_variations {
	font-size: 11px;
	color: var(--fv-ink-3);
	font-family: var(--fv-mono);
}

.single-product .woocommerce-variation-price {
	margin-bottom: 10px;
}

/* ── Buy row ───────────────────────────────────────────────────── */

.single-product form.cart {
	display: flex;
	align-items: stretch;
	gap: 10px;
	flex-wrap: wrap;
	margin-bottom: 14px;
}

/*
 * The buy row sits inside `.woocommerce-variation-add-to-cart` on a
 * variable product, and Storefront's own margins there opened a ~50px
 * gap between the last attribute row and the quantity box.
 */
.single-product .woocommerce-variation-add-to-cart {
	margin-top: 4px;
}

.single-product .woocommerce-variation {
	margin: 0;
}

.single-product .woocommerce-variation-price:empty,
.single-product .woocommerce-variation-availability:empty,
.single-product .woocommerce-variation-description:empty {
	display: none;
}

.single-product div.product .product_meta {
	margin-top: 12px;
	padding-top: 12px;
	border-top: 1px solid var(--fv-line);
}

.single-product form.cart.variations_form {
	display: block;
}

.single-product form.cart .quantity input.qty {
	width: 72px;
	height: 42px;
	text-align: center;
	font-family: var(--fv-mono);
	font-size: 14px;
	background: var(--fv-surface);
	border: 1px solid var(--fv-line);
	border-radius: var(--fv-radius-md);
}

/*
 * A fixed basis rather than `flex: 1`. Stretching two buttons across the
 * full summary column made each ~270px on a wide screen — far bigger than
 * the text needs, and it read as a pair of banners rather than controls.
 * Both share one width so neither looks more important than its colour
 * already says.
 */
.single-product form.cart .single_add_to_cart_button {
	flex: 0 0 168px;
	height: 42px;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	border-radius: var(--fv-radius-md);
}

.single-product .woocommerce-variation-add-to-cart,
.single-product form.cart {
	justify-content: flex-start;
}

.single-product .woocommerce-variation-add-to-cart {
	display: flex;
	gap: 10px;
	align-items: stretch;
	flex-wrap: wrap;
}

/*
 * Storefront sets `float: left; margin-right: .875em` at
 * `.single-product div.product form.cart .quantity` — (0,4,2). That margin
 * stacked on top of the flex `gap`, giving 21px between the quantity box
 * and Add to Cart against 10px between the two buttons. Matching its
 * specificity is not optional here: a shorter selector silently lost and
 * the row kept its uneven rhythm. The float goes too — it means nothing in
 * a flex row and only confuses the layout.
 */
.single-product div.product form.cart .quantity {
	float: none;
	margin: 0;
}

/* ── Stock + meta ──────────────────────────────────────────────── */

.single-product .stock.in-stock {
	color: var(--fv-good);
	font-family: var(--fv-mono);
	font-size: 11.5px;
	font-weight: 600;
}

.single-product .stock.out-of-stock {
	color: var(--fv-hot);
	font-family: var(--fv-mono);
	font-size: 11.5px;
	font-weight: 600;
}

.single-product .product_meta {
	font-size: 11.5px;
	color: var(--fv-ink-3);
	border-top: 1px solid var(--fv-line);
	padding-top: 12px;
	margin-top: 4px;
}

.single-product .product_meta .sku {
	font-family: var(--fv-mono);
}

/* ── Description ───────────────────────────────────────────────────
 * WooCommerce's tab panel is replaced with a plain block (see
 * inc/woocommerce.php), so what is left to style is a heading and a
 * column of text. The measure is capped: full-bleed body copy across a
 * 1440px rail runs to ~180 characters a line, which is unreadable.
 */
.fv-product-desc {
	margin-top: 20px;
	padding-top: 18px;
	border-top: 1px solid var(--fv-line);
	/* Breathing room where the description ends — related products used to
	 * begin 24px after the last line, which read as part of the same block. */
	margin-bottom: 40px;
}

.fv-product-desc h2 {
	font-family: var(--fv-mono);
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--fv-ink-3);
	margin: 0 0 12px;
}

.fv-product-desc-body {
	font-size: 13.5px;
	line-height: 1.75;
	color: var(--fv-ink-2);
	max-width: 74ch;
}

.fv-product-desc-body > *:first-child {
	margin-top: 0;
}

.fv-product-desc-body > *:last-child {
	margin-bottom: 0;
}

.fv-product-desc-body p {
	margin: 0 0 12px;
}

/* ── Related products heading ──────────────────────────────────── */

.related.products > h2,
.up-sells > h2,
.cross-sells > h2 {
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	font-family: var(--fv-mono);
	color: var(--fv-ink);
	padding-bottom: 10px;
	border-bottom: 1px solid var(--fv-line);
	margin-bottom: 18px;
}

/* ══════════════════════════════════════════════════════════════
   CART + CHECKOUT (block-based in WooCommerce 11)
   ══════════════════════════════════════════════════════════════ */

.wp-block-woocommerce-cart,
.wp-block-woocommerce-checkout {
	font-family: var(--fv-font);
	font-size: 13px;
	color: var(--fv-ink);
}

.wc-block-components-title,
.wp-block-woocommerce-cart h1,
.wp-block-woocommerce-checkout h1 {
	font-family: var(--fv-font);
	letter-spacing: -0.01em;
}

.wc-block-components-sidebar,
.wc-block-components-totals-wrapper,
.wc-block-cart__sidebar,
.wc-block-checkout__sidebar {
	background: var(--fv-cream);
	border-radius: var(--fv-radius-lg);
}

.wc-block-components-panel,
.wc-block-components-radio-control__option {
	border-radius: var(--fv-radius-md);
}

.wc-block-components-formatted-money-amount,
.wc-block-components-totals-item__value,
.wc-block-components-product-price {
	font-family: var(--fv-mono);
	font-variant-numeric: tabular-nums;
}

.wc-block-components-totals-footer-item .wc-block-components-totals-item__value {
	color: var(--fv-hot);
	font-weight: 800;
}

.wc-block-components-button,
.wc-block-cart__submit-button,
.wc-block-components-checkout-place-order-button {
	background: var(--fv-accent) !important;
	color: #fff !important;
	border-radius: var(--fv-radius-md) !important;
	font-family: var(--fv-font);
	font-weight: 700;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	font-size: 12.5px;
}

.wc-block-components-button:hover,
.wc-block-cart__submit-button:hover,
.wc-block-components-checkout-place-order-button:hover {
	background: var(--fv-accent-hover) !important;
}

.wc-block-components-text-input input,
.wc-block-components-select select,
.wc-block-components-address-form input {
	border-radius: var(--fv-radius-md);
	border-color: var(--fv-line);
	font-family: var(--fv-font);
}

.wc-block-components-radio-control__option--checked-option-highlighted,
.wc-block-components-radio-control-accordion-option--checked-option-highlighted {
	border-color: var(--fv-accent);
	box-shadow: 0 0 0 1px var(--fv-accent);
}

/* Classic (shortcode) cart table, in case the blocks are swapped out. */
.woocommerce table.shop_table {
	border: 1px solid var(--fv-line);
	border-radius: var(--fv-radius-lg);
	font-size: 12.5px;
}

.woocommerce table.shop_table th {
	font-family: var(--fv-mono);
	font-size: 11px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--fv-ink-2);
}

/* ══════════════════════════════════════════════════════════════
   Storefront alignment corrections
   ══════════════════════════════════════════════════════════════ */

/*
 * Storefront centres loop text; Fivany's cards are left-aligned.
 *
 * Alignment only. These used to share a rule with the products header below,
 * which meant the header's `padding: 8px 0 0` was also applied to the title,
 * meta and price — wiping out the 12px gutter each of them declares and
 * leaving the text flush against the card's edge.
 */
.woocommerce ul.products li.product,
.woocommerce ul.products li.product .woocommerce-loop-product__title,
.woocommerce ul.products li.product .price,
.woocommerce ul.products li.product .fv-card-meta {
	text-align: left;
}

/* Storefront sets `.storefront-full-width-content .woocommerce-products-header
 * { text-align: center; padding: 0 0 5.9968353111em }` — ~78px of dead space
 * under the title. Match its two-class specificity to win. */
.woocommerce-products-header,
.storefront-full-width-content .woocommerce-products-header {
	padding: 8px 0 0;
	margin: 0 0 10px;
	text-align: left;
}

.woocommerce-products-header .page-title,
.woocommerce-products-header__title {
	text-align: left;
	font-size: 20px;
	letter-spacing: -0.015em;
	margin-bottom: 4px;
}

.woocommerce-products-header .term-description {
	font-size: 12.5px;
	color: var(--fv-ink-3);
	max-width: 70ch;
}

/* Duplicate sorting bar at the foot of the loop adds noise. */
.woocommerce .storefront-sorting:last-of-type {
	border-bottom: 0;
	border-top: 1px solid var(--fv-line);
	margin-top: 8px;
	margin-bottom: 0;
	padding-top: 12px;
	padding-bottom: 0;
}

/* ══════════════════════════════════════════════════════════════
   PDP corrections
   ══════════════════════════════════════════════════════════════ */

/* WooCommerce emits <del> before <ins>; Opnar leads with the price you
 * actually pay and trails the struck original. */
.single-product div.product .summary .price ins,
.single-product div.product .summary .price > .woocommerce-Price-amount {
	order: 1;
}

.single-product div.product .summary .price del {
	order: 2;
}

.single-product div.product .summary .price .screen-reader-text {
	order: 3;
}

/*
 * Clip the gallery so slides cannot bleed past the product card.
 *
 * The wrapper is deliberately NOT in this list. FlexSlider sizes it as a
 * multi-slide track — `width: 800%` for four images — and capping that at
 * `max-width: 100%` squeezed the track back to one slide's width, so the
 * floated slides wrapped into a 1727px vertical stack that `.images` then
 * clipped. It looked like a broken image; it was a wrapped track.
 *
 * Clipping the viewport is what actually contains the slides, and
 * FlexSlider sets `overflow: hidden` there itself.
 */
.woocommerce-product-gallery,
.woocommerce-product-gallery .flex-viewport {
	overflow: hidden;
	max-width: 100%;
}

/* Storefront centres these section headings. */
.related.products > h2,
.up-sells > h2,
.cross-sells > h2 {
	text-align: left;
}

/* Disabled add-to-cart (no variation chosen yet) should read as inert,
 * not as a washed-out brand colour. */
.single-product .single_add_to_cart_button.disabled,
.single-product .single_add_to_cart_button:disabled {
	background: var(--fv-ink-soft);
	color: #fff;
	opacity: 1;
	cursor: not-allowed;
}

/* ══════════════════════════════════════════════════════════════
   LISTING TOOLBAR — category / tag / shop archives
   ══════════════════════════════════════════════════════════════ */

.fv-listing-toolbar {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 6px 2px 0;
	flex-wrap: wrap;
}

.fv-listing-h {
	margin: 0;
	font-size: 18px;
	font-weight: 800;
	letter-spacing: -0.02em;
	color: var(--fv-ink);
	display: flex;
	align-items: center;
	gap: 10px;
	line-height: 1.2;
	min-width: 0;
	flex: 1 1 auto;
}

.fv-listing-h em {
	font-style: normal;
	color: var(--fv-accent);
}

.fv-listing-h .meta {
	font-family: var(--fv-mono);
	font-size: 11px;
	font-weight: 500;
	color: var(--fv-ink-3);
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.fv-listing-sub {
	margin: 8px 0 0;
	font-size: 12.5px;
	color: var(--fv-ink-3);
	line-height: 1.55;
	max-width: 70ch;
}

.fv-listing-sort {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	height: 34px;
	padding: 0 10px 0 12px;
	border: 1px solid var(--fv-line);
	border-radius: var(--fv-radius-md);
	background: var(--fv-surface);
	color: var(--fv-ink-2);
	font-size: 12.5px;
	box-shadow: var(--fv-shadow-sm);
	flex-shrink: 0;
}

.fv-listing-sort form.woocommerce-ordering {
	margin: 0;
}

.fv-listing-sort select {
	border: 0;
	background: transparent;
	font: inherit;
	font-size: 12.5px;
	font-weight: 600;
	color: var(--fv-ink);
	padding: 0;
	outline: 0;
	box-shadow: none;
	height: auto;
}

.fv-listing-sort select:focus {
	box-shadow: none;
	border: 0;
}

/* ── Subcategory chips ─────────────────────────────────────────── */

.fv-subcat-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 14px 0 18px;
}

.fv-subcat-chip {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	height: 30px;
	padding: 0 14px;
	border: 1px solid var(--fv-line);
	background: var(--fv-surface);
	border-radius: var(--fv-radius-lg);
	color: var(--fv-ink-2);
	font-size: 12.5px;
	font-weight: 600;
	letter-spacing: -0.005em;
	box-shadow: var(--fv-shadow-sm);
	transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}

.fv-subcat-chip:hover {
	border-color: var(--fv-accent);
	color: var(--fv-accent-hover);
	background: var(--fv-accent-soft);
}

.fv-subcat-chip .ct {
	font-family: var(--fv-mono);
	font-size: 10px;
	color: var(--fv-ink-3);
	letter-spacing: 0.02em;
}

.fv-subcat-chip:hover .ct {
	color: var(--fv-accent);
}

/* ── Account page title ────────────────────────────────────────────
 * Storefront prints "My account" above every screen in the account
 * area. Signed out, the sign-in card already names itself; signed in,
 * the rail says where you are and the screen carries its own heading.
 * Either way it is a second heading saying less.
 *
 * Lives here rather than in auth.css or account.css because those load
 * on opposite sides of the logged-in check — one rule in the sheet that
 * always loads beats the same rule maintained twice.
 */
.woocommerce-account .entry-header,
.woocommerce-account .woocommerce > h2 {
	display: none;
}

/* ══════════════════════════════════════════════════════════════
   BUY ROW — Add to Cart + Buy Now
   ══════════════════════════════════════════════════════════════ */

/*
 * Two actions of different weight: Buy Now is the one we want pressed, so
 * it keeps the filled brand colour, and Add to Cart steps back to an
 * outline. Both stay the same size — the hierarchy is colour, not scale,
 * so neither reads as disabled next to the other.
 */
.single-product form.cart .single_add_to_cart_button.fv-buy-now {
	background: var(--fv-accent);
	color: #fff;
	border: 1px solid var(--fv-accent);
}

.single-product form.cart .single_add_to_cart_button.fv-buy-now:hover {
	background: var(--fv-accent-hover);
	border-color: var(--fv-accent-hover);
}

/* The secondary action. `:not(.fv-buy-now)` rather than a class of its own
 * because the markup comes from WooCommerce's template, which we do not
 * override just to add one hook. */
.single-product form.cart .single_add_to_cart_button:not(.fv-buy-now) {
	background: transparent;
	color: var(--fv-accent);
	border: 1px solid var(--fv-accent);
}

.single-product form.cart .single_add_to_cart_button:not(.fv-buy-now):hover {
	background: var(--fv-accent-soft);
	color: var(--fv-accent-hover);
}

/* Disabled has to win over both treatments above, hence the extra class. */
.single-product form.cart .single_add_to_cart_button.disabled,
.single-product form.cart .single_add_to_cart_button:disabled {
	background: var(--fv-ink-soft);
	border-color: var(--fv-ink-soft);
	color: #fff;
	opacity: 1;
	cursor: not-allowed;
}

/* A simple product has no .woocommerce-variation-add-to-cart wrapper, so
 * the row is laid out on the form itself. */
.single-product form.cart {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	align-items: stretch;
}

.single-product form.cart.variations_form {
	display: block;
}

/*
 * Phones keep all three controls on one row. The desktop rule sets
 * min-width: 200px on the button, which at 390px forces each onto its own
 * line — so that floor is dropped and the two buttons split whatever is
 * left after the quantity box. `min-width: 0` is the part that actually
 * lets a flex item shrink below its content width; without it the label
 * keeps the button wide and the row wraps anyway.
 */
@media (max-width: 900px) {
	.single-product form.cart .quantity {
		flex: 0 0 auto;
	}

	/* Must match `input.qty` — the desktop width above is set at that
	 * specificity, so a `.qty` class selector loses to it. */
	.single-product form.cart .quantity input.qty {
		width: 52px;
		min-width: 0;
		padding-left: 4px;
		padding-right: 4px;
	}

	/* The wrapper wraps by default, which would undo everything below. */
	.single-product .woocommerce-variation-add-to-cart,
	.single-product form.cart {
		flex-wrap: nowrap;
	}

	.single-product form.cart .single_add_to_cart_button {
		/* Share whatever is left of the row instead of holding a fixed
		 * width — that fixed basis is what wrapped the row at ~768. */
		flex: 1 1 0;
		max-width: 200px;
		min-width: 0;
		padding-left: 6px;
		padding-right: 6px;
		font-size: 11.5px;
		letter-spacing: 0;
		white-space: nowrap;
	}
}

/* ══════════════════════════════════════════════════════════════
   YOU MAY ALSO LIKE — infinite scroll
   ══════════════════════════════════════════════════════════════ */

/*
 * Reuses `.fv-rail-head` and the shop's own `.products` grid, so this is the
 * same furniture as every other product run on the site. Only the sentinel
 * below the grid is new.
 */

.single-product .fv-alsolike {
	margin-top: 8px;
}

.single-product .fv-alsolike .fv-rail-head {
	margin-bottom: 14px;
}

/* ── Sentinel ──────────────────────────────────────────────────── */

/*
 * A reserved slot below the grid.
 *
 * It keeps its height whether or not the spinner is showing, so appending a
 * batch extends the page downward instead of shifting what the shopper is
 * already looking at.
 */
.single-product .fv-alsolike-more {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	min-height: 52px;
	margin-top: 18px;
}

.single-product .fv-alsolike-more .spin {
	display: none;
	width: 16px;
	height: 16px;
	border: 2px solid var(--fv-line-2);
	border-top-color: var(--fv-accent);
	border-radius: var(--fv-radius-full);
	animation: fv-alsolike-spin 0.7s linear infinite;
}

.single-product .fv-alsolike-more[aria-busy="true"] .spin {
	display: block;
}

@keyframes fv-alsolike-spin {
	to {
		transform: rotate(360deg);
	}
}

/*
 * A spinner is the one thing on the page that must not animate for someone
 * who asked for stillness. It stays visible as a static ring — the busy
 * state is still legible, it just does not move.
 */
@media (prefers-reduced-motion: reduce) {
	.single-product .fv-alsolike-more .spin {
		animation: none;
	}
}

.single-product .fv-alsolike-status {
	margin: 0;
	text-align: center;
	font-family: var(--fv-mono);
	font-size: 11px;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--fv-ink-3);
	min-height: 1em;
}
