/*
 * Express Shop chrome. WHM-56, approved direction.
 *
 * Loaded only when express_shop_chrome_visible() is true, so with the flag at 0
 * this file is never requested and the storefront is untouched.
 *
 * The chrome is the DARK half of the system: proof bar, header, category nav,
 * footer. Everything commercial between them stays light, either from the theme
 * underneath or from the plugin's own templates.
 *
 * No literal hex values below, with one exception noted at the proof bar. The
 * palette moved once already, orange to purple, and that cost hours precisely
 * because the old storefront hardcoded #FF6B00 fifty times inside page content.
 *
 * Phone-first. Desktop rules sit in one media query at the bottom.
 */

/* ---------------------------------------------------------------------------
   1. HIDE THE THEME CHROME

   Shoptimizer's header and footer are removed rather than restyled, because the
   plugin renders its own and two navigations is worse than either. The theme
   still renders everything BETWEEN them, which is the point of chrome-only
   takeover.

   !important is load-bearing here and only here: the theme's rules and Kirki's
   generated CSS both set display on these and are printed later in the
   document.
   --------------------------------------------------------------------------- */
body.express-chrome-on .site-header,
body.express-chrome-on #masthead,
body.express-chrome-on .storefront-primary-navigation,
body.express-chrome-on .col-full-nav,
body.express-chrome-on .mobile-bar,
body.express-chrome-on .site-footer,
body.express-chrome-on #colophon,
/* The footer trust widgets and the copyright are NOT inside .site-footer on
   this install: they sit in the .below-content widget region and a .copyright
   block that follow it. Hiding only .site-footer left the old footer rendering
   underneath the new one, which is how the first preview showed two footers.
   Found by reading the live markup, not by guessing at Shoptimizer's
   conventions. */
body.express-chrome-on .below-content,
body.express-chrome-on .copyright {
	display: none !important;
}

/* THE ANNOUNCEMENTS BAR.
   express-peds-announcements renders a rotating band (.ep-bar) carrying "Free
   Shipping On Orders Over £200" and the Telegram invite. Our proof bar already
   states the delivery threshold, read from the shipping zone, so with the
   chrome on the band is a duplicate claim in the old palette cutting across the
   new header.

   NOTE THE NAMESPACE COLLISION: that plugin uses the ep- prefix too (.ep-bar,
   .ep-bar__track, .ep-bar__slide). Nothing of ours is called ep-bar so there is
   no live conflict, but any new class here must be checked against it first. */
body.express-chrome-on .ep-bar {
	display: none !important;
}

body.express-chrome-on {
	background: var(--ep-lt-bg);
	color: var(--ep-lt-ink);
	font-family: var(--ep-font);
	font-size: var(--ep-t-base);
	line-height: var(--ep-lh-body);
	-webkit-font-smoothing: antialiased;
}

/* ---------------------------------------------------------------------------
   2. SHARED
   --------------------------------------------------------------------------- */
.ep-chrome, .ep-foot { font-family: var(--ep-font); }
.ep-chrome *, .ep-foot * { box-sizing: border-box; }

.ep-wrap {
	width: 100%;
	max-width: var(--ep-container);
	margin: 0 auto;
	padding: 0 var(--ep-gutter-now);
}

/* NO `color: inherit` HERE.
   This rule is (0,1,1) and every component class below it is (0,1,0), so a
   blanket colour here BEATS .ep-act and .ep-foot__col a (and the category nav that used to sit here). That is
   what made the category bar render near-black on the near-black ground in the
   first preview: the links took `inherit`, walked up past the nav row (which set no
   colour) to body, and landed on --ep-lt-ink.

   Links now take their colour from their own component rule, or inherit
   naturally from the container. Set a colour on the CONTAINER, never on a
   blanket descendant selector like this one. */
.ep-chrome a, .ep-foot a { text-decoration: none; }

.ep-chrome a:focus-visible,
.ep-foot a:focus-visible,
.ep-chrome button:focus-visible,
.ep-chrome input:focus-visible {
	outline: var(--ep-focus);
	outline-offset: var(--ep-focus-offset);
	border-radius: var(--ep-r-xs);
}

/* Every interactive target clears the 44px floor. The previous chrome had 32px
   targets in its pill, on a store used mostly on phones. */
.ep-chrome a, .ep-chrome button {
	min-height: var(--ep-tap);
	display: inline-flex;
	align-items: center;
}

/* ---------------------------------------------------------------------------
   3. PROOF BAR

   Carries only claims the shop can stand behind: the free-delivery threshold
   comes from the WooCommerce shipping zone, the cutoff is the real dispatch
   policy, and batch testing is the product programme. No borrowed review count.

   The gradient is the one place literal values appear: it is a single decorative
   ramp between two darker steps of --ep-ground, and expressing it as tokens
   would need two more tokens used nowhere else.
   --------------------------------------------------------------------------- */
.ep-proof {
	background: linear-gradient(90deg, #1B1030, #2A1A4A 50%, #1B1030);
	border-bottom: 1px solid var(--ep-edge);
	color: var(--ep-mut);
	font-size: var(--ep-t-xs);
}

.ep-proof__in {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--ep-s-3);
	min-height: var(--ep-tap);
	text-align: center;
	flex-wrap: wrap;
}

.ep-proof b { color: var(--ep-white); font-weight: var(--ep-w-semi); }
.ep-proof__sep { opacity: 0.4; display: none; }

.ep-proof__item { display: inline-flex; align-items: center; gap: 6px; }

/* ONE claim at a time on a phone. Seen on a real 375px screen: two claims
   wrapped onto two lines and pushed the wordmark and search further down an
   already tall header. They used to be simply hidden, so two of the three were
   never read by a phone visitor at all. Now they take turns.

   The hiding is gated on .is-rotating, which the script adds. Without it the
   :first-of-type rule below stands and one true claim is on screen, so a failed
   script leaves a correct bar rather than an empty one. */
