/*
Theme Name: WoodMart Child
Template: woodmart
Version: 1.0.0
Text Domain: woodmart-child
*/

/* ==========================================================================
   CosmoTouch branding — logo sizing
   The CosmoTouch script logo is chunkier than the demo logo (which was ~26px
   tall). Cap the rendered height so it sits cleanly in the header/footer rows.
   ========================================================================== */

/* Header logo (main + sticky + mobile all use .wd-logo) */
.site-logo .wd-logo img,
.wd-logo img {
	max-height: 86px;   /* +30% (was 66px) */
	width: auto;
	height: auto;
}

/* Sticky header: slightly smaller */
.whb-sticky-row .wd-logo img {
	max-height: 70px;   /* +30% (was 54px) */
}

/* Footer logo (Elementor wd_image_or_svg widget in the "Footer Makeup" block) */
.elementor-element-8a1081d img {
	max-height: 75px;   /* +30% (was 58px) */
	width: auto;
	height: auto;
}

/* Mobile header row is ~60px — keep the logo within it */
@media (max-width: 1024px) {
	.wd-logo img {
		max-height: 60px;   /* +30% (was 46px) */
	}
}

/* ==========================================================================
   CosmoTouch category pages — subcategory cards + "Shop by Concern" chips
   Soft-pink / no-blue palette (placeholder values — swap when the brand kit
   is locked). Scoped to .ct-* so nothing else is affected. RTL-aware.
   ========================================================================== */

:root {
	--ct-pink:        #e26a8d;  /* accent / active */
	--ct-pink-strong: #c94f74;  /* hover */
	--ct-pink-soft:   #fbe9ef;  /* chip / tile background */
	--ct-pink-line:   #f2cdd9;  /* borders */
	--ct-ink:         #33272c;  /* text on soft pink */
	--ct-radius:      14px;
}

/* ---- Subcategory image-card scroller ------------------------------------ */
/* Centered when the row fits the width; horizontally scrollable with prev/next
   arrows (revealed by JS) when it overflows. */
.ct-subcat-scroller {
	position: relative;                 /* anchor for the overlay arrows */
	margin: 0 0 28px;
}

.ct-subcat-grid {
	display: flex;
	gap: 14px;
	overflow-x: auto;
	justify-content: safe center;       /* center when it fits; align to start when overflowing */
	scroll-behavior: smooth;
	scroll-snap-type: x proximity;
	scroll-padding-inline: 44px;        /* keep snapped tiles clear of the arrows */
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;              /* Firefox — the arrows are the affordance */
	padding-bottom: 2px;
}
.ct-subcat-grid::-webkit-scrollbar { display: none; }   /* WebKit/Blink */

.ct-subcat-card {
	flex: 0 0 84px;                     /* fixed tile width; never shrink */
	scroll-snap-align: start;
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	text-decoration: none;
	color: var(--ct-ink);
}

/* Prev/next arrows — start hidden; JS reveals them only when the row overflows.
   Scoped + !important on the visual props because WooCommerce/WoodMart's generic
   `.woocommerce button` styles otherwise reset the border/radius/background. */
.ct-subcat-scroller .ct-subcat-arrow {
	position: absolute;
	top: 42px;                          /* vertical centre of the 84px tile media */
	transform: translateY(-50%);
	z-index: 2;
	width: 38px !important;
	height: 38px !important;
	min-width: 0 !important;
	padding: 0 !important;
	border: 2px solid #fff !important;          /* white ring separates it from photo tiles */
	border-radius: 50% !important;
	background: var(--ct-pink) !important;       /* solid pink reads on any background */
	color: #fff;                                 /* white chevron */
	display: flex;
	align-items: center;
	justify-content: center;
	line-height: 1;
	cursor: pointer;
	box-shadow: 0 2px 10px rgba(51, 39, 44, .3) !important;   /* neutral lift over tiles + band */
	transition: background .15s ease, color .15s ease, box-shadow .15s ease, opacity .15s ease;
}
.ct-subcat-scroller .ct-subcat-arrow--prev { inset-inline-start: -2px; }   /* start side (LTR: left, RTL: right) */
.ct-subcat-scroller .ct-subcat-arrow--next { inset-inline-end: -2px; }     /* end side */
/* Chevron drawn with borders (no glyph/SVG dependency) */
.ct-subcat-scroller .ct-subcat-arrow::before {
	content: "";
	width: 9px;
	height: 9px;
	border: solid currentColor;
	border-width: 2.5px 2.5px 0 0;      /* top + right → a corner */
	transform: rotate(45deg);           /* points right (next) */
	margin-left: -3px;
}
.ct-subcat-scroller .ct-subcat-arrow--prev::before {
	transform: rotate(-135deg);         /* points left (prev) */
	margin-left: 3px;
}
.ct-subcat-scroller .ct-subcat-arrow:hover:not(:disabled) {
	background: var(--ct-pink-strong) !important;
	color: #fff;
	box-shadow: 0 4px 14px rgba(51, 39, 44, .38) !important;
}
.ct-subcat-scroller .ct-subcat-arrow:disabled {
	background: #fff !important;
	color: var(--ct-pink);
	border-color: var(--ct-pink-line) !important;
	opacity: .6;
	cursor: default;
	box-shadow: 0 1px 4px rgba(51, 39, 44, .15) !important;
}
.ct-subcat-scroller .ct-subcat-arrow[hidden] { display: none !important; }

