/* ==========================================================================
   Cellstronic - frontend redesign
   --------------------------------------------------------------------------
   Layered on top of the Machic parent theme. Nothing here dequeues or replaces
   parent or plugin CSS; every rule is additive and scoped to `.cs-redesign` on
   the body so the whole redesign can be disabled from one place.

   Pricing, add-to-cart, cart icon and footer widgets are hidden site-wide by
   rules in Customizer > Additional CSS. Those rules use !important and load
   after this file, so they always win. This stylesheet is written on the
   assumption that those elements are absent.

   Contents
     01  Design tokens
     02  Base + typography
     03  Buttons and links
     04  Header and navigation
     05  Mobile navigation
     06  Homepage
     07  Product cards
     08  Shop archive
     09  Single product
     10  Search
     11  Editorial pages (About / Contact)
     12  Footer
     13  Motion, focus and reduced-motion
   ========================================================================== */


/* 01  Design tokens
   ========================================================================== */

.cs-redesign {
	/* Brand palette, taken from the existing Elementor global kit so the
	   redesign stays on Cellstronic's own identity. */
	--cs-accent:        #3b5bfd;
	--cs-accent-hover:  #2f49d6;
	--cs-amber:         #f5a623;

	/* Neutrals */
	--cs-ink:           #1a1f36;
	--cs-ink-soft:      #6b7280;
	--cs-ink-faint:     #9aa1ad;
	--cs-surface:       #ffffff;
	--cs-surface-alt:   #f5f5f7;
	--cs-surface-deep:  #0f1220;
	--cs-hairline:      #e5e5ea;

	/* Type scale - fluid, Apple-style tight display leading */
	--cs-font-display: "Space Grotesk", "Helvetica Neue", Helvetica, Arial, sans-serif;
	--cs-font-body:    "DM Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;

	/* Curves are tuned so the ceiling is reached around 1280px rather than at
	   tablet width - the steeper original slope hit its 56px max at 768px,
	   which made headings oversized on tablets. */
	--cs-fs-display:   clamp(2.5rem, 2.086rem + 1.77vw, 3.5rem);   /* 40 -> 56 */
	--cs-fs-headline:  clamp(1.75rem, 1.44rem + 1.33vw, 2.5rem);   /* 28 -> 40 */
	--cs-fs-title:     clamp(1.375rem, 1.05rem + 1.3vw, 1.75rem);/* 22 -> 28 */
	--cs-fs-subhead:   clamp(1.1875rem, 1.05rem + 0.55vw, 1.5rem);
	--cs-fs-body:      1.0625rem;   /* 17px */
	--cs-fs-small:     0.875rem;    /* 14px */

	/* Rhythm */
	--cs-gutter:       12px;        /* tile separation */
	--cs-pad-x:        clamp(1.25rem, 0.5rem + 3vw, 3rem);
	--cs-section-y:    clamp(3.5rem, 2rem + 6vw, 7rem);
	--cs-max:          1220px;
	--cs-radius:       18px;
	--cs-radius-lg:    28px;
	--cs-pill:         980px;

	--cs-ease:         cubic-bezier(0.28, 0.11, 0.32, 1);
	--cs-shadow:       0 1px 2px rgba(16, 20, 40, 0.05), 0 12px 32px rgba(16, 20, 40, 0.07);
}


/* 02  Base + typography
   ========================================================================== */

.cs-redesign {
	font-family: var(--cs-font-body);
	font-size: var(--cs-fs-body);
	line-height: 1.47;
	letter-spacing: -0.011em;
	color: var(--cs-ink);
	background: var(--cs-surface);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	text-rendering: optimizeLegibility;
}

/* The homepage overflowed horizontally by ~5px on small screens. Contain it at
   the root rather than with a blanket overflow:hidden, which would break any
   position:sticky descendant. */
.cs-redesign,
.cs-redesign body {
	max-width: 100%;
	overflow-x: clip;
}

.cs-redesign h1,
.cs-redesign h2,
.cs-redesign h3,
.cs-redesign h4,
.cs-redesign .cs-display,
.cs-redesign .cs-headline {
	font-family: var(--cs-font-display);
	color: var(--cs-ink);
	letter-spacing: -0.022em;
	line-height: 1.08;
	font-weight: 700;
	margin-top: 0;
}

.cs-display {
	font-size: var(--cs-fs-display);
	margin: 0 0 0.5rem;
}

.cs-headline {
	font-size: var(--cs-fs-headline);
	margin: 0 0 0.75rem;
}

.cs-subhead {
	font-size: var(--cs-fs-subhead);
	line-height: 1.3;
	font-weight: 400;
	color: var(--cs-ink-soft);
	letter-spacing: -0.01em;
	margin: 0 0 1.5rem;
	max-width: 42ch;
}

.cs-eyebrow {
	display: inline-block;
	font-family: var(--cs-font-body);
	font-size: var(--cs-fs-small);
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--cs-accent);
	margin: 0 0 0.75rem;
}

.cs-shell {
	width: 100%;
	max-width: var(--cs-max);
	margin-inline: auto;
	padding-inline: var(--cs-pad-x);
}

.cs-center { text-align: center; }
.cs-center .cs-subhead { margin-inline: auto; }


/* 03  Buttons and links
   ========================================================================== */

.cs-redesign .cs-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	min-height: 44px;                 /* comfortable touch target */
	padding: 0.75rem 1.45rem;
	border: 1px solid transparent;
	border-radius: var(--cs-pill);
	font-family: var(--cs-font-body);
	font-size: var(--cs-fs-body);
	font-weight: 500;
	line-height: 1;
	text-decoration: none;
	cursor: pointer;
	transition: background-color 0.25s var(--cs-ease),
	            color 0.25s var(--cs-ease),
	            border-color 0.25s var(--cs-ease),
	            transform 0.25s var(--cs-ease);
}

.cs-redesign .cs-btn--primary {
	background: var(--cs-accent);
	color: #fff;
}

.cs-redesign .cs-btn--primary:hover,
.cs-redesign .cs-btn--primary:focus-visible {
	background: var(--cs-accent-hover);
	color: #fff;
}

.cs-redesign .cs-btn--secondary {
	background: var(--cs-surface-alt);
	color: var(--cs-ink);
}

.cs-redesign .cs-btn--secondary:hover,
.cs-redesign .cs-btn--secondary:focus-visible {
	background: #ebebf0;
	color: var(--cs-ink);
}

.cs-redesign .cs-btn--ghost {
	background: transparent;
	border-color: rgba(255, 255, 255, 0.5);
	color: #fff;
}

.cs-redesign .cs-btn--ghost:hover,
.cs-redesign .cs-btn--ghost:focus-visible {
	background: rgba(255, 255, 255, 0.14);
	border-color: #fff;
	color: #fff;
}

/* Quiet inline link with a chevron, used under tiles and rails. */
.cs-redesign .cs-link {
	display: inline-flex;
	align-items: center;
	gap: 0.3rem;
	color: var(--cs-accent);
	font-weight: 500;
	text-decoration: none;
}

.cs-redesign .cs-link::after {
	content: "\203A";
	font-size: 1.25em;
	line-height: 0;
	transform: translateY(-0.04em);
	transition: transform 0.25s var(--cs-ease);
}

.cs-redesign .cs-link:hover::after,
.cs-redesign .cs-link:focus-visible::after {
	transform: translate(0.2em, -0.04em);
}

.cs-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	align-items: center;
}

.cs-center .cs-actions { justify-content: center; }


/* 03b  Machic demo content suppression
   ==========================================================================
   The parent theme ships promotional modules populated from its demo import and
   configured in the KlbTheme options panel. They render placeholder copy
   ("Maecenas non erat", "Home Speaker", "Weekend Discount"), 2021 stock imagery
   unrelated to the catalogue, and `href="#"` buttons that go nowhere.

   They are suppressed here rather than in the theme options so that nothing in
   the parent theme or the database is modified -- deleting this block restores
   them exactly. On the shop archive they occupied 546px above the first real
   product. */

/* Shop archive: the yellow "Shop and Save Big on Hottest Products" strip and
   the three "Home Speaker" price banners. */
.cs-redesign .shop-banner-top,
.cs-redesign .shop-banner-bottom {
	display: none;
}

/* Header: the "Only this weekend / Super Products" discount module, which links
   to demo content and duplicates the promotion the catalogue cannot honour. */
.cs-redesign .discount-products-wrapper {
	display: none;
}


/* 04  Header and navigation
   ========================================================================== */

/* Machic markup: header#masthead.site-header > .header-desktop > .header-top
   + .header-main > .container > .header-wrapper > .column */

.cs-redesign .site-header {
	position: sticky;
	top: 0;
	z-index: 900;
	background: rgba(255, 255, 255, 0.72);
	-webkit-backdrop-filter: saturate(180%) blur(20px);
	backdrop-filter: saturate(180%) blur(20px);
	border-bottom: 1px solid transparent;
	transition: background-color 0.3s var(--cs-ease),
	            border-color 0.3s var(--cs-ease),
	            box-shadow 0.3s var(--cs-ease);
}

/* .is-stuck is toggled from JS once the page scrolls past the header. */
.cs-redesign .site-header.is-stuck {
	background: rgba(255, 255, 255, 0.88);
	border-bottom-color: var(--cs-hairline);
	box-shadow: 0 1px 24px rgba(16, 20, 40, 0.06);
}

/* The utility strip is visual noise at this size; fold it away and let the
   main row carry the navigation. */
.cs-redesign .site-header .header-top {
	background: transparent;
	border: 0;
	min-height: 0;
}

/* The stock header stacked to 165px: a 111px main row whose search field spanned
   1156px, above a 54px nav row. The row height came from an oversized search
   control rather than from padding, so the field is sized explicitly below and
   both rows are tightened. Net result is roughly 118px, with the logo, search
   and navigation in a deliberate relationship rather than a search bar with
   things either side of it. */
/* Trimmed now that a 58px mark sets the row height; the padding no longer needs
   to do the work of giving the brand presence. */
.cs-redesign .site-header .header-main {
	padding-block: 0.4rem;
}

