/*
 * TJL Homepage Category Filter
 *
 * Every rule is gated on a class this plugin's JS adds only after it has
 * successfully wired at least one tile to a native filter tab:
 *   .tjl-hcf-on        -> on the tp-product-listout widget wrapper
 *   .tjl-hcf-strip-on  -> on the #tjl-category-strip container
 * If the JS bails, none of these apply and the widget's own visible text-tab
 * filter row keeps working.
 */

/* ---------- 1. Hide the widget's native text-tab row ---------- */
/* Kept in the DOM (display:none), because the tiles drive it programmatically. */
#tjl-cat-products.tjl-hcf-on .post-filter-data {
	display: none !important;
}

/* ---------- 2. The circular tiles become the filter control ---------- */
#tjl-category-strip .tjl-cat-tile {
	cursor: pointer;
	position: relative;
	border-radius: 14px;
	transition: transform 0.25s ease;
	-webkit-tap-highlight-color: transparent;
}

#tjl-category-strip .tjl-cat-tile img {
	box-shadow: 0 0 0 1px rgba(58, 58, 58, 0.1);
	transition: box-shadow 0.25s ease, transform 0.25s ease;
}

#tjl-category-strip .tjl-cat-tile .elementor-heading-title {
	transition: color 0.2s ease, font-weight 0.2s ease;
}

#tjl-category-strip .tjl-cat-tile:hover {
	transform: translateY(-2px);
}

#tjl-category-strip .tjl-cat-tile:hover img {
	box-shadow: 0 0 0 2px rgba(132, 65, 192, 0.35);
}

#tjl-category-strip .tjl-cat-tile:hover .elementor-heading-title {
	color: #8441c0 !important;
}

/* Active state: purple ring + halo, purple label. */
#tjl-category-strip .tjl-cat-tile--active img {
	box-shadow: 0 0 0 2px #8441c0, 0 0 0 6px rgba(132, 65, 192, 0.16);
}

#tjl-category-strip .tjl-cat-tile--active .elementor-heading-title {
	color: #8441c0 !important;
	font-weight: 600 !important;
}

/* Keyboard focus. :focus-visible only, so mouse clicks stay clean. */
#tjl-category-strip .tjl-cat-tile:focus {
	outline: none;
}

#tjl-category-strip .tjl-cat-tile:focus-visible {
	outline: 2px solid #8441c0;
	outline-offset: 4px;
}

/* ---------- 3. In-flight cue while the AJAX swap happens ---------- */
#tjl-cat-products.tjl-hcf-loading .post-inner-loop {
	/* The skeleton overlay (section 9) is what signals loading; dimming as well
	   just made the skeleton itself look washed out. */
	pointer-events: none;
}

#tjl-cat-products .post-inner-loop {
	transition: opacity 0.2s ease;
}

/* ---------- 4. The purple "See all <Category>" CTA ---------- */
#tjl-cat-cta {
	margin-top: 4px;
}

#tjl-cat-cta .elementor-button {
	white-space: normal;
}

/* ---------- 5. Mobile + tablet: one horizontally scrollable row ---------- */
/* Eight 104px tiles wrap to three ragged rows on a phone. Scroll instead. */
@media (max-width: 1024px) {
	#tjl-category-strip.tjl-hcf-strip-on > .e-con-inner {
		flex-wrap: nowrap !important;
		justify-content: flex-start !important;
		overflow-x: auto;
		overflow-y: hidden;
		scroll-snap-type: x proximity;
		scroll-padding-left: 12px;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
		-ms-overflow-style: none;
		/* Room for the active ring so it is not clipped by the scroll box. */
		padding-bottom: 8px;
	}

	#tjl-category-strip.tjl-hcf-strip-on > .e-con-inner::-webkit-scrollbar {
		display: none;
	}

	#tjl-category-strip.tjl-hcf-strip-on .tjl-cat-tile {
		flex: 0 0 auto;
		scroll-snap-align: center;
	}
}

