/**
 * Storefront custom styles — on top of vendored Bootstrap 5/FontAwesome/Owl
 * Carousel/Swiper/lightGallery (theme/frontend/assets/vendor/*). Kept
 * separate from those vendor files so a version bump never means re-diffing
 * hand-written CSS out of a minified vendor file.
 *
 * --shop-accent is set inline per-request from the `theme_accent_color`
 * setting (see layouts/frontend/main.php's <style> block) — every color
 * reference here goes through the variable so the whole storefront re-skins
 * from one Settings field, no CSS edit needed.
 */
:root {
	--shop-accent: #ff5722;
	--shop-accent-dark: #e64a19;
	--shop-ink: #1d2939;
	--shop-muted: #667085;
	--shop-border: #e4e7ec;
	--shop-surface: #f9fafb;
}

/*
 * Owl Carousel's own stylesheet forces `.owl-carousel .owl-item img{width:
 * 100%}` (correct for full-bleed slide images, wrong for a fixed-size
 * avatar/logo placed inside a slide) — these two selectors match that same
 * `.owl-carousel .owl-item img` prefix plus one extra class, so they win on
 * specificity without needing !important.
 */
.owl-carousel .owl-item img.testimonial-avatar {
	width: 72px;
	height: 72px;
	object-fit: cover;
}
.owl-carousel .owl-item img.brand-logo {
	width: auto;
	max-width: 100%;
	max-height: 60px;
}

body {
	color: var(--shop-ink);
	/* --shop-font-family is set per-request in layouts/frontend/main.php
	   from the real theme_font_family setting (Settings > Theme) — this
	   'Poppins' is only the pre-render fallback, same role --shop-accent's
	   static :root default plays in site.css. */
	font-family: var(--shop-font-family, 'Poppins', sans-serif);
}

/*
 * Bootstrap 5.3 colors EVERY plain <a> through these two CSS custom
 * properties (--bs-link-color / --bs-link-hover-color, defined on :root in
 * bootstrap.min.css). Overriding them here — instead of hand-styling every
 * individual link/hover pair across the footer, breadcrumbs, alerts, etc —
 * retints the whole storefront's default link color in one place. Anything
 * that needs its OWN look (nav links, product-card links) sets its own
 * color explicitly and isn't affected by this.
 */
:root {
	--bs-link-color: var(--shop-ink);
	--bs-link-color-rgb: 29, 41, 57; /* rgb() of --shop-ink (#1d2939) — a fixed design token, safe to hardcode */
	--bs-link-hover-color: var(--shop-accent);
	--bs-link-hover-color-rgb: var(--shop-accent-rgb); /* --shop-accent-rgb is computed server-side from the settings-driven hex (see main.php) so it can never drift out of sync */
}

/*
 * Bootstrap's pagination active-state variables are re-declared directly
 * ON `.pagination` itself (bootstrap.min.css sets --bs-pagination-active-bg
 * etc INSIDE its own `.pagination{...}` rule, not just on :root) — so a
 * :root-level override gets shadowed the moment an element actually
 * matches `.pagination`. The fix is overriding on that same `.pagination`
 * selector, which — since this file loads after bootstrap.min.css — wins
 * on identical specificity via source order.
 */
.pagination {
	--bs-pagination-active-bg: var(--shop-accent);
	--bs-pagination-active-border-color: var(--shop-accent);
}

/*
 * Bootstrap's checked radio/checkbox fill is a hardcoded hex (#0d6efd, not
 * a CSS variable like the two above), so it needs a real override rule —
 * same selector Bootstrap itself uses, this file loading after
 * bootstrap.min.css is what makes it win.
 */
.form-check-input:checked {
	background-color: var(--shop-accent);
	border-color: var(--shop-accent);
}
.form-check-input:focus {
	border-color: var(--shop-accent);
	box-shadow: 0 0 0 .25rem rgba(var(--shop-accent-rgb), .25);
}

a {
	text-decoration: none;
}

.btn-accent {
	background-color: var(--shop-accent);
	border-color: var(--shop-accent);
	color: #fff;
}
.btn-accent:hover,
.btn-accent:focus {
	background-color: var(--shop-accent-dark);
	border-color: var(--shop-accent-dark);
	color: #fff;
}
/*
 * Bootstrap's own `.btn:disabled` rule (bootstrap.min.css) resets color/
 * background/border to its own --bs-btn-disabled-* variables, which
 * .btn-accent never defines — so a disabled "Out of Stock" button fell
 * back to Bootstrap's default gray/transparent look instead of a muted
 * accent. Same specificity as that Bootstrap rule (one class + :disabled),
 * so normal cascade order (this file loads after bootstrap.min.css) makes
 * this win without needing !important.
 */
.btn-accent:disabled,
.btn-accent.disabled {
	background-color: var(--shop-accent);
	border-color: var(--shop-accent);
	color: #fff;
	opacity: .55;
}
.text-accent { color: var(--shop-accent); }
.bg-accent { background-color: var(--shop-accent); }

/* Buy Now (PDP) — visually distinct from the filled .btn-accent "Add to
   Cart" next to it (an outline, not a second solid color — there's only
   one accent color variable, so this is the natural second treatment
   rather than inventing an unrelated color to configure). Fills solid on
   hover, same accent-dark used elsewhere for a pressed/active feel. */
.btn-outline-accent {
	background-color: transparent;
	border-color: var(--shop-accent);
	color: var(--shop-accent);
}
.btn-outline-accent:hover,
.btn-outline-accent:focus {
	background-color: var(--shop-accent);
	border-color: var(--shop-accent);
	color: #fff;
}
.btn-outline-accent:disabled,
.btn-outline-accent.disabled {
	background-color: transparent;
	border-color: var(--shop-accent);
	color: var(--shop-accent);
	opacity: .55;
}

/*
 * "Smoke" section band — the light off-white used to alternate with plain
 * white between home-page sections (Flash Deals, Promo Banners, Brand
 * ticker) so a long single-page scroll reads as distinct zones instead of
 * one flat wall of white. Same color as --shop-surface (used elsewhere for
 * card/icon backgrounds) — one token, so a re-theme via Settings some day
 * only ever needs to touch --shop-surface, not every "smoke" reference.
 */
.bg-smoke {
	background-color: var(--shop-surface);
}

/* ---------------------------------------------------------------------
 * Announcement bar — thin, dismissible-free strip above the main navbar.
 * ------------------------------------------------------------------- */
.announcement-bar {
	background: var(--shop-ink);
	color: #fff;
	font-size: .8125rem;
	padding: .4rem 0;
	text-align: center;
}

/* ---------------------------------------------------------------------
 * Sticky main navbar — shrinks/gains a shadow once the page scrolls past
 * the announcement bar (site-common.js toggles .navbar-scrolled).
 *
 * Colored header (Flipkart/Amazon-style solid brand-color bar instead of
 * plain white) — still fully settings-driven: color-mix() derives the
 * darker sub-nav shade and hover tint FROM --shop-accent at paint time,
 * so there's nothing here to keep in sync if the accent color changes
 * (unlike --shop-accent-dark above, which is a separate hardcoded fallback
 * only ever correct for the default orange).
 * ------------------------------------------------------------------- */
