/*
 * RVM Product Page Redesign — the general single-product visual refresh,
 * enqueued by RVM_Product_Redesign for EVERY product page on the site
 * (see that file for why it's built against WooCommerce's own standard
 * template classes rather than anything theme-specific).
 *
 * --rvm-accent / --rvm-accent-rgb are set inline, per-request, from the
 * brand colour under Settings → RVM Settings — see
 * RVM_Product_Redesign::enqueue_assets(). Everything else below is a
 * fixed neutral palette that works with any brand colour.
 *
 * Scoped to ".single-product .product" throughout — WooCommerce's own
 * standard wrapper on the single-product template — so none of this can
 * ever leak onto the shop/archive grid, cart, or anywhere else.
 */

.single-product .product {
	--rvm-ink: #1a1d21;
	--rvm-muted: #6b7280;
	--rvm-border: #e5e7eb;
	--rvm-surface: #ffffff;
	--rvm-surface-soft: #f8f9fa;
	max-width: 1180px;
	margin: 0 auto;
}

/* Breadcrumb ("Home / Experiences / ... / <product>") — the theme prints
 * this in its own `.page-head` section, above `.product` entirely, but
 * (confirmed live) it shares the same container and already renders at
 * the exact same left offset and width as `.product` at every size that
 * was checked, so capping it to the same 1180px and centering it lines
 * it up with the redesigned card below instead of the page's default
 * full-bleed edge-to-edge text. Only the two colour/size properties are
 * touched — link markup and the "/" separators are left as the theme
 * prints them. */
.single-product .woocommerce-breadcrumb {
	max-width: 1180px;
	margin: 0 auto 18px;
	font-size: 13px;
	color: var(--rvm-muted);
}

.single-product .woocommerce-breadcrumb a {
	color: var(--rvm-muted);
	text-decoration: none;
}