/* Respect reduced-motion preferences. */
@media (prefers-reduced-motion: reduce) {
	#tjl-category-strip .tjl-cat-tile,
	#tjl-category-strip .tjl-cat-tile img,
	#tjl-cat-products .post-inner-loop {
		transition: none !important;
	}

	#tjl-category-strip .tjl-cat-tile:hover {
		transform: none;
	}
}

/* =====================================================================
 * 6. The product grid itself
 *
 * Not cosmetic polish -- without this the listing has no layout at all.
 * The Plus maps tp-product-listout to `tp-bootstrap-grid.css` under
 * L_THEPLUS_PATH (its free plugin), and that file does not exist on this
 * install, so .tp-col-lg-3 / .tp-col-md-4 / .tp-col-sm-6 resolve to nothing.
 * The only other copy of those rules lives in general/theplus.min.css, a
 * site-wide stylesheet we deliberately do not load. So we define the columns
 * here, scoped to this one widget.
 *
 * These rules are NOT gated on .tjl-hcf-on: the listing needs them whether or
 * not the tile enhancement booted.
 * ===================================================================== */

/* Neutralise isotope. It absolutely-positions items using widths that do not
 * exist, which is what produced the single stacked column. Author !important
 * beats isotope's inline styles, so the layout below stays authoritative even
 * after its relayout on resize and after each AJAX swap. */
#tjl-cat-products .post-inner-loop {
	height: auto !important;
}

#tjl-cat-products .post-inner-loop .grid-item {
	position: static !important;
	left: auto !important;
	top: auto !important;
	transform: none !important;
	width: auto !important;
	max-width: none !important;
	float: none !important;
	margin: 0 !important;
	padding: 0 !important;
}

/* Desktop: 4 across. With display_posts = 8 that is exactly two rows. */
#tjl-cat-products .post-inner-loop {
	display: grid !important;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 34px 24px;
	margin: 0 !important;
}

/* Square, uniformly cropped product images. Two different markup shapes reach
 * this container -- the server render nests .hover-image, the AJAX response
 * nests .product-featured-image > .thumb-wrap -- so target the box, not the path. */
#tjl-cat-products .product-content-image {
	position: relative;
	width: 100%;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	border-radius: 20px;
	background: #f7f4fa;
}

#tjl-cat-products .product-content-image > a.product-image,
#tjl-cat-products .product-content-image .product-featured-image,
#tjl-cat-products .product-content-image .thumb-wrap,
#tjl-cat-products .product-content-image span.product-image {
	display: block;
	width: 100%;
	height: 100%;
}

#tjl-cat-products .product-content-image img {
	width: 100% !important;
	height: 100% !important;
	max-width: none;
	object-fit: cover;
	display: block;
}

/* Typography: sized for a 4-up card, not for a full-width row. */
#tjl-cat-products .product-list-content {
	padding-top: 14px;
}

#tjl-cat-products .post-title,
#tjl-cat-products .post-title a {
	font-size: 15px !important;
	line-height: 1.35 !important;
	display: block;
}

#tjl-cat-products .price,
#tjl-cat-products .price .woocommerce-Price-amount,
#tjl-cat-products .product-list-content .price bdi {
	font-size: 15px !important;
	line-height: 1.3 !important;
}

/* Tablet: 3 across, trimmed to a clean two rows. */
@media (min-width: 768px) and (max-width: 1024px) {
	#tjl-cat-products .post-inner-loop {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 26px 18px;
	}

	#tjl-cat-products .post-inner-loop .grid-item:nth-child(n + 7) {
		display: none !important;
	}
}

/* Mobile: one continuous horizontally scrolling row. */
@media (max-width: 767px) {
	#tjl-cat-products .post-inner-loop {
		display: flex !important;
		flex-wrap: nowrap !important;
		grid-template-columns: none;
		overflow-x: auto;
		overflow-y: hidden;
		gap: 14px;
		scroll-snap-type: x proximity;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
		-ms-overflow-style: none;
		padding-bottom: 6px;
	}

	#tjl-cat-products .post-inner-loop::-webkit-scrollbar {
		display: none;
	}

	#tjl-cat-products .post-inner-loop .grid-item {
		flex: 0 0 62% !important;
		scroll-snap-align: start;
	}

	#tjl-cat-products .post-title,
	#tjl-cat-products .post-title a {
		font-size: 14px !important;
	}

	#tjl-cat-products .price,
	#tjl-cat-products .price .woocommerce-Price-amount,
	#tjl-cat-products .product-list-content .price bdi {
		font-size: 14px !important;
	}
}