.ct-subcat-card__media {
	display: block;
	width: 100%;
	aspect-ratio: 1 / 1;
	border-radius: var(--ct-radius);
	overflow: hidden;
	background: var(--ct-pink-soft);
	border: 1px solid var(--ct-pink-line);
	transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}

.ct-subcat-card__media img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	object-position: center;
	display: block;
}

.ct-subcat-card:hover .ct-subcat-card__media {
	transform: translateY(-3px);
	border-color: var(--ct-pink);
	box-shadow: 0 8px 22px rgba(226, 106, 141, .22);
}

/* Placeholder tile (no term image, no product image) */
.ct-subcat-card__placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	font-size: 1.5rem;
	font-weight: 700;
	color: var(--ct-pink);
	background: linear-gradient(135deg, #fdeef3 0%, #f7d9e4 100%);
}

.ct-subcat-card__label {
	display: block;
	margin-top: 10px;
	font-size: .9rem;
	font-weight: 600;
	line-height: 1.3;
}

/* ---- Chip rows ----------------------------------------------------------- */
/* One shared look for both rows: "Shop by Concern" (--concern) on every category
   archive, and the subcategory links (--subcat) on subcategory pages, which use
   chips instead of tiles because level-3 terms have no artwork. */
.ct-chips {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin: 0 0 24px;
}

/* The subcategory row sits above the concern row — give it the tile grid's
   breathing space so the two rows don't read as one block. */
.ct-chips--subcat { margin-bottom: 28px; }

.ct-chips__label {
	font-weight: 700;
	font-size: .95rem;
	color: var(--ct-ink);
	margin-inline-end: 4px;
}

.ct-chip {
	display: inline-block;
	padding: 7px 15px;
	border-radius: 999px;
	font-size: .85rem;
	line-height: 1.2;
	text-decoration: none;
	color: var(--ct-pink-strong);
	background: var(--ct-pink-soft);
	border: 1px solid var(--ct-pink-line);
	transition: background .15s ease, color .15s ease, border-color .15s ease;
	white-space: nowrap;
}

.ct-chip:hover {
	background: #f7d9e4;
	color: var(--ct-pink-strong);
	border-color: var(--ct-pink);
}

.ct-chip.is-active {
	background: var(--ct-pink);
	color: #fff;
	border-color: var(--ct-pink);
}

/* On small screens let the chips scroll horizontally instead of wrapping tall */
@media (max-width: 767px) {
	.ct-chips {
		flex-wrap: nowrap;
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
		padding-bottom: 4px;
	}
	.ct-chips::-webkit-scrollbar { display: none; }
	.ct-chips__label { flex: 0 0 auto; }
	.ct-chip { flex: 0 0 auto; }
}

/* RTL: flex/grid and logical properties handle direction; nudge the label gap */
html[dir="rtl"] .ct-subcat-card__label,
body.rtl .ct-subcat-card__label {
	direction: rtl;
}

/* RTL: the scroller row reverses naturally (prev ends up on the right); flip the
   chevrons so prev (toward start) points right and next (toward end) points left */
html[dir="rtl"] .ct-subcat-arrow--prev::before,
body.rtl .ct-subcat-arrow--prev::before {
	transform: rotate(45deg);
	margin-left: -2px;
}
html[dir="rtl"] .ct-subcat-arrow--next::before,
body.rtl .ct-subcat-arrow--next::before {
	transform: rotate(-135deg);
	margin-left: 2px;
}

/* ==========================================================================
   Homepage "Enough With Acne" promo banner (Home Makeup, post 167)
   The section background was recoloured from the demo's blue to soft rose.
   The demo's title/body used a light (white) content skin meant for a busier
   backdrop; on the pale rose it fails contrast, so force readable dark ink.
   Scoped to the two Elementor element IDs — pill (#E26A8D, white text) and the
   "Shop Now" button are intentionally left untouched.
   ========================================================================== */
.elementor-element-d9f6498,
.elementor-element-d9f6498 .title,
.elementor-element-d9f6498 .liner-title,
.elementor-element-d9f6498 * {
	color: var(--ct-ink); /* #33272c — title */
}
.elementor-element-de9a96a,
.elementor-element-de9a96a p,
.elementor-element-de9a96a * {
	color: #5b4650; /* softer ink for the body copy — still ~7:1 on the rose */
}

/* The SALISES product image (widget #cc1a502) sat at 190px inside a row made tall
   by the before/after face shot beside it, so it floated small with wide empty
   space above and below. Enlarge it +30% so it fills the row and closes that gap.
   Display-only: the image FILE is untouched. Elementor sets `img{width:190px}` with
   no !important (specificity 0,3,1), so this scoped !important override wins.
   Desktop only — the banner stacks on tablet/mobile where Elementor's own smaller
   width still fits. */
@media (min-width: 1025px) {
	.elementor-element-cc1a502 img {
		width: 247px !important;   /* +30% (was 190px) */
		max-width: 247px !important;
		height: auto !important;
		/* Nudge left toward the copy, into the pink gap between the text column and
		   the product. translateX (not a margin) so it shifts visually without
		   reflowing the row; PHYSICAL left on purpose — the banner art does not
		   mirror for RTL, so a logical margin would push it the wrong way there. */
		transform: translateX(-40px);
	}
}

/* ==========================================================================
   Homepage hero — "Shop by category" vertical list (left of the main slider)
   Replaces the demo mega-menu. Each row = large category label + a soft-pink
   circular icon tile, matching the WoodMart Makeup demo layout. 7 categories.
   ========================================================================== */
