/**
 * Product Widget Styles
 * BEM Naming Convention: .flx-block__element--modifier
 *
 * Colors and spacing sampled directly from the site's existing product
 * page design (client reference screenshot) rather than approximated.
 *
 * @package Flolynx_Elementor
 */

/* ======================================================================
   CONTAINER
   ====================================================================== */

.flx-product {
	--flx-button-color: #111111;
	--flx-button-hover: #2c2c2c;
	--flx-option-border: #e0e0e0;
	--flx-gallery-border: #ececec;
	--flx-gallery-height: 420px;
	--flx-gallery-aspect-ratio: 1 / 1;
	--flx-gallery-bg: #cfe2e8;
	--flx-accent-blue: #24B5EB;
	--flx-accent-blue-dark: #187BA0;

	width: 100%;
	font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
	box-sizing: border-box;
	/* !important on the color/background/border declarations throughout
	   this file: some themes (Hello Elementor's reset.css among them,
	   confirmed by testing on this widget) ship a global reset for bare
	   button/input/text elements that can end up with equal or higher CSS
	   specificity than our own class selectors, depending on how deeply a
	   theme nests Elementor's widget markup. A generic reset is never
	   supposed to have the final word on a specific widget's look, so it's
	   safe to unconditionally win here. */
	color: #111111 !important;
	background: #ffffff !important;
	border: 1px solid var(--flx-gallery-border) !important;
	border-radius: 12px;
	padding: 24px;
}

.flx-product__layout {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 40px;
	align-items: flex-start;
}

/* ======================================================================
   GALLERY
   ====================================================================== */

.flx-product__gallery {
	display: flex;
	gap: 16px;
}

.flx-product__gallery-thumbs {
	display: flex;
	flex-direction: column;
	gap: 10px;
	flex-shrink: 0;
	width: 68px;
}

.flx-product__gallery-thumb {
	width: 68px;
	height: 68px;
	flex-shrink: 0;
	padding: 0;
	border: 1px solid var(--flx-gallery-border) !important;
	border-radius: 8px;
	overflow: hidden;
	cursor: pointer;
	background: #fff !important;
	transition: border-color 0.2s ease;
}

.flx-product__gallery-thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.flx-product__gallery-thumb.is-active,
.flx-product__gallery-thumb:hover {
	border-color: var(--flx-accent-blue) !important;
	border-width: 2px;
}

.flx-product__gallery-main {
	position: relative;
	flex: 1;
	width: 100%;
	/* Reverted a forced 120px min-width/min-height that was added
	   defensively against a hypothetical "frame collapses to invisible"
	   edge case — it was implicated (alongside container queries, removed
	   above) in a real, confirmed rendering bug on mobile: forcing a
	   minimum size regardless of available width can itself cause
	   horizontal overflow/scrollbars on genuinely narrow mobile viewports,
	   which is a worse, now-confirmed problem versus the speculative one
	   it was guarding against. `min-width: 0` is what actually lets a flex
	   item shrink to fit tight mobile widths correctly. */
	min-width: 0;
	/* aspect-ratio keeps the frame proportional to its own width at every
	   screen size (instead of a fixed pixel height that used to turn into
	   a very wide, short, crop-looking strip once the layout dropped to a
	   single column on tablet/small-laptop widths). The configured
	   "Gallery Height" control now acts as a cap on how tall the frame is
	   allowed to grow on wide desktop layouts. */
	aspect-ratio: var(--flx-gallery-aspect-ratio);
	max-height: var(--flx-gallery-height);
	border-radius: 16px;
	overflow: hidden;
	background: var(--flx-gallery-bg);
}