.ep-proof__item:not(:first-of-type),
.ep-proof__sep { display: none; }

.ep-proof__in.is-rotating .ep-proof__item { display: none; }
.ep-proof__in.is-rotating .ep-proof__item.is-on {
	display: inline-flex;
	animation: epProofIn 420ms var(--ep-ease) both;
}
@keyframes epProofIn {
	from { opacity: 0; transform: translateY(4px); }
	to   { opacity: 1; transform: none; }
}

/* The live dot. Present only while the countdown is actually counting, so it
   is a signal rather than decoration: no dot means we are not dispatching
   today and the bar says so in words. */
.ep-proof__dot { display: none; }
.ep-proof__cut.is-live .ep-proof__dot {
	display: block;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--ep-ok);
	box-shadow: 0 0 0 0 rgba(52, 211, 153, 0.55);
	animation: epPulse 2.4s ease-out infinite;
	flex: none;
}
.ep-proof__cut.is-urgent .ep-proof__dot {
	background: #FBBF24;
	box-shadow: 0 0 0 0 rgba(251, 191, 36, 0.55);
}
.ep-proof__cut.is-urgent b { color: #FCD34D; }
@keyframes epPulse {
	0%   { box-shadow: 0 0 0 0 rgba(52, 211, 153, 0.5); }
	70%  { box-shadow: 0 0 0 7px rgba(52, 211, 153, 0); }
	100% { box-shadow: 0 0 0 0 rgba(52, 211, 153, 0); }
}
@media (prefers-reduced-motion: reduce) {
	.ep-proof__cut.is-live .ep-proof__dot { animation: none; }
	.ep-proof__in.is-rotating .ep-proof__item.is-on { animation: none; }
}

/* ---------------------------------------------------------------------------
   4. HEADER
   --------------------------------------------------------------------------- */
.ep-head {
	background: var(--ep-ground);
	border-bottom: 1px solid var(--ep-edge);
	color: var(--ep-white);
}

.ep-head__in {
	display: grid;
	grid-template-columns: auto auto 1fr;
	grid-template-areas:
		"burger brand acts"
		"search search search";
	align-items: center;
	gap: var(--ep-s-3) var(--ep-s-4);
	padding-top: var(--ep-s-3);
	padding-bottom: var(--ep-s-3);
}

.ep-head__brand { grid-area: brand; }
.ep-head__brand img { display: block; width: auto; height: 30px; }

.ep-mark {
	font-weight: var(--ep-w-black);
	font-size: var(--ep-t-xl);
	letter-spacing: var(--ep-track-hero);
	line-height: 1;
	white-space: nowrap;
	color: var(--ep-white);
}
.ep-mark em { font-style: normal; color: var(--ep-vio); }

/* --- search --- */
.ep-search {
	grid-area: search;
	display: flex;
	align-items: center;
	gap: var(--ep-s-3);
	height: var(--ep-control-md);
	padding: 0 var(--ep-s-2) 0 var(--ep-s-4);
	background: var(--ep-surf);
	border: 1px solid var(--ep-edge);
	border-radius: var(--ep-r-md);
	transition: border-color var(--ep-dur-1) var(--ep-ease);
}
/* THE PILL WEARS THE FOCUS RING, NOT THE INPUT INSIDE IT.

   .ep-chrome input:focus-visible above gives every chrome input a 2px outline
   at a -2px offset with a small radius. On a plain field that is right. On this
   one the input is a transparent strip inside a tall rounded pill, so the
   outline drew a sharp cornered rectangle INSIDE the rounded border: two
   nested boxes with different corners, which is what made it look broken.

   The ring is not removed, it is moved. Taking it off without replacing it
   would leave keyboard users with no idea where they are, on the one control
   that is hardest to locate by sight. The pill itself now takes a violet
   border and a soft ring, which is bigger and clearer than the outline it
   replaces, and it follows the corner radius that is actually there.

   focus-within rather than focus-visible, deliberately: a search field lighting
   up when clicked is useful feedback, not noise, and it means mouse and
   keyboard get the same obvious state. */
.ep-chrome .ep-search__input:focus,
.ep-chrome .ep-search__input:focus-visible {
	outline: none;
	border-radius: 0 !important;
	box-shadow: none !important;
}
.ep-search:focus-within {
	border-color: var(--ep-vio);
	box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.28);
}
.ep-search__icon { flex: none; color: var(--ep-mut); }
/* The !importants are load-bearing. Shoptimizer styles input[type="search"]
   with its own border, background, radius and inner shadow, and its selector
   beats this one, on a phone that drew a second bordered box INSIDE the search
   pill, around the placeholder. Seen on a real 375px screen, not deduced. */
.ep-search .ep-search__input {
	flex: 1; min-width: 0; height: 100%;
	border: 0 !important;
	outline: 0;
	background: transparent !important;
	box-shadow: none !important;
	border-radius: 0 !important;
	padding: 0 !important;
	font-family: inherit; font-size: var(--ep-t-sm);
	color: var(--ep-white);
	-webkit-appearance: none; appearance: none;
}
.ep-search__input::placeholder { color: var(--ep-mut); }
.ep-search__go {
	flex: none;
	height: var(--ep-control-sm);
	min-height: var(--ep-control-sm);
	padding: 0 var(--ep-s-5);
	border: 0;
	border-radius: var(--ep-r-sm);
	background: var(--ep-vio-deep);
	color: var(--ep-white);
	font-family: inherit;
	font-size: var(--ep-t-sm);
	font-weight: var(--ep-w-bold);
	cursor: pointer;
	justify-content: center;
	transition: background var(--ep-dur-1) var(--ep-ease), color var(--ep-dur-1) var(--ep-ease);
}
.ep-search__go:hover { background: var(--ep-vio); color: var(--ep-vio-ink); }