.shop-navbar {
	position: sticky;
	top: 0;
	z-index: 1030;
	/*
	 * NOT a flat var(--shop-accent) fill — a fully-saturated color reads
	 * fine as a small accent (a button, a badge, an underline) but is hard
	 * on the eyes spread across an entire header-width surface, reported
	 * directly against the default orange. --shop-header-bg (computed in
	 * layouts/frontend/main.php, same for the auth layout) is EITHER a
	 * two-color linear-gradient() (Settings > Theme's gradient toggle) OR
	 * that same accent blended 10% toward near-black — this rule never
	 * needs to know which, or care if either color changes later.
	 */
	background: var(--shop-header-bg, var(--shop-accent));
	border-bottom: none;
	transition: box-shadow .2s ease;
}
.shop-navbar.navbar-scrolled {
	box-shadow: 0 4px 16px rgba(16, 24, 40, .16);
}
.shop-navbar .navbar-brand img {
	max-height: 44px;
	width: auto;
}
.shop-navbar .navbar-brand span {
	color: #fff;
}
.shop-navbar .shop-icon-btn {
	color: #fff;
}
.shop-navbar .shop-icon-btn:hover {
	background: color-mix(in srgb, var(--shop-accent) 70%, #fff 30%);
	color: #fff;
}
/* Cart/wishlist/notification counts — a fixed white pill with accent text
   reads clearly against the solid accent header regardless of what that
   accent color actually is, same reasoning real storefronts use a fixed
   badge color instead of tying it to the theme. */
.shop-navbar .shop-icon-btn .badge {
	background: #fff !important;
	color: var(--shop-accent);
}
/* Sub-nav row (category links) — a darker shade of the SAME accent, not a
   second color to configure, so the two rows read as one colored header
   block instead of two unrelated bars. Link color/underline-color overrides
   for .shop-main-nav .nav-link live further down, with the rest of that
   nav's styling (padding/spacing/font), so there's one definition per
   property instead of two blocks each setting half of it. */
.shop-navbar-subnav {
	background: color-mix(in srgb, var(--shop-accent) 82%, #000 18%);
}

/*
 * Main nav row (Home/About/Contact/etc, under the search bar) — a small
 * animated underline slides in under the link on hover, and stays under
 * whichever link is the current page (server sets .active on that <a>).
 * Cheap, common "premium" e-commerce nav touch — no extra markup needed
 * beyond the .active class the server already has to set.
 *
 * Top-level row is a real <ul class="shop-main-nav"> > <li class="nav-item">
 * > <a class="nav-link"> now (was a flat .nav > bare <a>/<div> mix) —
 * Bootstrap's own .nav/.nav-item/.nav-link classes are built for exactly
 * this structure, so nothing else needed to change for it to still look
 * identical to a plain flex row; .nav already zeroes the <ul>'s default
 * margin/padding/list-style.
 */
.shop-main-nav .nav-link {
	position: relative;
	padding: .75rem 1.1rem;
	color: rgba(255, 255, 255, .92);
	font-weight: 600;
	font-size: .925rem;
	letter-spacing: .2px;
	white-space: nowrap;
}
/*
 * Every .nav-link carries its own 1.1rem left padding (for even spacing
 * between "Home", "Categories", etc) — but that same padding, applied to
 * the FIRST item, pushes "Home"'s visible text to the right of the logo
 * above it, even though both elements' own boxes start at the exact same
 * x-position. Zeroing just the first item's left padding is what makes the
 * two rows' visible content actually line up.
 */
.shop-main-nav > li:first-child .nav-link {
	padding-left: 0;
}
.shop-main-nav > li:first-child .nav-link::after {
	left: 0;
}
.shop-main-nav .nav-link::after {
	content: '';
	position: absolute;
	left: 1.1rem;
	right: 1.1rem;
	bottom: 0;
	height: 2px;
	background: #fff;
	transform: scaleX(0);
	transform-origin: left;
	transition: transform .2s ease;
}
.shop-main-nav .nav-link:hover,
.shop-main-nav .nav-link.active {
	/* NOT var(--shop-accent) — this nav row's own background is already a
	   darker MIX of that same accent color (.shop-navbar-subnav above), so
	   accent-colored text on it would have very poor contrast, close to
	   invisible depending on the chosen accent. Plain white reads clearly
	   regardless of what the accent color actually is. */
	color: #fff;
}
.shop-main-nav .nav-link:hover::after,
.shop-main-nav .nav-link.active::after {
	transform: scaleX(1);
}

/*
 * A nav item with sub-links (e.g. "Categories") renders as a Bootstrap
 * .dropdown — Bootstrap's own JS only opens it on click, but a desktop
 * storefront nav is expected to open on hover too (click still works, e.g.
 * for touch/keyboard users — this is additive, not a replacement). Pure
 * CSS, no JS needed: the dropdown-menu just needs `display:block` while
 * the mouse is anywhere over the parent .dropdown, overriding Bootstrap's
 * own inline style="display:none" default state.
 */
.shop-main-nav .dropdown:hover > .dropdown-menu {
	display: block;
	margin-top: 0; /* removes the small gap Bootstrap's default offset leaves, which would let the mouse "fall off" between link and menu */
}
.shop-main-nav > .dropdown > .dropdown-toggle::after {
	transition: transform .15s ease;
}
.shop-main-nav > .dropdown:hover > .dropdown-toggle::after {
	transform: rotate(180deg);
}

/*
 * 3rd-level (and deeper) menu — a .dropdown-submenu is a normal <li> inside
 * an already-open .dropdown-menu that itself contains another .dropdown-
 * menu; Bootstrap 5 has no built-in multi-level dropdown, so this hover-to-
 * flyout-sideways behavior is hand-written. .dropend (Bootstrap's own
 * utility, reused just for its right-pointing ::after caret — see
 * shop_menu_submenu_items() in shop_ui_helper.php) supplies the arrow.
 */
.dropdown-submenu {
	position: relative;
}
.dropdown-submenu > .dropdown-menu {
	top: -.5rem; /* aligns the submenu's first item with the parent item it flies out from, offsetting the parent .dropdown-menu's own padding */
	/*
	 * left:100% with NO gap (no margin-left) is deliberate: the previous
	 * .25rem margin left a strip of dead space between the parent <li> and
	 * the flyout that belonged to neither element's hoverable box. Moving
	 * the mouse there — even briefly, on any diagonal path — dropped
	 * :hover on .dropdown-submenu and slammed the flyout shut before the
	 * cursor ever reached it. Flush (or a hair of overlap) keeps the
	 * hoverable area continuous the whole way across.
	 */
	left: 100%;
	margin-left: -2px;
	display: none;
}
.dropdown-submenu:hover > .dropdown-menu {
	display: block;
}
/*
 * Without this, the ::after arrow sits immediately after the label text
 * (Bootstrap's default), so it lands at a different x-position on every
 * row depending on how long that row's label is — "Fashion▸" and
 * "Home & Kitchen▸" don't line up. Flexing the item pins the label to the
 * left and the arrow to the same far-right edge on every row, regardless
 * of label length.
 */
.dropdown-submenu > .dropdown-toggle {
	display: flex;
	align-items: center;
	justify-content: space-between;
}
.dropdown-submenu > .dropdown-toggle::after {
	margin-left: .75rem;
}

/*
 * Tabbed Product Showcase (Trending/Best Sellers/New Arrivals) — Bootstrap's
 * stock .nav-tabs are boxy tabs with a hard border; this is the flatter,
 * underline-style tab treatment expected on a modern storefront. Written
 * from scratch (not extending .nav-tabs) since the box/border look isn't
 * salvageable with a couple of overrides.
 */
.shop-tabs {
	border-bottom: 1px solid var(--shop-border);
	gap: .5rem;
}
.shop-tabs .nav-link {
	border: 0;
	border-bottom: 2px solid transparent;
	border-radius: 0;
	padding: .75rem 1.25rem;
	color: var(--shop-muted);
	font-weight: 500;
	background: none;
	transition: color .15s ease, border-color .15s ease;
}
.shop-tabs .nav-link:hover {
	color: var(--shop-ink);
	border-color: var(--shop-border);
}
.shop-tabs .nav-link.active {
	color: var(--shop-accent);
	border-color: var(--shop-accent);
	background: none;
}

/*
 * Blog card "Read More" CTA — a text link (not a filled button, a filled
 * .btn-accent here would compete visually with the product cards' Add to
 * Cart buttons on the same page) with an arrow that nudges right on hover.
 */
.btn-read-more {
	display: inline-flex;
	align-items: center;
	color: var(--shop-accent);
	font-weight: 600;
	font-size: .875rem;
}
.btn-read-more i {
	transition: transform .15s ease;
}
.btn-read-more:hover {
	color: var(--shop-accent-dark);
}
.btn-read-more:hover i {
	transform: translateX(3px);
}

/* Category-scoped search bar (input + dropdown + submit as one visual unit). */
.shop-search {
	max-width: 560px;
}
.shop-search .form-select {
	max-width: 160px;
	border-right: 0;
	border-top-right-radius: 0;
	border-bottom-right-radius: 0;
}
.shop-search .form-control {
	border-left: 0;
	border-right: 0;
	border-radius: 0;
}
.shop-search .form-control:focus,
.shop-search .form-select:focus {
	box-shadow: none;
	border-color: var(--shop-border);
}
.shop-search .btn {
	border-top-left-radius: 0;
	border-bottom-left-radius: 0;
}
/* The search bar sits ON the colored header now (see .shop-navbar above) —
   a subtle shadow instead of a border is what makes a white bar actually
   read as "floating on color" instead of blending flat into it. */
.shop-search {
	border-radius: .5rem;
	overflow: hidden;
	box-shadow: 0 2px 10px rgba(0, 0, 0, .18);
}
.shop-search .form-select,
.shop-search .form-control {
	border: none;
}

/* Live search dropdown (site-common.js, GET shop/search_suggest) — sits
   directly under the search bar, same width, closes on blur/Escape/a
   result click. */
.shop-search-results {
	position: absolute;
	top: calc(100% + 6px);
	left: 0;
	right: 0;
	background: #fff;
	border-radius: .5rem;
	box-shadow: 0 8px 24px rgba(16, 24, 40, .18);
	z-index: 1040;
	max-height: 360px;
	overflow-y: auto;
}
.shop-search-result-item {
	display: flex;
	align-items: center;
	gap: .75rem;
	padding: .6rem .9rem;
	color: var(--shop-ink);
	text-decoration: none;
}
.shop-search-result-item:hover,
.shop-search-result-item.active,
.shop-search-view-all.active {
	/* .active is the keyboard-navigated row (site-common.js's Up/Down
	   handling) — same highlight as :hover so keyboard and mouse users
	   see an identical "this is what Enter will pick" state. */
	background: var(--shop-surface);
}
.shop-search-result-item img {
	width: 40px;
	height: 40px;
	object-fit: cover;
	border-radius: .25rem;
	flex-shrink: 0;
}
.shop-search-result-item .result-name {
	font-size: .875rem;
	font-weight: 500;
	flex-grow: 1;
	/* Truncate instead of pushing the price column off the edge of the
	   dropdown now that a sale result also carries a discount badge + MRP
	   next to the price — a long product name + all of that would
	   otherwise wrap awkwardly in a narrow dropdown. */
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.shop-search-result-item .result-price-wrap {
	display: flex;
	align-items: center;
	gap: .35rem;
	flex-shrink: 0;
}
.shop-search-result-item .result-price {
	font-size: .8125rem;
	font-weight: 600;
	color: var(--shop-accent);
	white-space: nowrap;
}
.shop-search-result-item .result-mrp {
	font-size: .6875rem;
	color: var(--shop-muted);
	text-decoration: line-through;
	white-space: nowrap;
}
.shop-search-result-item .result-discount {
	font-size: .6875rem;
	font-weight: 700;
	color: #fff;
	background: var(--shop-accent);
	border-radius: .25rem;
	padding: .05rem .3rem;
	white-space: nowrap;
}
.shop-search-view-all {
	display: block;
	text-align: center;
	padding: .6rem;
	font-size: .8125rem;
	font-weight: 600;
	color: var(--shop-accent);
	border-top: 1px solid var(--shop-border);
}
.shop-search-empty {
	padding: 1rem;
	text-align: center;
	color: var(--shop-muted);
	font-size: .875rem;
}

/* "Recent Searches" (Facebook/Flipkart-style) — shown in the same dropdown
   container as the live product results, just different content; see
   site-common.js's renderRecent(). */
.shop-search-recent-header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: .6rem .9rem .4rem;
	font-size: .75rem;
	font-weight: 600;
	color: var(--shop-muted);
	text-transform: uppercase;
	letter-spacing: .4px;
}
.shop-search-clear-all {
	background: none;
	border: none;
	padding: 0;
	font-size: .75rem;
	font-weight: 600;
	color: var(--shop-accent);
	text-transform: none;
	letter-spacing: normal;
}
.shop-search-recent-item {
	display: flex;
	align-items: center;
	gap: .65rem;
	padding: .55rem .9rem;
	cursor: pointer;
	color: var(--shop-ink);
}
.shop-search-recent-item:hover,
.shop-search-recent-item.active {
	background: var(--shop-surface);
}
.shop-search-recent-item i.fa-clock {
	color: var(--shop-muted);
	font-size: .9rem;
	flex-shrink: 0;
}
.shop-search-recent-item .recent-term {
	flex-grow: 1;
	font-size: .875rem;
	/* Matches shop-search-result-item's own text truncation — a long
	   remembered query shouldn't push the remove button off the edge of
	   the dropdown. */
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.shop-search-recent-remove {
	background: none;
	border: none;
	padding: .25rem .4rem;
	color: var(--shop-muted);
	flex-shrink: 0;
	border-radius: .25rem;
}
.shop-search-recent-remove:hover {
	background: var(--shop-border);
	color: var(--shop-ink);
}

/* ---------------------------------------------------------------------
 * Mini-cart drawer items (site-cart.js's refreshMiniCart()) — previously
 * plain flex rows with just a gap between them and the drawer's bare white
 * background; each line now reads as its own distinct card instead of
 * bleeding into the next one.
 * ------------------------------------------------------------------- */
.mini-cart-item {
	padding: .75rem;
	border-radius: .5rem;
	background: var(--shop-surface);
	transition: background-color .15s ease;
}
.mini-cart-item:hover {
	background: color-mix(in srgb, var(--shop-accent) 6%, var(--shop-surface) 94%);
}
.mini-cart-item + .mini-cart-item {
	margin-top: .6rem;
}

/* Icon buttons (wishlist/cart/account) with a badge counter pinned top-right. */
.shop-icon-btn {
	position: relative;
	color: var(--shop-ink);
	font-size: 1.15rem;
	width: 42px;
	height: 42px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	transition: background-color .15s ease;
}
.shop-icon-btn:hover {
	background: var(--shop-surface);
	color: var(--shop-ink);
}
.shop-icon-btn .badge {
	position: absolute;
	top: 2px;
	right: 2px;
	font-size: .625rem;
	padding: .2em .45em;
	min-width: 1.1em;
}
/*
 * Bootstrap's .dropdown-toggle::after caret is meant for text links/nav
 * items with room to spare — on these compact circular icon buttons
 * (bell/account) it becomes a 3rd flex child next to the icon, so
 * .shop-icon-btn's own justify-content:center centers the icon+caret PAIR
 * instead of the icon alone, visibly shifting the icon left of the
 * button's true center. A bell/account icon doesn't need a caret hint the
 * way a text nav dropdown does, so it's dropped entirely here.
 */
.shop-icon-btn.dropdown-toggle::after {
	display: none;
}

/*
 * Account dropdown (My Orders/Wishlist/Logout) + the category <select> in
 * the search bar — both are Bootstrap's stock components, restyled to
 * match the storefront's rounded/soft-shadow language instead of
 * Bootstrap's square, hard-edged defaults.
 */
.dropdown-menu {
	border: 1px solid var(--shop-border);
	border-radius: .625rem;
	box-shadow: 0 12px 28px rgba(16, 24, 40, .12);
	padding: .5rem;
}
.dropdown-menu .dropdown-item {
	border-radius: .375rem;
	padding: .55rem .75rem;
	font-size: .875rem;
	transition: background-color .15s ease;
}
.dropdown-menu .dropdown-item:hover,
.dropdown-menu .dropdown-item:focus {
	background-color: var(--shop-surface);
	color: var(--shop-accent);
}
.dropdown-menu .dropdown-divider {
	margin: .35rem 0;
}

/* ---------------------------------------------------------------------
 * Mobile-first bottom navigation bar — hidden on lg+ where the full
 * navbar already covers Home/Shop/Cart/Account.
 * ------------------------------------------------------------------- */
.mobile-bottom-nav {
	position: fixed;
	bottom: 0;
	left: 0;
	right: 0;
	z-index: 1030;
	background: #fff;
	border-top: 1px solid var(--shop-border);
	box-shadow: 0 -2px 12px rgba(16, 24, 40, .06);
	display: flex;
}
.mobile-bottom-nav .nav-item-link {
	flex: 1 1 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 2px;
	padding: .5rem 0 .4rem;
	font-size: .6875rem;
	color: var(--shop-muted);
	position: relative;
}
.mobile-bottom-nav .nav-item-link i {
	font-size: 1.15rem;
}
.mobile-bottom-nav .nav-item-link.active {
	color: var(--shop-accent);
}
.mobile-bottom-nav .nav-item-link .badge {
	position: absolute;
	top: 2px;
	right: calc(50% - 18px);
	font-size: .5625rem;
	padding: .2em .4em;
}
/*
 * .mobile-bottom-nav itself is `d-lg-none` (hidden at the lg breakpoint and
 * up, since the full navbar covers the same links there) — but this
 * padding-bottom was applying unconditionally on <body> regardless of
 * viewport, reserving a 60px gap below the footer on DESKTOP too, where no
 * fixed bar actually occupies it. Barely noticeable against a plain white
 * footer, but a visible white strip the moment the footer got a real
 * background color (see .shop-footer). Scoped to the same breakpoint the
 * bar itself disappears at, matching Bootstrap's own lg cutoff (992px).
 */
@media (max-width: 991.98px) {
	body.has-mobile-bottom-nav {
		padding-bottom: 60px;
	}
}

/* ---------------------------------------------------------------------
 * Product card — image-hover flip, discount pill, quick-view/wishlist
 * icons that fade in on hover, AJAX add-to-cart button.
 * ------------------------------------------------------------------- */
.product-card {
	border: 1px solid var(--shop-border);
	border-radius: .5rem;
	overflow: hidden;
	background: #fff;
	transition: box-shadow .2s ease, transform .2s ease;
	height: 100%;
	/*
	 * A flex column, not plain block flow — otherwise the "Only X left!"
	 * low-stock line (present on SOME cards in a grid row, not others)
	 * pushes just that card's Add to Cart button down by one line, so
	 * buttons land at different heights across an otherwise equal-height
	 * row. The .p-3 content block below grows to fill the remaining
	 * height and its own Add to Cart button gets margin-top:auto, so the
	 * button always sits flush with the card's bottom edge regardless of
	 * how many optional lines (rating, low-stock) render above it.
	 */
	display: flex;
	flex-direction: column;
}
.product-card:hover {
	box-shadow: 0 12px 24px rgba(16, 24, 40, .10);
	transform: translateY(-3px);
}
.product-card .product-thumb {
	position: relative;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	background: var(--shop-surface);
	flex-shrink: 0; /* never let the flex column squash the image area to make room for the text block below */
}
.product-card > .p-3 {
	display: flex;
	flex-direction: column;
	flex-grow: 1;
}
.product-card > .p-3 > button[data-add-to-cart] {
	margin-top: auto;
}
.product-card .product-thumb img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	transition: opacity .25s ease;
}
.product-card .product-thumb img.img-back {
	position: absolute;
	inset: 0;
	opacity: 0;
}
.product-card:hover .product-thumb img.img-back {
	opacity: 1;
}
.product-card:hover .product-thumb img.img-front {
	opacity: 0;
}
/* Base pill look (used bare on the PDP, next to the price); .product-card
   positions it absolutely over the thumbnail — same class, two contexts. */
.discount-pill {
	display: inline-block;
	background: var(--shop-accent);
	color: #fff;
	font-size: .6875rem;
	font-weight: 600;
	padding: .2rem .5rem;
	border-radius: 999px;
}
.product-card .discount-pill {
	position: absolute;
	top: .5rem;
	left: .5rem;
	z-index: 2;
}

/* Price widget's OWN discount indicator (shop_price_block()) — plain green
   text ("8% off"), not a filled pill like .discount-pill above (that one's
   a corner badge over a product thumbnail, a different, unrelated use —
   left as-is). Matches Flipkart's own convention directly: current price,
   struck-through MRP, then the saving in green, in that order. */
.price-discount {
	color: #388e3c;
	/* Relative to its own parent, not a fixed rem — so it stays visibly
	   smaller than price-current whether that's the PDP's large fs-3 price
	   or a card's small default size, instead of a flat .8125rem that was
	   barely smaller than price-current in the compact (card/cart) context
	   it's most commonly used in. */
	font-size: .75em;
	font-weight: 600;
}
.product-card .card-quick-actions {
	position: absolute;
	top: .5rem;
	right: .5rem;
	display: flex;
	flex-direction: column;
	gap: .35rem;
	opacity: 0;
	transform: translateX(6px);
	transition: opacity .2s ease, transform .2s ease;
	z-index: 2;
}
.product-card:hover .card-quick-actions {
	opacity: 1;
	transform: translateX(0);
}
.product-card .card-quick-actions .btn {
	width: 34px;
	height: 34px;
	padding: 0;
	border-radius: 50%;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: #fff;
	border: 1px solid var(--shop-border);
	color: var(--shop-ink);
}
.product-card .card-quick-actions .btn:hover {
	background: var(--shop-accent);
	border-color: var(--shop-accent);
	color: #fff;
}
.product-card .price-old {
	color: var(--shop-muted);
	text-decoration: line-through;
	font-size: .8125rem;
}
.product-card .price-current {
	color: var(--shop-accent);
	font-weight: 700;
}

/* ---------------------------------------------------------------------
 * Category tiles (home page) — circular icon-card style.
 * ------------------------------------------------------------------- */
.category-tile {
	text-align: center;
	color: var(--shop-ink);
}
.category-tile .icon-circle {
	width: 84px;
	height: 84px;
	margin: 0 auto .6rem;
	border-radius: 50%;
	background: var(--shop-surface);
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 2rem;
	color: var(--shop-accent);
	transition: background-color .2s ease, transform .2s ease;
}
.category-tile:hover .icon-circle {
	background: var(--shop-accent);
	color: #fff;
	transform: scale(1.05);
}

/* ---------------------------------------------------------------------
 * Deals-of-the-day countdown (placeholder markup — real countdown JS
 * wires in once order/campaign end-times exist in Phase 3+).
 * ------------------------------------------------------------------- */
.countdown-timer {
	display: flex;
	gap: .5rem;
}
.countdown-timer .unit {
	background: var(--shop-ink);
	color: #fff;
	border-radius: .375rem;
	min-width: 48px;
	padding: .4rem .3rem;
	text-align: center;
}
.countdown-timer .unit .value {
	font-size: 1.05rem;
	font-weight: 700;
	line-height: 1;
}
.countdown-timer .unit .label {
	font-size: .625rem;
	text-transform: uppercase;
	opacity: .75;
}

/* Trust badges + payment icon row (footer). */
.trust-badges .badge-item {
	display: flex;
	align-items: center;
	gap: .6rem;
}
.trust-badges .badge-item i {
	font-size: 1.5rem;
	color: var(--shop-accent);
}
.payment-icons i {
	font-size: 1.75rem;
	color: var(--shop-muted);
	margin-right: .5rem;
}

/* ---------------------------------------------------------------------
 * Colored footer (Flipkart/Amazon-style dark footer instead of plain
 * white) — scoped entirely under .shop-footer so Bootstrap utility
 * classes used inside it (.text-muted, .bg-body-tertiary, .border-top)
 * get overridden only here, never globally (those same classes are used
 * elsewhere in normal light-background contexts and must stay untouched).
 * ------------------------------------------------------------------- */
.shop-footer {
	background: var(--shop-ink);
	color: rgba(255, 255, 255, .72);
}
.shop-footer .trust-badges {
	background: color-mix(in srgb, var(--shop-ink) 85%, #000 15%) !important;
}
.shop-footer h5,
.shop-footer h6 {
	color: #fff;
}
.shop-footer .text-muted {
	color: rgba(255, 255, 255, .62) !important;
}
.shop-footer a.text-muted:hover {
	color: #fff !important;
}
.shop-footer .border-top {
	border-color: rgba(255, 255, 255, .12) !important;
}
.shop-footer .payment-icons i {
	color: rgba(255, 255, 255, .55);
}
.shop-footer .form-control::placeholder {
	color: var(--shop-muted);
}

/* PDP gallery — main image + a clickable thumbnail strip; lightGallery
   (already vendored) handles the click-to-zoom lightbox on top of this. */
.pdp-gallery-main img {
	aspect-ratio: 1 / 1;
	object-fit: contain;
	background: var(--shop-surface);
	border: 1px solid var(--shop-border);
}
.pdp-thumb-row {
	overflow-x: auto;
}
.pdp-thumb {
	flex: 0 0 72px;
	width: 72px;
	height: 72px;
	border: 1px solid var(--shop-border);
	border-radius: .375rem;
	overflow: hidden;
	opacity: .7;
	transition: opacity .15s ease, border-color .15s ease;
}
.pdp-thumb img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	background: var(--shop-surface);
}
.pdp-thumb:hover,
.pdp-thumb.active {
	opacity: 1;
	border-color: var(--shop-accent);
}

/* Quantity stepper (PDP + cart). */
.qty-stepper {
	display: inline-flex;
	align-items: stretch;
	border: 1px solid var(--shop-border);
	border-radius: .375rem;
	overflow: hidden;
}
.qty-stepper button {
	background: var(--shop-surface);
	border: 0;
	width: 36px;
	color: var(--shop-ink);
}
.qty-stepper input {
	width: 48px;
	border: 0;
	border-left: 1px solid var(--shop-border);
	border-right: 1px solid var(--shop-border);
	text-align: center;
}
.qty-stepper input:focus {
	outline: none;
	box-shadow: none;
}

/* Cart page — two clearly separate panels (items / order summary), each
   with its own gray header strip (same "white card, gray-strip-only-where-
   needed" language as the Shop page's .shop-filters-header), so the page
   reads as distinct sections instead of one flat block of content. */
.cart-panel {
	background: #fff;
	border: 1px solid var(--shop-border);
	border-radius: .5rem;
	overflow: hidden;
	box-shadow: 0 1px 3px rgba(16, 24, 40, .06);
}
.cart-panel-header {
	background: var(--shop-surface);
	border-bottom: 1px solid var(--shop-border);
	padding: 1rem 1.25rem;
}
.cart-panel-header h6 {
	font-weight: 700;
}
.cart-panel-footer {
	background: var(--shop-surface);
	border-top: 1px solid var(--shop-border);
	padding: .85rem 1.25rem;
	display: flex;
	flex-direction: column;
	gap: .4rem;
	font-size: .8125rem;
	color: var(--shop-muted);
}
.order-summary-panel {
	position: sticky;
	top: 1rem;
}
.cart-item {
	transition: background-color .12s ease;
}
.cart-item:hover {
	background: var(--shop-surface);
}
.cart-item + .cart-item {
	border-top: 1px solid var(--shop-border);
}
.cart-item-thumb {
	display: block;
	width: 88px;
	height: 88px;
	border: 1px solid var(--shop-border);
	border-radius: .375rem;
	overflow: hidden;
}
.cart-item-thumb img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	background: var(--shop-surface);
}
.cart-item-aside {
	width: 140px;
}
@media (max-width: 575.98px) {
	.cart-item {
		flex-wrap: wrap;
	}
	.cart-item-aside {
		width: 100%;
		margin-top: .75rem;
		display: flex;
		align-items: center;
		justify-content: space-between;
		text-align: left;
	}
	.cart-item-aside .qty-stepper {
		margin-bottom: 0 !important;
	}
}

/* Checkout-steps indicator — purely visual "step 1 of 3" orientation strip;
   Address/Payment aren't real pages yet (Phase 4), just context for where
   Cart sits in the journey. */
.checkout-steps {
	display: flex;
	align-items: center;
	max-width: 480px;
}
.checkout-steps .step {
	display: flex;
	align-items: center;
	gap: .5rem;
	font-size: .8125rem;
	font-weight: 600;
	color: var(--shop-muted);
	white-space: nowrap;
}
.checkout-steps .step.active,
.checkout-steps .step.done {
	color: var(--shop-ink);
}
.checkout-steps .step-circle {
	width: 28px;
	height: 28px;
	flex-shrink: 0;
	border-radius: 50%;
	border: 2px solid var(--shop-border);
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: .75rem;
	color: var(--shop-muted);
}
.checkout-steps .step.active .step-circle,
.checkout-steps .step.done .step-circle {
	background: var(--shop-accent);
	border-color: var(--shop-accent);
	color: #fff;
}
.checkout-steps .step-divider {
	flex: 1;
	height: 2px;
	background: var(--shop-border);
	margin: 0 .75rem;
}
.checkout-steps .step-divider.done {
	background: var(--shop-accent);
}

/* Selectable "card" radios — shared by Checkout's saved-address list and
   payment-method list: the whole card is clickable (label wraps the radio),
   :has() lights up the border/tint the moment its own radio is checked, no
   JS toggle needed. */
.select-card {
	display: block;
	border: 1px solid var(--shop-border);
	border-radius: .5rem;
	padding: 1rem;
	cursor: pointer;
	transition: border-color .15s ease, background-color .15s ease;
}
.select-card:hover {
	border-color: var(--shop-accent);
}
.select-card:has(input:checked) {
	border-color: var(--shop-accent);
	background: rgba(var(--shop-accent-rgb), .05);
}
.select-card input[type="radio"] {
	margin-right: .6rem;
}
.select-card + .select-card {
	margin-top: .75rem;
}

/* ---------------------------------------------------------------------
 * Brand grid (/brands) — a dedicated card, not a reuse of .select-card
 * above (that class is shared by checkout's address/payment pickers, a
 * plain compact radio-row style that would look thin here). Real brand
 * logos are small wordmark-style images (~160x60px) — scaling the IMAGE
 * itself up much further would just look blurry, so what "bigger/richer"
 * actually means here is the CARD around it: generous padding, a
 * consistent logo stage, a hover lift matching .product-card's own, and
 * the product count as a real pill instead of plain muted text.
 * ------------------------------------------------------------------- */
.brand-card {
	position: relative;
	overflow: hidden; /* clips the oversized ::before watermark below to the card's own rounded corners */
	border: 1px solid var(--shop-border);
	border-radius: .75rem;
	background: #fff;
	padding: 1.75rem 1.25rem 1.5rem;
	transition: box-shadow .2s ease, transform .2s ease, border-color .2s ease;
}
/*
 * A large, faded copy of the brand's OWN logo as a background watermark —
 * --brand-card-bg is set inline per card (see index.php) since each
 * brand's logo is a different file; this rule just says how to render
 * whatever that is. Sits BEHIND the real crisp logo/name/count (z-index
 * below, see the ">" rules further down), so it's pure visual texture,
 * never competing with the actual readable content.
 */
.brand-card::before {
	content: '';
	position: absolute;
	inset: -15%;
	background-image: var(--brand-card-bg, none);
	background-repeat: no-repeat;
	background-position: center;
	background-size: 80% auto;
	opacity: .05;
	pointer-events: none;
	z-index: 0;
	transition: opacity .2s ease;
}
.brand-card:hover::before {
	opacity: .09;
}
.brand-card > * {
	position: relative;
	z-index: 1;
}
.brand-card:hover {
	box-shadow: 0 12px 24px rgba(16, 24, 40, .10);
	transform: translateY(-3px);
	border-color: var(--shop-accent);
}
.brand-card-logo {
	height: 72px;
	display: flex;
	align-items: center;
	justify-content: center;
	margin-bottom: 1rem;
}
.brand-card-logo img {
	max-height: 56px;
	max-width: 100%;
	object-fit: contain;
}
.brand-card-fallback {
	width: 56px;
	height: 56px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	background: color-mix(in srgb, var(--shop-accent) 12%, #fff 88%);
	color: var(--shop-accent);
	font-size: 1.5rem;
	font-weight: 700;
}
.brand-card-count {
	display: inline-block;
	margin-top: .5rem;
	background: var(--shop-surface);
	color: var(--shop-muted);
	font-size: .75rem;
	font-weight: 600;
	padding: .3rem .75rem;
}
.brand-card:hover .brand-card-count {
	background: color-mix(in srgb, var(--shop-accent) 12%, #fff 88%);
	color: var(--shop-accent);
}

/* Brand detail page's hero logo — a white "stage" card floating on the
   colored band, same reasoning as .brand-card-logo (the real logo image
   is small, the CARD around it is what reads as "designed"). */
.brand-hero-logo {
	width: 140px;
	height: 90px;
	background: #fff;
	border-radius: .75rem;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: .75rem 1.25rem;
	box-shadow: 0 8px 20px rgba(0, 0, 0, .15);
}
.brand-hero-logo img {
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
}

/* Order-success confirmation icon. */
.order-success-icon {
	font-size: 3.5rem;
	color: #22c55e;
}

/* Header notification bell dropdown + the shared notification-item row
   (also reused, unwrapped, by the full account/notifications page). */
.notification-dropdown {
	width: 340px;
	max-width: 90vw;
	overflow: hidden;
}
.notification-dropdown-header {
	background: var(--shop-surface);
	border-bottom: 1px solid var(--shop-border);
	padding: .75rem 1rem;
}
.notification-dropdown-body {
	max-height: 320px;
	overflow-y: auto;
}
.notification-dropdown-footer {
	display: block;
	text-align: center;
	padding: .65rem;
	font-size: .8125rem;
	font-weight: 500;
	color: var(--shop-accent);
	border-top: 1px solid var(--shop-border);
}
.notification-item {
	display: flex;
	align-items: flex-start;
	gap: .65rem;
	padding: .75rem 1rem;
	border-bottom: 1px solid var(--shop-border);
	color: inherit;
	text-decoration: none;
}
.notification-item:last-child {
	border-bottom: 0;
}
.notification-item:hover {
	background: var(--shop-surface);
	color: inherit;
}
.notification-item.unread {
	background: rgba(var(--shop-accent-rgb), .04);
}
.notification-icon {
	width: 36px;
	height: 36px;
	flex-shrink: 0;
	border-radius: 50%;
	background: var(--shop-surface);
	color: var(--shop-accent);
	display: flex;
	align-items: center;
	justify-content: center;
}
.notification-dot {
	width: 8px;
	height: 8px;
	flex-shrink: 0;
	border-radius: 50%;
	background: var(--shop-accent);
	margin-top: .4rem;
}

/* Bootstrap 5 doesn't actually ship a .min-w-0 utility (unlike .min-vw-100
   etc.) — this project uses the class name anyway (a flex child needs
   min-width:0 to let text-truncate work instead of overflowing its flex
   container), so it's defined for real here rather than silently no-op'ing.
   Used by the Cart item row and every shop_notification_item() row. */
.min-w-0 {
	min-width: 0;
}

/* FAQ accordion — Bootstrap re-declares its own active-state variables
   directly on .accordion itself (same shadowing trap as .pagination
   earlier), so the override has to go on that same selector. */
.accordion {
	--bs-accordion-active-color: var(--shop-accent);
	--bs-accordion-active-bg: rgba(var(--shop-accent-rgb), .06);
	--bs-accordion-btn-focus-box-shadow: 0 0 0 .2rem rgba(var(--shop-accent-rgb), .15);
}

/* PDP write-a-review star picker. */
.pdp-star-input {
	font-size: 1.5rem;
	color: #ffc107;
}
.pdp-star-input i {
	cursor: pointer;
	margin-right: .25rem;
}

/* PDP variant picker — plain-text options (RAM, Storage, ...) and swatch
   options (Color) both get the same accent-highlighted "selected" ring;
   swatches additionally show their own color instead of a label. */
.variant-option.active {
	background-color: var(--shop-accent);
	border-color: var(--shop-accent);
	color: #fff;
}
.variant-swatch {
	width: 32px;
	height: 32px;
	border-radius: 50%;
	border: 2px solid var(--shop-border);
	padding: 0;
	cursor: pointer;
}
.variant-swatch.active {
	border-color: var(--shop-accent);
	box-shadow: 0 0 0 2px rgba(var(--shop-accent-rgb), .25);
}

/* My Orders list — small overlapping thumbnail stack per order card. */
.order-thumb-stack-item {
	width: 44px;
	height: 44px;
	border: 2px solid #fff;
	border-radius: .375rem;
	box-shadow: 0 0 0 1px var(--shop-border);
	overflow: hidden;
	margin-left: -12px;
}
.order-thumb-stack-item:first-child {
	margin-left: 0;
}
.order-thumb-stack-item img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	background: var(--shop-surface);
}

/* My Account side nav (Orders/Wishlist/Profile). */
.account-avatar {
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: var(--shop-surface);
	border: 1px solid var(--shop-border);
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--shop-muted);
}
.account-nav-link {
	display: block;
	padding: .55rem .75rem;
	border-radius: .375rem;
	color: var(--shop-ink);
	font-size: .9rem;
}
.account-nav-link:hover {
	background: var(--shop-surface);
}
.account-nav-link.active {
	background: rgba(var(--shop-accent-rgb), .08);
	color: var(--shop-accent);
	font-weight: 500;
}

/* Order tracking timeline — horizontal on desktop (a left-to-right journey
   reads naturally), stacked vertical on mobile where there's no width for it. */
.tracking-timeline {
	display: flex;
	align-items: flex-start;
}
.tracking-step {
	flex: 1;
	text-align: center;
	position: relative;
	padding-top: 44px;
}
.tracking-step::before {
	content: '';
	position: absolute;
	top: 21px;
	left: -50%;
	width: 100%;
	height: 2px;
	background: var(--shop-border);
	z-index: 0;
}
.tracking-step:first-child::before {
	display: none;
}
.tracking-step.done::before,
.tracking-step.active::before {
	background: var(--shop-accent);
}
.tracking-dot {
	position: absolute;
	top: 0;
	left: 50%;
	transform: translateX(-50%);
	width: 42px;
	height: 42px;
	border-radius: 50%;
	border: 2px solid var(--shop-border);
	background: #fff;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--shop-muted);
	z-index: 1;
}
.tracking-step.done .tracking-dot,
.tracking-step.active .tracking-dot {
	background: var(--shop-accent);
	border-color: var(--shop-accent);
	color: #fff;
}
.tracking-step.cancelled .tracking-dot {
	background: #dc3545;
	border-color: #dc3545;
	color: #fff;
}
.tracking-label {
	font-size: .8125rem;
	font-weight: 600;
	color: var(--shop-muted);
}
.tracking-step.done .tracking-label,
.tracking-step.active .tracking-label,
.tracking-step.cancelled .tracking-label {
	color: var(--shop-ink);
}
.tracking-date {
	font-size: .6875rem;
	color: var(--shop-muted);
	margin-top: .15rem;
}
@media (max-width: 575.98px) {
	.tracking-timeline {
		flex-direction: column;
		align-items: stretch;
	}
	.tracking-step {
		text-align: left;
		padding-top: 0;
		padding-left: 56px;
		min-height: 52px;
	}
	.tracking-dot {
		top: 0;
		left: 0;
		transform: none;
	}
	.tracking-step::before {
		top: 0;
		left: 20px;
		width: 2px;
		height: 100%;
	}
}

/* =======================================================================
 * AUTH PAGES (login/register/forgot-password/reset-password) — a split
 * screen: a branded accent-gradient panel (desktop only) + the actual form
 * on white. layouts/auth/main.php is the only view that uses these.
 * ===================================================================== */
html:has(.auth-body), .auth-body {
	height: 100%;
}
.auth-body {
	margin: 0;
	font-family: 'Poppins', sans-serif;
}
.auth-shell {
	min-height: 100vh;
	display: flex;
}

/* Branded left panel — gradient background, decorative ring SVG behind the
 * content (purely visual, aria-hidden, no extra HTTP request since it's
 * inline markup not an <img>), and the same 3 trust-badge lines the
 * storefront footer uses (repetition is intentional — reinforcing the
 * same 3 trust signals at both "convince" moments: browsing and signing up). */
.auth-brand-panel {
	flex: 0 0 44%;
	position: relative;
	overflow: hidden;
	background: linear-gradient(135deg, var(--shop-accent), var(--shop-accent-dark));
	padding: 3rem;
}
.auth-brand-rings {
	position: absolute;
	inset: 0;
	overflow: hidden;
}
.auth-brand-rings svg {
	position: absolute;
	top: 0;
	right: 0;
	width: 130%;
	height: 130%;
}
.auth-brand-content {
	position: relative;
	z-index: 1;
	height: 100%;
	display: flex;
	flex-direction: column;
	justify-content: center;
	max-width: 420px;
}
.auth-brand-icon {
	flex-shrink: 0;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: rgba(255, 255, 255, .15);
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

/* Form (right) panel. */
.auth-form-panel {
	flex: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 2rem 1.5rem;
	background: #fff;
}
.auth-form-inner {
	width: 100%;
	max-width: 420px;
}
.auth-form-inner h1,
.auth-form-inner h2 {
	font-size: 1.5rem;
	font-weight: 700;
	color: var(--shop-ink);
}
.auth-form-inner .subtitle {
	color: var(--shop-muted);
	font-size: .9rem;
}

/*
 * Icon-prefixed inputs — a modern alternative to Bootstrap's boxy
 * .input-group-text (a gray square glued to the input's edge). The icon
 * floats INSIDE the input itself (absolutely positioned over it), and the
 * input's own left padding makes room so text never runs under the icon.
 */
.auth-field {
	position: relative;
	margin-bottom: 1.25rem;
}
.auth-field label {
	display: block;
	font-size: .875rem;
	font-weight: 500;
	color: var(--shop-ink);
	margin-bottom: .4rem;
}
.auth-field .auth-field-icon {
	position: absolute;
	left: 1rem;
	top: 2.65rem; /* label height + margin — pins the icon to the input's own vertical center, not the whole .auth-field block's */
	color: var(--shop-muted);
	pointer-events: none;
}
.auth-field input {
	height: 48px;
	padding-left: 2.75rem;
	border-radius: .5rem;
	border-color: var(--shop-border);
}
.auth-field input:focus {
	border-color: var(--shop-accent);
	box-shadow: 0 0 0 .2rem rgba(var(--shop-accent-rgb), .15);
}

/* Password field's show/hide toggle — same floating-icon idea, mirrored to the right edge. */
.auth-password-toggle {
	position: absolute;
	right: 1rem;
	top: 2.65rem;
	background: none;
	border: 0;
	color: var(--shop-muted);
	padding: 0;
	line-height: 1;
}
.auth-password-toggle:hover {
	color: var(--shop-ink);
}

.auth-submit-btn {
	height: 48px;
	border-radius: .5rem;
	font-weight: 600;
}

/* =======================================================================
 * MOBILE NAV DRAWER (#mobileMenuDrawer) — the touch-friendly counterpart
 * to .shop-main-nav's hover dropdowns (which don't exist below lg, where
 * the whole secondary nav row is d-none). Rendered by
 * shop_mobile_menu_items() as click-to-expand Bootstrap .collapse
 * accordions, not hover-flyouts.
 * ===================================================================== */
.mobile-nav-link {
	display: block;
	padding: .85rem 1rem;
	color: var(--shop-ink);
	border-bottom: 1px solid var(--shop-border);
	font-weight: 500;
}
.mobile-nav-link:hover,
.mobile-nav-link:active {
	background: var(--shop-surface);
	color: var(--shop-ink);
}
.mobile-nav-caret {
	flex-shrink: 0;
	width: 48px;
	background: none;
	border: 0;
	border-left: 1px solid var(--shop-border);
	border-bottom: 1px solid var(--shop-border);
	color: var(--shop-muted);
}
.mobile-nav-caret i {
	transition: transform .15s ease;
}
/* Bootstrap's collapse.js toggles the `collapsed` class on every trigger
 * pointed at a given target — present while closed, removed once open —
 * so this flips the chevron with no JS of our own. */
.mobile-nav-caret:not(.collapsed) i {
	transform: rotate(180deg);
}
/* Nested accordion levels (sub-categories, sub-sub-categories) get the
 * surface tint so the drawer's hierarchy reads as "drilled into", not just
 * a longer flat list. */
.mobile-nav-group .collapse .mobile-nav-link,
.mobile-nav-group .collapse .mobile-nav-caret {
	background: var(--shop-surface);
}

/* =======================================================================
 * SHOP / PLP — sidebar filters, grid/list toggle, list-view row item, and
 * the dual-handle price-range slider.
 * ===================================================================== */
.shop-filters {
	background: #fff;
	border: 1px solid var(--shop-border);
	border-radius: .5rem;
	overflow: hidden; /* keeps .shop-filters-header's own background inside the card's rounded corners */
	box-shadow: 0 1px 3px rgba(16, 24, 40, .06);
}
/* Gray title strip at the top of the (otherwise white) filter card — the
 * "gray at the top only" look, not a whole-page tint. */
.shop-filters-header {
	background: var(--shop-surface);
	border-bottom: 1px solid var(--shop-border);
	padding: 1rem 1.25rem;
}
.filter-group {
	padding-bottom: 1rem;
	margin-bottom: 1rem;
	border-bottom: 1px solid var(--shop-border);
}
.filter-group:last-child {
	padding-bottom: 0;
	margin-bottom: 0;
	border-bottom: 0;
}

/* Results toolbar (count + grid/list toggle + sort) — same white-card
 * language as .shop-filters so the two feel like matched, aligned panels
 * instead of one boxed control and one floating row of text. */
.shop-toolbar {
	background: #fff;
	border: 1px solid var(--shop-border);
	border-radius: .5rem;
	padding: .85rem 1.25rem;
	box-shadow: 0 1px 3px rgba(16, 24, 40, .06);
}
.filter-title {
	font-size: .8125rem;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .03em;
	color: var(--shop-muted);
	margin-bottom: .75rem;
}

.view-toggle .btn {
	color: var(--shop-muted);
	border-color: var(--shop-border);
}
.view-toggle .btn.active {
	background: var(--shop-accent);
	border-color: var(--shop-accent);
	color: #fff;
}

/* List-view row (shop_product_list_item()) — a horizontal alternative to
 * the grid's vertical .product-card, redesigned to match the Quick View
 * modal's own layout/information density (a substantial image on the
 * left, brand/name/rating/price/description/actions on the right) rather
 * than a thin thumb+name+price+button strip.
 *
 * Its own independent border/background/hover — NOT borrowed from
 * .product-card via a wrapper div the way it used to be (Shop's view no
 * longer wraps it in one). That borrowed wrapper was a real bug: .product-
 * card's own ".product-card > .p-3" rule (added for the grid card's
 * button-alignment fix) unintentionally matched this component's OWN root
 * element too, since .product-list-item also carries a plain .p-3 class
 * for its own padding — forcing it into flex-direction:column and
 * stacking the image above the text instead of beside it. */
.product-list-item {
	border: 1px solid var(--shop-border);
	border-radius: .5rem;
	background: #fff;
	transition: box-shadow .2s ease;
}
.product-list-item:hover {
	box-shadow: 0 8px 20px rgba(16, 24, 40, .08);
}
.product-list-item .product-list-thumb {
	width: 200px;
	height: 200px;
	flex-shrink: 0;
	background: var(--shop-surface);
	border-radius: .375rem;
	overflow: hidden;
	display: block;
}
.product-list-item .product-list-thumb img {
	width: 100%;
	height: 100%;
	object-fit: contain;
}
.product-list-item .product-list-desc {
	/* Clamped, not left to overflow uncontrolled — a long description in
	   this compact row would otherwise push the Add to Cart row down by a
	   variable, unpredictable amount from one product to the next. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
@media (max-width: 575.98px) {
	.product-list-item .product-list-thumb {
		width: 110px;
		height: 110px;
	}
}

/*
 * Dual-handle price slider — two native <input type="range"> stacked
 * exactly on top of each other. Each one's own track is made invisible
 * (background:transparent) so only ONE visible track shows (the wrapper's
 * own ::before, positioned behind both) — otherwise you'd see two
 * overlapping track bars. `pointer-events:none` on the input plus
 * `pointer-events:auto` on just its thumb is what lets a click land on
 * whichever handle is physically closest, instead of only ever grabbing
 * the top input in the stack.
 */
.price-slider {
	position: relative;
	height: 24px;
}
.price-slider::before {
	content: '';
	position: absolute;
	top: 50%;
	left: 0;
	right: 0;
	height: 4px;
	transform: translateY(-50%);
	background: var(--shop-border);
	border-radius: 2px;
}
.price-slider input[type="range"] {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	margin: 0;
	background: transparent;
	pointer-events: none;
	-webkit-appearance: none;
	appearance: none;
}
.price-slider input[type="range"]::-webkit-slider-runnable-track {
	background: transparent;
	height: 24px;
}
.price-slider input[type="range"]::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	pointer-events: auto;
	width: 16px;
	height: 16px;
	border-radius: 50%;
	background: var(--shop-accent);
	border: 2px solid #fff;
	box-shadow: 0 1px 4px rgba(16, 24, 40, .25);
	margin-top: 4px;
	cursor: pointer;
}
.price-slider input[type="range"]::-moz-range-track {
	background: transparent;
	height: 4px;
}
.price-slider input[type="range"]::-moz-range-thumb {
	pointer-events: auto;
	width: 16px;
	height: 16px;
	border-radius: 50%;
	background: var(--shop-accent);
	border: 2px solid #fff;
	box-shadow: 0 1px 4px rgba(16, 24, 40, .25);
	cursor: pointer;
}

/*
 * Breadcrumb bar (layouts/frontend/main.php, any inner page — Shop, PDP,
 * account pages) — a full-width smoke strip with real padding above/below,
 * not bare text sitting flush against the sticky nav above it. A custom
 * chevron divider (instead of Bootstrap's default "/") and an accent hover
 * on the trail links are what keep it from reading as unstyled.
 */
.shop-breadcrumb-bar {
	background: var(--shop-surface);
	border-bottom: 1px solid var(--shop-border);
	padding: .85rem 0;
}
.shop-breadcrumb-bar .breadcrumb-item {
	font-size: .8125rem;
}
.shop-breadcrumb-bar .breadcrumb-item a {
	color: var(--shop-muted);
	font-weight: 500;
}
.shop-breadcrumb-bar .breadcrumb-item a:hover {
	color: var(--shop-accent);
}
.shop-breadcrumb-bar .breadcrumb-item.active {
	color: var(--shop-ink);
	font-weight: 600;
}
.shop-breadcrumb-bar .breadcrumb-item + .breadcrumb-item::before {
	content: '\f105'; /* fa-solid fa-chevron-right */
	font-family: 'Font Awesome 6 Free';
	font-weight: 900;
	font-size: .625rem;
	color: var(--shop-muted);
	display: inline-block;
	vertical-align: -1px;
	margin-top: 3px; /* user-verified live in-browser — the exact nudge that centers this glyph against the text baseline */
}

/*
 * Quick View modal (product card's eye icon) — a scale+fade entrance
 * instead of Bootstrap's default modal slide-down, a shimmering skeleton
 * while /quick-view/{id} loads, and a subtle image zoom on hover so the
 * modal feels alive rather than a plain content swap.
 */
.quick-view-modal .modal-content {
	border: none;
	border-radius: .75rem;
	overflow: hidden;
}
.quick-view-modal.fade .modal-dialog {
	transform: scale(.92) translateY(10px);
	opacity: 0;
	transition: transform .28s cubic-bezier(.34, 1.56, .64, 1), opacity .2s ease;
}
.quick-view-modal.show .modal-dialog {
	transform: scale(1) translateY(0);
	opacity: 1;
}
.quick-view-close {
	position: absolute;
	top: .75rem;
	right: .75rem;
	z-index: 5;
	background-color: #fff;
	border-radius: 50%;
	width: 32px;
	height: 32px;
	opacity: 1;
	box-shadow: 0 2px 6px rgba(0, 0, 0, .15);
}
.quick-view-media {
	overflow: hidden;
	background: var(--shop-surface);
	min-height: 320px;
	display: flex;
	align-items: center;
	justify-content: center;
}
.quick-view-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform .5s ease;
}
.quick-view-media:hover img {
	transform: scale(1.08);
}
.quick-view-skeleton .skeleton-block {
	background: linear-gradient(90deg, #eee 25%, #f6f6f6 37%, #eee 63%);
	background-size: 400% 100%;
	animation: qv-shimmer 1.4s ease infinite;
	border-radius: .375rem;
}
.quick-view-img-skel {
	width: 100%;
	min-height: 320px;
	border-radius: 0;
}
@keyframes qv-shimmer {
	0% { background-position: 100% 50%; }
	100% { background-position: 0 50%; }
}

/* ---------------------------------------------------------------------
   First-visit welcome popup (Settings > Popup) — see
   layouts/frontend/partials/welcome_popup.php / site-popup.js.
   --------------------------------------------------------------------- */
.welcome-popup-content { border: none; border-radius: .75rem; overflow: hidden; }
.welcome-popup-image { width: 100%; max-height: 260px; object-fit: cover; }
.welcome-popup-close {
	/* background-color, not `background` — a plain `background` shorthand
	   overwrites Bootstrap's own .btn-close background (that's where the
	   X icon SVG itself lives, as a background-image), so the circle drew
	   but the cross inside it never did. */
	position: absolute; top: .75rem; right: .75rem; z-index: 2;
	background-color: #fff; border-radius: 50%; opacity: .9; padding: .5rem;
}

/* ---------------------------------------------------------------------
   Festival header theme (Settings > Festival) — see
   site-festival.js. Fixed, full-viewport, click-through overlay so it
   never interferes with the real header/nav underneath it.
   --------------------------------------------------------------------- */
.festival-effect-layer {
	position: fixed;
	inset: 0;
	z-index: 1060; /* above Bootstrap's own sticky header, below a modal backdrop */
	pointer-events: none;
	overflow: hidden;
}
.festival-particle {
	position: absolute;
	top: -5vh;
	will-change: transform, opacity;
}
.festival-particle-fall {
	animation-name: festival-fall;
	animation-timing-function: linear;
	animation-iteration-count: infinite;
}
.festival-particle-float {
	animation-name: festival-float;
	animation-timing-function: ease-in-out;
	animation-iteration-count: infinite;
}
@keyframes festival-fall {
	0%   { transform: translateY(-5vh) rotate(0deg);   opacity: .9; }
	100% { transform: translateY(105vh) rotate(360deg); opacity: .6; }
}
@keyframes festival-float {
	0%   { transform: translateY(0) translateX(0);    opacity: .85; }
	50%  { transform: translateY(40vh) translateX(2vw); opacity: 1; }
	100% { transform: translateY(85vh) translateX(-2vw); opacity: .7; }
}

/* ---------------------------------------------------------------------
   Blog article body — rendered rich HTML from TinyMCE (default/blog's
   view.php), so this needs real typographic spacing Bootstrap's reset
   otherwise strips (margin:0 on headings/paragraphs).
   --------------------------------------------------------------------- */
.blog-article-content { font-size: 1.05rem; line-height: 1.75; color: var(--shop-ink, #212529); }
.blog-article-content p { margin-bottom: 1.1rem; }
.blog-article-content h2,
.blog-article-content h3,
.blog-article-content h4 { margin-top: 1.75rem; margin-bottom: .75rem; font-weight: 700; }
.blog-article-content ul,
.blog-article-content ol { margin-bottom: 1.1rem; padding-left: 1.5rem; }
.blog-article-content img { max-width: 100%; height: auto; border-radius: .375rem; }
.blog-article-content a { color: var(--shop-accent); text-decoration: underline; }

/* ---------------------------------------------------------------------
   CMS legal-page body (Shipping/Return/Terms/Privacy, §6t) — real
   admin-authored HTML from `cms_pages` via TinyMCE, same reasoning as
   .blog-article-content above (Bootstrap's reset otherwise strips
   heading/paragraph margins) but denser spacing, matching this page
   type's original plain "heading + paragraphs" look rather than the
   blog's more spacious article style.
   --------------------------------------------------------------------- */
.cms-content h2,
.cms-content h3,
.cms-content h4 { font-size: 1rem; font-weight: 700; margin-top: 1.25rem; margin-bottom: .5rem; }
.cms-content h2:first-child,
.cms-content h3:first-child,
.cms-content h4:first-child { margin-top: 0; }
.cms-content p { color: var(--shop-ink-muted, #6c757d); margin-bottom: .5rem; }
.cms-content ul,
.cms-content ol { margin-bottom: .5rem; padding-left: 1.25rem; }
