/* ==========================================================================
   Sparkx storefront design system
   Modern, Tailwind-inspired token layer applied on top of Bootstrap 5.
   Components keep Bootstrap markup/JS; this sheet restyles them globally.
   ========================================================================== */

*.icon-white {color:white}
*.icon-silver {color:silver}
*.icon-green {color: green;}
*.icon-dark {color: gray;}

:root {
	/* Brand */
	--sparkx-primary: #2563eb;
	--sparkx-primary-dark: #1d4ed8;
	--sparkx-primary-soft: #eff6ff;
	--sparkx-accent-soft: #e8f0ff;

	/* Semantic soft colors */
	--sparkx-success: #16a34a;
	--sparkx-success-soft: #ecfdf5;
	--sparkx-danger: #dc2626;
	--sparkx-danger-soft: #fef2f2;
	--sparkx-warning: #b45309;
	--sparkx-warning-soft: #fffbeb;
	--sparkx-info: #0369a1;
	--sparkx-info-soft: #f0f9ff;

	/* Neutrals (slate) */
	--sparkx-text: #0f172a;
	--sparkx-text-2: #334155;
	--sparkx-muted: #64748b;
	--sparkx-surface: #ffffff;
	--sparkx-surface-alt: #f6f8fb;
	--sparkx-border: #e2e8f0;
	--sparkx-border-strong: #cbd5e1;

	/* Radii */
	--sparkx-radius-sm: 0.5rem;
	--sparkx-radius: 0.75rem;
	--sparkx-radius-lg: 1rem;
	--sparkx-radius-xl: 1.25rem;
	--sparkx-radius-pill: 999px;

	/* Shadows */
	--sparkx-shadow-xs: 0 1px 2px rgba(15, 23, 42, 0.06);
	--sparkx-shadow-sm: 0 0.125rem 0.5rem rgba(15, 23, 42, 0.07);
	--sparkx-shadow-md: 0 0.5rem 1.25rem rgba(15, 23, 42, 0.12);
	--sparkx-shadow-lg: 0 1rem 2.5rem rgba(15, 23, 42, 0.16);

	--sparkx-focus-ring: 0 0 0 0.2rem rgba(37, 99, 235, 0.18);
	--sparkx-font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
		'Helvetica Neue', Arial, sans-serif;

	/* Map Bootstrap's own variables onto the design tokens */
	--bs-body-font-family: var(--sparkx-font);
	--bs-body-color: var(--sparkx-text);
	--bs-body-bg: var(--sparkx-surface-alt);
	--bs-border-color: var(--sparkx-border);
	--bs-primary: var(--sparkx-primary);
	--bs-primary-rgb: 37, 99, 235;
	--bs-link-color: var(--sparkx-primary);
	--bs-link-hover-color: var(--sparkx-primary-dark);
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

body {
	background-color: var(--sparkx-surface-alt);
	color: var(--sparkx-text);
	font-family: var(--sparkx-font);
	-webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, .display-6 {
	font-weight: 700;
	letter-spacing: -0.02em;
	color: var(--sparkx-text);
}

.text-muted {
	color: var(--sparkx-muted) !important;
}

/* Section heading with accent bar (homepage & listing sections) */
.section-title {
	position: relative;
	display: inline-block;
	font-weight: 700;
	letter-spacing: -0.02em;
	padding-bottom: 0.4rem;
	margin-bottom: 0.25rem;
}

.section-title::after {
	content: "";
	position: absolute;
	left: 0;
	bottom: 0;
	width: 2.75rem;
	height: 0.25rem;
	border-radius: var(--sparkx-radius-pill);
	background: linear-gradient(90deg, var(--sparkx-primary), #60a5fa);
}

.section-subtitle {
	color: var(--sparkx-muted);
	font-size: 0.95rem;
	font-weight: 400;
}

/* --------------------------------------------------------------------------
   Bootstrap component restyle (global consistency)
   -------------------------------------------------------------------------- */

.btn {
	border-radius: var(--sparkx-radius-sm);
	font-weight: 500;
	transition: background-color 0.15s ease, border-color 0.15s ease,
		box-shadow 0.15s ease, transform 0.1s ease;
}

.btn:focus-visible {
	box-shadow: var(--sparkx-focus-ring);
}

.btn:active {
	transform: translateY(1px);
}

.btn-primary {
	--bs-btn-bg: var(--sparkx-primary);
	--bs-btn-border-color: var(--sparkx-primary);
	--bs-btn-hover-bg: var(--sparkx-primary-dark);
	--bs-btn-hover-border-color: var(--sparkx-primary-dark);
	--bs-btn-active-bg: var(--sparkx-primary-dark);
	--bs-btn-active-border-color: var(--sparkx-primary-dark);
	box-shadow: 0 1px 2px rgba(37, 99, 235, 0.25);
}

.btn-outline-primary {
	--bs-btn-color: var(--sparkx-primary);
	--bs-btn-border-color: var(--sparkx-border-strong);
	--bs-btn-hover-bg: var(--sparkx-primary-soft);
	--bs-btn-hover-color: var(--sparkx-primary-dark);
	--bs-btn-hover-border-color: var(--sparkx-primary);
	--bs-btn-active-bg: var(--sparkx-primary-soft);
	--bs-btn-active-color: var(--sparkx-primary-dark);
	--bs-btn-active-border-color: var(--sparkx-primary);
}

.card {
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius);
	background-color: var(--sparkx-surface);
}

.card .card-header {
	border-top-left-radius: calc(var(--sparkx-radius) - 1px);
	border-top-right-radius: calc(var(--sparkx-radius) - 1px);
}

.badge {
	font-weight: 600;
	letter-spacing: 0.01em;
	border-radius: var(--sparkx-radius-pill);
	padding: 0.4em 0.75em;
}

/* Soft badges — modern replacement for solid bg-* badges */
.badge-soft-primary {
	background-color: var(--sparkx-primary-soft);
	color: var(--sparkx-primary-dark);
	border: 1px solid #bfdbfe;
}

.badge-soft-success {
	background-color: var(--sparkx-success-soft);
	color: var(--sparkx-success);
	border: 1px solid #bbf7d0;
}

.badge-soft-danger {
	background-color: var(--sparkx-danger-soft);
	color: var(--sparkx-danger);
	border: 1px solid #fecaca;
}

.badge-soft-warning {
	background-color: var(--sparkx-warning-soft);
	color: var(--sparkx-warning);
	border: 1px solid #fde68a;
}

.badge-soft-info {
	background-color: var(--sparkx-info-soft);
	color: var(--sparkx-info);
	border: 1px solid #bae6fd;
}

.badge-soft-neutral {
	background-color: #f1f5f9;
	color: var(--sparkx-text-2);
	border: 1px solid var(--sparkx-border);
}

.form-control,
.form-select {
	border-radius: var(--sparkx-radius-sm);
	border-color: var(--sparkx-border-strong);
	color: var(--sparkx-text);
}

.form-control:focus,
.form-select:focus {
	border-color: #93c5fd;
	box-shadow: var(--sparkx-focus-ring);
}

.modal-content {
	border: none;
	border-radius: var(--sparkx-radius-lg);
	box-shadow: var(--sparkx-shadow-lg);
}

.modal-header {
	border-bottom: 1px solid var(--sparkx-border);
}

.modal-footer {
	border-top: 1px solid var(--sparkx-border);
}

.alert {
	border: 1px solid transparent;
	border-radius: var(--sparkx-radius);
}

.alert-warning {
	background-color: var(--sparkx-warning-soft);
	border-color: #fde68a;
	color: var(--sparkx-warning);
}

.alert-info {
	background-color: var(--sparkx-info-soft);
	border-color: #bae6fd;
	color: var(--sparkx-info);
}

.alert-success {
	background-color: var(--sparkx-success-soft);
	border-color: #bbf7d0;
	color: var(--sparkx-success);
}

.pagination {
	--bs-pagination-border-radius: var(--sparkx-radius-sm);
	gap: 0.25rem;
}

.pagination .page-link {
	border-radius: var(--sparkx-radius-sm);
	border-color: var(--sparkx-border);
	color: var(--sparkx-text-2);
	font-weight: 500;
}

.pagination .page-item.active .page-link {
	background-color: var(--sparkx-primary);
	border-color: var(--sparkx-primary);
}

.pagination .page-link:focus {
	box-shadow: var(--sparkx-focus-ring);
}

.dropdown-menu {
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius);
	box-shadow: var(--sparkx-shadow-md);
}

/* --------------------------------------------------------------------------
   Header / navigation
   -------------------------------------------------------------------------- */

.app-navbar {
	background: rgba(255, 255, 255, 0.85);
	backdrop-filter: blur(12px);
	-webkit-backdrop-filter: blur(12px);
	border-bottom: 1px solid var(--sparkx-border);
	position: sticky;
	top: 0;
	z-index: 1030;
}

.app-navbar .nav-link {
	font-weight: 500;
	color: var(--sparkx-text-2);
	border-radius: var(--sparkx-radius-sm);
	padding-left: 0.75rem;
	padding-right: 0.75rem;
	transition: color 0.15s ease, background-color 0.15s ease;
}

.app-navbar .nav-link:hover,
.app-navbar .nav-link:focus {
	color: var(--sparkx-primary);
	background-color: var(--sparkx-primary-soft);
}

.app-logo {
	height: 3rem;
	/* width:auto keeps the rendered width driven by the height and the image's own ratio;
	   the width/height attributes on the tag then only reserve layout space (no jump on load). */
	width: auto;
	max-width: 10rem;
	object-fit: contain;
}

/* Live cart item-count badge (htmx-driven). Hidden when the server returns "". */
.cart-count-badge {
	position: absolute;
	top: 0.05rem;
	right: -0.15rem;
	min-width: 1.15rem;
	padding: 0.2em 0.4em;
	font-size: 0.62rem;
	font-weight: 700;
	line-height: 1;
	background-color: var(--sparkx-danger);
	color: #fff;
	box-shadow: 0 0 0 2px var(--sparkx-surface);
}

.cart-count-badge:empty {
	display: none;
}

/* Little pop when htmx swaps in a new count (after add/update/remove). */
.cart-count-badge.htmx-settling {
	animation: cart-badge-pop 0.32s ease;
}

@keyframes cart-badge-pop {
	0% { transform: scale(1); }
	45% { transform: scale(1.4); }
	100% { transform: scale(1); }
}

/* Search shell under the navbar */
.search-nav-shell {
	background: var(--sparkx-surface);
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius-lg);
	padding: 1.75rem 1.75rem;
	box-shadow: var(--sparkx-shadow-xs);
}