.single-product .woocommerce-breadcrumb a:hover {
	color: var(--rvm-accent, #1E8E3E);
	text-decoration: underline;
}

/* Scoped border-box reset for everything this redesign touches — can't
 * assume the active theme provides a global one. Without this, the
 * summary card's own padding below adds ON TOP OF its flex-basis width
 * (the browser default is content-box), which is just enough on most
 * screen widths to push the two-column layout above over 100% and force
 * an unwanted wrap to a single stacked column even on desktop. */
.single-product .product,
.single-product .product *,
.single-product .product *::before,
.single-product .product *::after {
	box-sizing: border-box;
}

/* Sticky gallery, NOT a sticky summary. Earlier versions of this file
 * tried to build a two-column layout by putting `display: flex` directly
 * on `.product` and making the SUMMARY column sticky — checked against
 * this site's actual live markup, that was wrong on two counts: (1) this
 * theme (th-shop-mania) already lays the gallery and summary out as a
 * two-column flex row itself, one level down, inside its own
 * `.thunk-single-product-summary-wrap` element — `.product`'s own direct
 * children are actually that wrapper and `.woocommerce-tabs`, so the
 * earlier flex rule never touched the gallery/summary at all and instead
 * pulled the Description/Redemption Terms tabs into an unwanted flex row
 * alongside the wrapper; and (2) even if it HAD applied, making the
 * TALLER column (summary — title, price, description, the "Redeem at"
 * card with its embedded map, stock, Add to Basket, categories, the
 * vendor card) the sticky one is backwards: once you scroll past the
 * SHORTER gallery column's own natural height, the space it used to
 * occupy is just blank, while the sticky (taller) summary is still
 * showing — exactly the "lots of white space under the image" gap this
 * was reported as.
 *
 * Sticking the SHORTER column instead (the gallery) has no such gap: it
 * simply stays pinned near the top of the viewport while the longer
 * summary content scrolls past beside it, the same pattern most modern
 * shopping sites use for a product photo next to a long description.
 * This only touches the gallery itself — nothing needs changing on
 * `.product`, since the actual column layout is already the theme's own
 * (confirmed live: a flex row, so `float` on WooCommerce's default
 * gallery/summary markup is moot — flex containers ignore `float` on
 * their own children). `align-self: flex-start` is a no-op outside a
 * flex/grid context, so this degrades harmlessly on a theme that stacks
 * the gallery and summary in a single column instead.
 *
 * The `!important` on `position`/`top` is deliberate and narrowly
 * targeted, not a habit: WooCommerce's own core stylesheet ships
 * `.woocommerce div.product div.images.woocommerce-product-gallery {
 * position: relative; }`, and that selector's specificity (two element
 * types + four classes) beats a plain `.single-product
 * .woocommerce-product-gallery` outright, regardless of which stylesheet
 * loads later — confirmed live by walking every loaded stylesheet's
 * matched rules for this element. Rather than fight that with an
 * ever-more-specific selector (fragile — it'd need updating again if a
 * theme or a WooCommerce update adds one more qualifier on its side),
 * this overrides just those two properties on purpose.
 *
 * UPDATE: the specificity fight above was real, but fixing it wasn't
 * enough on its own — the gallery still didn't actually stick when
 * scrolled on a real desktop-width screen; it just scrolled away with
 * the rest of the page, leaving the same "blank space under the image"
 * gap this was meant to fix. Tracked down live: the theme's global
 * stylesheet sets `body { overflow: hidden auto; }` (presumably to stop
 * some element somewhere on the site from causing a horizontal
 * scrollbar). Any ancestor with a non-`visible` overflow — even one that
 * never actually needs to scroll itself, which is the case here, since
 * this site's real scrolling happens one level up on `<html>` — still
 * counts as a "scroll container" by spec, and `position: sticky` sticks
 * an element relative to its NEAREST scroll-container ancestor. With
 * `body` claiming that role but never itself scrolling, every sticky
 * element on the page (this test was with a bare `position: sticky` div
 * placed directly in `<body>` with nothing else applied to it) was
 * computing its stickiness against a container that never moves —
 * functionally identical to `position: static`. This is a well-known
 * CSS interaction, not a one-off theme bug, and it isn't specific to the
 * gallery — it would silently break ANY sticky element added anywhere on
 * a single-product page. The `!important` here is the same deliberate,
 * narrow exception as the ones above: verified live (at both a ~1400px
 * desktop width and at 375px mobile) that neither `document.documentElement
 * .scrollWidth` nor `document.body.scrollWidth` exceed their own
 * `clientWidth` once this is removed, i.e. nothing on this page was
 * actually relying on `overflow-x: hidden` to hide a horizontal
 * scrollbar — but this couldn't be checked against every product on the
 * site, so if a horizontal scrollbar ever turns up specifically on a
 * product page after this update, this rule is the first place to look. */
body.single-product {
	overflow: visible !important;
}

@media (min-width: 782px) {
	.single-product .woocommerce-product-gallery,
	.single-product .images {
		position: sticky !important;
		top: 24px !important;
		align-self: flex-start;
	}
}

.single-product .woocommerce-product-gallery,
.single-product .images {
	border-radius: 14px;
	overflow: hidden;
	background: var(--rvm-surface-soft);
	/* Same shadow recipe as the summary card below, so the two halves of
	 * the page read as one matched pair of cards rather than one styled
	 * panel next to one plain image. */
	box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04), 0 8px 24px rgba(16, 24, 40, 0.06);
}

.single-product .woocommerce-product-gallery img {
	transition: transform .35s ease;
}

.single-product .woocommerce-product-gallery:hover img {
	transform: scale(1.035);
}

.single-product .summary.entry-summary {
	background: var(--rvm-surface);
	border: 1px solid var(--rvm-border);
	border-radius: 14px;
	padding: 28px;
	box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04), 0 8px 24px rgba(16, 24, 40, 0.06);
}