/* --- account + basket --- */
.ep-head__acts {
	grid-area: acts;
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: var(--ep-s-4);
	font-size: var(--ep-t-sm);
	font-weight: var(--ep-w-medium);
}
.ep-act { gap: var(--ep-s-2); color: var(--ep-white); border-radius: var(--ep-r-sm); }
.ep-act:hover { color: var(--ep-vio-2); }
.ep-act__label { display: none; }
.ep-act__count {
	min-width: 21px; height: 21px; padding: 0 6px;
	border-radius: var(--ep-r-full);
	background: var(--ep-vio);
	color: var(--ep-vio-ink);
	font-size: var(--ep-t-xs);
	font-weight: var(--ep-w-bold);
	display: inline-flex; align-items: center; justify-content: center;
	font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------
   5. CATEGORY NAV

   Scrolls horizontally on a phone rather than collapsing behind a hamburger.
   With eighteen categories, a menu you have to open to read is the thing that
   made this catalogue feel unbrowsable.
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   6. FOOTER
   --------------------------------------------------------------------------- */
.ep-foot {
	background: var(--ep-foot);
	color: var(--ep-mut);
	font-size: var(--ep-t-sm);
}

/* --- the credential strip ---
   Repeated at the foot because someone who has read the whole page leaves on
   it. Knocked white for the same reason as the hero: two brand palettes on one
   dark ground fight each other. */
.ep-foot__cred {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	gap: var(--ep-s-3) var(--ep-s-5);
	padding-top: var(--ep-s-6);
	padding-bottom: var(--ep-s-6);
	border-bottom: 1px solid var(--ep-edge);
}
.ep-foot__credl {
	font-size: 10px;
	font-weight: var(--ep-w-bold);
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--ep-mut);
}
.ep-foot__marks { display: flex; align-items: center; gap: var(--ep-s-5); }
.ep-foot__mk { display: block; line-height: 0; opacity: 0.72; }
.ep-foot__mk svg { display: block; height: auto; filter: brightness(0) invert(1); }
.ep-foot__mk:nth-child(1) svg { width: 58px; }
.ep-foot__mk:nth-child(2) svg { width: 82px; }

/* --- the main grid ---
   Mobile first and mobile shaped: the brand block full width, then the three
   link lists as a TWO column grid rather than three stacked lists. Stacked,
   this footer ran to most of a phone screen on its own; two up halves it and
   still leaves every link at a real tap size. */
.ep-foot__in {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--ep-s-6);
	padding-top: var(--ep-s-8);
	padding-bottom: var(--ep-s-6);
}
.ep-foot__about { margin: var(--ep-s-2) 0 var(--ep-s-4); max-width: 34ch; }
.ep-foot__brand .ep-social { max-width: 320px; }

.ep-foot__cols {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--ep-s-5) var(--ep-s-4);
}
.ep-foot__h {
	margin: 0 0 var(--ep-s-3);
	font-size: var(--ep-t-xs);
	font-weight: var(--ep-w-bold);
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--ep-white);
}
.ep-foot__col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.ep-foot__col li { margin: 0; }
/* THE ROW IS THE TAP TARGET, and it is a full --ep-tap tall on a phone.
   Padding alone gave 35px against this project's own 44px minimum, which is
   the sort of miss that only shows up when you measure it rather than look at
   it. Desktop drops back to padding, where a pointer does not need 44px. */
.ep-foot__col a {
	display: flex;
	align-items: center;
	min-height: var(--ep-tap);
	color: var(--ep-mut);
	transition: color var(--ep-dur-1) var(--ep-ease);
}
.ep-foot__col a:hover { color: var(--ep-white); }

/* --- dispatch and payment ---
   Gateways are printed from WooCommerce, so this row cannot claim a payment
   method the checkout does not actually offer. */
.ep-foot__strip {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--ep-s-3);
	padding-top: var(--ep-s-5);
	padding-bottom: var(--ep-s-5);
	border-top: 1px solid var(--ep-edge);
	font-size: var(--ep-t-xs);
}
.ep-foot__ship { display: inline-flex; align-items: center; gap: var(--ep-s-2); margin: 0; }
.ep-foot__ship b { color: var(--ep-white); font-weight: var(--ep-w-semi); }
.ep-foot__pay {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--ep-s-2) var(--ep-s-3);
	margin: 0;
}
.ep-foot__payl { color: var(--ep-mut); }

/* MONOCHROME, and that is the point of this version. The first one gave every
   mark its own white plate and brand colours, which put five bright rectangles
   along the bottom of a dark footer and pulled far more attention than a
   payment row should. In one muted colour they read as a quiet statement of
   fact, which is what they are.

   currentColor throughout, so the whole set is retinted from one declaration
   here rather than by editing six drawings. */
.ep-foot__pmset {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--ep-s-3);
	color: var(--ep-mut);
	opacity: 0.72;
}
.ep-foot__pm { display: block; line-height: 0; }
.ep-foot__pm svg { display: block; }

/* The enabled gateway keeps its pill: it is a different kind of claim to the
   marks beside it, being the one the checkout can actually honour today. */
.ep-foot__gw {
	padding: 4px 10px;
	border: 1px solid var(--ep-edge);
	border-radius: var(--ep-r-full);
	color: var(--ep-white);
	font-weight: var(--ep-w-semi);
}

.ep-foot__legal {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: var(--ep-s-3);
	border-top: 1px solid var(--ep-edge);
	padding-top: var(--ep-s-4);
	padding-bottom: var(--ep-s-8);
	font-size: var(--ep-t-xs);
}
.ep-foot__top {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	min-height: var(--ep-tap);
	color: var(--ep-mut);
}
.ep-foot__top:hover { color: var(--ep-white); }

/* ---------------------------------------------------------------------------
   7. PREVIEW RIBBON

   Flag state 2 only. Without it there is no way to tell, on the live domain,
   whether you are looking at the new chrome or the old site, and that
   ambiguity is how somebody flips the flag to 1 believing it already was.
   --------------------------------------------------------------------------- */