/* =====================================================================
 * 7. Scroll affordances: hairline rule, edge glows, category arrows
 *
 * The host gets .tjl-no-scroll whenever the row is not actually scrollable
 * (the desktop product grid, or a category row that fits), so every affordance
 * below disappears on its own at wider breakpoints -- no breakpoint duplication.
 * ===================================================================== */

/* The rule that separates the categories from the products. Sits between the
 * two as a section-level sibling, pulled in from the section's 60px gap. */
.tjl-rule {
	display: block;
	align-self: stretch;
	width: 100%;
	max-width: 1250px;
	height: 1px;
	margin: -26px auto;
	border: 0;
	background: linear-gradient(
		90deg,
		rgba(132, 65, 192, 0) 0%,
		rgba(132, 65, 192, 0.22) 22%,
		rgba(132, 65, 192, 0.22) 78%,
		rgba(132, 65, 192, 0) 100%
	);
}

.tjl-scroll-host {
	position: relative;
}

/* Edge glow. Brand-purple rather than a white fade, because the left of this
 * section sits on the decorative grey panel and a white fade would smear. */
.tjl-fade {
	position: absolute;
	top: 0;
	bottom: 0;
	width: 58px;
	z-index: 3;
	pointer-events: none;
	opacity: 1;
	transition: opacity 0.28s ease;
}

.tjl-fade--start {
	left: 0;
	background: linear-gradient(
		to right,
		rgba(132, 65, 192, 0.14) 0%,
		rgba(132, 65, 192, 0.05) 45%,
		rgba(132, 65, 192, 0) 100%
	);
}

.tjl-fade--end {
	right: 0;
	background: linear-gradient(
		to left,
		rgba(132, 65, 192, 0.14) 0%,
		rgba(132, 65, 192, 0.05) 45%,
		rgba(132, 65, 192, 0) 100%
	);
}

/* Nothing to scroll, or already parked at that end -> no hint. */
.tjl-no-scroll .tjl-fade,
.tjl-at-start .tjl-fade--start,
.tjl-at-end .tjl-fade--end {
	opacity: 0;
}

/* Category arrows. White pill with a purple chevron; fills purple on hover,
 * matching the theme's button family (#8441C0 -> #E4097F).
 *
 * Specificity + !important are load-bearing here, not defensive habit: the
 * theme styles bare <button> strongly enough to beat a single class. Measured
 * before this was added, these arrows computed to background rgb(0,0,0),
 * colour white, border-radius 0, 62x32, with the chevron SVG at width 0 --
 * they rendered as solid black rectangles over the tiles. */
.tjl-scroll-host button.tjl-nav {
	position: absolute !important;
	top: var(--tjl-nav-top, 50%) !important;
	transform: translateY(-50%) !important;
	width: 38px !important;
	height: 38px !important;
	min-width: 0 !important;
	min-height: 0 !important;
	max-width: none !important;
	padding: 0 !important;
	margin: 0 !important;
	border: 1px solid rgba(132, 65, 192, 0.25) !important;
	border-radius: 50% !important;
	background: #fff !important;
	background-image: none !important;
	color: #8441c0 !important;
	font-size: 0 !important;
	line-height: 0 !important;
	letter-spacing: normal !important;
	text-transform: none !important;
	display: flex !important;
	align-items: center !important;
	justify-content: center !important;
	cursor: pointer !important;
	z-index: 4 !important;
	box-shadow: 0 2px 12px rgba(58, 58, 58, 0.12) !important;
	transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease, opacity 0.2s ease !important;
}

.tjl-scroll-host button.tjl-nav:hover,
.tjl-scroll-host button.tjl-nav:focus-visible {
	background: #8441c0 !important;
	border-color: #8441c0 !important;
	color: #fff !important;
	outline: none !important;
}