.single-product .summary.entry-summary .product_title {
	font-size: 26px;
	line-height: 1.25;
	margin: 0 0 12px;
	color: var(--rvm-ink);
}

.single-product .summary.entry-summary .price {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	font-size: 28px;
	font-weight: 700;
	color: var(--rvm-ink);
	margin: 0 0 18px;
}

.single-product .summary.entry-summary .price del {
	font-size: 17px;
	font-weight: 400;
	opacity: .55;
	margin-right: 8px;
}

.single-product .summary.entry-summary .price ins {
	text-decoration: none;
}

/* WooCommerce's own short-description block — sits between the price and
 * the "Redeem at" card. Left completely unstyled before, it inherited
 * plain body copy with a default paragraph margin, which read as an
 * afterthought next to the cards around it. */
.single-product .summary.entry-summary .woocommerce-product-details__short-description {
	color: var(--rvm-muted);
	font-size: 15px;
	line-height: 1.65;
	margin: 0 0 22px;
}

.single-product .summary.entry-summary .woocommerce-product-details__short-description p {
	margin: 0 0 12px;
}

.single-product .summary.entry-summary .woocommerce-product-details__short-description p:last-child {
	margin-bottom: 0;
}

/* Sale badge. WooCommerce's own default markup is
 * <span class="onsale">Sale!</span>, but this site's active theme
 * renders it as <span class="free-shipping-badge">Save 50%</span>
 * instead (confirmed against the live staging page's actual HTML) — both
 * are styled identically here so this keeps working if the theme ever
 * changes, or on a product type that falls back to WooCommerce's
 * default. `position: static` overrides the handful of themes that
 * absolutely-position the badge in a corner of the gallery by default;
 * here it sits inline next to the price instead. */
.single-product .onsale,
.single-product .free-shipping-badge {
	position: static;
	display: inline-flex;
	align-items: center;
	background: rgba(var(--rvm-accent-rgb, 30, 142, 62), 0.12);
	color: var(--rvm-accent, #1E8E3E);
	font-size: 13px;
	font-weight: 700;
	padding: 4px 10px;
	border-radius: 999px;
	margin-left: 10px;
	text-transform: none;
}

.single-product .stock {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: 14px;
	font-weight: 600;
	padding: 0;
	margin: 14px 0;
}

.single-product .stock::before {
	content: "";
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: currentColor;
	flex-shrink: 0;
}

.single-product .stock.in-stock {
	color: #1a8a44;
}

.single-product .stock.out-of-stock {
	color: #c0362c;
}

.single-product .product_meta {
	font-size: 13px;
	color: var(--rvm-muted);
	border-top: 1px solid var(--rvm-border);
	margin-top: 20px;
	padding-top: 16px;
}

.single-product .product_meta > span {
	display: block;
	margin-bottom: 4px;
}

.single-product .product_meta a {
	color: var(--rvm-muted);
	text-decoration: underline;
}

/* This theme's own "Categories:" / "Availability:" rows inside
 * .product_meta (.custom-meta-row / .meta-label / .meta-value — confirmed
 * against the live staging page's actual HTML, not WooCommerce's plain
 * default markup) — styled as a clean label/value line instead of the
 * default run-on "Label: value" plain text. */
.single-product .product_meta .custom-meta-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 7px 0;
}

.single-product .product_meta .meta-label {
	color: var(--rvm-muted);
	font-weight: 600;
}

.single-product .product_meta .meta-value {
	color: var(--rvm-ink);
	text-align: right;
}

.single-product .product_meta .meta-value .stock {
	margin: 0;
}

/* "Visit vendor's website" external link (.iyr-vendor-website — this
 * theme's own class) — a quieter, secondary-looking pill button since
 * it's a less important action than Add to Basket. */
.single-product .iyr-vendor-website-wrap {
	margin-top: 14px;
}

.single-product .iyr-vendor-website {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 8px 14px;
	border: 1px solid var(--rvm-border);
	border-radius: 999px;
	font-size: 13px;
	font-weight: 600;
	color: var(--rvm-ink);
	text-decoration: none;
}

