/* CHXN page: product detail — gallery, price block, quantity+CTA, tabs,
   related products, WFBT, recently viewed.
   Targets WooCommerce core's own default classes (".summary",
   ".woocommerce-product-gallery", ".product_title", ".related.products",
   ".price"...) plus this theme's own custom-hook classes (chxn-*) — NOT
   Flatsome's equivalents. A lot of hai-tra's version of this file spent
   real effort specifically fighting Flatsome's own competing CSS
   (!important wars over button min-height, row display, overflow axes) —
   none of that applies here since there's no Flatsome stylesheet loaded
   to fight, so this version is considerably shorter. */

/* WooCommerce's default content-single-product.php prints the gallery
   (via "woocommerce_before_single_product_summary") and ".summary" as two
   SIBLINGS inside this native "div.product" wrapper — no template
   override needed, just grid-ing the wrapper WooCommerce already gives. */
.single-product div.product {
	display: grid;
	/* "minmax(0, 1fr)", not a bare "1fr" — a plain "1fr" track's default
	   "auto" minimum sizes to its widest child's min-content (the gallery
	   slider's flexslider markup, which doesn't shrink on its own), so the
	   whole grid held at that width and forced horizontal scroll on every
	   viewport up to 850px instead of actually narrowing with it. */
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: 40px;
	padding: 24px 0 0;
}
/* below ~1380px "#chxn-main.chxn-container" (max-width:1240px, 20px side
   padding — same shared container class as every other page) has no
   spare margin outside that padding for the fixed floating contact
   cluster (components/fab.css, bottom-right, ~90px footprint incl.
   offset) to sit in — so the summary column's hotline/Zalo buttons,
   flush against the container's own right edge, end up partly hidden
   under it. Extra right padding scoped to just this grid (not the
   shared .chxn-container, which would shift header/footer/every other
   page too) keeps it clear. */
@media (min-width: 851px) and (max-width: 1380px) {
	.single-product div.product {
		padding-right: 90px;
	}
}
@media (max-width: 850px) {
	.single-product div.product {
		grid-template-columns: minmax(0, 1fr);
		/* "gap:40px" above is sized as a horizontal gutter between the
		   2 desktop columns — once they stack into 1 column here, that
		   same 40px becomes VERTICAL space between every section
		   (gallery, summary, tabs, related, seen), adding up to a lot of
		   dead scroll distance between blocks that are already full-width
		   and clearly separated by their own card backgrounds. */
		gap: 20px;
	}
}
/* everything that hooks in AFTER the gallery+summary pair (tabs, related
   products, WFBT once JS repositions it, recently-viewed) is a later
   sibling of the same grid container — CSS Grid auto-places extra
   children into individual cells by default instead of stacking them
   full-width below, so each needs to explicitly span both columns. */
.single-product div.product > .woocommerce-tabs,
.single-product div.product > .related.products,
.single-product div.product > .yith-wfbt-section,
.single-product div.product > .chxn-seen-section {
	grid-column: 1 / -1;
}

/* WooCommerce's own woocommerce-layout.css (a float-based fallback for
   themes with no gallery CSS of their own) ships
   ".woocommerce div.product div.images.woocommerce-product-gallery
   {float:left;width:48%}" — that selector's specificity beats a plain
   ".woocommerce-product-gallery" rule, so it has to be matched exactly
   to win the override. */
.woocommerce div.product div.images.woocommerce-product-gallery,
.woocommerce-product-gallery {
	float: none;
	width: 100%;
	box-sizing: border-box;
}
/* border/radius on the main-image viewport only (detail.dc.html: the
   16px-rounded 1px border belongs to the big photo alone) — it used to
   sit on the whole ".woocommerce-product-gallery" wrapper above, which
   also contains the thumbnail strip and whatever slack height the
   flexslider viewport math leaves below it, so the box read as one
   oversized border around photo + thumbs + empty space. ">" matters:
   with flexslider active the slides' ".woocommerce-product-gallery__
   wrapper" is nested INSIDE ".flex-viewport" (only the viewport is the
   direct child, so only it gets the border); on a single-photo product
   flexslider never initializes and the wrapper itself is the direct
   child instead. */
.woocommerce-product-gallery > .flex-viewport,
.woocommerce-product-gallery > .woocommerce-product-gallery__wrapper {
	border: 1px solid var(--chxn-line);
	border-radius: var(--chxn-radius-img);
	overflow: hidden;
}
.woocommerce-product-gallery .flex-control-thumbs {
	margin-top: 10px;
}
/* the gallery slide's own "<img>" tag never had a width/height CSS rule
   at all — only its wrapping ".woocommerce-product-gallery__image" slide
   div gets a "width:Npx" from flexslider's own JS (needed for the
   horizontal-scroll-via-transform track math, so that div's width can't
   be touched here). Without it, a plain "<img>" renders at its OWN
   native/attribute-declared pixel size regardless of that wrapper's
   width — fine by coincidence for a photo whose upload happened to be
   sized close to the slide box, but any OTHER photo at a different
   native size/aspect ratio rendered at ITS OWN size instead, inconsistent
   from slide to slide and liable to overflow past the rounded gallery
   border entirely. "object-fit:cover" (rather than stretching to fill)
   keeps non-square photos looking correct instead of squished. */