/* Segmented Shopping / Minutes switcher */
.view-switch {
	display: inline-flex;
	background: #eef2f7;
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius-pill);
	padding: 0.3rem;
	gap: 0.25rem;
}

.view-switch-btn {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.55rem 1.4rem;
	border-radius: var(--sparkx-radius-pill);
	font-weight: 600;
	font-size: 0.95rem;
	color: var(--sparkx-text-2);
	text-decoration: none;
	transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
	white-space: nowrap;
}

.view-switch-btn:hover,
.view-switch-btn:focus {
	color: var(--sparkx-primary-dark);
}

.view-switch-btn.active {
	background: var(--sparkx-surface);
	color: var(--sparkx-primary-dark);
	box-shadow: var(--sparkx-shadow-sm);
}

.view-switch-btn .view-switch-sub {
	display: block;
	font-size: 0.72rem;
	font-weight: 400;
	color: var(--sparkx-muted);
}

/* Phones: the segmented switch must fit inside the search-nav card. Fill the width,
   split it evenly between the two buttons, and drop the long descriptive sub-labels
   so the pills stop spilling outside the box. */
@media (max-width: 575.98px) {
	.view-switch {
		display: flex;
		width: 100%;
		max-width: 100%;
	}
	.view-switch-btn {
		flex: 1 1 0;
		min-width: 0;
		justify-content: center;
		padding: 0.5rem 0.5rem;
		font-size: 0.9rem;
		gap: 0.4rem;
	}
	.view-switch-btn .view-switch-sub {
		display: none;
	}
}

/* Search form */
.search-nav-form {
	position: relative;
	border-radius: var(--sparkx-radius-pill);
}

.search-nav-form.minutes-search-active {
	border: none;
	box-shadow: none;
	padding: 0;
}

.app-search-input {
	height: 3rem;
	border: 1px solid var(--sparkx-border-strong);
	border-radius: var(--sparkx-radius-pill) 0 0 var(--sparkx-radius-pill);
	padding-left: 1.25rem;
}

.app-search-input:focus {
	border-color: #93c5fd;
	box-shadow: var(--sparkx-focus-ring);
}

.app-search-btn {
	height: 3rem;
	background-color: var(--sparkx-primary);
	border-color: var(--sparkx-primary);
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

.app-search-btn:hover,
.app-search-btn:focus {
	background-color: var(--sparkx-primary-dark);
	border-color: var(--sparkx-primary-dark);
}

.app-search-btn.search-btn-square {
	min-width: 3.25rem;
	padding: 0;
}

.app-search-btn.search-btn-wide {
	padding: 0 1.25rem;
	min-width: 6rem;
}

@media (max-width: 576px) {
	.app-search-btn.search-btn-wide {
		min-width: 3.25rem;
		padding: 0;
	}
}

/* The field and its inline clear share one flex cell so the × can sit inside the
   input's right edge regardless of how wide the buttons beside it are. */
.search-input-wrap {
	position: relative;
	display: flex;
	flex: 1 1 auto;
	/* Bootstrap gives `.input-group > .form-control` a 1% basis so it can shrink below
	   the input's intrinsic size. The wrapper has to carry that too, or `.input-group`
	   (which wraps by default) drops the buttons onto a second row on narrow phones. */
	width: 1%;
	min-width: 0;
}

.search-input-wrap .app-search-input {
	width: 100%;
	padding-right: 2.5rem; /* keeps typed text from running under the × */
}

/* WebKit draws its own search cancel button; ours replaces it. */
.app-search-input::-webkit-search-cancel-button {
	-webkit-appearance: none;
	appearance: none;
}

.search-clear-inline {
	position: absolute;
	top: 50%;
	right: 0.5rem;
	transform: translateY(-50%);
	z-index: 4;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.75rem;
	height: 1.75rem;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	color: var(--sparkx-muted);
	font-size: 0.85rem;
	line-height: 1;
}

.search-clear-inline:hover,
.search-clear-inline:focus {
	background-color: #e2e8f0;
	color: var(--sparkx-text-2);
}

/* With the eraser gone, Ask Sparkx is the right-hand end of the bar. Bootstrap
   only rounds :last-child, and the suggestion box is the real last child. */
#askSparkxBtn {
	border-radius: 0 var(--sparkx-radius-pill) var(--sparkx-radius-pill) 0 !important;
}