.tjl-scroll-host button.tjl-nav:focus-visible {
	box-shadow: 0 0 0 3px rgba(132, 65, 192, 0.25) !important;
}

.tjl-scroll-host button.tjl-nav svg {
	width: 14px !important;
	height: 14px !important;
	flex: 0 0 14px !important;
	display: block !important;
	fill: none !important;
	stroke: currentColor !important;
	stroke-width: 2.4 !important;
	stroke-linecap: round !important;
	stroke-linejoin: round !important;
}

.tjl-scroll-host button.tjl-nav--prev {
	left: -2px !important;
	right: auto !important;
}

.tjl-scroll-host button.tjl-nav--prev svg {
	transform: rotate(180deg) !important;
}

.tjl-scroll-host button.tjl-nav--next {
	right: -2px !important;
	left: auto !important;
}

.tjl-no-scroll button.tjl-nav {
	display: none !important;
}

/* Fully hidden, not dimmed: these float over the row, and a ghosted circle
   sitting on top of the first tile read as a smudge rather than a control. */
.tjl-at-start button.tjl-nav--prev,
.tjl-at-end button.tjl-nav--next {
	opacity: 0 !important;
	pointer-events: none !important;
}

@media (max-width: 767px) {
	.tjl-rule {
		margin: -22px auto;
	}

	.tjl-fade {
		width: 42px;
	}

	.tjl-scroll-host button.tjl-nav {
		width: 32px !important;
		height: 32px !important;
	}
}

/* =====================================================================
 * 8. Homepage-wide fix: horizontal overflow at phone widths
 *
 * The Instagram feed carousel (elementor-element-3496d4e, tp-social-feed) has
 * The Plus's `outer_section_arrow` enabled, which parks its slick arrows
 * OUTSIDE the section. At 390px that put .slick-next at left:385 -> right:445,
 * pushing document.scrollWidth to 445 against a 390px viewport: exactly 55px of
 * horizontal page scroll. Measured, not guessed -- it was the only element
 * extending past the right edge once fixed-position and clipped subtrees were
 * excluded.
 *
 * Applied across phone AND tablet (<=1024px): at 768px the same arrow sat at
 * left:768 -> right:828, i.e. 60px of page scroll. Desktop is left untouched,
 * and the arrows are moved inside rather than hidden, so the control is kept.
 *
 * Second offender at 768px: the header's login/register trigger. The anchor's
 * intrinsic width is 129.8px but its flex-shrunk parent is 121.7px, so it hung
 * 8px past the edge. Capped rather than un-shrunk, because un-shrinking it
 * would just push the overflow onto its neighbours in the header row.
 * NOTE: that button is in the site header, so the same 8px exists on every
 * page; this plugin is front-page-only, so only the homepage is fixed here.
 * ===================================================================== */
@media (max-width: 1024px) {
	.elementor-element-e6740b9 .tp-ursp-btn.tp-ursp-trigger {
		max-width: 100%;
		box-sizing: border-box;
		padding-left: 8px;
		padding-right: 8px;
	}

	.elementor-element-3496d4e .slick-nav.slick-prev {
		left: 4px !important;
		right: auto !important;
	}

	.elementor-element-3496d4e .slick-nav.slick-next {
		right: 4px !important;
		left: auto !important;
	}

	/* Belt and braces: nothing inside this widget may widen the page. */
	.elementor-element-3496d4e {
		overflow-x: clip;
	}
}

/* =====================================================================
 * 9. Own the skeleton placeholder state
 *
 * The Plus shows/hides its .tp-skeleton overlays by writing inline styles, and
 * hides them 1s after the AJAX with `tp_Skeleton_filter('hidden')` -- which
 * only acts on a skeleton whose INLINE style still reads visibility:visible.
 * The AJAX response replaces .post-inner-loop wholesale, so the skeletons the
 * hide-pass looks at are not the ones it made visible. Whether they end up
 * hidden then depends on what markup came back: observed stuck-visible on two
 * runs and correctly hidden on a third, at the same breakpoint.
 *
 * So the skeleton follows OUR loading flag instead, which is set when a filter
 * starts and cleared on ajaxComplete. Deterministic, and scoped to this widget.
 * ===================================================================== */