.ct-hero-cats {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 16px;
	padding: 6px 0;
}
.ct-hero-cat {
	display: inline-flex;
	align-items: center;
	gap: 14px;
	max-width: 100%;        /* never wider than the list column */
	min-width: 0;
	text-decoration: none;
	color: var(--ct-ink);
	transition: color .16s ease;
}
.ct-hero-cat__label {
	font-size: clamp(1.05rem, 1.75vw, 1.7rem);  /* scales with viewport so long labels fit */
	font-weight: 600;
	line-height: 1.2;
	letter-spacing: .2px;
	min-width: 0;
	/* NOTE: intentionally allow wrapping — the label must never be clipped by the
	   slider. clamp keeps it on one line at normal widths; it wraps only as a
	   last resort at extreme sizes. */
}
.ct-hero-cat__circle {
	order: -1;            /* circle before the label — icons line up in a column on the left */
	flex: 0 0 auto;
	width: clamp(44px, 3.4vw, 54px);
	height: clamp(44px, 3.4vw, 54px);
	border-radius: 50%;
	overflow: hidden;
	display: block;
	box-shadow: 0 2px 8px rgba(226, 106, 141, .14);
	transition: transform .18s ease, box-shadow .18s ease;
}
.ct-hero-cat__circle img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.ct-hero-cat:hover { color: var(--ct-pink); }
.ct-hero-cat:hover .ct-hero-cat__circle {
	transform: scale(1.09);
	box-shadow: 0 8px 20px rgba(226, 106, 141, .30);
}
/* Desktop side-by-side (Elementor keeps the hero as a row above 1024px): the demo's
   25% list column is too narrow for our longer labels ("Manicure & Pedicure") and they
   slid under the slider. Widen the list column so they always fit. Below 1024px the hero
   stacks (Elementor tablet = 100% cols), so no override is needed there. */
@media (min-width: 1025px) {
	.elementor-element-935df71 { width: 28% !important; flex-basis: 28% !important; }
	.elementor-element-2a4147a { width: 72% !important; flex-basis: 72% !important; }
}
/* Tablet & down — list is full-width above the slider, so give it comfortable sizing */
@media (max-width: 1024px) {
	.ct-hero-cat__label { font-size: 1.55rem; }
	.ct-hero-cat__circle { width: 52px; height: 52px; }
}
@media (max-width: 575px) {
	.ct-hero-cats { gap: 12px; }
	.ct-hero-cat__label { font-size: 1.25rem; }
	.ct-hero-cat__circle { width: 46px; height: 46px; }
}

/* ==========================================================================
   CosmoTouch header — main category nav on its own full-width row
   The 7-category main menu sits alone in the WoodMart "Header bottom" row
   (that row's "Hidden on mobile" setting keeps the burger on phones). Force it
   to ONE centered line so it never wraps to two layers on laptop / small-desktop
   widths. Item spacing itself is set natively on the element (Main menu → Style →
   "items gap"); this only enforces single-line + centering + a mid-range text
   nudge. `.wd-nav-main` is unique to the main menu, so no builder class is
   needed. EN-only for now (AR menu deferred); flex + WoodMart RTL handle RTL.
   ========================================================================== */
.wd-nav.wd-nav-main {
	flex-wrap: nowrap;            /* never stack to a second line */
	justify-content: center;     /* center the 7 items in the full-width row */
}

/* Mid-range: shrink the label a touch so 7 items stay easy on ~1025–1200px */
@media (min-width: 1025px) and (max-width: 1200px) {
	.wd-nav.wd-nav-main > li.item-level-0 > a {
		font-size: 14px;
	}
}

/* ==========================================================================
   Homepage hero "Free Delivery" marquee (Home Makeup, post 167, el #bdf3402)
   The WoodMart marquee is an absolutely-positioned Elementor widget whose
   compiled CSS only sets `left:0; bottom:0` (no width), so its black bar
   shrinks to the scrolling content instead of spanning the hero. Anchor it to
   both edges so it stretches the full hero width. Works LTR + RTL.
   ========================================================================== */
.elementor-167 .elementor-element.elementor-element-bdf3402 {
	left: 0 !important;
	right: 0 !important;
	width: auto !important;
}

/* ==========================================================================
   Homepage hero slider — FLUID title & subtitle (post 167, slider #cbba82e)
   Each slide's title was a fixed 52px that hard-jumped to 40px (tablet) / 28px
   (mobile), so the heading looked proportionally different at each screen size
   and snapped abruptly at breakpoints. Replace with clamp() so it scales
   smoothly with the viewport — consistent look at every size. Overrides the
   per-slide Elementor font-size rules (need !important). Scoped to the hero
   section so no other slider/title is affected.
   ========================================================================== */
.elementor-element-6c9c1e8 .woodmart-title-container.title {
	font-size: clamp(1.75rem, 1.35rem + 2.05vw, 3.3rem) !important;  /* ~28px → ~52px @1440 → cap ~53px */
	line-height: 1.15 !important;
}
.elementor-element-6c9c1e8 .wd-slide .wd-text-block,
.elementor-element-6c9c1e8 .wd-slide .woodmart-text-block,
.elementor-element-6c9c1e8 .wd-slide p {
	font-size: clamp(0.85rem, 0.78rem + 0.4vw, 1.05rem) !important;  /* subtitle scales gently with the title */
}

/* Slide #225 "Care for Every Concern" — its long title used a fixed 615px text
   zone that ran into the product/glass area on the right (reached 53–68% of the
   slide; products start ~52%). Cap the text container to the left ~44% of the
   slide so the title wraps and always clears the products; balance the two lines.
   %-width is relative to the SLIDE (the slider is only part of the page width, so
   vw would be wrong here). On phones the products are less prominent, so relax. */