.woocommerce-product-gallery__image {
	/* only ".flex-viewport" (this element's grandparent) gets an explicit
	   pixel height from flexslider's own JS — without one here too, the
	   img's own "height:100%" below has nothing to resolve against per
	   the CSS spec (a percentage height needs an explicit parent height)
	   and falls back to "auto" instead. */
	height: 100%;
}
.woocommerce-product-gallery__image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	/* modules/product-gallery.js's setupImageClickLightbox() — clicking the
	   photo itself now opens the same PhotoSwipe album the magnifier icon
	   does, so it needs the same visual hint that icon already gives. */
	cursor: zoom-in;
}
/* PhotoSwipe's own default skin ships a plain black ".pswp__bg{background:
   #000}" — the top bar (close/zoom/counter), arrow buttons, and caption
   bar each already paint their OWN semi-transparent dark backing
   independent of this (their own "rgba(0,0,0,.3-.5)" rules), so changing
   just the empty-space background here to a light color doesn't lose any
   icon/text contrast — nothing else needs recoloring alongside it. */
.pswp__bg {
	background: rgba(255, 255, 255, .92) !important;
}
/* WC core hooks its sale-flash template on "woocommerce_before_single_
   product_summary" at priority 10 and the gallery itself at priority 20
   (wc-template-hooks.php) — the badge prints FIRST, as a SIBLING <span>
   immediately BEFORE ".woocommerce-product-gallery" inside "div.product",
   never actually nested inside it. A descendant selector expecting it
   inside the gallery (".woocommerce-product-gallery .onsale") never
   matched anything, so the badge kept showing — positioned by product-
   card.css's own shared, unscoped ".chxn-badge-sale, .onsale{position:
   absolute;top:10px;left:10px}" rule (written for shop/related CARDS,
   where that lands relative to ".chxn-product-card-media" — here, with
   no equivalent positioned ancestor around it, it happened to land
   overlapping the gallery's own corner instead, by coincidence rather
   than intent). */
.single-product div.product > .onsale,
.single-product div.product > .chxn-badge-sale {
	display: none;
}
/* thumbnail album — WooCommerce core's own flexslider CSS lays these out
   as a "width:25%;float:left" WRAPPING grid (clearing every 3rd/4th/5th
   item depending on gallery column count), which for a product with many
   photos meant several tall rows stacked below the main image instead of
   a single, compact scrollable strip. */
.flex-control-thumbs {
	display: flex;
	flex-wrap: nowrap;
	overflow-x: auto;
	gap: 10px;
	padding: 4px 2px;
	scroll-snap-type: x proximity;
}
.flex-control-thumbs li {
	float: none;
	width: auto;
	flex: 0 0 84px;
	scroll-snap-align: start;
}
.flex-control-thumbs li img {
	width: 84px !important;
	height: 84px !important;
	object-fit: cover;
	border-radius: var(--chxn-radius-input);
	border: 2px solid transparent;
	box-sizing: border-box;
}
.flex-control-thumbs li img.flex-active {
	border-color: var(--chxn-green);
	opacity: 1;
}
/* thumbnail slider buttons — modules/product-gallery.js's setupThumbSlider()
   wraps ".flex-control-thumbs" in this on products with enough photos to
   overflow the strip (drag-to-scroll alone worked, but wasn't obvious at a
   glance the way a visible arrow button is). Same look/overlap idea as
   ".chxn-related-scroll-btn" (related products slider), just sized down to
   the 84px-tall thumbnail row instead of a full product card. */
.chxn-thumb-scroll-wrap {
	position: relative;
}
.chxn-thumb-scroll-btn {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 3;
	width: 28px;
	height: 28px;
	border-radius: 50% !important;
	border: 1px solid var(--chxn-line);
	background: var(--chxn-card);
	box-shadow: 0 2px 8px rgba(0, 0, 0, .14);
	font-size: 14px;
	line-height: 1;
	color: var(--chxn-ink);
	cursor: pointer;
	font-family: inherit;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	margin: 0;
	box-sizing: border-box;
}
.chxn-thumb-scroll-btn:hover {
	border-color: var(--chxn-green);
	color: var(--chxn-green-d);
}
/* unlike the related-products/recently-viewed sliders, this wrap sits
   NESTED inside ".woocommerce-product-gallery" itself (same element the
   main slide viewport needs its own "overflow:hidden" on) — a button
   overlapping PAST that box's edge (negative left/right, like those other
   sliders use) got silently clipped away by that same overflow:hidden,
   rendering as if the buttons simply didn't exist. Inset instead of
   overlapping keeps both fully inside the visible, unclipped area. */
.chxn-thumb-scroll-btn.chxn-thumb-scroll-prev {
	left: 6px;
}
.chxn-thumb-scroll-btn.chxn-thumb-scroll-next {
	right: 6px;
}
.chxn-thumb-scroll-btn[disabled] {
	opacity: 0;
	pointer-events: none;
}

/* same woocommerce-layout.css fallback also floats+narrows ".summary"
   (".woocommerce div.product div.summary{float:right;width:48%}") — match
   its specificity to override, same reasoning as the gallery rule above. */
.woocommerce div.product div.summary,
.summary {
	float: none;
	width: 100%;
}

/* ---- breadcrumb (business-logic.php: custom "chxn_product_card_after"-
   style hook replacing Flatsome's own breadcrumb) ---- */
.chxn-product-crumb {
	font-size: 13px;
	color: var(--chxn-ink-2);
	margin: 0 0 4px;
}
.chxn-product-crumb a {
	color: var(--chxn-ink-2);
}
.chxn-product-crumb a:hover {
	color: var(--chxn-green-d);
}