.cs-redesign .site-header .header-main .header-wrapper {
	/* Machic adds 20px top and bottom here, which was 40px of the row's height
	   on top of a 44px logo. */
	padding-block: 0;
	min-height: 0;
	gap: 1.5rem;
	align-items: center;
}

.cs-redesign .site-header .header-wrapper {
	gap: 1.5rem;
	align-items: center;
}

.cs-redesign .site-header .header-nav {
	border-top: 1px solid var(--cs-hairline);
}

/* No padding of its own: the departments control and the menu links already
   carry theirs, and stacking the two pushed the row to 66px. */
.cs-redesign .site-header .header-nav .header-wrapper {
	min-height: 0;
	padding-block: 0;
	gap: 1.25rem;
}

/* The departments control shipped as a filled grey block sitting proud of the
   nav row, which read as a leftover component rather than part of the header.
   Flattened to match the menu links beside it. */
/* The control was a fixed 293px block, most of it empty, anchoring the left of
   the nav row with nothing in it. Sized to its content so it reads as a menu
   item rather than a panel. */
.cs-redesign .site-header .site-departments {
	width: auto;
	min-width: 0;
	flex: 0 0 auto;
}

/* Matched to the menu links beside it -- same size, weight, padding and radius,
   so the hamburger, its label and the nav read as one row rather than three
   separate components. */
.cs-redesign .site-header .site-departments > a,
.cs-redesign .site-header .site-departments .all-categories {
	display: flex;
	align-items: center;
	width: auto;
	min-width: 0;
	height: auto;
	background: transparent;
	border-radius: var(--cs-pill);
	padding: 0.5rem 0.95rem;
	gap: 0.5rem;
	font-family: var(--cs-font-body);
	font-size: 0.9375rem;
	font-weight: 500;
	letter-spacing: -0.01em;
	color: var(--cs-ink);
	white-space: nowrap;
	transition: background-color 0.2s var(--cs-ease);
}

/* The hamburger sat on its own baseline, adrift from its label. */
.cs-redesign .site-header .site-departments .departments-icon {
	display: flex;
	align-items: center;
	margin: 0;
	font-size: 17px;
	line-height: 1;
}

/* Machic pushes the caret to the far edge of the old fixed width. */
.cs-redesign .site-header .site-departments .departments-arrow {
	position: static;
	margin-left: 0.15rem;
}

.cs-redesign .site-header .site-departments > a:hover,
.cs-redesign .site-header .site-departments .all-categories:hover {
	background: var(--cs-surface-alt);
}

.cs-redesign .site-header .site-departments .departments-text {
	font-weight: 500;
	letter-spacing: -0.005em;
}

/* The asset is a 200x200 square whose wordmark is small within it, so 44px read
   as an icon rather than a brand. 58px gives it enough presence to anchor the
   header without the square driving the row height much further. */
.cs-redesign .site-brand img {
	height: auto;
	max-height: 58px;
	width: auto;
	transition: opacity 0.25s var(--cs-ease);
}

.cs-redesign .site-brand a:hover img { opacity: 0.72; }

/* Primary menu.
   ------------------------------------------------------------------
   Evenly spaced items at a single weight and size, the way a navigation bar
   should read. Previously the hamburger, the departments label and the menu
   links each sat on their own rhythm, which made the row look unsettled. */
.cs-redesign .site-header .header-nav .site-menu.primary > .menu {
	display: flex;
	align-items: center;
	gap: 0.35rem;
}

.cs-redesign .site-menu .menu > li > a {
	display: flex;
	align-items: center;
	font-family: var(--cs-font-body);
	font-size: 0.9375rem;
	font-weight: 500;
	letter-spacing: -0.01em;
	color: var(--cs-ink);
	padding: 0.5rem 0.95rem;
	border-radius: var(--cs-pill);
	text-transform: none;
	white-space: nowrap;
	transition: background-color 0.2s var(--cs-ease), color 0.2s var(--cs-ease);
}

.cs-redesign .site-menu .menu > li > a:hover,
.cs-redesign .site-menu .menu > li > a:focus-visible {
	background: var(--cs-surface-alt);
	color: var(--cs-ink);
}

.cs-redesign .site-menu .menu > li.current-menu-item > a {
	color: var(--cs-accent);
}

/* Departments / sidebar menu column
   ------------------------------------------------------------------
   Machic renders this list with `.collapse.show` on the homepage and positions
   it absolutely, but its wrapper is `position: static` -- so it resolves
   against the sticky header and floats over the page at every scroll position,
   covering the hero and the first product rail.

   Anchoring it to its own column fixes the positioning. Opening and closing is
   handled by initDepartmentsMenu() in cellstronic.js, which drives the theme's
   own control so Bootstrap's state stays consistent -- see the note there.

   The two rules below are the no-JS fallback for that: without them, and
   without JS, the homepage would render the panel open over the hero exactly
   as it did before. With JS they never apply, because init() drops `.no-js`
   from <html> and closes the panel on load. */
.cs-redesign .site-departments { position: relative; }

.no-js .cs-home .site-departments .departments-menu.show {
	opacity: 0;
	visibility: hidden;
	transform: translateY(-6px);
	transition: opacity 0.2s var(--cs-ease),
	            transform 0.2s var(--cs-ease),
	            visibility 0.2s var(--cs-ease);
}

.no-js .cs-home .site-departments:hover .departments-menu.show,
.no-js .cs-home .site-departments:focus-within .departments-menu.show {
	opacity: 1;
	visibility: visible;
	transform: none;
}

.cs-redesign .site-departments .departments-menu {
	border: 1px solid var(--cs-hairline);
	border-radius: var(--cs-radius);
	overflow: hidden;
	background: var(--cs-surface);
	box-shadow: var(--cs-shadow);
}

.cs-redesign .site-departments .departments-menu > li > a {
	font-size: var(--cs-fs-small);
	padding: 0.8rem 1.1rem;
	color: var(--cs-ink);
	border-bottom: 1px solid var(--cs-hairline);
	transition: background-color 0.2s var(--cs-ease), padding-left 0.2s var(--cs-ease);
}

.cs-redesign .site-departments .departments-menu > li:last-child > a { border-bottom: 0; }

.cs-redesign .site-departments .departments-menu > li > a:hover {
	background: var(--cs-surface-alt);
	padding-left: 1.35rem;
}

/* Search field in the header.
   Unconstrained it spanned the full 1156px of the row and became the loudest
   element on every page; capped and right-aligned it reads as a utility. */
/* Centre the search in the space beside the logo. Pinned to the right it left a
   wide void through the middle of the header and read as lopsided. */
.cs-redesign .site-header .header-main .header-wrapper > .column.right {
	flex: 1;
	display: flex;
	justify-content: center;
}

/* Sized down from 544px, and pinned to the right rather than centred: search is
   a utility that belongs with the other tools, not a centrepiece competing with
   the brand mark. */
.cs-redesign .header-form.site-search {
	max-width: 24rem;
	margin-left: auto;
	margin-right: 0;
	width: 100%;
}

.cs-redesign .header-form .search-form .input-group {
	/* Explicit height: the stock control rendered at 52px and was the tallest
	   thing in the row, which is what made the header 119px. */
	height: 42px;
	align-items: stretch;
	border: 1px solid var(--cs-hairline);
	border-radius: var(--cs-pill);
	background: var(--cs-surface-alt);
	overflow: hidden;
	transition: border-color 0.25s var(--cs-ease), background-color 0.25s var(--cs-ease);
}

/* The button and the category select both rendered at 50px inside a 42px pill,
   so they bulged out of it -- the single biggest thing making this header look
   unfinished. Everything in the group now matches the pill exactly. */
.cs-redesign .header-form .search-form .input-group > *,
.cs-redesign .header-form .search-form .input-group button,
.cs-redesign .header-form .search-form .input-group .form-select {
	height: 100%;
	min-height: 0;
	align-self: stretch;
	border-radius: 0;
}

.cs-redesign .header-form .search-form .input-group:focus-within {
	background: var(--cs-surface);
	border-color: var(--cs-accent);
	box-shadow: 0 0 0 4px rgba(59, 91, 253, 0.12);
}

.cs-redesign .header-form .search-form input[type="text"],
.cs-redesign .header-form .search-form input[type="search"],
.cs-redesign .header-form .search-form .form-select {
	border: 0;
	background: transparent;
	font-family: var(--cs-font-body);
	font-size: var(--cs-fs-small);
	color: var(--cs-ink);
	box-shadow: none;
}

/* A bright blue call-to-action on a utility field made search the loudest thing
   on every page. Search is a tool, not the headline -- so it reads as ink on a
   quiet ground, and the accent is reserved for actual calls to action. */
.cs-redesign .header-form .search-form button {
	border-radius: 0;
	background: var(--cs-ink);
	color: #fff;
	border: 0;
	font-size: var(--cs-fs-small);
	font-weight: 500;
	padding-inline: 1.35rem;
	white-space: nowrap;
	transition: background-color 0.25s var(--cs-ease);
}