.elementor-element-8e9a203 {
	max-width: 44% !important;
	/* the container is "boxed" (auto-centered); capping its width would center it,
	   so pin it to the left so the text stays in the left zone */
	margin-inline-start: 0 !important;
	margin-inline-end: auto !important;
	align-self: flex-start !important;
}
.elementor-element-474e93e { max-width: 100% !important; }
.elementor-element-474e93e .woodmart-title-container.title { text-wrap: balance; }
@media (max-width: 600px) {
	.elementor-element-8e9a203 { max-width: 90% !important; }
}

/* ==========================================================================
   CosmoTouch product page (Keune touches) — inc/product-page.php +
   woocommerce/single-product/rating.php. Soft-pink / no-blue palette tokens,
   scoped to .ct-*, RTL-aware (logical properties). See the category-page block
   above for the shared --ct-* tokens.
   ========================================================================== */

/* ---- Always-visible star rating (empty + "be the first") ---------------- */
/* The star glyphs come from WooCommerce's star-rating font; we only tint the
   empty outline to soft pink and style the invite link. */
.ct-rating-empty {
	display: inline-block;
	vertical-align: middle;
	color: var(--ct-pink-line);          /* outline stars, on-brand (not grey) */
}
.woocommerce-product-rating .ct-review-link {
	margin-inline-start: 8px;
	vertical-align: middle;
	color: var(--ct-pink);
	font-size: 13px;
}
.woocommerce-product-rating .ct-review-link:hover {
	color: var(--ct-pink-strong);
}

/* ---- Display-only "Size" box (pa_volume) -------------------------------- */
.ct-volume {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 4px 0 20px;
}
.ct-volume__label {
	font-size: 12px;
	font-weight: 600;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--ct-ink);
	opacity: .75;
}
.ct-volume__boxes {
	display: inline-flex;
	flex-wrap: wrap;
	gap: 8px;
}
.ct-volume__box {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 54px;
	padding: 7px 14px;
	border: 1.5px solid var(--ct-pink-line);
	border-radius: 10px;
	background: var(--ct-pink-soft);
	color: var(--ct-ink);
	font-size: 14px;
	font-weight: 600;
	line-height: 1;
}

/* ---- Content tabs: Description · How to Use · Ingredients ---------------- */
.ct-product-tab {
	line-height: 1.7;
	color: #5b4650;                      /* body ink used elsewhere in this theme */
}
.ct-product-tab p { margin: 0 0 1em; }
.ct-product-tab p:last-child { margin-bottom: 0; }

/* ---- Brand archive header (inc/brand-page.php) -------------------------- *
 * The brand NAME is intentionally absent here — the WoodMart archive layout
 * already prints it as the page title. This block adds the logo + copy above
 * the grid. Logical properties keep it correct in RTL without a mirror rule. */
.ct-brand-header {
	display: flex;
	align-items: center;
	gap: 24px;
	flex-wrap: wrap;
	margin: 0 0 24px;
	padding: 20px 24px;
	background: var(--ct-pink-soft);
	border: 1px solid var(--ct-pink-line);
	border-radius: var(--ct-radius);
}
/* The supplied logos are flattened onto WHITE (no alpha), so they would read as
   stray white rectangles on the pink band. Presenting them on a white card makes
   that background deliberate and works for any future transparent logo too. */
.ct-brand-header__logo {
	flex: 0 0 auto;
	width: 180px;
	max-width: 45%;
	padding: 12px 16px;
	background: #fff;
	border-radius: calc(var(--ct-radius) - 4px);
	box-shadow: 0 1px 3px rgba(51, 39, 44, .08);
}
.ct-brand-header__logo img {
	display: block;
	width: 100%;
	height: auto;
	/* Logos differ in aspect ratio (672x226 .. 198x232) — contain keeps each
	   whole instead of cropping one of them. */
	object-fit: contain;
}
.ct-brand-header__text {
	flex: 1 1 260px;
	min-width: 0;
	color: var(--ct-ink);
}
.ct-brand-header__desc {
	line-height: 1.7;
}
.ct-brand-header__desc p:last-child { margin-bottom: 0; }
.ct-brand-header__empty {
	margin: 0;
	font-size: 15px;
	color: var(--ct-pink-strong);
}

@media (max-width: 576px) {
	.ct-brand-header {
		gap: 16px;
		padding: 16px;
	}
	.ct-brand-header__logo { width: 120px; }
}

/* ---- Brands landing page grid ([cosmotouch_brands], inc/brands-page.php) --- *
 * The /brands/ page the header's "Brand" item points at. ONE white card, not a
 * white logo panel nested in a pink one — the logos are flattened onto white, so a
 * pink card always shows a second frame around them and the double border reads as
 * clutter (client, 2026-07-21). Pink survives only as the hairline border, the
 * hover, and the product count. Logical properties throughout, so RTL needs no
 * mirror rule. */