/* Mobile full-screen search takeover (toggled by mobile_search.js). Hidden by
   default; only the phone breakpoint promotes the search area to full-screen. */
.mobile-search-back {
	display: none;
	border: none;
	background: transparent;
}

@media (max-width: 767.98px) {
	body.search-expanded {
		overflow: hidden;
	}

	/* Promote the search column to a fixed, full-screen panel above everything. */
	body.search-expanded #searchNavbar {
		position: fixed;
		inset: 0;
		z-index: 1080;
		background: var(--sparkx-surface);
		padding: 0.6rem 0.75rem;
		display: flex;
		align-items: flex-start;
		gap: 0.35rem;
		box-shadow: var(--sparkx-shadow-md);
	}

	body.search-expanded .mobile-search-back {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		flex: 0 0 auto;
		width: 2.5rem;
		height: 3rem;
		color: var(--sparkx-text-2);
		font-size: 1.15rem;
	}

	body.search-expanded #globalSearchForm {
		flex: 1 1 auto;
		margin: 0;
	}

	body.search-expanded .app-search-input {
		height: 3rem;
		font-size: 16px;
	}

	/* Suggestions become a full-width, full-height scrollable list under the input. */
	body.search-expanded .search-suggest-box {
		position: fixed;
		top: 3.85rem;
		left: 0;
		right: 0;
		bottom: 0;
		max-height: none;
		border: none;
		border-top: 1px solid var(--sparkx-border);
		border-radius: 0;
		box-shadow: none;
		padding: 0.5rem 0.5rem calc(0.5rem + env(safe-area-inset-bottom, 0px));
	}

	body.search-expanded .search-suggest-item {
		padding: 0.75rem;
		font-size: 1rem;
	}
}

/* Search-as-you-type dropdown (anchored to the relative .search-nav-form) */
.search-suggest-box {
	position: absolute;
	top: calc(100% + 0.4rem);
	left: 0;
	right: 0;
	z-index: 1050;
	background: var(--sparkx-surface);
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius);
	box-shadow: var(--sparkx-shadow-md);
	max-height: 24rem;
	overflow-y: auto;
	padding: 0.35rem;
}

.search-suggest-item {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	padding: 0.5rem 0.75rem;
	border-radius: var(--sparkx-radius-sm);
	text-decoration: none;
	color: var(--sparkx-text);
	font-size: 0.95rem;
}

.search-suggest-item:hover,
.search-suggest-item.active {
	background-color: var(--sparkx-primary-soft);
	color: var(--sparkx-primary-dark);
}

.search-suggest-img {
	width: 2.25rem;
	height: 2.25rem;
	object-fit: contain;
	flex-shrink: 0;
	background: #fff;
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius-sm);
	padding: 0.15rem;
}

.search-suggest-name {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Footer */
.footer-nav {
	background: var(--sparkx-surface);
	border-top: 1px solid var(--sparkx-border);
}

.footer-nav .nav-link {
	font-weight: 500;
	color: var(--sparkx-text-2);
}

.footer-nav .nav-link:hover,
.footer-nav .nav-link:focus {
	color: var(--sparkx-primary);
}

.app-footer-note {
	color: var(--sparkx-muted);
	font-size: 0.9rem;
}

/* --------------------------------------------------------------------------
   Product cards (listing, homepage sections, shop page)
   -------------------------------------------------------------------------- */

.product-card {
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius);
	overflow: hidden;
	transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

.product-card:hover {
	transform: translateY(-0.25rem);
	border-color: #bfdbfe;
	box-shadow: var(--sparkx-shadow-md);
}

.product-card-media {
	position: relative;
	min-height: 14rem;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	background: var(--sparkx-surface);
}

.product-card-image {
	max-height: 12.5rem;
	object-fit: contain;
	transition: transform 0.25s ease;
}

/* The product page's thumbnail strip carried only a height="60" attribute and no CSS, so each
   thumbnail's width depended on its own aspect ratio: the row reserved no horizontal space and
   shuffled as the images arrived. A fixed box reserves it whatever shape the photo is, and
   object-fit keeps the picture undistorted. */
.image-thumbnail {
	width: 60px;
	height: 60px;
	object-fit: contain;
}

.product-card:hover .product-card-image {
	transform: scale(1.04);
}

/* The media is a centered flex column; without a width bound a long, nowrap name
   grows past the card and — being centered inside .product-card's overflow:hidden —
   gets clipped on BOTH sides. Force the link (and its text) to the card width so the
   name wraps/clamps within it instead. */
.product-card-media > a {
	display: block;
	width: 100%;
	min-width: 0;
}

.product-name {
	font-size: 1rem;
	font-weight: 600;
	min-height: 2.5rem;
	color: var(--sparkx-text);
	max-width: 100%;
	/* Show the full (server-capped ~70-char) name — wrap to as many lines as it
	   needs within the card width; the width bound on .product-card-media > a keeps
	   it from clipping at the edges, and rail/grid cards stretch to equal height. */
	overflow-wrap: anywhere;
	word-break: break-word;
}

.discount-flag {
	position: absolute;
	top: 0.75rem;
	left: 0.75rem;
	z-index: 2;
	background: var(--sparkx-danger);
	color: #fff;
	font-size: 0.72rem;
	font-weight: 700;
	padding: 0.3rem 0.6rem;
	border-radius: var(--sparkx-radius-pill);
	box-shadow: var(--sparkx-shadow-xs);
}

/* --------------------------------------------------------------------------
   Page shells & heroes
   -------------------------------------------------------------------------- */

.page-hero {
	background: linear-gradient(135deg, var(--sparkx-primary-soft) 0%, #ffffff 65%);
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius-lg);
	padding: 1.75rem 1.5rem;
}

.page-hero h2 {
	margin-bottom: 0.35rem;
}

.filter-card {
	background: var(--sparkx-surface);
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius-lg);
	padding: 1.25rem;
	box-shadow: var(--sparkx-shadow-xs);
}

/* Chip group (status filters etc.) */
.chip-group {
	display: inline-flex;
	background: #eef2f7;
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius-pill);
	padding: 0.25rem;
	gap: 0.25rem;
}

.chip {
	border: none;
	background: transparent;
	padding: 0.4rem 1.1rem;
	border-radius: var(--sparkx-radius-pill);
	font-size: 0.875rem;
	font-weight: 600;
	color: var(--sparkx-text-2);
	transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}

.chip:hover {
	color: var(--sparkx-primary-dark);
}

.chip.active {
	background: var(--sparkx-surface);
	box-shadow: var(--sparkx-shadow-sm);
	color: var(--sparkx-primary-dark);
}

.chip.chip-success.active {
	color: var(--sparkx-success);
}

.chip.chip-danger.active {
	color: var(--sparkx-danger);
}

/* --------------------------------------------------------------------------
   Checkout / cart
   -------------------------------------------------------------------------- */

.checkout-shell {
	max-width: 1200px;
	margin: 0 auto;
	padding: 0 0.75rem;
}