.flx-product__new-badge {
	position: absolute;
	top: 16px;
	inset-inline-start: 16px;
	z-index: 2;
	background: #ffffff !important;
	color: #333333 !important;
	font-size: 12px;
	font-weight: 600;
	padding: 6px 16px;
	border-radius: 999px;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.flx-product__gallery-image {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: contain;
	padding: 24px;
	box-sizing: border-box;
	opacity: 0;
	transition: opacity 0.3s ease;
	pointer-events: none;
}

.flx-product__gallery-image.is-active {
	opacity: 1;
	pointer-events: auto;
}

.flx-product__gallery-placeholder {
	width: 100%;
	height: 100%;
	background: repeating-linear-gradient(45deg, #c3dbe2, #c3dbe2 10px, var(--flx-gallery-bg) 10px, var(--flx-gallery-bg) 20px);
}

/* ======================================================================
   DETAILS
   ====================================================================== */

.flx-product__details {
	padding-top: 4px;
}

.flx-product__eyebrow {
	font-size: 12px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	/* !important on color/border/background throughout this file's
	   interactive elements: some themes (Hello Elementor's reset.css among
	   them, confirmed by testing) ship a global reset — normalize-style
	   rules for bare `button`/`input`/text elements — that can end up
	   with equal or higher specificity than our own class selectors,
	   depending on how deeply Elementor nests the widget markup on a given
	   theme/page. A generic reset is never supposed to act as the final
	   word on a specific widget's look, so it's safe to unconditionally
	   win here. */
	color: #8a8a8a !important;
	margin: 0 0 8px;
}

.flx-product__title {
	font-size: 28px;
	font-weight: 700;
	line-height: 1.25;
	color: #111111 !important;
	margin: 0 0 6px;
}

.flx-product__tagline {
	font-size: 14px;
	color: #8a8a8a !important;
	margin: 0 0 16px;
}

.flx-product__divider {
	height: 1px;
	background: #ececec !important;
	margin: 0 0 20px;
}

.flx-product__price-block {
	margin-bottom: 24px;
}

.flx-product__price {
	font-size: 32px;
	font-weight: 700;
	color: #111111 !important;
	line-height: 1.2;
}

.flx-product__price del {
	opacity: 0.5;
	font-weight: 400;
	font-size: 0.6em;
	margin-inline-end: 8px;
}

.flx-product__price-note-static,
.flx-product__price-note {
	font-size: 13px;
	color: #9a9a9a !important;
	margin: 4px 0 0;
}

/* ======================================================================
   OPTIONS (FLAVOUR / PACK SIZE)
   ====================================================================== */

.flx-product__options {
	margin-bottom: 24px;
}

.flx-product__options-label {
	font-size: 12px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: #8a8a8a !important;
	margin: 0 0 10px;
}

.flx-product__options-grid {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

.flx-product__option-btn {
	padding: 10px 16px;
	min-height: 44px;
	border: 1px solid var(--flx-option-border) !important;
	border-radius: 10px;
	background: #ffffff !important;
	color: #111111 !important;
	font-size: 14px;
	cursor: pointer;
	transition: border-color 0.2s ease, border-width 0.1s ease;
}

.flx-product__option-btn:hover {
	border-color: #b8b8b8 !important;
}

.flx-product__option-btn.is-active {
	border-color: var(--flx-button-color) !important;
	border-width: 2px;
	background: #ffffff !important;
}

.flx-product__option-btn:focus-visible {
	outline: 2px solid var(--flx-accent-blue);
	outline-offset: 2px;
}

/* Pack size buttons: big number + small "PACK" caption, stacked */

.flx-product__pack-btn {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 2px;
	min-width: 74px;
	padding: 12px 10px;
}

.flx-product__pack-num {
	font-size: 22px;
	font-weight: 700;
	color: #111111 !important;
	line-height: 1;
}

.flx-product__pack-unit {
	font-size: 11px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: #9a9a9a !important;
}

/* Flavour buttons: icon + name */

.flx-product__flavour-btn {
	display: flex;
	align-items: center;
	gap: 8px;
	text-align: start;
}

.flx-product__flavour-icon {
	font-size: 18px;
	line-height: 1;
	display: inline-flex;
}

.flx-product__flavour-icon img {
	width: 20px;
	height: 20px;
	object-fit: contain;
	border-radius: 4px;
}

.flx-product__flavour-name {
	font-size: 14px;
	color: #333333 !important;
}

.flx-product__flavour-btn.is-active .flx-product__flavour-name {
	color: #111111 !important;
	font-weight: 600;
}

/* ======================================================================
   PURCHASE TYPE / SUBSCRIPTION
   ====================================================================== */

.flx-product__purchase-type {
	margin-bottom: 24px;
}

.flx-product__purchase-tabs {
	display: flex;
	border: 1px solid var(--flx-option-border) !important;
	border-radius: 10px;
	overflow: hidden;
}

.flx-product__purchase-tab {
	flex: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 14px 12px;
	min-height: 48px;
	border: none;
	background: #f9f9f9 !important;
	color: #555555 !important;
	font-size: 14px;
	font-weight: 600;
	cursor: pointer;
	transition: background 0.2s ease, color 0.2s ease;
}

.flx-product__purchase-tab.is-active {
	background: var(--flx-button-color) !important;
	color: #ffffff !important;
}

.flx-product__purchase-tab.is-disabled {
	opacity: 0.45;
	cursor: not-allowed;
}

.flx-product__purchase-icon {
	font-size: 15px;
	line-height: 1;
}

.flx-product__purchase-icon--accent {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
	border-radius: 5px;
	background: var(--flx-accent-blue);
	font-size: 12px;
}

/* Delivery panel: shown only while "Subscribe & Save" is selected */

.flx-product__delivery-panel {
	display: none;
	background: #f9f9f9 !important;
	border-radius: 12px;
	padding: 18px;
	margin-top: 12px;
}

.flx-product__purchase-type[data-mode="subscribe"] .flx-product__delivery-panel {
	display: block;
}

.flx-product__delivery-panel .flx-product__options-label {
	margin-bottom: 10px;
}

.flx-product__intervals {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-bottom: 14px;
}

.flx-product__interval-btn {
	padding: 10px 18px;
	min-height: 44px;
	border: 1px solid var(--flx-option-border) !important;
	border-radius: 8px;
	background: #ffffff !important;
	color: #333333 !important;
	font-size: 14px;
	font-weight: 600;
	cursor: pointer;
	transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.flx-product__interval-btn.is-active {
	background: var(--flx-button-color) !important;
	border-color: var(--flx-button-color) !important;
	color: #ffffff !important;
}

.flx-product__subscribe-badge {
	display: flex;
	align-items: center;
	gap: 10px;
	background: #e8f5e9 !important;
	border-radius: 8px;
	padding: 6px;
	margin-bottom: 12px;
}

.flx-product__subscribe-badge-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	flex-shrink: 0;
	background: #2e65cd !important;
	color: #ffffff !important;
	border-radius: 6px;
	font-size: 14px;
	font-weight: 700;
}

.flx-product__subscribe-badge-text {
	background: #2e65cd !important;
	color: #ffffff !important;
	font-size: 14px;
	font-weight: 700;
	padding: 8px 14px 8px 0;
	border-radius: 0 6px 6px 0;
	flex: 1;
}

.flx-product__delivery-note {
	font-size: 12px;
	color: #9a9a9a !important;
	margin: 0;
}

/* ======================================================================
   FORM / ADD TO CART
   ====================================================================== */

.flx-product__form {
	margin-bottom: 20px;
}

/* WooCommerce's own quantity input. Hidden — the pack-size buttons above
   already represent quantity/size choice in this design, so a second,
   native numeric stepper is redundant. The field stays in the DOM (still
   submits its default value of 1) so Add to Cart keeps working; it's
   just not shown to the shopper. */
.flx-product__form .quantity {
	display: none;
}

/* Belt-and-suspenders for the quantity field: some quantity-stepper
   plugins (a +/- button UI wrapped around the input) replace WooCommerce's
   default ".quantity" wrapper with their own custom markup, which the
   rule above wouldn't match — leaving the plugin's stepper visible on
   some products but not others, depending on which quantity UI happens to
   render for that specific product. `name="quantity"` is the one thing
   guaranteed constant across all of them (WooCommerce requires that exact
   field name for Add to Cart to work at all), so:
   1. Hide the input itself directly, regardless of what wraps it.
   2. Where :has() is supported, also hide whatever div actually wraps
      it — catching any sibling +/- buttons a stepper plugin adds — without
      needing to know that plugin's specific class name in advance. */
.flx-product__form input[name="quantity"] {
	display: none;
}

.flx-product__form div:has(> input[name="quantity"]) {
	display: none;
}

/* WooCommerce's own Add to Cart button */
.flx-product__form .single_add_to_cart_button,
.flx-product__form button[type="submit"] {
	width: 100%;
	min-height: 52px;
	padding: 14px 24px;
	border: none;
	border-radius: 10px;
	background: var(--flx-button-color) !important;
	color: #ffffff !important;
	font-size: 15px;
	font-weight: 700;
	cursor: pointer;
	transition: background 0.2s ease;
}

.flx-product__form .single_add_to_cart_button:hover,
.flx-product__form button[type="submit"]:hover {
	background: var(--flx-button-hover) !important;
}

.flx-product__form .single_add_to_cart_button:focus-visible,
.flx-product__form button[type="submit"]:focus-visible {
	outline: 2px solid var(--flx-accent-blue);
	outline-offset: 2px;
}

/* WooCommerce's own variation form (the "Flavor" label + native <select> +
   "Clear" reset link). Hidden — the custom flavour buttons rendered above
   (.flx-product__options[data-role="flavours"]) already drive this same
   <select>'s value via JS, so showing WooCommerce's native dropdown too
   would just duplicate the same choice in a second, unstyled control. The
   table stays in the DOM (not removed) so the buttons' JS and WooCommerce's
   own variation-price/stock logic keep working exactly as before — it's
   only hidden from view. */
.flx-product__form table.variations {
	display: none;
}

.flx-product__form .woocommerce-variation-price {
	display: none;
}

/* "All Products for WooCommerce Subscriptions" (WCS-ATT) renders its own
   subscription-plan radio buttons inside the add-to-cart form (wrapped in
   a .wcsatt-options-wrapper element). Hidden for the same reason as the
   native variation <select> above: Flolynx's own "Delivery Every" buttons
   drive this real control via JS when it's present (see
   applyRealSubscriptionScheme() in product-widget.js), so WooCommerce
   Subscriptions still creates a genuine recurring subscription at
   checkout — the native UI just isn't shown twice.

   IMPORTANT (fixes BUG-009): this rule is scoped to
   .flx-product__form--has-real-subscription, a modifier class the widget
   only adds when it actually rendered its own subscribe UI (real schemes
   exist AND the "Show Subscribe & Save Toggle" setting is on — see
   render_add_to_cart_form() in class-product-widget.php). Previously this
   rule was unconditional, so turning that Elementor toggle off for a
   product that does have real WCS-ATT plans hid WCS-ATT's native picker
   (nothing shows it) without Flolynx's own picker ever being rendered to
   replace it — silently removing the customer's only way to subscribe.
   Now, whenever Flolynx's own UI isn't rendered, WCS-ATT's native picker
   is left visible so subscribing is still possible through it. */
.flx-product__form--has-real-subscription .wcsatt-options-wrapper {
	display: none;
}

/* ======================================================================
   TRUST BADGES
   ====================================================================== */

.flx-product__trust-badges {
	display: flex;
	flex-wrap: wrap;
	gap: 12px 20px;
	list-style: none;
	padding: 0;
	margin: 0;
	font-size: 13px;
	color: #6a6a6a !important;
}

.flx-product__trust-badges li {
	position: relative;
	padding-inline-start: 18px;
}

.flx-product__trust-badges li::before {
	content: '✓';
	position: absolute;
	inset-inline-start: 0;
	color: #1f7a3d !important;
	font-weight: 700;
}

/* ======================================================================
   FULL DESCRIPTION (below the gallery/details grid)
   ====================================================================== */

.flx-product__full-description {
	margin-top: 32px;
	padding-top: 24px;
	border-top: 1px solid #ececec;
	font-size: 14px;
	line-height: 1.7;
	color: #444444 !important;
}

/* ======================================================================
   RESPONSIVE BREAKPOINTS

   Plain viewport-width media queries. An earlier version of this file
   used CSS container queries instead (keying breakpoints to the widget's
   own rendered width rather than the browser window, to handle a theme
   sidebar squeezing the widget narrower than the viewport at "laptop"
   widths) — reverted after it was implicated in a serious rendering bug
   on a live site (content collapsing to blank/zero-size on mobile, and
   unstable multi-pass re-rendering) that went away once container
   queries were removed. Container queries are a newer, less
   battle-tested CSS feature than plain media queries, and the sidebar
   edge case they were solving is a smaller problem than the breakage
   they caused here, so plain `@media` is the safer default until/unless
   that edge case is specifically reported again.
   ====================================================================== */

/* Small laptop: the two-column layout still fits, but the 40px gap starts
   to feel cramped as the column width shrinks. */
@media (max-width: 1200px) {
	.flx-product__layout {
		gap: 28px;
	}
}

/* Tablet / small laptop: the layout drops to a single column, so the
   gallery's "flex: 1" width would otherwise stretch to the full card
   width (900px+) while the frame's height stayed a short, fixed pixel
   value — producing a very wide, short frame that made square product
   photography look zoomed-in/cropped. Capping the whole gallery block's
   width (tied to the configured Gallery Height, so it scales with that
   control) keeps the frame close to its intended proportions and centers
   it above the product details instead. */
@media (max-width: 1024px) {
	.flx-product__layout {
		grid-template-columns: 1fr;
	}

	.flx-product__gallery {
		max-width: calc(var(--flx-gallery-height) + 84px);
		margin: 0 auto 8px;
	}
}

@media (max-width: 768px) {
	.flx-product {
		padding: 16px;
	}

	.flx-product__title {
		font-size: 22px;
	}

	.flx-product__gallery {
		flex-direction: column-reverse;
		max-width: none;
	}

	.flx-product__gallery-thumbs {
		flex-direction: row;
		width: 100%;
		overflow-x: auto;
		overflow-y: hidden;
		-webkit-overflow-scrolling: touch;
		/* A little bottom padding keeps the scrollbar (where the browser
		   draws one) from overlapping the thumbnails themselves. */
		padding-bottom: 4px;
		scrollbar-width: thin;
	}
}

@media (max-width: 480px) {
	.flx-product__gallery-main {
		max-height: 280px;
	}

	.flx-product__purchase-tabs {
		flex-direction: column;
	}
}

/* ======================================================================
   ACCESSIBILITY / MOTION / CONTRAST
   ====================================================================== */

@media (prefers-reduced-motion: reduce) {
	.flx-product * {
		transition: none !important;
	}
}

@media (prefers-contrast: more) {
	.flx-product__option-btn,
	.flx-product__purchase-tab,
	.flx-product__interval-btn {
		border-width: 2px;
	}
}
