/* ==========================================================
   Typography & buttons
   ========================================================== */
h1, h2, h3, h4 { font-family: var(--wl-font-heading); font-weight: 400; margin: 0 0 0.5em; }
.wl-section { padding: 16px 0; }
@media (max-width: 640px) {
	.wl-section { padding: 12px 0; }
}
.wl-section__title { font-size: 1.6rem; margin-bottom: 24px; text-align: center; }

/* Editorial, unboxed homepage section heading — see
   wl_render_section_heading() in inc/setup.php. Replaced an earlier
   boxed-card treatment (white card, border, shadow, a rule fading in
   from each side) with plain oversized serif type — no card, no
   underline mark — rather than a bordered UI element competing with
   the product photography around it. Used by every homepage section
   (Shop by Room, Our Selection, Latest from us, each category showcase
   block). */
.wl-section-heading { text-align: left; margin-bottom: 8px; }
/* Shop by Room only (wl_render_section_heading()'s $align param) — every
   other section heading stays left-aligned. */
.wl-section-heading--center { text-align: center; }
.wl-section-heading__kicker {
	display: block;
	font-size: 0.78rem;
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--wl-color-accent);
	margin-bottom: 10px;
}
.wl-section-heading__title { margin: 0; font-size: 2.15rem; letter-spacing: 0.01em; }
@media (max-width: 640px) {
	.wl-section-heading { margin-bottom: 6px; }
	.wl-section-heading__title { font-size: 1.5rem; }
}