.checkout-title {
	font-weight: 700;
	letter-spacing: -0.02em;
}

.checkout-card {
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius);
	box-shadow: var(--sparkx-shadow-xs);
}

.checkout-card .card-header {
	background-color: var(--sparkx-primary-soft);
	border-bottom: 1px solid var(--sparkx-border);
	font-weight: 600;
}

.checkout-order-table {
	width: 100%;
	font-size: 0.95rem;
	border-collapse: separate;
	border-spacing: 0 0.5rem;
}

.checkout-order-table td {
	vertical-align: top;
}

.checkout-total-row {
	font-size: 0.98rem;
	padding-top: 0.35rem;
	padding-bottom: 0.35rem;
}

.checkout-pay-btn {
	min-height: 2.9rem;
	font-weight: 600;
}

.cart-summary-sticky {
	top: 1rem;
	z-index: 100;
}

.cart-item-card {
	border-radius: var(--sparkx-radius);
	border: 1px solid var(--sparkx-border);
}

.cart-item-image {
	max-height: 5rem;
	object-fit: contain;
}

.cart-empty-icon {
	font-size: 3.5rem;
	color: #94a3b8;
}

/* --------------------------------------------------------------------------
   Minutes / shop cards
   -------------------------------------------------------------------------- */

.minutes-shop-card {
	transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
	position: relative;
	border-radius: var(--sparkx-radius-lg);
	border: 1px solid var(--sparkx-border);
	overflow: hidden;
}

.minutes-shop-card:hover {
	transform: translateY(-0.25rem);
	border-color: #bfdbfe;
	box-shadow: var(--sparkx-shadow-md);
}

.minutes-shop-card.shop-closed {
	opacity: 0.8;
	background-color: #f8fafc;
	filter: grayscale(0.35);
}

.minutes-shop-card.shop-closed:hover {
	transform: none;
	box-shadow: var(--sparkx-shadow-sm);
}

.minutes-shop-ribbon {
	position: absolute;
	top: 0.75rem;
	right: 0.75rem;
	z-index: 2;
}

.shop-logo {
	width: 4.5rem;
	height: 4.5rem;
	object-fit: contain;
	border-radius: var(--sparkx-radius) !important;
	box-shadow: var(--sparkx-shadow-xs);
}

.shop-meta {
	display: flex;
	align-items: center;
	gap: 0.4rem;
	color: var(--sparkx-muted);
	font-size: 0.85rem;
}

.shop-meta i {
	width: 1rem;
	text-align: center;
	color: #94a3b8;
}

.shop-header-card {
	position: relative;
	border-radius: var(--sparkx-radius-lg);
	border: 1px solid var(--sparkx-border);
	background: linear-gradient(135deg, var(--sparkx-primary-soft) 0%, #ffffff 55%);
}

.shop-header-card.shop-closed {
	opacity: 0.85;
	background: #f8fafc;
}

.shop-header-ribbon {
	position: absolute;
	top: 0.75rem;
	right: 0.75rem;
	z-index: 2;
}

.shop-logo-lg {
	width: 6.25rem;
	height: 6.25rem;
	object-fit: contain;
	border-radius: var(--sparkx-radius) !important;
	box-shadow: var(--sparkx-shadow-xs);
}

/* --------------------------------------------------------------------------
   Product detail
   -------------------------------------------------------------------------- */

.product-detail-shell {
	max-width: 1200px;
	margin: 1rem auto;
	padding: 0 0.75rem;
}

.product-image-container {
	position: relative;
	overflow: hidden;
	border-radius: var(--sparkx-radius);
	border: 1px solid var(--sparkx-border);
	box-shadow: var(--sparkx-shadow-xs);
	cursor: zoom-in;
	height: 30rem;
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: #fff;
}

.product-image-container img {
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	transition: transform 0.3s ease;
	display: block;
	object-fit: contain;
}

.product-image-container:hover img {
	transform: scale(1.2);
}

.thumbnail-container {
	cursor: pointer;
	transition: all 0.2s;
	border: 0.125rem solid transparent;
	border-radius: var(--sparkx-radius-sm);
}

.thumbnail-container:hover,
.thumbnail-container.active {
	border-color: var(--sparkx-primary);
	transform: translateY(-0.125rem);
}

.product-detail-price {
	font-size: 1.5rem;
	font-weight: 700;
}

.product-detail-discount {
	color: var(--sparkx-danger);
	font-weight: 700;
}

.product-buy-card {
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius);
	box-shadow: var(--sparkx-shadow-xs);
}

/* Keep the buy card in view while the shopper scrolls the description/specs.
   Only on lg+ where there's a side column; on mobile it stacks normally. */
@media (min-width: 992px) {
	.product-buy-card {
		position: sticky;
		top: 1rem;
	}
}

/* --------------------------------------------------------------------------
   Product image lightbox (the #carouselModal opened from the gallery)
   -------------------------------------------------------------------------- */

.product-lightbox .modal-content {
	background: #0b0b0f;
	border-radius: var(--sparkx-radius-lg);
	overflow: hidden;
}

/* Constant-size stage: every slide is the same height, so switching between
   images of different dimensions never resizes / jumps the modal. */
.product-lightbox .lightbox-stage {
	height: 82vh;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 1.5rem;
}

.product-lightbox .lightbox-img {
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	object-fit: contain;
	border-radius: var(--sparkx-radius-sm);
}

/* Floating close button (overlay, top-right) instead of a header bar. */
.product-lightbox .lightbox-close {
	position: absolute;
	top: 0.85rem;
	right: 0.85rem;
	z-index: 6;
	padding: 0.65rem;
	background-color: rgba(0, 0, 0, 0.45);
	border-radius: 50%;
	opacity: 0.9;
}

.product-lightbox .lightbox-close:hover {
	opacity: 1;
}

/* Bootstrap's control/indicator hit areas, nudged a touch larger and clearer. */
.product-lightbox .carousel-control-prev,
.product-lightbox .carousel-control-next {
	width: 12%;
}

.product-lightbox .carousel-control-prev-icon,
.product-lightbox .carousel-control-next-icon {
	width: 2.25rem;
	height: 2.25rem;
	background-color: rgba(0, 0, 0, 0.4);
	border-radius: 50%;
	background-size: 55% 55%;
}

.product-lightbox .carousel-indicators {
	z-index: 6;
	margin-bottom: 0.75rem;
}

@media (max-width: 575.98px) {
	.product-lightbox .lightbox-stage {
		height: 70vh;
		padding: 0.75rem;
	}
}

/* --------------------------------------------------------------------------
   Category cards
   -------------------------------------------------------------------------- */

.category-card {
	transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
	border-radius: var(--sparkx-radius);
	border: 1px solid var(--sparkx-border);
}

.category-card:hover {
	transform: translateY(-0.25rem);
	border-color: #bfdbfe;
	box-shadow: var(--sparkx-shadow-sm);
}

.category-thumb {
	max-height: 5rem;
	object-fit: contain;
}

/* --------------------------------------------------------------------------
   Status / result pages
   -------------------------------------------------------------------------- */