body.express-chrome-preview .ep-chrome::before {
	content: "Preview: not visible to customers";
	display: block;
	padding: 7px var(--ep-s-4);
	background: var(--ep-lt-warn-bg);
	color: var(--ep-lt-warn);
	font-size: var(--ep-t-xs);
	font-weight: var(--ep-w-semi);
	text-align: center;
}

/* ---------------------------------------------------------------------------
   8. DESKTOP
   --------------------------------------------------------------------------- */
@media (min-width: 900px) {

	/* All three at once, and the rotator stands down: it checks the same
	   breakpoint before it advances, so the two cannot disagree. */
	.ep-proof__item:not(:first-of-type) { display: inline-flex; }
	.ep-proof__in.is-rotating .ep-proof__item { display: inline-flex; }
	.ep-proof__sep { display: inline; }

	.ep-head__in {
		grid-template-columns: auto auto minmax(0, 1fr) auto;
		grid-template-areas: "burger brand search acts";
		gap: var(--ep-s-8);
		padding-top: var(--ep-s-4);
		padding-bottom: var(--ep-s-4);
	}
	.ep-head__brand img { height: 34px; }
	.ep-mark { font-size: 25px; }

	.ep-head__acts { gap: var(--ep-s-6); font-size: var(--ep-t-base); }
	.ep-act__label { display: inline; }


	.ep-foot__in {
		grid-template-columns: 1.5fr 2fr;
		gap: var(--ep-s-14);
		padding-top: var(--ep-s-14);
		padding-bottom: var(--ep-s-10);
	}
	.ep-foot__cols { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--ep-s-8); }
	.ep-foot__col a { min-height: 0; padding: 4px 0; }
	.ep-foot__mk:nth-child(1) svg { width: 74px; }
	.ep-foot__mk:nth-child(2) svg { width: 104px; }
}

/* ---------------------------------------------------------------------------
   THE BURGER AND THE MENU DRAWER

   REPLACES THE CATEGORY NAV ROW. That row fitted seven of eighteen categories,
   picked by product count, so eleven were reachable only through the homepage
   or a search. It also spent a whole band of vertical space above the fold on
   every page of a store whose traffic is almost entirely phones. The drawer
   holds the whole catalogue plus the pages and costs one button.
   --------------------------------------------------------------------------- */
.ep-burger {
	grid-area: burger;
	display: inline-flex;
	align-items: center;
	gap: var(--ep-s-2);
	height: var(--ep-control-md);
	padding: 0 var(--ep-s-3) 0 var(--ep-s-2);
	background: transparent;
	border: 1px solid var(--ep-edge);
	border-radius: var(--ep-r-md);
	color: var(--ep-white);
	font: inherit;
	font-size: var(--ep-t-xs);
	font-weight: var(--ep-w-bold);
	cursor: pointer;
	transition: border-color var(--ep-dur-1) var(--ep-ease);
}
.ep-burger:hover { border-color: var(--ep-vio); }
/* THE LABEL GOES ON THE NARROWEST PHONES. Measured at 375px, an iPhone SE
   width: burger plus wordmark plus the account and cart actions came to 391px
   in a 375px viewport, so the whole document scrolled sideways by 15px. The
   burger column is new, and it took the room the wordmark used to have.

   The icon keeps its aria-label, so nothing is lost but the word. */
@media (max-width: 399px) {
	.ep-burger__txt { display: none; }
	.ep-burger { padding: 0 var(--ep-s-2); }
}

.ep-burger__box { display: block; width: 16px; }
.ep-burger__box i {
	display: block;
	height: 2px;
	border-radius: 2px;
	background: currentColor;
	transition: transform var(--ep-dur-2) var(--ep-ease), opacity var(--ep-dur-1) var(--ep-ease);
}
.ep-burger__box i + i { margin-top: 3px; }
/* Open state: top and bottom bars cross, middle fades. */
.ep-burger[aria-expanded="true"] .ep-burger__box i:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.ep-burger[aria-expanded="true"] .ep-burger__box i:nth-child(2) { opacity: 0; }
.ep-burger[aria-expanded="true"] .ep-burger__box i:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

/* Scroll lock while the drawer is modal. */
.ep-locked, .ep-locked body { overflow: hidden; }

.ep-menu {
	position: fixed;
	inset: 0;
	z-index: 999;
}
.ep-menu[hidden] { display: none; }

.ep-menu__veil {
	position: absolute;
	inset: 0;
	background: rgba(5, 2, 10, 0.66);
	opacity: 0;
	transition: opacity var(--ep-dur-2) var(--ep-ease);
}
.ep-menu.is-open .ep-menu__veil { opacity: 1; }

.ep-menu__panel {
	position: absolute;
	inset: 0 auto 0 0;
	width: min(86vw, 380px);
	display: flex;
	flex-direction: column;
	background: var(--ep-surf);
	border-right: 1px solid var(--ep-edge);
	transform: translateX(-100%);
	transition: transform 240ms var(--ep-ease);
}
.ep-menu.is-open .ep-menu__panel { transform: none; }

.ep-menu__top {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--ep-s-3);
	padding: var(--ep-s-4);
	border-bottom: 1px solid var(--ep-edge);
	flex: none;
}
.ep-menu__title {
	font-size: var(--ep-t-xs);
	font-weight: var(--ep-w-bold);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--ep-mut);
}
.ep-menu__x {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	background: transparent;
	border: 1px solid var(--ep-edge);
	border-radius: var(--ep-r-sm);
	color: var(--ep-white);
	cursor: pointer;
}
.ep-menu__x:hover { border-color: var(--ep-vio); }

.ep-menu__body {
	flex: 1 1 auto;
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	padding: var(--ep-s-4) var(--ep-s-4) var(--ep-s-8);
}