.wl-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	padding: 12px 22px;
	border-radius: var(--wl-radius);
	border: 1px solid transparent;
	font-size: 0.95rem;
	font-weight: 600;
	cursor: pointer;
	text-decoration: none;
	min-height: 44px;
}
.wl-btn--primary { background: var(--wl-color-accent); color: #fff; }
.wl-btn--primary:hover { background: var(--wl-color-accent-dark); }
.wl-btn--secondary { background: transparent; border-color: var(--wl-color-border); color: var(--wl-color-text); }
.wl-btn--small { padding: 8px 14px; min-height: 36px; font-size: 0.85rem; }
/* Solid black / black-outline, matching the dtalemodern.com login-modal
   reference exactly rather than the site's own accent color — this modal
   is deliberately styled as its own compact system, not restyled to the
   rest of the site. */
.wl-btn--dark { background: #111; color: #fff; flex: 1; }
.wl-btn--dark:hover { background: #000; }
.wl-btn--outline { background: transparent; border-color: #111; color: #111; flex: 1; }
.wl-btn--outline:hover { background: #f5f5f5; }
.wl-btn--block { width: 100%; }

.wl-link-arrow { display: inline-block; margin-top: 12px; font-weight: 600; text-decoration: underline; }

.wl-empty-note { color: var(--wl-color-text-muted); }

/* ==========================================================
   Header promo / offer bar (inc/promo-bar.php + admin-editable via
   ACF "Header Promo / Offer Bar" on the Site-Wide Settings options
   page — Enable toggle, up to 6 rotating messages each with their own
   text, discount code, link, colors, and active date range).
   Deliberately kept solid/opaque even on the homepage's transparent
   overlay header — an offer banner needs to stay legible regardless
   of what's behind it. Multiple slides stack via position:absolute so
   .promo-bar__track's own height (not any one slide's) sets the bar's
   height, and assets/js/main.js's initPromoRotation() just toggles
   .is-active to cross-fade between them; a single slide never gets
   the rotation JS attached at all (slides.length < 2 guard) and simply
   renders as .is-active from PHP with nothing to fade against. */
.promo-bar {
	background: #1a1a1a;
	position: relative;
	/* A flat solid bar reads fine sitting on the plain white header further
	   down the page, but pasted directly over hero photography (the
	   homepage's transparent overlay header) it looked like a stark,
	   disconnected stripe rather than something intentionally placed on
	   top of the image — this shadow gives it depth/separation from
	   whatever photo is directly behind it regardless of how dark or busy
	   that photo is, rather than relying on the photo's own tones for
	   contrast the way the flat version did. */
	box-shadow: 0 4px 18px -4px rgba(0,0,0,0.45);
}
.promo-bar__track { position: relative; min-height: 40px; }
.promo-bar__slide {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 8px 44px;
	/* clamp(), not a fixed rem size: this box is a fixed single-line
	   height (position:absolute + overflow:hidden, so rotating slides
	   can crossfade in place instead of each reflowing the bar's own
	   height) with no room for the message to wrap onto a second line —
	   on some narrow phones the fixed 0.82rem/0.76rem sizes used before
	   were still too wide for the full message, so flex-wrap on its
	   children (below) kicked in and produced a broken-looking stacked
	   layout inside a box built for one line, part of it invisible
	   under overflow:hidden. Scaling continuously with viewport width
	   keeps it fitting on one real line at any width instead of only
	   at whatever handful of breakpoints were hand-tuned. */
	font-size: clamp(0.62rem, 2.6vw, 0.82rem);
	white-space: nowrap;
	text-align: center;
	opacity: 0;
	pointer-events: none;
	overflow: hidden;
	transition: opacity 0.5s ease;
}
.promo-bar__slide.is-active { opacity: 1; pointer-events: auto; }
/* Slow diagonal shine sweep — a subtle, continuous "highlight" so the bar
   reads as an active promotion rather than a static stripe, independent
   of the page background since it's drawn on the slide's own (always-
   opaque) surface rather than relying on any transparency effect. */
.promo-bar__slide::before {
	content: '';
	position: absolute;
	top: 0;
	left: -60%;
	width: 45%;
	height: 100%;
	background: linear-gradient(115deg, transparent, rgba(255,255,255,0.16) 45%, transparent 90%);
	animation: wl-promo-shine 6s ease-in-out infinite;
	pointer-events: none;
}
@keyframes wl-promo-shine {
	0%, 15% { left: -60%; }
	55%, 100% { left: 130%; }
}
.promo-bar__slide a {
	color: inherit;
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	flex-wrap: nowrap;
	justify-content: center;
	text-decoration: none;
}
.promo-bar__slide a:hover { text-decoration: underline; text-underline-offset: 3px; }
.promo-bar__slide > span {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	flex-wrap: nowrap;
	justify-content: center;
}
/* The discount code pulses gently to draw the eye to the one part of the
   message someone actually needs to remember/copy. */
.promo-bar__code {
	display: inline-block;
	padding: 1px 9px;
	border: 1px solid currentColor;
	border-radius: 999px;
	/* em, not rem: scales with .promo-bar__slide's own clamp()'d
	   font-size (same ~0.88 ratio to it that 0.72rem was to the slide's
	   old fixed 0.82rem) so the code badge keeps shrinking in step with
	   the rest of the message on narrow screens instead of staying a
	   fixed size that eats proportionally more of the available width
	   the smaller the message text gets. */
	font-size: 0.88em;
	font-weight: 600;
	letter-spacing: 0.03em;
	animation: wl-promo-pulse 2.6s ease-in-out infinite;
}
@keyframes wl-promo-pulse {
	0%, 100% { box-shadow: 0 0 0 0 rgba(255,255,255,0.35); }
	50% { box-shadow: 0 0 0 5px rgba(255,255,255,0); }
}
@media (max-width: 640px) {
	.promo-bar__slide { padding: 8px 16px; gap: 6px; }
}
@media (prefers-reduced-motion: reduce) {
	.promo-bar__slide::before { animation: none; }
	.promo-bar__code { animation: none; }
}

/* ==========================================================
   Header
   ========================================================== */
.site-header {
	position: sticky;
	top: 0;
	z-index: 500;
	background: var(--wl-color-surface);
	border-bottom: 1px solid var(--wl-color-border);
	transition: box-shadow 0.2s ease;
}
.site-header.is-stuck { box-shadow: 0 2px 10px rgba(0,0,0,0.06); }

/* Front-page only: promo bar + header overlay transparently on the hero
   banner instead of pushing it down. The wrapper is fixed so its height
   never occupies document flow — <main> starts at true y=0 right behind
   it, and the hero image runs full-bleed underneath both bars. */
.site-header-stack { position: fixed; top: 0; left: 0; right: 0; z-index: 600; }
/* Glossy/glass overlay — frosted panel (dark tint + blur), not a flat
   opaque bar: the hero photo still reads through it, with white text
   carrying its own text-shadow for legibility on top of that. The tint
   itself was originally much lighter (0.12 alpha, "barely-there"), sized
   for a naturally dark hero photo (a dim fireplace scene) where white
   text already had plenty of contrast on its own — swapping in a bright,
   mostly-white hero photo (a product shot against a white wall) made
   the white nav text/logo/icons nearly invisible against it, since a
   12%-opacity dark wash barely dims a background that's already close
   to white itself. 0.42 is dark enough to guarantee real contrast for
   white text against ANY photo behind it, bright or dark, while still
   reading as a tinted/blurred glass panel rather than a flat solid bar
   (still under the .is-stuck/mega-menu-open solid-white swap below).
   (Tried masking this fade-to-transparent at its bottom edge directly
   with mask-image, so it would merge into the banner instead of ending
   in a hard line — combining mask-image with backdrop-filter rendered
   as a flat washed-out panel instead of an actual blurred view of
   what's behind it, a real compositing limitation, not a typo, so
   that's not attempted here.) ::after below instead adds a plain
   color-only gradient — no blur, so no compositing surprises —
   extending a little past the header's own bottom edge to soften the
   transition into the sharp image below it. Swaps to fully solid in two
   cases, both via the same var(--wl-color-surface) treatment as
   everywhere else on the site: .is-stuck (assets/js/main.js, once
   scrolled past the banner) and the :has() rule below (a mega-menu
   dropdown is open — a transparent bar above an inherently opaque
   dropdown panel read as broken/disconnected, so the whole bar
   solidifies to visually anchor it). */
.site-header--overlay {
	position: relative;
	background: rgba(20, 17, 13, 0.22);
	backdrop-filter: blur(12px) saturate(150%);
	-webkit-backdrop-filter: blur(12px) saturate(150%);
	border-bottom: none;
	color: #fff;
	transition: background 0.25s ease, backdrop-filter 0.25s ease;
}
.site-header--overlay::after {
	content: '';
	position: absolute;
	left: 0;
	right: 0;
	bottom: -32px;
	height: 32px;
	background: linear-gradient(to bottom, rgba(20, 17, 13, 0.22), transparent);
	pointer-events: none;
}
.site-header--overlay .site-header__logo-text,
.site-header--overlay .site-header__hamburger,
.site-header--overlay .wl-header-icon,
.site-header--overlay .mega-menu__top-link {
	color: #fff;
	text-shadow: 0 1px 5px rgba(0,0,0,0.55);
}
.site-header--overlay .wl-search-form__input { background: rgba(255,255,255,0.15); border-color: rgba(255,255,255,0.4); color: #fff; }
.site-header--overlay .wl-search-form__input::placeholder { color: rgba(255,255,255,0.75); }
.site-header--overlay .mega-menu { border-top: none; }
/* The mega-menu dropdown panel and live-search results always stay solid/opaque regardless of the transparent bar above them. */
.site-header--overlay .mega-menu__panel,
.site-header--overlay .wl-search-results { color: var(--wl-color-text); }

.site-header--overlay.is-stuck,
.site-header--overlay:has(.menu-item.has-children:hover),
.site-header--overlay:has(.menu-item.has-children:focus-within),
.site-header--overlay.is-mobile-search-open {
	background: var(--wl-color-surface);
	backdrop-filter: none;
	-webkit-backdrop-filter: none;
	border-bottom: 1px solid var(--wl-color-border);
	color: inherit;
}
/* Fully opaque here already — the ::after soft-edge gradient below would
   otherwise still show past the header's own solid bottom edge. */
.site-header--overlay.is-stuck::after,
.site-header--overlay:has(.menu-item.has-children:hover)::after,
.site-header--overlay:has(.menu-item.has-children:focus-within)::after,
.site-header--overlay.is-mobile-search-open::after { display: none; }
.site-header--overlay.is-stuck .site-header__logo-text,
.site-header--overlay.is-stuck .site-header__hamburger,
.site-header--overlay.is-stuck .wl-header-icon,
.site-header--overlay.is-stuck .mega-menu__top-link,
.site-header--overlay:has(.menu-item.has-children:hover) .site-header__logo-text,
.site-header--overlay:has(.menu-item.has-children:hover) .site-header__hamburger,
.site-header--overlay:has(.menu-item.has-children:hover) .wl-header-icon,
.site-header--overlay:has(.menu-item.has-children:hover) .mega-menu__top-link,
.site-header--overlay:has(.menu-item.has-children:focus-within) .site-header__logo-text,
.site-header--overlay:has(.menu-item.has-children:focus-within) .site-header__hamburger,
.site-header--overlay:has(.menu-item.has-children:focus-within) .wl-header-icon,
.site-header--overlay:has(.menu-item.has-children:focus-within) .mega-menu__top-link,
.site-header--overlay.is-mobile-search-open .site-header__logo-text,
.site-header--overlay.is-mobile-search-open .site-header__hamburger,
.site-header--overlay.is-mobile-search-open .wl-header-icon,
.site-header--overlay.is-mobile-search-open .mega-menu__top-link { color: inherit; text-shadow: none; }
.site-header--overlay.is-stuck .wl-search-form__input,
.site-header--overlay:has(.menu-item.has-children:hover) .wl-search-form__input,
.site-header--overlay:has(.menu-item.has-children:focus-within) .wl-search-form__input,
.site-header--overlay.is-mobile-search-open .wl-search-form__input { background: var(--wl-color-bg); border-color: var(--wl-color-border); color: inherit; }
.site-header--overlay.is-stuck .wl-search-form__input::placeholder,
.site-header--overlay:has(.menu-item.has-children:hover) .wl-search-form__input::placeholder,
.site-header--overlay:has(.menu-item.has-children:focus-within) .wl-search-form__input::placeholder,
.site-header--overlay.is-mobile-search-open .wl-search-form__input::placeholder { color: var(--wl-color-text-muted); }

.site-header__row {
	display: flex;
	align-items: center;
	gap: 16px;
	padding: 14px 20px;
}

/* No-op wrapper on desktop — display:contents removes it from the box
   model entirely, so .site-header__hamburger and .site-header__logo
   remain direct flex children of .site-header__row exactly as before
   (its only job is providing a sized positioning context for the logo's
   centering trick below the mobile breakpoint). */
.site-header__topline { display: contents; }

.site-header__hamburger {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 4px;
	width: 44px;
	height: 44px;
	background: none;
	border: none;
	cursor: pointer;
}
/* Bars sized to match the 19px stroke-1.6 SVG icons beside it (account,
   wishlist, cart — see wl_header_icon_svg()) rather than the larger 22px
   / 2px bars it used to have, which read heavier than its neighbours. */
.site-header__hamburger { align-items: center; gap: 3.5px; }
.site-header__hamburger span { display: block; width: 15px; height: 1.5px; border-radius: 1px; background: currentColor; }

.site-header__logo { flex: 0 0 auto; }
.site-header__logo-text { font-family: var(--wl-font-heading); font-size: 1.4rem; letter-spacing: 0.02em; }
.site-header__logo .custom-logo-link { display: flex; align-items: center; }
/* The square badge (assets/img/logo.svg — kept as the favicon/site icon,
   where a dense small icon-mark belongs) reads "WAARA LIVING" in fine
   print sized relative to its own decorative background pattern: legible
   as a 512px favicon, but shrunk into ANY reasonable header height it
   stops being readable — that's font density, not a sizing bug, and no
   amount of CSS max-height fixes it. assets/img/logo-wordmark.svg pulls
   the exact same letterform paths out of that file into their own tight
   horizontal viewBox with no surrounding badge, so this is the header
   logo instead — same brand mark, sized to actually be read at header
   scale. Real intrinsic width/height are on the SVG itself, so
   width:auto here resolves correctly (unlike the square badge before it
   also got explicit dimensions — see the fix history for that bug). */
.site-header__logo .custom-logo { height: 42px; width: auto; display: block; }
/* The wordmark is dark ink (#1c1a17) for the normal solid-white header;
   on the homepage's transparent overlay header it sits on a dark hero
   photo instead, so it's forced to pure white here the same way the
   overlay's other header elements (icons, nav links) already switch to
   white — see the .site-header--overlay rules above. brightness(0)
   invert(1) recolors the SVG via <img> without needing a second file. */
.site-header--overlay:not(.is-stuck):not(.is-mobile-search-open):not(:has(.menu-item.has-children:hover)):not(:has(.menu-item.has-children:focus-within)) .site-header__logo .custom-logo { filter: brightness(0) invert(1); }

/* Always-visible pill search bar (tikamoon.co.uk reference) — was
   previously a small input hidden behind a toggle icon; the icon button
   is gone (see header.php) and this now sits inline in the header row
   at all times, wide enough to read as the header's primary search
   affordance rather than an afterthought. */
.site-header__search { flex: 1 1 auto; min-width: 0; max-width: 560px; margin: 0 auto; position: relative; }
.wl-header-icon.is-active { background-color: var(--wl-color-bg); }
.site-header--overlay:not(.is-stuck) .wl-header-icon.is-active { background-color: rgba(255,255,255,0.18); }
.wl-search-form { display: flex; position: relative; }
.wl-search-form__icon {
	position: absolute;
	left: 16px;
	top: 50%;
	transform: translateY(-50%);
	display: flex;
	color: var(--wl-color-text-muted);
	pointer-events: none;
}
.site-header--overlay:not(.is-stuck):not(:has(.menu-item.has-children:hover)):not(:has(.menu-item.has-children:focus-within)) .wl-search-form__icon { color: rgba(255,255,255,0.75); }
.wl-search-form__input {
	width: 100%;
	min-width: 0;
	padding: 12px 40px 12px 44px;
	border: 1px solid var(--wl-color-border);
	border-radius: 999px;
	background: var(--wl-color-bg);
	font-size: 0.95rem;
	min-height: 46px;
}
.wl-search-form__submit {
	position: absolute;
	right: 6px;
	top: 50%;
	transform: translateY(-50%);
	background: none;
	border: none;
	cursor: pointer;
	min-width: 32px;
	min-height: 32px;
	opacity: 0.7;
}

.wl-search-results {
	position: absolute;
	top: calc(100% + 6px);
	left: 0;
	right: 0;
	background: var(--wl-color-surface);
	border: 1px solid var(--wl-color-border);
	border-radius: var(--wl-radius);
	box-shadow: 0 8px 24px rgba(0,0,0,0.08);
	max-height: 420px;
	overflow-y: auto;
	z-index: 600;
}
.wl-search-results__item { display: flex; align-items: center; gap: 12px; padding: 10px 14px; text-decoration: none; color: inherit; }
.wl-search-results__item:hover { background: var(--wl-color-bg); }
.wl-search-results__item img { width: 48px; height: 48px; object-fit: cover; border-radius: 3px; }
.wl-search-results__title { display: block; font-weight: 600; }
.wl-search-results__price { display: block; color: var(--wl-color-text-muted); font-size: 0.85rem; }
.wl-search-results__view-all { display: block; text-align: center; padding: 10px; font-weight: 600; border-top: 1px solid var(--wl-color-border); }
.wl-search-results__empty, .wl-search-results__loading { padding: 14px; color: var(--wl-color-text-muted); }

.site-header__icons { display: flex; align-items: center; gap: 4px; flex: 0 0 auto; }
/* Mobile-only toggle for the search icon (see header.php) — the desktop
   header keeps its own always-visible search bar instead, so this has
   nothing to do above the breakpoint that un-hides it below. */
#wl-search-toggle { display: none; }
.wl-header-icon {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	width: 44px;
	padding: 0;
	text-decoration: none;
	font-size: 1.05rem;
	border-radius: var(--wl-radius);
	transition: background-color 0.15s ease;
	/* Reset native <button> chrome (border, background, font) so a
	   button-based icon like #wl-search-toggle matches the <a>-based
	   icons beside it instead of rendering as a boxed system button. */
	background: none;
	border: none;
	font-family: inherit;
	color: inherit;
	cursor: pointer;
}
.site-header:not(.site-header--overlay) .wl-header-icon:hover,
.site-header--overlay.is-stuck .wl-header-icon:hover { background-color: var(--wl-color-bg); }
.site-header--overlay:not(.is-stuck) .wl-header-icon:hover { background-color: rgba(255,255,255,0.12); }
/* display:flex removes the few px of baseline descender gap an inline
   <svg> otherwise leaves under itself, which showed up as the icon
   sitting slightly above-center relative to its label next to it. */
.wl-header-icon__glyph { position: relative; line-height: 1; display: flex; align-items: center; }
.wl-header-icon__glyph svg { display: block; }
/* Icon-only header: kept in the DOM (redundant with each link's own
   aria-label, but harmless) and visually hidden rather than removed,
   so nothing regresses for screen readers that ignore aria-label. */
.wl-header-icon__label {
	position: absolute;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}
.wl-header-icon__count {
	position: absolute;
	top: -8px;
	right: -10px;
	background: var(--wl-color-accent);
	color: #fff;
	font-size: 0.6rem;
	line-height: 1;
	padding: 3px 5px;
	border-radius: 999px;
	min-width: 15px;
	text-align: center;
}

/* Mega menu */
.mega-menu { position: relative; border-top: 1px solid var(--wl-color-border); }
.site-header--overlay .mega-menu { border-top: none; }
/* Centered, with horizontal scroll as the overflow fallback (kept
   off-screen via scrollbar:none below) on any viewport too narrow to
   fit the full row — at 11 items (6 product-category rooms + Ready to
   Ship / Best Sellers / Custom Furniture / Collections / Sale — see
   wl_get_extra_nav_links() in inc/category-menu.php) it comfortably
   fits inside .wl-container's 1320px on an ordinary desktop width, so
   centering reads correctly there; a still-narrower viewport (a small
   laptop, or the ≤900px mobile breakpoint below, which explicitly
   overrides back to flex-start) falls back to scrolling instead of
   clipping. */
.mega-menu__list {
	list-style: none;
	display: flex;
	flex-wrap: nowrap;
	justify-content: center;
	align-items: center;
	margin: 0;
	padding: 0;
	/* 16px, not the 20px every other gap in this file uses — kept even
	   after trimming this row to 11 items, since it's what let the row
	   fit .wl-container's 1320px without scrolling on an ordinary
	   desktop width in the first place. */
	gap: 16px;
	overflow-x: auto;
	scrollbar-width: none;
}
.mega-menu__list::-webkit-scrollbar { display: none; }
/* Deliberately not position:relative on the individual <li> — the dropdown
   panel below needs its containing block to be the full-width .mega-menu
   nav (set above), not the narrow menu item, so it spans edge-to-edge as a
   true "mega" menu rather than a normal-width dropdown pinned under the
   single trigger word. */
.mega-menu__top-link { display: inline-flex; align-items: center; gap: 4px; padding: 12px 2px; text-decoration: none; font-weight: 600; font-size: 0.88rem; white-space: nowrap; position: relative; }
.mega-menu__top-link::after {
	content: '';
	position: absolute;
	left: 2px;
	right: 2px;
	bottom: 8px;
	height: 1px;
	background: currentColor;
	transform: scaleX(0);
	transform-origin: center;
	transition: transform 0.2s ease;
}
.mega-menu__top-link:hover::after,
.menu-item.has-children:focus-within .mega-menu__top-link::after { transform: scaleX(1); }
.mega-menu__caret { display: inline-block; width: 6px; height: 6px; border-right: 1px solid currentColor; border-bottom: 1px solid currentColor; transform: rotate(45deg); }
/* "Sale" picked out from the rest of the nav row — red text on a soft
   red pill background (site-wide, not just the mega-menu: the mobile
   menu's equivalent link gets the same treatment below), with a slow
   pulse on the pill so it reads as an active promotion rather than
   just a differently-colored label, echoing the same "trending" pulse
   .promo-bar__code already uses in the header offer bar above it.
   !important on color: the homepage's transparent overlay header has
   several of its own higher-specificity ".site-header--overlay
   .mega-menu__top-link{color:#fff}"-shaped rules (plain, .is-stuck,
   :has(...) hover/focus states) that would otherwise repaint this
   back to white/inherited exactly like every other nav word — Sale
   needs to stay red through all of those, not just the default state. */
.mega-menu__top-link--sale {
	color: var(--wl-color-sale) !important;
	text-shadow: none !important;
	background: rgba(179,73,47,0.1);
	padding: 6px 12px;
	border-radius: 999px;
	animation: wl-sale-pulse 2.2s ease-in-out infinite;
}
@keyframes wl-sale-pulse {
	0%, 100% { box-shadow: 0 0 0 0 rgba(179,73,47,0.25); }
	50% { box-shadow: 0 0 0 5px rgba(179,73,47,0); }
}
@media (prefers-reduced-motion: reduce) {
	.mega-menu__top-link--sale { animation: none; }
}

.mega-menu__panel {
	display: none;
	position: absolute;
	left: 0;
	right: 0;
	top: 100%;
	background: var(--wl-color-surface);
	border-top: 1px solid var(--wl-color-border);
	border-bottom: 1px solid var(--wl-color-border);
	box-shadow: 0 12px 24px rgba(0,0,0,0.06);
	z-index: 400;
}
.menu-item.has-children:hover > .mega-menu__panel,
.menu-item.has-children:focus-within > .mega-menu__panel { display: block; }
/* Two-column layout: subcategory links on the left, one promo image
   (reusing the category's own "category_tile_image" ACF field — the same
   image already used for the homepage room tiles and the category-page
   subcategory chips, so this needs no new admin data entry) on the right —
   matching the tikamoon.co.uk reference mega menu. */
/* Two nested wrappers doing two different jobs, not one element trying
   to do both:
   .mega-menu__panel-align carries the plain .wl-container class
   (max-width:1320px, margin:0 auto, padding:0 20px) UNMODIFIED — this
   is what guarantees its edges line up with the nav row's own
   .wl-container (.mega-menu__panel itself spans the full nav's width
   edge-to-edge, so without this there's nothing tying the panel's
   position back to where the trigger row actually sits).
   .mega-menu__panel-inner, inside it, is the actual flex row (links +
   promo image) sized to width:fit-content with margin:0 auto so it
   centers within that 1320px box regardless of category — a category
   with a short subcategory list (e.g. Garden, 5 links) would otherwise
   leave a large empty gap on one side, since the image's own flex-grow
   is already capped by its max-width. This deliberately does NOT anchor
   the panel under whichever top-level trigger is hovered (Kids, near
   the nav's right edge, still opens a horizontally-centered panel, not
   one flush against the far right) — centering the panel as a fixed
   unit read as more balanced than either edge-anchoring, which one-
   sidedly favoured a leftmost or rightmost trigger's position. */
.mega-menu__panel-inner { display: flex; align-items: flex-start; gap: 72px; padding: 36px 0; width: fit-content; margin: 0 auto; }
.mega-menu__links { flex: 0 0 280px; display: flex; flex-direction: column; }
.mega-menu__sublist { list-style: none; margin: 0 0 16px; padding: 0; }
.mega-menu__link { text-decoration: none; display: block; padding: 9px 0; color: var(--wl-color-text-muted); font-size: 0.95rem; }
.mega-menu__link:hover { color: var(--wl-color-text); }
.mega-menu__view-all {
	display: inline-flex; align-items: center; gap: 6px;
	margin-top: 8px; padding-top: 12px; border-top: 1px solid var(--wl-color-border);
	font-weight: 600; font-size: 0.88rem; text-decoration: none; color: var(--wl-color-text);
}
.mega-menu__view-all:hover span { transform: translateX(3px); }
.mega-menu__view-all span { display: inline-block; transition: transform 0.15s ease; }
/* Fills the remaining panel width next to the link list (flex: 1 1 auto),
   up to a sensible cap, matching the tikamoon.co.uk reference's large
   landscape image rather than a small fixed thumbnail. Both dimensions
   come from aspect-ratio alone — no separate max-height fighting it the
   way an earlier version did (aspect-ratio wanted one height, max-height
   forced a shorter one, and the mismatch stretched/cropped the image
   oddly) — so the box can't end up a different shape than intended
   regardless of how much width the flex layout actually gives it. */
.mega-menu__media {
	position: relative;
	/* Was `flex: 1 1 auto` (flex-basis:auto — sized from content) until
	   the img inside became position:absolute below: an absolutely
	   positioned child is removed from normal flow entirely, so it no
	   longer contributes anything to this box's own content-based
	   sizing — with nothing left to measure, the whole tile collapsed to
	   zero width (confirmed live: the mega-menu dropdown rendered as a
	   single links column with no image at all, not just a mis-cropped
	   one). A fixed width sidesteps content-based sizing altogether, so
	   it no longer matters that the img isn't in flow. */
	width: 640px;
	aspect-ratio: 8 / 5;
	display: block;
	overflow: hidden;
	border-radius: var(--wl-radius-image);
	background: var(--wl-color-border);
}
/* !important on every "width:100%;height:100%;object-fit:cover" image
   fill in this file (mega-menu media, product cards, blog cards, the
   photo slider, cart drawer thumbnails, etc.) for the same reason
   documented in full next to .page-hero__media further down: without
   it, style.css's global `img { height: auto }` reset silently wins
   despite lower specificity, and the image falls back to its own
   intrinsic aspect ratio instead of filling its container — cropping
   correctly on some pages only by coincidence (when the image's own
   ratio happens to be close to the container's), and leaving a visible
   gap of the container's plain background color everywhere it doesn't
   (confirmed on the shop-grid product cards: a woocommerce_thumbnail
   image, always cropped square by WordPress, inside a 4:4.6 portrait
   card — the square photo only filled the top portion, leaving a
   beige strip at the bottom instead of actually covering the card). */
.mega-menu__media img { position: absolute; inset: 0; width: 100% !important; height: 100% !important; object-fit: cover; }

/* Mobile nav */
/* Same overlay+sliding-panel pattern as .wl-cart-drawer (see that
   section further down) — a dark backdrop over the dimmed page, a
   real panel covering only part of the width, sliding in from its own
   edge — mirrored on the left instead of the right, matching the
   dtalemodern.com reference this was modelled on rather than the
   previous full-bleed edge-to-edge overlay. */
.mobile-nav[hidden] { display: none; }
.mobile-nav__overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.4); z-index: 700; }
.mobile-nav__panel {
	position: fixed; top: 0; left: 0; bottom: 0; width: min(360px, 85vw);
	z-index: 701;
	background: var(--wl-color-surface);
	overflow-y: auto;
	padding: 0 20px 20px;
	animation: wl-mobile-nav-in 0.25s ease;
}
@keyframes wl-mobile-nav-in {
	from { transform: translateX(-100%); }
	to { transform: translateX(0); }
}
/* Sticky (not just top-of-page) — .mobile-nav__panel itself scrolls
   (overflow-y:auto above) once an expanded category pushes the list
   taller than the viewport, so the close button needs to stay
   reachable throughout that scroll, not just visible on first open.
   Given its own tinted background + accent underline (rather than the
   plain white bar + "Menu" text label it used to be) so the branded
   logo up top reads as a deliberate header block, not an afterthought. */
.mobile-nav__header {
	position: sticky;
	top: 0;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 22px 20px;
	margin: 0 -20px 8px;
	background: var(--wl-color-bg);
	border-bottom: 2px solid var(--wl-color-accent);
}
.mobile-nav__logo { display: flex; align-items: center; }
.mobile-nav__logo .custom-logo-link { display: flex; align-items: center; }
.mobile-nav__logo img { max-height: 32px; width: auto; }
.mobile-nav__logo-text { font-family: var(--wl-font-heading); font-size: 1.25rem; letter-spacing: 0.02em; color: var(--wl-color-text); }
.mobile-nav__close {
	display: flex; align-items: center; justify-content: center;
	width: 32px; height: 32px;
	background: var(--wl-color-surface);
	border: 1px solid var(--wl-color-border);
	border-radius: 50%;
	font-size: 1.2rem; line-height: 1;
	cursor: pointer;
	color: var(--wl-color-text);
	transition: background-color 0.15s ease, border-color 0.15s ease;
}
.mobile-nav__close:hover { background: var(--wl-color-bg); border-color: var(--wl-color-text-muted); }
.mobile-nav__list { list-style: none; margin: 0; padding: 0; }
.mobile-nav__list .menu-item { border-bottom: 1px solid var(--wl-color-border); }
.mobile-nav__list a {
	display: block;
	padding: 15px 4px;
	margin: 0 -4px;
	text-decoration: none;
	font-weight: 600;
	border-radius: 6px;
	transition: background-color 0.15s ease, color 0.15s ease, padding-left 0.15s ease;
}
.mobile-nav__list > .menu-item > a:hover,
.mobile-nav__list .menu-item--expandable summary:hover { background: var(--wl-color-bg); color: var(--wl-color-accent); padding-left: 10px; }
/* Same red-highlight treatment as .mega-menu__top-link--sale above,
   for this menu's own "Sale" link. */
.mobile-nav__extra-link--sale { color: var(--wl-color-sale); }
.mobile-nav__extra-link--sale:hover { color: var(--wl-color-sale) !important; }
/* "Ready to Ship" through "Contact Us": secondary links below the main
   category list — lighter weight so the category tree above (the
   primary way through this menu) stays visually first. */
.mobile-nav__extra-link { font-weight: 400; color: var(--wl-color-text-muted); }
.mobile-nav__list .menu-item--expandable summary {
	list-style: none;
	display: flex;
	align-items: center;
	justify-content: space-between;
	cursor: pointer;
	padding: 15px 4px;
	margin: 0 -4px;
	border-radius: 6px;
	transition: background-color 0.15s ease, color 0.15s ease, padding-left 0.15s ease;
}
.mobile-nav__list .menu-item--expandable summary::-webkit-details-marker { display: none; }
.mobile-nav__list .menu-item--expandable summary a { padding: 0; margin: 0; border-radius: 0; }
.mobile-nav__list .menu-item--expandable summary a:hover { background: none; color: inherit; padding-left: 0; }
.mobile-nav__list .menu-item--expandable summary::after {
	content: '';
	width: 8px; height: 8px;
	border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
	transform: rotate(45deg);
	transition: transform 0.2s ease;
	flex: none;
}
.mobile-nav__list .menu-item--expandable details[open] summary::after { transform: rotate(-135deg); }
.mobile-nav__sublist { list-style: none; margin: 0 0 12px; padding: 0 0 0 16px; }
.mobile-nav__sublist a { padding: 10px 4px; font-weight: 400; color: var(--wl-color-text-muted); }
.mobile-nav__sublist a:hover { color: var(--wl-color-accent); background: var(--wl-color-bg); }
/* "Follow" links, bottom of the panel — reuses the same wl_social_*
   Customizer URLs as the footer's social column (see footer.php),
   just plain text links here rather than icon glyphs. */
.mobile-nav__social {
	list-style: none;
	margin: 20px 0 0;
	padding: 16px 0 0;
	border-top: 1px solid var(--wl-color-border);
	display: flex;
	gap: 20px;
}
.mobile-nav__social a { font-size: 0.85rem; font-weight: 600; color: var(--wl-color-text-muted); text-decoration: none; }
.mobile-nav__social a:hover { color: var(--wl-color-accent); }

@media (max-width: 900px) {
	/* Category row scrolls horizontally right in the header itself
	   (.mega-menu__list already has overflow-x:auto + flex-wrap:nowrap
	   from the desktop rules above — nothing extra needed there) instead
	   of being dropped entirely and only reachable through the hamburger
	   overlay. Each .mega-menu__top-link already links straight to that
	   category's own archive page regardless of the dropdown panel (see
	   wl_render_mega_menu() in inc/category-menu.php), so tapping one
	   works immediately; the panel itself is hidden below since it only
	   ever opened on :hover/:focus-within, neither of which is a real
	   touch gesture, and a stray tap-triggered hover on some touch
	   browsers would otherwise require a second tap to actually follow
	   the link. The hamburger menu (unaffected) still covers subcategory
	   drill-down and the extra nav links beyond what fits on screen. */
	.mega-menu { display: block; border-top: 1px solid var(--wl-color-border); }
	.site-header--overlay .mega-menu { border-top: none; }
	.mega-menu .wl-container { padding: 0 20px; }
	/* justify-content back to flex-start here (the desktop-width rule
	   above now centers it, safe there since the row fits without
	   scrolling): a phone-width row realistically never fits all 11
	   items, and a centered flex row that overflows isn't reliably
	   scrollable to its negative-offset half in every mobile browser —
	   left-aligned is what actually guarantees the scroll works. */
	.mega-menu__list { justify-content: flex-start; gap: 20px; padding: 2px 0; -webkit-overflow-scrolling: touch; }
	.mega-menu__panel { display: none !important; }
	/* Thinner row overall (dtalemodern.com reference) — each link's own
	   12px top/bottom padding (desktop-sized, for a comfortable click
	   target on a pointer-driven row) reads as excess height once this
	   row scrolls by touch instead. */
	.mega-menu__top-link { padding: 6px 2px; font-size: 0.82rem; }

	/* Tighter than the shared desktop 14px 20px — that padding was sized
	   for a taller desktop logo/icon row; at this row's actual mobile
	   content height (~34px) it read as excess empty space above/below
	   the logo and category row rather than intentional breathing room. */
	/* Thinner overall (dtalemodern.com reference) — was 8px 20px, sized
	   for the old centered-grid layout's taller effective row. */
	.site-header__row { padding: 6px 20px; }

	/* Hamburger removed on mobile entirely (stays display:none from its
	   desktop-default rule — nothing here turns it back on). Account /
	   Wishlist / Cart share the logo's row (icon-only). The always-
	   visible desktop search bar is
	   replaced by a toggle icon (#wl-search-toggle, first among the
	   icons — see header.php) that reveals #wl-header-search as its own
	   full-width row between this one and the category nav below, per
	   .is-mobile-search-open below.

	   Plain flex, left-aligned (dtalemodern.com reference: hamburger +
	   logo grouped together at the left edge, icons pushed to the right
	   via the icons column's own margin-left:auto below) — replacing an
	   earlier true-centered 3-column grid layout here, a deliberate
	   design change per the site owner rather than a fix to that
	   centering (which worked correctly for what it was). */
	.site-header__row { display: flex; align-items: center; gap: 10px; }
	.site-header__hamburger {
		display: flex;
		width: 22px;
		height: 22px;
		gap: 3px;
	}
	.site-header__hamburger span { width: 14px; }
	.site-header__topline { display: block; }
	.site-header__logo { position: static; transform: none; }
	/* Smaller than the 42px desktop wordmark — sized to actually read as
	   "thin" alongside the also-shrunk hamburger/icons here, rather than
	   dominating the row's height on its own. */
	.site-header__logo .custom-logo { height: 26px; }
	.site-header__logo-text { font-size: 1.1rem; }
	.site-header__icons { display: flex; align-items: center; gap: 3px; margin-left: auto; }
	.site-header__icons .wl-header-icon { width: 25px; min-width: 25px; min-height: 25px; font-size: 0.85rem; }
	.site-header__icons .wl-header-icon__glyph svg { width: 15px; height: 15px; }
	/* .wl-header-icon__count is positioned absolute relative to
	   .wl-header-icon__glyph (a ~15px box at this size, itself sitting
	   centered with ~5px of padding inside the 25px button) — the base
	   desktop rule's -8px/-10px offset is tuned for a much bigger glyph,
	   so at this size it barely cleared the glyph's own edge and the
	   badge sat almost directly on top of the basket icon instead of at
	   its corner. Sized down and pushed out further so it actually
	   clears to the button's outer corner instead. */
	.site-header__icons .wl-header-icon__count {
		top: -6px;
		right: -8px;
		padding: 1px 4px;
		min-width: 12px;
		font-size: 0.55rem;
	}
	#wl-search-toggle { display: inline-flex; order: -1; }
	.wl-search-toggle__icon-close { display: none; font-size: 1rem; line-height: 1; }

	.site-header__search { display: none; max-width: none; margin: 0; }
	.wl-search-form { width: 100%; }

	/* Search-open state (assets/js/main.js's initMobileSearchToggle(),
	   toggling this class on #site-header): icons collapse to just the
	   toggle button (now showing its close "X" glyph), staying put next
	   to the hamburger/logo, and the search bar appears as a new
	   full-width row right below — flex-wrap wrapping it onto its own
	   line, the flex equivalent of the old grid-based full-width-row
	   trick from when this was a grid layout. */
	.site-header.is-mobile-search-open .site-header__row { flex-wrap: wrap; padding-bottom: 4px; }
	.site-header.is-mobile-search-open .site-header__icons .wl-header-icon:not(#wl-search-toggle) { display: none; }
	.site-header.is-mobile-search-open .wl-search-toggle__icon-open { display: none; }
	.site-header.is-mobile-search-open .wl-search-toggle__icon-close { display: block; }
	.site-header.is-mobile-search-open .site-header__search { display: flex; flex: 1 1 100%; }

	/* Individual filter pills (Wood Finish, Colour, etc. — not the "All
	   filters" drawer, which already stacks its widgets full-width via
	   .wl-filter-bar.is-open) stay independently tappable on mobile, same
	   as desktop. Each one's dropdown is "position:absolute; left:0"
	   relative to ITS OWN pill (.wl-filter-widget), so a pill sitting near
	   the right edge of a wrapped row — very likely on a 375px screen with
	   11 pills — would open a 260px-min-width panel that runs off the
	   right edge of the viewport. Anchoring to the viewport instead of the
	   triggering pill removes that risk entirely regardless of which pill
	   was tapped. */
	.wl-filter-bar:not(.is-open) .wl-filter-widget__content {
		position: fixed;
		left: 16px;
		right: 16px;
		top: auto;
		min-width: 0;
		max-width: none;
	}
}

/* ==========================================================
   Promo bar rotation handled by JS toggling .is-active
   ========================================================== */

.wl-photo-credit {
	position: absolute; bottom: 4px; right: 6px; z-index: 2;
	font-size: 0.62rem; color: rgba(255,255,255,0.85); background: rgba(0,0,0,0.35);
	padding: 2px 6px; border-radius: 3px; line-height: 1.4;
}
.wl-photo-credit a { color: inherit; text-decoration: underline; }

/* Brand statement */
.wl-brand-statement__inner { max-width: 640px; margin: 0 auto; text-align: center; }
.wl-brand-statement--split .wl-brand-statement__inner {
	max-width: var(--wl-container);
	display: grid;
	grid-template-columns: 1fr;
	gap: 32px;
	text-align: left;
	align-items: center;
}
.wl-brand-statement__media { position: relative; aspect-ratio: 4/5; overflow: hidden; border-radius: var(--wl-radius-image); background: var(--wl-color-border); }
.wl-brand-statement__media img { position: absolute; inset: 0; width: 100% !important; height: 100% !important; object-fit: cover; display: block; }
.wl-brand-statement--split .wl-brand-statement__copy { max-width: 480px; }
@media (min-width: 700px) {
	.wl-brand-statement--split .wl-brand-statement__inner { grid-template-columns: 1fr 1fr; }
}

/* Our Selection tabs */
.wl-selection__tabs { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-bottom: 24px; }
.wl-selection__tab { padding: 8px 16px; border-radius: 999px; border: 1px solid var(--wl-color-border); background: transparent; cursor: pointer; font-size: 0.9rem; min-height: 40px; }
.wl-selection__tab.is-active { background: var(--wl-color-text); color: #fff; border-color: var(--wl-color-text); }
.wl-selection__panel[hidden] { display: none; }

/* ==========================================================
   Homepage category showcase sections — a highlighted .wl-section-heading
   (see above) first, then a real category photo on one side ("View all"
   overlaid on it) and a 2x2 product grid on the other, one block per
   top-level category — see wl_render_category_showcase_section() in
   inc/category-menu.php. Every card in the row is a real product, all
   the same size (no separate, differently-shaped category photo tile
   any more); a top divider + background tint on every other block is
   what keeps several of these stacked in a row from blending into one
   continuous scroll.
   ========================================================== */
.wl-category-showcase { border-top: 1px solid var(--wl-color-border); }
.wl-category-showcase--alt { background: var(--wl-color-bg); }

/* "View All", above the slider, right-aligned — used to live as a
   link overlaid on the (now-removed) category photo; same underline-
   on-hover treatment, just relocated since there's no photo to sit on
   any more. */
.wl-category-showcase__slider-header { display: flex; justify-content: flex-end; margin-bottom: 8px; }
.wl-category-showcase__view-all {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	font-weight: 600;
	font-size: 0.9rem;
	color: var(--wl-color-text);
	padding-bottom: 2px;
	border-bottom: 1px solid var(--wl-color-border);
	transition: border-color 0.15s ease, color 0.15s ease;
}
.wl-category-showcase__view-all span { transition: transform 0.15s ease; }
.wl-category-showcase__view-all:hover { color: var(--wl-color-accent); border-color: var(--wl-color-accent); }
.wl-category-showcase__view-all:hover span { transform: translateX(4px); }

/* Sliding track (matches "Shop by Room"'s .wl-worlds__track below —
   same overflow-x/scroll-snap/hidden-scrollbar treatment, same shared
   .wl-worlds__arrow buttons and generic initArrowSliders() scroll
   logic in main.js) instead of the previous static 2x2 CSS grid. */
.wl-category-showcase__slider { position: relative; }
/* Qualified as "ul.products.wl-category-showcase__products" (element +
   2 classes, specificity 0,2,1) specifically to beat the generic
   "ul.products { display:grid; ... }" rule below (0,1,1) — a plain
   ".wl-category-showcase__products" class-only selector (0,1,0), and
   even "ul.wl-category-showcase__products" alone (0,1,1, only a tie),
   both lost to it: ul.products is declared later in the file, so an
   equal-specificity tie still goes to it. */
ul.products.wl-category-showcase__products {
	display: flex;
	width: 100%;
	max-width: 100%;
	gap: 16px;
	overflow-x: auto;
	scroll-snap-type: x proximity;
	scrollbar-width: none;
	padding-bottom: 4px;
}
.wl-category-showcase__products::-webkit-scrollbar { display: none; }
/* !important: li.product IS .wl-product-card (same element, not a
   parent/child pair — content-product.php puts both classes on one
   <li>), and that class's own "width:100% !important" rule (added
   earlier to beat WooCommerce's float-layout width) otherwise wins
   over a plain width here regardless of selector specificity. */
.wl-category-showcase__products li.product {
	flex: 0 0 auto;
	width: 200px !important;
	scroll-snap-align: start;
}
@media (min-width: 480px) {
	.wl-category-showcase__products li.product { width: 220px !important; }
}
@media (max-width: 480px) {
	.wl-category-showcase__link { left: 16px; bottom: 16px; }
}

/* ==========================================================
   Homepage "Shop by Room" — category/subcategory tabs, modelled on
   tikamoon.co.uk's "Our worlds" section. Pill row reuses
   .wl-selection__tab (see wl_render_shop_by_room_section() in
   inc/category-menu.php).
   ========================================================== */
.wl-worlds__panel[hidden] { display: none; }
/* initWorldsTabs() (assets/js/main.js) toggles .is-switching instead of
   [hidden] directly so the incoming panel can fade/slide in — see that
   function for the two-step (add class, force reflow, remove class) dance
   this transition relies on. */
.wl-worlds__panel {
	transition: opacity 0.32s ease, transform 0.32s ease;
	opacity: 1;
	transform: translateY(0);
}
.wl-worlds__panel.is-switching { opacity: 0; transform: translateY(10px); }
.wl-worlds__row { position: relative; }
.wl-worlds__track {
	display: flex;
	gap: 16px;
	overflow-x: auto;
	scroll-snap-type: x proximity;
	scrollbar-width: none;
	padding-bottom: 4px;
}
.wl-worlds__track::-webkit-scrollbar { display: none; }

.wl-worlds__card {
	position: relative;
	flex: 0 0 auto;
	/* Matches the old .wl-room-tile grid's tile size (4 columns across
	   .wl-container's 1320px max-width, ~308px each after gaps) — this
	   section replaced that grid, so its cards should read at the same
	   scale, not smaller. */
	width: 300px;
	scroll-snap-align: start;
	text-decoration: none;
	color: inherit;
}
.wl-worlds__card-media {
	position: relative;
	display: block;
	aspect-ratio: 4/5;
	overflow: hidden;
	/* Visibly rounded (not the site's usual subtle 4px --wl-radius) —
	   at this card size a 4px radius reads as square-cornered, so this
	   uses the shared --wl-radius-image token, now applied to every
	   other real content image across the site too (see style.css). */
	border-radius: var(--wl-radius-image);
	background: var(--wl-color-border);
	box-shadow: 0 1px 3px rgba(20,17,13,0.08);
	transition: box-shadow 0.35s ease, transform 0.35s ease;
}
.wl-worlds__card-media img {
	position: absolute;
	inset: 0;
	width: 100% !important;
	height: 100% !important;
	object-fit: cover;
	transition: transform 0.6s cubic-bezier(.25,.8,.25,1);
}
.wl-worlds__card-placeholder { position: absolute; inset: 0; background: var(--wl-color-border); }
/* Bottom-up gradient so the label stays legible over any photo, plus the
   "latest hover effect" ask: the whole card lifts, its image zooms in,
   and the gradient deepens — a true overlay label instead of text below
   the image (matching the reference site's layout, where the caption
   sits on the photo, not under it). */
.wl-worlds__card-media::after {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(to top, rgba(20,17,13,0.65) 0%, rgba(20,17,13,0.05) 45%, transparent 70%);
	transition: opacity 0.35s ease;
}
.wl-worlds__card:hover .wl-worlds__card-media {
	transform: translateY(-4px);
	box-shadow: 0 20px 36px -16px rgba(20,17,13,0.4);
}
.wl-worlds__card:hover .wl-worlds__card-media img { transform: scale(1.09); }
.wl-worlds__card-label {
	position: absolute;
	left: 14px;
	right: 14px;
	bottom: 12px;
	z-index: 1;
	font-weight: 600;
	font-size: 0.95rem;
	color: #fff;
}

.wl-worlds__arrow {
	position: absolute;
	top: 40%;
	transform: translateY(-50%);
	width: 40px;
	height: 40px;
	border-radius: 999px;
	border: none;
	background: var(--wl-color-text);
	color: #fff;
	font-size: 1.3rem;
	line-height: 1;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 6px 16px -4px rgba(20,17,13,0.4);
	transition: background-color 0.15s ease;
}
.wl-worlds__arrow:hover { background: var(--wl-color-accent); }
.wl-worlds__arrow--prev { left: -14px; }
.wl-worlds__arrow--next { right: -14px; }
@media (max-width: 640px) {
	.wl-worlds__arrow { display: none; }
	/* Matches the old .wl-room-tile grid's mobile tile size (2 columns
	   across a 375px screen, minus container padding/gap, ~160px each). */
	.wl-worlds__card { width: 160px; }
}
@media (prefers-reduced-motion: reduce) {
	.wl-worlds__card-media, .wl-worlds__card-media img, .wl-worlds__track, .wl-worlds__panel { transition: none; scroll-behavior: auto; }
}

/* Product grid (loop).
   WooCommerce's own woocommerce_product_loop_start() — used on every
   shop/category/search/related-products loop — prints <ul class="products
   columns-N">, NOT our own "wl-products-grid" class (that class only
   exists on hand-written markup like the homepage's product-tab panels).
   Requiring the compound ".wl-products-grid.columns-4" meant this rule
   never matched the actual archive loop at all: display:grid silently
   never applied there, so it fell back to WooCommerce's own float-based
   li.product{float:left} layout the whole time — which never equalizes
   sibling heights, the real root cause of the row-misalignment bug (the
   title-height and margin-top:auto fixes were both correct in isolation,
   they just never had an actual CSS Grid row to align within). Matching
   the real markup — .products, and its real .columns-4 modifier — fixes
   every context at once.

   Qualified as "ul.products" (not bare ".products"): WooCommerce's
   related/upsell wrapper is "<section class="related products">" —
   "products" there is a co-class on the SECTION, not the inner
   "<ul class="products">" grid. A bare ".products" selector matched that
   wrapper too, turning it into a second, outer 3-column grid with the
   <h2> and the real <ul class="products"> competing as its two grid
   items — which is what was crushing "Related products" on the single
   product page into a narrow sliver instead of a full-width heading over
   a full-width card grid. */
.wl-products-grid, ul.products {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 20px 16px;
}
@media (min-width: 700px) {
	/* Homepage "Shop by room"/"Our selection" panels hardcode columns-4 and
	   stay 4-up regardless of viewport — these are kept as a separate rule
	   (not shared with ul.products) specifically so they can diverge from
	   the shop/category grid below. */
	.wl-products-grid.columns-4 { grid-template-columns: repeat(4, 1fr); }
	/* The real WooCommerce shop/category loop (ul.products, no
	   "wl-products-grid" class): 3-up at tablet width, matching the
	   viratraartdecor.com reference's denser, smaller-card grid — was a
	   flat 3-up at every width down to 700px, giving each card
	   noticeably larger product photography than the reference's more
	   compact tiles. */
	ul.products { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 1100px) {
	/* 5-up from here, matching the reference's card size/density on an
	   ordinary desktop width rather than just 3 much larger cards. */
	ul.products { grid-template-columns: repeat(5, 1fr); }
}
/* WooCommerce's core stylesheet still applies its old float-layout
   clearfix — ".products:before, .products:after { content:' ';
   display:table }" — directly to this same .products element. A
   generated-content pseudo-element with display:table is still a real
   box, so inside our CSS Grid it becomes an actual (invisible) grid
   item sitting in column 1, row 1 — shoving every real product over by
   one column and leaving a blank first column exactly the width of a
   card. Grid doesn't need a clearfix at all (it isn't float-based), so
   just kill the pseudo-elements outright. */
.wl-products-grid::before, .wl-products-grid::after,
ul.products::before, ul.products::after {
	content: none !important;
	display: none !important;
}

/* Every card in a grid row is stretched to equal height by CSS Grid's
   default align-items:stretch; the fixes below make sure each card's own
   *content* lines up on a common baseline too — title block reserved to a
   consistent 2-line height regardless of actual wrap, and the add-to-cart
   row pinned to the bottom of the card — so price/button don't drift up or
   down between cards with shorter vs. longer product names. */
/* The actual root cause of every card/button alignment symptom chased in
   this file: WooCommerce's own woocommerce-layout.css ships
   ".woocommerce ul.products li.product{float:left;width:22.05%;margin:0
   3.8% 2.992em 0}" — written for its own float-based grid, at specificity
   (0,3,2). That comfortably beats a plain ".wl-product-card{width:100%}"
   (0,1,0), so every card was silently collapsing to 22.05% of its GRID
   CELL width (~49px, not 22.05% of the row like the float layout
   intended) — one word per line, and two different button labels
   wrapping to a different number of lines is what actually produced the
   mismatched button heights, not a flex/grid alignment bug at all.
   !important is the honest tool here: this is overriding a
   higher-specificity plugin default built for a layout system (float)
   we've replaced with CSS Grid, not fighting our own CSS. margin is
   zeroed the same way — grid's own `gap` handles spacing now, WooCommerce's
   float margins would just add uneven extra space on top of it. */
.wl-product-card {
	position: relative;
	display: flex;
	flex-direction: column;
	width: 100% !important;
	min-width: 0;
	margin: 0 !important;
	float: none !important;
}
/* aspect-ratio + object-fit gives every card the same tall product-photo
   shape regardless of the source image's own dimensions, matching the
   large, consistently-cropped photography in the tikamoon.co.uk reference
   grid (their images are portrait-ish and fill the card width edge to edge,
   not a small thumbnail floating in whitespace). */
.wl-product-card__media { position: relative; display: block; aspect-ratio: 4 / 4.6; overflow: hidden; border-radius: var(--wl-radius-image); background: var(--wl-color-border); }
/* Baseline hover feedback for every card, independent of the JS-driven
   photo cycle in assets/js/hover-gallery.js: that cycle only has
   something to show for products with a REAL second gallery photo (see
   inc/hover-gallery.php, which now deliberately emits nothing for
   products whose only "extra" photos are demo placeholder swatches —
   swapping to those looked like a broken/blank image, not a second
   angle). Without this, hovering a placeholder-only card did nothing at
   all. A plain CSS zoom applies to every card regardless, so hover
   always reads as responsive; the JS image-swap still layers on top of
   it for cards that do have a real second photo. */
/* position:absolute + inset:0, not a normal in-flow block img with
   height:100% — the !important fix above wasn't enough here on its own:
   confirmed via computed style that this image (a WordPress-generated
   woocommerce_thumbnail, always physically cropped to a literal 300x300
   square file) was rendering at 402x402 instead of filling its
   402x463 portrait card, because .wl-product-card__media's own height
   comes from `aspect-ratio` rather than a literal `height` declaration
   — percentage-height resolution for an ordinary in-flow child
   apparently doesn't reliably work against an aspect-ratio-derived
   parent height the way it does against a literal one (compare
   .page-hero__media just above, whose parent DOES use a literal
   `height`, and which !important alone was sufficient to fix).
   Absolute positioning sidesteps that resolution path entirely: its
   containing block is the nearest positioned ancestor's padding box
   (this parent, already position:relative), which inset:0 fills
   directly regardless of how that ancestor's own height was arrived
   at. */
.wl-product-card__media img { position: absolute; inset: 0; width: 100% !important; height: 100% !important; object-fit: cover; transition: transform 0.5s cubic-bezier(.25,.8,.25,1); }
.wl-product-card:hover .wl-product-card__media img { transform: scale(1.05); }
@media (hover: none) {
	.wl-product-card:hover .wl-product-card__media img { transform: none; }
}
.wl-card-badges { position: absolute; top: 8px; left: 8px; z-index: 2; display: flex; flex-direction: column; gap: 4px; }
.wl-badge { font-size: 0.7rem; font-weight: 700; padding: 3px 8px; border-radius: 3px; background: #fff; }
.wl-badge--sale { background: var(--wl-color-sale); color: #fff; }
.wl-badge--new { background: var(--wl-color-text); color: #fff; }
.wl-badge--oos { background: var(--wl-color-border); color: var(--wl-color-text-muted); }
/* Wishlist + quick-view stack bottom-right of the image, hidden until the
   card is hovered/focused — matching the reference, which keeps the photo
   clean and only reveals these two icons on hover instead of the old
   always-visible top-right heart. They're two independent absolutely-
   positioned elements (not one wrapper div) since both already render via
   separate action hooks onto the same <a>; stacking is done with fixed
   "bottom" offsets rather than flex/gap. Touch devices have no hover, so
   they stay visible below the tablet breakpoint. */
.wl-card-wishlist,
.wl-card-quickview {
	position: absolute; right: 12px; z-index: 2;
	width: 40px; height: 40px; border-radius: 999px; background: #fff; border: none;
	display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 1.1rem;
	color: var(--wl-color-text);
	box-shadow: 0 4px 14px -6px rgba(28,26,23,0.35);
	opacity: 0; transform: translateY(6px);
	transition: opacity 0.18s ease, transform 0.18s ease;
	overflow: hidden;
}
.wl-card-wishlist { bottom: 60px; }
.wl-card-quickview { bottom: 12px; }
.wl-product-card:hover .wl-card-wishlist,
.wl-product-card:hover .wl-card-quickview,
.wl-product-card:focus-within .wl-card-wishlist,
.wl-product-card:focus-within .wl-card-quickview {
	opacity: 1; transform: translateY(0);
}
@media (max-width: 700px) {
	.wl-card-wishlist, .wl-card-quickview { opacity: 1; transform: none; }
}
.wl-card-wishlist.is-active { color: var(--wl-color-sale); }

/* YITH WCWL renders its own "Add to wishlist" button (icon + text label)
   into the .yith-add-to-wishlist-button-block mount point — the theme
   only provides the round 40px slot above (and the 48px PDP slot below);
   without this, YITH's full-width text button overflows the circle and
   overlaps the quick-view icon underneath it, especially on mobile where
   both icons are always visible (no hover to hide the overflow). This
   collapses YITH's button down to icon-only, filling the same circle
   the old fallback heart button used. */
.wl-card-wishlist .yith-add-to-wishlist-button-block,
.wl-pdp-wishlist .yith-add-to-wishlist-button-block {
	display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;
}
.wl-card-wishlist .yith-wcwl-add-to-wishlist-button,
.wl-pdp-wishlist .yith-wcwl-add-to-wishlist-button {
	display: flex; align-items: center; justify-content: center;
	width: 100%; height: 100%; padding: 0; margin: 0; border: none; background: none;
	color: inherit; text-decoration: none; cursor: pointer;
}
.wl-card-wishlist .yith-wcwl-add-to-wishlist-button__label,
.wl-pdp-wishlist .yith-wcwl-add-to-wishlist-button__label {
	display: none;
}
.wl-card-wishlist .yith-wcwl-add-to-wishlist-button-icon,
.wl-pdp-wishlist .yith-wcwl-add-to-wishlist-button-icon {
	width: 18px; height: 18px; flex: none;
}
.wl-card-wishlist .yith-wcwl-add-to-wishlist-button--added .yith-wcwl-add-to-wishlist-button-icon,
.wl-pdp-wishlist .yith-wcwl-add-to-wishlist-button--added .yith-wcwl-add-to-wishlist-button-icon {
	color: var(--wl-color-sale);
}
.wl-product-card__body { display: flex; flex-direction: column; flex: 1; padding-top: 10px; text-align: left; }
/* .wl-product-card__price-row's "margin-top: auto" (below) is meant to
   pin the price to the bottom of the card regardless of how many lines
   the title/description above it wrapped to — same idea already applied
   to the title's line-clamp. But margin:auto only pushes to the edge of
   its own flex container, and the actual direct children of
   .wl-product-card__body are just the fulfillment badge and ONE <a>
   (content-product.php wraps title, rating, description and the price
   row together inside a single woocommerce-loop-product__link anchor) —
   a plain block, not a flex container. So the auto margin was silently
   inert, and the price row's position tracked the description's actual
   line count instead (2 vs 3 lines misaligning it between cards in the
   same row, confirmed via getBoundingClientRect on a live "You May Also
   Like" row: identical card heights, but ~18px different price-row
   tops). Making the anchor itself a flex column filling the body's
   remaining height is what actually lets the auto margin do its job. */
/* !important on display: WooCommerce core ships
   ".woocommerce ul.products li.product a.woocommerce-loop-product__link
   {display:block}" at (0,4,3), well above this rule's (0,2,1). */
.wl-product-card__body > a.woocommerce-loop-product__link { display: flex !important; flex-direction: column; flex: 1; min-height: 0; }
/* Ready to Ship / Made to Order — see wl_get_fulfillment_status() in
   inc/woocommerce-setup.php. Deliberately the same neutral styling for
   both states (matching the dtalemodern.com reference, which doesn't
   colour-code them either) since neither is a "problem" the way an
   out-of-stock badge is — it's just informational. */
.wl-fulfillment-badge {
	display: inline-block;
	align-self: flex-start;
	margin-bottom: 8px;
	padding: 3px 9px;
	border-radius: 999px;
	font-size: 0.64rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	line-height: 1.5;
}
.wl-fulfillment-badge--ready-to-ship { color: #2f6b3a; background: #e3f2e5; }
.wl-fulfillment-badge--made-to-order { color: #9a5b12; background: #fbecd8; }
/* On the PDP specifically, "Made to Order" matches the dark grey
   .wl-pdp-tax-badge tag below the price instead of its shop-grid-card
   orange/tan — "Ready to Ship" there is untouched (still green), only
   requested for this one badge. */
.single-product .wl-fulfillment-badge--made-to-order { color: #fff; background: #5a5650; }
.single-product .wl-fulfillment-badge { margin-bottom: 14px; font-size: 0.7rem; }
@media (max-width: 640px) {
	.single-product .wl-fulfillment-badge { margin-bottom: 6px; }
}
/* WooCommerce's core stylesheet ships ".woocommerce ul.products li.product
   .woocommerce-loop-product__title { padding:.5em 0; margin:0; font-size:1em }"
   at specificity (0,4,2) — well above this rule's (0,2,0) — so it was
   silently winning the font-size (16px instead of our 0.95rem) and, worse,
   adding .5em top+bottom padding on top of our min-height reservation.
   Since this element is content-box, that padding stacked ON TOP of the
   2-line-clamp height instead of being absorbed by it, so a genuinely
   2-line title (which fills the clamp box) ended up visibly taller than a
   1-line title (which doesn't) — the price/rating/button rows below then
   started at a different height per card. !important reclaims all three
   properties from the plugin default. */
.wl-product-card .woocommerce-loop-product__title {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	overflow: hidden;
	min-height: 2.6em;
	margin: 0 0 6px !important;
	padding: 0 !important;
	font-size: 0.95rem !important;
	font-weight: 500;
	line-height: 1.3;
}
/* Reference-style card copy: name (the title rule above), a one-line
   description (only printed when the product actually has a WooCommerce
   short description — no placeholder text invented for products that
   don't), then price + variation count pinned to the bottom of the card
   with margin-top:auto so it lines up across a row regardless of how many
   lines the name/description above it wrapped to. */
.wl-product-card__desc {
	margin: 0 0 8px;
	font-size: 0.82rem;
	color: var(--wl-color-text-muted);
	line-height: 1.4;
}
.wl-product-card__price-row { margin-top: auto; }
.wl-product-card .price { display: block; margin-bottom: 2px; color: var(--wl-color-text); line-height: 1.2; }
.wl-product-card del { color: var(--wl-color-text-muted); }
.wl-product-card ins { text-decoration: none; color: var(--wl-color-sale); }
.wl-product-card__variants { display: block; font-size: 0.78rem; color: var(--wl-color-text-muted); }
.wl-product-card > a:first-of-type { display: block; }

/* Blog cards */
.wl-blog-grid { display: grid; grid-template-columns: repeat(1, 1fr); gap: 20px; }
@media (min-width: 700px) { .wl-blog-grid { grid-template-columns: repeat(3, 1fr); } }
.wl-blog-card { text-decoration: none; color: inherit; display: block; }
.wl-blog-card__media { position: relative; display: block; aspect-ratio: 4/3; background: var(--wl-color-border); overflow: hidden; margin-bottom: 10px; border-radius: var(--wl-radius-image); }
.wl-blog-card__media img { position: absolute; inset: 0; width: 100% !important; height: 100% !important; object-fit: cover; }
.wl-blog-card__title { font-weight: 600; display: block; }

/* Trust strip */
.wl-trust-strip { background: var(--wl-color-surface); border-top: 1px solid var(--wl-color-border); border-bottom: 1px solid var(--wl-color-border); padding: 28px 0; }
.wl-trust-strip__row { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; text-align: center; font-size: 0.85rem; }
@media (min-width: 700px) { .wl-trust-strip__row { grid-template-columns: repeat(4, 1fr); } }

/* ==========================================================
   Shop / category archive layout
   ========================================================== */
/* Subcategory pages' plain header (TV Stands, Coffee Tables, ...) —
   centered breadcrumb (default woocommerce_breadcrumb() styling, see
   .wl-breadcrumbs above) + title + short intro, matching the
   tikamoon.co.uk reference's subcategory-page header — no hero photo,
   that's top-level-only (see .wl-category-hero). */
.wl-breadcrumbs:has(+ .wl-archive-header) { text-align: center; }
.wl-archive-header { max-width: var(--wl-container); margin: 24px auto 40px; padding: 0 20px; text-align: center; }
.wl-archive-header__title { font-size: clamp(2rem, 4vw, 3rem); text-transform: uppercase; letter-spacing: 0.02em; }
.wl-archive-header__intro { color: var(--wl-color-text-muted); max-width: 68ch; margin: 16px auto 0; }
/* Grid of rounded-rectangle cards, matching tikamoon.co.uk's category-page
   subcategory grid (NOT a horizontal-scroll pill strip, which read as a
   throwaway afterthought sitting under the much heavier hero photo above
   it). 2 columns on mobile, 4 on desktop; each card is a full-width tap
   target with the subcategory name + a small real-photo thumbnail
   (tikamoon uses custom line-icons per subcategory type, which this
   theme has no equivalent asset set for — a real product photo reuses
   what already exists and still reads as a distinct per-card visual). */
.wl-subcategory-strip {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 10px;
	padding: 32px 20px 40px;
	max-width: var(--wl-container);
	margin: 0 auto;
}
/* At 3-up on a phone width, the card's desktop padding/min-height/icon
   size and label font left barely any room for two-word category names
   (e.g. "Armchairs & Benches") without cramping — scaled down together
   rather than just shrinking the grid columns and leaving the card's
   own content sized for a wider column. */
.wl-subcategory-strip .wl-subcategory-chip {
	min-height: 88px;
	padding: 12px 10px;
	/* A 3-up column here only leaves ~77px of content width per card
	   (column width minus this padding) — reserving horizontal room for
	   the icon beside the label on top of that was never reliable: a
	   single unbroken word like "Sideboards" measures ~72px on its own,
	   leaving as little as 4-5px for any icon column at all. Bumping
	   padding-right kept landing exactly on that knife-edge instead of
	   fixing it (confirmed live — a prior padding-right increase here
	   fixed the overlap at one viewport width only to reintroduce it at
	   others once an unrelated grid-equal-columns fix changed the exact
	   column width). Stacking the icon above the label instead of beside
	   it removes the horizontal competition entirely, so it's correct
	   regardless of word length or exact column width — same reasoning
	   as pinning the price row to the bottom of the product card: a
	   structural flex fix instead of a pixel value tuned to fit today's
	   content. */
	flex-direction: column;
}
.wl-subcategory-strip .wl-subcategory-chip__media {
	position: static;
	width: 20px; height: 20px;
	margin-bottom: 8px;
}
.wl-subcategory-strip .wl-subcategory-chip__label { font-size: 0.82rem; padding-right: 0; }
.wl-subcategory-strip .wl-subcategory-chip__count { font-size: 0.74rem; }
@media (min-width: 700px) {
	.wl-subcategory-strip { grid-template-columns: repeat(4, 1fr); gap: 16px; }
	.wl-subcategory-strip .wl-subcategory-chip {
		min-height: 104px;
		padding: 18px 20px;
	}
	.wl-subcategory-strip .wl-subcategory-chip__media { width: 26px; height: 26px; }
	.wl-subcategory-strip .wl-subcategory-chip__label { font-size: 1rem; padding-right: 30px; }
	.wl-subcategory-strip .wl-subcategory-chip__count { font-size: 0.82rem; }
}
.wl-subcategory-chip {
	position: relative;
	display: flex;
	/* Was flex-end (bottom-anchored) — since the label is the only real
	   flex child (the icon is position:absolute, out of flow), that
	   pinned every label's BOTTOM edge to the same spot while its TOP
	   floated wherever a 1-line vs. 3-line wrap happened to start,
	   leaving wildly different empty space above the text card to card
	   (e.g. "Bookcases" vs. "Armchairs & Benches") — the actual "not
	   uniform" look reported, not a grid/row-height bug. Top-aligning
	   instead gives every card's label the same start position
	   regardless of how many lines its name wraps to. */
	align-items: flex-start;
	min-height: 104px;
	/* As a grid item (.wl-subcategory-strip is display:grid, 1fr columns),
	   this defaults to min-width:auto — its label's unbroken longest word
	   plus padding-right becomes a hard floor under the "equal 1fr
	   columns" the grid is supposed to enforce. Confirmed live: bumping
	   the label's padding-right for icon clearance (above) pushed one
	   column's min-content width past what 1fr would give it, and the
	   grid responded by shrinking a DIFFERENT column (98px vs ~124px)
	   while letting that one run 35px past the strip's own right edge —
	   the exact same min-width:auto grid/flex blowout already fixed
	   several times elsewhere on this site (PDP gallery, related-products
	   slider). min-width:0 here is what actually makes "repeat(3, 1fr)"
	   produce three equal columns regardless of label content. */
	min-width: 0;
	padding: 18px 20px;
	border: 1px solid var(--wl-color-border);
	border-radius: 18px;
	text-decoration: none;
	color: var(--wl-color-text);
	background: var(--wl-color-surface);
	transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.wl-subcategory-chip:hover { border-color: var(--wl-color-accent); box-shadow: 0 10px 24px -12px rgba(28,26,23,0.25); transform: translateY(-2px); }
.wl-subcategory-chip__media {
	position: absolute; top: 16px; right: 16px;
	width: 26px; height: 26px; flex: none;
	color: var(--wl-color-text-muted);
}
.wl-subcategory-chip__media svg { width: 100%; height: 100%; }
.wl-subcategory-chip__label { font-size: 1rem; font-weight: 600; line-height: 1.25; padding-right: 30px; overflow-wrap: break-word; }
.wl-subcategory-chip__count { display: block; font-weight: 400; font-size: 0.82rem; color: var(--wl-color-text-muted); margin-top: 2px; }

.wl-shop-layout { max-width: var(--wl-container); margin: 0 auto; padding: 40px 20px 48px; }
.wl-shop-layout__main { width: 100%; }
.wl-filter-note { font-size: 0.85rem; color: var(--wl-color-text-muted); }

/* Horizontal filter bar (tikamoon.co.uk reference: Sort + each attribute as
   its own dropdown pill, an "All filters" pill, product count on the right)
   replacing the old fixed-width vertical sidebar. The bar's outer element
   (id="wl-filter-sidebar", unchanged so assets/js/main.js's drawer toggle
   still targets it) doubles as the "All filters" slide-over drawer when
   .is-open is added — see that block below. */
.wl-filter-bar { margin-bottom: 28px; }
.wl-filter-bar__head { display: none; align-items: center; gap: 12px; }
.wl-filter-bar__title { font-size: 1.1rem; font-weight: 600; }
.wl-filter-bar__clear { margin-left: auto; font-size: 0.82rem; font-weight: 600; color: var(--wl-color-accent); text-decoration: none; }
.wl-filter-bar__clear:hover { text-decoration: underline; }
.wl-filter-drawer-close { display: none; }

.wl-filter-bar__row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.wl-filter-bar__left { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; flex: 1 1 auto; min-width: 0; }
.wl-filter-bar__count { margin-left: auto; font-size: 0.85rem; color: var(--wl-color-text-muted); white-space: nowrap; }
.wl-filter-bar__count .woocommerce-result-count { margin: 0; }

/* Each filter widget renders as a pill button that opens a floating dropdown
   panel underneath it (see inc/setup.php's before_widget/before_title for
   the button+content wrapper markup, assets/js/main.js's
   initShopFilterAccordion() for the open/close-on-outside-click toggle). */
.wl-filter-widget { position: relative; }
.wl-filter-widget__header {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 10px 16px;
	border: 1px solid var(--wl-color-border);
	border-radius: 999px;
	background: var(--wl-color-surface);
	cursor: pointer;
	white-space: nowrap;
	font-size: 0.85rem;
	color: var(--wl-color-text);
	transition: border-color 0.15s ease;
}
.wl-filter-widget__header:hover,
.wl-filter-widget__header[aria-expanded="true"] { border-color: var(--wl-color-accent); }
.wl-filter-widget__title { font-size: 0.85rem; text-transform: none; letter-spacing: 0; margin: 0; font-weight: 500; }
.wl-filter-widget__caret {
	flex: none; width: 7px; height: 7px; margin-top: -3px;
	border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
	transform: rotate(45deg); transition: transform 0.2s ease;
}
.wl-filter-widget__header[aria-expanded="true"] .wl-filter-widget__caret { transform: rotate(-135deg); margin-top: 3px; }
/* Inside the drawer, a +/− text glyph instead of the pill-mode arrow —
   matching the tikamoon.co.uk reference's accordion rows. */
.wl-filter-bar.is-open .wl-filter-widget__caret {
	width: auto; height: auto; border: none; transform: none; margin-top: 0;
	font-size: 1.2rem; line-height: 1; font-weight: 400;
}
.wl-filter-bar.is-open .wl-filter-widget__caret::before { content: '+'; }
.wl-filter-bar.is-open .wl-filter-widget__header[aria-expanded="true"] .wl-filter-widget__caret { transform: none; margin-top: 0; }
.wl-filter-bar.is-open .wl-filter-widget__header[aria-expanded="true"] .wl-filter-widget__caret::before { content: '\2212'; }
.wl-filter-widget__content {
	position: absolute; top: calc(100% + 8px); left: 0; z-index: 60;
	min-width: 260px;
	background: var(--wl-color-surface);
	border: 1px solid var(--wl-color-border);
	border-radius: 12px;
	box-shadow: 0 16px 40px -16px rgba(28,26,23,0.3);
	padding: 18px 20px;
}
.wl-filter-widget__content[hidden] { display: none; }

/* Sort control: same .wl-filter-widget pill+dropdown as every attribute
   filter (see wl_render_sort_widget() in inc/woocommerce-setup.php) — an
   up/down-arrow icon instead of the caret, and its dropdown lists sort
   options as plain links rather than checkboxes. */
.wl-filter-widget--sort .wl-filter-widget__sort-icon { flex: none; color: var(--wl-color-text-muted); }
.wl-sort-options { list-style: none; margin: 0; padding: 0; min-width: 200px; }
.wl-sort-options li + li { margin-top: 2px; }
.wl-sort-options a {
	display: block;
	padding: 8px 10px;
	border-radius: 8px;
	font-size: 0.88rem;
	color: var(--wl-color-text);
	text-decoration: none;
	white-space: nowrap;
}
.wl-sort-options a:hover { background: var(--wl-color-bg); }
.wl-sort-options a.is-active { background: var(--wl-color-bg); font-weight: 600; }

.wl-filter-bar__all {
	padding: 10px 18px;
	border: 1px solid var(--wl-color-text);
	border-radius: 999px;
	background: var(--wl-color-text);
	color: #fff;
	font-size: 0.85rem;
	font-weight: 600;
	cursor: pointer;
	white-space: nowrap;
}
.wl-filter-bar__all:hover { background: var(--wl-color-accent-dark, var(--wl-color-text)); }

/* "All filters" turns the whole bar into a full-height slide-over drawer —
   every pill's dropdown panel collapses into a plain stacked accordion
   list instead, forced open regardless of its individual collapsed state
   (the point of this view is to see every filter at once). */
.wl-filter-bar.is-open {
	position: fixed; inset: 0; z-index: 900;
	background: rgba(20,17,13,0.45);
	display: flex; justify-content: flex-end;
}
.wl-filter-bar.is-open .wl-filter-bar__row {
	flex-direction: column; align-items: stretch; justify-content: flex-start;
	width: 380px; max-width: 88vw; height: 100%;
	background: var(--wl-color-surface);
	padding: 20px; margin: 0; gap: 0;
	overflow-y: auto;
}
.wl-filter-bar.is-open .wl-filter-bar__head {
	display: flex; padding-bottom: 16px; margin-bottom: 8px;
	border-bottom: 1px solid var(--wl-color-border);
}
.wl-filter-bar.is-open .wl-filter-drawer-close { display: block; background: none; border: none; font-size: 1.5rem; cursor: pointer; line-height: 1; }
.wl-filter-bar.is-open .wl-filter-bar__left { flex-direction: column; align-items: stretch; width: 100%; gap: 0; }
.wl-filter-bar.is-open .wl-filter-bar__all,
.wl-filter-bar.is-open .wl-filter-bar__count { display: none; }
.wl-filter-bar.is-open .wl-filter-widget { position: static; border-bottom: 1px solid var(--wl-color-border); }
.wl-filter-bar.is-open .wl-filter-widget__header {
	display: flex; width: 100%; justify-content: space-between;
	border: none; border-radius: 0; background: none; padding: 16px 0;
}
.wl-filter-bar.is-open .wl-filter-widget__content {
	position: static; min-width: 0; border: none; box-shadow: none; background: none; padding: 0 0 16px;
}
/* Real accordion here (was forced permanently open before, which just
   dumped every filter's full option list on screen at once) — each
   section starts collapsed ("+") and expands on click ("−"), same
   toggle JS as the pill/dropdown mode outside the drawer (see
   initShopFilterAccordion() in assets/js/main.js), which also
   auto-expands Sort the moment the drawer opens. */

/* Sort renders as a row of pill buttons in the drawer instead of a
   vertical link list, matching the tikamoon.co.uk reference. */
.wl-filter-bar.is-open .wl-sort-options { display: flex; flex-wrap: wrap; gap: 8px; min-width: 0; }
.wl-filter-bar.is-open .wl-sort-options li { flex: none; margin: 0 !important; }
.wl-filter-bar.is-open .wl-sort-options a {
	padding: 9px 16px;
	border: 1px solid var(--wl-color-border);
	border-radius: 999px;
	font-size: 0.85rem;
}
.wl-filter-bar.is-open .wl-sort-options a:hover { background: var(--wl-color-bg); }
.wl-filter-bar.is-open .wl-sort-options a.is-active { background: var(--wl-color-text); color: #fff; font-weight: 600; }

/* Sticky Clear Filter / Submit footer, pinned to the bottom of the
   drawer panel — hidden entirely outside the drawer. */
.wl-filter-bar__footer { display: none; }
.wl-filter-bar.is-open .wl-filter-bar__footer {
	display: flex; gap: 12px;
	position: sticky; bottom: 0; left: 0; right: 0;
	margin-top: auto;
	padding: 16px 0 4px;
	background: var(--wl-color-surface);
	border-top: 1px solid var(--wl-color-border);
}
.wl-filter-bar__footer-clear,
.wl-filter-bar__footer-submit {
	flex: 1 1 0;
	text-align: center;
	padding: 12px 16px;
	border-radius: var(--wl-radius);
	font-size: 0.9rem;
	font-weight: 600;
	cursor: pointer;
}
.wl-filter-bar__footer-clear {
	border: 1px solid var(--wl-color-border);
	background: var(--wl-color-surface);
	color: var(--wl-color-text);
	text-decoration: none;
}
.wl-filter-bar__footer-clear:hover { border-color: var(--wl-color-text); }
.wl-filter-bar__footer-submit {
	border: 1px solid var(--wl-color-text);
	background: var(--wl-color-text);
	color: #fff;
}
.wl-filter-bar__footer-submit:hover { background: var(--wl-color-accent); border-color: var(--wl-color-accent); }

.wl-filter-bar ul { list-style: none; margin: 0; padding: 0; }
/* WooCommerce's layered-nav/rating markup is <li><a>Term</a> <span class="count">(1)</span></li> —
   the count is a SIBLING of the link, not nested inside it, so the li itself
   (not the link) needs to be the flex row for the name/count to align on
   opposite ends instead of the count wrapping onto its own line. */
.wl-filter-bar .widget_layered_nav ul li,
.wl-filter-bar .widget_rating_filter ul li {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	margin-bottom: 2px;
	padding: 2px 10px;
	border-radius: 8px;
	transition: background-color 0.15s ease;
}
.wl-filter-bar .widget_layered_nav_filters ul li { margin-bottom: 4px; }
.wl-filter-bar .widget_layered_nav ul li:hover,
.wl-filter-bar .widget_rating_filter ul li:hover { background: var(--wl-color-bg); }
.wl-filter-bar .widget_layered_nav ul li a,
.wl-filter-bar .widget_rating_filter ul li a {
	display: flex;
	align-items: center;
	gap: 10px;
	flex: 1 1 auto;
	min-width: 0;
	padding: 8px 0;
	color: var(--wl-color-text);
	text-decoration: none;
	font-size: 0.9rem;
}
.wl-filter-bar .widget_layered_nav ul li .count,
.wl-filter-bar .widget_rating_filter ul li .count { flex: none; color: var(--wl-color-text-muted); font-size: 0.8rem; }

/* Checkbox indicator — WooCommerce's layered-nav links are plain <a> tags,
   not real <input type="checkbox">, so this is a CSS-drawn square that
   fills in when the term is the active/"chosen" filter. */
.wl-filter-bar .widget_layered_nav ul li a::before {
	content: '';
	flex: none;
	width: 16px; height: 16px;
	border: 1.5px solid var(--wl-color-border);
	border-radius: 4px;
	background: var(--wl-color-surface);
	transition: background-color 0.15s ease, border-color 0.15s ease;
}
.wl-filter-bar .widget_layered_nav ul li:hover a::before { border-color: var(--wl-color-accent); }
.wl-filter-bar .widget_layered_nav ul li.chosen a::before,
.wl-filter-bar .widget_layered_nav ul li.wc-layered-nav-term--chosen a::before {
	background: var(--wl-color-accent);
	border-color: var(--wl-color-accent);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='white' stroke-width='2'%3E%3Cpath d='M3.5 8.5l3 3 6-6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
}
.wl-filter-bar .widget_layered_nav ul li.chosen a,
.wl-filter-bar .widget_layered_nav ul li.wc-layered-nav-term--chosen a { font-weight: 600; }

/* Material filter: colour-swatch grid instead of a checkbox list — the
   swatch itself (see .wl-swatch below, injected by initMaterialSwatches()
   in assets/js/main.js) replaces the checkbox as the visual indicator,
   so the checkbox square is turned off entirely for this one widget. */
.wl-filter-bar ul.wl-swatch-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 16px;
	min-width: 260px;
}
.wl-filter-bar.is-open ul.wl-swatch-grid { grid-template-columns: repeat(5, 1fr); min-width: 0; }
.wl-filter-bar ul.wl-swatch-grid li {
	display: flex; flex-direction: column; align-items: center; gap: 6px;
	padding: 4px 0; margin: 0; border-radius: 0;
}
.wl-filter-bar ul.wl-swatch-grid li:hover { background: none; }
.wl-filter-bar ul.wl-swatch-grid li a {
	flex-direction: column; gap: 6px; padding: 0; text-align: center; font-size: 0.78rem;
}
.wl-filter-bar ul.wl-swatch-grid li a::before { content: none; }
.wl-filter-bar ul.wl-swatch-grid li .count { display: none; }
.wl-swatch {
	width: 44px; height: 44px; border-radius: 50%; flex: none;
	border: 2px solid transparent;
	box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08);
	transition: border-color 0.15s ease, transform 0.15s ease;
}
.wl-filter-bar ul.wl-swatch-grid li:hover .wl-swatch { transform: scale(1.06); }
.wl-filter-bar ul.wl-swatch-grid li.chosen .wl-swatch,
.wl-filter-bar ul.wl-swatch-grid li.wc-layered-nav-term--chosen .wl-swatch {
	border-color: var(--wl-color-accent);
	box-shadow: 0 0 0 2px var(--wl-color-surface), 0 0 0 3px var(--wl-color-accent);
}

.wl-filter-bar .widget_layered_nav_filters ul li a {
	display: inline-flex; align-items: center; gap: 6px;
	padding: 6px 12px; border-radius: 999px; background: var(--wl-color-bg);
	font-size: 0.82rem; text-decoration: none; color: var(--wl-color-text);
}
.wl-filter-bar .widget_layered_nav_filters ul li a:hover { background: var(--wl-color-border); }

/* Price filter (jQuery UI slider) */
.wl-filter-bar .price_slider_wrapper { margin-top: 4px; }
.wl-filter-bar .price_slider { margin-bottom: 18px; }
.wl-filter-bar .ui-slider {
	position: relative; height: 4px; border-radius: 999px; background: var(--wl-color-border);
}
.wl-filter-bar .ui-slider-range { position: absolute; top: 0; height: 100%; border-radius: 999px; background: var(--wl-color-accent); }
.wl-filter-bar .ui-slider-handle {
	position: absolute; top: 50%; width: 16px; height: 16px; margin-left: -8px;
	background: var(--wl-color-surface); border: 2px solid var(--wl-color-accent);
	border-radius: 50%; transform: translateY(-50%); cursor: pointer; outline: none;
	box-shadow: 0 1px 3px rgba(0,0,0,0.15);
}
/* WooCommerce core's own woocommerce.css ships `.woocommerce
   .widget_price_filter .ui-slider[-handle/-range]` rules (thick purple
   #7f54b3 bar, filled purple handles) at 4 class-selectors of
   specificity — higher than the plain 2-class rules above, so it was
   winning regardless of stylesheet load order and made the Price
   slider visually inconsistent with the Dimension filter's sliders
   right next to it, even though both use the exact same .ui-slider
   markup from the exact same jQuery UI widget. These re-declarations
   chain enough real, already-present classes (price_slider/
   ui-slider-horizontal are jQuery UI's own added classes, not new
   markup) to out-specificity WC's core rule outright, rather than
   relying on load order. */
.wl-filter-bar .wl-filter-widget .price_slider.ui-slider-horizontal {
	height: 4px; background: var(--wl-color-border);
}
.wl-filter-bar .wl-filter-widget .price_slider.ui-slider .ui-slider-range {
	background: var(--wl-color-accent); border-radius: 999px;
}
.wl-filter-bar .wl-filter-widget .price_slider.ui-slider .ui-slider-handle {
	width: 16px; height: 16px; top: 50%; margin-left: -8px;
	background: var(--wl-color-surface); border: 2px solid var(--wl-color-accent);
	border-radius: 50%; transform: translateY(-50%);
	box-shadow: 0 1px 3px rgba(0,0,0,0.15);
}
/* WooCommerce's own markup here is <label (screen-reader-text)><input
   #min_price><label><input #max_price><button>Apply</button>
   <div class="price_label">...</div><div class="clear"></div> — the two
   raw text inputs (JS-driven, not meant to be visibly styled) and the
   leftover float-era ".clear" div all still count as flex children
   otherwise, which is what was actually throwing off the Apply-button/
   price-label alignment (space-between distributing across 3+ items
   instead of the 2 that are actually visible). Hiding the non-visual
   ones outright is simpler and more robust than trying to account for
   them in the flex layout. */
.wl-filter-bar .price_slider_amount input[type="text"],
.wl-filter-bar .price_slider_amount .clear { display: none; }
/* Stacked, not side-by-side: the dropdown is only 260px wide (220px once
   its own padding is subtracted), and "Price: ₹710 — ₹1,500" plus an
   "Apply" button next to it doesn't reliably fit on one line — larger
   amounts or a longer currency format wrap the second price onto its
   own line, leaving the Apply button oddly straddling both lines.
   Stacking is robust regardless of how long the price text gets. */
.wl-filter-bar .price_slider_amount { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.wl-filter-bar .price_slider_amount .price_label { order: -1; font-size: 0.85rem; color: var(--wl-color-text-muted); }
.wl-filter-bar .price_slider_amount button {
	padding: 8px 16px; border: none; border-radius: 999px; background: var(--wl-color-accent);
	color: #fff; font-size: 0.82rem; font-weight: 600; cursor: pointer;
}
.wl-filter-bar .price_slider_amount button:hover { background: var(--wl-color-accent-dark); }

/* Dimension filter (inc/dimension-filter.php) — three Width/Depth/Height
   sliders reusing the exact same .ui-slider/.ui-slider-range/
   .ui-slider-handle styling defined above for the Price filter, so
   these need only their own layout (label + slider + numeric readout
   per row), not a second copy of the handle/track visuals. */
.wl-dimension-filter { min-width: 220px; }
.wl-dimension-filter__row + .wl-dimension-filter__row { margin-top: 22px; }
.wl-dimension-filter__row label { display: block; font-size: 0.85rem; font-weight: 600; margin-bottom: 14px; }
.wl-dimension-slider { margin: 0 2px; }
.wl-dimension-filter__values { display: flex; justify-content: space-between; margin-top: 10px; font-size: 0.82rem; color: var(--wl-color-text-muted); }
.wl-dimension-filter__apply {
	margin-top: 20px;
	padding: 8px 16px; border: none; border-radius: 999px; background: var(--wl-color-accent);
	color: #fff; font-size: 0.82rem; font-weight: 600; cursor: pointer;
}
.wl-dimension-filter__apply:hover { background: var(--wl-color-accent-dark); }

/* Rating filter stars */
.wl-filter-bar .star-rating { overflow: hidden; position: relative; height: 1em; line-height: 1em; width: 5.4em; font-size: 0.9rem; }
.wl-filter-bar .star-rating::before { content: '\2605\2605\2605\2605\2605'; color: var(--wl-color-border); letter-spacing: 2px; }
.wl-filter-bar .star-rating span { position: absolute; top: 0; left: 0; overflow: hidden; }
.wl-filter-bar .star-rating span::before { content: '\2605\2605\2605\2605\2605'; color: #d4a72c; letter-spacing: 2px; }

/* Short intro paragraph (category_intro ACF field), between the
   subcategory grid and the photo slider — tikamoon.co.uk's equivalent
   copy block sits in the same spot. Generous top/bottom spacing here
   and on the sections below is deliberate: these blocks previously sat
   right up against each other with no breathing room, reading as a
   crowded, broken layout rather than the spacious tikamoon reference. */
.wl-category-intro { margin: 56px auto 48px; text-align: center; }
.wl-category-intro p { max-width: 68ch; margin-left: auto; margin-right: auto; font-size: 1.02rem; color: var(--wl-color-text-muted); }

/* Plain photo carousel, no names/links (wl_render_category_photo_slider()
   in inc/category-menu.php) — reuses .wl-worlds__row/__track/__arrow for
   the scroll-by-card JS (assets/js/main.js's initArrowSliders()), just
   with its own smaller, caption-less card instead of .wl-worlds__card. */
.wl-photo-slider { margin: 0 0 64px; }
.wl-photo-slider__item {
	position: relative;
	flex: 0 0 auto;
	width: 220px;
	aspect-ratio: 4/5;
	border-radius: var(--wl-radius-image);
	overflow: hidden;
	display: block;
	scroll-snap-align: start;
	background: var(--wl-color-border);
}
.wl-photo-slider__item img { position: absolute; inset: 0; width: 100% !important; height: 100% !important; object-fit: cover; }

.wl-category-seo-copy { max-width: var(--wl-container); margin: 0 auto 64px; padding: 0 20px; color: var(--wl-color-text-muted); text-align: center; }
.wl-category-seo-copy__body {
	max-width: 80ch;
	margin: 0 auto;
	max-height: 6.6em;
	overflow: hidden;
	position: relative;
	transition: max-height 0.3s ease;
}
.wl-category-seo-copy__body p { margin: 0 0 1em; }
.wl-category-seo-copy.is-expanded .wl-category-seo-copy__body { max-height: 800px; }
.wl-category-seo-copy__toggle {
	margin: 10px auto 0;
	display: block;
	background: none;
	border: none;
	padding: 0;
	font-weight: 600;
	font-size: 0.9rem;
	color: var(--wl-color-text);
	text-decoration: underline;
	text-underline-offset: 2px;
	cursor: pointer;
}

/* ==========================================================
   Page hero / FAQ / content pages
   ========================================================== */
.page-hero { position: relative; padding: 48px 0; text-align: center; }
.page-hero--has-image { color: #fff; min-height: 40vh; display: flex; align-items: flex-end; }
/* !important on width/height: style.css's global reset (`img { max-width:
   100%; height: auto; }`) wins over this rule's plain width:100%/height:100%
   despite lower specificity (class beats element) — confirmed via
   computed-style inspection in a real browser, not just theory: without
   !important here, this image's rendered height silently falls back to
   its own intrinsic aspect ratio scaled to the rendered width, ignoring
   this box's actual height entirely (460px intended, ~1600px actual on
   the category-archive hero) and visually bleeding down over every
   section below it. !important is the reliable fix; removing it
   reintroduces that bug. */
.page-hero__media { position: absolute; inset: 0; width: 100% !important; height: 100% !important; object-fit: cover; z-index: 0; }
/* White text needs a guaranteed-dark surface under it regardless of how
   light or busy the particular hero photo is — same reasoning as the
   header logo/promo-bar/commitment-band contrast fixes elsewhere in this
   theme. This page-hero markup existed before but had never actually
   been used with a real image until this page, so the gap was latent. */
.page-hero--has-image::before {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 0;
	background: linear-gradient(to top, rgba(20,17,13,0.65), rgba(20,17,13,0.15) 60%);
}
.page-hero__content { position: relative; z-index: 1; padding-bottom: 32px; }
.page-hero__kicker { text-transform: uppercase; letter-spacing: 0.1em; font-size: 0.8rem; }
.page-hero__description { max-width: 560px; margin: 12px auto 0; font-size: 1.02rem; }
.page-hero--has-image .page-hero__description { opacity: 0.92; }

/* Category archive hero (woocommerce/archive-product.php,
   wl_render_category_hero() in inc/category-menu.php) — the same
   .page-hero component used for static content pages, left-aligned
   instead of centered and with the breadcrumb rendered inside it,
   matching the tikamoon.co.uk reference's category-page header. Capped
   to a fixed height (unlike the other .page-hero pages, which only set
   min-height and let the box grow with their content) — this is what
   exposed the style.css `img{height:auto}` cascade bug fixed above via
   !important on .page-hero__media; confirmed fixed with a real
   computed-style check (the photo now measures exactly 460px here,
   matching this box, instead of ~1600px bleeding into the sections
   below). */
/* Full-bleed edge to edge, breaking out of the <main class="wl-container">
   wrapper (max-width:1320px + centered) this sits inside — the standard
   "full-bleed" trick: 100vw wide, pulled left by half the viewport and
   pushed back by half its own width, which re-centers it under the
   viewport regardless of the parent's own max-width/padding. */
.wl-category-hero { text-align: left; min-height: 0; height: clamp(340px, 34vw, 460px); padding: 0; width: 100vw; margin-left: calc(50% - 50vw); margin-right: calc(50% - 50vw); }
.wl-category-hero h1 { font-size: clamp(2rem, 4vw, 3rem); margin: 0; }
/* No breadcrumb in this hero (removed per site owner's request) — just
   the title, bottom-anchored using .page-hero__content's own default
   32px padding-bottom. The subcategory grid used to overlap UP onto
   the photo's bottom portion (tikamoon.co.uk-style, via a larger
   padding-bottom here plus a negative margin-top on the grid below) —
   moved back to sitting cleanly below the hero instead, per site
   owner's request, so neither override is needed any more. */

/* Breadcrumbs had no dedicated styling anywhere else before this — the
   markup already carries .wl-container (box model handled there), this
   just adds the missing size/color/spacing. */
.wl-breadcrumbs { margin-top: 16px; margin-bottom: 16px; font-size: 0.85rem; color: var(--wl-color-text-muted); }

.wl-subcategory-chip--view-all {
	background: var(--wl-color-text);
	color: #fff;
	border-color: var(--wl-color-text);
	font-weight: 600;
	font-size: 1rem;
	align-items: center;
	justify-content: center;
	text-align: center;
}
.wl-subcategory-chip--view-all:hover { background: var(--wl-color-accent); border-color: var(--wl-color-accent); }
.wl-subcategory-chip--view-all span[aria-hidden] { margin-left: 6px; }

.wl-page-content { padding: 40px 20px; max-width: 860px; margin: 0 auto; }
.wl-faq { margin-top: 48px; border-top: 1px solid var(--wl-color-border); padding-top: 24px; }
.wl-faq__item { border-bottom: 1px solid var(--wl-color-border); }
.wl-faq__question { width: 100%; text-align: left; background: none; border: none; padding: 16px 0; font-size: 1rem; font-weight: 600; display: flex; justify-content: space-between; cursor: pointer; }
.wl-faq__caret { display: inline-block; width: 8px; height: 8px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg); transition: transform 0.2s ease; }
.wl-faq__question[aria-expanded="true"] .wl-faq__caret { transform: rotate(-135deg); }
.wl-faq__answer { padding: 0 0 16px; color: var(--wl-color-text-muted); }
.wl-faq__answer[hidden] { display: none; }

/* ==========================================================
   Footer
   ========================================================== */
.site-footer { background: var(--wl-color-accent-dark); color: #f3efe9; margin-top: 48px; }
.site-footer__newsletter { border-bottom: 1px solid rgba(255,255,255,0.12); }
.site-footer__newsletter-inner { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 16px; padding: 32px 20px; }
.wl-newsletter-form { display: flex; flex-wrap: wrap; gap: 8px; }
.wl-newsletter-form input { padding: 10px 14px; border-radius: var(--wl-radius); border: none; min-width: 0; flex: 1 1 220px; min-height: 44px; }
.wl-newsletter-form__message { flex-basis: 100%; margin: 4px 0 0; font-size: 0.85rem; color: #b7f5c1; }
.wl-newsletter-form__message.is-error { color: #f7b8b8; }
.site-footer__columns { display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px; padding: 32px 20px; }
.site-footer a { text-decoration: none; color: #f3efe9; opacity: 0.85; }
.site-footer h3 { font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 12px; opacity: 0.8; }
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: 8px; }
.site-footer__bottom { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; padding: 16px 20px; font-size: 0.8rem; opacity: 0.7; }
/* 5 columns now (Get in Touch added), not 4 — auto-fit/minmax instead
   of a hardcoded repeat(4/5, 1fr) so this keeps working regardless of
   exactly how many columns end up here later, wrapping to a second
   row on narrower desktop widths rather than squeezing 5 into
   uncomfortably narrow tracks. */
@media (min-width: 700px) { .site-footer__columns { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); } }
.site-footer__contact-list { display: flex; flex-direction: column; gap: 10px; }
.site-footer__contact-list li { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 0; }
.site-footer__contact-list svg { flex: none; width: 18px; height: 18px; margin-top: 2px; opacity: 0.8; }
.site-footer__contact-list a,
.site-footer__contact-list address { opacity: 0.85; font-style: normal; line-height: 1.5; }

/* ==========================================================
   Cart drawer (dtalemodern.com reference) — see wl_render_cart_drawer_
   contents() in inc/cart-drawer.php for the markup this styles, and
   initCartDrawer()/initAjaxAddToCart() in assets/js/main.js for the
   open/close + AJAX qty/remove/add wiring.
   ========================================================== */
.wl-cart-drawer[hidden] { display: none; }
.wl-cart-drawer__overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.4); z-index: 900; }
.wl-cart-drawer__panel {
	position: fixed; top: 0; right: 0; bottom: 0; width: min(440px, 100%);
	background: var(--wl-color-surface); z-index: 901;
	display: flex; flex-direction: column;
	/* Slide in from the right, not just appear — .wl-cart-drawer[hidden]
	   removes it from the flow entirely on close, so nothing to animate
	   there; the transform only needs to run on open. */
	animation: wl-cart-drawer-in 0.25s ease;
}
@keyframes wl-cart-drawer-in {
	from { transform: translateX(100%); }
	to { transform: translateX(0); }
}
.wl-cart-drawer__header { display: flex; justify-content: space-between; align-items: center; padding: 20px 24px; border-bottom: 1px solid var(--wl-color-border); flex: none; }
.wl-cart-drawer__header h2 { margin: 0; font-size: 1.3rem; }
.wl-cart-drawer__close { background: none; border: none; font-size: 1.5rem; line-height: 1; cursor: pointer; color: var(--wl-color-text); padding: 4px; }

.wl-cart-drawer__body { flex: 1 1 auto; overflow-y: auto; padding: 20px 24px 24px; }
.wl-cart-drawer__empty { color: var(--wl-color-text-muted); margin: 40px 0; text-align: center; }

.wl-cart-drawer__items { list-style: none; margin: 0 0 20px; padding: 0; }
.wl-cart-drawer__item { display: flex; gap: 14px; padding: 18px 0; border-bottom: 1px solid var(--wl-color-border); }
.wl-cart-drawer__item:first-child { padding-top: 0; }
.wl-cart-drawer__item-media { position: relative; flex: none; width: 84px; aspect-ratio: 4 / 5; display: block; overflow: hidden; border-radius: var(--wl-radius-image); background: var(--wl-color-border); }
.wl-cart-drawer__item-media img { position: absolute; inset: 0; width: 100% !important; height: 100% !important; object-fit: cover; }
.wl-cart-drawer__item-body { flex: 1 1 auto; min-width: 0; }
.wl-cart-drawer__item-name { display: block; font-weight: 600; color: var(--wl-color-text); text-decoration: none; margin-bottom: 4px; }
.wl-cart-drawer__item-variation { margin: 0 0 10px; font-size: 0.82rem; color: var(--wl-color-text-muted); }
.wl-cart-drawer__item-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }

.wl-cart-drawer__qty { display: inline-flex; align-items: center; border: 1px solid var(--wl-color-border); border-radius: 999px; }
.wl-cart-drawer__qty-btn { width: 30px; height: 30px; border: none; background: none; cursor: pointer; font-size: 1rem; line-height: 1; color: var(--wl-color-text); display: flex; align-items: center; justify-content: center; }
.wl-cart-drawer__qty-btn:hover { background: var(--wl-color-bg); }
.wl-cart-drawer__qty-value { min-width: 22px; text-align: center; font-size: 0.9rem; }

.wl-cart-drawer__item-price { margin: 0; text-align: right; font-weight: 600; white-space: nowrap; }
.wl-cart-drawer__item-price-regular { display: block; font-weight: 400; font-size: 0.8rem; color: var(--wl-color-text-muted); }

.wl-cart-drawer__remove {
	display: inline-flex; align-items: center; gap: 5px;
	background: none; border: none; padding: 0; cursor: pointer;
	font-size: 0.8rem; color: var(--wl-color-text-muted); text-decoration: underline;
}
.wl-cart-drawer__remove:hover { color: var(--wl-color-sale); }

.wl-cart-drawer__summary { padding-top: 4px; }
.wl-cart-drawer__summary-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 6px 0; font-size: 0.9rem; color: var(--wl-color-text-muted); }
.wl-cart-drawer__summary-row--total { border-top: 1px solid var(--wl-color-border); margin-top: 8px; padding-top: 14px; font-size: 1.05rem; font-weight: 700; color: var(--wl-color-text); }
.wl-cart-drawer__summary-row--savings { color: #3a7a3a; font-weight: 600; }

.wl-cart-drawer__actions { display: flex; flex-direction: column; gap: 10px; margin-top: 20px; }
.wl-cart-drawer__actions .wl-btn { width: 100%; }

/* ==========================================================
   Sticky mobile add-to-cart bar (single product)
   ========================================================== */
.wl-sticky-atc {
	display: none;
	position: fixed; bottom: 0; left: 0; right: 0; z-index: 460;
	background: var(--wl-color-surface); border-top: 1px solid var(--wl-color-border);
	padding: 10px 16px; align-items: center; justify-content: space-between; gap: 12px;
}
.wl-sticky-atc__info { display: flex; align-items: center; gap: 10px; }
.wl-sticky-atc__info img { width: 44px; height: 44px; object-fit: cover; border-radius: 3px; }
.wl-sticky-atc__title { margin: 0; font-size: 0.85rem; }
.wl-sticky-atc__price { margin: 0; font-weight: 700; }
@media (max-width: 900px) { .wl-sticky-atc.is-visible { display: flex; } }

/* ==========================================================
   Installments / delivery estimator
   ========================================================== */
.wl-installments { font-size: 0.85rem; color: var(--wl-color-text-muted); }

/* Product accordion tabs */
.woocommerce-tabs ul.tabs { display: none !important; }
.woocommerce-tabs .wc-tab-accordion-heading {
	display: flex; width: 100%; justify-content: space-between; align-items: center;
	cursor: pointer; padding: 16px 0; margin: 0; font-size: 1rem; font-weight: 600;
	background: none; border: none; border-top: 1px solid var(--wl-color-border); text-align: left;
}
.woocommerce-tabs .wc-tab-accordion-heading::after {
	content: ''; width: 8px; height: 8px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
	transform: rotate(45deg); transition: transform 0.2s ease; flex: none;
}
.woocommerce-tabs .wc-tab-accordion-heading[aria-expanded="true"]::after { transform: rotate(-135deg); }
.woocommerce-tabs .wc-tab[hidden] { display: none; }
.woocommerce-tabs .wc-tab { padding-bottom: 16px; border-bottom: 1px solid var(--wl-color-border); }

/* Misc */
.wl-404 { text-align: center; padding: 80px 20px; }
.wl-404__popular ul { list-style: none; display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; padding: 0; }

/* ==========================================================
   Blog: single post, tags, comments
   ========================================================== */
.wl-post-tags { list-style: none; display: flex; gap: 8px; flex-wrap: wrap; padding: 0; margin: 24px 0 0; }
.wl-post-tags li a { display: inline-block; padding: 4px 12px; border: 1px solid var(--wl-color-border); border-radius: 999px; text-decoration: none; font-size: 0.8rem; }
.wl-related-posts { background: var(--wl-color-surface); }

.wl-comments-wrap { max-width: 860px; margin: 0 auto 60px; }
.wl-comments__title { font-size: 1.3rem; }
.wl-comments__list { list-style: none; margin: 0; padding: 0; }
.wl-comments__list .comment-body { padding: 16px 0; border-bottom: 1px solid var(--wl-color-border); }
.wl-comments__list .comment-author img { border-radius: 999px; vertical-align: middle; margin-right: 8px; }
.wl-comments__list ol.children { list-style: none; margin: 0 0 0 24px; padding: 0; }
#commentform input[type="text"],
#commentform input[type="email"],
#commentform input[type="url"],
#commentform textarea {
	width: 100%; padding: 10px; border: 1px solid var(--wl-color-border); border-radius: var(--wl-radius);
	margin-bottom: 12px; min-height: 44px; font-family: inherit;
}
#commentform textarea { min-height: 120px; }

.wl-blog-sidebar { max-width: 860px; margin: 0 auto 60px; padding-top: 24px; border-top: 1px solid var(--wl-color-border); }
.wl-widget { margin-bottom: 24px; }
.wl-widget__title { font-size: 1rem; text-transform: uppercase; letter-spacing: 0.06em; }

/* ==========================================================
   Contact Us page
   ========================================================== */
.wl-contact-page { padding: 56px 20px 96px; }

.wl-contact-split {
	display: grid;
	grid-template-columns: 1fr;
	gap: 48px;
	max-width: 1100px;
	margin: 0 auto;
	align-items: start;
}
@media (min-width: 900px) {
	.wl-contact-split { grid-template-columns: 0.85fr 1.15fr; gap: 64px; }
}

.wl-contact-intro { color: var(--wl-color-text-muted); font-size: 1.05rem; line-height: 1.6; margin-bottom: 36px; }
.wl-contact-intro p:last-child { margin-bottom: 0; }

.wl-contact-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.wl-contact-list__item {
	position: relative;
	display: flex;
	align-items: flex-start;
	gap: 18px;
	padding: 20px;
	margin: 0 -20px;
	border-radius: 14px;
	border: 1px solid transparent;
	transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
.wl-contact-list__item::after {
	/* subtle accent bar that slides in from the left on hover */
	content: '';
	position: absolute;
	left: 0;
	top: 14px;
	bottom: 14px;
	width: 3px;
	border-radius: 999px;
	background: var(--wl-color-accent);
	transform: scaleY(0);
	transition: transform 0.2s ease;
}
.wl-contact-list__item:hover,
.wl-contact-list__item:focus-within {
	background: var(--wl-color-surface);
	border-color: var(--wl-color-border);
	box-shadow: 0 10px 24px -12px rgba(28,26,23,0.18);
	transform: translateX(4px);
}
.wl-contact-list__item:hover::after,
.wl-contact-list__item:focus-within::after { transform: scaleY(1); }
.wl-contact-list__icon {
	flex: none;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 46px;
	height: 46px;
	border-radius: 999px;
	background: var(--wl-color-bg);
	color: var(--wl-color-accent);
	transition: background-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
}
.wl-contact-list__item:hover .wl-contact-list__icon,
.wl-contact-list__item:focus-within .wl-contact-list__icon {
	background: var(--wl-color-accent);
	color: #fff;
	transform: scale(1.08);
}
.wl-contact-list__icon svg { width: 20px; height: 20px; }
.wl-contact-list__item strong { display: block; font-size: 1rem; margin-bottom: 4px; }
.wl-contact-list__item a {
	display: inline-block;
	font-weight: 600;
	color: var(--wl-color-accent);
	text-decoration: none;
	background-image: linear-gradient(currentColor, currentColor);
	background-size: 0% 1px;
	background-repeat: no-repeat;
	background-position: 0 100%;
	transition: background-size 0.2s ease;
}
.wl-contact-list__item a:hover,
.wl-contact-list__item a:focus-visible { background-size: 100% 1px; }
.wl-contact-list__meta { display: block; font-size: 0.82rem; color: var(--wl-color-text-muted); margin-top: 4px; }
.wl-contact-list__address { display: block; font-weight: 600; line-height: 1.5; }

.wl-contact-form-panel {
	background: var(--wl-color-surface);
	border-radius: 16px;
	padding: 40px 32px;
	box-shadow: 0 1px 3px rgba(28,26,23,0.06), 0 20px 40px -20px rgba(28,26,23,0.18);
}
.wl-contact-form-panel h2 { font-size: 1.5rem; margin: 0 0 24px; }
@media (max-width: 480px) {
	.wl-contact-form-panel { padding: 28px 20px; border-radius: 12px; }
}

/* Contact Form 7 field styling */
.wl-contact-form .wpcf7-form label { display: block; margin-bottom: 20px; font-weight: 600; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--wl-color-text-muted); }
.wl-contact-form .wpcf7-form input[type="text"],
.wl-contact-form .wpcf7-form input[type="email"],
.wl-contact-form .wpcf7-form select,
.wl-contact-form .wpcf7-form textarea {
	display: block;
	width: 100%;
	margin-top: 8px;
	padding: 13px 14px;
	border: 1px solid var(--wl-color-border);
	border-radius: 8px;
	font-family: inherit;
	font-size: 0.95rem;
	font-weight: 400;
	text-transform: none;
	letter-spacing: normal;
	color: var(--wl-color-text);
	min-height: 46px;
	background: var(--wl-color-bg);
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.wl-contact-form .wpcf7-form input[type="text"]:focus,
.wl-contact-form .wpcf7-form input[type="email"]:focus,
.wl-contact-form .wpcf7-form select:focus,
.wl-contact-form .wpcf7-form textarea:focus {
	outline: none;
	border-color: var(--wl-color-accent);
	box-shadow: 0 0 0 3px rgba(122,92,62,0.15);
	background: var(--wl-color-surface);
}
.wl-contact-form .wpcf7-form textarea { min-height: 140px; resize: vertical; }
.wl-contact-form .wpcf7-form input[type="submit"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 14px 32px;
	min-height: 50px;
	width: 100%;
	border: none;
	border-radius: 999px;
	background: var(--wl-color-accent);
	color: #fff;
	font-weight: 600;
	font-size: 0.95rem;
	letter-spacing: 0.02em;
	cursor: pointer;
	transition: background-color 0.15s ease, transform 0.1s ease;
}
@media (min-width: 480px) {
	.wl-contact-form .wpcf7-form input[type="submit"] { width: auto; padding: 14px 40px; }
}
.wl-contact-form .wpcf7-form input[type="submit"]:hover { background: var(--wl-color-accent-dark); }
.wl-contact-form .wpcf7-form input[type="submit"]:active { transform: scale(0.98); }
.wl-contact-form .wpcf7-form input[type="submit"]:disabled { opacity: 0.6; cursor: default; transform: none; }
.wl-contact-form .wpcf7-not-valid { border-color: var(--wl-color-sale) !important; }
.wl-contact-form .wpcf7-not-valid-tip { color: var(--wl-color-sale); font-size: 0.8rem; font-weight: 400; text-transform: none; letter-spacing: normal; margin-top: 6px; }
.wl-contact-form .wpcf7-response-output {
	margin-top: 24px;
	padding: 14px 18px;
	border-radius: 8px;
	font-size: 0.9rem;
	border: 1px solid var(--wl-color-border);
}
.wl-contact-form form.sent .wpcf7-response-output { border-color: #3a7a3a; color: #245c24; background: #eef7ee; }
.wl-contact-form form.invalid .wpcf7-response-output,
.wl-contact-form form.failed .wpcf7-response-output { border-color: var(--wl-color-sale); color: var(--wl-color-sale); background: #fbeceb; }
.wl-contact-form .wpcf7-spinner { display: inline-block; margin-left: 10px; }

/* ==========================================================
   Shared "structured content page" building blocks — originally built
   for page-our-commitment.php, generalized so page-custom-furniture.php
   (and any future page needing this shape: hero, quick-nav, alternating
   image+text sections, closing band) reuses the same classes instead of
   near-duplicate page-specific CSS.
   ========================================================== */
/* Quick-jump pill row to each section below, in place of a single big
   intro image — each section already carries its own image further
   down, so a second shared image up here would just be redundant. */
.wl-page-quicknav { padding: 40px 20px 8px; }
.wl-page-quicknav ul { list-style: none; display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin: 0; padding: 0; }
.wl-page-quicknav a {
	display: inline-block;
	padding: 9px 18px;
	border: 1px solid var(--wl-color-border);
	border-radius: 999px;
	text-decoration: none;
	color: var(--wl-color-text);
	font-size: 0.88rem;
	transition: border-color 0.15s ease, background-color 0.15s ease;
}
.wl-page-quicknav a:hover { border-color: var(--wl-color-accent); background: var(--wl-color-bg); }

/* One alternating image+text block per section — "respective image for
   each section" — instead of one shared image up top. Odd sections show
   image-left/text-right, even sections flip via --reverse so the page
   doesn't read as a monotonous single-column repeat. */
.wl-page-sections { max-width: 1100px; margin: 0 auto; padding: 24px 20px 64px; }
.wl-feature-row {
	display: flex;
	align-items: center;
	gap: 48px;
	padding: 48px 0;
	border-top: 1px solid var(--wl-color-border);
	scroll-margin-top: 100px;
	flex-wrap: wrap;
}
.wl-feature-row:first-child { border-top: none; padding-top: 8px; }
.wl-feature-row--reverse { flex-direction: row-reverse; }
.wl-feature-row__media {
	position: relative;
	flex: 1 1 380px;
	max-width: 480px;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	border-radius: var(--wl-radius-image);
	background: var(--wl-color-border);
}
.wl-feature-row__media img { position: absolute; inset: 0; width: 100% !important; height: 100% !important; object-fit: cover; display: block; }
.wl-feature-row__copy { flex: 1 1 320px; }
.wl-feature-row__copy h2 { font-size: 1.5rem; margin: 0 0 12px; }
/* WhatsApp contact nudge under each section's copy (page-custom-furniture.php) —
   soft gradient card with a lift-on-hover shadow and a sliding arrow,
   rather than a plain bordered box, to read as an active CTA. */
.wl-feature-row__whatsapp {
	display: inline-flex;
	align-items: center;
	gap: 14px;
	max-width: 360px;
	margin-top: 24px;
	padding: 14px 18px;
	border-radius: 18px;
	background: linear-gradient(135deg, rgba(37,211,102,0.1), rgba(37,211,102,0.02));
	border: 1px solid rgba(37,211,102,0.22);
	text-decoration: none;
	color: var(--wl-color-text);
	box-shadow: 0 1px 2px rgba(20,17,13,0.04);
	transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}
.wl-feature-row__whatsapp:hover {
	transform: translateY(-3px);
	border-color: rgba(37,211,102,0.5);
	background: linear-gradient(135deg, rgba(37,211,102,0.16), rgba(37,211,102,0.04));
	box-shadow: 0 16px 32px -14px rgba(37,211,102,0.45);
}
.wl-feature-row__whatsapp-icon {
	display: flex; align-items: center; justify-content: center;
	flex: none;
	width: 44px; height: 44px;
	border-radius: 999px;
	background: linear-gradient(135deg, #2be676, #1fae56);
	color: #fff;
	box-shadow: 0 6px 16px -4px rgba(37,211,102,0.6);
}
.wl-feature-row__whatsapp-icon svg { width: 21px; height: 21px; }
.wl-feature-row__whatsapp-text { display: flex; flex-direction: column; gap: 2px; }
.wl-feature-row__whatsapp strong { font-size: 0.98rem; font-weight: 700; letter-spacing: -0.01em; }
.wl-feature-row__whatsapp-text span { font-size: 0.82rem; color: var(--wl-color-text-muted); line-height: 1.3; }
.wl-feature-row__whatsapp-arrow {
	display: flex; align-items: center; justify-content: center;
	flex: none;
	margin-left: 2px;
	color: #1fae56;
	transition: transform 0.2s ease;
}
.wl-feature-row__whatsapp:hover .wl-feature-row__whatsapp-arrow { transform: translateX(4px); }

/* Full-bleed closing band: a real image (reusing an existing category
   tile photo until real photography exists) with a dark gradient so
   light text stays legible regardless of the photo's own tones — same
   reasoning as the header logo/promo-bar contrast fixes elsewhere in
   this theme. Optionally holds a real CTA button (e.g. linking to
   Contact Us), not just text. */
.wl-cta-band {
	position: relative;
	background-color: var(--wl-color-text);
	background-size: cover;
	background-position: center;
	padding: 80px 0;
}
.wl-cta-band::before {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(to bottom, rgba(20,17,13,0.55), rgba(20,17,13,0.75));
}
.wl-cta-band__inner { position: relative; max-width: 640px; color: #fff; }
.wl-cta-band__inner h2 { font-size: 2rem; margin: 0 0 16px; }
.wl-cta-band__inner p { font-size: 1.05rem; opacity: 0.92; margin: 0; }
.wl-cta-band__button {
	display: inline-block;
	margin-top: 24px;
	padding: 13px 28px;
	background: #fff;
	color: var(--wl-color-text);
	border-radius: 999px;
	text-decoration: none;
	font-weight: 600;
	font-size: 0.92rem;
	transition: background-color 0.15s ease;
}
.wl-cta-band__button:hover { background: var(--wl-color-bg); }

@media (max-width: 700px) {
	.wl-feature-row,
	.wl-feature-row--reverse { flex-direction: column; gap: 24px; padding: 32px 0; }
	/* flex-basis applies to the main axis, which is now vertical (column
	   direction) instead of horizontal — so .wl-feature-row__media's own
	   "flex: 1 1 380px" (desktop rule) was being read as a 380px HEIGHT,
	   not width. Combined with its aspect-ratio:4/3, the browser then
	   derived width FROM that height (380 * 4/3 ≈ 507px) instead of from
	   the actual ~350px-wide column it sits in, overflowing well past
	   the screen edge. flex-basis:auto lets the explicit width:100% win
	   instead, so height derives correctly from aspect-ratio the other
	   way around. */
	.wl-feature-row__media { max-width: none; width: 100%; flex-basis: auto; }
	/* Same flex-basis-becomes-height issue as the media fix above —
	   .wl-feature-row__copy's desktop "flex: 1 1 320px" was forcing a
	   320px-tall text column on mobile even though its actual content
	   (heading + placeholder paragraph) only needed ~110px, leaving a
	   large dead gap before the next section's divider. */
	.wl-feature-row__copy { flex-basis: auto; }
	.wl-cta-band { padding: 56px 0; }
	.wl-cta-band__inner h2 { font-size: 1.5rem; }
}

/* ==========================================================
   Collections page (page-collections.php)
   Grid of the real product categories, styled after the
   dtalemodern.com/collections.html reference — each tile an image with
   the name overlaid at the bottom, not a separate label below it.
   ========================================================== */
.wl-collections-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 28px;
	padding: 48px 20px 80px;
}
.wl-collection-tile {
	position: relative;
	display: block;
	aspect-ratio: 4 / 3;
	border-radius: var(--wl-radius-image);
	overflow: hidden;
	text-decoration: none;
	color: inherit;
	background: var(--wl-color-border);
	box-shadow: 0 0 0 rgba(0,0,0,0);
	transition: transform 0.4s cubic-bezier(.25,.8,.25,1), box-shadow 0.4s ease;
}
.wl-collection-tile:hover { transform: translateY(-5px); box-shadow: 0 18px 34px -14px rgba(20,17,13,0.4); }
.wl-collection-tile__media { position: absolute; inset: 0; display: block; }
.wl-collection-tile__media img {
	width: 100% !important;
	height: 100% !important;
	object-fit: cover;
	transition: transform 0.6s cubic-bezier(.25,.8,.25,1);
}
.wl-collection-tile:hover .wl-collection-tile__media img { transform: scale(1.06); }
/* Bottom-up gradient so the overlaid name/count stays legible regardless
   of the photo's own tones — same reasoning as every other text-over-
   image treatment in this theme (header logo, promo bar, commitment
   band, room tiles). */
.wl-collection-tile::before {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(to top, rgba(20,17,13,0.72), transparent 60%);
	z-index: 1;
}
.wl-collection-tile__label {
	position: relative;
	z-index: 2;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	height: 100%;
	padding: 20px;
	color: #fff;
	font-size: 1.15rem;
	font-weight: 600;
}
.wl-collection-tile__count { font-size: 0.8rem; font-weight: 400; opacity: 0.85; margin-top: 2px; }

@media (max-width: 900px) {
	.wl-collections-grid { grid-template-columns: repeat(2, 1fr); gap: 18px; padding: 36px 16px 56px; }
}
@media (max-width: 560px) {
	.wl-collections-grid { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
	.wl-collection-tile,
	.wl-collection-tile__media img { transition: none; }
	.wl-collection-tile:hover { transform: none; }
	.wl-collection-tile:hover .wl-collection-tile__media img { transform: none; }
}

/* Floating WhatsApp + Call buttons (dtalemodern.com reference) — fixed
   bottom-right on every page, above the cart drawer's own z-index:901
   so it's still reachable while the drawer is open. */
.wl-floating-contact {
	position: fixed;
	right: 20px;
	bottom: 20px;
	z-index: 950;
	display: flex;
	flex-direction: column;
	gap: 12px;
}
.wl-floating-contact__btn {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 54px;
	height: 54px;
	border-radius: 50%;
	color: #fff;
	box-shadow: 0 4px 14px rgba(0,0,0,0.25);
	transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.wl-floating-contact__btn:hover {
	transform: translateY(-2px);
	box-shadow: 0 6px 18px rgba(0,0,0,0.3);
	color: #fff;
}
.wl-floating-contact__btn--whatsapp { background: #25D366; }
.wl-floating-contact__btn--call { background: #F5821F; }
@media (max-width: 640px) {
	.wl-floating-contact { right: 14px; bottom: 14px; gap: 10px; }
	.wl-floating-contact__btn { width: 48px; height: 48px; }
}
@media (prefers-reduced-motion: reduce) {
	.wl-floating-contact__btn { transition: none; }
	.wl-floating-contact__btn:hover { transform: none; }
}

/* ==========================================================================
   Account login/signup modal (dtalemodern.com reference) — see
   inc/account-auth.php (wl_render_account_modal()) and
   assets/js/account-modal.js. Centered card over a dim overlay, distinct
   from .mobile-nav's left-edge slide-out panel. */
.wl-account-modal[hidden] { display: none; }
.wl-account-modal__overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 800; }
.wl-account-modal__panel {
	position: fixed;
	top: 50%; left: 50%;
	transform: translate(-50%, -50%);
	z-index: 801;
	width: min(440px, 92vw);
	max-height: 90vh;
	overflow-y: auto;
	background: #fff;
	border-radius: 4px;
	padding: 40px 32px 32px;
	box-shadow: 0 20px 60px rgba(0,0,0,0.25);
	animation: wl-account-modal-in 0.2s ease;
}
@keyframes wl-account-modal-in {
	from { opacity: 0; transform: translate(-50%, -48%); }
	to { opacity: 1; transform: translate(-50%, -50%); }
}
.wl-account-modal__close {
	position: absolute; top: 16px; right: 16px;
	width: 32px; height: 32px;
	display: flex; align-items: center; justify-content: center;
	background: none; border: none;
	font-size: 1.4rem; line-height: 1;
	cursor: pointer;
	color: #111;
}
.wl-account-modal__title { font-family: var(--wl-font-heading); font-size: 1.6rem; font-weight: 400; margin: 0 0 24px; }
.wl-account-modal__error {
	background: #fdecea; color: #c0392b;
	border: 1px solid #f5c6c2;
	border-radius: 4px;
	padding: 10px 12px;
	font-size: 0.85rem;
	margin-bottom: 16px;
}
.wl-account-modal__success {
	background: #eafaf1; color: #1e8449;
	border: 1px solid #b7e4c7;
	border-radius: 4px;
	padding: 10px 12px;
	font-size: 0.85rem;
	margin-bottom: 16px;
}
.wl-account-modal__field { margin-bottom: 18px; }
.wl-account-modal__field input {
	width: 100%;
	padding: 13px 14px;
	border: 1px solid #d9d9d9;
	border-radius: 4px;
	font-size: 0.95rem;
	font-family: inherit;
	background: #fff;
	color: #111;
}
.wl-account-modal__field input:focus { outline: none; border-color: #111; }
.wl-account-modal__field--password { position: relative; }
.wl-account-modal__field--password input { padding-right: 60px; }
.wl-account-modal__show-toggle {
	position: absolute; top: 50%; right: 14px; transform: translateY(-50%);
	background: none; border: none;
	font-size: 0.82rem; font-weight: 600;
	color: var(--wl-color-text-muted);
	cursor: pointer;
	padding: 4px;
}
.wl-account-modal__field--phone { display: flex; align-items: center; border: 1px solid #d9d9d9; border-radius: 4px; overflow: hidden; }
.wl-account-modal__field--phone .wl-account-modal__prefix { padding: 13px 10px 13px 14px; color: #111; font-size: 0.95rem; border-right: 1px solid #d9d9d9; }
.wl-account-modal__field--phone input { border: none; border-radius: 0; }
.wl-account-modal__field--phone input:focus { outline: none; }
.wl-account-modal__label { display: block; font-size: 0.85rem; color: var(--wl-color-text-muted); margin-bottom: 8px; }
.wl-account-modal__hint { font-size: 0.85rem; color: var(--wl-color-text-muted); margin: -8px 0 20px; line-height: 1.5; }
.wl-account-modal__forgot { text-align: right; margin: -6px 0 20px; }
.wl-account-modal__actions { display: flex; gap: 12px; margin-bottom: 20px; }
.wl-account-modal__switch { text-align: center; font-size: 0.9rem; color: var(--wl-color-text-muted); margin: 18px 0 0; }
.wl-account-modal__link {
	background: none; border: none; padding: 0;
	font: inherit; font-weight: 600;
	color: #c9973a;
	cursor: pointer;
	text-decoration: none;
}
.wl-account-modal__link:disabled { color: var(--wl-color-text-muted); cursor: default; font-weight: 400; }
.wl-account-modal__divider { display: flex; align-items: center; gap: 12px; margin: 22px 0; color: var(--wl-color-text-muted); font-size: 0.85rem; }
.wl-account-modal__divider::before, .wl-account-modal__divider::after { content: ''; flex: 1; height: 1px; background: var(--wl-color-border); }
.wl-account-modal__social { display: flex; gap: 12px; }
.wl-account-modal__social-btn {
	flex: 1;
	display: flex; align-items: center; justify-content: center; gap: 8px;
	padding: 12px;
	border: 1px solid #d9d9d9;
	border-radius: 4px;
	background: #fff;
	font-size: 0.9rem; font-weight: 500;
	color: #111;
	cursor: not-allowed;
	opacity: 0.55;
}
@media (max-width: 480px) {
	.wl-account-modal__panel { padding: 32px 20px 24px; }
	.wl-account-modal__actions { flex-direction: column; }
}

/* Top-level category pages: subcategory boxes jump to that subcategory's
   own slider section (id="wl-cat-<slug>", see
   wl_render_category_showcase_section()) — offset for the sticky header. */
html { scroll-behavior: smooth; }
.wl-category-showcase { scroll-margin-top: 150px; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