.cs-redesign .header-form .search-form button:hover { background: #000; }

/* Category scope selector: a quiet label, separated by a hairline rather than
   sitting as a second control. */
.cs-redesign .header-form .search-form .form-select {
	border: 0;
	border-right: 1px solid var(--cs-hairline);
	padding: 0 1.75rem 0 1.1rem;
	font-size: var(--cs-fs-small);
	color: var(--cs-ink-soft);
	background-color: transparent;
}

/* Machic positions the magnifier absolutely at `left: 12px` inside the field.
   The input needs enough left padding to clear it, otherwise the glyph sits on
   top of the placeholder text. */
.cs-redesign .header-form .search-form .klbth-icon-search {
	left: 14px;
	width: auto;
	font-size: 15px;
	line-height: 1;
	color: var(--cs-ink-faint);
	pointer-events: none;
}

.cs-redesign .header-form .search-form input[type="text"],
.cs-redesign .header-form .search-form input[type="search"] {
	padding-left: 2.6rem;
	padding-right: 0.9rem;
}


/* 05  Mobile navigation
   ========================================================================== */

.cs-redesign .header-mobile {
	background: rgba(255, 255, 255, 0.9);
	-webkit-backdrop-filter: saturate(180%) blur(20px);
	backdrop-filter: saturate(180%) blur(20px);
}

.cs-redesign .header-mobile .site-brand img { max-height: 32px; }

/* Machic's fixed bottom bar - give it the same glass treatment and make the
   targets finger-sized. */
.cs-redesign .mobile-bottom-menu {
	background: rgba(255, 255, 255, 0.9);
	-webkit-backdrop-filter: saturate(180%) blur(20px);
	backdrop-filter: saturate(180%) blur(20px);
	border-top: 1px solid var(--cs-hairline);
	padding-bottom: env(safe-area-inset-bottom, 0);
}

.cs-redesign .mobile-bottom-menu .mobile-menu ul li a {
	min-height: 52px;
	color: var(--cs-ink);
	gap: 0.15rem;
}

.cs-redesign .mobile-bottom-menu .mobile-menu ul li a span {
	font-family: var(--cs-font-body);
	font-size: 10px;
	letter-spacing: 0.02em;
	color: var(--cs-ink-soft);
}

/* Offcanvas panel */
.cs-redesign .site-offcanvas,
.cs-redesign .offcanvas-body {
	background: var(--cs-surface);
}

.cs-redesign .site-offcanvas .menu > li > a {
	font-family: var(--cs-font-display);
	font-size: 1.25rem;
	font-weight: 600;
	padding-block: 0.85rem;
	color: var(--cs-ink);
	border-bottom: 1px solid var(--cs-hairline);
}


/* 06  Homepage
   ========================================================================== */

.cs-home-main { display: block; }

/* --- Hero ------------------------------------------------------------- */

.cs-hero {
	position: relative;
	display: grid;
	place-items: center;
	/* min-height already sets the stage; keep the vertical padding modest so the
	   hero does not overshoot the viewport on a laptop screen. */
	min-height: clamp(28rem, 24rem + 14vw, 38rem);
	padding: clamp(2.5rem, 1.5rem + 3vw, 4rem) var(--cs-pad-x);
	/* No gutter below: the hero ends on #0b0e18, which is exactly where the
	   paired tiles' canvas begins, so the two form one uninterrupted surface. */
	margin-bottom: 0;
	background: radial-gradient(120% 120% at 50% 0%, #1c2340 0%, #0f1220 55%, #0b0e18 100%);
	color: #fff;
	overflow: hidden;
	text-align: center;
}

.cs-hero__inner {
	position: relative;
	z-index: 2;
	max-width: 46rem;
}

.cs-hero .cs-display,
.cs-hero .cs-headline { color: #fff; }

.cs-hero .cs-subhead {
	color: rgba(255, 255, 255, 0.72);
	margin-inline: auto;
}

.cs-hero .cs-eyebrow { color: #8fa3ff; }

/* The hero is centre-aligned, but flex children default to flex-start, which
   left-aligned the CTA row under centred copy. */
.cs-hero .cs-actions { justify-content: center; }

/* Soft product glow behind the hero copy. */
.cs-hero__glow {
	position: absolute;
	inset: auto 50% -35% auto;
	transform: translateX(50%);
	width: min(52rem, 120vw);
	aspect-ratio: 1;
	background: radial-gradient(circle, rgba(59, 91, 253, 0.42) 0%, rgba(59, 91, 253, 0) 62%);
	pointer-events: none;
	z-index: 1;
}

.cs-hero__media {
	position: relative;
	z-index: 2;
	margin: 2.5rem auto 0;
	max-width: min(30rem, 82vw);
}

/* Same plate treatment as the feature tiles, for the same reason: the hero
   product shot also carries a white background. */
.cs-hero__media {
	padding: clamp(1rem, 0.5rem + 1.5vw, 1.75rem);
	background: linear-gradient(180deg, #ffffff 0%, #f2f2f5 100%);
	border-radius: var(--cs-radius-lg);
	box-shadow: 0 30px 70px rgba(0, 0, 0, 0.45);
}

.cs-hero__media img {
	width: auto;
	max-width: 100%;
	/* Cap the height so a tall product shot cannot push the hero far past the
	   viewport on tablet and mobile. */
	max-height: clamp(14rem, 10rem + 18vw, 22rem);
	height: auto;
	object-fit: contain;
	display: block;
	margin-inline: auto;
	mix-blend-mode: multiply;
}

/* --- Full-bleed feature tiles ----------------------------------------- */

.cs-tiles {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--cs-gutter);
	margin-bottom: var(--cs-gutter);
}

/* The paired tiles previously butted a flat light panel against a flat dark one,
   which split the page with a hard seam and read as two unrelated boxes. They
   now sit on a single continuous canvas that the hero flows into, so the hero
   and both tiles form one dark storytelling band before the catalogue opens
   into light. */
.cs-tiles--pair {
	position: relative;
	gap: 0;
	background:
		radial-gradient(80% 60% at 20% 0%, rgba(59, 91, 253, 0.16) 0%, rgba(59, 91, 253, 0) 60%),
		radial-gradient(80% 60% at 80% 100%, rgba(245, 166, 35, 0.10) 0%, rgba(245, 166, 35, 0) 60%),
		linear-gradient(180deg, #0b0e18 0%, #12172b 52%, #0c1020 100%);
	overflow: hidden;
}

@media (min-width: 768px) {
	.cs-tiles--pair { grid-template-columns: 1fr 1fr; }

	/* A soft light seam replaces the old colour boundary, so the two halves
	   stay distinguishable without being separate blocks. */
	.cs-tiles--pair > .cs-tile + .cs-tile::before {
		content: "";
		position: absolute;
		left: 0;
		top: 14%;
		bottom: 14%;
		width: 1px;
		background: linear-gradient(180deg,
			transparent 0%,
			rgba(255, 255, 255, 0.16) 50%,
			transparent 100%);
	}
}

.cs-tile {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: flex-start;
	text-align: center;
	/* No bottom padding: the product image is meant to run toward the lower
	   edge rather than sit in a padded box with dead space above it. */
	padding: clamp(3rem, 2rem + 3vw, 4.5rem) var(--cs-pad-x) clamp(2.5rem, 1.5rem + 3vw, 4rem);
	min-height: clamp(25rem, 21rem + 10vw, 32rem);
	background: transparent;
	color: #fff;
	overflow: hidden;
}

/* Standalone dark tile (the closing CTA) still paints its own ground. */
.cs-tile--dark {
	background: var(--cs-surface-deep);
	color: #fff;
}

/* Inside the pair the canvas below supplies the ground for both halves. */
.cs-tiles--pair > .cs-tile { background: transparent; }

.cs-tile .cs-headline,
.cs-tile .cs-display { color: #fff; }

.cs-tile .cs-subhead { color: rgba(255, 255, 255, 0.68); }

/* Per-tile accent bloom behind the product, so each half has its own centre of
   gravity while sharing one background. */
.cs-tiles--pair > .cs-tile::after {
	content: "";
	position: absolute;
	left: 50%;
	bottom: -26%;
	width: min(32rem, 115%);
	aspect-ratio: 1;
	transform: translateX(-50%);
	background: radial-gradient(circle, rgba(59, 91, 253, 0.30) 0%, rgba(59, 91, 253, 0) 62%);
	pointer-events: none;
	z-index: 0;
}

.cs-tiles--pair > .cs-tile:last-child::after {
	background: radial-gradient(circle, rgba(245, 166, 35, 0.20) 0%, rgba(245, 166, 35, 0) 62%);
}

.cs-tile__copy {
	position: relative;
	z-index: 2;
	max-width: 34rem;
}

/* Tiles are centre-aligned; keep their inline controls on the same axis. */
.cs-tile .cs-actions { justify-content: center; }
.cs-tile .cs-subhead { margin-inline: auto; margin-bottom: 1.25rem; }

/* Catalogue photography varies between landscape and portrait, so sizing the
   media by width gave the two halves visibly unequal weight. Fixing the height
   of the media band and letting the image size itself within it keeps both
   products on the same visual footing whatever their aspect ratio. */
.cs-tile__media {
	position: relative;
	z-index: 1;
	margin-top: auto;
	padding-top: clamp(1.25rem, 0.5rem + 2vw, 2.25rem);
	width: 100%;
	height: clamp(11rem, 7rem + 13vw, 17rem);
	display: flex;
	align-items: flex-end;
	justify-content: center;
}

/* The catalogue photography carries a baked-in white background, which on a
   dark canvas read as an accidental bright rectangle. Seating the product on a
   deliberate rounded plate that rises from the lower edge turns that white into
   an intentional surface. */
.cs-tiles--pair .cs-tile__media {
	max-width: min(26rem, 86%);
	margin-inline: auto;
	/* The plate is fully enclosed rather than bleeding off the tile's lower
	   edge -- clipped mid-product it read as a rendering fault, not as intent. */
	padding: clamp(1rem, 0.5rem + 1.5vw, 1.75rem);
	background: linear-gradient(180deg, #ffffff 0%, #f2f2f5 100%);
	border-radius: var(--cs-radius-lg);
	box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
}

.cs-tile__media img {
	max-height: 100%;
	max-width: min(24rem, 82%);
	width: auto;
	height: auto;
	display: block;
	object-fit: contain;
	mix-blend-mode: multiply;   /* drops the residual white on the plate */
	transition: transform 0.6s var(--cs-ease);
}

.cs-tile:hover .cs-tile__media img { transform: scale(1.035); }

/* --- Horizontal product rail ------------------------------------------ */

.cs-section {
	padding-block: var(--cs-section-y);
}

.cs-section--alt { background: var(--cs-surface-alt); }

.cs-section__head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	margin-bottom: 2.25rem;
}

.cs-section__head .cs-headline { margin-bottom: 0; }

.cs-rail {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: minmax(15rem, 1fr);
	gap: 1.25rem;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-padding-inline: var(--cs-pad-x);
	padding-bottom: 0.5rem;
	/* bleed to the viewport edge so cards run off-screen like a shelf */
	margin-inline: calc(var(--cs-pad-x) * -1);
	padding-inline: var(--cs-pad-x);
	scrollbar-width: thin;
}

.cs-rail > * { scroll-snap-align: start; }

.cs-rail::-webkit-scrollbar { height: 6px; }
.cs-rail::-webkit-scrollbar-track { background: transparent; }
.cs-rail::-webkit-scrollbar-thumb {
	background: var(--cs-hairline);
	border-radius: var(--cs-pill);
}

@media (min-width: 900px) {
	.cs-rail {
		grid-auto-flow: row;
		grid-template-columns: repeat(4, 1fr);
		overflow: visible;
		margin-inline: 0;
		padding-inline: 0;
	}
}

/* --- Category browse grid --------------------------------------------- */

.cs-cats {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
	gap: 1rem;
}

.cs-cat {
	position: relative;
	display: flex;
	flex-direction: column;
	/* Most product_cat terms have no thumbnail, which left a tall empty band
	   above the label. Pushing the label to the bottom and pinning a chevron to
	   the top corner gives the card intent whether or not an image exists. */
	justify-content: flex-end;
	min-height: 10rem;
	padding: 1.5rem;
	border-radius: var(--cs-radius-lg);
	background: var(--cs-surface);
	border: 1px solid var(--cs-hairline);
	text-decoration: none;
	color: var(--cs-ink);
	overflow: hidden;
	transition: transform 0.35s var(--cs-ease), box-shadow 0.35s var(--cs-ease);
}

.cs-cat:hover,
.cs-cat:focus-visible {
	transform: translateY(-4px);
	box-shadow: var(--cs-shadow);
	color: var(--cs-ink);
}

/* Affordance in the top corner, so a thumbnail-less card still reads as a
   destination rather than an empty box. */
.cs-cat::after {
	content: "\203A";
	position: absolute;
	top: 1.1rem;
	right: 1.35rem;
	font-size: 1.5rem;
	line-height: 1;
	color: var(--cs-ink-faint);
	transition: transform 0.25s var(--cs-ease), color 0.25s var(--cs-ease);
}

.cs-cat:hover::after {
	transform: translateX(0.2em);
	color: var(--cs-accent);
}

.cs-cat__name {
	font-family: var(--cs-font-display);
	font-size: 1.25rem;
	font-weight: 600;
	letter-spacing: -0.02em;
}

.cs-cat__count {
	font-size: var(--cs-fs-small);
	color: var(--cs-ink-soft);
	margin-top: 0.15rem;
}

.cs-cat__thumb {
	position: absolute;
	inset: 0 0 auto auto;
	width: 58%;
	opacity: 0.9;
	transform: translate(12%, -6%);
	transition: transform 0.5s var(--cs-ease);
	pointer-events: none;
}

.cs-cat:hover .cs-cat__thumb { transform: translate(8%, -8%) scale(1.05); }

.cs-cat__thumb img { width: 100%; height: auto; display: block; }

/* --- Trust / value strip ---------------------------------------------- */

.cs-values {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
	gap: 2rem;
	text-align: center;
}

.cs-value__title {
	font-family: var(--cs-font-display);
	font-size: 1.05rem;
	font-weight: 600;
	margin: 0 0 0.35rem;
}

.cs-value__text {
	font-size: var(--cs-fs-small);
	color: var(--cs-ink-soft);
	margin: 0;
}


/* 07  Product cards
   ==========================================================================
   Two card surfaces are styled: `.cs-card` (rendered by the child theme on the
   homepage) and Machic's own `.product-wrapper` markup used by the shop
   archive and related-product loops. They are kept visually identical. */

.cs-card,
.cs-redesign .product .product-wrapper {
	position: relative;
	height: 100%;
	background: var(--cs-surface-alt);
	border: 1px solid transparent;
	border-radius: var(--cs-radius-lg);
	overflow: hidden;
	transition: transform 0.35s var(--cs-ease),
	            box-shadow 0.35s var(--cs-ease),
	            border-color 0.35s var(--cs-ease);
}

.cs-card:hover,
.cs-redesign .product .product-wrapper:hover {
	transform: translateY(-4px);
	border-color: var(--cs-hairline);
	/* Tighter than the general shadow token: the wide 32px bleed read as the
	   hovered card spilling onto its neighbours in a dense grid. */
	box-shadow: 0 2px 4px rgba(16, 20, 40, 0.05), 0 10px 22px rgba(16, 20, 40, 0.10);
	/* Lift cleanly above siblings rather than relying on paint order. */
	z-index: 2;
}

.cs-card__link {
	display: flex;
	flex-direction: column;
	height: 100%;
	text-decoration: none;
	color: inherit;
}

.cs-card__media,
.cs-redesign .product .thumbnail-wrapper {
	display: block;
	position: relative;
	aspect-ratio: 1 / 1;
	background: var(--cs-surface-alt);
	overflow: hidden;
}

.cs-card__media img,
.cs-redesign .product .thumbnail-wrapper img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	/* The source photography already carries generous white margin, so a large
	   frame padding on top of it made products read small in their cards. */
	padding: 7%;
	transition: transform 0.55s var(--cs-ease);
}

.cs-card:hover .cs-card__img,
.cs-redesign .product .product-wrapper:hover .thumbnail-wrapper img {
	transform: scale(1.06);
}

.cs-card__body {
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
	padding: 1.25rem 1.35rem 1.5rem;
	background: var(--cs-surface);
	flex: 1;
}

/* Product names vary from one line to two, which left rows of cards at
   different heights. Reserving two lines and clamping longer names keeps every
   card in the grid identical. */
.cs-card__title,
.cs-redesign .product .product-title {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	min-height: 2.5em;
}

/* Machic's loop card titles are `h3.product-title`; the WooCommerce core class
   is kept for loops that fall back to stock markup. */
.cs-card__title,
.cs-redesign .product .product-title,
.cs-redesign .product .product-title a,
.cs-redesign .product .woocommerce-loop-product__title {
	font-family: var(--cs-font-display);
	font-size: 1.0625rem;
	font-weight: 600;
	line-height: 1.25;
	letter-spacing: -0.015em;
	color: var(--cs-ink);
	margin: 0;
}

/* Category label, set above the product name as a quiet eyebrow so the name
   stays the loudest thing in the card. */
.cs-card__meta {
	font-size: 0.6875rem;
	font-weight: 500;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: var(--cs-ink-faint);
	line-height: 1.3;
}

/* Card affordance.
   Rests at partial opacity and settles into place on hover, so a grid of cards
   stays calm but each one clearly reads as a destination. */
.cs-card__cta {
	display: block;
	margin-top: 0.5rem;
	font-size: var(--cs-fs-small);
	font-weight: 500;
	color: var(--cs-accent);
	opacity: 0.55;
	transform: translateY(2px);
	transition: opacity 0.28s var(--cs-ease), transform 0.28s var(--cs-ease);
}

.cs-card__cta::after {
	content: "\203A";
	margin-left: 0.25rem;
	display: inline-block;
	transition: transform 0.25s var(--cs-ease);
}

.cs-card:hover .cs-card__cta,
.cs-redesign .product .product-wrapper:hover .cs-card__cta {
	opacity: 1;
	transform: none;
}

.cs-card:hover .cs-card__cta::after,
.cs-redesign .product .product-wrapper:hover .cs-card__cta::after {
	transform: translateX(0.25em);
}

/* Media lifts very slightly with the card, so the product leads the motion
   rather than the frame. */
.cs-card__media,
.cs-redesign .product .thumbnail-wrapper {
	transition: background-color 0.35s var(--cs-ease);
}

.cs-card:hover .cs-card__media,
.cs-redesign .product .product-wrapper:hover .thumbnail-wrapper {
	background: #eeeef2;
}

/* Machic card padding, matched to the child-theme card. */
.cs-redesign .product .product-content {
	display: flex;
	flex-direction: column;
	height: 100%;
}

/* Machic spaces the thumbnail and the text block for a card that also showed a
   price row and action buttons. Both are hidden site-wide, so that spacing was
   left as 40px of empty card below the title -- invisible against the white
   page until the hover border and shadow drew the card's real bounds, which is
   what made a hovered card look like it was growing over its neighbour. */
.cs-redesign .product .thumbnail-wrapper { margin-bottom: 0; }
.cs-redesign .product .content-wrapper { margin-top: 0; }

/* Machic's hover reveal.
   ------------------------------------------------------------------
   productHover.js adds `.custom-hover` to every loop card and sets an inline
   `margin-bottom: -<footer height>` on `.product-content-fade`, which hides a
   `.product-footer` underneath. Hovering releases that margin, so the card
   grows by roughly 48px and pushes over the row beneath it -- the overlap that
   shows up on the shop grid.

   The footer only repeats the product's short description ("16PROMAX" under
   "Iphone 16PROMAX"), and the price and add-to-cart it was built around are
   hidden site-wide, so there is nothing worth revealing. Neutralising the
   negative margin keeps every card a fixed height and stops the reveal.

   !important is required because the margin is an inline style written by JS. */
/* This wrapper also carries its own white ground, 8px radius and shadow, and it
   is larger than the card itself (233x374 against 213x363) -- so it showed as a
   square-cornered panel poking out behind the rounded card. Its only purpose
   was the hover reveal, which is disabled above, so it is made invisible while
   still holding its children. */
/* Removed outright rather than just made invisible: the element is empty in the
   markup, and it was still claiming height -- 582px on the product page, which
   inflated related-product cards to 571px when their content is 435px. */
.cs-redesign .product .product-content-fade {
	display: none !important;
}

.cs-redesign .product .product-footer {
	display: none !important;
}

.cs-redesign .product .product-wrapper .product-details,
.cs-redesign .product .product-wrapper .content-wrapper {
	padding: 1.25rem 1.35rem 1.5rem;
	background: var(--cs-surface);
	flex: 1;
}


/* 08  Shop archive
   ========================================================================== */

/* The archive now opens with a breadcrumb and the editorial header, both of
   which carry their own spacing. The extra 56px of content padding on top of
   that read as a dead band under the navigation. */
.cs-redesign.woocommerce-shop .site-content,
.cs-redesign.post-type-archive-product .site-content,
.cs-redesign.tax-product_cat .site-content {
	padding-top: 0;
}

/* Editorial archive header.
   Injected via woocommerce_before_shop_loop, so it sits at the top of the
   product column. Left-aligned to lead the grid rather than float above it. */
.cs-archive-head {
	padding: 0 0 clamp(1.25rem, 0.9rem + 1.2vw, 1.75rem);
	margin-bottom: clamp(1.25rem, 0.9rem + 1.2vw, 1.75rem);
	border-bottom: 1px solid var(--cs-hairline);
	text-align: left;
}

.cs-archive-head .cs-headline {
	margin-bottom: 0.4rem;
}

.cs-archive-head__meta {
	font-size: var(--cs-fs-subhead);
	line-height: 1.35;
	color: var(--cs-ink-soft);
	max-width: 52ch;
	margin: 0;
}

/* Category chips - real terms with real counts, so categories and products read
   as one catalogue instead of a sidebar filter bolted onto a grid. */
.cs-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin-top: 1.5rem;
}

.cs-redesign .cs-chip {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	min-height: 38px;
	padding: 0.45rem 1rem;
	border: 1px solid var(--cs-hairline);
	border-radius: var(--cs-pill);
	background: var(--cs-surface);
	font-size: var(--cs-fs-small);
	font-weight: 500;
	color: var(--cs-ink);
	text-decoration: none;
	white-space: nowrap;
	transition: background-color 0.2s var(--cs-ease),
	            border-color 0.2s var(--cs-ease),
	            color 0.2s var(--cs-ease);
}

.cs-redesign .cs-chip:hover,
.cs-redesign .cs-chip:focus-visible {
	background: var(--cs-surface-alt);
	border-color: var(--cs-ink-faint);
	color: var(--cs-ink);
}

.cs-redesign .cs-chip.is-current {
	background: var(--cs-ink);
	border-color: var(--cs-ink);
	color: #fff;
}

.cs-chip__count {
	font-size: 0.75rem;
	font-variant-numeric: tabular-nums;
	color: var(--cs-ink-faint);
}

.cs-redesign .cs-chip.is-current .cs-chip__count { color: rgba(255, 255, 255, 0.6); }

/* Breadcrumb: present for orientation, but demoted so it stops being the first
   thing the eye lands on.
   ------------------------------------------------------------------
   The run from the header to the first product measured 423px, most of it gaps
   between a breadcrumb, a toolbar and a heading that each carried their own
   generous spacing. Tightened here and below so the catalogue starts sooner. */
.cs-redesign .shop-page-header .woocommerce-breadcrumb,
.cs-redesign .woocommerce-breadcrumb {
	font-size: 0.8125rem;
	color: var(--cs-ink-faint);
	padding-block: 0.85rem 0;
	margin: 0;
}

/* Machic stacks 30px-plus margins on the breadcrumb block and on each row of
   the shop content. Between the header and the first product that added up to
   136px of pure gap, on top of 264px of actual content. These bring the
   catalogue up without collapsing the rhythm entirely. */
.cs-redesign .shop-page-header {
	margin-top: 0.85rem;
	margin-bottom: 0;
}

/* The two 30px margins are on `.before-shop-loop` (above the toolbar) and on
   the `.row.content-wrapper` that holds the sidebar and grid. */
.cs-redesign .shop-content .before-shop-loop {
	margin-top: 0.6rem;
	padding-bottom: 0.35rem;
}

.cs-redesign .shop-content .row.content-wrapper {
	margin-top: 0.85rem;
}

.cs-redesign .filter-wrapper {
	margin-block: 0;
}

.cs-redesign .woocommerce-breadcrumb a { color: var(--cs-ink-faint); }
.cs-redesign .woocommerce-breadcrumb a:hover { color: var(--cs-ink-soft); }

.cs-redesign .woocommerce-products-header__title,
.cs-redesign .page-title {
	font-family: var(--cs-font-display);
	font-size: var(--cs-fs-headline);
	font-weight: 700;
	letter-spacing: -0.022em;
	margin: 0 0 0.5rem;
}

.cs-redesign .term-description,
.cs-redesign .woocommerce-products-header p {
	font-size: var(--cs-fs-subhead);
	color: var(--cs-ink-soft);
	max-width: 46ch;
	margin-inline: auto;
}

/* Product grid
   ------------------------------------------------------------------
   Machic does NOT use WooCommerce's `ul.products > li.product`. It renders
   `div.products.column-N` as a flex row of `div.product` children, so the grid
   is applied to that container. The `ul.products` selectors are kept alongside
   for any loop that does fall back to core markup (related products, widgets). */
/* `.related.products` and `.up-sells.products` are section wrappers that happen
   to carry the same `products` class as the grid inside them. Without this the
   grid rule applied twice -- a 4-column grid nested inside a 4-column grid --
   which squeezed related-product cards down to 56px wide. */
.cs-redesign .related.products,
.cs-redesign .up-sells.products,
.cs-redesign .cross-sells.products {
	display: block;
	grid-template-columns: none;
}

.cs-redesign .products,
.cs-redesign ul.products {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 1rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

@media (min-width: 640px) {
	.cs-redesign .products,
	.cs-redesign ul.products { grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
}

@media (min-width: 1024px) {
	.cs-redesign .products,
	.cs-redesign ul.products { grid-template-columns: repeat(4, 1fr); gap: 1.5rem; }

	/* Machic's own column count wins where it asks for fewer columns. `column-6`
	   is used for related products; four keeps those cards the same width as
	   the shop grid rather than squeezing six into the content column. */
	.cs-redesign .products.column-3 { grid-template-columns: repeat(3, 1fr); }
	.cs-redesign .products.column-2 { grid-template-columns: repeat(2, 1fr); }
	.cs-redesign .products.column-6 { grid-template-columns: repeat(4, 1fr); }
}

/* List view.
   ------------------------------------------------------------------
   The toolbar's grid/list switch renders `.products.list-view-products`. The
   grid rules above would otherwise force it into columns and make the switch
   look broken, so it is laid out as full-width rows: media left, copy centred
   beside it. */
.cs-redesign .products.list-view-products {
	display: flex;
	flex-direction: column;
	gap: 1rem;
}

/* Machic spaces list rows with `padding: 30px 0 0` plus a 15px top margin, and
   exempts the first row -- which left row one 31px shorter than every other.
   The flex `gap` above already handles the rhythm. */
.cs-redesign .products.list-view-products > .product {
	margin: 0;
	padding: 0;
}

.cs-redesign .products.list-view-products > .product .product-content {
	flex-direction: row;
	align-items: stretch;
}

.cs-redesign .products.list-view-products .thumbnail-wrapper {
	flex: 0 0 clamp(8rem, 6rem + 8vw, 14rem);
	width: clamp(8rem, 6rem + 8vw, 14rem);
	aspect-ratio: 1;
}

.cs-redesign .products.list-view-products .content-wrapper {
	flex: 1;
	display: flex;
	flex-direction: column;
	justify-content: center;
	padding-inline: clamp(1.25rem, 0.75rem + 2vw, 2rem);
}

/* A full-width row does not need the two-line reservation that keeps grid cards
   even, but the clamp stays: without it a wrapped title made some rows taller
   than the rest and the list read as ragged. */
.cs-redesign .products.list-view-products .product-title {
	min-height: 0;
	-webkit-line-clamp: 2;
	font-size: var(--cs-fs-title);
}

@media (max-width: 575px) {
	.cs-redesign .products.list-view-products > .product .product-content {
		flex-direction: column;
	}

	.cs-redesign .products.list-view-products .thumbnail-wrapper {
		flex-basis: auto;
		width: 100%;
	}

	.cs-redesign .products.list-view-products .content-wrapper {
		padding: 1.25rem 1.35rem 1.5rem;
	}
}

/* Neutralise the parent theme's flex/percentage-width sizing so the CSS grid
   above is the single source of layout truth. */
.cs-redesign .products > .product,
.cs-redesign ul.products li.product,
/* Related and up-sell loops carry a more specific Machic rule that puts
   44.8px / 89.6px of padding on each card -- 134px of empty height per tile. */
.cs-redesign .related.products .products > .product,
.cs-redesign .up-sells .products > .product,
.cs-redesign .cross-sells .products > .product {
	width: auto;
	max-width: none;
	margin: 0;
	padding: 0;
	float: none;
	clear: none;
	flex: none;
}

/* Toolbar: result count + ordering */
.cs-redesign .woocommerce-notices-wrapper:empty { display: none; }

.cs-redesign .shop-toolbar,
.cs-redesign .woocommerce-result-count,
.cs-redesign .woocommerce-ordering {
	font-size: var(--cs-fs-small);
	color: var(--cs-ink-soft);
}

.cs-redesign .woocommerce-ordering select,
.cs-redesign .form-select {
	border: 1px solid var(--cs-hairline);
	border-radius: var(--cs-pill);
	padding: 0.55rem 2rem 0.55rem 1rem;
	font-family: var(--cs-font-body);
	font-size: var(--cs-fs-small);
	background-color: var(--cs-surface);
	color: var(--cs-ink);
}

/* Sidebar filters.
   The real container is `.sidebar-column .widget` (an earlier guess at
   `.klbsidebarwidget` matched nothing). Boxing each widget made the column read
   as a stack of panels competing with the grid; hairline separators and more
   whitespace let the products stay the focus. */
.cs-redesign .sidebar-column {
	padding-right: clamp(0.5rem, 0.25rem + 1vw, 1.75rem);
}

.cs-redesign .sidebar-column .widget {
	border: 0;
	border-bottom: 1px solid var(--cs-hairline);
	border-radius: 0;
	padding: 0 0 1.5rem;
	margin-bottom: 1.5rem;
	background: transparent;
}

.cs-redesign .sidebar-column .widget:last-child {
	border-bottom: 0;
	margin-bottom: 0;
}

.cs-redesign .widget-title {
	font-family: var(--cs-font-body);
	font-size: 0.6875rem;
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--cs-ink-faint);
	margin: 0 0 1rem;
}

/* Category / status filters.
   Machic renders each row as <li><a><input type=checkbox><label>…</label></a>,
   so the row is styled through the anchor and the native control is replaced
   with a drawn box that can actually take a brand colour. */
.cs-redesign .widget-checkbox-list { list-style: none; margin: 0; padding: 0; }

.cs-redesign .widget-checkbox-list li { margin: 0; }

/* Machic sets the native input to display:none and uses the empty <span> in the
   label as the drawn control, so the span is styled here rather than the input
   -- restyling the input has no effect, and hiding the span removes the
   checkbox entirely. */
.cs-redesign .widget-checkbox-list li a {
	display: block;
	padding: 0.45rem 0.6rem;
	margin-inline: -0.6rem;
	border-radius: 10px;
	font-size: var(--cs-fs-small);
	color: var(--cs-ink-soft);
	text-decoration: none;
	transition: background-color 0.18s var(--cs-ease), color 0.18s var(--cs-ease);
}

.cs-redesign .widget-checkbox-list li a:hover {
	background: var(--cs-surface-alt);
	color: var(--cs-ink);
}

.cs-redesign .widget-checkbox-list label {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	margin: 0;
	cursor: pointer;
	line-height: 1.3;
}

.cs-redesign .widget-checkbox-list li a label > span {
	display: inline-block;
	flex: 0 0 auto;
	width: 17px;
	min-width: 17px;
	height: 17px;
	border: 1.5px solid var(--cs-hairline);
	border-radius: 5px;
	background: var(--cs-surface);
	transition: border-color 0.18s var(--cs-ease), background-color 0.18s var(--cs-ease);
}

.cs-redesign .widget-checkbox-list li a:hover label > span {
	border-color: var(--cs-ink-faint);
}

/* Checked state.
   ------------------------------------------------------------------
   `background-color` on this element is overridden somewhere in the parent
   theme's cascade that I could not isolate -- a literal colour in a rule
   appended last still lost, while `background-image` from the same rule applied
   cleanly. So the fill is painted as the bottom background layer instead of as
   a background-color, and the tick sits above it. Same result, and it does not
   depend on winning that particular battle. */
.cs-redesign .widget-checkbox-list li a input:checked + label > span {
	border-color: var(--cs-accent);
	background-image:
		linear-gradient(45deg, transparent 45%, #fff 45%, #fff 55%, transparent 55%),
		linear-gradient(-45deg, transparent 45%, #fff 45%, #fff 55%, transparent 55%),
		linear-gradient(var(--cs-accent), var(--cs-accent));
	background-size: 7px 2px, 7px 2px, 100% 100%;
	background-position: 3px 9px, 7px 9px, 0 0;
	background-repeat: no-repeat;
}

/* Nested sub-categories, indented and quieter than their parents. */
.cs-redesign .widget-checkbox-list ul {
	list-style: none;
	margin: 0.1rem 0 0.35rem 1.5rem;
	padding: 0;
}

.cs-redesign .widget-checkbox-list ul > li > a { font-size: 0.8125rem; }

/* Empty categories are hidden from this control, but the rule is generated in
   functions.php (cellstronic_hide_empty_filter_terms) rather than written here,
   because the set of empty terms is data and changes as the catalogue does.
   It is emitted as inline CSS attached to this stylesheet's handle. */

/* Empty result state.
   Filtering to a category that holds no products is a reachable state -- five
   of the sidebar's terms are empty -- and WooCommerce renders it as a bare line
   of text. Given a shape so it reads as a considered outcome. */
.cs-redesign .woocommerce-info,
.cs-redesign .woocommerce-no-products-found .woocommerce-info {
	display: block;
	padding: clamp(2.5rem, 1.5rem + 3vw, 4rem) 1.5rem;
	margin: 0;
	border: 1px solid var(--cs-hairline);
	border-radius: var(--cs-radius-lg);
	background: var(--cs-surface-alt);
	text-align: center;
	font-size: var(--cs-fs-subhead);
	color: var(--cs-ink-soft);
}

.cs-redesign .woocommerce-info::before {
	content: none;   /* drop WooCommerce's icon pseudo-element */
}

/* Active filter chips shown above the results ("Clear filters", "Battery").
   Machic renders these as `ul.remove-filter > li > a.remove-filter-element`. */
.cs-redesign .remove-filter {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin: 0 0 1.5rem;
	padding: 0;
	list-style: none;
}

.cs-redesign .remove-filter li { margin: 0; }

.cs-redesign .remove-filter .remove-filter-element {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	min-height: 32px;
	padding: 0.35rem 0.85rem;
	border: 1px solid var(--cs-hairline);
	border-radius: var(--cs-pill);
	background: var(--cs-surface);
	font-size: 0.8125rem;
	font-weight: 500;
	color: var(--cs-ink);
	text-decoration: none;
	transition: background-color 0.2s var(--cs-ease), border-color 0.2s var(--cs-ease);
}

.cs-redesign .remove-filter .remove-filter-element:hover {
	background: var(--cs-surface-alt);
	border-color: var(--cs-ink-faint);
}

/* "Clear filters" reads as the primary action of that row. */
.cs-redesign .remove-filter .clear-all {
	background: var(--cs-ink);
	border-color: var(--cs-ink);
	color: #fff;
}

.cs-redesign .remove-filter .clear-all:hover {
	background: #000;
	border-color: #000;
	color: #fff;
}

/* Pagination
   ------------------------------------------------------------------
   The <ul> itself carries `class="page-numbers"`, the same class as each link.
   Styling `.page-numbers` unqualified therefore hit the list as well as its
   items, giving the whole 923px row a 50% radius and a hover background -- the
   grey ellipse. Everything below is scoped to items inside an <li>. */
.cs-redesign .woocommerce-pagination ul.page-numbers {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: 0.4rem;
	border: 0;
	border-radius: 0;
	background: transparent;
	min-width: 0;
	min-height: 0;
	padding: 2.5rem 0 0;
	margin: 0;
	list-style: none;
}

.cs-redesign .woocommerce-pagination ul.page-numbers > li {
	border: 0;
	margin: 0;
	display: flex;
}

.cs-redesign .woocommerce-pagination li .page-numbers {
	display: grid;
	place-items: center;
	min-width: 42px;
	min-height: 42px;
	border-radius: 50%;
	border: 1px solid var(--cs-hairline);
	background: var(--cs-surface);
	font-size: var(--cs-fs-small);
	font-weight: 500;
	color: var(--cs-ink);
	text-decoration: none;
	transition: background-color 0.2s var(--cs-ease),
	            border-color 0.2s var(--cs-ease),
	            color 0.2s var(--cs-ease),
	            transform 0.2s var(--cs-ease);
}

.cs-redesign .woocommerce-pagination li a.page-numbers:hover {
	background: var(--cs-ink);
	border-color: var(--cs-ink);
	color: #fff;
	transform: translateY(-2px);
}

.cs-redesign .woocommerce-pagination li .page-numbers.current {
	background: var(--cs-ink);
	border-color: var(--cs-ink);
	color: #fff;
}

/* The ellipsis is a label, not a target. */
.cs-redesign .woocommerce-pagination li .page-numbers.dots {
	border-color: transparent;
	background: transparent;
	color: var(--cs-ink-faint);
}

/* Arrows read as controls rather than numbered pages. */
.cs-redesign .woocommerce-pagination li .page-numbers.prev,
.cs-redesign .woocommerce-pagination li .page-numbers.next {
	color: var(--cs-ink-soft);
	font-size: 1rem;
}


/* 09  Single product
   ========================================================================== */

.cs-redesign.single-product .klb-product-detail,
.cs-redesign.single-product div.product {
	padding-top: clamp(1.5rem, 1rem + 2vw, 3rem);
}

/* Gallery gets a large, calm, contained stage. */
.cs-redesign.single-product .woocommerce-product-gallery {
	background: var(--cs-surface-alt);
	border-radius: var(--cs-radius-lg);
	padding: clamp(1.5rem, 1rem + 3vw, 3rem);
}

.cs-redesign.single-product .woocommerce-product-gallery img {
	mix-blend-mode: multiply;   /* drops the white box on product cut-outs */
}

.cs-redesign.single-product .product_title {
	font-family: var(--cs-font-display);
	font-size: var(--cs-fs-headline);
	font-weight: 700;
	letter-spacing: -0.022em;
	line-height: 1.1;
	margin: 0 0 0.75rem;
}

.cs-redesign.single-product .woocommerce-product-details__short-description {
	font-size: var(--cs-fs-subhead);
	line-height: 1.4;
	color: var(--cs-ink-soft);
	margin-bottom: 1.5rem;
}

.cs-redesign.single-product .product_meta {
	font-size: var(--cs-fs-small);
	color: var(--cs-ink-soft);
	border-top: 1px solid var(--cs-hairline);
	padding-top: 1.25rem;
	margin-top: 1.5rem;
}

/* Fabricated scarcity notice.
   ------------------------------------------------------------------
   Machic renders "N people have this in their carts right now" from a value it
   generates: the same product reported 9 when captured and 1 on three
   consecutive loads afterwards, and sibling products showed 2 and 8. The cart
   redirects to the homepage, so nobody can have anything in a cart at all.

   It is a false statement shown to customers, so it is removed. Deleting this
   rule brings it back. */
.cs-redesign .people-have,
.cs-redesign .product-message.warning {
	display: none;
}

/* Variant chips
   ------------------------------------------------------------------
   Selectable pills under the product title. They are real buttons because
   they do something -- the selection is written into the WhatsApp enquiry
   message -- rather than static labels styled to look clickable. */
.cs-variants {
	margin: 1.5rem 0 0;
}

.cs-variants__group + .cs-variants__group {
	margin-top: 1rem;
}

.cs-variants__label {
	display: block;
	margin-bottom: 0.55rem;
	font-size: var(--cs-fs-small);
	font-weight: 500;
	color: var(--cs-ink-faint);
	letter-spacing: 0.02em;
}

.cs-variants__chips {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

.cs-chip {
	appearance: none;
	min-height: 44px;                 /* same touch target as the CTAs */
	padding: 0.5rem 1.05rem;
	border: 1px solid var(--cs-hairline);
	border-radius: var(--cs-pill);
	background: var(--cs-surface);
	color: var(--cs-ink);
	font-family: var(--cs-font-body);
	font-size: var(--cs-fs-small);
	font-weight: 500;
	line-height: 1.2;
	cursor: pointer;
	transition: border-color 0.2s var(--cs-ease),
	            background-color 0.2s var(--cs-ease),
	            color 0.2s var(--cs-ease);
}

.cs-chip:hover {
	border-color: var(--cs-ink);
}

.cs-chip[aria-pressed="true"] {
	background: var(--cs-ink);
	border-color: var(--cs-ink);
	color: #fff;
}

.cs-variants__note {
	margin: 0.9rem 0 0;
	font-size: var(--cs-fs-small);
	color: var(--cs-ink-faint);
}

/* Trade details.
   A quiet two-column list of facts read from the product itself, in place of
   the loose SKU line and stock pill. */
.cs-spec {
	margin: 1.75rem 0 0;
	padding: 1.5rem 0 0;
	border-top: 1px solid var(--cs-hairline);
	font-size: var(--cs-fs-small);
}

.cs-spec__row {
	display: flex;
	gap: 1rem;
	padding: 0.55rem 0;
	border-bottom: 1px solid var(--cs-hairline);
}

.cs-spec__row:last-child { border-bottom: 0; }

.cs-spec dt {
	flex: 0 0 9.5rem;
	color: var(--cs-ink-faint);
	font-weight: 500;
	margin: 0;
}

.cs-spec dd {
	margin: 0;
	color: var(--cs-ink);
	font-weight: 500;
}

/* Machic's own SKU/category lines are superseded by the list above.
   The theme prints the SKU twice under two similar but distinct class names --
   `.product-meta > .sku-wrapper` (hyphens) high in the column, and
   `.product_meta.product-categories` (underscore) below it, which also repeats
   the category. Both are now rows in .cs-spec, so both are hidden. */
.cs-redesign.single-product .klb-product-detail > .product-meta,
.cs-redesign.single-product .product_meta.product-categories,
.cs-redesign.single-product .product_meta .sku_wrapper,
.cs-redesign.single-product .product_meta .posted_in {
	display: none;
}

/* Same for the stock badge: "Availability" in .cs-spec says it in the same
   words, and the green pill read as a call to action next to the real one. */
.cs-redesign.single-product .klb-single-stock {
	display: none;
}

/* Click to Chat renders its own inline button in the summary. The enquiry panel
   below carries both calls to action, so the plugin's inline copy would be a
   third WhatsApp button on the same screen -- the floating bubble stays.
   The plugin's WooCommerce placement is `.ctc_chat.ctc_woo_place`, not the
   `.ht-ctc-chat` class used by its other placements; targeting the placement
   class leaves the floating bubble and any shortcode instance untouched.
   !important is required because Click to Chat writes `display: inline-block`
   as an inline style attribute on this element, which no stylesheet rule can
   otherwise outrank. */
.cs-redesign.single-product .ctc_chat.ctc_woo_place {
	display: none !important;
}

/* Enquiry block replaces the hidden add-to-cart control. */
/* The enquiry panel is the primary action on this page -- there is no cart, so
   this is the only route to a sale. Sized and weighted accordingly. */
.cs-enquiry {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.75rem;
	padding: clamp(1.25rem, 1rem + 1vw, 1.75rem);
	margin: 1.75rem 0 0;
	background: var(--cs-surface-alt);
	border-radius: var(--cs-radius);
}

.cs-enquiry .cs-btn {
	flex: 1 1 12rem;
	justify-content: center;
}

.cs-enquiry__note {
	flex-basis: 100%;
	margin: 0;
	font-size: var(--cs-fs-small);
	color: var(--cs-ink-soft);
}

/* Machic wraps the (hidden) add-to-cart form in a bordered panel, which was
   left as a large empty box around a single small button. */
.cs-redesign.single-product form.cart,
.cs-redesign.single-product .product-action-wrapper {
	border: 0;
	padding: 0;
	margin: 0;
	background: transparent;
}

/* Tabs */
.cs-redesign.single-product .woocommerce-tabs ul.tabs {
	display: flex;
	gap: 0.5rem;
	border-bottom: 1px solid var(--cs-hairline);
	padding: 0;
	margin: 0 0 2rem;
}

.cs-redesign.single-product .woocommerce-tabs ul.tabs::before,
.cs-redesign.single-product .woocommerce-tabs ul.tabs li::before,
.cs-redesign.single-product .woocommerce-tabs ul.tabs li::after {
	display: none;
}

.cs-redesign.single-product .woocommerce-tabs ul.tabs li {
	background: transparent;
	border: 0;
	border-radius: 0;
	margin: 0;
	padding: 0;
}

.cs-redesign.single-product .woocommerce-tabs ul.tabs li a {
	display: block;
	padding: 0.85rem 0.25rem;
	font-family: var(--cs-font-body);
	font-size: var(--cs-fs-body);
	font-weight: 500;
	color: var(--cs-ink-soft);
	border-bottom: 2px solid transparent;
	transition: color 0.2s var(--cs-ease), border-color 0.2s var(--cs-ease);
}

.cs-redesign.single-product .woocommerce-tabs ul.tabs li.active a,
.cs-redesign.single-product .woocommerce-tabs ul.tabs li a:hover {
	color: var(--cs-ink);
	border-bottom-color: var(--cs-ink);
}

/* Product page rhythm.
   ==========================================================================
   Modelled on the section cadence Apple uses on a product page: full-bleed
   grounds alternating between white and a light grey, one idea per section,
   and a lot of vertical air -- roughly 96px above and 110px below. The page
   previously ran gallery, tabs and related products together as one dense
   block. */

.cs-redesign.single-product .klb-product-detail,
.cs-redesign.single-product div.product {
	padding-bottom: clamp(3rem, 2rem + 4vw, 6rem);
}

/* Gallery gets more of the page and a calmer stage. */
.cs-redesign.single-product .woocommerce-product-gallery {
	padding: clamp(2rem, 1.25rem + 4vw, 4rem);
}

/* Summary column: quieter supporting detail, louder product name. */
.cs-redesign.single-product .product_title {
	font-size: clamp(2rem, 1.4rem + 2.4vw, 3rem);
	margin-bottom: 1rem;
}

.cs-redesign.single-product .product_meta,
.cs-redesign.single-product .sku_wrapper {
	font-size: var(--cs-fs-small);
	color: var(--cs-ink-soft);
}

/* Machic's stock and scarcity notices, given a considered shape rather than
   the default plugin styling. */
.cs-redesign.single-product .stock,
.cs-redesign.single-product .klb-single-low-stock {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.5rem 0.9rem;
	border-radius: var(--cs-pill);
	font-size: var(--cs-fs-small);
	font-weight: 500;
}

.cs-redesign.single-product .klb-single-low-stock {
	display: block;
	border-radius: var(--cs-radius);
	background: var(--cs-surface-alt);
	color: var(--cs-ink-soft);
	padding: 1rem 1.25rem;
	border: 0;
}

/* Tabs sit in their own band of air rather than butting the summary. */
.cs-redesign.single-product .woocommerce-tabs {
	margin-top: clamp(3rem, 2rem + 4vw, 6rem);
}

/* Related products become a full-bleed closing section on the grey ground,
   the way Apple closes a product page. The negative-margin bleed is bounded by
   the root `overflow-x: clip`, so it cannot introduce a horizontal scrollbar. */
/* `100vw` includes the scrollbar, so the bleed sat 8px wider than the content
   area and produced a horizontal scrollbar. Clipping at the full-width content
   wrapper keeps the ground edge-to-edge visually while containing the excess. */
.cs-redesign.single-product .site-content {
	overflow-x: clip;
}

.cs-redesign.single-product .related.products {
	position: relative;
	margin-top: clamp(3.5rem, 2rem + 5vw, 7rem);
	padding: clamp(3.5rem, 2rem + 5vw, 6rem) 0 clamp(4rem, 2.5rem + 6vw, 7rem);
	background: transparent;
}

/*
 * The grey ground is painted by a pseudo-element rather than by bleeding the
 * section itself with `width: 100vw`. 100vw includes the scrollbar, which added
 * 8px of horizontal overflow; an absolutely positioned layer behind the content
 * spans the viewport without affecting layout width at all.
 */
.cs-redesign.single-product .related.products::before {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	left: 50%;
	transform: translateX(-50%);
	width: 100vw;
	background: var(--cs-surface-alt);
	z-index: 0;
	pointer-events: none;
}

.cs-redesign.single-product .related.products > * {
	position: relative;
	z-index: 1;
}

.cs-redesign.single-product .related.products > * {
	max-width: var(--cs-max);
	margin-inline: auto;
}

/* Related products heading */
.cs-redesign .related.products > h2,
.cs-redesign .up-sells > h2 {
	font-family: var(--cs-font-display);
	font-size: var(--cs-fs-headline);
	font-weight: 700;
	letter-spacing: -0.022em;
	margin: 0 0 2rem;
	text-align: center;
}

/* On the grey ground the cards need a white frame to separate from it. */
.cs-redesign.single-product .related.products .product-wrapper {
	background: var(--cs-surface);
}

.cs-redesign.single-product .related.products .thumbnail-wrapper {
	background: var(--cs-surface);
}


/* 10  Search
   ========================================================================== */

.cs-redesign.search-results .site-content,
.cs-redesign.search-no-results .site-content {
	padding-block: clamp(2.5rem, 1.5rem + 4vw, 4.5rem);
}

.cs-search-head { text-align: center; margin-bottom: 2.5rem; }

.cs-search-head .cs-headline { margin-bottom: 0.35rem; }

.cs-search-head__meta {
	color: var(--cs-ink-soft);
	font-size: var(--cs-fs-body);
}

/* Machic AJAX search dropdown */
.cs-redesign .ajax-search-result,
.cs-redesign .klb-ajax-result {
	border: 1px solid var(--cs-hairline);
	border-radius: var(--cs-radius);
	box-shadow: var(--cs-shadow);
	overflow: hidden;
	background: var(--cs-surface);
}


/* 11  Editorial pages (About / Contact)
   ==========================================================================
   These pages are built in Elementor. Their structure is left untouched; only
   typography, rhythm and control styling are lifted so they sit in the same
   system as the rest of the site. */

.cs-redesign.page .elementor-widget-text-editor,
.cs-redesign.page .elementor-widget-theme-post-content {
	font-size: var(--cs-fs-body);
	line-height: 1.6;
	color: var(--cs-ink-soft);
}

.cs-redesign.page .elementor-heading-title {
	font-family: var(--cs-font-display);
	letter-spacing: -0.022em;
	line-height: 1.1;
	color: var(--cs-ink);
}

.cs-redesign.page .elementor-widget-text-editor p { margin-bottom: 1.15rem; }

/* Contact Form 7 */
.cs-redesign .wpcf7-form label {
	display: block;
	font-size: var(--cs-fs-small);
	font-weight: 500;
	color: var(--cs-ink);
	margin-bottom: 0.4rem;
}

.cs-redesign .wpcf7-form input[type="text"],
.cs-redesign .wpcf7-form input[type="email"],
.cs-redesign .wpcf7-form input[type="tel"],
.cs-redesign .wpcf7-form textarea {
	width: 100%;
	padding: 0.85rem 1.1rem;
	border: 1px solid var(--cs-hairline);
	border-radius: 14px;
	background: var(--cs-surface-alt);
	font-family: var(--cs-font-body);
	font-size: var(--cs-fs-body);
	color: var(--cs-ink);
	transition: border-color 0.2s var(--cs-ease), background-color 0.2s var(--cs-ease), box-shadow 0.2s var(--cs-ease);
}

.cs-redesign .wpcf7-form input:focus,
.cs-redesign .wpcf7-form textarea:focus {
	outline: none;
	background: var(--cs-surface);
	border-color: var(--cs-accent);
	box-shadow: 0 0 0 4px rgba(59, 91, 253, 0.12);
}

.cs-redesign .wpcf7-form textarea { min-height: 9rem; resize: vertical; }

.cs-redesign .wpcf7-form .wpcf7-submit {
	min-height: 48px;
	padding: 0.85rem 1.75rem;
	border: 0;
	border-radius: var(--cs-pill);
	background: var(--cs-accent);
	color: #fff;
	font-family: var(--cs-font-body);
	font-size: var(--cs-fs-body);
	font-weight: 500;
	cursor: pointer;
	transition: background-color 0.25s var(--cs-ease);
}

.cs-redesign .wpcf7-form .wpcf7-submit:hover { background: var(--cs-accent-hover); }


/* 12  Footer
   ========================================================================== */

.cs-redesign .site-footer {
	background: var(--cs-surface-alt);
	color: var(--cs-ink-soft);
	font-size: var(--cs-fs-small);
	margin-top: var(--cs-section-y);
}

/* The newsletter band renders a heading and a promise but no form: Mailchimp
   for WordPress has no API key configured, so `.subscribe-form` comes through
   empty. A sign-up call to action with nothing to sign up to is worse than no
   band at all, so it is suppressed until the plugin is connected. Deleting this
   rule brings it straight back. */
.cs-redesign .site-footer .footer-row.footer-newsletter {
	display: none;
}

/* Restore the footer navigation.
   ------------------------------------------------------------------
   Customizer > Additional CSS hides `.footer-row.footer-widgets`, which left a
   164px empty grey band where the footer's only content was a logo. That row
   holds genuinely useful links -- six real product categories plus the policy
   pages -- so it is brought back here with the specificity needed to beat an
   !important rule that loads after this file.

   This is the one place the redesign deliberately overrides an existing
   Customizer setting. Remove this block to hand control back to the Customizer. */
.cs-redesign .site-footer .footer-row.footer-widgets {
	display: block !important;
	padding-block: clamp(2rem, 1.25rem + 2.5vw, 3rem);
	border-bottom: 1px solid var(--cs-hairline);
}

/* Machic lays the footer out as five 25%-wide Bootstrap columns, but only three
   hold widgets -- so the content occupied 969px of a 1290px row and left a third
   of the footer empty. Distributing the populated columns across the full width
   closes that gap without touching which widgets are assigned where. */
.cs-redesign .site-footer .footer-widgets .row {
	display: flex;
	flex-wrap: wrap;
	gap: 2rem;
}

.cs-redesign .site-footer .footer-widgets .row > .col {
	flex: 1 1 0;
	max-width: none;
	width: auto;
	padding-inline: 0;
}

/* Columns with no widget assigned would otherwise still claim a share. */
.cs-redesign .site-footer .footer-widgets .row > .col:empty {
	display: none;
}

@media (max-width: 767px) {
	.cs-redesign .site-footer .footer-widgets .row > .col {
		flex-basis: 100%;
	}
}

.cs-redesign .site-footer .klbfooterwidget .widget-title {
	font-family: var(--cs-font-body);
	font-size: 0.6875rem;
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--cs-ink-faint);
	margin: 0 0 1rem;
}

.cs-redesign .site-footer .klbfooterwidget ul {
	list-style: none;
	margin: 0;
	padding: 0;
}

.cs-redesign .site-footer .klbfooterwidget li {
	margin-bottom: 0.6rem;
}

.cs-redesign .site-footer .klbfooterwidget a {
	font-size: var(--cs-fs-small);
	color: var(--cs-ink-soft);
}

.cs-redesign .site-footer .klbfooterwidget a:hover {
	color: var(--cs-ink);
}

/* Two of the restored menu links still point at the theme author's demo site,
   and one points at the account page, which redirects to the homepage. Hidden
   rather than followed into dead ends -- the underlying menus are content and
   are left untouched. */
.cs-redesign .site-footer a[href*="klbtheme.com"],
.cs-redesign .site-footer a[href*="/my-account"] {
	display: none;
}

.cs-redesign .site-footer a {
	color: var(--cs-ink-soft);
	text-decoration: none;
	transition: color 0.2s var(--cs-ease);
}

.cs-redesign .site-footer a:hover { color: var(--cs-ink); }

/* The brand row is a full-width band holding nothing but a 40px logo -- 120px
   tall, 80px of it padding. cellstronic.js moves the mark into the copyright
   bar below, which already carries the brand name and payment marks, and stamps
   `data-cs-relocated` once the move has actually happened. Without JS the
   attribute never appears and the original row simply stays. */
.cs-redesign .site-footer .footer-details[data-cs-relocated] {
	display: none;
}

.cs-redesign .site-footer .footer-details .container {
	padding-block: clamp(1.25rem, 0.9rem + 1vw, 1.75rem);
}

.cs-redesign .site-footer .footer-copyright {
	border-top: 1px solid var(--cs-hairline);
	padding-block: 0;
	font-size: 0.8125rem;
	color: var(--cs-ink-faint);
}

.cs-redesign .site-footer .footer-copyright .container {
	padding-block: 1.5rem;
}

/* Brand, copyright and payment marks on one baseline. */
.cs-redesign .site-footer .footer-copyright .row > .col {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 1rem 1.75rem;
}

.cs-redesign .site-footer .footer-copyright .site-brand {
	flex: 0 0 auto;
	margin: 0;
}

.cs-redesign .site-footer .footer-copyright .site-brand img {
	max-height: 34px;
	width: auto;
	display: block;
}

/* Machic wraps the copyright line and the payment marks together in
   `.footer-bottom` with space-between. Letting that block fill the space beside
   the logo spreads the three elements across the bar, rather than leaving a
   600px gap and bunching them on the right. */
.cs-redesign .site-footer .footer-copyright .footer-bottom {
	flex: 1 1 auto;
	min-width: 0;
}

/* Colophon rendered by the child theme's front page / footer additions. */
.cs-colophon {
	display: grid;
	gap: 2rem;
	grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
	padding-block: clamp(2.5rem, 1.5rem + 4vw, 4rem);
}

.cs-colophon__title {
	font-family: var(--cs-font-display);
	font-size: 0.9375rem;
	font-weight: 600;
	color: var(--cs-ink);
	margin: 0 0 0.85rem;
}

.cs-colophon ul { list-style: none; margin: 0; padding: 0; }
.cs-colophon li { margin-bottom: 0.5rem; }


/* 13  Motion, focus and reduced-motion
   ========================================================================== */

/* Scroll reveal. Elements start slightly low and faded; JS adds .is-in when
   they cross the viewport. If JS never runs the .no-js fallback keeps content
   visible, so content is never trapped behind an effect. */
.cs-reveal {
	opacity: 0;
	transform: translateY(18px);
	transition: opacity 0.7s var(--cs-ease), transform 0.7s var(--cs-ease);
	will-change: opacity, transform;
}

.cs-reveal.is-in,
.no-js .cs-reveal {
	opacity: 1;
	transform: none;
}

/* Stagger children within a rail or grid. */
.cs-reveal:nth-child(2) { transition-delay: 0.06s; }
.cs-reveal:nth-child(3) { transition-delay: 0.12s; }
.cs-reveal:nth-child(4) { transition-delay: 0.18s; }

/* Visible, consistent keyboard focus everywhere. */
.cs-redesign :focus-visible {
	outline: 2px solid var(--cs-accent);
	outline-offset: 3px;
	border-radius: 4px;
}

/* Skip link */
.cs-skip {
	position: absolute;
	left: 50%;
	top: 0;
	transform: translate(-50%, -120%);
	z-index: 1000;
	padding: 0.75rem 1.25rem;
	background: var(--cs-ink);
	color: #fff;
	border-radius: 0 0 12px 12px;
	text-decoration: none;
	transition: transform 0.2s var(--cs-ease);
}

.cs-skip:focus { transform: translate(-50%, 0); color: #fff; }

@media (prefers-reduced-motion: reduce) {
	.cs-redesign *,
	.cs-redesign *::before,
	.cs-redesign *::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}

	.cs-reveal { opacity: 1; transform: none; }
}