.chxn-product-region {
	display: inline-block;
	margin: 10px 0;
	font-size: 11.5px;
	background: var(--chxn-green-l);
	color: var(--chxn-green-d);
	font-weight: 700;
	padding: 3px 10px;
	border-radius: var(--chxn-radius-pill);
}

.product_title {
	font-size: 27px;
	font-weight: 800;
	line-height: 1.2;
	margin: 13px 0 0;
}

/* ---- rating + sold + stock row ---- */
.chxn-product-rating-row {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 10px 0 0;
	font-size: 13.5px;
	color: var(--chxn-ink-2);
	flex-wrap: wrap;
}
.chxn-product-rating-num {
	color: var(--chxn-amber);
	font-weight: 700;
}
.chxn-product-rating-link {
	color: var(--chxn-ink-2);
}
.chxn-product-rating-link:hover {
	color: var(--chxn-green-d);
}
.chxn-product-stock.in-stock {
	color: var(--chxn-green-d);
	font-weight: 600;
}
.chxn-product-stock.out-of-stock {
	color: var(--chxn-red);
	font-weight: 600;
}

/* ---- price block ---- */
.summary .price {
	margin-top: 16px;
	background: #fff4ec;
	border: 1px solid #f6d7c6;
	border-radius: 12px;
	padding: 16px 18px;
	display: flex;
	align-items: baseline;
	gap: 11px;
	flex-wrap: wrap;
	font-weight: 800;
	font-size: 30px;
	color: var(--chxn-red);
}
/* WooCommerce always prints <del>(old)</del> before <ins>(new)</ins> — the
   design shows the new price first, so this reorders via flex. */
.summary .price ins {
	order: 1;
	text-decoration: none;
}
.summary .price ins .amount {
	color: var(--chxn-red);
}
.summary .price .devvn_woocommerce_price_suffix {
	order: 2;
	font-size: 15px;
	font-weight: 600;
	color: var(--chxn-ink-2);
}
.summary .price del {
	order: 3;
	text-decoration: none;
}
.summary .price del .amount {
	font-size: 17px;
	color: var(--chxn-ink-2);
	font-weight: 400;
	text-decoration: line-through;
}
.summary .price .chxn-badge-sale {
	position: static;
	order: 4;
	background: var(--chxn-red);
	color: #fff;
	font-size: 13px;
	font-weight: 700;
	padding: 3px 9px;
	border-radius: 7px;
}
.chxn-product-save {
	order: 5;
	flex-basis: 100%;
	font-size: 13px;
	color: var(--chxn-green-d);
	font-weight: 600;
	margin-top: 8px;
}
.summary .price .devvn_woocommerce_price_prefix {
	display: none;
}

/* ---- short description (real catalog data: an info table of xuất xứ /
   loại thực phẩm / bảo quản / gửi từ — genuinely useful, always shown) ---- */
.summary .woocommerce-product-details__short-description {
	margin: 18px 0 0;
	border: 1px solid var(--chxn-line);
	border-radius: var(--chxn-radius-card);
	overflow: hidden;
	font-size: 13px;
	line-height: 1.8;
	color: var(--chxn-ink-2);
}
.summary .woocommerce-product-details__short-description > *:not(table) {
	margin: 0;
	padding: 14px 18px;
}
.summary .woocommerce-product-details__short-description > *:not(table):not(:last-child) {
	border-bottom: 1px solid var(--chxn-line);
}
.summary .woocommerce-product-details__short-description table {
	width: 100%;
	border-collapse: collapse;
	margin: 0;
	border: 0;
}
.summary .woocommerce-product-details__short-description tr {
	background: var(--chxn-card);
	border-top: 1px solid var(--chxn-line);
}
.summary .woocommerce-product-details__short-description tr:first-child {
	border-top: 0;
}
.summary .woocommerce-product-details__short-description tr:nth-child(even) {
	background: var(--chxn-bg);
}
/* modules/product-gallery.js's positionShortDescription() moves this
   whole block to sit right before ".single_variation_wrap" on variable
   products — which is itself INSIDE "form.cart", so WooCommerce core's
   own "form.cart table td{padding-left:0}" (higher specificity, 3
   classes vs. this rule's 2) was winning and zeroing out just the
   left padding, only on variable products. */
.summary .woocommerce-product-details__short-description td {
	padding: 9px 14px !important;
	font-size: 13px;
	color: var(--chxn-ink-2);
	border: 0;
}
.summary .woocommerce-product-details__short-description td:first-child {
	font-weight: 700;
	color: var(--chxn-ink);
	width: 42%;
}

/* ---- hotline + zalo quick-contact row ---- */
.chxn-product-contact-row {
	display: flex;
	gap: 10px;
	margin: 14px 0 0;
}
.chxn-product-contact-hotline,
.chxn-product-contact-zalo {
	flex: 1;
	text-align: center;
	border-radius: var(--chxn-radius-pill);
	padding: 11px;
	font-weight: 700;
	font-size: 13.5px;
}
.chxn-product-contact-hotline {
	background: var(--chxn-green-l);
	color: var(--chxn-green-d);
}
.chxn-product-contact-zalo {
	background: #e7f0ff;
	color: #0068ff;
}

/* ---- product meta (SKU/category) ---- */
.chxn-product-meta {
	margin: 20px 0 0;
	padding-top: 18px;
	border-top: 1px solid var(--chxn-line);
	font-size: 13px;
	color: var(--chxn-ink-2);
	line-height: 1.95;
}
.chxn-product-meta span {
	color: var(--chxn-ink);
	font-weight: 600;
}
.chxn-product-meta a {
	color: var(--chxn-green-d);
}