.ct-brands-grid {
	display: grid;
	grid-template-columns: repeat(var(--ct-brands-cols, 3), minmax(0, 1fr));
	gap: 24px;
	margin: 0 0 32px;
}
.ct-brand-card {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 14px;
	padding: 28px 24px 22px;
	background: #fff;
	border: 1px solid var(--ct-pink-line);
	border-radius: var(--ct-radius);
	text-align: center;
	transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
.ct-brand-card:hover,
.ct-brand-card:focus-visible {
	border-color: var(--ct-pink);
	box-shadow: 0 6px 18px rgba(51, 39, 44, .10);
	transform: translateY(-2px);
}
.ct-brand-card__media {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	/* Ratio, not a fixed height: prep_brand_logos.py normalises every logo onto ONE
	   900x560 canvas (a width-biased shared size inside it), so matching that 45:28
	   here lets the artwork fill the box edge to edge instead of being letterboxed to
	   its own aspect — which is what made the row look ragged when each logo kept its
	   own. Was 15:7, until that shape proved too short for Sadeen's stacked lockup to
	   reach the shared size (2026-07-21) — keep this in step with CANVAS_W/CANVAS_H. */
	aspect-ratio: 45 / 28;
	/* No background/border of its own: the card is already white, so a panel here
	   would just draw the inner frame this design got rid of. */
}
.ct-brand-card__media img {
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	object-fit: contain;
}
.ct-brand-card__fallback {
	font-size: 20px;
	font-weight: 600;
	color: var(--ct-ink);
}
.ct-brand-card__meta {
	display: flex;
	flex-direction: column;
	gap: 4px;
}
.ct-brand-card__name {
	font-size: 17px;
	font-weight: 600;
	color: var(--ct-ink);
}
.ct-brand-card__count {
	font-size: 14px;
	color: var(--ct-pink-strong);
}

@media (max-width: 768px) {
	.ct-brands-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 16px;
	}
	.ct-brand-card { padding: 18px 16px 14px; }
}

/* ---- Brand banner strip (brand archive hero) ----------------------------- */
/* inc/brand-banner.php — a wide cinematic shot opening `/brand/<slug>/`.
   The art is composed with negative space on the LEFT,
   so the CTA is pinned bottom-left; on narrow screens the image is cropped to a
   friendlier ratio with object-position pushed right, keeping the products (which
   sit on the right of every shot) in frame while the CTA moves under them. */

.ct-bb {
	position: relative;
	margin: 40px 0 8px;
	border-radius: var(--ct-radius);
	overflow: hidden;
	background: var(--ct-pink-soft);   /* holds the box while the image lazy-loads */
}
.ct-bb__track {
	display: grid;                     /* all slides stack in one cell -> no reflow */
}
.ct-bb__slide {
	grid-area: 1 / 1;
	position: relative;
	margin: 0;
	min-width: 0;
}
/* Two classes, not one: the strip lives inside the Elementor archive layout,
   whose `.elementor img { height: auto }` (0,1,1) outranks a lone
   `.ct-bb__img` (0,1,0) — the crops below silently did nothing until this
   was raised to (0,2,0). */
.ct-bb .ct-bb__img {
	display: block;
	width: 100%;
	/* The band is sized from the container WIDTH, not the viewport height. It used
	   to be `clamp(220px, 34vh, 360px)`, which kept the banner off the first screen
	   (client, 2026-07-21) but tied the crop to how TALL the window was — so the
	   same page framed the art differently on every screen, and a short window
	   sliced the nozzle off Sadeen's bottle. A ratio cannot do that: 4.8 keeps the
	   band at ~1/5 of the container (still nowhere near the first screen), it is
	   the same on every slide of a multi-banner brand, and Sadeen's art is built to
	   match it exactly (BANNER_CSS_AR in scripts/prep_brand_banners.py) so that
	   file lands here uncropped. The cap only bites past a ~2000px container, where
	   it eats that file's margin above the bottle rather than the bottle. */
	height: auto;
	aspect-ratio: 4.8;
	max-height: 420px;
	object-fit: cover;
	/* Anchored right, not centred: art wider than the band (Sadeen is built at
	   4.8 so its hand + bottle clear this crop — see BANNER_FRAME in
	   scripts/prep_brand_banners.py) is trimmed horizontally, and every shot puts
	   its products on the right and its negative space on the left, so the trim
	   must come off the left. Art narrower than the band is cropped vertically
	   instead, where this has no effect. */
	object-position: right center;
}
.ct-bb__cta {
	position: absolute;
	inset-inline-start: clamp(20px, 4vw, 56px);
	inset-block-end: clamp(18px, 3.5vw, 44px);
	z-index: 2;
	display: inline-block;
	padding: 12px 26px;
	border-radius: 999px;
	background: #fff;
	color: var(--ct-ink);
	font-size: clamp(0.85rem, 0.78rem + 0.35vw, 1rem);
	font-weight: 600;
	line-height: 1;
	text-decoration: none;
	box-shadow: 0 6px 20px rgb(51 39 44 / 18%);
	transition: background-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
}
.ct-bb__cta:hover,
.ct-bb__cta:focus-visible {
	background: var(--ct-pink);
	color: #fff;
	transform: translateY(-2px);
}

/* Brand logo / wordmark, printed into the empty left half of the art.
   `left` is PHYSICAL on purpose: the Arabic brand pages serve the same image
   files and the artwork does not mirror, so `inset-inline-start` would land the
   name on top of the products. `direction: ltr` on the box keeps the block
   left-aligned in RTL too — the names are single bidi runs, so Arabic still
   shapes correctly inside it.
   The white wash is what lets one rule serve all three brands: Sesderma's peach
   and Sadeen's tan take the ink straight, but Keune's left third is a printed
   poster and needs it to stay legible. It fades out before the products. */