.order-complete-card {
	max-width: 760px;
	margin: 1rem auto;
	padding: 2rem 1.5rem;
	border: 1px solid #bfdbfe;
	border-radius: var(--sparkx-radius-lg);
	background: linear-gradient(180deg, #ffffff 0%, #eff6ff 100%);
	box-shadow: var(--sparkx-shadow-xs);
}

.status-page-shell {
	max-width: 860px;
	margin: 1rem auto;
	padding: 0 0.75rem;
}

.status-card {
	padding: 2rem 1.5rem;
	border-radius: var(--sparkx-radius-lg);
	border: 1px solid var(--sparkx-border);
	background: #fff;
	box-shadow: var(--sparkx-shadow-xs);
	text-align: center;
}

.status-card .status-icon {
	font-size: 2.75rem;
	margin-bottom: 0.75rem;
}

.status-card .status-title {
	font-size: 1.9rem;
	font-weight: 700;
	margin-bottom: 0.5rem;
}

.status-card .status-subtitle {
	font-size: 1.05rem;
	color: var(--sparkx-muted);
	margin-bottom: 1rem;
}

.status-card.status-error {
	border-color: #fecaca;
	background: linear-gradient(180deg, #ffffff 0%, #fff5f5 100%);
}

.status-card.status-error .status-icon {
	color: var(--sparkx-danger);
}

.status-card.status-success {
	border-color: #bbf7d0;
	background: linear-gradient(180deg, #ffffff 0%, #f0fdf4 100%);
}

.status-card.status-success .status-icon {
	color: var(--sparkx-success);
}

.status-card.status-info {
	border-color: #bfdbfe;
	background: linear-gradient(180deg, #ffffff 0%, #eff6ff 100%);
}

.status-card.status-info .status-icon {
	color: var(--sparkx-primary);
}

/* --------------------------------------------------------------------------
   Homepage product rails (horizontally scrollable section rows)
   -------------------------------------------------------------------------- */

.product-rail {
	flex-wrap: nowrap;
	overflow-x: auto;
	scroll-snap-type: x proximity;
	-webkit-overflow-scrolling: touch;
	padding-bottom: 0.75rem;
	scrollbar-width: thin;
	scrollbar-color: var(--sparkx-border) transparent;
}

.product-rail::-webkit-scrollbar {
	height: 6px;
}

.product-rail::-webkit-scrollbar-thumb {
	background: var(--sparkx-border);
	border-radius: var(--sparkx-radius-pill);
}

.product-rail::-webkit-scrollbar-track {
	background: transparent;
}

.product-rail > [class*="col-"] {
	flex: 0 0 auto;
	width: 11.5rem;
	scroll-snap-align: start;
}

.product-rail .product-card-media {
	min-height: 10.5rem;
}

.product-rail .product-card-image {
	max-height: 9rem;
}

.product-rail .product-name {
	font-size: 0.9rem;
}

@media (min-width: 768px) {
	.product-rail > [class*="col-"] {
		width: 14rem;
	}

	.product-rail .product-card-media {
		min-height: 12rem;
	}

	.product-rail .product-card-image {
		max-height: 10.5rem;
	}
}

/* --------------------------------------------------------------------------
   Account dropdown (header navbar)
   -------------------------------------------------------------------------- */

.account-dropdown {
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius);
	box-shadow: var(--sparkx-shadow-md);
	min-width: 13rem;
	padding: 0.5rem 0;
}

.account-dropdown .dropdown-item {
	padding: 0.5rem 1rem;
	font-size: 0.925rem;
}

.account-dropdown .dropdown-item i {
	width: 1.4rem;
	text-align: center;
	margin-right: 0.4rem;
	color: var(--sparkx-muted);
}

.account-dropdown .dropdown-item:hover i {
	color: var(--sparkx-primary);
}

/* --------------------------------------------------------------------------
   Minutes shop-card product previews
   -------------------------------------------------------------------------- */

.shop-preview-thumb {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 3.25rem;
	height: 3.25rem;
	padding: 0.25rem;
	background: #fff;
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius);
	transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.shop-preview-thumb:hover {
	border-color: #bfdbfe;
	box-shadow: var(--sparkx-shadow-sm);
}

.shop-preview-thumb img {
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
}

/* --------------------------------------------------------------------------
   Wishlist heart (product cards + detail page)
   -------------------------------------------------------------------------- */

/* On a product card: floating circular button, top-right of the media area. */
.product-card-media .wishlist-toggle {
	position: absolute;
	top: 0.75rem;
	right: 0.75rem;
	z-index: 2;
	width: 2rem;
	height: 2rem;
	padding: 0;
	border-radius: 50%;
	border: 1px solid var(--sparkx-border);
	background: #fff;
	color: var(--sparkx-muted);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	transition: color 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}

.product-card-media .wishlist-toggle:hover {
	color: var(--sparkx-danger);
	border-color: #fecaca;
	box-shadow: var(--sparkx-shadow-sm);
}

.wishlist-toggle.is-wishlisted {
	color: var(--sparkx-danger);
	border-color: #fecaca;
}

.wishlist-toggle:disabled {
	opacity: 0.6;
	cursor: default;
}

/* On the detail page it's a normal outline button (class="btn ... wishlist-toggle"). */
.btn.wishlist-toggle.is-wishlisted {
	color: var(--sparkx-danger);
	border-color: var(--sparkx-danger);
}

/* --------------------------------------------------------------------------
   SparkCoins
   -------------------------------------------------------------------------- */

.coin-balance {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	font-size: 2rem;
	font-weight: 700;
	color: var(--sparkx-text);
}

.coin-balance i {
	color: #f59e0b;
}

.coin-earn-hint {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	font-size: 0.85rem;
	font-weight: 600;
	color: #b45309;
	background: #fffbeb;
	border: 1px solid #fde68a;
	border-radius: var(--sparkx-radius-pill);
	padding: 0.25rem 0.75rem;
}

.coin-earn-hint i {
	color: #f59e0b;
}

/* --------------------------------------------------------------------------
   Account hub quick links (account details page)
   -------------------------------------------------------------------------- */

.account-quick-links .quick-link-card {
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius);
	transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
	height: 100%;
}

.account-quick-links .quick-link-card:hover {
	transform: translateY(-0.2rem);
	border-color: #bfdbfe;
	box-shadow: var(--sparkx-shadow-sm);
}

.account-quick-links .quick-link-card i {
	font-size: 1.35rem;
	color: var(--sparkx-primary);
}

/* --------------------------------------------------------------------------
   Trust strip (homepage USP bar)
   -------------------------------------------------------------------------- */

.trust-strip {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 1rem;
	background: var(--sparkx-surface);
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius);
	padding: 1rem 1.25rem;
}

.trust-item {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	min-width: 0;
}

.trust-item i {
	flex: 0 0 auto;
	width: 2.5rem;
	height: 2.5rem;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	background: #eff6ff;
	color: var(--sparkx-primary);
	font-size: 1.1rem;
}

.trust-item strong {
	display: block;
	font-size: 0.9rem;
	line-height: 1.2;
}

.trust-item small {
	color: var(--sparkx-muted);
}

@media (max-width: 767.98px) {
	.trust-strip {
		grid-template-columns: 1fr 1fr;
		gap: 0.75rem;
		padding: 0.75rem;
	}

	.trust-item small {
		display: none;
	}
}

/* --------------------------------------------------------------------------
   Responsive helpers (legacy)
   -------------------------------------------------------------------------- */

@media screen and (max-width:539px){
	/* small screen */
	div.full-details {display: none;}
	div.less-details {display:block;}
	.hideable-column {display: none;}
	.search-nav-shell {padding: 1rem;}
	.app-logo {height: 2.5rem;}
	.product-card-media {min-height: 12rem;}
	.product-image-container {height: 20rem;}
	.page-hero {padding: 1.25rem 1rem;}
}

@media screen and (min-width:540px) and (max-width:1024px){
	/* medium screen */
	div.full-details {display: block;}
	div.less-details {display: none;}
	.hideable-column {display: none;}
}

@media screen and (min-width:1024px) {
	/* large screen */
	div.less-details {display: none;}
	.hideable-column {display: table-cell;}
}

/* --------------------------------------------------------------------------
   Mobile polish (latest-standards): sticky product CTA bar, iOS input-zoom
   fix, comfortable touch targets. All scoped so desktop is untouched.
   -------------------------------------------------------------------------- */

/* Sticky bottom action bar on the product page (shown via .d-lg-none). */
.mobile-buy-bar {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 1030;
	display: flex;
	gap: 0.5rem;
	padding: 0.6rem 0.75rem;
	/* respect the iOS home-indicator safe area */
	padding-bottom: calc(0.6rem + env(safe-area-inset-bottom, 0px));
	background: var(--sparkx-surface);
	border-top: 1px solid var(--sparkx-border);
	box-shadow: 0 -4px 16px rgba(15, 23, 42, 0.08);
}

.mobile-buy-bar .btn {
	flex: 1 1 0;
	min-width: 0;
	min-height: 3rem;
	font-weight: 600;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.4rem;
}

@media (max-width: 991.98px) {
	/* Keep the last bit of page content clear of the fixed bar. Only pages that
	   render .mobile-buy-bar / .cart-checkout-bar need it, so key off that with :has(). */
	body:has(.mobile-buy-bar),
	body:has(.cart-checkout-bar) {
		padding-bottom: 4.75rem;
	}
}

/* Cart page: sticky mobile checkout bar (mirrors the desktop summary card). */
.cart-checkout-bar {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 1030;
	display: flex;
	align-items: center;
	gap: 0.75rem;
	padding: 0.55rem 0.9rem;
	padding-bottom: calc(0.55rem + env(safe-area-inset-bottom, 0px));
	background: var(--sparkx-surface);
	border-top: 1px solid var(--sparkx-border);
	box-shadow: 0 -4px 16px rgba(15, 23, 42, 0.08);
}

.cart-checkout-bar-total {
	flex: 0 0 auto;
	line-height: 1.15;
	white-space: nowrap;
}

/* iOS zooms the viewport when a focused input's text is < 16px. Bump text-ish
   controls to 16px on phones so tapping a field never triggers an auto-zoom. */
@media (max-width: 575.98px) {
	.form-control,
	.form-select,
	.app-search-input,
	input[type="text"],
	input[type="search"],
	input[type="email"],
	input[type="tel"],
	input[type="number"],
	input[type="password"] {
		font-size: 16px;
	}

	/* Comfortable minimum tap target for icon-only nav actions. */
	.app-navbar .nav-link {
		padding-top: 0.5rem;
		padding-bottom: 0.5rem;
	}
}

/* ==========================================================================
   Polish layer (2026-07-07) — Material/Tailwind-style tactility on top of the
   token system. Appended so it overrides cleanly; markup/JS unchanged.
   ========================================================================== */

html {
	scroll-behavior: smooth;
}

::selection {
	background: var(--sparkx-accent-soft);
	color: var(--sparkx-primary-dark);
}

/* Solid CTAs get a soft elevation that lifts on hover and presses on click —
   the tactile "raised surface" feel from Material, kept subtle like Tailwind. */
.btn-primary,
.btn-warning,
.btn-success,
.btn-danger {
	box-shadow: 0 1px 2px rgba(2, 6, 23, 0.12);
}

.btn-primary:hover,
.btn-warning:hover,
.btn-success:hover,
.btn-danger:hover {
	transform: translateY(-1px);
	box-shadow: var(--sparkx-shadow-sm);
}

/* On press, settle back to baseline so the click reads as a push-down from the
   hovered (lifted) state. */
.btn-primary:active,
.btn-warning:active,
.btn-success:active,
.btn-danger:active {
	transform: translateY(0);
	box-shadow: 0 1px 2px rgba(2, 6, 23, 0.12);
}

/* A crisp, consistent focus ring on every interactive control (Tailwind hallmark). */
a:focus-visible,
.btn:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible,
.page-link:focus-visible,
.dropdown-item:focus-visible {
	outline: none;
	box-shadow: var(--sparkx-focus-ring);
	border-radius: var(--sparkx-radius-sm);
}

/* Product cards: cleaner surface + a smoother, slightly deeper lift. */
.card,
.product-card {
	box-shadow: var(--sparkx-shadow-xs);
}

.product-card {
	transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

.product-card:hover {
	transform: translateY(-0.35rem);
	box-shadow: var(--sparkx-shadow-md);
}

.product-card-media {
	background: linear-gradient(180deg, #fbfdff 0%, #ffffff 100%);
	position: relative;
}

/* Pin the two floating badges to opposite top corners, guaranteed. Higher
   specificity + explicit position/left/right so neither can drift toward the
   centre or overlap, and the %-off flag can't grow into the heart. */
.product-card .product-card-media .discount-flag {
	position: absolute;
	top: 0.6rem;
	left: 0.6rem;
	right: auto;
	z-index: 3;
	max-width: calc(100% - 3.4rem);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.product-card .product-card-media .wishlist-toggle {
	position: absolute;
	top: 0.6rem;
	right: 0.6rem;
	left: auto;
	bottom: auto;
	margin: 0;
	z-index: 3;
}

/* Minutes marker sits bottom-left so it never collides with the %-off flag
   (top-left) or the wishlist heart (top-right). Colour/shape come from the shared
   .badge.bg-warning classes so it matches the Minutes badge on the orders page. */
.product-card .product-card-media .minutes-flag {
	position: absolute;
	bottom: 0.6rem;
	left: 0.6rem;
	z-index: 3;
	font-size: 0.68rem;
	font-weight: 700;
	box-shadow: var(--sparkx-shadow-sm);
	max-width: calc(100% - 1.2rem);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* Softer, more premium image zoom on the PDP (1.2 felt abrupt). */
.product-image-container:hover img {
	transform: scale(1.08);
}

/* Buy card reads as a distinct, elevated panel. */
.product-buy-card {
	border-radius: var(--sparkx-radius-lg);
	box-shadow: var(--sparkx-shadow-sm);
}

/* Keep everything inside the (narrow, on desktop) buy card — long words wrap and
   badges/pills stop rendering on a single overflowing line. */
.product-buy-card .card-body {
	overflow-wrap: anywhere;
	word-break: break-word;
}

.product-buy-card .badge {
	white-space: normal;
}

.product-buy-card .deliver-to-address {
	white-space: normal;
	word-break: break-word;
}

/* Prices align nicely and don't jitter as digits change (tabular figures). */
.product-detail-price,
.product-card .h5 {
	font-variant-numeric: tabular-nums;
}

/* Trust strip: each promise becomes a subtle, hoverable tile. */
.trust-item {
	padding: 0.6rem 0.75rem;
	border-radius: var(--sparkx-radius);
	transition: background-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.trust-item:hover {
	background: var(--sparkx-surface-alt);
	box-shadow: var(--sparkx-shadow-xs);
	transform: translateY(-1px);
}

/* Slightly bolder section accent bar for stronger visual rhythm on the home page. */
.section-title::after {
	width: 3.25rem;
	height: 0.28rem;
}

/* Password show/hide toggle (added by password_toggle.js). */
.pw-toggle-wrap {
	position: relative;
	display: block;
}

.pw-has-toggle > input,
.pw-has-toggle > .form-control {
	padding-right: 2.6rem;
}

.pw-toggle-btn {
	position: absolute;
	right: 0.55rem;
	top: 50%;
	transform: translateY(-50%);
	z-index: 3;
	border: none;
	background: transparent;
	color: var(--sparkx-muted);
	padding: 0.25rem 0.35rem;
	line-height: 1;
	cursor: pointer;
}

.pw-toggle-btn:hover {
	color: var(--sparkx-text-2);
}

/* Toast notifications (created by toast.js). Bottom-centre, auto-dismiss. */
.sparkx-toasts {
	position: fixed;
	left: 50%;
	bottom: 1.25rem;
	transform: translateX(-50%);
	z-index: 1090;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.5rem;
	width: min(92vw, 26rem);
	pointer-events: none;
}

.sparkx-toast {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	width: 100%;
	padding: 0.75rem 1rem;
	border-radius: var(--sparkx-radius);
	background: #0f172a;
	color: #fff;
	box-shadow: var(--sparkx-shadow-lg);
	font-size: 0.92rem;
	font-weight: 500;
	opacity: 0;
	transform: translateY(0.75rem);
	transition: opacity 0.25s ease, transform 0.25s ease;
}

.sparkx-toast.show {
	opacity: 1;
	transform: translateY(0);
}

.sparkx-toast i {
	font-size: 1.1rem;
	flex: 0 0 auto;
}

.sparkx-toast-success i {
	color: #4ade80;
}

.sparkx-toast-error {
	background: #7f1d1d;
}

.sparkx-toast-error i {
	color: #fecaca;
}

@media (max-width: 991.98px) {
	body:has(.mobile-buy-bar) .sparkx-toasts,
	body:has(.cart-checkout-bar) .sparkx-toasts {
		bottom: 5rem;
	}
}

/* Floating back-to-top button (element created by back_to_top.js). */
.back-to-top {
	position: fixed;
	right: 1rem;
	bottom: 1rem;
	z-index: 1035;
	width: 2.75rem;
	height: 2.75rem;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	border: 1px solid var(--sparkx-border);
	background: var(--sparkx-surface);
	color: var(--sparkx-primary);
	box-shadow: var(--sparkx-shadow-md);
	cursor: pointer;
	opacity: 0;
	visibility: hidden;
	transform: translateY(0.5rem);
	transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s, background-color 0.15s ease;
}

.back-to-top.show {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
}

.back-to-top:hover {
	background: var(--sparkx-primary-soft);
	color: var(--sparkx-primary-dark);
}

/* On phones, lift it above the sticky product action bar when that bar is present. */
@media (max-width: 991.98px) {
	body:has(.mobile-buy-bar) .back-to-top,
	body:has(.cart-checkout-bar) .back-to-top {
		bottom: 4.75rem;
	}
}

/* Respect users who prefer reduced motion — disable the lifts/zooms/smooth scroll. */
@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}
	.btn-primary:hover,
	.btn-warning:hover,
	.btn-success:hover,
	.btn-danger:hover,
	.product-card:hover,
	.trust-item:hover {
		transform: none;
	}
	.product-image-container:hover img {
		transform: none;
	}
}

/* --------------------------------------------------------------------------
   Order fulfilment tracker (orders page; inside the htmx-swapped status div)
   -------------------------------------------------------------------------- */

.order-tracker {
	display: flex;
	align-items: flex-start;
	margin-top: 0.85rem;
}

.order-tracker-step {
	flex: 1 1 0;
	position: relative;
	text-align: center;
	min-width: 0;
}

/* Connector line running back to the previous step's dot. */
.order-tracker-step::before {
	content: "";
	position: absolute;
	top: 0.85rem;
	right: 50%;
	width: 100%;
	height: 2px;
	background: var(--sparkx-border);
	z-index: 0;
}

.order-tracker-step:first-child::before {
	display: none;
}

.order-tracker-step.done::before {
	background: var(--sparkx-success);
}

.order-tracker-dot {
	position: relative;
	z-index: 1;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.7rem;
	height: 1.7rem;
	border-radius: 50%;
	background: var(--sparkx-surface);
	border: 2px solid var(--sparkx-border);
	color: var(--sparkx-muted);
	font-size: 0.8rem;
}

.order-tracker-label {
	display: block;
	margin-top: 0.3rem;
	font-size: 0.72rem;
	color: var(--sparkx-muted);
}

.order-tracker-step.done .order-tracker-dot {
	background: var(--sparkx-success);
	border-color: var(--sparkx-success);
	color: #fff;
}

.order-tracker-step.done .order-tracker-label {
	color: var(--sparkx-text-2);
	font-weight: 600;
}

.order-tracker-step.active .order-tracker-dot {
	box-shadow: 0 0 0 4px var(--sparkx-success-soft);
}

/* ==========================================================================
   Mobile app tab bar + micro-interactions (2026-07-19). Additive only —
   rendered by navigation :: footer_menu, hidden >=768px via d-md-none.
   ========================================================================== */

.mobile-tabbar {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 1030;
	display: flex;
	justify-content: space-around;
	align-items: stretch;
	background: rgba(255, 255, 255, 0.92);
	backdrop-filter: blur(12px);
	-webkit-backdrop-filter: blur(12px);
	border-top: 1px solid var(--sparkx-border);
	padding: 0.3rem 0 calc(0.3rem + env(safe-area-inset-bottom));
	box-shadow: 0 -2px 12px rgba(15, 23, 42, 0.06);
}

.tabbar-item {
	flex: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
	padding: 0.15rem 0;
	font-size: 0.68rem;
	font-weight: 600;
	color: var(--sparkx-muted);
	text-decoration: none;
}

.tabbar-item i { font-size: 1.15rem; }

.tabbar-item.active,
.tabbar-item:hover,
.tabbar-item:focus-visible { color: var(--sparkx-primary); }

.tabbar-icon-wrap { position: relative; display: inline-flex; }

.mobile-tabbar .cart-count-badge { top: -0.4rem; right: -0.7rem; }

/* Clear the tab bar on phones: page content and the floating back-to-top
   button must never sit underneath it. */
@media (max-width: 767.98px) {
	body { padding-bottom: 4.4rem; }
	.back-to-top { bottom: 4.9rem; }
}

@media print { .mobile-tabbar { display: none; } }

/* Micro-interactions */
html { scroll-behavior: smooth; }

::selection { background: var(--sparkx-primary); color: #fff; }

.btn:active { transform: scale(0.985); }

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	.product-card,
	.minutes-shop-card,
	.btn:active { transform: none; transition: none; }
}

/* ==========================================================================
   Order support message thread (2026-07-20).
   ========================================================================== */
.order-thread { max-height: 22rem; overflow-y: auto; padding-right: 0.25rem; }
.order-msg { display: flex; margin-bottom: 0.6rem; }
.order-msg.msg-mine { justify-content: flex-end; }
.order-msg.msg-staff { justify-content: flex-start; }
.order-msg-bubble {
	max-width: 78%;
	padding: 0.5rem 0.75rem;
	border-radius: var(--sparkx-radius, 0.75rem);
	font-size: 0.92rem;
	line-height: 1.35;
}
.msg-mine .order-msg-bubble {
	background: var(--sparkx-primary, #2563eb);
	color: #fff;
	border-bottom-right-radius: 0.25rem;
}
.msg-staff .order-msg-bubble {
	background: var(--sparkx-surface-alt, #f1f5f9);
	color: var(--sparkx-text, #0f172a);
	border-bottom-left-radius: 0.25rem;
}
.order-msg-body { white-space: pre-wrap; word-break: break-word; }
.order-msg-meta { font-size: 0.68rem; opacity: 0.75; margin-top: 0.2rem; }

/* Minutes search hits: a product row that names the shop it comes from, so one
   result list can mix "shops" and "things shops sell" without ambiguity. */
.minutes-hit {
	transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}

.minutes-hit:hover {
	box-shadow: var(--sparkx-shadow-md);
	transform: translateY(-2px);
}

.minutes-hit-img {
	flex: 0 0 auto;
	width: 3.5rem;
	height: 3.5rem;
	object-fit: contain;
	background: #fff;
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius);
	padding: 0.2rem;
}

/* Lets a flex child shrink instead of forcing its text to overflow the card. */
.min-width-0 {
	min-width: 0;
}

.text-truncate-2 {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* ==========================================================================
   Help assistant — shared by the /help/chat page and the floating widget.
   ========================================================================== */

.chat-log { overflow-y: auto; }

.chat-row { display: flex; margin-bottom: 0.6rem; }
.chat-row.from-bot { justify-content: flex-start; }
.chat-row.from-user { justify-content: flex-end; }

.chat-bubble {
	max-width: 85%;
	padding: 0.6rem 0.85rem;
	border-radius: var(--sparkx-radius-lg);
	font-size: 0.95rem;
	line-height: 1.45;
	white-space: pre-wrap;
}

.from-bot .chat-bubble {
	background: #f1f5f9;
	color: var(--sparkx-text);
	border-bottom-left-radius: 0.25rem;
}

.from-user .chat-bubble {
	background: var(--sparkx-primary);
	color: #fff;
	border-bottom-right-radius: 0.25rem;
}

.chat-chip {
	border: 1px solid var(--sparkx-border-strong);
	background: #fff;
	color: var(--sparkx-text-2);
	border-radius: var(--sparkx-radius-pill);
	padding: 0.3rem 0.8rem;
	font-size: 0.85rem;
}

.chat-chip:hover,
.chat-chip:focus {
	background: var(--sparkx-primary-soft);
	border-color: var(--sparkx-primary);
}

/* --- floating widget ---------------------------------------------------- */

.help-fab {
	position: fixed;
	right: 1rem;
	bottom: 1rem;
	z-index: 1045;
	width: 3.25rem;
	height: 3.25rem;
	border: 0;
	border-radius: 50%;
	background: var(--sparkx-primary);
	color: #fff;
	font-size: 1.15rem;
	box-shadow: var(--sparkx-shadow-md);
}

.help-fab:hover { background: var(--sparkx-primary-dark); }

.help-widget {
	position: fixed;
	right: 1rem;
	bottom: 5rem;
	z-index: 1046;
	width: min(23rem, calc(100vw - 2rem));
	max-height: min(30rem, calc(100vh - 8rem));
	display: none;
	flex-direction: column;
	background: var(--sparkx-surface);
	border: 1px solid var(--sparkx-border);
	border-radius: var(--sparkx-radius-lg);
	box-shadow: var(--sparkx-shadow-lg);
	overflow: hidden;
}

.help-widget.open { display: flex; }
.help-widget .chat-log { flex: 1 1 auto; min-height: 9rem; }

/* The phone tab bar owns the bottom edge, so the launcher sits above it rather
   than on top of the Account button. */
@media (max-width: 767.98px) {
	.help-fab { bottom: 4.75rem; }
	.help-widget { bottom: 8.75rem; max-height: calc(100vh - 12rem); }
}

/* Live stock on product cards (live_availability.js). Bottom-right, because the other
   three corners belong to the discount flag, the wishlist heart and the Minutes flag. */
.product-card .product-card-media .stock-flag {
	position: absolute;
	bottom: 0.6rem;
	right: 0.6rem;
	z-index: 3;
	font-size: 0.68rem;
	font-weight: 700;
	background-color: var(--sparkx-danger-soft);
	color: var(--sparkx-danger);
	border: 1px solid #fecaca;
	box-shadow: var(--sparkx-shadow-sm);
}

.product-card .product-card-media .stock-flag-out {
	background-color: var(--sparkx-muted);
	color: #fff;
	border-color: transparent;
}

.product-card.is-sold-out .product-card-image {
	opacity: 0.5;
	filter: grayscale(35%);
}

.cart-item-card .availability-note {
	font-weight: 600;
}

/* Minutes items already flag the bottom-left corner of the card, so on a narrow phone card the
   stock flag (bottom-right) collided with it. Lift the stock flag above it when both exist. */
.product-card .product-card-media:has(.minutes-flag) .stock-flag {
	bottom: 2.35rem;
}

/* Touch targets. On a phone the small buttons (quantity steppers, remove links, btn-sm links)
   measured 24-31px tall, well under what a thumb reliably hits. Desktop keeps the compact
   sizing; only pointer-coarse/narrow screens grow. */
@media (max-width: 767.98px) {
	.btn-sm,
	.input-group-sm > .btn,
	.input-group-sm > .form-control {
		min-height: 40px;
	}

	.navbar-toggler,
	.pw-toggle-btn {
		min-height: 40px;
	}

	.cart-item-card .linkRemove,
	.product-card-media .wishlist-toggle {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		min-width: 40px;
		min-height: 40px;
	}

	/* Breadcrumbs are the way back on a phone, and each link was only as tall as its text
	   (20px). Padding grows the area a thumb can hit without changing the type size, so the
	   trail still reads as a breadcrumb rather than a row of buttons. */
	.breadcrumb-item a {
		display: inline-block;
		padding: 0.55rem 0;
	}

	/* The clear button inside the search field was 28px. It sits over the input, so it can
	   only grow to what the field can hold. */
	.search-clear-inline {
		width: 2.25rem;
		height: 2.25rem;
	}

	/* Bootstrap's close button is 24px square, which is the one control every dialog has and
	   the one a thumb most often misses. The icon keeps its size; the box around it grows. */
	.btn-close {
		width: 2.25rem;
		height: 2.25rem;
		background-size: 1rem;
	}
}

/* On a phone the floating chat button sat on top of "Proceed to Checkout" in the cart summary
   (a one-item cart puts that button exactly in the corner the button floats over), so taps on
   the right of the CTA opened chat instead of checking out. The cart and checkout already
   carry their own sticky action bar, so the launcher stands down on those two screens; it is
   still there everywhere else, and Help remains in the menu. */
@media (max-width: 767.98px) {
	body:has(#cartCheckoutBar) .help-fab,
	body:has(.checkout-sticky-bar) .help-fab {
		display: none;
	}
}