/* ---- variation/attribute selector ("Chọn quy cách") — flat text+price
   swatch buttons, built directly from the variations_form's own data by
   modules/product-gallery.js (setupVariationSwatches), not a skin over
   any plugin's native swatch markup. ---- */
table.variations {
	width: 100%;
	/* 14px, not 20 — matches the other same-level gaps in this column
	   (".chxn-product-contact-row{margin:14px 0 0}" right below); 20px
	   read as an outlier, a visibly bigger jump right after the price
	   box than every other gap between these stacked rows. */
	margin: 14px 0 0;
	position: relative;
}
table.variations tbody,
table.variations tr,
table.variations th,
table.variations td {
	display: block;
	width: 100%;
	padding: 0;
	border: 0;
}
table.variations th.label {
	/* browsers' default UA stylesheet centers <th> text — this theme's own
	   "display:block" above doesn't touch that, so the label floated
	   centered above the (left-aligned) swatch row instead of sitting
	   directly above them. */
	text-align: left;
	font-size: 13.5px;
	font-weight: 700;
	color: var(--chxn-ink);
	margin-bottom: 10px;
}
.reset_variations {
	/* the "th" (Loại) and the swatches ".td" are separate table cells
	   stacked block-on-block — absolute-positioning against the table
	   itself (not either cell) is what actually lines this up with the
	   label's own row instead of trailing below the swatch row. */
	position: absolute;
	top: 0;
	right: 0;
	font-size: 12px;
	color: var(--chxn-ink-2);
	display: inline-block;
}
.chxn-variant-swatches {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin: 4px 0 0;
}
.chxn-variant-swatch {
	position: relative;
	border: 1.5px solid var(--chxn-line);
	background: var(--chxn-card);
	color: var(--chxn-ink);
	/* base.css's site-wide "button{border-radius:var(--chxn-radius-pill)
	   !important}" reset otherwise wins over a plain (non-!important)
	   value here since this is a real <button> tag (modules/product-
	   gallery.js's setupVariationSwatches()) — same fix as the coupon
	   chips and the account page's login button. */
	border-radius: 11px !important;
	padding: 8px 34px 8px 14px;
	cursor: pointer;
	text-align: left;
	font-family: inherit;
	display: block;
	white-space: normal;
	text-transform: none;
}
.chxn-variant-swatch:hover {
	border-color: var(--chxn-ink-2);
}
.chxn-variant-swatch.is-selected {
	border-color: var(--chxn-green);
	background: var(--chxn-green-l);
	color: var(--chxn-green-d);
}
.chxn-variant-swatch-label {
	display: block;
	font-weight: 700;
	font-size: 12.5px;
	line-height: 1.3;
	white-space: normal;
	max-width: 175px;
}
.chxn-variant-swatch-price {
	display: block;
	font-size: 12.5px;
	color: var(--chxn-red);
	font-weight: 700;
	margin-top: 2px;
}
.chxn-variant-swatch-badge {
	position: absolute;
	top: -9px;
	right: -6px;
	background: var(--chxn-red);
	color: #fff;
	font-size: 10.5px;
	font-weight: 700;
	padding: 2px 6px;
	border-radius: 6px;
}
/* modules/product-gallery.js reuses the already-styled price box as the
   single dynamic price display by swapping its contents on
   "found_variation" — Woo's own native variation price element would
   otherwise show a second, unstyled price line alongside it. */
.woocommerce-variation-price {
	display: none;
}
.woocommerce-variation-add-to-cart-disabled {
	margin-top: 14px;
}

/* ---- quantity + CTA buttons row ---- */
form.cart:not(.variations_form),
.woocommerce-variation-add-to-cart {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 12px 14px;
}
form.cart:not(.variations_form) {
	margin-top: 22px;
}
.woocommerce-variation-add-to-cart {
	margin-top: 14px;
}
form.cart:not(.variations_form)::after,
.woocommerce-variation-add-to-cart::after {
	content: "";
	order: 2;
	flex-basis: 100%;
	height: 0;
}
.chxn-product-qty-label {
	order: 0;
	flex: 0 0 auto;
	font-size: 13.5px;
	color: var(--chxn-ink-2);
}
.quantity {
	order: 1;
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	background: var(--chxn-green-l);
	border: 1.5px solid var(--chxn-green);
	border-radius: var(--chxn-radius-pill);
	overflow: hidden;
	margin: 0;
	height: 45px;
}
.quantity .qty {
	width: 34px;
	height: 42px;
	padding: 0;
	border: 0;
	background: none;
	font-weight: 800;
	font-size: 15px;
	color: var(--chxn-green-d);
	text-align: center;
	/* the design's "−"/"+" buttons (modules/product-gallery.js's
	   setupQuantitySteppers()) replace the browser's own up/down spinner
	   arrows, which otherwise still show stacked on the right. */
	-moz-appearance: textfield;
}
.quantity .qty::-webkit-inner-spin-button,
.quantity .qty::-webkit-outer-spin-button {
	-webkit-appearance: none;
	margin: 0;
}
.chxn-qty-btn {
	flex: none;
	width: 32px;
	height: 45px;
	border: 0;
	background: none;
	color: var(--chxn-green-d);
	font-weight: 800;
	font-size: 16px;
	line-height: 1;
	cursor: pointer;
	font-family: inherit;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0;
}
.chxn-qty-btn:hover {
	background: var(--chxn-green);
	color: #fff;
}
.single_add_to_cart_button.button {
	order: 4;
	flex: 1 1 0;
	align-self: stretch;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--chxn-green) !important;
	border-color: var(--chxn-green) !important;
	border-radius: var(--chxn-radius-pill) !important;
	font-weight: 700;
	font-size: 15px;
	line-height: 1.2;
	padding: 15px;
	text-transform: none;
	margin: 0;
}
.single_add_to_cart_button.button:hover {
	background: var(--chxn-green-d) !important;
}
/* WooCommerce core's own ".button.loading::after" spinner assumes a
   plain inline button with visible label text beside it — it positions
   the icon with "right:1em", not centered, and reserves room via
   "padding-right" rather than moving it. This button's own "display:
   flex" already centers its actual TEXT, but that spinner is an
   absolutely-positioned pseudo-element outside the flex flow, so it
   still rendered off to WC's default right-anchored spot instead of
   the middle of this pill. */