.ct-bb__name {
	position: absolute;
	inset-block: 0;
	left: 0;
	z-index: 2;
	box-sizing: border-box;
	display: flex;
	align-items: center;
	width: min(48%, 560px);
	/* Per-brand override so one brand can sit closer to the edge without moving the
	   others; it also buys width back, which a scaled-up logo needs (see below). */
	padding: 0 var(--ct-bb-name-pad, clamp(20px, 4vw, 64px));
	direction: ltr;
	text-align: left;
	pointer-events: none;   /* never steals a click from the slider dots */
	background: linear-gradient(to right, rgb(255 255 255 / 40%), rgb(255 255 255 / 16%) 55%, rgb(255 255 255 / 0%));
}
/* The logo file (prep_brand_logos.py) is a 15:7 canvas with the mark sized to a
   shared optical WEIGHT inside it — Sesderma's 3.3:1 wordmark and Sadeen's stacked
   lockup are not the same shape, so this box is sized by width and lets the height
   follow, exactly as the /brands/ cards do. Two classes for the same specificity
   reason as .ct-bb__img above: `.elementor img { height: auto }` outranks one. */
.ct-bb .ct-bb__logo {
	width: calc(clamp(150px, 19vw, 300px) * var(--ct-bb-logo-scale, 1));
	height: auto;
	max-height: 78%;
	object-fit: contain;
	object-position: left center;
}
/* Per-brand optical nudge on top of the shared size. The prep script equalises ink
   AREA, which is right for the /brands/ cards but leaves Sadeen's stacked lockup —
   a circle over a script wordmark — reading small on a banner this wide, where the
   two flat wordmarks stretch across the space. +30% (client, 2026-07-21), then a
   further +30% the same day: 1.3 x 1.3 = 1.69, compounding on what was already live
   rather than resetting to it.
   The tighter padding is the "move it left" half of that request, and it is also what
   makes the size increase real: the logo is a flex item, so once its calc() width
   exceeds the padding box it just shrinks back and the extra 30% is silently eaten.
   At 1440 the maths is 273px x 1.69 = 461px against 560 - 2x23 = 514px of room. */
.ct-bb--sadeen {
	--ct-bb-logo-scale: 1.69;
	--ct-bb-name-pad: clamp(8px, 1.6vw, 26px);
}

/* Sesderma's shot is 3.05 and the band is 4.8, so ~36% of its height is cropped away.
   Centred, that split the loss evenly and sliced the bases off the bottles and the
   stones out of the bottom (client, 2026-07-21: "move it up"). Biasing the window down
   to 75% spends the whole loss on the empty peach headroom instead, which keeps the
   full product line, its shadows and the surface edge. Not 100%: that clips the dropper
   caps and the Hidraloe lid.
   Per-brand on purpose, and Sesderma is now the only banner that needs it: Sadeen's and
   Keune's art is authored at exactly 4.8 (BANNER_FRAME in scripts/prep_brand_banners.py),
   so it reaches the band already framed and is never cropped vertically — this rule would
   be a no-op on both. Sesderma alone still ships at 3.05.
   Desktop only — the mobile block below re-crops to a tall band where the trim is
   horizontal and the vertical anchor stops mattering. */
.ct-bb--sesderma .ct-bb__img { object-position: 100% 75%; }
.ct-bb__name span {
	color: var(--ct-ink);
	font-size: clamp(1.5rem, 0.9rem + 2.4vw, 3.2rem);
	font-weight: 600;
	line-height: 1.15;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	text-shadow: 0 1px 12px rgb(255 255 255 / 50%);
}
/* Arabic has no letter case, and letter-spacing breaks its joins. */
html[dir="rtl"] .ct-bb__name span {
	letter-spacing: 0;
	text-transform: none;
}

/* Slider: only the active slide is painted. Opacity (not display) so the box
   keeps a constant height and nothing jumps mid-rotation. The slides used to be
   pinned to the FIRST one's aspect ratio (brands ship mixed ratios, and the grid
   would otherwise size to the tallest and letterbox the rest); the fixed height
   above now does that job for all of them. */
.ct-bb--slider .ct-bb__slide {
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.6s ease;
}
.ct-bb--slider .ct-bb__slide.is-active {
	opacity: 1;
	visibility: visible;
}
/* Pre-JS / no-JS: nothing carries .is-active yet, so show the first slide rather
   than a blank hero. The JS drops `is-ready` on the root once it has taken over,
   which retires this rule. (An earlier attempt paired a :first-child rule with
   :first-child:not(.is-active) — the second immediately cancelled the first and
   the banner rendered as an empty box until the first rotation.) */
.ct-bb--slider:not(.is-ready) .ct-bb__slide:first-child {
	opacity: 1;
	visibility: visible;
}

.ct-bb__dots {
	position: absolute;
	inset-inline-end: clamp(20px, 4vw, 56px);
	inset-block-end: clamp(18px, 3.5vw, 44px);
	z-index: 3;
	display: flex;
	gap: 8px;
}
/* Specificity is deliberate: WoodMart styles bare <button> with padding 5px 20px
   and min-height 42px, which turned these into white rectangles. The resets below
   (appearance / min-*/ /* padding / line-height) are all load-bearing. */
.ct-bb .ct-bb__dots .ct-bb__dot {
	appearance: none;
	box-sizing: border-box;
	width: 9px;
	height: 9px;
	min-width: 0;
	min-height: 0;
	padding: 0;
	border: 0;
	border-radius: 50%;
	line-height: 0;
	font-size: 0;
	background: rgb(255 255 255 / 55%);
	box-shadow: 0 1px 4px rgb(51 39 44 / 30%);
	cursor: pointer;
	transition: background-color 0.2s ease, transform 0.2s ease;
}
.ct-bb .ct-bb__dots .ct-bb__dot[aria-selected="true"] {
	background: #fff;
	transform: scale(1.35);
}

