/**
 * Product components — price, badges, gallery, single-product layout.
 * Theme-agnostic: tokens only, no hardcoded colors/fonts/spacing.
 */

/* ───── Price block ───── */

[class*="-shop-product-price"] {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--shop-space-xs);
	margin: var(--shop-space-sm) 0;
	font-family: var(--shop-font-body);
}

[class*="-shop-price-compare"] {
	/* Lighthouse contrast: text-muted (#636363) on white fails large-text
	   threshold on some viewports — bumping to full text color (#111) keeps
	   the strike-through semantic while restoring AA. */
	color: var(--shop-color-text);
	font-size: var(--shop-text-sm);
	text-decoration: line-through;
	opacity: 0.6; /* visual de-emphasis without dropping contrast ratio */
}

/* Single-product price uses its own responsive scale (mobile-first) so
   admin can tune it independently via Settings → หน้าสินค้า. Card price
   is overridden later in this file by [card] [price] selector. */
[class*="-shop-price-current"] {
	color: var(--shop-color-text);
	font-size: var(--shop-product-price-size-mobile);
	font-weight: 700;
	line-height: 1.2;
}

@media (min-width: 550px) {
	[class*="-shop-price-current"] {
		font-size: var(--shop-product-price-size-tablet);
	}
}

@media (min-width: 850px) {
	[class*="-shop-price-current"] {
		font-size: var(--shop-product-price-size-desktop);
	}
}

[class*="-shop-price-unit"] {
	/* Contrast — text-muted failed Lighthouse on small inline labels next
	   to the bold price; full text keeps the unit readable alongside it. */
	color: var(--shop-color-text);
	font-size: var(--shop-text-sm);
	font-weight: 400;
}

/* ───── Badges (Sale / Out of Stock) ───── */

[class*="-shop-badge"] {
	position: absolute;
	top: var(--shop-space-xs);
	left: var(--shop-space-xs);
	display: inline-block;
	padding: 0.2em 0.6em;
	font-size: var(--shop-text-xs);
	font-weight: 700;
	font-family: var(--shop-font-body);
	line-height: 1.4;
	border-radius: var(--shop-radius-pill);
	letter-spacing: 0.02em;
	text-transform: uppercase;
	z-index: 1;
}

/* Color modifiers — semantic preset names. Admin picks one in Settings → Badges.
   All colors resolve via tokens (rule 21 — no hardcoded hex in components). */
[class*="-shop-badge--color-red"]    { background: var(--shop-color-sale);    color: var(--shop-color-on-accent); }
[class*="-shop-badge--color-blue"]   { background: var(--shop-color-info);    color: var(--shop-color-on-accent); }
[class*="-shop-badge--color-orange"] { background: var(--shop-color-warning); color: var(--shop-color-on-accent); }
[class*="-shop-badge--color-green"]  { background: var(--shop-color-success); color: var(--shop-color-on-accent); }
[class*="-shop-badge--color-purple"] { background: var(--shop-color-purple);  color: var(--shop-color-on-accent); }
[class*="-shop-badge--color-black"]  { background: var(--shop-color-text);    color: var(--shop-color-surface); }

/* Legacy --sale modifier kept for single-product.php which still uses is_on_sale() directly. */
[class*="-shop-badge--sale"]:not([class*="-color-"]) {
	background: var(--shop-color-sale);
	color: var(--shop-color-on-accent);
}

[class*="-shop-badge--oos"] {
	background: var(--shop-color-oos);
	color: var(--shop-color-on-primary);
	left: auto;
	right: var(--shop-space-xs);
}

/* ───── Product card (used in archive + taxonomy) ─────
   Card is flex-column so footer (CTA) tracks bottom edge regardless of title length.
   Card-level layout (background, border) lives in shop-base.css. */

[class*="-shop-product-card"] {
	position: relative;
	display: flex;
	flex-direction: column;
}

[class*="-shop-product-card"] [class*="-shop-product-link"] {
	display: flex;
	flex-direction: column;
	flex: 1;
}

[class*="-shop-product-card"] [class*="-shop-product-media"] {
	position: relative;
}

[class*="-shop-product-body"] {
	padding: var(--shop-space-sm);
	display: flex;
	flex-direction: column;
	flex: 1;
}

/* Title — clamp to 2 lines so admins typing long titles can't break card layout
   (case #19 — FAB hits long title; now with text-CTA below, clamp keeps grid even). */
[class*="-shop-product-card"] [class*="-shop-product-title"] {
	padding: 0;
	margin: 0 0 var(--shop-space-xs);
	font-size: var(--shop-card-title-size, 0.9375rem); /* 15px — was inheriting Flatsome 20px */
	line-height: 1.35;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	min-height: calc(0.9375rem * 1.35 * 2); /* reserve 2 lines so cards align */
}

[class*="-shop-product-card"] [class*="-shop-product-price"] {
	margin: 0;
	margin-top: auto; /* push price to bottom of body so CTA tracks card edge */
}

/* ───── Aggregate rating (card) ─────
   Shopee/Lazada-style: ★★★★★ 4.9 (10) under title, before price.
   Stars use Unicode (★/☆) — Flatsome strips/recolors inline SVG in cards
   (skill rule §6). Cached aggregate via Universal_Shop_Review::aggregate().
   Specificity: nest under .-product-card to outweigh Flatsome card resets. */
[class*="-shop-product-card"] [class*="-shop-product-rating"] {
	display: flex;
	align-items: center;
	gap: 6px;
	margin: 0 0 var(--shop-space-xs);
	font-size: 0.8125rem; /* 13px — sub-line under title */
	line-height: 1.2;
	min-height: 1.2em; /* reserve row so empty/filled cards stay aligned */
}