.single_add_to_cart_button.button.loading::after {
	top: 50% !important;
	right: auto !important;
	left: 50% !important;
	transform: translate(-50%, -50%);
	margin: 0 !important;
}
/* "⚡ Đặt hàng nhanh" — NEW (not in hai-tra/functions.php as a template
   override; hai-tra relied on Flatsome's own bundled buy-now button
   feature, which doesn't exist without Flatsome — see inc/business-
   logic.php's "chxn_buy_now_button" for the from-scratch implementation:
   add-to-cart + immediate redirect to checkout via a URL flag). */
.chxn-buy-now-button {
	order: 3;
	flex: 1 1 0;
	align-self: stretch;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 2px;
	background: var(--chxn-red);
	color: #fff;
	border: 0;
	border-radius: var(--chxn-radius-pill);
	font-weight: 700;
	font-size: 15px;
	padding: 12px 15px;
	line-height: 1.2;
	text-transform: none;
	margin: 0;
	white-space: normal;
}
.chxn-buy-now-button:hover {
	background: var(--chxn-red-d);
}
.chxn-buy-now-button:disabled {
	opacity: .5;
	cursor: not-allowed;
}
/* icon + title on one row, "nowrap" so a narrow button can't split the
   "⚡" onto its own line above the text (which also made the whole
   button noticeably taller than "Thêm vào giỏ" next to it). */
.chxn-buy-now-main {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	white-space: nowrap;
}
.chxn-buy-now-sub {
	display: block;
	font-size: 11px;
	font-weight: 400;
	opacity: .9;
}

/* ---- tabs — underline style (3px bottom border on the active one) ----
   Every selector below matches WooCommerce core's own
   ".woocommerce div.product .woocommerce-tabs ul.tabs li ..." shape —
   core ships a full gray folder-tab skin for these (li background,
   1px borders, 4px top radii, ::before/::after corner-curve pseudo
   elements, its own ul padding/margin) at that higher specificity, so
   the previous plain ".woocommerce-tabs ul.tabs ..." rules here lost
   every tie and the tabs still rendered as beveled folder tabs instead
   of detail.dc.html's flat underline row. */
.woocommerce-tabs {
	background: var(--chxn-card);
	border: 1px solid var(--chxn-line);
	border-radius: var(--chxn-radius-card);
	padding: 4px 24px 22px;
	box-shadow: 0 4px 16px rgba(18, 107, 72, .04);
	margin-top: 40px;
}
.woocommerce div.product .woocommerce-tabs ul.tabs {
	border-bottom: 1px solid var(--chxn-line);
	display: flex;
	gap: 6px;
	flex-wrap: wrap;
	padding: 0;
	margin: 0;
	list-style: none;
	overflow: visible;
}
.woocommerce div.product .woocommerce-tabs ul.tabs::before,
.woocommerce div.product .woocommerce-tabs ul.tabs::after,
.woocommerce div.product .woocommerce-tabs ul.tabs li::before,
.woocommerce div.product .woocommerce-tabs ul.tabs li::after {
	display: none;
}
.woocommerce div.product .woocommerce-tabs ul.tabs li {
	margin: 0;
	padding: 0;
	background: none;
	border: 0;
	border-radius: 0;
}
.woocommerce div.product .woocommerce-tabs ul.tabs li a {
	display: block;
	color: var(--chxn-ink-2);
	font-weight: 700;
	font-size: 14.5px;
	text-transform: none;
	padding: 13px 16px;
	border-bottom: 3px solid transparent;
	margin-bottom: -1px;
}
.woocommerce div.product .woocommerce-tabs ul.tabs li.active a {
	color: var(--chxn-green-d);
	border-bottom-color: var(--chxn-green);
}
.woocommerce-tabs .panel {
	padding: 26px 2px;
	text-align: justify;
}

/* ---- reviews tab — detail.dc.html spec: amber stars, one flat card
   per review (name left / date right / stars / text), tinted form card
   with pill submit. WC core's own "#reviews #comments ol.commentlist"
   skin (double-id selectors: 32px absolute avatar over a bordered
   .comment-text with margin-left) outranks plain #reviews rules, so the
   overrides below match that exact shape. ---- */
.woocommerce-Reviews-title {
	font-size: 15px;
	font-weight: 700;
	color: var(--chxn-ink);
	margin: 0 0 16px;
}
#reviews .commentlist {
	list-style: none;
	margin: 0;
	padding: 0;
	max-width: 680px;
	display: flex;
	flex-direction: column;
	gap: 12px;
}
.woocommerce #reviews #comments ol.commentlist li {
	margin: 0;
}
/* design has no avatar column (every review shows the store-account
   fallback silhouette anyway — pure noise) */