.ep-menu__all {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--ep-s-3);
	min-height: var(--ep-control-md);
	padding: 0 var(--ep-s-4);
	margin-bottom: var(--ep-s-5);
	background: var(--ep-vio);
	border-radius: var(--ep-r-md);
	color: var(--ep-vio-ink) !important;
	font-size: var(--ep-t-sm);
	font-weight: var(--ep-w-bold);
	text-decoration: none;
}

.ep-menu__lbl {
	margin: 0 0 var(--ep-s-2);
	font-size: 11px;
	font-weight: var(--ep-w-bold);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--ep-mut);
}

.ep-menu__cats, .ep-menu__kids, .ep-menu__pages { list-style: none; margin: 0; padding: 0; }
.ep-menu__cats { margin-bottom: var(--ep-s-5); }
.ep-menu__cats > li + li { border-top: 1px solid var(--ep-edge); }

.ep-menu__cat,
.ep-menu__kids a,
.ep-menu__pages a {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--ep-s-3);
	padding: 11px 0;
	color: var(--ep-white) !important;
	font-size: var(--ep-t-sm);
	text-decoration: none;
}
.ep-menu__cat { font-weight: var(--ep-w-semi); }
.ep-menu__cat .ep-num, .ep-menu__kids .ep-num { color: var(--ep-mut); font-size: var(--ep-t-xs); }
.ep-menu__cat:hover, .ep-menu__kids a:hover, .ep-menu__pages a:hover { color: var(--ep-vio-2) !important; }

/* Children sit indented under their parent rather than in a second list, so
   the relationship is readable without an accordion nobody asked for. */
.ep-menu__kids { padding-left: var(--ep-s-3); border-left: 1px solid var(--ep-edge); margin-bottom: var(--ep-s-2); }
.ep-menu__kids a { padding: 8px 0; color: var(--ep-mut) !important; font-size: var(--ep-t-xs); }

.ep-menu__pages { margin-bottom: var(--ep-s-5); }
.ep-menu__pages > li + li { border-top: 1px solid var(--ep-edge); }

.ep-menu__comm { display: flex; gap: var(--ep-s-2); }
.ep-menu__comm .ep-social__h { min-height: 40px; font-size: var(--ep-t-xs); }
.ep-menu__home { display: flex !important; width: max-content; align-items: center; gap: 6px; margin: 2px 0 22px; font-size: var(--ep-t-sm); font-weight: var(--ep-w-semi); color: var(--ep-lt-mut) !important; text-decoration: none; }
.ep-menu__home:hover { color: var(--ep-lt-ink); }
.ep-menu__home { display: flex !important; width: max-content; align-items: center; gap: 6px; margin: 2px 0 22px; font-size: var(--ep-t-sm); font-weight: var(--ep-w-semi); color: var(--ep-lt-mut) !important; text-decoration: none; }
.ep-menu__home:hover { color: var(--ep-lt-ink); }

@media (prefers-reduced-motion: reduce) {
	.ep-menu__panel, .ep-menu__veil, .ep-burger__box i { transition: none; }
}

/* THE SOCIAL CAPSULE lives HERE, not in home.css, because the drawer above
   uses it and the drawer renders on every page while home.css loads only on
   the front page. The hero uses the same component.

   It replaced two saturated pills. The hero stacked violet, Telegram blue and
   WhatsApp green as three full width blocks: three unrelated hues at full
   strength with no hierarchy, so the eye had nowhere to land first. As one
   outlined object the page offers two decisions rather than three, and the
   platform colours survive on the icons, which is where they still read. */
.ep-social {
	display: flex;
	align-items: stretch;
	border: 1px solid var(--ep-edge);
	border-radius: var(--ep-r-full);
	background: rgba(255, 255, 255, 0.03);
	overflow: hidden;
}
.ep-social__h {
	flex: 1 1 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--ep-s-2);
	min-height: var(--ep-control-md);
	padding: 0 var(--ep-s-3);
	color: var(--ep-white) !important;
	font-size: var(--ep-t-sm);
	font-weight: var(--ep-w-bold);
	text-decoration: none;
	transition: background var(--ep-dur-1) var(--ep-ease);
}
.ep-social__h:hover { background: rgba(255, 255, 255, 0.06); }
.ep-social__d { width: 1px; background: var(--ep-edge); flex: none; }
/* Colour stays on the icons only. At 16px it is still the fastest way to
   recognise either app, and it costs the layout nothing. */