#tjl-cat-products .tp-skeleton {
	visibility: hidden !important;
	opacity: 0 !important;
}

#tjl-cat-products.tjl-hcf-loading .tp-skeleton {
	visibility: visible !important;
	opacity: 1 !important;
}

/* =====================================================================
 * 10. Mobile refinement
 *
 * Both horizontal rows run edge to edge: the row bleeds past the section's
 * 20px side padding while its CONTENT keeps a 20px inset, so the first card
 * still lines up with the headings above it but cards scroll away under the
 * screen edge instead of stopping short of it.
 *
 * Loaded last on purpose: these override the grid rules in section 6.
 * ===================================================================== */
@media (max-width: 767px) {

	/* ---- full bleed, with the content inset preserved ---- */
	#tjl-category-strip.tjl-hcf-strip-on > .e-con-inner,
	#tjl-cat-products .post-inner-loop {
		width: calc(100% + 40px) !important;
		max-width: calc(100% + 40px) !important;
		margin-left: -20px !important;
		margin-right: -20px !important;
		padding-left: 20px !important;
		padding-right: 20px !important;
		scroll-padding-left: 20px;
		scroll-padding-right: 20px;
	}

	/* The rule stays aligned to the text column, not the bled row. */
	.tjl-rule {
		margin: -8px auto !important;
	}

	/* ---- category row ---- */
	#tjl-category-strip.tjl-hcf-strip-on > .e-con-inner {
		/* Arrows sit over the extreme edges; keep snapped tiles clear of them. */
		scroll-padding-left: 44px;
		scroll-padding-right: 44px;
		padding-top: 2px;
		padding-bottom: 2px;
	}

	#tjl-category-strip.tjl-hcf-strip-on {
		padding-top: 6px !important;
		padding-bottom: 0 !important;
	}

	/* ---- product row ---- */
	#tjl-cat-products .post-inner-loop {
		gap: 12px !important;
	}

	#tjl-cat-products .post-inner-loop .grid-item {
		/* Peeking card: one full card plus a clear slice of the next. */
		flex: 0 0 64% !important;
	}

	#tjl-cat-products .product-list-content {
		padding-top: 10px;
	}

	/* Titles down ~10% here too, to match the headings. */
	#tjl-cat-products .post-title,
	#tjl-cat-products .post-title a {
		font-size: 13px !important;
	}

	#tjl-cat-products .price,
	#tjl-cat-products .price .woocommerce-Price-amount,
	#tjl-cat-products .product-list-content .price bdi {
		font-size: 13px !important;
	}

	/* The glow must sit at the true screen edges now that the row is bled. */
	.tjl-scroll-host .tjl-fade {
		width: 34px;
	}

	/* ---- arrows: floating controls, not blocks ---- */
	.tjl-scroll-host button.tjl-nav {
		width: 30px !important;
		height: 30px !important;
		background: rgba(255, 255, 255, 0.94) !important;
		-webkit-backdrop-filter: blur(3px);
		backdrop-filter: blur(3px);
		box-shadow: 0 2px 10px rgba(58, 58, 58, 0.18) !important;
	}

	.tjl-scroll-host button.tjl-nav--prev {
		left: 6px !important;
	}

	.tjl-scroll-host button.tjl-nav--next {
		right: 6px !important;
	}

	.tjl-scroll-host button.tjl-nav svg {
		width: 12px !important;
		height: 12px !important;
		flex: 0 0 12px !important;
	}

	/* ---- CTA breathing ---- */
	#tjl-cat-cta {
		margin-top: 2px;
	}
}

/* =====================================================================
 * 11. Hero stat strip on mobile
 *
 * The strip is laid out in Elementor (3 x 33.33% with hairline dividers on
 * mobile, same shape as desktop). These two rules just stop the tightest
 * value, "1,000,000+", from breaking across lines in a ~100px column.
 * ===================================================================== */
@media (max-width: 767px) {
	#tjl-hero-stats .elementor-counter-number-wrapper {
		white-space: nowrap;
	}

	#tjl-hero-stats .elementor-counter-title {
		line-height: 1.25;
	}
}