.woocommerce #reviews #comments ol.commentlist li img.avatar {
	display: none;
}
.woocommerce #reviews #comments ol.commentlist li .comment-text {
	margin: 0;
	border: 1px solid var(--chxn-line);
	border-radius: 12px;
	padding: 16px 20px;
	background: var(--chxn-card);
}
#reviews .comment-text .star-rating {
	float: none;
	margin: 0 0 6px;
	color: var(--chxn-amber);
	font-size: 13px;
}
#reviews .comment-text .meta {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 6px;
	margin: 0 0 6px;
	font-size: 13px;
}
#reviews .woocommerce-review__author {
	font-size: 14px;
	font-weight: 700;
	font-style: normal;
	color: var(--chxn-ink);
}
#reviews .woocommerce-review__verified {
	font-size: 12px;
	font-style: normal;
	color: var(--chxn-ink-2);
}
#reviews .woocommerce-review__dash {
	display: none;
}
#reviews .woocommerce-review__published-date {
	margin-left: auto;
	font-size: 12px;
	color: var(--chxn-ink-2);
}
#reviews .comment-text .description p {
	margin: 0;
	font-size: 13.5px;
	line-height: 1.7;
	color: var(--chxn-ink-2);
}
/* review form — tinted card, amber pick-a-star row, pill submit */
#review_form_wrapper {
	max-width: 680px;
	margin-top: 18px;
}
#reviews #respond {
	background: var(--chxn-bg);
	border: 0;
	border-radius: 14px;
	padding: 20px 22px;
}
#reviews #respond .comment-reply-title {
	display: block;
	font-size: 15px;
	font-weight: 700;
	color: var(--chxn-ink);
	margin: 0 0 10px;
}
#reviews #respond label {
	display: block;
	font-size: 13px;
	font-weight: 600;
	color: var(--chxn-ink);
	margin: 0 0 6px;
}
#reviews #respond p {
	margin: 0 0 12px;
}
#reviews #respond p.stars a {
	color: var(--chxn-amber);
}
#reviews #respond input[type="text"],
#reviews #respond input[type="email"],
#reviews #respond textarea {
	width: 100%;
	box-sizing: border-box;
	background: var(--chxn-card);
	border: 1px solid var(--chxn-line);
	border-radius: 9px;
	padding: 11px 13px;
	font-size: 14px;
	font-family: inherit;
	color: var(--chxn-ink);
	box-shadow: none;
}
#reviews #respond input:focus,
#reviews #respond textarea:focus {
	outline: none;
	border-color: var(--chxn-green);
}
#reviews #respond .form-submit {
	margin: 4px 0 0;
}
#reviews #respond .form-submit .submit {
	background: var(--chxn-green);
	color: #fff;
	border: 0;
	padding: 12px 26px;
	font-size: 13.5px;
	font-weight: 700;
	cursor: pointer;
}
#reviews #respond .form-submit .submit:hover {
	background: var(--chxn-green-d);
}
#review_form .review-form-inner.has-border {
	border: 0;
	padding: 0;
}
.woocommerce-verification-required {
	font-size: 13px;
	color: var(--chxn-ink-2);
}

/* ==== related products — full-width cream-tinted, full-bleed section ==== */
.related.products {
	background: var(--chxn-cream);
	border-top: 1px solid var(--chxn-line);
	margin-top: 28px;
	padding: 40px 0;
	width: 100vw;
	position: relative;
	left: 50%;
	right: 50%;
	margin-left: -50vw;
	margin-right: -50vw;
	list-style: none;
}
.related.products h2 {
	max-width: var(--chxn-container);
	margin: 0 auto 20px;
	padding: 0 20px;
	box-sizing: border-box;
	font-size: 21px;
	font-weight: 800;
}
/* the sliding "track" — modules/product-gallery.js's clone-buffer
   infinite carousel (see setupScroller()). WooCommerce's related-products
   template outputs the SAME ".products" wrapper class the shop archive
   uses (components/product-card.css: "ul.products{display:grid}") — the
   3-part selector here (vs. that rule's 1-part "ul.products") wins on
   specificity to turn it into a flex track instead, scoped to just this
   section. Shares this with ".chxn-seen-grid" below (same shortcode
   output, same carousel).
   The "> li" rule further down sizes each card as "(100% - 3*20px) / 4" —
   math that only comes out to exactly 4 full cards per screen if a 20px
   "gap" is actually reserved BETWEEN them. Without declaring one here,
   the 4 cards sat flush against each other instead, together falling
   ~60px short of the full track width — leaving a sliver of the 5th
   card visible at the edge (looked like a deliberate "peek the next
   item" hint, but was really just unclaimed width from a gap that was
   assumed in the size math but never applied). */
.related.products ul.products,
.chxn-seen-grid ul.products {
	display: flex !important;
	flex-wrap: nowrap;
	gap: 20px;
	overflow: visible;
	margin: 0;
	padding: 0;
	transition: transform .4s ease;
}
.related.products ul.products > li,
.chxn-seen-grid ul.products > li {
	flex-shrink: 0;
	/* without an explicit width, a flex item with "flex-shrink:0" and no
	   basis sizes to its own CONTENT — and ".chxn-product-card-media img
	   {width:100%}" has nothing to be 100% OF in that case, so the whole
	   card (and its image) blew up to a huge intrinsic size instead of
	   sharing the row evenly. modules/product-gallery.js's setupScroller()
	   uses VISIBLE=4. */
	width: calc((100% - 3 * 20px) / 4) !important;
}
@media (max-width: 1100px) {
	.related.products ul.products > li,
	.chxn-seen-grid ul.products > li {
		width: calc((100% - 2 * 20px) / 3) !important;
	}
}
@media (max-width: 850px) {
	.related.products ul.products > li,
	.chxn-seen-grid ul.products > li {
		width: calc((100% - 20px) / 2) !important;
	}
}
/* wrapper injected by product-gallery.js around the track, so the round
   scroll buttons can be positioned relative to it. */