@media (max-width: 768px) {
	.ct-bb { margin-top: 28px; }
	/* 3:1 art is a letterbox sliver on a phone — crop to a taller band and hold the
	   right side, where the products are, in frame. Capped at ~36vh so the top of
	   the grid still shows on open. The anchor is the right EDGE, not a percentage:
	   a phone keeps only ~25% of a 4.8-ratio file, so the 78% this used to carry
	   pushed Sadeen's bottles clean out of frame once that shot was widened. */
	.ct-bb .ct-bb__img {
		height: clamp(200px, 36vh, 300px);
		object-position: right center;
	}
	.ct-bb__cta {
		inset-inline-start: 50%;
		transform: translateX(-50%);
	}
	.ct-bb__cta:hover,
	.ct-bb__cta:focus-visible { transform: translateX(-50%) translateY(-2px); }
	.ct-bb__dots { inset-block-end: auto; inset-block-start: 14px; }
	/* The crop above throws the negative space away, so the wordmark would sit on
	   the products. The archive title prints the brand name right below anyway. */
	.ct-bb__name { display: none; }
}

@media (prefers-reduced-motion: reduce) {
	.ct-bb--slider .ct-bb__slide { transition: none; }
	.ct-bb__cta { transition: none; }
}

/* ---- Product card thumbnails: one uniform square box --------------------- */
/* The catalog grid renders `medium_large`, which is an UNCROPPED size, so each
   card was as tall as its own packshot. 79 of 85 product images are exactly 1:1,
   but three (Celulex / Estryses / Salises, 874x1200) are portrait — those cards
   got a 285x391 image instead of 285x285 and pushed their title, category and
   price ~106px below the neighbours' (reported 2026-07-21).

   Fixed in CSS rather than by switching the grid to the hard-cropped
   `woocommerce_thumbnail` (600x600, crop=1): cropping a tall tube to a square
   slices the product itself. `contain` inside a square box keeps every packshot
   whole and just pads the sides — invisible here, since the shots are on white
   and so is the card. Two classes + type = (0,2,1), enough to beat the theme's
   own `.wd-product-thumb img` rules. */
.wd-product-thumb .product-image-link img {
	aspect-ratio: 1 / 1;
	width: 100%;
	height: auto;
	object-fit: contain;
}

/* ---- Linked-variation swatches (Keune-style boxes) ---------------------- */
/* WoodMart's "Linked Variations" renders each sibling product as
   `a.wd-swatch.wd-text` inside `.variations_form-linked`. Its default text-swatch
   style is a bare underlined word; CLAUDE.md asks for boxed size/variant options,
   so these are restyled to match the read-only `.ct-volume__box` chip already used
   for Size — one visual language for "pick a variant" across the page.
   Scoped to .variations_form-linked so ordinary attribute swatches elsewhere
   (layered nav, future variable products) keep the theme's own styling. */
.variations_form-linked .wd-swatches .wd-swatch.wd-text {
	min-width: 54px;
	padding: 8px 15px;
	border: 1.5px solid var(--ct-pink-line);
	border-radius: 10px;
	background: #fff;
	color: var(--ct-ink);
	line-height: 1;
	transition: border-color .15s ease, background-color .15s ease, color .15s ease;
}
.variations_form-linked .wd-swatches .wd-swatch.wd-text .wd-swatch-text {
	font-size: 14px;
	font-weight: 600;
	text-decoration: none;
}
/* The active/hover affordance in swatch "style 1" is a 2px dark rule drawn by
   `.wd-swatch.wd-text:after` at bottom:-3px. Under a boxed swatch it reads as a
   stray line below the border, so the box itself carries the state instead. */
.variations_form-linked .wd-swatches .wd-swatch.wd-text::after {
	display: none;
}
.variations_form-linked .wd-swatches .wd-swatch.wd-text:hover {
	border-color: var(--ct-pink);
	background: var(--ct-pink-soft);
}
/* Current product = selected option. */
.variations_form-linked .wd-swatches .wd-swatch.wd-text.wd-active {
	border-color: var(--ct-pink);
	background: var(--ct-pink-soft);
	color: var(--ct-pink-strong);
}
.variations_form-linked .variations th.label label {
	font-size: 12px;
	font-weight: 600;
	letter-spacing: .04em;
	text-transform: uppercase;
	opacity: .75;
}

/* ==========================================================================
   Site content width — widen the boxed layout on large screens
   The site runs TWO width caps that both centred content and left big empty
   margins on wide monitors (client, 2026-07-22):
     1. WoodMart:  .container { max-width: var(--wd-container-w) } — injected
        inline from the theme's "Site width" option (~1200px).
     2. Elementor: the kit (post-12.css) sets .e-con { --container-max-width:
        1140px } and the legacy .elementor-section-boxed rule to the same.
   Raise both to a ~1560px CONTENT width. In the child theme (not the theme
   option / kit setting) so it is git-tracked and survives the staging deploy.

   The values keep the two systems' content edges ALIGNED: WoodMart's
   .container carries 15px padding-inline, so its cap is 1590px (= 1560 + 30);
   Elementor containers have zero default padding on this kit, so theirs is
   1560px exactly.

   min(..., 94vw) is the boxed "breathing room": without it, any viewport
   narrower than the new cap (e.g. a 1440px laptop) would render edge-to-edge,
   which reads as a layout bug rather than a wide design. 94vw keeps a slim
   ~3%-per-side margin at every size between 1200px and the cap.

   Override mechanics (why this wins without !important): the theme prints its
   value on :root, so declaring on body shadows it for every element via
   inheritance; the kit's `.e-con` (0,1,0) and boxed-section (0,3,0) rules are
   each outranked by one extra `body` type selector. Scoped ≥1200px: below
   that, both systems already fill the viewport, and the kit's own 1024px /
   767px tablet-mobile values must keep winning. Width-only + direction-
   neutral, so RTL/Arabic needs no mirror rule.
   ========================================================================== */