.single-product .iyr-vendor-website:hover {
	border-color: var(--rvm-accent, #1E8E3E);
	color: var(--rvm-accent, #1E8E3E);
}

.single-product .iyr-vendor-website-icon img {
	width: 14px;
	height: 14px;
}

/* Vendor snapshot card (Dokan's own .dokan-vendor-info-wrap markup) — a
 * small bordered card with avatar/name/rating instead of sitting as
 * plain inline elements with no visual grouping. */
.single-product .dokan-vendor-info-wrap {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 12px;
	margin-top: 16px;
	padding: 12px;
	border: 1px solid var(--rvm-border);
	border-radius: 10px;
	background: var(--rvm-surface-soft);
	transition: box-shadow .15s ease, border-color .15s ease;
}

.single-product .dokan-vendor-info-wrap:hover {
	border-color: var(--rvm-accent, #1E8E3E);
	box-shadow: 0 4px 14px rgba(16, 24, 40, 0.06);
}

/* A plain "name + avatar" row read as just another line of text next to
 * the Categories/Availability rows above it, easy to mistake for one more
 * meta field rather than a distinct "who you're buying from" card. This
 * is a generated label, not real markup — safe here because it's a fixed,
 * non-informational caption (the vendor's actual name/link is still real
 * text underneath), and `flex-wrap` above is what lets a `width: 100%`
 * pseudo-element force itself onto its own line above the avatar instead
 * of becoming a flex item squeezed in next to it. */
.single-product .dokan-vendor-info-wrap::before {
	content: "Sold by";
	width: 100%;
	font-size: 11px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--rvm-muted);
}

.single-product .dokan-vendor-image img {
	width: 40px;
	height: 40px;
	border-radius: 50%;
	object-fit: cover;
	display: block;
}

.single-product .dokan-vendor-name h5 {
	margin: 0;
	font-size: 14px;
}

.single-product .dokan-vendor-name a {
	text-decoration: none;
	color: var(--rvm-ink);
}

.single-product .dokan-vendor-rating {
	color: #f5a623;
	font-size: 13px;
	margin-top: 2px;
}

/* Add to Basket / "visit website" button — targets WooCommerce's own
 * .single_add_to_cart_button class, which every product type (simple,
 * external/affiliate) shares, so one rule covers both a normal Add to
 * Basket button and an External Product's "Visit site" button without
 * needing separate cases for each. */
.single-product .summary.entry-summary .button,
.single-product .summary.entry-summary .single_add_to_cart_button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	background: var(--rvm-accent, #1E8E3E);
	border: none;
	color: #fff;
	font-weight: 700;
	font-size: 15px;
	padding: 14px 20px;
	border-radius: 10px;
	/* A soft glow tinted with the brand colour, not just a flat button —
	 * `--rvm-accent-rgb` is the same triplet the sale badge above already
	 * uses, so this always matches whatever accent colour is set under
	 * Settings → RVM Settings without needing its own fallback logic. */
	box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05), 0 10px 20px -6px rgba(var(--rvm-accent-rgb, 30, 142, 62), 0.45);
	transition: filter .15s ease, transform .12s ease, box-shadow .15s ease;
}

.single-product .summary.entry-summary .button:hover,
.single-product .summary.entry-summary .single_add_to_cart_button:hover {
	filter: brightness(0.94);
	color: #fff;
	transform: translateY(-1px);
	box-shadow: 0 2px 4px rgba(16, 24, 40, 0.06), 0 14px 26px -6px rgba(var(--rvm-accent-rgb, 30, 142, 62), 0.55);
}

.single-product .summary.entry-summary .button:active,
.single-product .summary.entry-summary .single_add_to_cart_button:active {
	transform: translateY(1px);
	box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05), 0 6px 14px -6px rgba(var(--rvm-accent-rgb, 30, 142, 62), 0.45);
}