.chxn-related-scroll-wrap {
	position: relative;
	max-width: var(--chxn-container);
	margin: 0 auto;
	padding: 0 20px;
	box-sizing: border-box;
}
/* the actual clip boundary — deliberately separate from
   ".chxn-related-scroll-wrap": overflow:hidden clips at an element's
   PADDING edge, not its content edge, so clipping directly on the
   padded/centered wrap lets a sliver of the neighboring clone card bleed
   through that padding. */
.chxn-related-scroll-viewport {
	overflow: hidden;
}
.chxn-related-scroll-btn {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 3;
	width: 40px;
	height: 40px;
	/* same base.css "button{border-radius:pill!important}" fix as the
	   coupon chips / variant swatches — without !important here this
	   renders as a full circle/pill instead of a rounded square. */
	border-radius: 12px !important;
	border: 1px solid var(--chxn-line);
	background: var(--chxn-card);
	box-shadow: 0 4px 14px rgba(0, 0, 0, .12);
	font-size: 18px;
	line-height: 1;
	color: var(--chxn-ink);
	cursor: pointer;
	font-family: inherit;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	margin: 0;
	box-sizing: border-box;
}
.chxn-related-scroll-btn:hover {
	border-color: var(--chxn-green);
	color: var(--chxn-green-d);
}
/* ".chxn-related-scroll-wrap"'s own 20px side padding is where the visible
   track/images actually start — a button centered right on THAT boundary
   (half its 40px width sitting in the empty padding gutter, half
   overlapping onto the first/last product image) reads as a classic
   carousel arrow cutting into the photo, rather than floating off to the
   side of it. */
.chxn-related-scroll-prev {
	left: 0;
}
.chxn-related-scroll-next {
	right: 0;
}
@media (max-width: 850px) {
	/* NOT "display:none" — the related/recently-viewed tracks scroll only
	   via these buttons' click handler (modules/product-gallery.js's
	   setupScroller(), driving a CSS transform); the viewport clipping
	   them has no native touch-scroll fallback of its own, so hiding the
	   only way to advance left both carousels stuck on their first
	   screenful on mobile. */
	.chxn-related-scroll-btn {
		width: 32px;
		height: 32px;
		font-size: 15px;
	}
}

/* ---- "Sản phẩm đã xem" (recently viewed) — after related products. This
   whole single-product content area sits inside "<main id=chxn-main
   class=chxn-container>" (max-width:1240px, 20px side padding) —
   ".related.products" escapes that with its own 100vw/negative-margin
   full-bleed trick so ITS inner wrap can re-center at the TRUE full
   1240px container width, but this section never did the same, so its
   own "max-width:var(--chxn-container)" below could only ever resolve
   within the ALREADY-narrowed ~1200px left inside <main> — 40px narrower
   than the related-products track above it, and off by that same 40px
   from the site's actual standard container width. */
.chxn-seen-section {
	width: 100vw;
	position: relative;
	left: 50%;
	right: 50%;
	margin-left: -50vw;
	margin-right: -50vw;
}
.chxn-seen-inner {
	max-width: var(--chxn-container);
	margin: 0 auto;
	/* horizontal inset handled by the heading and the scroll wrap
	   independently below (not here) — this element's own 1240px box is
	   what the NESTED ".chxn-related-scroll-wrap" needs to be full width
	   itself before ITS OWN 20px padding narrows it down, matching
	   ".related.products"'s (unnested) wrap exactly. Padding here too
	   would narrow that available width by another 40px first.
	   Top value is 28px, not 40 — ".related.products" right above
	   already spends its own 40px bottom padding getting from its last
	   card down to here, so a matching 40px top here on top of THAT
	   stacked into a visibly bigger gap than the one leading into
	   "related products" itself (that section's own 28px margin-top +
	   40px padding-top, measured from the tabs above it). Matching the
	   28px keeps both gaps reading the same. */
	padding: 28px 0 40px;
	box-sizing: border-box;
}
.chxn-seen-inner h2 {
	font-size: 21px;
	font-weight: 800;
	margin: 0 0 20px;
	padding: 0 20px;
	box-sizing: border-box;
}

