/**
 * B2B RFQ Pro — Product Archive widget, grid view (SPEC.md §3.4.1).
 * Baseline, theme-agnostic structure and behaviour only — every colour,
 * size, spacing, and hover value is an Elementor control
 * (ProductArchiveWidget) targeting the classes below via a
 * {{WRAPPER}}-scoped selector. Registered as this widget's own style
 * dependency (ProductArchiveWidget::get_style_depends()), so it loads
 * only on a page that actually uses the widget in grid mode — table view
 * reuses .b2b-rfq-product-table-* from frontend.css (already loaded
 * unconditionally) and needs nothing from this file.
 *
 * Equal card heights (SPEC.md §3.4.1) come from CSS Grid's own default
 * `align-items: stretch`, not JS: every `.b2b-rfq-product-grid-card` in a
 * row is stretched to the row's tallest card automatically. The card
 * itself is a flex column with its footer pinned via `margin-top: auto`
 * on `.b2b-rfq-product-grid-card-footer` — the Add to RFQ button, however
 * tall the content above it in that specific card, always sits at the
 * card's own bottom edge.
 */

.b2b-rfq-product-grid-wrap {
	width: 100%;
	box-sizing: border-box;
}

.b2b-rfq-product-grid {
	display: grid;
	grid-template-columns: repeat( 4, 1fr );
	row-gap: 24px;
	column-gap: 24px;
	align-items: stretch;
	width: 100%;
}

.b2b-rfq-product-grid-empty {
	grid-column: 1 / -1;
	margin: 0;
	text-align: center;
	color: #52525b;
}

.b2b-rfq-product-grid-card {
	display: flex;
	flex-direction: column;
	height: 100%;
	box-sizing: border-box;
	background-color: #ffffff;
	border: 1px solid #e4e4e7;
	border-radius: 6px;
	padding: 16px;
	transition-property: background-color, border-color, box-shadow, transform;
	transition-duration: 200ms;
	transition-timing-function: ease;
}

/**
 * frontend.css's .b2b-rfq-add-to-cart-form — also carried on every card
 * (see ProductGridRenderer::render_card()) purely as frontend.js's event-
 * delegation scope — sets `align-items: center` for its own, unrelated
 * single-button-control layout. Left unopposed, that centres this card's
 * image/body/footer at their own content width instead of stretching them
 * to fill the card (breaking the equal-width image container and the
 * full-width Add to RFQ button product-archive.css's own rules above and
 * below expect). This selector's two classes together outrank that single-
 * class rule on specificity, restoring the stretch every flex column
 * needs regardless of file load order.
 */
.b2b-rfq-product-grid-card.b2b-rfq-add-to-cart-form {
	align-items: stretch;
}

/**
 * Fixed-height image container (SPEC.md: "equal image containers, with
 * object-fit control"). object-fit defaults to "cover" here (a sensible
 * default for real product photography, unlike Brand Grid's logo-safe
 * "contain") but is a genuine Elementor SELECT control
 * (ProductArchiveWidget's image_object_fit), not hard-coded the way Brand
 * Grid's is — see that widget for the full set of Image controls.
 */
.b2b-rfq-product-grid-card-image {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	width: 100%;
	height: 180px;
	box-sizing: border-box;
	margin-bottom: 12px;
}

.b2b-rfq-product-grid-card-img {
	display: block;
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	object-fit: cover;
	object-position: center center;
}