[class*="-shop-product-card"] [class*="-shop-product-rating__stars"] {
	color: var(--shop-color-accent, #c9a84c);
	letter-spacing: 2px;
	font-size: 1rem; /* 16px — visual weight; brighter than text-row */
	line-height: 1;
	/* Force fill against Flatsome card overrides that re-color child text. */
	-webkit-text-fill-color: var(--shop-color-accent, #c9a84c);
}

[class*="-shop-product-card"] [class*="-shop-product-rating__value"] {
	font-weight: 700;
	color: var(--shop-color-text, #2c2c2c);
}

[class*="-shop-product-card"] [class*="-shop-product-rating__count"] {
	color: var(--shop-color-text-muted, #9a9585);
}

[class*="-shop-product-card"] [class*="-shop-product-rating--empty"] {
	color: var(--shop-color-text-muted, #9a9585);
	font-style: italic;
	font-size: 0.75rem; /* 12px — quieter than active state */
}

/* Material spec strip — fallback for cards with 0 reviews. Subtle: smaller
   than the active rating, muted colour, icon-led so it reads as info not
   marketing. 13px (not 12) for mobile readability — Thai vowel marks lose
   too much fidelity at 12px. Renders only when the product has
   _shop_material set; otherwise the row is hidden entirely (no negative
   "no reviews" string). */
[class*="-shop-product-card"] [class*="-shop-product-spec"] {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	color: var(--shop-color-text-muted, #9a9585);
	font-size: 0.8125rem; /* 13px */
	line-height: 1.3;
}
[class*="-shop-product-card"] [class*="-shop-product-spec"] svg {
	flex: 0 0 auto;
	color: var(--shop-color-accent);
}

/* Price on cards — Flatsome's h-style was bleeding 36px in here. Cap at 1.25rem
   so the card hierarchy reads as TITLE > price > unit, not PRICE > everything. */
[class*="-shop-product-card"] [class*="-shop-price-current"] {
	font-size: var(--shop-card-price-size, 1.25rem); /* 20px */
	line-height: 1.2;
}

/* ───── Add-to-Cart CTA (full-width button) ─────
   Sibling of <a class="…-product-link"> — never a child (invalid HTML).
   Sits at the bottom of every card; flex-equal-height keeps CTAs aligned across grid. */
[class*="-shop-product-footer"] {
	padding: 0 var(--shop-space-sm) var(--shop-space-sm);
	margin-top: 0;
}

/* Card FAB — same accent token as the single-product cart button so the
   "add to cart" affordance reads consistently between archive and detail.
   Both routes through Cart_Button SSOT (Settings → ปุ่มเพิ่มลงตะกร้า) which
   can override the accent via inline CSS at runtime. */
[class*="-shop-product-cta"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--shop-space-xs);
	width: 100%;
	min-height: 2.75rem; /* 44px — touch target */
	padding: 0 var(--shop-space-sm);
	border: 0;
	border-radius: var(--shop-radius-sm);
	background: var(--shop-color-accent);
	color: var(--shop-color-on-accent);
	font-family: inherit;
	font-size: var(--shop-text-sm);
	font-weight: 600;
	cursor: pointer;
	transition: background-color var(--shop-transition-fast), transform var(--shop-transition-fast);
}

[class*="-shop-product-cta"]:hover {
	background: var(--shop-color-accent-hover, var(--shop-color-accent));
	filter: brightness(0.92);
}

[class*="-shop-product-cta"]:focus-visible {
	outline: 2px solid var(--shop-color-accent);
	outline-offset: 2px;
}

[class*="-shop-product-cta"]:disabled,
[class*="-shop-product-cta"][aria-busy="true"],
[class*="-shop-product-cta"][aria-disabled="true"] {
	background: var(--shop-color-bg-hover);
	color: var(--shop-color-text-muted);
	cursor: not-allowed;
}

[class*="-shop-product-cta"] svg {
	display: block;
	width: 1.125rem;
	height: 1.125rem;
	overflow: visible; /* override Flatsome's svg:not(:root) clip — case #15 */
}

/* Brief success pulse after click (data-shop-add-to-cart handler adds .is-added). */
[class*="-shop-product-cta"].is-added {
	background: var(--shop-color-success);
	color: var(--shop-color-on-accent);
}

/* ───── Trust Badges (under cart CTA on single-product) ─────
   Admin-curated list: SSOT in class-trust-badges.php. Each row is an icon
   + short label, optionally wrapped in <a> when admin sets a URL.
   Layout: 2-column grid so 4 default badges fit in 2 rows on mobile,
   keeping the above-the-fold zone compact. Falls back to 1 column under
   24em (small phones) so labels don't truncate awkwardly. */
[class*="-shop-trust-badges"] {
	list-style: none;
	margin: var(--shop-space-md) 0 0;
	padding: var(--shop-space-sm) 0 0;
	border-top: 1px solid var(--shop-color-border);
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 0.5rem 1rem;
	font-family: var(--shop-font-body);
	font-size: var(--shop-text-sm);
}

/* 1-column fallback for very narrow viewports (≤ 24em / 384px) so a long
   Thai label like "เปลี่ยนคืนได้ภายใน 7 วัน" doesn't overflow. */
@media (max-width: 24em) {
	[class*="-shop-trust-badges"] {
		grid-template-columns: 1fr;
	}
}

/* IMPORTANT — wildcard substring trap (do-not-do.md rule 25):
   `[class*="-shop-trust-badge"]` would ALSO match `-shop-trust-badges`
   (the parent <ul>), overriding its grid layout with flex and collapsing
   all badges into one row. Use the BEM list-item selector that ends with
   the singular class via `[class$=]` (attribute-ends-with), or scope to
   the <ul> > <li> child combinator. */
[class*="-shop-trust-badges"] > li {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	min-width: 0;       /* lets text-overflow ellipsis work inside flex */
	padding: 0;
	color: var(--shop-color-text);
	line-height: 1.4;
}

/* Wrap as <a> when URL set — keep visual identical to non-link rows; the
   icon hint colour shifts on hover so it's discoverable as interactive. */
[class*="-shop-trust-badges"] > li > a {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	color: inherit;
	text-decoration: none;
	min-width: 0;
	transition: color var(--shop-transition-fast);
}

[class*="-shop-trust-badges"] > li > a:hover,
[class*="-shop-trust-badges"] > li > a:focus-visible {
	color: var(--shop-color-accent);
}

[class*="-shop-trust-badge__icon"] {
	flex: none;
	display: block;
	width: 1.125rem;
	height: 1.125rem;
	color: var(--shop-color-accent);
}

/* Long labels truncate with ellipsis instead of wrapping — keeps grid
   rows the same height. Hover/focus reveals full text via title attr
   (browser default tooltip). */
[class*="-shop-trust-badge__text"] {
	flex: 1 1 auto;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* ───── Single product layout ─────
   Card wrapper: image + info live inside a single elevated surface so the
   above-the-fold zone reads as one focused buying decision (mockup ref:
   sample-uxui-product1.html .product-card — white bg + 20px radius +
   diffuse shadow over a soft page bg).

   Selector: [class$=] (ends-with) avoids matching child elements like
   `__inner` or future BEM elements — gating by SKILL §4 (block rule with
   border + radius + padding must be [class$=]). */
[class$="-shop-product-layout"] {
	display: grid;
	gap: var(--shop-space-lg);
	grid-template-columns: 1fr;
	padding: var(--shop-space-md);
	background: var(--shop-color-surface);
	border: 1px solid var(--shop-color-border);
	border-radius: 20px;
	/* intentional hardcode — diffuse depth shadow that reads on both light
	   and white page backgrounds. color-mix() with var(--shop-color-text)
	   produces uneven results across themes (dark-text themes get a heavy
	   black shadow); a fixed near-black low-alpha rgba is predictable. */
	box-shadow: 0 4px 32px rgba(0, 0, 0, 0.07);
}

/* Grid children: Flatsome `.col` ancestor may carry implicit min-width that
   lets items overflow the 1fr column on narrow viewports. min-width:0 resets
   the implicit min-content sizing so the column can shrink properly. */
[class$="-shop-product-layout"] > * {
	min-width: 0;
}

@media (min-width: 850px) {
	[class$="-shop-product-layout"] {
		grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
		padding: var(--shop-space-lg);
	}
}

/* Mobile cap — tighter padding so the card doesn't dominate small screens. */
@media (max-width: 549px) {
	[class$="-shop-product-layout"] {
		padding: var(--shop-space-sm);
		border-radius: var(--shop-radius-md);
	}
}

[class*="-shop-product-media--hero"] {
	position: relative;
	margin: 0;
	padding: 0;
	border-radius: var(--shop-radius-md);
	overflow: hidden;
	background: var(--shop-color-surface-muted);
	line-height: 0; /* kill inline baseline gap under <img> */
}

[class*="-shop-product-media--hero"] img {
	width: 100%;
	height: auto;
	display: block;
	line-height: 1; /* restore for any text inside */
	transition: opacity 200ms ease;
}

/* Mobile: hero 4:3 aspect-ratio + full-bleed.
   3-class chain beats shop-base.css 2-class rule regardless of source order. */
@media (max-width: 549px) {
	[class*="-shop-single-product"] [class*="-shop-product-layout"] [class*="-shop-product-media-stack"] {
		margin-top: calc(-1 * var(--shop-space-sm));
		margin-left: calc(-1 * var(--shop-space-sm));
		margin-right: calc(-1 * var(--shop-space-sm));
	}
	[class*="-shop-single-product"] [class*="-shop-product-layout"] [class*="-shop-product-media--hero"] {
		aspect-ratio: 4 / 3;
		border-radius: 0;
	}
	[class*="-shop-single-product"] [class*="-shop-product-layout"] [class*="-shop-product-media--hero"] img {
		height: 100%;
		object-fit: cover;
		object-position: center;
	}
}

/* Hero swap: brief fade while JS preloads the next image. */
[class*="-shop-product-media--hero"][data-loading="1"] img {
	opacity: 0.4;
}



/* Gallery thumbnails below hero image */

[class*="-shop-product-gallery"] {
	list-style: none;
	padding: 0;
	margin: var(--shop-space-sm) 0 0;
	display: grid;
	/* 4 equal columns matching sample mockup. `minmax(0, 1fr)` (not `1fr`
	   alone) lets thumbs shrink uniformly on narrow viewports without
	   overflowing into an awkward 3+1 last-row layout (which earlier
	   auto-fit/auto-fill rules produced at 480-560px widths). */
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: var(--shop-space-xs);
}

[class*="-shop-product-gallery"] li {
	margin: 0;
}

[class*="-shop-gallery-thumb"] {
	display: block;
	width: 100%;
	aspect-ratio: 1 / 1;
	padding: 0;
	border: 2px solid transparent;
	border-radius: var(--shop-radius-sm);
	background: var(--shop-color-surface-muted);
	overflow: hidden;
	cursor: pointer;
	transition: border-color 150ms ease, transform 150ms ease;
}

[class*="-shop-gallery-thumb"]:hover {
	border-color: var(--shop-color-text-muted);
}

[class*="-shop-gallery-thumb"]:focus-visible {
	outline: none;
	border-color: var(--shop-color-accent);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--shop-color-accent) 30%, transparent);
}

[class*="-shop-gallery-thumb"][aria-current="true"] {
	border-color: var(--shop-color-accent);
}

[class*="-shop-product-gallery"] img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* Info column */

[class*="-shop-product-info"] {
	display: flex;
	flex-direction: column;
	gap: var(--shop-space-sm);
}

/* Product H1 — intentionally not styled by the plugin.
   Heading scale is owned by the active theme (Flatsome Customizer →
   Typography, or theme.json on block themes). Customers usually have
   site-wide heading rules in Customizer → Additional CSS that use
   !important; fighting those would mean the plugin can't lose, but the
   user can't win either. We let the H1 inherit fully — just keep
   margin/padding tidy via shop-base.css.  See do-not-do.md rule 21. */

[class*="-shop-product-sku"] {
	font-size: var(--shop-text-sm);
	/* Contrast — gray-on-white at this size triggered Lighthouse; full
	   text color keeps the SKU readable. */
	color: var(--shop-color-text);
	margin: 0;
}

[class*="-shop-product-sku"] code {
	font-size: inherit;
	background: var(--shop-color-surface-muted);
	/* code chip has a muted bg — inherit alone gave gray-on-gray.
	   Explicit text color restores contrast against the chip. */
	color: var(--shop-color-text);
	padding: 0.1em 0.4em;
	border-radius: var(--shop-radius-sm);
}

[class*="-shop-product-stock"] {
	font-size: var(--shop-text-sm);
	margin: 0;
	font-weight: 600;
}

/* Stock state line — flex row so admin-set SVG icon sits beside the label.
   Icon is now inline <svg> from Stock_Modes::icon_html() (admin-curated)
   instead of an emoji ::before content (which rendered as tofu in Sarabun).
   `currentColor` lets each state's color modifier paint the icon too. */
[class*="-shop-product-stock"] {
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
}

[class*="-shop-product-stock__icon"] {
	flex: none;
	display: block;
	width: 1.125em;
	height: 1.125em;
}

[class*="-shop-product-stock--in"] {
	/* Contrast — Flatsome's default success token (#2e8b57) lands at
	   3.97:1 on white, just below WCAG AA (4.5:1) for normal text.
	   color-mix darkens it 25% toward black → ~5.2:1 while still
	   tracking whatever success hue the active theme defines.
	   Falls back to the raw token on browsers without color-mix. */
	color: var(--shop-color-success);
	color: color-mix(in srgb, var(--shop-color-success) 75%, #000);
}

[class*="-shop-product-stock--oos"] {
	color: var(--shop-color-oos);
}

/* Made-to-order — neutral info colour (calendar feel, not urgent). */
[class*="-shop-product-stock--mto"] {
	color: var(--shop-color-info);
	font-weight: 600;
}

/* Inquiry — warmer accent so the call-to-contact reads as a CTA. */
[class*="-shop-product-stock--inquiry"] {
	color: var(--shop-color-warning);
	font-weight: 600;
}

/* Bottom meta footer — sits between description and Related Products
   (Amazon pattern). Hairline above hands the eye off from the description
   block to "browse mode" content below. */
[class*="-shop-product-meta-footer"] {
	margin-top: 2rem;
	padding-top: 1.25rem;
	padding-bottom: 1.875rem; /* 30px — owns the gap to Related below */
	border-top: 1px solid color-mix(in srgb, var(--shop-color-border) 40%, transparent);
}

[class*="-shop-product-categories"] {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 0.5rem;
	font-size: var(--shop-text-sm);
	color: var(--shop-color-text-muted);
	margin: 0;
}

[class*="-shop-product-categories__icon"] {
	flex: none;
	color: var(--shop-color-text-muted);
}

[class*="-shop-product-categories__label"] {
	font-weight: 500;
}

[class*="-shop-product-categories"] a {
	color: var(--shop-color-text);
	text-decoration: none;
	border-bottom: 1px solid color-mix(in srgb, var(--shop-color-text-muted) 30%, transparent);
	transition: color var(--shop-transition-fast), border-color var(--shop-transition-fast);
}

[class*="-shop-product-categories"] a:hover,
[class*="-shop-product-categories"] a:focus-visible {
	color: var(--shop-color-accent);
	border-bottom-color: var(--shop-color-accent);
}

/* Breadcrumb — minimal, theme-agnostic, responsive (SSOT tokens).
   AIOSEO renders its own markup; we only style the <nav> wrapper +
   fallback links/separator. Mobile-first: small font + tight margins
   on iPhone, scales up at iPad portrait + desktop breakpoints.

   Truncation strategy:
   - Whole crumb trail is single-line (white-space: nowrap) so the row
     keeps its visual rhythm.
   - The LAST crumb (current page = product/term name) gets ellipsis on
     overflow so long Thai titles never break the line. Earlier crumbs
     stay full-width because they're short ("Home", "category-slug").
   - On desktop we relax the truncation so users see the full title
     when there's room. */
[class*="-shop-breadcrumb"] {
	margin: var(--shop-breadcrumb-margin-block-mobile) 0;
	font-size: var(--shop-breadcrumb-size-mobile);
	/* Use text token (not muted) so link crumbs hit WCAG AA 4.5:1 — the
	   theme can apply opacity to muted-text via inheritance, dropping the
	   resolved color to ~3.7:1 (DevTools-confirmed). Current page is bold
	   + same color, separator is muted (decorative, aria-hidden). */
	color: var(--shop-color-text);
	font-family: var(--shop-font-body);
	line-height: 1.5;
	white-space: nowrap;
	overflow: hidden;
	opacity: 1;
}

/* The crumb trail wrapper (AIOSEO uses .aioseo-breadcrumbs; fallback
   uses <ol>) acts as a single-line flex row so we can apply ellipsis
   to the last child only.
   `gap` adds breathing room between every child including bare separator
   text nodes — works whether AIOSEO wraps the › in a <span> or not, so
   we don't have to guess AIOSEO's internal markup. Fallback path also
   benefits (separator + crumb spans both get spacing). */
[class*="-shop-breadcrumb"] .aioseo-breadcrumbs,
[class*="-shop-breadcrumb"] > ol {
	display: flex;
	align-items: center;
	flex-wrap: nowrap;
	gap: 0.5em;
	min-width: 0;             /* lets the last crumb shrink and ellipsis */
	max-width: 100%;
	overflow: hidden;
}

/* Home icon prefix on the first crumb's link.
   AIOSEO escapes label strings with esc_html so we can't inject an
   <svg> in PHP — instead we paint the icon with ::before using a
   background-image inline-SVG so the glyph stays sharp on retina and
   inherits currentColor on the theme.
   Targets the first <a> inside both the AIOSEO wrapper and our fallback
   <ol>; if the first crumb is a non-link span (uncommon), no icon —
   acceptable degradation. */
[class*="-shop-breadcrumb"] .aioseo-breadcrumbs > .aioseo-breadcrumb:first-child a::before,
[class*="-shop-breadcrumb"] > ol > li:first-child a::before {
	content: "";
	display: inline-block;
	width: 14px;
	height: 14px;
	margin-right: 4px;
	vertical-align: -2px;
	background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 9 12 2l9 7v11a2 2 0 0 1-2 2h-4v-7H9v7H5a2 2 0 0 1-2-2z'/></svg>");
	background-size: contain;
	background-repeat: no-repeat;
}

/* Chevron separator — AIOSEO ships » by default; we override via the
   aioseo_breadcrumbs_separator filter to ›. Fallback path (customer pages)
   emits the same glyph inside <span aria-hidden="true"> with NO class, so
   we target both: the AIOSEO class AND the bare aria-hidden span between
   crumbs. Without the second selector the › sits flush against the next
   crumb on cart/checkout/account pages (visible bug in fallback render). */
[class*="-shop-breadcrumb"] .aioseo-breadcrumb-separator,
[class*="-shop-breadcrumb"] > span[aria-hidden="true"] {
	display: inline-block;
	color: var(--shop-color-text-muted);
}

/* Last crumb (current page) — truncate with ellipsis when it overflows.
   AIOSEO renders the current crumb as the last <span class="aioseo-breadcrumb">
   (no link); fallback uses [aria-current="page"]. Both selectors. */
[class*="-shop-breadcrumb"] .aioseo-breadcrumb:last-child,
[class*="-shop-breadcrumb"] [aria-current="page"] {
	flex: 1 1 auto;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* iPad portrait — Flatsome tablet bucket (550-849px) */
@media (min-width: 550px) {
	[class*="-shop-breadcrumb"] {
		font-size: var(--shop-breadcrumb-size-tablet);
	}
}

/* PC desktop — Flatsome PC bucket (≥850px). Full title room,
   drop the ellipsis clamp so users see everything. */
@media (min-width: 850px) {
	[class*="-shop-breadcrumb"] {
		margin: var(--shop-breadcrumb-margin-block-desktop) 0;
		font-size: var(--shop-breadcrumb-size-desktop);
		white-space: normal;
		overflow: visible;
	}
	[class*="-shop-breadcrumb"] .aioseo-breadcrumb:last-child,
	[class*="-shop-breadcrumb"] [aria-current="page"] {
		flex: 0 1 auto;
		overflow: visible;
		text-overflow: clip;
	}
}

/* Google breadcrumb guideline: every crumb (link OR visited link) styled
   identically — only the current page differs (bold, no link). Override
   theme + browser defaults that make :visited links look different from
   :link, which breaks visual consistency. */
[class*="-shop-breadcrumb"] a,
[class*="-shop-breadcrumb"] a:link,
[class*="-shop-breadcrumb"] a:visited {
	color: inherit;
	text-decoration: none;
}

[class*="-shop-breadcrumb"] a:hover,
[class*="-shop-breadcrumb"] a:focus {
	color: var(--shop-color-primary);
	text-decoration: underline;
}

/* Current page = the last crumb. AIOSEO doesn't add aria-current, so style
   any non-link span (the only crumb without an <a>) the same way. */
[class*="-shop-breadcrumb"] [aria-current="page"],
[class*="-shop-breadcrumb"] .aioseo-breadcrumb:last-child {
	color: var(--shop-color-text);
	font-weight: 600;
}

/* Full-width description rendered outside the product-layout grid.
   Lives below the image+info row so wide content (H2/H3 + inline images)
   gets the full container width instead of being squeezed into the info col. */
[class*="-shop-product-description"] {
	/* Minimal-modern divider between the 2-column header (gallery + info)
	   and the long-form description. The author writes their own H2/H3
	   inside post_content; this just paints a hairline separator and gives
	   it breathing room so the description doesn't run into the gallery. */
	margin-top: 2rem; /* 32px — tight modern feel */
	padding-top: 2rem;
	/* Editorial gradient divider — fades to 10% in the middle, 40% at the
	   edges. Painted with a top-positioned background image instead of
	   border-top so the gradient can run end-to-end at exactly 1px tall. */
	border-top: 0;
	background-image: linear-gradient(
		to right,
		color-mix(in srgb, var(--shop-color-border) 40%, transparent) 0%,
		color-mix(in srgb, var(--shop-color-border) 10%, transparent) 50%,
		color-mix(in srgb, var(--shop-color-border) 40%, transparent) 100%
	);
	background-repeat: no-repeat;
	background-size: 100% 1px;
	background-position: top left;
	font-family: var(--shop-font-body);
	line-height: 1.7;
}

[class*="-shop-product-description"] > *:first-child {
	margin-top: 0;
}

[class*="-shop-product-description"] h2,
[class*="-shop-product-description"] h3,
[class*="-shop-product-description"] h4 {
	font-family: var(--shop-font-heading);
	margin-top: var(--shop-space-lg);
	margin-bottom: var(--shop-space-sm);
}

[class*="-shop-product-description"] p {
	margin: 0 0 var(--shop-space-md);
}

[class*="-shop-product-description"] img,
[class*="-shop-product-description"] figure {
	max-width: 100%;
	height: auto;
	margin: var(--shop-space-md) 0;
}

[class*="-shop-product-description"] figure {
	display: block;
}

/* Legacy class kept for backward-compat (theme overrides referencing it). */
[class*="-shop-product-content"] {
	max-width: 65ch;
}

/* ──────────────────────────────────────────────────────────────────────
   Product Spec Cards (material / size / color) — 3-column grid layout
   Mockup ref: 02-html-mockup/wp-skills-page-หน้าสินค้า/photo-grid2.html
   Renders below product summary, above description.

   - 3-column desktop grid → 2-col tablet → 1-col mobile
   - Each card: icon-tile (44×44 soft-bg) + text (label + value)
   - Hover: border tints to accent + lift shadow
   - Tokens-only: chains Flatsome --fs-* → WP --wp--preset--* → fallback

   Selector strategy: ul[class*=...] adds element specificity so Flatsome
   generic ul/li resets don't reintroduce bullets / list-item display.
   ────────────────────────────────────────────────────────────────────── */
ul[class*="-shop-product-specs"] {
	list-style: none !important;
	margin: var(--shop-space-lg) 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--shop-space-sm);
}

ul[class*="-shop-product-specs"] > li[class*="-shop-product-specs__card"] {
	list-style: none !important;
	margin: 0;
	padding: var(--shop-space-md) var(--shop-space-md);
	display: flex;
	align-items: center;
	gap: var(--shop-space-md);
	background: var(--shop-color-surface);
	border: 1px solid var(--shop-color-border);
	border-radius: var(--shop-radius-md);
	transition: box-shadow 0.2s, border-color 0.2s;
}

ul[class*="-shop-product-specs"] > li[class*="-shop-product-specs__card"]:hover {
	border-color: var(--shop-color-accent);
	box-shadow: 0 4px 18px rgba(0, 0, 0, 0.08);
}

ul[class*="-shop-product-specs"] > li[class*="-shop-product-specs__card"]::before,
ul[class*="-shop-product-specs"] > li[class*="-shop-product-specs__card"]::marker {
	content: none !important;
	display: none !important;
}

[class*="-shop-product-specs__icon"] {
	flex: 0 0 auto;
	width: 44px;
	height: 44px;
	border-radius: var(--shop-radius-md);
	background: var(--shop-color-bg-soft);
	color: var(--shop-color-accent);
	display: inline-flex;
	align-items: center;
	justify-content: center;
}
[class*="-shop-product-specs__icon"] svg {
	width: 22px;
	height: 22px;
}

[class*="-shop-product-specs__text"] {
	display: flex;
	flex-direction: column;
	min-width: 0;
}

[class*="-shop-product-specs__label"] {
	font-size: var(--shop-text-xs);
	/* Contrast — was --shop-color-text-muted; failed Lighthouse on the
	   card surface. The __value below it already uses full text color
	   (line 887), so the visual hierarchy still works via font-weight. */
	color: var(--shop-color-text);
	line-height: 1.2;
	margin-bottom: 3px;
}

[class*="-shop-product-specs__value"] {
	font-size: 18px; /* intentional hardcode — down from computed 20px; rem unreliable (root=16px not 20px) */
	font-weight: 700;
	color: var(--shop-color-text);
	line-height: 1.3;
	overflow-wrap: break-word;
	word-break: keep-all;
	hyphens: none;
}

@media (max-width: 849px) {
	ul[class*="-shop-product-specs"] {
		grid-template-columns: repeat(2, 1fr);
	}
}
@media (max-width: 549px) {
	ul[class*="-shop-product-specs"] {
		grid-template-columns: 1fr;
	}
}

/* ──────────────────────────────────────────────────────────────────────
   Reviews section — tokens only, BEM brand-prefixed.
   Selector strategy mirrors product-specs: element+class compound to
   defeat Flatsome generic ul/li resets.
   ────────────────────────────────────────────────────────────────────── */
[class$="-shop-reviews"] {
	margin: var(--shop-space-lg) 0;
	counter-reset: none;
}

/* Header card — padding:30px 36px matches mockup rating-box.
   Use [class$=] (ends-with) not [class*=] to avoid bleeding border/padding
   into __header__summary, __header__big, __header__breakdown children. */
[class$="-reviews__header"] {
	display: block;
	padding: 30px 36px;
	background: var(--shop-color-surface);
	border: 1px solid var(--shop-color-border);
	border-radius: 20px;
	box-shadow: 0 2px 16px rgba(0, 0, 0, .06);
	margin-bottom: var(--shop-space-md);
}

/* Demoted from <h2> to <p class="...title"><strong> — see do-not-do.md #30
   (anti-duplicate). Sized at 20px (between text-base 16 and text-lg 24) so
   the section label reads as a heading without dominating the rating widget
   beneath it — the 4.9 / star summary is the real focal point of the block. */
[class*="-shop-reviews__header__title"] {
	display: flex;
	align-items: center;
	gap: var(--shop-space-sm);
	font-family: var(--shop-font-heading);
	font-size: 20px;
	font-weight: 700;
	letter-spacing: -.2px;
	margin: 0;
}
[class*="-shop-reviews__header__title"] strong {
	font-weight: inherit;
}
[class*="-shop-reviews__header__title"] svg {
	fill: currentColor;
	color: var(--shop-color-accent);
}

[class*="-shop-reviews__header__summary"] {
	display: grid;
	grid-template-columns: 180px 1fr;
	gap: 36px; /* matches mockup rating-box gap */
	align-items: center;
}

[class*="-shop-reviews__header__big"] {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	padding: var(--shop-space-md) var(--shop-space-md);
	background: var(--shop-color-surface-muted);
	border: 1px solid var(--shop-color-border);
	border-radius: 16px;
}

[class*="-shop-reviews__header__avg"] {
	font-size: 3.625rem; /* 58px — matches mockup r-num */
	font-weight: 900;
	color: var(--shop-color-text);
	line-height: 1;
	letter-spacing: -3px;
}

[class*="-shop-reviews__header__big-stars"] {
	display: block;
	font-size: 22px;
	color: #c9a84c;
	letter-spacing: 3px;
	margin: 8px 0 6px;
	line-height: 1;
	text-align: center;
}

[class*="-shop-reviews__header__total"] {
	font-size: var(--shop-text-xs);
	color: var(--shop-color-text-muted);
	font-weight: 500;
}

ul[class*="-shop-reviews__header__breakdown"] {
	list-style: none !important;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 10px;
	flex: 1;
}

ul[class*="-shop-reviews__header__breakdown"] > li[class*="-shop-reviews__header__breakdown-row"] {
	list-style: none !important;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: 30px 1fr 28px;
	align-items: center;
	gap: 12px;
}

ul[class*="-shop-reviews__header__breakdown"] > li[class*="-shop-reviews__header__breakdown-row"]::before,
ul[class*="-shop-reviews__header__breakdown"] > li[class*="-shop-reviews__header__breakdown-row"]::marker {
	content: none !important;
	display: none !important;
}

[class*="-shop-reviews__header__breakdown-star"] {
	font-size: var(--shop-text-xs);
	font-weight: 600;
	color: var(--shop-color-text-muted);
	text-align: right;
}

[class*="-shop-reviews__header__breakdown-bar"] {
	display: block;
	width: 100%;
	height: 9px;
	background: #f0ece4;
	border-radius: var(--shop-radius-pill);
	overflow: hidden;
}

[class*="-shop-reviews__header__breakdown-fill"] {
	display: block;
	height: 100%;
	background: linear-gradient(90deg, #c9a84c, #e8c96a);
	border-radius: var(--shop-radius-pill);
}

[class*="-shop-reviews__header__breakdown-count"] {
	font-size: var(--shop-text-xs);
	color: var(--shop-color-text-muted);
	font-weight: 700;
	text-align: right;
	min-width: 20px;
}

[class*="-shop-reviews__list"] {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

[class*="-shop-reviews__empty"] {
	text-align: center;
	/* Contrast — empty-state copy sits inside a bordered card; muted text
	   tripped Lighthouse against the surface bg. */
	color: var(--shop-color-text);
	padding: var(--shop-space-lg);
	background: var(--shop-color-surface);
	border: 1px dashed var(--shop-color-border);
	border-radius: var(--shop-radius-md);
}

[class*="-shop-reviews__more"] {
	text-align: center;
	color: var(--shop-color-text-muted);
	font-size: var(--shop-text-xs);
	margin-top: var(--shop-space-md);
}

/* ── Pagination bar ─────────────────────────────────────────────────────
   Use [class$=] (ends-with) to avoid the wildcard trap (do-not-do #25):
   [class*="...pager-num"] would also match "...pager-nums" (the wrapper),
   crushing the wrapper to 38×38 and squashing the buttons inside.
   ────────────────────────────────────────────────────────────────────── */
[class$="-reviews__pager"] {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 10px;
	margin-top: var(--shop-space-md);
	margin-bottom: var(--shop-space-lg);
	background: transparent;
	border: none;
	padding: 0;
}

/* Prev / Next buttons — use <a> for both active+disabled so Flatsome styles identically */
[class$="-reviews__pager-btn"],
[class$="-reviews__pager-btn--disabled"] {
	display: inline-flex !important;
	align-items: center;
	gap: 6px;
	padding: 9px 20px !important;
	margin: 0 !important;
	line-height: 1 !important;
	white-space: nowrap;
	border-radius: 10px;
	font-size: 13px;
	font-weight: 600;
	cursor: pointer;
	border: 1.5px solid var(--shop-color-border) !important;
	background: var(--shop-color-surface) !important;
	color: var(--shop-color-text-muted) !important;
	text-decoration: none !important;
	opacity: 1 !important;
	transition: border-color 0.2s, color 0.2s, background 0.2s;
	font-family: inherit;
	box-sizing: border-box;
}
[class$="-reviews__pager-btn"]:hover {
	border-color: var(--shop-color-accent) !important;
	color: var(--shop-color-accent) !important;
	background: #fffdf7 !important;
	opacity: 1 !important;
}
[class$="-reviews__pager-btn--disabled"] {
	opacity: 0.35 !important;
	cursor: default;
	pointer-events: none;
}

/* Page number buttons group (wrapper) */
[class$="-reviews__pager-nums"] {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	gap: 6px;
	margin: 0;
	padding: 0;
	background: transparent;
	border: none;
}

[class$="-reviews__pager-num"],
[class$="-reviews__pager-num--active"] {
	width: 38px !important;
	height: 38px !important;
	border-radius: 10px;
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	font-size: 14px;
	font-weight: 700;
	cursor: pointer;
	text-decoration: none !important;
	opacity: 1 !important;
	transition: border-color 0.2s, color 0.2s;
	border: 1.5px solid var(--shop-color-border) !important;
	background: var(--shop-color-surface) !important;
	color: var(--shop-color-text-muted) !important;
	margin: 0 !important;
	padding: 0 !important;
	line-height: 1 !important;
	box-sizing: border-box;
}
[class$="-reviews__pager-num"]:hover {
	border-color: var(--shop-color-accent) !important;
	color: var(--shop-color-accent) !important;
	opacity: 1 !important;
}
[class$="-reviews__pager-num--active"] {
	/* intentional hardcode — rating gold, matches mockup btn-num.active */
	background: linear-gradient(135deg, #c9a84c, #a07d2a) !important;
	border-color: transparent !important;
	color: #fff !important;
	box-shadow: 0 2px 8px rgba(201, 168, 76, .4) !important;
	opacity: 1 !important;
	cursor: default;
	pointer-events: none;
}

[class$="-reviews__pager-ellipsis"] {
	color: var(--shop-color-text-muted);
	font-size: 14px;
	padding: 0 4px;
}

[class$="-reviews__pager-info"] {
	font-size: 13px;
	color: var(--shop-color-text-muted);
	font-weight: 500;
	white-space: nowrap;
}

/* ──────────────────────────────────────────────────────────────────────
   Customer photo gallery (Lazada/Shopee-style image-first social proof)
   Lives between aggregate header and review list. Thumbnails open via
   Flatsome's magnificPopup (theme-provided lightbox — no library added).
   [class$=] (ends-with) avoids bleeding card styles into __gallery__link,
   __gallery__item, __gallery__head children (wildcard trap — do-not-do #25).
   ────────────────────────────────────────────────────────────────────── */
[class$="-reviews__gallery"] {
	margin: var(--shop-space-md) 0;
	padding: 22px 28px 26px;
	background: var(--shop-color-surface);
	border: 1px solid var(--shop-color-border);
	border-radius: 20px;
	box-shadow: 0 2px 16px rgba(0, 0, 0, .06);
}
[class*="-shop-reviews__gallery__head"] {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 18px;
}
[class*="-shop-reviews__gallery__title"] {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	font-size: 13px;
	font-weight: 700;
	color: var(--shop-color-text-muted);
}
ul[class*="-shop-reviews__gallery__list"] {
	list-style: none !important;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}
ul[class*="-shop-reviews__gallery__list"] > li[class*="-shop-reviews__gallery__item"] {
	list-style: none !important;
	margin: 0;
	padding: 0;
	flex: 0 0 auto;
}
ul[class*="-shop-reviews__gallery__list"] > li[class*="-shop-reviews__gallery__item"]::before,
ul[class*="-shop-reviews__gallery__list"] > li[class*="-shop-reviews__gallery__item"]::marker {
	content: none !important;
	display: none !important;
}
[class*="-shop-reviews__gallery__link"] {
	position: relative;
	display: block;
	width: 86px;
	height: 86px;
	border-radius: 12px;
	overflow: hidden;
	border: 2px solid transparent;
	cursor: zoom-in;
	box-shadow: 0 1px 6px rgba(0, 0, 0, .10);
	transition: transform .15s, border-color .2s;
	/* override Flatsome .image-lightbox opacity/background */
	opacity: 1 !important;
	background: none !important;
	padding: 0 !important;
}
[class*="-shop-reviews__gallery__link"]:hover {
	transform: scale(1.04);
	border-color: var(--shop-color-accent);
	opacity: 1 !important;
}
/* Flatsome: a img{width:100%} — override with compound selector for specificity */
[class*="-shop-reviews__gallery__link"] > img {
	width: 100% !important;
	height: 100% !important;
	object-fit: cover;
	display: block;
}
[class*="-shop-reviews__gallery__overlay"] {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(0, 0, 0, .55);
	color: #fff;
	font-weight: 700;
	font-size: var(--shop-text-base);
	pointer-events: none;
}
/* Hidden anchors that extend the lightbox group beyond visible thumbs.
 * They render in DOM but don't take layout space. */
[class*="-shop-reviews__gallery__hidden"] {
	display: none;
}

@media (max-width: 849px) {
	[class*="-shop-reviews__gallery__link"] {
		width: 64px;
		height: 64px;
	}
}

/* "แนบรูป N" hint inside review-card (links to top gallery) */
[class*="-shop-review-card__images-hint"] {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	margin: var(--shop-space-sm) 0 0;
	font-size: var(--shop-text-xs);
	color: var(--shop-color-text-muted);
}

/* ── Single review card — [class$=] avoids bleeding border/padding into
   __header, __body, __avatar children (wildcard trap — do-not-do #25). */
[class$="-shop-review-card"] {
	padding: 24px 28px;
	background: var(--shop-color-surface);
	border: 1px solid var(--shop-color-border);
	border-radius: 20px;
	box-shadow: 0 2px 14px rgba(0, 0, 0, .05);
	transition: box-shadow 0.2s, transform 0.15s;
}
[class$="-shop-review-card"]:hover {
	box-shadow: 0 6px 28px rgba(0, 0, 0, .10);
	transform: translateY(-2px);
}

/* Card header: reviewer left, verified badge right */
[class*="-shop-review-card__header"] {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--shop-space-sm) var(--shop-space-md);
	margin-bottom: 14px;
}

[class*="-shop-review-card__reviewer"] {
	display: flex;
	align-items: center;
	gap: 14px;
}

/* Avatar initials tile */
[class*="-shop-review-card__avatar"] {
	width: 46px;
	height: 46px;
	min-width: 46px;
	border-radius: 50%;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-size: 19px;
	font-weight: 800;
	color: #fff;
	box-shadow: 0 2px 8px rgba(0, 0, 0, .18);
	flex-shrink: 0;
	user-select: none;
}

[class*="-shop-review-card__reviewer-info"] {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

[class*="-shop-review-card__author"] {
	font-size: 14px;
	font-weight: 700;
	color: var(--shop-color-text);
	line-height: 1.2;
}

[class*="-shop-review-card__date"] {
	font-size: var(--shop-text-xs);
	color: var(--shop-color-text-muted);
	line-height: 1;
}

[class*="-shop-review-card__verified"] {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	font-size: 12px;
	font-weight: 600;
	color: var(--shop-color-success);
	background: #f0faf4;
	border: 1px solid #b4e2c0;
	padding: 5px 12px;
	border-radius: var(--shop-radius-pill);
}

/* Star row */
[class*="-shop-review-card__rating"] {
	display: inline-flex;
	align-items: center;
	gap: 2px;
	margin-bottom: 13px;
}

[class*="-shop-review-card__star--on"] {
	color: var(--shop-color-accent);
}
[class*="-shop-review-card__star--on"] svg {
	fill: currentColor;
}

[class*="-shop-review-card__star--off"] {
	color: #e0ddd6;
}
[class*="-shop-review-card__star--off"] svg {
	fill: currentColor; /* intentional hardcode — muted star matches mockup .empty color */
}

/* Card body: image left + text right (or full-width when no image) */
[class*="-shop-review-card__body"] {
	display: flex;
	gap: 16px;
	align-items: flex-start;
	color: var(--shop-color-text);
	line-height: 1.85;
}

[class*="-shop-review-card__body--no-img"] {
	display: block;
}

[class*="-shop-review-card__body-img-link"] {
	flex: 0 0 108px; /* override any flex-grow/shrink from Flatsome */
	display: block;
	width: 108px !important;
	min-width: 108px !important;
	max-width: 108px !important;
	height: 108px;
	border-radius: 12px;
	overflow: hidden;
	border: 1px solid var(--shop-color-border);
	box-shadow: 0 1px 8px rgba(0, 0, 0, .10);
	transition: transform 0.15s, border-color 0.2s;
}
[class*="-shop-review-card__body-img-link"]:hover {
	transform: scale(1.04);
	border-color: var(--shop-color-accent);
}

/* Flatsome: a img{display:block;width:100%} — lock dimensions inside 108px container */
[class*="-shop-review-card__body-img"] {
	width: 108px !important;
	height: 108px !important;
	object-fit: cover;
	display: block;
}

[class*="-shop-review-card__body-text"] {
	flex: 1;
	min-width: 0;
	font-size: 14px;
	color: #4a4a4a;
	overflow-wrap: break-word;
	word-break: break-word; /* Thai long-word fallback */
}

[class*="-shop-review-card__quote"] {
	border-left: 3px solid var(--shop-color-accent);
	padding-left: 12px;
	color: var(--shop-color-text);
	font-style: italic;
	margin: 0 0 8px;
	font-size: 14px;
	line-height: 1.6;
}

[class*="-shop-review-card__body-text"] p {
	margin: 0;
	font-size: 14px;
	line-height: 1.85;
	overflow-wrap: break-word;
}

/* Form ------------------------------------------------------------------ */
[class*="-shop-review-form"] {
	margin-top: var(--shop-space-lg);
	padding: var(--shop-space-md);
	background: var(--shop-color-surface);
	border: 1px solid var(--shop-color-border);
	border-radius: var(--shop-radius-md);
}

[class*="-shop-review-form__heading"] {
	display: flex;
	align-items: center;
	gap: var(--shop-space-sm);
	font-family: var(--shop-font-heading);
	margin: 0 0 var(--shop-space-sm);
}

[class*="-shop-review-form__verified"] {
	color: var(--shop-color-success);
	font-size: var(--shop-text-xs);
	margin: 0 0 var(--shop-space-md);
}

[class*="-shop-review-form__field"] {
	margin-bottom: var(--shop-space-md);
	border: none;
	padding: 0;
}

[class*="-shop-review-form__label"] {
	display: block;
	font-weight: 600;
	color: var(--shop-color-text);
	margin-bottom: 6px;
}

[class*="-shop-review-form__hint"] {
	font-weight: 400;
	font-size: var(--shop-text-xs);
	color: var(--shop-color-text-muted);
	margin-left: var(--shop-space-sm);
}

[class*="-shop-review-form__stars"] {
	display: inline-flex;
	gap: 4px;
	direction: ltr;
}

[class*="-shop-review-form__star"] {
	cursor: pointer;
	display: inline-flex;
	color: var(--shop-color-border);
	transition: color 0.15s;
}

[class*="-shop-review-form__star"] input {
	position: absolute;
	opacity: 0;
	pointer-events: none;
}

[class*="-shop-review-form__star"]:hover,
[class*="-shop-review-form__star"]:hover ~ [class*="-shop-review-form__star"] {
	color: var(--shop-color-accent);
}

[class*="-shop-review-form__star"]:has(input:checked),
[class*="-shop-review-form__star"]:has(input:checked) ~ [class*="-shop-review-form__star"] {
	color: var(--shop-color-accent);
}

[class*="-shop-review-form__textarea"] {
	width: 100%;
	min-height: 120px;
	padding: var(--shop-space-sm);
	border: 1px solid var(--shop-color-border);
	border-radius: var(--shop-radius-sm);
	background: var(--shop-color-surface);
	color: var(--shop-color-text);
	font-family: var(--shop-font-body);
	font-size: var(--shop-text-base);
	resize: vertical;
}

[class*="-shop-review-form__counter"] {
	font-size: var(--shop-text-xs);
	color: var(--shop-color-text-muted);
	text-align: right;
	margin-top: 4px;
}

[class*="-shop-review-form__images"] {
	display: flex;
	gap: var(--shop-space-sm);
	flex-wrap: wrap;
}

[class*="-shop-review-form__image-slot"] {
	position: relative;
	width: 88px;
	height: 88px;
	border: 1px dashed var(--shop-color-border);
	border-radius: var(--shop-radius-sm);
	background: var(--shop-color-surface-muted);
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
}

[class*="-shop-review-form__image-slot"] input[type="file"] {
	position: absolute;
	inset: 0;
	opacity: 0;
	cursor: pointer;
	width: 100%;
	height: 100%;
}

[class*="-shop-review-form__image-placeholder"] {
	color: var(--shop-color-text-muted);
}

[class*="-shop-review-form__image-placeholder"] img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

[class*="-shop-review-form__moderation-note"] {
	display: flex;
	align-items: center;
	gap: 6px;
	color: var(--shop-color-text-muted);
	font-size: var(--shop-text-xs);
	margin: var(--shop-space-md) 0;
}

/* Ineligibility states — Compact 1-line bar layout.
   Was: 250px tall panel with stacked icon/title/desc/button (4 rows).
   Now: 60px bar with icon + message + CTA on one row. -76% height, -89% words.
   Mobile (<560px): wraps to 2 rows (icon+message stays inline; CTA drops down).
   Padding uses --shop-space-md vertical too so the CTA's larger min-height
   can't push past the panel's right edge — left/right gap stay symmetric. */
[class*="-shop-reviews__state"] {
	display: flex;
	align-items: center;
	gap: var(--shop-space-md);
	margin-top: var(--shop-space-md);
	padding: var(--shop-space-md);
	background: var(--shop-color-surface-muted);
	border: 1px solid var(--shop-color-border);
	border-radius: var(--shop-radius-md);
	counter-reset: none;
	counter-increment: none;
}
[class*="-shop-reviews__state"]::before,
[class*="-shop-reviews__state"]::after {
	content: none !important;
	display: none !important;
}

/* SVG icon — inline left, muted colour. */
[class*="-shop-reviews__state"] > svg {
	flex: 0 0 auto;
	color: var(--shop-color-text-muted);
}
[class*="-shop-reviews__state"] > svg::before,
[class*="-shop-reviews__state"] > svg::after {
	content: none !important;
	display: none !important;
}

/* Inline message — flex-grows to push CTA right. Reset Flatsome's default
   <p> border/background so it doesn't read as an <input> placeholder. */
[class*="-shop-reviews__state-msg"] {
	flex: 1 1 auto;
	margin: 0;
	padding: 0;
	background: transparent;
	border: 0;
	color: var(--shop-color-text);
	font-size: 16px; /* intentional hardcode — Flatsome single-product layout sets :root font-size to 20px, so var(--shop-text-base)=1rem resolves to 20px not 16px (same precedent as specs__value above). */
	font-weight: 600;
	line-height: 1.4;
}

/* CTA button — compact, sized to content. Three Flatsome quirks force the
   defensive overrides below:
     1. Flatsome ships a global rule that adds margin-top:0.67em (~10.72px at
        16px base) to any block-level link in flow context — DevTools shows
        Margin: 10.72px 0px 0px on this anchor. We pin margin to 0 so the
        button stays vertically centred with the message line.
     2. shop-base.css ships min-height:2.75rem + padding:.7rem 1.4rem on every
        shop-button — those defaults overhang the bar. We shrink to fit.
     3. Some Flatsome layouts re-target [class~="full-width"] / .expand which
        forces width:100% — we lock width:auto so the bar stays right-anchored. */
[class*="-shop-reviews__state-cta"] {
	flex: 0 0 auto;
	white-space: nowrap;
	min-height: 0;
	width: auto;
	margin: 0;
	padding: .55rem 1rem;
	font-size: var(--shop-text-sm, .9375rem);
	align-self: center;
}

@media (max-width: 549px) {
	[class*="-shop-reviews__state"] {
		flex-wrap: wrap;
	}
	[class*="-shop-reviews__state-cta"] {
		width: 100%;
		text-align: center;
	}
}

@media (max-width: 549px) {
	[class*="-shop-reviews__header__summary"] {
		grid-template-columns: 1fr;
	}
	[class*="-shop-review-card__body"] {
		flex-direction: column;
	}
	[class*="-shop-review-card__body-img-link"] {
		width: 100%;
		height: 180px;
	}
	[class$="-reviews__pager"] {
		gap: 6px;
	}
}


/* ── Zoom button (hero bottom-left) ──────────────────────────────────────── */

[class$="-zoom-btn"] {
	position: absolute;
	bottom: var(--shop-space-sm);
	left: var(--shop-space-sm);
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	padding: 0;
	background: var(--shop-color-surface);
	border: 1px solid var(--shop-color-border);
	border-radius: var(--shop-radius-sm);
	color: var(--shop-color-text);
	cursor: pointer;
	opacity: 0.85;
	transition: opacity 150ms ease, background 150ms ease;
}

[class$="-zoom-btn"]:hover,
[class$="-zoom-btn"]:focus-visible {
	opacity: 1;
	background: var(--shop-color-surface-muted);
	outline: none;
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--shop-color-accent) 30%, transparent);
}

[class$="-zoom-btn"] svg {
	display: block;
}


/* ── Lightbox dialog ─────────────────────────────────────────────────────── */

/* Lightbox dialog — full-viewport flex container that centers the image.
   `100vw` (visual viewport) instead of `100%` (layout viewport) so the
   dialog isn't narrowed by the scrollbar gutter — otherwise the centered
   image lands a few pixels left of the true window center. */
[class$="-lightbox"] {
	position: fixed;
	top: 0;
	left: 0;
	right: auto;
	bottom: auto;
	width: 100vw;
	height: 100vh;
	max-width: 100vw;
	max-height: 100vh;
	margin: 0;
	padding: 0;
	border: none;
	/* intentional hardcode — near-black backdrop, no theme token equivalent */
	background: rgba(0, 0, 0, 0.92);
	display: flex;
	align-items: center;
	justify-content: center;
	z-index: 99999;
}

[class$="-lightbox"]:not([open]) {
	display: none;
}

[class$="-lightbox"]::backdrop {
	display: none; /* we style the dialog bg directly */
}

[class$="-lightbox__close"] {
	position: absolute;
	top: var(--shop-space-sm);
	right: var(--shop-space-sm);
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	background: transparent;
	border: none;
	border-radius: var(--shop-radius-sm);
	/* intentional hardcode — white icon on dark backdrop */
	color: #fff;
	cursor: pointer;
	opacity: 0.8;
	transition: opacity 150ms ease;
}

[class$="-lightbox__close"]:hover,
[class$="-lightbox__close"]:focus-visible {
	opacity: 1;
	outline: none;
	/* intentional hardcode — subtle white ring on dark bg */
	box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.5);
}

/* Figure shrinks to image — `inline-block` + `position: relative` so the
   nav buttons (absolute children) anchor to the image edges instead of the
   full dialog. Dialog's flex centering still places the figure mid-screen. */
[class$="-lightbox__figure"] {
	position: relative;
	display: inline-block;
	margin: 0;
	padding: 0;
	max-width: calc(100vw - 2 * var(--shop-space-md));
	max-height: calc(100vh - 2 * var(--shop-space-md));
}

/* Lightbox img — pinned at natural max 768px so the source image (served
   at 'medium_large' / 768px) never upscales above its true pixels. On
   viewports larger than 768px the dialog backdrop letterboxes the image;
   on smaller viewports `min(100%, 768px)` lets it scale down to fit.
   Result: no pixelation at any viewport size, ~46% smaller payload than
   'large', and no regenerate needed (WP ships medium_large by default).
   Specificity boost via dialog ancestor — Flatsome ships `img { max-width:
   100% }` which would let the image stretch larger than 768px otherwise. */
dialog[data-shop-lightbox] [class$="-lightbox__img"] {
	display: block;
	max-width: min(100%, 768px);
	max-height: min(100%, 768px);
	width: auto;
	height: auto;
	object-fit: contain;
	border-radius: var(--shop-radius-md);
	margin: 0 auto;
}

@media (max-width: 549px) {
	[class$="-lightbox__figure"] {
		max-width: calc(100vw - 2 * var(--shop-space-sm));
		max-height: calc(100vh - 2 * var(--shop-space-sm));
	}
}