.single-product .summary.entry-summary form.cart {
	margin-top: 18px;
}

/* Share row (theme's own .social-share) and Dokan's "Report Abuse" link —
 * both sat at the bottom of the summary card completely unstyled before:
 * default link-blue icons with no hover state, and a plain flag icon/link
 * with no visual relationship to anything around it. Grouped into one
 * quiet utility row, visually separated from the vendor card above by its
 * own top border, since neither is as important as the content above it. */
.single-product .summary.entry-summary .social-share {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 12px;
	margin-top: 20px;
	padding-top: 16px;
	border-top: 1px solid var(--rvm-border);
}

.single-product .summary.entry-summary .social-share > span {
	font-size: 12px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--rvm-muted);
}

.single-product .summary.entry-summary .social-share ul {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.single-product .summary.entry-summary .social-share a {
	display: inline-flex;
	color: var(--rvm-muted);
	transition: color .15s ease;
}

.single-product .summary.entry-summary .social-share a:hover {
	color: var(--rvm-accent, #1E8E3E);
}

.single-product .summary.entry-summary .social-share svg {
	width: 16px;
	height: 16px;
	fill: currentColor;
}

.single-product .summary.entry-summary .dokan-report-abuse-button {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin-top: 12px;
	font-size: 12px;
	color: var(--rvm-muted);
	text-decoration: none;
}

.single-product .summary.entry-summary .dokan-report-abuse-button:hover {
	color: #c0362c;
	text-decoration: underline;
}

/* Tabs (Description, this plugin's own "Redemption Terms", Reviews,
 * etc.) — restyled as a single bordered card rather than the
 * browser-default underlined-links look an unstyled WooCommerce theme
 * ships with. */
.single-product .woocommerce-tabs {
	margin-top: 48px;
	max-width: 100%;
	clear: both;
}

/* Pill-style segmented control instead of the underlined-links look the
 * previous version used — the underline variant tied each tab visually
 * to the panel below it (rounded 0 on the top-left corner to "connect" to
 * whichever tab was active), which worked but read as a fairly dated
 * pattern next to the rest of this redesign. A tab bar that's its own
 * self-contained rounded control, sitting just above a fully-rounded
 * panel with no forced connection between the two, reads as more current
 * — most sites don't literally attach their tab strip to their content
 * pane anymore.
 *
 * `margin: 0 auto` centres the bar — `width: fit-content` gives it a
 * definite width to centre WITHIN (the row of tabs, not the full card),
 * which is what auto-margin centring needs to work on a block-level box.
 *
 * `flex-wrap: wrap` (rather than the single scrollable row this used to
 * be) is what makes this hold up for however many tabs this product ends
 * up with — WooCommerce's own default tabs plus this plugin's own
 * "Redemption Terms" is only 3, but a store can add more later (a
 * "Shipping" tab, a custom plugin tab, etc.), and a fixed-width row
 * eventually either overflows visibly (what was happening on mobile —
 * the last tab was getting clipped at the card edge with no visual hint
 * it was scrollable) or relies on the shopper discovering they can swipe
 * it sideways. Wrapping to a second centred row instead means EVERY tab
 * stays fully visible and reachable at any screen width, with no
 * count-dependent tuning ever needed again. The container's own
 * `border-radius` drops from a full 999px pill to a softer 14px (matching
 * the panel below and the rest of this file's cards) specifically
 * because a two-row wrapped box stops reading as a "pill" once it's
 * taller than one line — 14px looks intentional at any row count, where
 * 999px only ever looked right at exactly one. Each individual tab
 * button below keeps its own small pill shape regardless, since a single
 * tab's own label is still always one line (`white-space: nowrap`) even
 * when the row it's in wraps. */
/* Verified live against every loaded stylesheet on this exact element,
 * same way the sticky-gallery override above was: the theme ships
 * `.single-product div.product .woocommerce-tabs ul.tabs { padding-bottom:
 * 9px; }`, which beats this file's own `padding: 4px` shorthand on that
 * one longhand side regardless of load order (four classes + `div.product`
 * outweighs three classes with no element qualifier); a SEPARATE theme
 * rule, `.woocommerce div.product .woocommerce-tabs ul.tabs { margin: 0;
 * … }`, does the exact same thing to `margin` (four classes + two
 * elements beats this file's three classes + one element) — this is what
 * was silently cancelling the `margin: 0 auto` this file relies on for
 * centering, so the bar rendered flush left no matter what the actual
 * declaration said; and BOTH `.woocommerce div.product .woocommerce-tabs
 * ul.tabs li.active a` in the theme's stylesheet AND a
 * theme-options-generated inline `<style>` block (same selector, chained
 * `.single-product.woocommerce`) set the active tab's colour straight
 * from the site's own accent setting, beating the plain 3-class selectors
 * below the same way. Rather than chase ever more specific selectors —
 * fragile, and this exact fight already happened once in this file — the
 * affected declarations get `!important` where it's actually needed,
 * nothing more. */
.single-product .woocommerce-tabs ul.tabs {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 4px;
	list-style: none;
	margin: 0 auto 20px !important;
	padding: 4px !important;
	background: var(--rvm-surface-soft);
	border-radius: 14px;
	width: fit-content;
	max-width: 100%;
}

.single-product .woocommerce-tabs ul.tabs li {
	margin: 0;
}

.single-product .woocommerce-tabs ul.tabs li a {
	display: inline-block;
	padding: 10px 20px;
	font-weight: 600;
	font-size: 14px;
	color: var(--rvm-muted) !important;
	text-decoration: none;
	border-radius: 999px;
	white-space: nowrap;
	transition: background .15s ease, color .15s ease;
}

.single-product .woocommerce-tabs ul.tabs li.active a {
	color: #fff !important;
	background: var(--rvm-ink) !important;
	/* The theme's own active-tab rule also sets an underline
	 * (`text-decoration-line: underline`) at the same higher specificity
	 * that fought the colour/background above — needed here too, or the
	 * active pill ends up with a stray underline UNDER white text that
	 * already has a solid dark pill behind it, which looks like a rendering
	 * glitch rather than a deliberate style. */
	text-decoration: none !important;
}

.single-product .woocommerce-tabs ul.tabs li a:hover {
	color: var(--rvm-ink) !important;
}

.single-product .woocommerce-tabs ul.tabs li.active a:hover {
	color: #fff !important;
}

/* Same specificity fight as everything else in this file marked
 * `!important`, just not caught for THIS property until it was reported
 * as text sitting flush against the panel's edges: WooCommerce's own core
 * stylesheet ships `.woocommerce div.product .woocommerce-tabs .panel {
 * padding: 0; }` (four classes + one element, beats this file's three
 * classes + zero elements) as a baseline, and — active on this element
 * regardless of viewport, since matching a selector at a narrower
 * media query still requires winning the same specificity fight — the
 * theme separately ships `.woocommerce div.product .woocommerce-tabs
 * .panel { padding: 0 10px; }` inside `@media screen and (max-width:
 * 767px)`, which is why this was only visibly broken on mobile (a
 * ~1024px-wide screenshot wouldn't have shown it) even though the
 * dekstop rule was losing its own fight too, just down to a plain `0`
 * that happened to look less obviously "wrong" than `0 10px`. Confirmed
 * live via computed padding before and after adding `!important` here,
 * not just by reading the stylesheet. */
.single-product .woocommerce-tabs .panel {
	border: 1px solid var(--rvm-border);
	border-radius: 14px;
	padding: 28px !important;
	background: var(--rvm-surface);
}

@media (max-width: 781px) {
	.single-product .summary.entry-summary {
		margin-top: 24px;
		padding: 20px;
	}

	.single-product .woocommerce-tabs .panel {
		padding: 18px !important;
	}
}