.ep-social__i--tg { color: #48B3E6; }
.ep-social__i--wa { color: #48B3E6; }

/* THE CATEGORY ROW, DESKTOP ONLY.
   Hidden by default and switched on at the same breakpoint that hides the
   burger, so exactly one of the two is ever present. Mobile first, so the
   phone pays for nothing it does not show. */
.ep-nav { display: none; }

@media (min-width: 900px) {
	/* .ep-chrome .ep-burger, not .ep-burger. The blanket
	   ".ep-chrome a, .ep-chrome button { display: inline-flex }" near the top
	   of this file is (0,1,1) and a bare .ep-burger is (0,1,0), so it lost and
	   the burger stayed visible next to the restored nav at every width. A
	   media query adds no specificity, which is exactly the trap. */
	.ep-chrome .ep-burger { display: none; }
	.ep-nav {
		display: block;
		background: var(--ep-ground);
		border-bottom: 1px solid var(--ep-edge);
		/* Explicit, so anything inside that inherits has somewhere sane to land. */
		color: var(--ep-mut);
	}
	/* IT MUST BE ABLE TO SCROLL. Nine categories in a flex row do not fit at
	   900px, and without this the row pushed the whole document 191px wider
	   than the viewport and every page gained a horizontal scrollbar. The
	   original row had overflow-x here; it was dropped when the row became
	   desktop only, on the assumption that a desktop always has room. It does
	   not at the breakpoint itself, and it would not after the next category
	   is added either. */
	.ep-nav__in {
		display: flex;
		align-items: stretch;
		gap: var(--ep-s-5);
		overflow-x: auto;
		scrollbar-width: none;
		-webkit-overflow-scrolling: touch;
	}
	.ep-nav__in::-webkit-scrollbar { display: none; }
	.ep-nav__item {
		flex: none;
		display: inline-flex;
		align-items: center;
		min-height: 50px;
		font-size: var(--ep-t-sm);
		color: var(--ep-mut);
		white-space: nowrap;
		transition: color var(--ep-dur-1) var(--ep-ease);
	}
	.ep-nav__item:hover { color: var(--ep-white); }
	.ep-nav__item.is-on { color: var(--ep-white); font-weight: var(--ep-w-semi); }
	.ep-nav__lab { color: var(--ep-vio-2); font-weight: var(--ep-w-semi); }
}

/* THE DRAWER IS LIGHT.
   It was the same near-black as the header, which made opening it feel like
   nothing had happened: a dark panel sliding over a dark page reads as a
   shadow, not as a surface. Light gives it a clear edge and makes the
   catalogue easier to scan, which is what a menu is for.

   These rules come after the drawer's own block on purpose. They are the same
   specificity, so document order decides, and putting them last is what makes
   them win. That ordering has bitten this stylesheet before. */
.ep-menu__panel {
	background: var(--ep-lt-card);
	border-right: 1px solid var(--ep-lt-line);
}
.ep-menu__top { border-bottom: 1px solid var(--ep-lt-line); }
.ep-menu__title { color: var(--ep-lt-mut); }
.ep-menu__x { color: var(--ep-lt-ink); border-color: var(--ep-lt-line); }
.ep-menu__x:hover { border-color: var(--ep-vio-deep); }

.ep-menu__all {
	background: var(--ep-vio-deep);
	color: #FFFFFF !important;
}
.ep-menu__lbl { color: var(--ep-lt-mut); }

.ep-menu__cats > li + li,
.ep-menu__pages > li + li { border-top: 1px solid var(--ep-lt-line); }

.ep-menu__cat,
.ep-menu__pages a { color: var(--ep-lt-ink) !important; }
.ep-menu__cat .ep-num { color: var(--ep-lt-mut); }

.ep-menu__kids { border-left: 1px solid var(--ep-lt-line); }
.ep-menu__kids a { color: var(--ep-lt-mut) !important; }
.ep-menu__kids .ep-num { color: var(--ep-lt-mut); }

.ep-menu__cat:hover,
.ep-menu__kids a:hover,
.ep-menu__pages a:hover { color: var(--ep-vio-deep) !important; }

/* The capsule is shared with the hero, where it sits on dark. Inside the light
   drawer it needs the light treatment or it is a white-on-white ghost. */
.ep-menu__comm .ep-social {
	border-color: var(--ep-lt-line);
	background: var(--ep-lt-sunk);
}
.ep-menu__comm .ep-social__h { color: var(--ep-lt-ink) !important; }
.ep-menu__comm .ep-social__h:hover { background: rgba(0, 0, 0, 0.04); }
.ep-menu__comm .ep-social__d { background: var(--ep-lt-line); }

/* Wide enough for the whole row with air to spare: only here does the lab link
   get pushed to the right edge, because an auto margin inside a row that is
   overflowing pins it to the visible edge and lets the items behind it slide
   underneath. */
@media (min-width: 1180px) {
	.ep-nav__in { overflow-x: visible; gap: var(--ep-s-6); }
	.ep-nav__lab { margin-left: auto; }
}

/* ---------------------------------------------------------------------------
   THE CART DRAWER

   Shoptimizer's own drawer markup, dressed to match the storefront. Its
   contents are a WooCommerce fragment that gets replaced wholesale on every
   add to cart, so nothing here can depend on markup this plugin added at page
   load; the extras inside it are injected through the mini cart hook instead.
   --------------------------------------------------------------------------- */
.shoptimizer-mini-cart-wrap {
	background: var(--ep-lt-card);
	border-left: 1px solid var(--ep-lt-line);
}
.shoptimizer-mini-cart-wrap .cart-drawer-heading {
	font-size: var(--ep-t-xs);
	font-weight: var(--ep-w-bold);
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--ep-lt-mut);
}
.shoptimizer-mini-cart-wrap .close-drawer { color: var(--ep-lt-ink); }

.shoptimizer-mini-cart-wrap .woocommerce-mini-cart__total {
	padding-top: var(--ep-s-3);
	border-top: 1px solid var(--ep-lt-line);
	font-size: var(--ep-t-base);
	color: var(--ep-lt-ink);
}
.shoptimizer-mini-cart-wrap .woocommerce-mini-cart__total strong { font-weight: var(--ep-w-regular); color: var(--ep-lt-mut); }
.shoptimizer-mini-cart-wrap .woocommerce-mini-cart__total .amount {
	float: right;
	font-weight: var(--ep-w-black);
	font-variant-numeric: tabular-nums;
}

/* The drawer's checkout button is the same decision as the one on the basket,
   so it looks the same. */
.shoptimizer-mini-cart-wrap .woocommerce-mini-cart__buttons a.checkout {
	display: flex !important;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: var(--ep-control);
	border-radius: var(--ep-r-md);
	background: var(--ep-vio-deep) !important;
	color: #FFFFFF !important;
	font-weight: var(--ep-w-bold);
	border: 0;
}
.shoptimizer-mini-cart-wrap .woocommerce-mini-cart__buttons a:not(.checkout) {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: var(--ep-control-md);
	border: 1px solid var(--ep-lt-line);
	border-radius: var(--ep-r-md);
	background: var(--ep-lt-card);
	color: var(--ep-lt-ink) !important;
	font-weight: var(--ep-w-semi);
}

/* The dispatch promise, inside the drawer. */
.ep-mini__ship {
	display: block;
	margin: var(--ep-s-3) 0;
	padding: var(--ep-s-2) var(--ep-s-3);
	border: 1px solid var(--ep-lt-line);
	border-left: 3px solid var(--ep-lt-line);
	border-radius: var(--ep-r-sm);
	background: var(--ep-lt-sunk);
	font-size: var(--ep-t-xs);
	color: var(--ep-lt-ink-2);
	line-height: 1.4;
}
.ep-mini__ship.is-live { border-left-color: var(--ep-lt-ok); background: var(--ep-lt-ok-bg); border-color: #CFE7DA; }
.ep-mini__ship.is-urgent { border-left-color: var(--ep-lt-warn); background: var(--ep-lt-warn-bg); border-color: #EDDFB6; }
.ep-mini__ship b { color: var(--ep-lt-ink); font-weight: var(--ep-w-bold); }

/* Payment marks in the drawer: smaller, and quiet. */
.shoptimizer-mini-cart-wrap .ep-foot__pay { margin: 0 0 var(--ep-s-3); gap: var(--ep-s-1) var(--ep-s-2); }
.shoptimizer-mini-cart-wrap .ep-foot__payl { color: var(--ep-lt-mut); font-size: 11px; }
.shoptimizer-mini-cart-wrap .ep-foot__pmset { color: var(--ep-lt-ink-2); opacity: 0.55; gap: var(--ep-s-2); }
.shoptimizer-mini-cart-wrap .ep-foot__pm svg { width: 30px; height: 19px; }
.shoptimizer-mini-cart-wrap .ep-foot__gw {
	border-color: var(--ep-lt-line);
	color: var(--ep-lt-ink);
	font-size: 11px;
	padding: 2px 8px;
}


/* ---------------------------------------------------------------------------
   SEARCH TYPEAHEAD (WHM-98)

   Sits under the pill, built by search.js. The panel is positioned against
   .ep-search, which is why that element carries position: relative below: it
   was static, and an absolutely positioned panel would otherwise have hung off
   whichever ancestor happened to be positioned, which on this header is the
   whole chrome bar.

   ON PHONES it stays anchored to the field rather than becoming a full screen
   overlay. A takeover would be the fashionable choice and the wrong one here:
   it hides the basket count and the menu, and this search is a shortcut rather
   than a destination.
   --------------------------------------------------------------------------- */
.ep-search { position: relative; }

.ep-sug {
	position: absolute;
	top: calc(100% + 6px);
	left: 0;
	right: 0;
	z-index: 60;
	max-height: min(60vh, 420px);
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: var(--ep-s-1);
	background: var(--ep-surf);
	border: 1px solid var(--ep-edge);
	border-radius: var(--ep-r-md);
	box-shadow: 0 18px 44px rgba(0, 0, 0, 0.45);
}
.ep-sug__row {
	display: flex;
	align-items: center;
	gap: var(--ep-s-3);
	padding: var(--ep-s-2);
	border-radius: var(--ep-r-sm, 8px);
	text-decoration: none;
	color: var(--ep-white);
}
/* Hover and keyboard share one state, so there is never a moment where two
   different rows both look like the one that Enter will open. */
.ep-sug__row:hover,
.ep-sug__row.is-on { background: rgba(124, 58, 237, 0.18); }
.ep-sug__pic {
	flex: none;
	width: 40px;
	height: 40px;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	border-radius: var(--ep-r-sm, 8px);
	background: #FFFFFF;
}
/* COVER, NOT CONTAIN, and measured rather than assumed: the thumbnails looked
   blank in testing and the images were loading perfectly (HTTP 200, natural
   width 300). The catalogue is shot on white with generous margins, so contain
   inside a 40px white tile fits the WHOLE frame, margins included, leaving a
   product a few pixels across on a white ground. Cover crops the empty margin
   and shows the product instead. */
.ep-sug__pic img { width: 100%; height: 100%; object-fit: cover; }
.ep-sug__ph { width: 100%; height: 100%; background: var(--ep-edge); }
.ep-sug__txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ep-sug__name {
	font-size: var(--ep-t-sm);
	line-height: 1.3;
	/* Two lines then ellipsis. A long product name must not be allowed to push
	   the price out of the row. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
/* The typed run, emphasised so the match is obvious at a glance. */
.ep-sug__name b { color: var(--ep-vio-soft, #C4B5FD); font-weight: var(--ep-w-bold); }
.ep-sug__tag {
	align-self: flex-start;
	font-size: 11px;
	font-weight: var(--ep-w-semi);
	letter-spacing: 0.02em;
	color: var(--ep-lt-ok, #22C55E);
}
.ep-sug__tag--off { color: var(--ep-mut); }
/* The struck through was-price, kept quiet so the price people pay is the one
   that reads first. */
.ep-sug__price s {
	margin-right: 4px;
	color: var(--ep-mut);
	font-weight: var(--ep-w-semi);
	text-decoration-thickness: 1px;
}
.ep-sug__price {
	flex: none;
	font-size: var(--ep-t-sm);
	font-weight: var(--ep-w-bold);
	color: var(--ep-white);
	font-variant-numeric: tabular-nums;
}
.ep-sug__none {
	margin: 0;
	padding: var(--ep-s-4) var(--ep-s-3);
	font-size: var(--ep-t-sm);
	color: var(--ep-mut);
	text-align: center;
}
.ep-sug__none b { color: var(--ep-white); }
/* The way through to the full results page. Six rows is a preview, and without
   this the dropdown would be a dead end for anything broader. */
.ep-sug__all {
	display: block;
	width: 100%;
	margin-top: var(--ep-s-1);
	padding: var(--ep-s-3);
	border: 0;
	border-top: 1px solid var(--ep-edge);
	background: transparent;
	color: var(--ep-vio-soft, #C4B5FD);
	font-family: inherit;
	font-size: var(--ep-t-sm);
	font-weight: var(--ep-w-semi);
	text-align: center;
	cursor: pointer;
}
.ep-sug__all:hover { color: var(--ep-white); }

/* On a narrow phone the two part price took 114px of a 323px row and squeezed
   the product name to 129px, which truncated names that would otherwise fit.
   The was-price is the first thing to go: the price people actually pay is the
   one that matters in a six row preview, and the full comparison is right there
   on the product page. */
@media (max-width: 480px) {
	.ep-sug__price s { display: none; }
}


/* =========================================================================
   UI RULE (2026-09-26, .claude/skills/ui-rule): text never decides a
   control's shape. A control is one line at every width; when a label does
   not fit, the row wraps or the row becomes a stack, never the label.
   ========================================================================= */
.ep-btn, .button, .wp-element-button, .single_add_to_cart_button, .ep-search__go,
.ep-social__h, .ep-pill, .ep-badge, .ep-chip, .ep-tab, .ep-card__badge, .ep-card__brand {
	white-space: nowrap;
}
.ep-btn { justify-content: center; flex-shrink: 0; }
.ep-btn > span { white-space: nowrap; }
/* Two pills side by side: each stays whole; the pair wraps onto two rows instead. */
.ep-social { flex-wrap: wrap; row-gap: 8px; }
.ep-social__h { flex: 0 1 auto; justify-content: center; }
/* Rows of calls to action stack into full-width buttons on phones. */
@media (max-width: 560px) {
	.ep-hero__cta, .ep-tiva__cta, .ep-toro__cta, .ep-deal__cta, .ep-lab__cta, .ep-cta__row {
		flex-direction: column;
		align-items: stretch;
	}
	.ep-hero__cta .ep-btn, .ep-tiva__cta .ep-btn, .ep-toro__cta .ep-btn, .ep-deal__cta .ep-btn, .ep-lab__cta .ep-btn, .ep-cta__row .ep-btn {
		display: flex;
		width: 100%;
	}
	.ep-social__h { flex: 1 1 100%; }
	.ep-social__d { display: none; }
}
/* A long label on a phone drops one size step before it may ever wrap. */
@media (max-width: 400px) {
	.ep-btn { font-size: 15px; padding-left: 18px; padding-right: 18px; }
}

/* SOCIAL LINKS (2026-09-26). The capsule became two underlined links: icon,
   label, small arrow. Same markup in the hero, the drawer and the footer. The
   support icon is green so the two read apart at a glance. Tap height stays
   44px even without a box. */
.ep-social { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 28px; border: 0; border-radius: 0; background: none; overflow: visible; }
.ep-social__d { display: none; }
.ep-social__h { flex: 0 0 auto; justify-content: flex-start; gap: 8px; min-height: 44px; padding: 0; background: none !important; }
.ep-social__t { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px; text-decoration-color: rgba(192, 132, 252, 0.45); transition: text-decoration-color var(--ep-dur-1) var(--ep-ease); }
.ep-social__ar { flex: none; opacity: 0.6; transition: transform var(--ep-dur-1) var(--ep-ease), opacity var(--ep-dur-1) var(--ep-ease); }
.ep-social__h:hover .ep-social__t { text-decoration-color: #C084FC; }
.ep-social__h:hover .ep-social__ar { opacity: 1; transform: translate(2px, -2px); }
.ep-social__i--sup { color: #34C77B; }
.ep-hero .ep-social { justify-content: center; }
.ep-menu__comm .ep-social { flex-direction: column; align-items: flex-start; gap: 0; background: none; border: 0; }
.ep-menu__comm .ep-social__h { min-height: 44px; font-size: var(--ep-t-sm); }
.ep-menu__comm .ep-social__t { text-decoration-color: var(--ep-lt-line); }
.ep-menu__comm .ep-social__h:hover .ep-social__t { text-decoration-color: var(--ep-vio-deep); }
.ep-menu__comm .ep-social__i--sup { color: #0F7B4F; }

/* ---------------------------------------------------------------- how ordering works (2026-09-30)
   Four steps under the pay button on the basket and checkout (Express_Shop_Chrome::order_steps).
   Body text, so lines may wrap; icons sit in square 36px circles. */
ul.ep-steps { list-style: none; margin: var(--ep-s-4) 0 0; padding: var(--ep-s-4); display: grid; gap: var(--ep-s-3); background: var(--ep-lt-card); border: 1px solid var(--ep-lt-line); border-radius: 14px; font-family: var(--ep-font); text-align: left; }
ul.ep-steps > li.ep-steps__i { display: flex; align-items: center; gap: var(--ep-s-3); margin: 0; padding: 0; list-style: none; font-size: 15px; line-height: 1.4; color: var(--ep-lt-ink-2); }
ul.ep-steps > li.ep-steps__i::before, ul.ep-steps > li.ep-steps__i::marker { content: none; }
.ep-steps__t strong { color: var(--ep-lt-ink); font-weight: var(--ep-w-semi); }
.ep-steps__t a { color: var(--ep-lt-ink); font-weight: var(--ep-w-semi); text-decoration: underline; text-decoration-color: var(--ep-lt-tint-e); text-underline-offset: 3px; }
.ep-steps__t a:hover { color: var(--ep-vio-deep); }
.ep-steps__ic { flex: none; width: 36px; aspect-ratio: 1 / 1; border-radius: 50%; display: grid; place-items: center; background: var(--ep-lt-tint); color: var(--ep-vio-deep); }
.ep-steps__ic--wa { background: #E7F8EE; color: #1DA851; }
.ep-steps__ic svg { display: block; }
/* The theme indents lists inside the payment box and cart totals: undo it for this one. */
#payment ul.ep-steps, .cart_totals ul.ep-steps, .woocommerce-checkout ul.ep-steps { margin: var(--ep-s-4) 0 0; }