@media (min-width: 1200px) {
	body {
		--wd-container-w: min(1590px, 94vw);
	}
	body .e-con {
		--container-max-width: calc(min(1590px, 94vw) - 30px);
	}
	body .elementor-section.elementor-section-boxed > .elementor-container {
		max-width: calc(min(1590px, 94vw) - 30px);
	}
}

/* ==========================================================================
   Product carousels (Week Bestsellers / New Arrivals …) — bound + arrows
   Client (2026-07-23): the homepage product rows must stay INSIDE the page,
   with visible prev/next arrows cueing that more products exist.

   Two demo behaviors caused the complaint, both on the wd_products widgets
   #e30d40f (Week Bestsellers) and #bdf7e0e (New Arrivals) on Home EN #167:
     1. The widget sets `--wd-carousel-overflow: visible` INLINE — a deliberate
        demo "bleed" that paints off-viewport slides past the container edge.
        Inside the old ~1140px layout it spilled into wide side margins; on the
        widened 1560px layout it runs to the screen edge and products render
        cut off. Custom-property `!important` in a stylesheet beats a
        non-important inline declaration, hence the flag.
     2. Both carousels ALREADY render WoodMart's native arrows, but with the
        `wd-hover-1` style: desktop hides them until the pointer is over the
        carousel (style-elementor.css:4574), so users never learn the row
        scrolls. The override below just makes them always visible; wd-lock
        (carousel fits, nothing to scroll) and pre-init hiding keep their
        theme `!important` rules, so arrows still auto-hide when useless.

   Scoped to `.wd-products-element` = every WoodMart PRODUCTS carousel (incl.
   the third homepage row and any future AR-homepage mirror — no element IDs,
   so it survives Elementor re-builds). The banner / brand-logo carousels keep
   their stock hover arrows and were never bleeding. Where overflow is already
   clip, rule 1 is a no-op.

   The arrows are restyled via WoodMart's own --wd-arrow-* hooks to the pink
   circle language of the category pages' subcat scroller (.ct-subcat-arrow) —
   one affordance across the site. The negative offset pulls them INSIDE the
   row edges: pos-sep's default puts them OUTSIDE the container, where the
   widened layout's slim side gap (94vw cushion) would clip them at laptop
   widths. Positioning is all logical-property based upstream, so RTL mirrors
   without extra rules.
   ========================================================================== */
.wd-products-element .wd-carousel {
	--wd-carousel-overflow: clip !important;   /* vs the widget's inline `visible` */
}

.wd-products-element .wd-nav-arrows {
	--wd-arrow-size: 44px;
	--wd-arrow-icon-size: 18px;
	--wd-arrow-radius: 50%;
	--wd-arrow-bg: var(--ct-pink);
	--wd-arrow-color: #fff;
	--wd-arrow-bg-hover: var(--ct-pink-strong);
	--wd-arrow-color-hover: #fff;
	--wd-arrow-brd: 2px solid;                 /* white ring separates it from card art */
	--wd-arrow-brd-color: #fff;
	--wd-arrow-shadow: 0 2px 10px rgba(51, 39, 44, .3);
	/* End-of-list state, like .ct-subcat-arrow:disabled */
	--wd-arrow-bg-dis: #fff;
	--wd-arrow-color-dis: var(--ct-pink);
	--wd-arrow-brd-color-dis: var(--ct-pink-line);
	/* Inside the row edges (see header comment). Also outweighs the theme's
	   zero-specificity `:where(.wd-pos-sep)` tablet offset, so placement is
	   consistent at every width. */
	--wd-arrow-offset-h: calc((var(--wd-arrow-size) + 6px) * -1);
}

/* Desktop: defeat the wd-hover-1 hide + slide-in (opacity 0 / translateX ±30px)
   with one higher-specificity rule. Tablet/mobile never hide arrows. */
@media (min-width: 1025px) {
	.wd-products-element .wd-nav-arrows[class*="wd-hover"].wd-pos-sep .wd-btn-arrow {
		opacity: 1;
		pointer-events: unset;
		transform: none;
	}
}

/* ---------------------------------------------------------------------------
   Homepage hero — keep the copy block on the banners' empty half.
   Every hero banner (C1_hero_slider.php) is shot with its products on the RIGHT
   and an empty field on the LEFT, and the artwork does not mirror for RTL. The
   copy is a 615px Elementor container, and Elementor gives .e-con
   `margin-inline: auto`, so it CENTRES itself over the products regardless of
   the slide's own "horizontal align" setting.
   These are deliberately PHYSICAL margins, not logical ones: the target is the
   physical left edge in English and Arabic alike, so `margin-inline-start`
   would be exactly wrong in one of the two. Scoped to .wd-slide so it cannot
   reach any other Elementor container on the site.
   --------------------------------------------------------------------------- */
.wd-slide .wd-slide-inner > .elementor > .e-con {
	margin-left: 0;
	margin-right: auto;
}