.b2b-rfq-product-grid-card-body {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.b2b-rfq-product-grid-card-part-number {
	margin: 0;
	font-size: 13px;
	font-weight: 600;
	color: #52525b;
}

.b2b-rfq-product-grid-card-title-link {
	text-decoration: none;
	color: inherit;
}

.b2b-rfq-product-grid-card-title {
	margin: 0;
	font-size: 15px;
	font-weight: 600;
	line-height: 1.35;
	color: #18181b;
	overflow-wrap: anywhere;
	word-break: break-word;
}

/**
 * Phase C2: Condition, Quantity and the Add to RFQ button now live
 * together in this one group — moved out of `.b2b-rfq-product-grid-card-body`
 * (which now holds only Part No./Title, the part whose height genuinely
 * varies card to card). `margin-top: auto` pins the whole group to the
 * card's own bottom edge exactly as `.b2b-rfq-product-grid-card-actions`
 * alone used to pin itself — the CSS Grid row height, not this element, is
 * what makes every card in the row match height, so Condition (and
 * everything below it) lands at the exact same visual row across a row of
 * cards regardless of how long any one card's own title happens to be.
 * `padding-top`/`gap` are ProductListingStyleControlsTrait's own
 * card_bottom_group_top_spacing/card_bottom_group_gap controls — the
 * "Title to Condition" and "Condition to Quantity/Button" pairs of Phase
 * C2's "full internal spacing control between every card element."
 */
.b2b-rfq-product-grid-card-bottom {
	display: flex;
	flex-direction: column;
	gap: 8px;
	margin-top: auto;
	padding-top: 8px;
}

.b2b-rfq-product-grid-card-condition {
	font-size: 13px;
}

/**
 * A zero-condition product's ConditionManager::render_condition_field()
 * call returns '' — this rule collapses the wrapper so it takes no space
 * rather than leaving an empty gap above Quantity/Add to RFQ.
 */
.b2b-rfq-product-grid-card-condition:empty {
	display: none;
}

/**
 * Quantity field + Add to RFQ button, together (SPEC.md-driven redesign):
 * one flex row. `flex-direction` here is the one property
 * `quantity_button_layout` (ProductListingStyleControlsTrait::
 * register_quantity_style_controls()) overrides per breakpoint — also
 * shared, since Phase C3, with Table view's own merged
 * `.b2b-rfq-product-table-actions` cell; `row` (inline, this file's own
 * default) needs no Elementor control touched at all to look correct out
 * of the box.
 */
.b2b-rfq-product-grid-card-actions {
	display: flex;
	flex-direction: row;
	align-items: flex-end;
	gap: 10px;
}

.b2b-rfq-product-grid-card-quantity {
	flex: 0 0 auto;
}

/**
 * A compact fixed width here (rather than the pre-inline design's 100%)
 * is what makes "inline, same row as the button" actually look inline —
 * this is a genuine Elementor control already (qty_input_width, below),
 * not hard-coded: a store wanting the old full-width look back, in
 * either layout, sets it there per breakpoint.
 */
.b2b-rfq-product-grid-card-quantity .b2b-rfq-qty-input {
	width: 90px;
	box-sizing: border-box;
	padding: 8px 10px;
	border: 1px solid #d0d0d0;
	border-radius: 4px;
	font: inherit;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.b2b-rfq-product-grid-card-quantity .b2b-rfq-qty-input:focus {
	border-color: #1a1a1a;
	outline: none;
	box-shadow: 0 0 0 2px rgba( 26, 26, 26, 0.15 );
}

.b2b-rfq-product-grid-card-footer {
	flex: 1 1 auto;
	min-width: 0;
}

.b2b-rfq-product-grid-card-footer .b2b-rfq-add-to-cart-btn {
	display: block;
	width: 100%;
	box-sizing: border-box;
	padding: 9px 14px;
	border: 1px solid #1a1a1a;
	border-radius: 4px;
	background-color: #1a1a1a;
	color: #ffffff;
	font: inherit;
	font-size: 13px;
	font-weight: 600;
	text-align: center;
	cursor: pointer;
	transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.b2b-rfq-product-grid-card-footer .b2b-rfq-add-to-cart-btn:hover:not( :disabled ) {
	background-color: #3f3f46;
	border-color: #3f3f46;
}

.b2b-rfq-product-grid-card-footer .b2b-rfq-add-to-cart-btn:disabled {
	opacity: 0.5;
	cursor: not-allowed;
}

.b2b-rfq-product-grid-card-footer .b2b-rfq-add-to-cart-feedback {
	display: block;
	margin-top: 6px;
	font-size: 12px;
}

.b2b-rfq-product-grid-card-footer .b2b-rfq-add-to-cart-feedback:empty {
	display: none;
}

/**
 * Hover lift (SPEC.md "Card hover: ... lift") — a transform, via a custom
 * property with a fallback so this rule alone produces a small lift even
 * with no Elementor config; ProductArchiveWidget's Card Lift Distance
 * control only ever sets the property's *value*, never this whole rule,
 * so the prefers-reduced-motion override below can disable the animation
 * without needing to know that value. Background/border/box-shadow hover
 * changes are ordinary Elementor Normal/Hover tab controls writing direct
 * :hover selectors — see ProductArchiveWidget — no indirection needed for
 * those, since removing a transition on a colour/shadow property is
 * harmless to disable outright (unlike a transform some users have
 * explicitly asked never to see).
 */
.b2b-rfq-product-grid-card:hover {
	transform: translateY( calc( -1 * var( --b2b-rfq-product-grid-card-lift, 4px ) ) );
}

@media ( prefers-reduced-motion: reduce ) {
	.b2b-rfq-product-grid-card {
		transition: none !important;
	}

	.b2b-rfq-product-grid-card:hover {
		transform: none !important;
	}
}

@media ( max-width: 768px ) {
	.b2b-rfq-product-grid {
		grid-template-columns: repeat( 2, 1fr );
	}
}

@media ( max-width: 480px ) {
	.b2b-rfq-product-grid {
		grid-template-columns: repeat( 1, 1fr );
	}

	/**
	 * Plain-CSS fallback matching quantity_button_layout's own
	 * mobile_default ('column') — present so an instance nobody has
	 * opened the Style tab on yet still reverts to stacked below this
	 * breakpoint, the same "usable before any Elementor control is
	 * touched" guarantee this file's other baseline rules already give.
	 * Elementor's own generated CSS for the control, if the value is
	 * ever changed from its default, always wins on cascade order
	 * regardless of this rule.
	 */
	.b2b-rfq-product-grid-card-actions {
		flex-direction: column;
		align-items: stretch;
	}

	.b2b-rfq-product-grid-card-quantity .b2b-rfq-qty-input {
		width: 100%;
	}
}

/**
 * AJAX engine (SPEC.md §3.5, Phase 11) — shared by both layouts (this
 * stylesheet already loads unconditionally regardless of the widget's own
 * Layout setting, per ProductArchiveWidget::get_style_depends()'s own
 * docblock), since product-archive-engine.js drives grid and table
 * identically.
 *
 * Loading state: an opacity fade on the *existing, still-in-place*
 * content — never a height/display change — so nothing about the page's
 * layout shifts while a request is in flight ("without the layout
 * jumping"). pointer-events: none stops a stray click on fading-out
 * content (e.g. a second, accidental pagination-link click) from
 * queueing a request the engine's own abort-and-sequence guarantee would
 * just have to discard anyway.
 */
.b2b-rfq-product-archive-engine.is-loading .b2b-rfq-product-grid,
.b2b-rfq-product-archive-engine.is-loading .b2b-rfq-product-table-body {
	opacity: 0.5;
	pointer-events: none;
	transition: opacity 150ms ease;
}

@media ( prefers-reduced-motion: reduce ) {
	.b2b-rfq-product-archive-engine.is-loading .b2b-rfq-product-grid,
	.b2b-rfq-product-archive-engine.is-loading .b2b-rfq-product-table-body {
		transition: none;
	}
}

/**
 * Visually hidden but still screen-reader-announced (aria-live="polite")
 * and still a valid focus target (tabindex="-1" in the markup — see
 * ProductArchiveWidget::render()) — the same clip-based technique
 * manual-entry-table.css's own .b2b-rfq-manual-visually-hidden already
 * uses, not the theme-provided .screen-reader-text class this plugin
 * cannot assume exists (SPEC.md: must render correctly with no theme
 * styling at all).
 */
.b2b-rfq-product-archive-status {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect( 0, 0, 0, 0 );
	white-space: nowrap;
	border: 0;
}

.b2b-rfq-product-archive-pagination {
	margin-top: 16px;
}

.b2b-rfq-product-archive-pagination-links {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
}

/**
 * Empty when the current result set fits on one page (see
 * ProductArchiveWidget::build_pagination_links_html()) — collapses the
 * persistent `<nav>` wrapper down to nothing visible, the same as Phase
 * 15's "print nothing at all" behaviour, while still giving
 * product-archive-engine.js a stable node to fill back in after a search
 * that produces more than one page of results.
 */
.b2b-rfq-product-archive-pagination-links:empty {
	display: none;
}

.b2b-rfq-product-archive-pagination-links a,
.b2b-rfq-product-archive-pagination-links span.current {
	display: inline-block;
	padding: 6px 10px;
	border: 1px solid #d0d0d0;
	border-radius: 4px;
	font-size: 13px;
	text-decoration: none;
	color: inherit;
}

.b2b-rfq-product-archive-pagination-links a:hover {
	border-color: #1a1a1a;
}

.b2b-rfq-product-archive-pagination-links span.current {
	background-color: #1a1a1a;
	border-color: #1a1a1a;
	color: #ffffff;
}

/**
 * Editor-only preview notice (ProductArchiveWidget::resolve_editor_preview_if_needed())
 * — never shown to a real front-end visitor. Same dashed-amber convention
 * live-search.css/pagination.css/related-products.css already use for
 * their own editor-only notices.
 */
.b2b-rfq-product-archive-editor-notice {
	margin: 0 0 12px;
	padding: 8px 12px;
	border: 1px dashed #f59e0b;
	border-radius: 4px;
	background-color: #fffbeb;
	color: #92400e;
	font-size: 0.875em;
}