/* ==== YITH WooCommerce Frequently Bought Together — "Thường mua cùng" ==== */
.yith-wfbt-section {
	margin: 0 0 28px;
	background: var(--chxn-card);
	border: 1px solid var(--chxn-line);
	border-radius: var(--chxn-radius-card);
	padding: 20px 22px;
}
.yith-wfbt-section h3,
.yith-wfbt-section .yith-wfbt-title {
	font-size: 16px;
	font-weight: 800;
	color: var(--chxn-ink);
	margin: 0 0 14px;
	display: flex;
	align-items: center;
	gap: 8px;
}
.yith-wfbt-section h3::before,
.yith-wfbt-section .yith-wfbt-title::before {
	content: "🧺";
}
.yith-wfbt-section .yith-wfbt-form {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 16px 20px;
	/* the form's default bottom margin was ~46px of dead space inside the
	   card, under the checklist */
	margin: 0;
}
.yith-wfbt-section .yith-wfbt-images {
	float: none;
	border-collapse: separate;
	border-spacing: 0;
	flex: none;
}
.yith-wfbt-images .image-td {
	padding: 0;
}
.yith-wfbt-images .image-td a {
	display: block;
	width: 60px;
	height: 60px;
	border-radius: var(--chxn-radius-input);
	overflow: hidden;
	border: 1px solid var(--chxn-line);
}
.yith-wfbt-images .image-td img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.yith-wfbt-section .yith-wfbt-images .image_plus {
	width: auto;
	color: var(--chxn-ink-2);
	font-weight: 700;
	font-size: 16px;
	padding: 0 8px;
	text-align: center;
}
.yith-wfbt-submit-block {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	flex: 1 1 auto;
	gap: 14px;
	min-width: 260px;
}
.yith-wfbt-submit-block .price_text {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 4px 10px;
	font-size: 13.5px;
	color: var(--chxn-ink-2);
}
.yith-wfbt-submit-block .total_price_label {
	font-weight: 600;
}
.yith-wfbt-submit-block .total_price {
	font-size: 18px;
	font-weight: 800;
	color: var(--chxn-red);
}
.yith-wfbt-submit-block .total_price .amount {
	color: var(--chxn-red);
}
.yith-wfbt-submit-block .total_price ins {
	text-decoration: none;
}
.yith-wfbt-submit-block .total_price del {
	font-size: 13px;
	font-weight: 400;
	color: var(--chxn-ink-2);
	margin-right: 4px;
	text-decoration: line-through;
}
.yith-wfbt-section .yith-wfbt-submit-block .save-amount {
	display: flex;
	align-items: center;
	gap: 4px;
	margin: 0;
	background: #fdece8;
	color: var(--chxn-red);
	font-size: 12px;
	font-weight: 700;
	padding: 3px 9px;
	border-radius: var(--chxn-radius-pill);
}
.yith-wfbt-section .yith-wfbt-submit-block .save-amount::before {
	content: "🎉";
	font-size: 11px;
}
.yith-wfbt-section .yith-wfbt-submit-button.button {
	background: var(--chxn-green) !important;
	border: 0 !important;
	color: #fff !important;
	border-radius: var(--chxn-radius-pill) !important;
	padding: 13px 26px !important;
	font-size: 14px;
	font-weight: 700;
	text-transform: none;
	white-space: nowrap;
	display: flex;
	align-items: center;
	gap: 8px;
}
.yith-wfbt-section .yith-wfbt-submit-button.button::before {
	content: "🛒";
}
.yith-wfbt-section .yith-wfbt-submit-button.button:hover {
	background: var(--chxn-green-d) !important;
}
.yith-wfbt-section .yith-wfbt-items {
	list-style: none;
	display: flex;
	flex-basis: 100%;
	flex-wrap: wrap;
	gap: 6px 20px;
	margin: 14px 0 0;
	padding-top: 12px;
	padding-left: 0;
	border-top: 1px solid var(--chxn-line);
}
.yith-wfbt-items .yith-wfbt-item {
	padding: 0;
	margin-bottom: 0;
	border-top: 0;
	flex: 0 1 auto;
	min-width: 0;
	width: auto;
}
.yith-wfbt-items .yith-wfbt-item label {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	min-width: 0;
	gap: 8px;
	font-size: 12.5px;
	color: var(--chxn-ink);
	cursor: pointer;
}
.yith-wfbt-items .yith-wfbt-item input[type="checkbox"] {
	accent-color: var(--chxn-green);
	width: 15px;
	height: 15px;
	flex: none;
	margin: 0 2px 0 0;
}
.yith-wfbt-items .yith-wfbt-item .product-name {
	font-weight: 600;
	color: var(--chxn-green-d);
}
.yith-wfbt-items .yith-wfbt-item a {
	color: var(--chxn-ink);
}
.yith-wfbt-items .yith-wfbt-item a:hover .product-name {
	color: var(--chxn-green-d);
}
.yith-wfbt-items .yith-wfbt-item .price {
	font-size: 13px;
	color: var(--chxn-red);
	font-weight: 700;
	background: none;
	border: 0;
	padding: 0;
}
.yith-wfbt-items .yith-wfbt-item .price ins {
	color: var(--chxn-red);
	text-decoration: none;
	font-weight: 700;
}
/* YITH builds each row's price from the product's full price_html — which
   on this site also carries business-logic.php's "Giá:" prefix, the
   struck-through old price, the "-N%" sale badge (position:absolute via
   product-card.css's shared rule, so here it lands ON TOP of the row's
   own text) and the "💰 Tiết kiệm" pill. detail.dc.html's checklist rows
   are just "name + current price"; everything else is noise at this size
   (the bundle's own savings pill already sits next to the total above). */
/* "del" needs the extra ".woocommerce div.product ... span.price" shape:
   core's own "div.product span.price del{display:inline-block}" is 1
   element more specific than a plain ".yith-wfbt-item .price del" and
   was re-showing it. */
.woocommerce div.product .yith-wfbt-items span.price del,
.yith-wfbt-items .yith-wfbt-item .price .devvn_woocommerce_price_prefix,
.yith-wfbt-items .yith-wfbt-item .price .chxn-badge-sale,
.yith-wfbt-items .yith-wfbt-item .price .chxn-product-save {
	display: none;
}
