/**
 * GridPanda Frontend Styles
 *
 * BEM naming: .gridpanda-{block}__{element}--{modifier}
 *
 * @package GridPanda
 * @since   1.0.0
 */

:root {
	--gridpanda-primary: #0073aa;
	--gridpanda-primary-hover: #005177;
	--gridpanda-secondary: #f0f0f0;
	--gridpanda-border: #ddd;
	--gridpanda-text: #333;
	--gridpanda-text-light: #666;
	--gridpanda-text-muted: #999;
	--gridpanda-spacing: 1rem;
	--gridpanda-radius: 4px;
	--gridpanda-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);

	/* ── Public CSS API (Phase 4 — Elementor-parity scoping) ─────────────
	   The `--gp-*` namespace is the supported public token API for theme
	   integrators. The internal stylesheet still references `--gridpanda-*`
	   for full backward compatibility with any user CSS that overrides the
	   legacy names. New code should consume `--gp-*` and override there.
	   Both names point at the same underlying value — overriding either
	   name changes the rendered card. */
	--gp-primary: var(--gridpanda-primary);
	--gp-primary-hover: var(--gridpanda-primary-hover);
	--gp-secondary: var(--gridpanda-secondary);
	--gp-border: var(--gridpanda-border);
	--gp-text: var(--gridpanda-text);
	--gp-text-light: var(--gridpanda-text-light);
	--gp-text-muted: var(--gridpanda-text-muted);
	--gp-spacing: var(--gridpanda-spacing);
	--gp-radius: var(--gridpanda-radius);
	--gp-shadow: var(--gridpanda-shadow);
}

/* =============================================
   Theme Isolation Reset
   =============================================
   WordPress themes routinely target bare `input`,
   `input[type="text"]`, `button`, `select`, etc.
   with global styles (padding, border, height,
   background, box-shadow, line-height …).
   The block below hard-resets every form element
   inside a GridPanda facet / grid so the plugin's
   own styles are the single source of truth.
   ============================================= */

/* --- Inputs (text, search, number, date, range) --- */
/* :where() zeroes specificity so component-level classes always override. */
:where(.gridpanda-facet) input,
:where(.gridpanda-facet) select,
:where(.gridpanda-facet) textarea,
:where(.gridpanda-facet) button,
:where(.gridpanda-grid-wrapper) input,
:where(.gridpanda-grid-wrapper) select,
:where(.gridpanda-grid-wrapper) textarea,
:where(.gridpanda-grid-wrapper) button {
	margin: 0;
	padding: 0;
	border: none;
	border-radius: 0;
	background: none;
	box-shadow: none;
	outline: none;
	font-family: inherit;
	font-size: inherit;
	font-weight: inherit;
	line-height: inherit;
	letter-spacing: inherit;
	color: inherit;
	text-transform: none;
	text-indent: 0;
	text-decoration: none;
	box-sizing: border-box;
	-webkit-appearance: none;
	-moz-appearance: none;
	appearance: none;
	min-height: 0;
	max-width: none;
	height: auto;
	width: auto;
	vertical-align: baseline;
	transition: none;
}

/* Restore pointer cursor on interactive elements */
:where(.gridpanda-facet) button,
:where(.gridpanda-facet) select,
:where(.gridpanda-facet) label,
:where(.gridpanda-facet) [role="button"],
:where(.gridpanda-grid-wrapper) button,
:where(.gridpanda-grid-wrapper) select {
	cursor: pointer;
}

/* Prevent themes from adding pseudo-element decorations */
:where(.gridpanda-facet) input::before,
:where(.gridpanda-facet) input::after,
:where(.gridpanda-facet) button::before,
:where(.gridpanda-facet) button::after,
:where(.gridpanda-grid-wrapper) input::before,
:where(.gridpanda-grid-wrapper) input::after {
	display: none;
}

/* Kill theme focus outlines — GridPanda supplies its own */
:where(.gridpanda-facet) input:focus,
:where(.gridpanda-facet) select:focus,
:where(.gridpanda-facet) button:focus,
:where(.gridpanda-grid-wrapper) input:focus {
	outline: none;
	box-shadow: none;
}

/* ── Screen-reader text fallback ─────────────────
   WC 8.x+ adds .screen-reader-text spans inside
   get_price_html().  WordPress/WC normally hide them
   via their own stylesheet, but in contexts where
   that CSS isn't loaded (e.g. admin live preview)
   the text would be visible.  GridPanda strips these
   spans server-side, but this rule provides an extra
   safety net.
   ──────────────────────────────────────────────── */
.gridpanda-card .screen-reader-text {
	clip: rect(1px, 1px, 1px, 1px);
	position: absolute !important;
	height: 1px;
	width: 1px;
	overflow: hidden;
	word-wrap: normal !important;
}

/* =============================================
   Facets
   ============================================= */

.gridpanda-facets {
	display: flex;
	flex-direction: column;
	gap: var(--gridpanda-spacing);
}

.gridpanda-facet {
	border: var(--fx-facet-border-width, 0) var(--fx-facet-border-style, solid) var(--fx-facet-border-color, transparent);
	border-radius: var(--fx-facet-border-radius, var(--gridpanda-radius));
	padding: var(--fx-facet-padding, 0);
	background: var(--fx-facet-bg, transparent);
	box-shadow: var(--fx-facet-shadow, none);
	box-sizing: border-box;
	max-width: 100%;
	min-width: 0;
}

/* Facet header (collapsible) */
.gridpanda-facet__header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	cursor: pointer;
	user-select: none;
	margin-bottom: 12px;
	background: var(--fx-header-bg, transparent);
	padding: var(--fx-header-padding, 0);
}

.gridpanda-facet__title {
	margin: 0;
	font-family:     var(--fx-header-font-family, inherit);
	font-size:       var(--fx-header-font-size, 15px);
	font-weight:     var(--fx-header-font-weight, 600);
	line-height:     var(--fx-header-line-height, normal);
	color:           var(--fx-header-color, var(--gridpanda-text));
	text-transform:  var(--fx-header-text-transform, uppercase);
	letter-spacing:  var(--fx-header-letter-spacing, 0.5px);
	text-align:      var(--fx-header-text-align, left);
	text-decoration: var(--fx-header-text-decoration, none);
}

.gridpanda-facet__toggle {
	font-size: 19px;
	line-height: 1;
	color: var(--gridpanda-text-muted);
}

/* Facet content */
.gridpanda-facet__content {
	/* container for search + list */
}

/* Hide content when header says collapsed */
.gridpanda-facet__header[aria-expanded="false"] + .gridpanda-facet__content {
	display: none;
}

/* Facet search input */
.gridpanda-facet__search {
	display: block;
	width: 100%;
	padding: var(--fx-input-padding, 6px 10px);
	margin-bottom: 8px;
	border: 1px solid var(--fx-input-border-color, var(--gridpanda-border));
	border-radius: var(--fx-input-border-radius, var(--gridpanda-radius));
	font-family:     var(--fx-input-font-family, inherit);
	font-size:       var(--fx-input-font-size, 14px);
	font-weight:     var(--fx-input-font-weight, inherit);
	line-height:     var(--fx-input-line-height, normal);
	letter-spacing:  var(--fx-input-letter-spacing, normal);
	text-transform:  var(--fx-input-text-transform, none);
	text-decoration: var(--fx-input-text-decoration, none);
	background:      var(--fx-input-bg, #fff);
	color:           var(--fx-input-color, inherit);
	box-sizing: border-box;
}

.gridpanda-facet__search:focus {
	border-color: var(--fx-input-focus-border-color, var(--gridpanda-primary));
	outline: none;
	box-shadow: 0 0 0 2px rgba(0, 115, 170, 0.2);
}

/* Facet list — flex container so --fx-item-layout-direction can switch between
   vertical (column, default) and horizontal (row) orientations.
   --fx-item-gap drives the gap in both orientations so SpacingGroupControl's
   Gap input has a single consistent target. */
.gridpanda-facet__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: var(--fx-item-layout-direction, column);
	flex-wrap: nowrap;
	gap: var(--fx-item-gap, 0);
}

/* Horizontal orientation: let items wrap and sit side-by-side.
   Items default to auto-width when horizontal so they don't stretch across
   the full row — keeps checkbox/radio rows compact. */
.gridpanda-facet-element[style*="--fx-item-layout-direction:row"] .gridpanda-facet__list,
.gridpanda-facet-element[style*="--fx-item-layout-direction: row"] .gridpanda-facet__list {
	flex-wrap: wrap;
	align-items: center;
}

.gridpanda-facet-element[style*="--fx-item-layout-direction:row"] .gridpanda-facet__item,
.gridpanda-facet-element[style*="--fx-item-layout-direction: row"] .gridpanda-facet__item {
	flex: 0 0 auto;
}

/* Facet item (checkbox/radio row) — per-side vars with shorthand + legacy fallbacks */
.gridpanda-facet__item {
	padding-top:    var(--fx-item-padding-top,    var(--fx-item-padding, 6px));
	padding-right:  var(--fx-item-padding-right,  var(--fx-item-padding, 0));
	padding-bottom: var(--fx-item-padding-bottom, var(--fx-item-padding, 6px));
	padding-left:   var(--fx-item-padding-left,   var(--fx-item-padding, 0));
	background: var(--fx-item-bg, transparent);
	border-style: var(--fx-item-border-style, none);
	border-color: var(--fx-item-border-color, transparent);
	border-top-width:    var(--fx-item-border-width-top,    var(--fx-item-border-width, 0));
	border-right-width:  var(--fx-item-border-width-right,  var(--fx-item-border-width, 0));
	border-bottom-width: var(--fx-item-border-width-bottom, var(--fx-item-border-width, 0));
	border-left-width:   var(--fx-item-border-width-left,   var(--fx-item-border-width, 0));
	border-top-left-radius:     var(--fx-item-border-radius-tl, var(--fx-item-border-radius, 0));
	border-top-right-radius:    var(--fx-item-border-radius-tr, var(--fx-item-border-radius, 0));
	border-bottom-right-radius: var(--fx-item-border-radius-br, var(--fx-item-border-radius, 0));
	border-bottom-left-radius:  var(--fx-item-border-radius-bl, var(--fx-item-border-radius, 0));
}

/* Legacy back-compat: still honor --fx-item-border-bottom shorthand if set
   (e.g. "1px solid #eee"). Comes last so new per-side wins when they're set. */
.gridpanda-facet__item[style*="--fx-item-border-bottom"] {
	border-bottom: var(--fx-item-border-bottom, none);
}

.gridpanda-facet__item:hover {
	background: var(--fx-item-hover-bg, transparent);
}

.gridpanda-facet__item--hidden {
	display: none;
}

.gridpanda-facet__item--disabled {
	opacity: 0.4;
	pointer-events: none;
}

/* Facet label (wraps input + text + count) */
.gridpanda-facet__label {
	display: flex;
	align-items: center;
	gap: var(--fx-item-gap, 8px);
	cursor: pointer;
	font-family:     var(--fx-label-font-family, inherit);
	font-size:       var(--fx-label-font-size, 14px);
	font-weight:     var(--fx-label-font-weight, inherit);
	line-height:     var(--fx-label-line-height, 1.4);
	letter-spacing:  var(--fx-label-letter-spacing, normal);
	text-transform:  var(--fx-label-text-transform, none);
	text-align:      var(--fx-label-text-align, left);
	text-decoration: var(--fx-label-text-decoration, none);
}

.gridpanda-facet__label:hover .gridpanda-facet__text {
	color: var(--fx-label-hover-color);
}

/* Facet input */
.gridpanda-facet__input {
	margin: 0;
	cursor: pointer;
	flex-shrink: 0;
}

/* Custom checkbox styling via CSS variables.
   :not(.gridpanda-toggle__input) — toggle inputs are visually hidden (the track
   is the visual control), so they must not inherit this checkbox widget styling. */
.gridpanda-facet__input[type="checkbox"]:not(.gridpanda-toggle__input) {
	-webkit-appearance: none;
	appearance: none;
	width: var(--fx-checkbox-size, 16px);
	height: var(--fx-checkbox-size, 16px);
	border: var(--fx-checkbox-border-width, 2px) solid var(--fx-checkbox-border-color, var(--gridpanda-border));
	border-radius: var(--fx-checkbox-border-radius, 3px);
	background: var(--fx-checkbox-bg, #fff);
	position: relative;
	transition: all 0.15s ease;
}

.gridpanda-facet__input[type="checkbox"]:not(.gridpanda-toggle__input):hover {
	border-color: var(--fx-checkbox-hover-border, var(--gridpanda-primary));
}

.gridpanda-facet__input[type="checkbox"]:not(.gridpanda-toggle__input):checked {
	background: var(--fx-checkbox-checked-bg, var(--gridpanda-primary));
	border-color: var(--fx-checkbox-checked-border, var(--gridpanda-primary));
}

.gridpanda-facet__input[type="checkbox"]:not(.gridpanda-toggle__input):checked::after {
	content: '';
	position: absolute;
	left: 3px;
	top: 0px;
	width: 5px;
	height: 9px;
	border: solid var(--fx-checkbox-check-color, #fff);
	border-width: 0 2px 2px 0;
	transform: rotate(45deg);
}

/* Custom radio styling via CSS variables.
   :not(.gridpanda-rating__input) — rating inputs are hidden siblings,
   not visible form controls, so they must not inherit this widget styling. */
.gridpanda-facet__input[type="radio"]:not(.gridpanda-rating__input) {
	-webkit-appearance: none;
	appearance: none;
	width: var(--fx-radio-size, 16px);
	height: var(--fx-radio-size, 16px);
	border: var(--fx-radio-border-width, 2px) solid var(--fx-radio-border-color, var(--gridpanda-border));
	border-radius: var(--fx-radio-border-radius, 50%);
	background: var(--fx-radio-bg, #fff);
	position: relative;
	transition: all 0.15s ease;
}

.gridpanda-facet__input[type="radio"]:not(.gridpanda-rating__input):hover {
	border-color: var(--fx-radio-hover-border, var(--gridpanda-primary));
}

.gridpanda-facet__input[type="radio"]:not(.gridpanda-rating__input):checked {
	border-color: var(--fx-radio-checked-color, var(--gridpanda-primary));
}

.gridpanda-facet__input[type="radio"]:not(.gridpanda-rating__input):checked::after {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	width: 6px;
	height: 6px;
	background: var(--fx-radio-checked-color, var(--gridpanda-primary));
	border-radius: 50%;
	transform: translate(-50%, -50%);
}

/* Facet text */
.gridpanda-facet__text {
	flex: 1;
	color: var(--fx-label-color, var(--gridpanda-text));
}

/* Facet count */
.gridpanda-facet__count {
	font-family:     var(--fx-count-font-family, inherit);
	font-size:       var(--fx-count-font-size, 13px);
	font-weight:     var(--fx-count-font-weight, inherit);
	line-height:     var(--fx-count-line-height, normal);
	letter-spacing:  var(--fx-count-letter-spacing, normal);
	text-transform:  var(--fx-count-text-transform, none);
	text-decoration: var(--fx-count-text-decoration, none);
	color:           var(--fx-count-color, var(--gridpanda-text-muted));
	background:      var(--fx-count-bg, transparent);
	border-radius:   var(--fx-count-border-radius, 0);
	padding:         var(--fx-count-padding, 0);
	margin-left: auto;
	flex-shrink: 0;
}

/* Show more / show less toggle */
.gridpanda-facet__toggle-more {
	display: block;
	width: 100%;
	margin-top: 8px;
	padding: 5px 0;
	background: none;
	border: none;
	color: var(--fx-more-color, var(--gridpanda-primary));
	cursor: pointer;
	font-size: var(--fx-more-font-size, 14px);
	text-align: left;
}

.gridpanda-facet__toggle-more:hover {
	color: var(--fx-more-hover-color, var(--gridpanda-primary-hover));
	text-decoration: underline;
}

/* Facet clear button */
.gridpanda-facet__clear {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	margin-top: var(--fx-clear-margin-top, 10px);
	padding-top:    var(--fx-clear-padding-top,    var(--fx-clear-padding, 4px));
	padding-right:  var(--fx-clear-padding-right,  var(--fx-clear-padding, 12px));
	padding-bottom: var(--fx-clear-padding-bottom, var(--fx-clear-padding, 4px));
	padding-left:   var(--fx-clear-padding-left,   var(--fx-clear-padding, 12px));
	/* Colors */
	background:   var(--fx-clear-bg, transparent);
	color:        var(--fx-clear-color, var(--gridpanda-text-muted));
	/* Border */
	border-style: var(--fx-clear-border-style, solid);
	border-color: var(--fx-clear-border-color, var(--gridpanda-border));
	border-top-width:    var(--fx-clear-border-width-top,    var(--fx-clear-border-width, 1px));
	border-right-width:  var(--fx-clear-border-width-right,  var(--fx-clear-border-width, 1px));
	border-bottom-width: var(--fx-clear-border-width-bottom, var(--fx-clear-border-width, 1px));
	border-left-width:   var(--fx-clear-border-width-left,   var(--fx-clear-border-width, 1px));
	border-top-left-radius:     var(--fx-clear-border-radius-tl, var(--fx-clear-border-radius, 999px));
	border-top-right-radius:    var(--fx-clear-border-radius-tr, var(--fx-clear-border-radius, 999px));
	border-bottom-right-radius: var(--fx-clear-border-radius-br, var(--fx-clear-border-radius, 999px));
	border-bottom-left-radius:  var(--fx-clear-border-radius-bl, var(--fx-clear-border-radius, 999px));
	/* Typography */
	font-family:     var(--fx-clear-font-family, inherit);
	font-size:       var(--fx-clear-font-size, 12px);
	font-weight:     var(--fx-clear-font-weight, 500);
	line-height:     var(--fx-clear-line-height, 1.2);
	letter-spacing:  var(--fx-clear-letter-spacing, 0.02em);
	text-transform:  var(--fx-clear-text-transform, uppercase);
	text-decoration: var(--fx-clear-text-decoration, none);
	/* Effects */
	box-shadow: var(--fx-clear-box-shadow, none);
	transition: var(--fx-clear-transition, all 0.15s ease);
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
}

.gridpanda-facet__clear:hover {
	background:   var(--fx-clear-hover-bg, var(--gridpanda-primary));
	color:        var(--fx-clear-hover-color, #fff);
	border-color: var(--fx-clear-hover-border-color, var(--gridpanda-primary));
	box-shadow:   var(--fx-clear-hover-box-shadow, none);
}

/* Facet select/dropdown */
/* ── Single-select styled native <select> ── */
.gridpanda-facet__select,
.gridpanda-dropdown__select {
	display: block;
	width: 100%;
	padding: var(--fx-select-padding, 9px 32px 9px 12px);
	border: 1px solid var(--fx-select-border-color, var(--gridpanda-border, #d1d5db));
	border-radius: var(--fx-select-border-radius, var(--gridpanda-radius, 8px));
	background: var(--fx-select-bg, #fff) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E") no-repeat right 8px center / 16px;
	color:           var(--fx-select-color, var(--gridpanda-text, #374151));
	font-family:     var(--fx-select-font-family, inherit);
	font-size:       var(--fx-select-font-size, 14px);
	font-weight:     var(--fx-select-font-weight, inherit);
	line-height:     var(--fx-select-line-height, normal);
	letter-spacing:  var(--fx-select-letter-spacing, normal);
	text-transform:  var(--fx-select-text-transform, none);
	text-decoration: var(--fx-select-text-decoration, none);
	appearance: none;
	-webkit-appearance: none;
	box-sizing: border-box;
	height: var(--fx-select-height, auto);
	cursor: pointer;
	transition: border-color 0.15s, box-shadow 0.15s;
}

.gridpanda-facet__select:hover,
.gridpanda-dropdown__select:hover {
	border-color: var(--fx-select-hover-border, #9ca3af);
	background-color: var(--fx-select-hover-bg, transparent);
	color: var(--fx-select-hover-color, inherit);
}

.gridpanda-facet__select:focus,
.gridpanda-dropdown__select:focus {
	border-color: var(--fx-select-focus-border, var(--gridpanda-primary, #6366f1));
	outline: none;
	box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2);
}

/* ── Multi-select: custom checkbox-dropdown ── */
.gridpanda-dropdown {
	position: relative;
}

.gridpanda-dropdown__trigger {
	display: flex;
	align-items: center;
	gap: 8px;
	width: 100%;
	padding: 9px 12px;
	font-size: 14px;
	font-family: inherit;
	color: #374151;
	background: #fff;
	border: 1px solid var(--gridpanda-border, #d1d5db);
	border-radius: var(--gridpanda-radius, 8px);
	cursor: pointer;
	text-align: left;
	transition: border-color 0.15s, box-shadow 0.15s;
	user-select: none;
	box-sizing: border-box;
}

.gridpanda-dropdown__trigger:hover {
	border-color: #9ca3af;
}

.gridpanda-dropdown__trigger[aria-expanded="true"] {
	border-color: var(--gridpanda-primary, #6366f1);
	box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2);
	border-radius: var(--gridpanda-radius, 8px) var(--gridpanda-radius, 8px) 0 0;
}

.gridpanda-dropdown__trigger-label {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.gridpanda-dropdown__trigger-label--placeholder {
	color: #9ca3af;
}

.gridpanda-dropdown__trigger-icon {
	flex-shrink: 0;
	display: flex;
	align-items: center;
	color: #6b7280;
	transition: transform 0.2s;
}

.gridpanda-dropdown__trigger[aria-expanded="true"] .gridpanda-dropdown__trigger-icon {
	transform: rotate(180deg);
}

.gridpanda-dropdown__panel {
	position: absolute;
	top: 100%;
	left: 0;
	right: 0;
	z-index: 200;
	background: #fff;
	border: 1px solid var(--gridpanda-primary, #6366f1);
	border-top: none;
	border-radius: 0 0 var(--gridpanda-radius, 8px) var(--gridpanda-radius, 8px);
	box-shadow: 0 6px 16px rgba(0, 0, 0, 0.1);
	max-height: 220px;
	overflow-y: auto;
	overscroll-behavior: contain;
}

.gridpanda-dropdown__option {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 9px 12px;
	cursor: pointer;
	font-size: 14px;
	color: #374151;
	transition: background 0.1s;
	user-select: none;
}

.gridpanda-dropdown__option:hover {
	background: #f3f4f6;
}

.gridpanda-dropdown__option--selected {
	background: #eff6ff;
}

.gridpanda-dropdown__option--disabled {
	opacity: 0.45;
	cursor: default;
	pointer-events: none;
}

.gridpanda-dropdown__option-label {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	line-height: 1.4;
}

.gridpanda-dropdown__option-count {
	margin-left: 0.2em;
	color: #9ca3af;
	font-size: 0.8em;
}

/* The .gridpanda-facet__input[type="checkbox"] rule already styles these;
   just ensure no extra space from the hidden-input pattern used elsewhere. */
.gridpanda-dropdown__checkbox {
	flex-shrink: 0;
}

/* =============================================
   Grid
   ============================================= */

.gridpanda-grid-wrapper {
	position: relative;
}

.gridpanda-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
	gap: var(--gridpanda-spacing);
}

/* Layout modifiers via CSS custom properties (set by LayoutEngine) */
.gridpanda-grid--grid {
	/* minmax(0, 1fr) instead of bare 1fr — prevents intrinsic-content blowout
	   when card children (e.g. <img width="1024">) declare a min-content larger
	   than the would-be track width. Without this, narrow viewports overflow. */
	grid-template-columns: repeat(var(--gridpanda-columns-desktop, 3), minmax(0, 1fr));
	gap: var(--gridpanda-gap-h, var(--gridpanda-gap, 20px));
	row-gap: var(--gridpanda-gap-v, var(--gridpanda-gap, 20px));
}

/* ── Metro layout — mixed-size tile grid ── */
/* Uses CSS Grid with fixed row height and span classes applied by JS.
   Default pattern cycles: large(2×2), small(1×1), small(1×1), wide(2×1),
   small(1×1), tall(1×2), small(1×1), small(1×1) — repeats every 8 items. */
.gridpanda-grid--metro {
	grid-template-columns: repeat(var(--gridpanda-columns-desktop, 4), minmax(0, 1fr));
	grid-auto-rows: var(--gridpanda-metro-row-h, 200px);
	grid-auto-flow: dense;
	gap: var(--gridpanda-gap-h, var(--gridpanda-gap, 20px));
	row-gap: var(--gridpanda-gap-v, var(--gridpanda-gap, 20px));
}

/* Metro tile span modifiers */
.gridpanda-grid--metro .gridpanda-grid__item--span-2x2 {
	grid-column: span 2;
	grid-row: span 2;
}
.gridpanda-grid--metro .gridpanda-grid__item--span-2x1 {
	grid-column: span 2;
}
.gridpanda-grid--metro .gridpanda-grid__item--span-1x2 {
	grid-row: span 2;
}

/* Metro cards must fill their cell entirely */
.gridpanda-grid--metro .gridpanda-grid__item {
	overflow: hidden;
}
.gridpanda-grid--metro .gridpanda-grid__item > .gridpanda-card {
	width: 100% !important;
	height: 100% !important;
	max-width: 100%;
	box-sizing: border-box;
}
/* Make card containers flex-fill the tile */
.gridpanda-grid--metro .gridpanda-card--container {
	height: 100%;
	display: flex;
	flex-direction: column;
}
.gridpanda-grid--metro .gridpanda-card--container > .gridpanda-container-wrapper {
	flex: 1;
	display: flex;
	flex-direction: column;
}
/* Background images should cover the tile */
.gridpanda-grid--metro .gridpanda-card__block--image img,
.gridpanda-grid--metro .gridpanda-card [style*="background-image"] {
	object-fit: cover;
	width: 100%;
	height: 100%;
}

/* ── Justified layout — JS calculates row-based proportional sizing ── */
/* Flickr / Google Photos style: items in each row are scaled to fill the
   full container width at a uniform row height. JS computes widths and
   positions; CSS provides the flexbox shell and image cover behaviour. */
.gridpanda-grid--justified {
	display: block;
}

.gridpanda-grid--justified .gridpanda-grid__items {
	display: flex;
	flex-wrap: wrap;
	gap: var(--gridpanda-gap-v, var(--gridpanda-gap, 10px));
}

/* Justified rows are built by JS — each row is a flex row.
   Items get explicit width via inline style; height is uniform per row. */
.gridpanda-grid--justified .gridpanda-grid__item {
	overflow: hidden;
	flex-shrink: 0;
	flex-grow: 0;
}

/* Cards fill the justified cell entirely */
.gridpanda-grid--justified .gridpanda-grid__item > .gridpanda-card {
	width: 100% !important;
	height: 100% !important;
	max-width: 100%;
	box-sizing: border-box;
}

/* Images in justified layout should cover the card area */
.gridpanda-grid--justified .gridpanda-card__block--image img,
.gridpanda-grid--justified .gridpanda-card__image {
	object-fit: cover;
	width: 100%;
	height: 100%;
}

/* Force card container to fill height */
.gridpanda-grid--justified .gridpanda-card--container {
	height: 100%;
	display: flex;
	flex-direction: column;
}
.gridpanda-grid--justified .gridpanda-card--container > .gridpanda-container-wrapper {
	flex: 1;
	display: flex;
	flex-direction: column;
}

/* Masonry layout — JS handles absolute positioning; disable CSS Grid */
.gridpanda-grid--masonry {
	display: block;
}

/* Masonry items wrapper must be a real box for Masonry.js absolute positioning.
   The global .gridpanda-grid__items uses display:contents which strips the element's
   box from the render tree — Masonry needs a positioned container for its children. */
.gridpanda-grid--masonry .gridpanda-grid__items {
	display: block;
	position: relative;
}

.gridpanda-grid--list {
	grid-template-columns: 1fr;
	gap: var(--gridpanda-gap-v, var(--gridpanda-gap, 20px));
	column-gap: 0;
}

/* ── Carousel layout — JS-driven sliding with arrows & dots ── */
.gridpanda-grid--carousel {
	display: flex !important;
	flex-direction: column;
	position: relative;
	overflow: hidden;
	touch-action: pan-y;
	-webkit-user-select: none;
	user-select: none;
}

/* Track — flex row that slides via transform: translateX */
.gridpanda-grid--carousel .gridpanda-grid__items {
	display: flex !important;
	flex-wrap: nowrap !important;
	overflow: visible;
	transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
	gap: var(--gridpanda-gap-h, var(--gridpanda-gap, 20px));
	will-change: transform;
	cursor: grab;
}

.gridpanda-grid--carousel .gridpanda-grid__items.gridpanda-grabbing {
	cursor: grabbing;
	transition: none;
}

/* Each item — fixed fraction of visible area */
.gridpanda-grid--carousel .gridpanda-grid__item {
	flex: 0 0 auto;
	box-sizing: border-box;
	pointer-events: auto;
}

/* Cards fill carousel cell */
.gridpanda-grid--carousel .gridpanda-grid__item > .gridpanda-card {
	width: 100% !important;
	max-width: 100%;
	box-sizing: border-box;
	height: 100%;
}

/* ── Carousel Arrows ── */
.gridpanda-carousel__arrow {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 10;
	display: flex;
	align-items: center;
	justify-content: center;
	width: var(--gridpanda-arrow-size, 36px);
	height: var(--gridpanda-arrow-size, 36px);
	background: var(--gridpanda-arrow-bg, rgba(0, 0, 0, 0.5));
	color: var(--gridpanda-arrow-color, #fff);
	border: none;
	border-radius: var(--gridpanda-arrow-radius, 50%);
	cursor: pointer;
	font-size: calc(var(--gridpanda-arrow-size, 36px) * 0.5);
	line-height: 1;
	padding: 0;
	transition: opacity 0.2s, background-color 0.2s;
	opacity: 0.8;
}
.gridpanda-carousel__arrow:hover {
	opacity: 1;
	background: var(--gridpanda-arrow-bg-hover, var(--gridpanda-arrow-bg, rgba(0, 0, 0, 0.7)));
}
.gridpanda-carousel__arrow[disabled] {
	opacity: 0.3;
	cursor: default;
	pointer-events: none;
}
/* Default (center-overlay): arrows centered vertically, at left/right edges */
.gridpanda-carousel__arrow--prev { left: 8px; }
.gridpanda-carousel__arrow--next { right: 8px; }

/* ── Arrow position variants ── */
/* Top positions */
.gridpanda-grid--carousel[data-arrows-position="top-left"] .gridpanda-carousel__arrow,
.gridpanda-grid--carousel[data-arrows-position="top-center"] .gridpanda-carousel__arrow,
.gridpanda-grid--carousel[data-arrows-position="top-right"] .gridpanda-carousel__arrow {
	top: 8px;
	transform: none;
}
.gridpanda-grid--carousel[data-arrows-position="top-left"] .gridpanda-carousel__arrow--prev { left: 8px; }
.gridpanda-grid--carousel[data-arrows-position="top-left"] .gridpanda-carousel__arrow--next { left: calc(var(--gridpanda-arrow-size, 36px) + 14px); right: auto; }
.gridpanda-grid--carousel[data-arrows-position="top-center"] .gridpanda-carousel__arrow--prev { left: calc(50% - var(--gridpanda-arrow-size, 36px) - 3px); right: auto; }
.gridpanda-grid--carousel[data-arrows-position="top-center"] .gridpanda-carousel__arrow--next { right: calc(50% - var(--gridpanda-arrow-size, 36px) - 3px); left: auto; }
.gridpanda-grid--carousel[data-arrows-position="top-right"] .gridpanda-carousel__arrow--next { right: 8px; }
.gridpanda-grid--carousel[data-arrows-position="top-right"] .gridpanda-carousel__arrow--prev { right: calc(var(--gridpanda-arrow-size, 36px) + 14px); left: auto; }

/* Center positions */
.gridpanda-grid--carousel[data-arrows-position="center-left"] .gridpanda-carousel__arrow { left: 12px; right: auto; }
.gridpanda-grid--carousel[data-arrows-position="center-left"] .gridpanda-carousel__arrow--next { left: calc(var(--gridpanda-arrow-size, 36px) + 18px); }
.gridpanda-grid--carousel[data-arrows-position="center-right"] .gridpanda-carousel__arrow { right: 12px; left: auto; }
.gridpanda-grid--carousel[data-arrows-position="center-right"] .gridpanda-carousel__arrow--prev { right: calc(var(--gridpanda-arrow-size, 36px) + 18px); }

/* Bottom positions */
.gridpanda-grid--carousel[data-arrows-position="bottom-left"] .gridpanda-carousel__arrow,
.gridpanda-grid--carousel[data-arrows-position="bottom-center"] .gridpanda-carousel__arrow,
.gridpanda-grid--carousel[data-arrows-position="bottom-right"] .gridpanda-carousel__arrow {
	top: auto;
	bottom: 8px;
	transform: none;
}
.gridpanda-grid--carousel[data-arrows-position="bottom-left"] .gridpanda-carousel__arrow--prev { left: 8px; }
.gridpanda-grid--carousel[data-arrows-position="bottom-left"] .gridpanda-carousel__arrow--next { left: calc(var(--gridpanda-arrow-size, 36px) + 14px); right: auto; }
.gridpanda-grid--carousel[data-arrows-position="bottom-center"] .gridpanda-carousel__arrow--prev { left: calc(50% - var(--gridpanda-arrow-size, 36px) - 3px); right: auto; }
.gridpanda-grid--carousel[data-arrows-position="bottom-center"] .gridpanda-carousel__arrow--next { right: calc(50% - var(--gridpanda-arrow-size, 36px) - 3px); left: auto; }
.gridpanda-grid--carousel[data-arrows-position="bottom-right"] .gridpanda-carousel__arrow--next { right: 8px; }
.gridpanda-grid--carousel[data-arrows-position="bottom-right"] .gridpanda-carousel__arrow--prev { right: calc(var(--gridpanda-arrow-size, 36px) + 14px); left: auto; }

/* Outside — arrows placed beyond grid boundary, needs wrapper with visible overflow */
.gridpanda-grid--carousel[data-arrows-position="outside-center"] {
	overflow: visible;
}
.gridpanda-grid--carousel[data-arrows-position="outside-center"] .gridpanda-grid__items {
	overflow: hidden;
}
.gridpanda-grid--carousel[data-arrows-position="outside-center"] .gridpanda-carousel__arrow--prev { left: -48px; }
.gridpanda-grid--carousel[data-arrows-position="outside-center"] .gridpanda-carousel__arrow--next { right: -48px; }

/* Default SVG chevron icon inside arrows */
.gridpanda-carousel__arrow svg {
	width: 60%;
	height: 60%;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.5;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* ── Carousel Dots ── */
.gridpanda-carousel__dots {
	display: flex;
	justify-content: center;
	align-items: center;
	gap: var(--gridpanda-dot-gap, 6px);
	padding: 12px 0 4px;
}

/* ── Dot position variants ── */
/* Inside top */
.gridpanda-grid--carousel[data-dots-position="top-left"] .gridpanda-carousel__dots,
.gridpanda-grid--carousel[data-dots-position="top-center"] .gridpanda-carousel__dots,
.gridpanda-grid--carousel[data-dots-position="top-right"] .gridpanda-carousel__dots {
	order: -1;
	padding: 0 0 8px;
}
.gridpanda-grid--carousel[data-dots-position="top-left"] .gridpanda-carousel__dots { justify-content: flex-start; }
.gridpanda-grid--carousel[data-dots-position="top-center"] .gridpanda-carousel__dots { justify-content: center; }
.gridpanda-grid--carousel[data-dots-position="top-right"] .gridpanda-carousel__dots { justify-content: flex-end; }

/* Inside bottom (default) */
.gridpanda-grid--carousel[data-dots-position="bottom-left"] .gridpanda-carousel__dots,
.gridpanda-grid--carousel[data-dots-position="bottom-center"] .gridpanda-carousel__dots,
.gridpanda-grid--carousel[data-dots-position="bottom-right"] .gridpanda-carousel__dots {
	order: 10;
	padding: 8px 0 0;
}
.gridpanda-grid--carousel[data-dots-position="bottom-left"] .gridpanda-carousel__dots { justify-content: flex-start; }
.gridpanda-grid--carousel[data-dots-position="bottom-center"] .gridpanda-carousel__dots { justify-content: center; }
.gridpanda-grid--carousel[data-dots-position="bottom-right"] .gridpanda-carousel__dots { justify-content: flex-end; }

/* Outside bottom — below the grid boundary */
.gridpanda-grid--carousel[data-dots-position="outside-bottom"] .gridpanda-carousel__dots {
	order: 10;
	padding: 12px 0 0;
	justify-content: center;
}

/* Dot base — circle style (default) */
.gridpanda-carousel__dot {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--gridpanda-dot-size, 10px);
	height: var(--gridpanda-dot-size, 10px);
	border-radius: 50%;
	background: var(--gridpanda-dot-color, #d1d5db);
	border: none;
	padding: 0;
	cursor: pointer;
	transition: background-color 0.2s, transform 0.2s;
}
.gridpanda-carousel__dot:hover {
	transform: scale(1.2);
}
.gridpanda-carousel__dot--active {
	background: var(--gridpanda-dot-active, #2563eb);
	transform: scale(1.15);
}

/* Dot style: pill */
.gridpanda-carousel__dots--pill .gridpanda-carousel__dot {
	width: calc(var(--gridpanda-dot-size, 10px) * 2);
	height: calc(var(--gridpanda-dot-size, 10px) * 0.5);
	border-radius: calc(var(--gridpanda-dot-size, 10px) * 0.25);
}
.gridpanda-carousel__dots--pill .gridpanda-carousel__dot--active {
	width: calc(var(--gridpanda-dot-size, 10px) * 3);
}

/* Dot style: dash */
.gridpanda-carousel__dots--dash .gridpanda-carousel__dot {
	width: calc(var(--gridpanda-dot-size, 10px) * 2.5);
	height: 3px;
	border-radius: 2px;
}
.gridpanda-carousel__dots--dash .gridpanda-carousel__dot--active {
	width: calc(var(--gridpanda-dot-size, 10px) * 3.5);
}

/* Dot style: number */
.gridpanda-carousel__dots--number .gridpanda-carousel__dot {
	width: auto;
	height: auto;
	min-width: calc(var(--gridpanda-dot-size, 10px) * 2.2);
	padding: 2px 6px;
	border-radius: 4px;
	font-size: calc(var(--gridpanda-dot-size, 10px) * 0.9);
	font-weight: 600;
	color: var(--gridpanda-dot-color, #6b7280);
	background: transparent;
}
.gridpanda-carousel__dots--number .gridpanda-carousel__dot--active {
	color: var(--gridpanda-dot-active, #2563eb);
	background: transparent;
	text-decoration: underline;
}

/* Grid items container */
.gridpanda-grid__items {
	display: contents;
}

/* Grid item wrapper */
.gridpanda-grid__item {
	/* article wrapper from grid-item.php */
	min-width: 0; /* prevent grid blowout */
}

/* Inside a grid, cards fill their cell regardless of inline width */
.gridpanda-grid__item > .gridpanda-card {
	width: 100% !important;
	max-width: 100%;
	box-sizing: border-box;
}

/* Force border-box on every gridpanda-controlled element inside a grid item.
   The PHP/JS LayoutEngine emits inline `width: 100%; padding: Npx` on
   `.gridpanda-container` and `.gridpanda-card__block-wrapper` and similar
   wrappers. Without `box-sizing: border-box`, `width: 100%` resolves to
   *content* width, so the box becomes parent_width + 2*padding wide and
   bleeds outside the grid track. This rule is scoped to grid items so it
   can't accidentally affect host-theme containers. */
.gridpanda-grid__item,
.gridpanda-grid__item *,
.gridpanda-card,
.gridpanda-card *,
.gridpanda-container,
.gridpanda-container *,
[class*="gridpanda-el-"] {
	box-sizing: border-box;
}

/* =============================================
   Cards
   ============================================= */

.gridpanda-card {
	border: none;
	border-radius: var(--gridpanda-radius);
	overflow: hidden;
	background: #ffffff;
	box-shadow: none;
	transition: box-shadow 0.2s ease, transform 0.2s ease;
	/* Allow the card to shrink below its intrinsic min-content size.
	   Required so grid tracks using minmax(0, 1fr) can actually shrink the card
	   when the parent container is narrower than (cols * intrinsic_card_width). */
	min-width: 0;
	max-width: 100%;
	box-sizing: border-box;
}

.gridpanda-card:hover {
	box-shadow: none;
	transform: none;
}

/* Defensive image sizing — WordPress emits <img width="1024" height="..."> with
   intrinsic dimensions. Without these, images become min-content anchors that
   refuse to shrink, blowing the grid track at narrow viewports. */
.gridpanda-card img,
.gridpanda-card picture > img,
.gridpanda-card .gridpanda-card__image img {
	max-width: 100%;
	height: auto;
}

/* Inner card containers must also yield, otherwise their flex/auto min-width
   propagates the same blowout up to the card. */
.gridpanda-card--container,
.gridpanda-container-wrapper {
	min-width: 0;
}

/* Clickable card — JS delegation via data-gridpanda-link attribute */
.gridpanda-card--clickable {
	cursor: pointer;
}

/* ── Equal-height cards ── */
/* Forces every card in a row to the same height. The grid item becomes a
   flex container so the card stretches, and the card's root layout uses
   flex-grow so internal content fills the available space. The last
   direct child inside the root container pushes down via margin-top:auto,
   which pins CTAs / buttons to the bottom regardless of title length. */
.gridpanda-grid--equal-height .gridpanda-grid__item {
	display: flex;
	flex-direction: column;
}

.gridpanda-grid--equal-height .gridpanda-card,
.gridpanda-grid--equal-height .gridpanda-card--container,
.gridpanda-grid--equal-height .gridpanda-card--grid {
	flex: 1;
	display: flex;
	flex-direction: column;
}

/* Container-tree cards: stretch the root container wrapper */
.gridpanda-grid--equal-height .gridpanda-card--container > .gridpanda-container-wrapper {
	flex: 1;
	display: flex;
	flex-direction: column;
}

.gridpanda-grid--equal-height .gridpanda-card--container > .gridpanda-container-wrapper > .gridpanda-container {
	flex: 1;
}

/* Push the last child in a vertical container to the bottom */
.gridpanda-grid--equal-height .gridpanda-container[style*="flex-direction: column"] > .gridpanda-container-wrapper:last-child,
.gridpanda-grid--equal-height .gridpanda-container[style*="flex-direction:column"] > .gridpanda-container-wrapper:last-child {
	margin-top: auto;
}

/* Card blocks (BEM from CardBuilder + default card) */
.gridpanda-card__block {
	/* generic block container */
}

.gridpanda-card__block--image {
	/* overflow visible so image shadow/border can extend beyond */
}

.gridpanda-card__image-link {
	display: block;
	line-height: 0;
	border-radius: inherit;
}

/* ── Image wrapper — supports aspect-ratio via inline style ── */
.gridpanda-card__image-wrapper {
	position: relative;
	line-height: 0;
	border-radius: inherit;
}

/* Ratio wrapper: img uses position:absolute + inset to fill, then
   clips itself via border-radius:inherit. No overflow:hidden on
   wrapper so box-shadow and border can extend outward. */

.gridpanda-card__image-wrapper--ratio .gridpanda-card__image {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
}

.gridpanda-card__image {
	display: block;
	width: 100%;
	height: auto;
	object-fit: cover;
	border-radius: inherit;
}

.gridpanda-card__block--title,
.gridpanda-card__block--excerpt,
.gridpanda-card__block--date {
	padding: 0 var(--gridpanda-spacing);
}

.gridpanda-card__block--title {
	padding-top: var(--gridpanda-spacing);
}

.gridpanda-card__block--date {
	padding-bottom: var(--gridpanda-spacing);
}

/* Custom card templates: wrapper handles all spacing — reset inner block defaults. */
.gridpanda-card__block-wrapper > .gridpanda-card__block {
	padding: 0;
}

/* Absolutely-positioned blocks (e.g. badges) must stack above siblings
   whose animation classes create stacking contexts via will-change/transform. */
.gridpanda-card__block-wrapper[style*="position:absolute"],
.gridpanda-card__block-wrapper[style*="position: absolute"] {
	z-index: 10;
}

.gridpanda-card__title {
	margin: 0 0 6px 0;
	font-size: var(--fx-font-size, 17px);
	font-weight: var(--fx-font-weight, 600);
	line-height: var(--fx-line-height, 22px);
	letter-spacing: var(--fx-letter-spacing, 0px);
	text-transform: var(--fx-text-transform, none);
	text-decoration: var(--fx-text-decoration, none);
	font-family: var(--fx-font-family, inherit);
	color: var(--fx-color, inherit);
	text-align: var(--fx-text-align, inherit);
}

.gridpanda-card__title a {
	color: var(--gridpanda-link-color, var(--gridpanda-text));
	text-decoration: none;
}

.gridpanda-card__title a:hover {
	color: var(--gridpanda-link-hover, var(--gridpanda-primary));
}

.gridpanda-card__title-prefix,
.gridpanda-card__title-suffix {
	vertical-align: middle;
}

.gridpanda-card__excerpt {
	margin: 0 0 8px 0;
	font-size: var(--fx-font-size, 14px);
	color: var(--fx-color, var(--gridpanda-text-light));
	line-height: var(--fx-line-height, 21px);
	font-weight: var(--fx-font-weight, 400);
	letter-spacing: var(--fx-letter-spacing, 0px);
	text-transform: var(--fx-text-transform, none);
	font-family: var(--fx-font-family, inherit);
	text-align: var(--fx-text-align, inherit);
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.gridpanda-card__date {
	display: block;
	font-size: var(--fx-font-size, 13px);
	color: var(--fx-color, var(--gridpanda-text-muted));
	font-weight: var(--fx-font-weight, 400);
	font-family: var(--fx-font-family, inherit);
	line-height: var(--fx-line-height, 18px);
	letter-spacing: var(--fx-letter-spacing, 0px);
	text-transform: var(--fx-text-transform, none);
	text-align: var(--fx-text-align, inherit);
}

/* ACF field (from CardBuilder blocks) */
.gridpanda-card__acf-field {
	font-size: var(--fx-font-size, 14px);
	font-family: var(--fx-font-family, inherit);
	color: var(--fx-color, inherit);
	font-weight: var(--fx-font-weight, 400);
	line-height: var(--fx-line-height, 1.5);
	letter-spacing: var(--fx-letter-spacing, normal);
	text-transform: var(--fx-text-transform, none);
	text-align: var(--fx-text-align, inherit);
	text-decoration: var(--fx-text-decoration, none);
	margin: 0;
}

.gridpanda-card__acf-label {
	font-weight: var(--fx-font-weight, 600);
	margin-right: 4px;
}

.gridpanda-card__acf-value {
	font-size: var(--fx-font-size, 14px);
	font-family: var(--fx-font-family, inherit);
	color: var(--fx-color, inherit);
}

/* Card meta (from CardBuilder blocks) */
.gridpanda-card__meta {
	font-size: var(--fx-font-size, 14px);
	font-family: var(--fx-font-family, inherit);
	color: var(--fx-color, inherit);
	font-weight: var(--fx-font-weight, 400);
	line-height: var(--fx-line-height, 1.5);
	letter-spacing: var(--fx-letter-spacing, normal);
	text-transform: var(--fx-text-transform, none);
	text-align: var(--fx-text-align, inherit);
	text-decoration: var(--fx-text-decoration, none);
	padding: 0 var(--gridpanda-spacing);
	margin: 0;
}

.gridpanda-card__meta-label {
	font-weight: var(--fx-font-weight, 600);
	margin-right: 4px;
}

.gridpanda-card__meta-value {
	font-size: var(--fx-font-size, 14px);
	font-family: var(--fx-font-family, inherit);
	color: var(--fx-color, inherit);
}

/* Text block (from CardBuilder blocks) */
.gridpanda-card__text {
	margin: 0;
	font-size: var(--fx-font-size, 14px);
	font-family: var(--fx-font-family, inherit);
	line-height: var(--fx-line-height, 1.5);
	color: var(--fx-color, inherit);
}

/* Author block */
.gridpanda-card__author {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 0 var(--gridpanda-spacing) var(--gridpanda-spacing);
}

.gridpanda-card__author-image {
	border-radius: 50%;
	width: 32px;
	height: 32px;
}

.gridpanda-card__author-name {
	font-size: var(--fx-font-size, 14px);
	color: var(--fx-color, var(--gridpanda-text));
	text-decoration: var(--fx-text-decoration, none);
	font-weight: var(--fx-font-weight, 400);
	font-family: var(--fx-font-family, inherit);
}

.gridpanda-card__author-name:hover {
	color: var(--gridpanda-primary);
}

/* Taxonomy block */
.gridpanda-card__taxonomy {
	display: flex;
	flex-wrap: wrap;
	gap: 5px;
	padding: 0 var(--gridpanda-spacing) 8px;
}

.gridpanda-card__term {
	display: inline-block;
	padding: 2px 8px;
	background: var(--gridpanda-secondary);
	border-radius: 3px;
	font-size: var(--fx-font-size, 12px);
	color: var(--fx-color, var(--gridpanda-text-light));
	text-decoration: var(--fx-text-decoration, none);
	font-weight: var(--fx-font-weight, 400);
	font-family: var(--fx-font-family, inherit);
}

.gridpanda-card__term:hover {
	background: var(--gridpanda-primary);
	color: #fff;
}

/* Button block
   ------------------------------------------------------------------
   THEME ISOLATION: the button renders as <a> by default, which means
   any host-theme rule targeting `a` (font-family, letter-spacing,
   text-transform, font-style) will leak in and override the plugin's
   intended look. We pin every typography-derived property here so the
   plugin produces consistent output regardless of the active theme.
   font-family inherits from the card / theme body so the plugin still
   blends with the surrounding typography stack — the lock is against
   theme rules that *target the anchor element specifically*.

   The base rule uses single-class specificity (0,1,0) for the layout +
   color values that users routinely override with their own theme CSS.
   The TYPOGRAPHY LOCK uses doubled-class scoping
   `.gridpanda-card.gridpanda-card-instance .gridpanda-card__button`
   → specificity 0,3,0, which beats host-theme rules like
   `.entry-content a.button` (0,2,1) without `!important`.
   ------------------------------------------------------------------ */
.gridpanda-card__button {
	display: inline-block;
	padding: 8px 16px;
	margin: 0 var(--gridpanda-spacing) var(--gridpanda-spacing);
	background: var(--gridpanda-primary);
	color: #fff;
	border: none;
	border-radius: var(--gridpanda-radius);
	font-size: 14px;
	font-weight: 600;
	line-height: 20px;
	cursor: pointer;
	transition: background 0.2s ease;
}

.gridpanda-card__button:hover {
	background: var(--gridpanda-primary-hover);
}

/* Typography lock — chained-class scope (specificity 0,3,0) defeats
   theme `.entry-content a {}` (0,2,1) and `.theme-class p a {}`
   (0,2,1) without `!important`. Any host-theme selector with three or
   more classes can still legitimately override; that is a deliberate
   user-intent escape hatch. Mirrors Elementor's
   `.elementor-element.elementor-element-edit-mode` doubled-class trick. */
.gridpanda-card.gridpanda-card-instance .gridpanda-card__button {
	font-family: inherit;
	font-style: normal;
	letter-spacing: normal;
	text-transform: none;
	text-decoration: none;
	text-shadow: none;
}

/* Button variants */
.gridpanda-card__button--primary {
	background: var(--gridpanda-primary);
	color: #fff;
	border: none;
}

.gridpanda-card__button--primary:hover {
	background: var(--gridpanda-primary-hover);
}

.gridpanda-card__button--secondary {
	background: #e5e7eb;
	color: #111827;
	border: none;
}

.gridpanda-card__button--secondary:hover {
	background: #d1d5db;
	color: #111827;
}

.gridpanda-card__button--outline {
	background: transparent;
	color: var(--gridpanda-primary);
	border: 2px solid var(--gridpanda-primary);
}

.gridpanda-card__button--outline:hover {
	background: var(--gridpanda-primary);
	color: #fff;
}

.gridpanda-card__button--custom {
	background: transparent;
	color: inherit;
	border: none;
	transition: background-color 0.2s ease, color 0.2s ease;
}

.gridpanda-card__button--full-width {
	display: block;
	width: 100%;
	box-sizing: border-box;
	text-align: center;
	margin-left: 0;
	margin-right: 0;
}

/* Inside container layout, spacing is handled by the container gap,
   so reset the button's default margin to avoid inflating the row. */
.gridpanda-card__block-wrapper .gridpanda-card__button {
	margin: 0;
}

/* Add-to-cart block (WooCommerce) ---------------------------------------- */
.gridpanda-card__add-to-cart {
	display: flex;
	align-items: center;
}

.gridpanda-card__add-to-cart a,
.gridpanda-card__add-to-cart a.button {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	padding: 8px 16px;
	background: var(--gridpanda-primary);
	color: #fff;
	border: none;
	border-radius: var(--gridpanda-radius);
	font-size: 14px;
	font-weight: 600;
	text-decoration: none;
	cursor: pointer;
	transition: background 0.2s ease;
	line-height: 20px;
}

/* Single-class hover: specificity 0,1,1 so scoped per-block hover
   rules (.gridpanda-el-xxx a.button:hover → 0,2,1) can override. */
.gridpanda-card__add-to-cart a:hover {
	background: var(--gridpanda-primary-hover);
	color: #fff;
	text-decoration: none;
}

.gridpanda-card__add-to-cart a svg {
	flex-shrink: 0;
	width: 14px;
	height: 14px;
}

.gridpanda-card__add-to-cart--full-width {
	width: 100%;
}

.gridpanda-card__add-to-cart--full-width a {
	display: flex;
	justify-content: center;
	width: 100%;
	box-sizing: border-box;
	text-align: center;
}

/* Outline / filled variant colors use chained-class scoping so theme
   `.entry-content a {}` (0,2,1) loses against our 0,3,1 selector —
   no `!important` needed. Background already wins on natural ordering. */
.gridpanda-card.gridpanda-card-instance .gridpanda-card__add-to-cart--outline a {
	background: transparent;
	color: var(--gridpanda-primary);
	border: 2px solid var(--gridpanda-primary);
}

.gridpanda-card.gridpanda-card-instance .gridpanda-card__add-to-cart--outline a:hover {
	background: var(--gridpanda-primary);
	color: #fff;
}

.gridpanda-card.gridpanda-card-instance .gridpanda-card__add-to-cart--filled a {
	background: var(--gridpanda-primary);
	color: #fff;
}

/* Inside container layout, reset margin like regular buttons */
.gridpanda-card__block-wrapper .gridpanda-card__add-to-cart a {
	margin: 0;
}

/* Star rating */
.gridpanda-card__rating {
	display: flex;
	align-items: center;
	gap: 5px;
	padding: 0 var(--gridpanda-spacing) 8px;
}

.gridpanda-card__star--filled {
	color: #f5a623;
}

.gridpanda-card__star--empty {
	color: #ddd;
}

/* Half star: base layer is gray (empty), overlay layer is gold (filled). */
.gridpanda-card__star--half {
	color: #ddd;
}

.gridpanda-card__star--half > span:last-child {
	color: #f5a623;
}

.gridpanda-card__review-count {
	font-size: 13px;
	color: var(--gridpanda-text-muted);
}

/* Price block */
.gridpanda-card__price {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
	padding: 0 var(--gridpanda-spacing) 8px;
	/* Default 18px matches the preview renderer default — override via
	   ElementStyles typography or the price_font_size block setting. */
	font-size: var(--fx-font-size, 18px);
	font-weight: var(--fx-font-weight, 600);
	color: var(--fx-color, inherit);
	font-family: var(--fx-font-family, inherit);
}

.gridpanda-card__price--stacked {
	flex-direction: column;
	align-items: flex-start;
}

.gridpanda-card__price-value {
	display: flex;
	align-items: baseline;
	gap: 6px;
	flex-wrap: wrap;
}

/* WooCommerce injects <del>/<ins> for sale prices. Reset font-size so they
   inherit from .gridpanda-card__price-value, and rely on inline styles
   (injected by PHP) for colour overrides. */
.gridpanda-card__price-value del,
.gridpanda-card__price-value ins {
	font-size: inherit;
	text-decoration-color: inherit;
}
.gridpanda-card__price-value ins {
	text-decoration: none;
}
.gridpanda-card__price-value del {
	opacity: 0.6;
}

.gridpanda-card__sale-badge {
	display: inline-flex;
	align-items: center;
	padding: 2px 8px;
	background: #e74c3c;
	color: #fff;
	border-radius: 3px;
	font-size: 11px;
	font-weight: 700;
	text-transform: uppercase;
	line-height: 15px;
}

.gridpanda-card__subscription-badge {
	display: inline-flex;
	align-items: center;
	padding: 2px 8px;
	background: #6366f1;
	color: #fff;
	border-radius: 3px;
	font-size: 11px;
	font-weight: 700;
	text-transform: uppercase;
	line-height: 15px;
}

.gridpanda-card__subscription-fee,
.gridpanda-card__subscription-trial {
	width: 100%;
	font-size: 12px;
	color: #6b7280;
}

/* =============================================
   Loading State
   ============================================= */

.gridpanda-loading {
	opacity: 0.6;
	pointer-events: none;
	position: relative;
}

.gridpanda-loading::after {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	width: 30px;
	height: 30px;
	margin: -15px 0 0 -15px;
	border: 3px solid var(--gridpanda-secondary);
	border-top-color: var(--gridpanda-primary);
	border-radius: 50%;
	animation: gridpanda-spin 0.8s linear infinite;
	z-index: 10;
}

@keyframes gridpanda-spin {
	to {
		transform: rotate(360deg);
	}
}

/* =============================================
   Empty State
   ============================================= */

.gridpanda-grid-empty {
	grid-column: 1 / -1;
	text-align: center;
	padding: 48px var(--gridpanda-spacing);
	color: var(--gridpanda-text-muted);
}

.gridpanda-grid-empty p {
	font-size: 18px;
	margin: 0;
}

/* =============================================
   Pagination — CSS custom property driven
   All --fxp-* vars are set inline from pagination_config.
   ============================================= */

.gridpanda-pagination {
	display: flex;
	justify-content: var(--fxp-justify, center);
	align-items: center;
	gap: var(--fxp-gap, 6px);
	margin-top: var(--fxp-margin-top, 24px);
	margin-bottom: var(--fxp-margin-bottom, 0);
	flex-wrap: wrap;
	font-size: var(--fxp-font-size, 14px);
}

/* Numbered list */
.gridpanda-pagination__list {
	display: flex;
	list-style: none;
	margin: 0;
	padding: 0;
	gap: var(--fxp-gap, 6px);
	align-items: center;
	flex-wrap: wrap;
}

.gridpanda-pagination__item {
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

.gridpanda-pagination__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.25em;
	height: 2.25em;
	padding: var(--fxp-padding, 8px 12px);
	border: 1px solid var(--fxp-border-color, #d1d5db);
	border-radius: var(--fxp-radius, 4px);
	background: var(--fxp-bg, #fff);
	color: var(--fxp-color, #374151);
	text-decoration: none;
	transition: background 0.15s, color 0.15s, border-color 0.15s;
	cursor: pointer;
	line-height: 1;
}

.gridpanda-pagination__link:hover {
	background: var(--fxp-hover-bg, #3b82f6);
	color: var(--fxp-hover-color, #fff);
	border-color: var(--fxp-hover-border-color, #3b82f6);
}

.gridpanda-pagination__link--active,
.gridpanda-pagination__link--active:hover {
	background: var(--fxp-active-bg, #3b82f6);
	color: var(--fxp-active-color, #fff);
	border-color: var(--fxp-active-border-color, #3b82f6);
	pointer-events: none;
}

.gridpanda-pagination__dots {
	border: none;
	background: transparent;
	color: var(--gridpanda-text-muted, #9ca3af);
	min-width: 1.5em;
	cursor: default;
}

/* Results info */
.gridpanda-pagination__info {
	width: 100%;
	text-align: var(--fxp-justify, center);
	font-size: 0.85em;
	color: var(--gridpanda-text-light, #6b7280);
	margin-bottom: 8px;
}

/* Load More button */
.gridpanda-pagination__load-more {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--fxp-btn-width, auto);
	min-height: var(--fxp-btn-height, 40px);
	padding: var(--fxp-padding, 8px 24px);
	font-size: var(--fxp-font-size, 14px);
	border: 1px solid var(--fxp-border-color, #d1d5db);
	border-radius: var(--fxp-radius, 4px);
	background: var(--fxp-bg, #fff);
	color: var(--fxp-color, #374151);
	cursor: pointer;
	transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.gridpanda-pagination__load-more:hover {
	background: var(--fxp-hover-bg, #3b82f6);
	color: var(--fxp-hover-color, #fff);
	border-color: var(--fxp-hover-border-color, #3b82f6);
}

.gridpanda-pagination__load-more[disabled] {
	opacity: 0.6;
	cursor: not-allowed;
}

.gridpanda-pagination__no-more {
	font-size: 0.85em;
	color: var(--gridpanda-text-muted, #9ca3af);
}

/* Infinite scroll trigger */
.gridpanda-pagination__infinite-trigger {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 16px;
	color: var(--gridpanda-text-muted, #9ca3af);
	font-size: 0.85em;
}

.gridpanda-pagination__spinner {
	width: 20px;
	height: 20px;
	border: 2px solid var(--gridpanda-border, #d1d5db);
	border-top-color: var(--fxp-active-bg, #3b82f6);
	border-radius: 50%;
	animation: gridpanda-spin 0.6s linear infinite;
}

@keyframes gridpanda-spin {
	to { transform: rotate(360deg); }
}

/* =============================================
   Responsive
   ============================================= */

@media ( max-width: 1024px ) {
	.gridpanda-grid--grid {
		grid-template-columns: repeat(var(--gridpanda-columns-tablet, 2), minmax(0, 1fr));
	}

	.gridpanda-grid--metro {
		grid-template-columns: repeat(var(--gridpanda-columns-tablet, 2), minmax(0, 1fr));
		grid-auto-rows: var(--gridpanda-metro-row-h, 180px);
	}
	/* Downgrade 2-col spans to 1-col on tablet with 2 columns */
	.gridpanda-grid--metro .gridpanda-grid__item--span-2x2 {
		grid-column: span min(2, var(--gridpanda-columns-tablet, 2));
		grid-row: span 2;
	}
	.gridpanda-grid--metro .gridpanda-grid__item--span-2x1 {
		grid-column: span min(2, var(--gridpanda-columns-tablet, 2));
	}

}

@media ( max-width: 767px ) {
	.gridpanda-grid--grid {
		grid-template-columns: repeat(var(--gridpanda-columns-mobile, 1), minmax(0, 1fr));
	}

	.gridpanda-grid--metro {
		grid-template-columns: repeat(var(--gridpanda-columns-mobile, 1), minmax(0, 1fr));
		grid-auto-rows: var(--gridpanda-metro-row-h, 160px);
	}
	/* On single-column mobile, remove all spanning */
	.gridpanda-grid--metro .gridpanda-grid__item--span-2x2,
	.gridpanda-grid--metro .gridpanda-grid__item--span-2x1 {
		grid-column: span 1;
	}
	.gridpanda-grid--metro .gridpanda-grid__item--span-2x2,
	.gridpanda-grid--metro .gridpanda-grid__item--span-1x2 {
		grid-row: span 1;
	}

	/* Carousel: shrink arrows on mobile for touch UX */
	.gridpanda-carousel__arrow {
		width: 28px;
		height: 28px;
		font-size: 12px;
	}

	.gridpanda-facets {
		flex-direction: row;
		flex-wrap: wrap;
	}

	.gridpanda-facet {
		flex: 0 1 calc(50% - 8px);
	}
}

@media ( max-width: 480px ) {
	.gridpanda-facet {
		flex: 1;
		min-width: 100%;
	}

	.gridpanda-grid {
		grid-template-columns: 1fr;
	}
}

/* =============================================
   Range Facet
   ============================================= */

.gridpanda-range {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.gridpanda-range__input {
	width: 100%;
	height: var(--fx-range-track-height, 4px);
	border-radius: 2px;
	background: var(--fx-range-track-bg, var(--gridpanda-secondary));
	outline: none;
	-webkit-appearance: none;
	appearance: none;
	padding: 0;
	margin: 0;
	border: none;
	cursor: pointer;
}

.gridpanda-range__input::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	width: var(--fx-range-thumb-size, 18px);
	height: var(--fx-range-thumb-size, 18px);
	border-radius: var(--fx-range-thumb-border-radius, 50%);
	/* --fx-range-track-active controls the active/filled track colour.
	   A JS-driven two-tone fill can read this var via getComputedStyle().
	   It also acts as a thumb bg override when set. */
	background: var(--fx-range-thumb-bg, var(--fx-range-track-active, var(--gridpanda-primary)));
	border: var(--fx-range-thumb-border-width, 2px) solid var(--fx-range-thumb-border, transparent);
	cursor: pointer;
	transition: background 0.2s ease;
}

.gridpanda-range__input::-webkit-slider-thumb:hover {
	background: var(--fx-range-thumb-hover, var(--gridpanda-primary-hover));
}

.gridpanda-range__input::-moz-range-thumb {
	width: var(--fx-range-thumb-size, 18px);
	height: var(--fx-range-thumb-size, 18px);
	border-radius: var(--fx-range-thumb-border-radius, 50%);
	background: var(--fx-range-thumb-bg, var(--gridpanda-primary));
	border: var(--fx-range-thumb-border-width, 2px) solid var(--fx-range-thumb-border, transparent);
	cursor: pointer;
	transition: background 0.2s ease;
}

.gridpanda-range__input::-moz-range-thumb:hover {
	background: var(--fx-range-thumb-hover, var(--gridpanda-primary-hover));
}

.gridpanda-range__input:focus {
	outline: none;
}

/* ── Inputs row — compact pill boxes, no visible labels (Amazon/FB style) ── */
.gridpanda-range__inputs {
	display: flex;
	align-items: center;
	gap: 8px;
}

/* Visually hide labels but keep them for screen readers */
.gridpanda-range__input-group label {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
}

/* Each input group = bordered pill wrapper */
.gridpanda-range__input-group {
	flex: 1;
	display: flex;
	align-items: center;
	border: 1.5px solid var(--fx-input-border-color, var(--gridpanda-border, #d1d5db));
	border-radius: 8px;
	background: var(--fx-input-bg, #fff);
	overflow: hidden;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.gridpanda-range__input-group:focus-within {
	border-color: var(--gridpanda-primary, #6366f1);
	box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.12) !important;
}

.gridpanda-range__input-group .gridpanda-range__input-addon {
	padding: 0 6px;
	font-size: 13px;
	color: var(--gridpanda-text-muted, #9ca3af);
	user-select: none;
}

/* Number input: no border of its own, fills the pill.
   height: auto overrides the legacy .gridpanda-range__input { height: 4px } rule
   which was written for <input type="range"> and must not apply here. */
.gridpanda-range__input--min,
.gridpanda-range__input--max {
	flex: 1;
	min-width: 0;
	width: 100%;
	height: auto;
	min-height: 36px;
	padding: 6px 10px;
	border: 0 !important;
	border-radius: 0;
	background: transparent !important;
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
	font-size: 14px;
	color: var(--fx-input-color, #333);
	text-align: center;
	box-sizing: border-box;
	-moz-appearance: textfield;
	line-height: 1.4;
	box-shadow: none !important;
}

.gridpanda-range__input--min::-webkit-inner-spin-button,
.gridpanda-range__input--min::-webkit-outer-spin-button,
.gridpanda-range__input--max::-webkit-inner-spin-button,
.gridpanda-range__input--max::-webkit-outer-spin-button {
	-webkit-appearance: none;
	margin: 0;
}

.gridpanda-range__input--min:focus,
.gridpanda-range__input--max:focus {
	outline: none;
}

/* Separator dash between the two pill inputs */
.gridpanda-range__input-separator {
	flex-shrink: 0;
	padding: 0 2px;
	color: var(--gridpanda-text-muted, #9ca3af);
	font-size: 16px;
	font-weight: 500;
	text-align: center;
	user-select: none;
}

/* Range display text */
.gridpanda-range__display {
	color: var(--fx-range-display-color, inherit);
	font-size: var(--fx-range-display-font-size, inherit);
}

/* Hide the text display when number inputs are present — inputs are the display */
.gridpanda-range__wrapper:has(.gridpanda-range__input--min) .gridpanda-range__display {
	display: none;
}

/* ── JS-built dual-handle slider track ── */
.gridpanda-range__slider {
	position: relative;
	height: 28px; /* extra height gives room for the larger thumb */
	margin: 0 10px; /* side margin so thumb doesn't clip the card edge */
}

.gridpanda-range__track {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	left: 0;
	right: 0;
	height: var(--fx-range-track-height, 6px);
	background: var(--fx-range-track-bg, #e5e7eb);
	border-radius: 9999px;
	pointer-events: none;
}

.gridpanda-range__track-fill {
	position: absolute;
	height: 100%;
	background: var(--fx-range-track-active, var(--gridpanda-primary, #6366f1));
	border-radius: 9999px;
}

/* Two overlaid <input type="range"> elements that share the same track space */
.gridpanda-range__thumb {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	-webkit-appearance: none;
	appearance: none;
	background: transparent;
	pointer-events: none;
	outline: none;
	margin: 0;
	padding: 0;
}

.gridpanda-range__thumb--min { z-index: 1; }
.gridpanda-range__thumb--max { z-index: 2; }

/* Amazon/Facebook thumb: white circle with accent border + subtle shadow */
.gridpanda-range__thumb::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	width: var(--fx-range-thumb-size, 20px);
	height: var(--fx-range-thumb-size, 20px);
	border-radius: 50%;
	background: var(--fx-range-thumb-bg, #fff);
	border: 2px solid var(--gridpanda-primary, #6366f1);
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
	cursor: pointer;
	pointer-events: all;
	transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.gridpanda-range__thumb::-webkit-slider-thumb:hover,
.gridpanda-range__thumb:focus::-webkit-slider-thumb {
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2), 0 0 0 4px rgba(99, 102, 241, 0.15);
	transform: scale(1.1);
}

.gridpanda-range__thumb::-moz-range-thumb {
	width: var(--fx-range-thumb-size, 20px);
	height: var(--fx-range-thumb-size, 20px);
	border-radius: 50%;
	background: var(--fx-range-thumb-bg, #fff);
	border: 2px solid var(--gridpanda-primary, #6366f1);
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
	cursor: pointer;
	pointer-events: all;
}

/* =============================================
   Date Range Facet
   ============================================= */

/* Wrapper — was wrongly named .gridpanda-date-range in old CSS */
.gridpanda-date-range__wrapper {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

/* Three-column grid: [From group] [–] [To group] */
.gridpanda-date-range__inputs {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: end;   /* align separator baseline with the inputs */
	gap: 0 8px;
}

/* Each group stacks its label above its input */
.gridpanda-date-range__input-group {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.gridpanda-date-range__input-group label {
	font-size: 12px;
	font-weight: 500;
	color: var(--gridpanda-text-muted, #6b7280);
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

.gridpanda-date-range__input {
	width: 100%;
	padding: var(--fx-input-padding, 6px 10px);
	border: 1px solid var(--fx-input-border-color, var(--gridpanda-border));
	border-radius: var(--fx-input-border-radius, var(--gridpanda-radius));
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
	font-size: var(--fx-input-font-size, 14px);
	line-height: 1.5;
	min-height: 36px;
	height: auto;
	background: var(--fx-input-bg, #fff);
	color: var(--fx-input-color, #333);
	box-sizing: border-box;
	-webkit-appearance: none;
	appearance: none;
}

.gridpanda-date-range__input:focus {
	border-color: var(--fx-input-focus-border-color, var(--gridpanda-primary));
	outline: none !important;
	box-shadow: 0 0 0 2px rgba(0, 115, 170, 0.2) !important;
}

/* Separator "–" — was wrongly named .gridpanda-date-range__separator in old CSS */
.gridpanda-date-range__input-sep {
	display: flex;
	align-items: center;
	justify-content: center;
	padding-bottom: 8px;  /* align with input centre, not label top */
	color: var(--gridpanda-text-muted, #9ca3af);
	font-size: 14px;
	line-height: 1;
	user-select: none;
}

/* =============================================
   Search Facet
   ============================================= */

.gridpanda-search {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

/* ── Wrapper ── */
.gridpanda-search__wrapper {
	position: relative;
	display: flex;
	align-items: center;
}

/* ── Input ── */
.gridpanda-search__input {
	width: 100%;
	padding: var(--fx-search-padding, 6px 10px);
	border: 1px solid var(--fx-input-border-color, var(--gridpanda-border));
	border-radius: var(--fx-input-border-radius, var(--gridpanda-radius));
	font-size: var(--fx-input-font-size, 14px);
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
	line-height: 1.5;
	background: var(--fx-input-bg, #fff);
	color: var(--fx-input-color, #333);
	box-sizing: border-box;
	height: auto;
	min-height: 36px;
	-webkit-appearance: none;
	appearance: none;
}

/* Suppress browser's native ×/clear in WebKit */
.gridpanda-search__input::-webkit-search-cancel-button,
.gridpanda-search__input::-webkit-search-decoration {
	-webkit-appearance: none;
	appearance: none;
}

.gridpanda-search__input:focus {
	border-color: var(--fx-input-focus-border-color, var(--gridpanda-primary));
	outline: none !important;
	box-shadow: 0 0 0 2px rgba(0, 115, 170, 0.2) !important;
}

/* ── Icon ── */
.gridpanda-search__icon {
	position: absolute;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--fx-search-icon-color, #9ca3af);
	pointer-events: none;
	flex-shrink: 0;
}

.gridpanda-search__icon--left {
	left: 9px;
}

.gridpanda-search__icon--right {
	right: 9px;
}

/* Pad input so text doesn't overlap icon or clear button */
.gridpanda-search__wrapper--icon-left  .gridpanda-search__input { padding-left: 32px; }
.gridpanda-search__wrapper--icon-right .gridpanda-search__input { padding-right: 32px; }
.gridpanda-search__wrapper--has-clear  .gridpanda-search__input { padding-right: 29px; }

/* When both icon-right AND has-clear */
.gridpanda-search__wrapper--icon-right.gridpanda-search__wrapper--has-clear .gridpanda-search__input {
	padding-right: 51px;
}

/* ── Inline clear (×) button ── */
.gridpanda-search__clear {
	position: absolute;
	right: 7px;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 3px;
	border: none !important;
	background: transparent;
	box-shadow: none !important;
	color: var(--fx-search-clear-color, #9ca3af);
	cursor: pointer;
	border-radius: 50%;
	transition: color 0.15s, background 0.15s;
	line-height: 1;
	min-height: 0;
	height: auto;
	width: auto;
}

.gridpanda-search__clear:hover {
	color: var(--fx-search-clear-hover-color, #374151);
	background: var(--fx-search-clear-hover-bg, #f3f4f6);
}

/* When icon is on right, shift clear further left */
.gridpanda-search__wrapper--icon-right .gridpanda-search__clear {
	right: 32px;
}

/* ── Results (autocomplete) ── */
.gridpanda-search__results {
	max-height: 250px;
	overflow-y: auto;
}

/* =============================================
   Button Group Facet
   ============================================= */

.gridpanda-button-group__wrapper {
	display: flex;
	flex-wrap: wrap;
	gap: var(--fx-btn-gap, 8px);
}

/* Hide the underlying checkbox/radio input — visual state is on the label */
.gridpanda-button-group__input {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
	opacity: 0;
	pointer-events: none;
}

.gridpanda-button-group__button {
	/* Spacing */
	padding-top: var(--fx-btn-padding-top, var(--fx-btn-padding, 6px));
	padding-right: var(--fx-btn-padding-right, var(--fx-btn-padding, 13px));
	padding-bottom: var(--fx-btn-padding-bottom, var(--fx-btn-padding, 6px));
	padding-left: var(--fx-btn-padding-left, var(--fx-btn-padding, 13px));
	/* Border */
	border-style: var(--fx-btn-border-style, solid);
	border-color: var(--fx-btn-border-color, var(--gridpanda-border));
	border-top-width: var(--fx-btn-border-width-top, var(--fx-btn-border-width, 1px));
	border-right-width: var(--fx-btn-border-width-right, var(--fx-btn-border-width, 1px));
	border-bottom-width: var(--fx-btn-border-width-bottom, var(--fx-btn-border-width, 1px));
	border-left-width: var(--fx-btn-border-width-left, var(--fx-btn-border-width, 1px));
	border-top-left-radius: var(--fx-btn-border-radius-tl, var(--fx-btn-border-radius, var(--gridpanda-radius)));
	border-top-right-radius: var(--fx-btn-border-radius-tr, var(--fx-btn-border-radius, var(--gridpanda-radius)));
	border-bottom-right-radius: var(--fx-btn-border-radius-br, var(--fx-btn-border-radius, var(--gridpanda-radius)));
	border-bottom-left-radius: var(--fx-btn-border-radius-bl, var(--fx-btn-border-radius, var(--gridpanda-radius)));
	/* Background & Color */
	background: var(--fx-btn-bg, #fff);
	color: var(--fx-btn-color, var(--gridpanda-text));
	/* Typography */
	font-family: var(--fx-btn-font-family, inherit);
	font-size: var(--fx-btn-font-size, 14px);
	font-weight: var(--fx-btn-font-weight, 400);
	line-height: var(--fx-btn-line-height, 20px);
	letter-spacing: var(--fx-btn-letter-spacing, 0px);
	text-transform: var(--fx-btn-text-transform, none);
	text-decoration: var(--fx-btn-text-decoration, none);
	/* Effects */
	box-shadow: var(--fx-btn-box-shadow, none);
	transition: var(--fx-btn-transition, all 0.2s ease);
	cursor: pointer;
}

.gridpanda-button-group__button:hover {
	border-color: var(--fx-btn-hover-border, var(--gridpanda-primary));
	color: var(--fx-btn-hover-color, var(--gridpanda-primary));
	background: var(--fx-btn-hover-bg, transparent);
	box-shadow: var(--fx-btn-hover-box-shadow, none);
}

.gridpanda-button-group__button--active {
	background: var(--fx-btn-active-bg, var(--gridpanda-primary));
	color: var(--fx-btn-active-color, #fff);
	border-color: var(--fx-btn-active-border, var(--gridpanda-primary));
	box-shadow: var(--fx-btn-active-box-shadow, none);
}

/* Disabled state */
.gridpanda-button-group__button--disabled {
	opacity: 0.4;
	cursor: not-allowed;
	pointer-events: none;
}

/* Hidden (show-more) */
.gridpanda-button-group__button--hidden {
	display: none;
}

/* "All" button subtle distinction */
.gridpanda-button-group__button--all {
	font-style: italic;
}

/* Count badge */
.gridpanda-button-group__count {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	margin-left: 0.35em;
	font-size: 0.75em;
	font-weight: 600;
	opacity: 0.65;
}

/* Size modifiers */
.gridpanda-button-group--sm .gridpanda-button-group__button {
	padding: var(--fx-btn-padding-sm, 3px 9px);
	font-size: 12px;
}

.gridpanda-button-group--lg .gridpanda-button-group__button {
	padding: var(--fx-btn-padding-lg, 10px 19px);
	font-size: 15px;
}

/* Scroll layout */
.gridpanda-button-group__wrapper.gridpanda-button-group--scroll {
	flex-wrap: nowrap;
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: thin;
	padding-bottom: 4px;
}

/* =============================================
   Color Swatch Facet
   ============================================= */

/* ── List container ── */
.gridpanda-color__list {
	list-style: none;
	margin: 0;
	padding: 0;
}

/* Grid layout: swatches wrap in a flex row */
.gridpanda-color__list--grid {
	display: flex;
	flex-wrap: wrap;
	column-gap: var(--fx-swatch-gap-x, var(--fx-swatch-gap, 6px));
	row-gap: var(--fx-swatch-gap-y, var(--fx-swatch-gap, 6px));
}

/* List layout: one row per colour with swatch + name + count */
.gridpanda-color__list--list {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.gridpanda-color__list--list .gridpanda-color__item {
	width: 100%;
}

.gridpanda-color__list--list .gridpanda-color__label {
	display: flex;
	align-items: center;
	gap: 8px;
	width: 100%;
	padding: 3px 6px;
	border-radius: var(--fx-radius, 4px);
	transition: background 0.15s ease;
}

.gridpanda-color__list--list .gridpanda-color__label:hover {
	background: var(--fx-item-hover-bg, rgba(0, 0, 0, 0.04));
}

.gridpanda-color__list--list .gridpanda-color__item--selected .gridpanda-color__label,
.gridpanda-color__list--list .gridpanda-color__item:has(.gridpanda-color__input:checked) .gridpanda-color__label {
	background: var(--fx-item-active-bg, rgba(99, 102, 241, 0.08));
}

/* ── Label wrapper (used in both layouts) ── */
.gridpanda-color__label {
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	flex-direction: column;
	gap: 4px;
	user-select: none;
}

/* Grid layout: column-direction (swatch on top, name below) */
.gridpanda-color__list--grid .gridpanda-color__label {
	flex-direction: column;
}

/* ── Hidden checkbox ── */
.gridpanda-color__input {
	position: absolute;
	opacity: 0;
	pointer-events: none;
	width: 0;
	height: 0;
}

/* ── Swatch ── */
.gridpanda-color__swatch {
	width: var(--fx-swatch-size, 36px);
	height: var(--fx-swatch-size, 36px);
	border: var(--fx-swatch-border-width, 2px) solid var(--fx-swatch-border-color, var(--gridpanda-border, #e5e7eb));
	cursor: pointer;
	transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
	position: relative;
	flex-shrink: 0;
	display: block;
}

/* Shape variants */
.gridpanda-color__swatch--circle {
	border-radius: 50%;
}

.gridpanda-color__swatch--square {
	border-radius: 0;
}

.gridpanda-color__swatch--rounded {
	/* --fx-swatch-border-radius is the panel alias; falls back to --fx-swatch-radius */
	border-radius: var(--fx-swatch-border-radius, var(--fx-swatch-radius, 6px));
}

/* Hover */
.gridpanda-color__label:hover .gridpanda-color__swatch {
	transform: scale(var(--fx-swatch-hover-scale, 1.08));
	border-color: var(--fx-swatch-hover-border, var(--gridpanda-primary, #6366f1));
}

/* ── Indicator element (hidden by default, shown per indicator type) ── */
.gridpanda-color__indicator {
	display: none;
}

/* ════════════════════════════════════════════════════════════════════════
   SELECTION INDICATORS  –  activated via :checked sibling combinator
   ════════════════════════════════════════════════════════════════════════ */

/* ── 1. CHECKMARK ── */
.gridpanda-color--indicator-checkmark .gridpanda-color__input:checked + .gridpanda-color__swatch {
	border-color: var(--fx-selection-color, var(--gridpanda-primary, #6366f1));
}

.gridpanda-color--indicator-checkmark .gridpanda-color__input:checked + .gridpanda-color__swatch .gridpanda-color__indicator {
	display: flex;
	align-items: center;
	justify-content: center;
	position: absolute;
	inset: 0;
	border-radius: inherit;
	background: rgba(0, 0, 0, 0.35);
}

.gridpanda-color--indicator-checkmark .gridpanda-color__input:checked + .gridpanda-color__swatch .gridpanda-color__indicator::after {
	content: '';
	display: block;
	width: 35%;
	height: 55%;
	border-right: 2.5px solid var(--fx-selection-color, #fff);
	border-bottom: 2.5px solid var(--fx-selection-color, #fff);
	transform: rotate(45deg) translate(-5%, -5%);
}

/* ── 2. RING (outer glow) ── */
.gridpanda-color--indicator-ring .gridpanda-color__input:checked + .gridpanda-color__swatch {
	border-color: var(--fx-selection-color, var(--gridpanda-primary, #6366f1));
	box-shadow: 0 0 0 3px var(--fx-selection-color, var(--gridpanda-primary, #6366f1)), 0 0 0 5px rgba(0, 0, 0, 0.08);
}

/* ── 3. BORDER (thick coloured border) ── */
.gridpanda-color--indicator-border .gridpanda-color__input:checked + .gridpanda-color__swatch {
	border-width: 3px;
	border-color: var(--fx-selection-color, var(--gridpanda-primary, #6366f1));
}

/* ── 4. DOT (small badge in bottom-right) ── */
.gridpanda-color--indicator-dot .gridpanda-color__input:checked + .gridpanda-color__swatch {
	border-color: var(--fx-selection-color, var(--gridpanda-primary, #6366f1));
}

.gridpanda-color--indicator-dot .gridpanda-color__input:checked + .gridpanda-color__swatch .gridpanda-color__indicator {
	display: block;
	position: absolute;
	bottom: -2px;
	right: -2px;
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: var(--fx-selection-color, var(--gridpanda-primary, #6366f1));
	border: 2px solid #fff;
	z-index: 2;
}

/* ── Fallback: no indicator class on container (legacy) ── */
.gridpanda-color:not([class*="indicator-"]) .gridpanda-color__input:checked + .gridpanda-color__swatch {
	border-color: var(--fx-swatch-active-border, var(--gridpanda-primary, #6366f1));
	box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.25);
}

.gridpanda-color:not([class*="indicator-"]) .gridpanda-color__input:checked + .gridpanda-color__swatch::after {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	width: 7px;
	height: 7px;
	background: #fff;
	border-radius: 50%;
	transform: translate(-50%, -50%);
	box-shadow: 0 0 3px rgba(0, 0, 0, 0.45);
}

/* ── Focus-visible for keyboard navigation ── */
.gridpanda-color__input:focus-visible + .gridpanda-color__swatch {
	outline: 2px solid var(--fx-selection-color, var(--gridpanda-primary, #6366f1));
	outline-offset: 2px;
}

/* ── Selected item label styling ── */
.gridpanda-color__item:has(.gridpanda-color__input:checked) .gridpanda-color__name {
	font-weight: 600;
	color: var(--gridpanda-text, #333);
}

/* Empty / out-of-stock swatches: visually struck through */
.gridpanda-color__swatch--empty {
	opacity: 0.35;
	position: relative;
}

.gridpanda-color__swatch--empty::before {
	content: '';
	position: absolute;
	inset: 0;
	background: repeating-linear-gradient(
		-45deg,
		transparent,
		transparent 3px,
		rgba(0, 0, 0, 0.15) 3px,
		rgba(0, 0, 0, 0.15) 4px
	);
	border-radius: inherit;
}

/* ── Colour name ── */
.gridpanda-color__name {
	font-size: 12px;
	color: var(--gridpanda-text-muted, #9ca3af);
	text-align: center;
	line-height: 1.2;
	white-space: nowrap;
}

/* In grid layout, constrain name width to swatch width so long names don't stretch the cell */
.gridpanda-color__list--grid .gridpanda-color__name {
	max-width: var(--fx-swatch-size, 36px);
	overflow: hidden;
	text-overflow: ellipsis;
}

/* In list layout, name sits beside the swatch and aligns left */
.gridpanda-color__list--list .gridpanda-color__name {
	font-size: 14px;
	color: var(--fx-text, inherit);
	text-align: left;
	white-space: normal;
	flex: 1;
}

/* ── Count badge ── */
.gridpanda-color__count {
	font-size: 12px;
	color: var(--gridpanda-text-muted, #9ca3af);
	margin-left: auto;
}

/* In grid layout, count sits below the name centred under the swatch */
.gridpanda-color__list--grid .gridpanda-color__count {
	margin-left: 0;
	text-align: center;
}

/* ── Clear button ── */
.gridpanda-color__clear {
	margin-top: 8px;
}

/* =============================================
   Rating Stars Facet
   ============================================= */

.gridpanda-rating__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 2px;
}

/* ── Inline (single-row) layout ─────────────────────────────── */
.gridpanda-rating__list--inline {
	flex-direction: row;
	flex-wrap: wrap;
	gap: 4px;
}

.gridpanda-rating__list--inline .gridpanda-rating__label {
	padding: 5px 4px;
	flex-direction: column;
	gap: 2px;
}

.gridpanda-rating__list--inline .gridpanda-rating__text,
.gridpanda-rating__list--inline .gridpanda-rating__count {
	display: none;
}

.gridpanda-rating__item--disabled {
	opacity: 0.45;
	pointer-events: none;
}

.gridpanda-rating__label {
	display: flex;
	align-items: center;
	gap: 6px;
	cursor: pointer;
	padding: 4px 6px;
	border-radius: var(--fx-radius, 4px);
	transition: background 0.15s ease;
	user-select: none;
}

.gridpanda-rating__label:hover {
	background: var(--fx-item-hover-bg, rgba(0, 0, 0, 0.04));
}

/* Active state via :checked sibling selector (works regardless of class state). */
.gridpanda-rating__input:checked + .gridpanda-rating__label,
.gridpanda-rating__item--active .gridpanda-rating__label {
	background: var(--fx-item-active-bg, rgba(99, 102, 241, 0.12));
	border-left: var(--fx-item-active-border-width, 3px) solid var(--fx-item-active-border-color, #6366f1);
	font-weight: 600;
}

/* Visually hide the rating radio — interaction is via the <label for="..."> sibling.
   The input is NOT inside the label's flex container so layout is unaffected.
   Specificity [0,2,0] matches .gridpanda-facet__input[type="radio"]:not(...) at [0,2,1]
   and wins by source order (this rule comes later in the file).
   clip-path: inset(50%) clips to zero-area regardless of position type. */
.gridpanda-rating__list .gridpanda-rating__input {
	-webkit-appearance: none;
	appearance: none;
	clip-path: inset(50%);
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	white-space: nowrap;
	margin: 0;
	padding: 0;
	border: 0;
	opacity: 0;
	pointer-events: none;
}

.gridpanda-rating__stars {
	display: flex;
	gap: var(--fx-star-gap, 2px);
	line-height: 1;
}

.gridpanda-rating__star {
	font-size: var(--fx-star-size, 16px);
	/* --fx-star-color is the panel alias for the empty-star colour */
	color: var(--fx-star-color, var(--fx-star-empty-color, #d1d5db));
	transition: color 0.15s ease;
}

.gridpanda-rating__star--filled {
	color: var(--fx-star-filled-color, #f59e0b);
}

.gridpanda-rating__label:hover .gridpanda-rating__star--filled {
	color: var(--fx-star-hover-color, #d97706);
}

.gridpanda-rating__input:checked + .gridpanda-rating__label .gridpanda-rating__star--filled,
.gridpanda-rating__item--active .gridpanda-rating__star--filled {
	color: var(--fx-star-active-color, #f59e0b);
}

/* Active state text emphasis */
.gridpanda-rating__input:checked + .gridpanda-rating__label .gridpanda-rating__text,
.gridpanda-rating__item--active .gridpanda-rating__text {
	color: var(--fx-text, inherit);
	font-weight: inherit;
}

.gridpanda-rating__input:checked + .gridpanda-rating__label .gridpanda-rating__count,
.gridpanda-rating__item--active .gridpanda-rating__count {
	color: var(--fx-text, #6b7280);
}

.gridpanda-rating__text {
	font-size: 14px;
	color: var(--fx-text, inherit);
	white-space: nowrap;
}

.gridpanda-rating__count {
	font-size: 12px;
	color: var(--gridpanda-text-muted, #9ca3af);
	margin-left: auto;
}

.gridpanda-rating__clear {
	margin-top: 8px;
}

/* =============================================
   Hierarchy Tree Facet
   ============================================= */

/* ── List reset (all levels) ── */
.gridpanda-hierarchy__list {
	list-style: none;
	margin: 0;
	padding: 0;
}

/* Indent nested levels using a CSS custom property.
   Default 2rem (32px) = toggle-column (24px) + 8px extra, so child checkboxes
   sit visibly to the right of the parent's label column. Override via
   --fx-hierarchy-indent in your theme to suit your design. */
.gridpanda-hierarchy__list:not(.gridpanda-hierarchy__list--level-0) {
	padding-left: var(--fx-hierarchy-indent, 32px);
}

/* ── List item ── */
.gridpanda-hierarchy__item {
	margin: 0;
	padding: 0;
}

/* ── Row: toggle + label on one flex line ── */
.gridpanda-hierarchy__row {
	display: flex;
	align-items: center;
	gap: 4px;
	padding: 2px 0;
}

/* ── Expand / collapse toggle button ── */
.gridpanda-hierarchy__toggle {
	flex-shrink: 0;
	width: 20px;
	height: 20px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: none;
	border: 1px solid var(--gridpanda-border, #e5e7eb);
	border-radius: 3px;
	cursor: pointer;
	font-size: 13px;
	line-height: 1;
	color: var(--gridpanda-text-muted, #6b7280);
	padding: 0;
	transition: background 0.15s ease, color 0.15s ease;
}

.gridpanda-hierarchy__toggle:hover {
	background: var(--fx-item-hover-bg, rgba(0, 0, 0, 0.05));
	color: var(--fx-text, inherit);
}

/* Spacer keeps label alignment for leaf nodes (same width as toggle) */
.gridpanda-hierarchy__toggle-spacer {
	flex-shrink: 0;
	width: 20px;
	height: 20px;
	display: inline-block;
}

/* ── Label row ── */
.gridpanda-hierarchy__label {
	display: flex;
	align-items: center;
	gap: 6px;
	cursor: pointer;
	flex: 1;
	padding: 3px 5px;
	border-radius: var(--fx-radius, 4px);
	transition: background 0.15s ease;
	user-select: none;
	font-size: 14px;
}

.gridpanda-hierarchy__label:hover {
	background: var(--fx-item-hover-bg, rgba(0, 0, 0, 0.04));
}

.gridpanda-hierarchy__item--selected > .gridpanda-hierarchy__row > .gridpanda-hierarchy__label {
	background: var(--fx-item-active-bg, rgba(99, 102, 241, 0.08));
	font-weight: 500;
}

/* ── Hidden checkbox (interaction via label) ── */
/* Use .gridpanda-hierarchy__row descendant combinator to get specificity 0-2-0,
   matching .gridpanda-facet__input[type="checkbox"] and winning by source order. */
.gridpanda-hierarchy__row .gridpanda-hierarchy__input {
	position: absolute;
	opacity: 0;
	pointer-events: none;
	width: 0 !important;
	height: 0 !important;
	border: 0 !important;
	background: transparent !important;
	padding: 0;
	margin: 0;
}

/* ── Custom checkbox indicator rendered via ::before on the label ── */
.gridpanda-hierarchy__label::before {
	content: '';
	flex-shrink: 0;
	width: 14px;
	height: 14px;
	border: 1.5px solid var(--gridpanda-border, #d1d5db);
	border-radius: 3px;
	background: #fff;
	transition: border-color 0.15s ease, background 0.15s ease;
	box-sizing: border-box;
}

/* Checked state: filled primary colour with a white tick */
.gridpanda-hierarchy__item--selected > .gridpanda-hierarchy__row > .gridpanda-hierarchy__label::before {
	background: var(--gridpanda-primary, #6366f1);
	border-color: var(--gridpanda-primary, #6366f1);
	background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 10 8' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 4l3 3 5-6' stroke='%23fff' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
	background-size: 10px 8px;
}

/* Hover: tint the border */
.gridpanda-hierarchy__label:hover::before {
	border-color: var(--gridpanda-primary, #6366f1);
}

/* ── Term name text ── */
.gridpanda-hierarchy__text {
	flex: 1;
	color: var(--fx-text, inherit);
	line-height: 1.3;
}

/* ── Count badge ── */
.gridpanda-hierarchy__count {
	flex-shrink: 0;
	font-size: 12px;
	color: var(--gridpanda-text-muted, #9ca3af);
}

/* ── Clear button ── */
.gridpanda-hierarchy__clear {
	margin-top: 8px;
}

/* ── Depth-level visual hints (optional, relies on CSS var) ── */
/* Root level items can have a slightly heavier font weight */
.gridpanda-hierarchy__list--level-0 > .gridpanda-hierarchy__item > .gridpanda-hierarchy__row > .gridpanda-hierarchy__label {
	font-weight: 500;
}

/* Deeper items are visually lighter */
.gridpanda-hierarchy__list--level-1 > .gridpanda-hierarchy__item > .gridpanda-hierarchy__row > .gridpanda-hierarchy__label,
.gridpanda-hierarchy__list--level-2 > .gridpanda-hierarchy__item > .gridpanda-hierarchy__row > .gridpanda-hierarchy__label {
	font-weight: 400;
	font-size: 14px;
}

/* =============================================
   Toggle Switch Facet
   ============================================= */

/* Custom properties — override on the wrapper or globally */
.gridpanda-toggle__wrapper {
	--fx-toggle-width:         44px;
	--fx-toggle-height:        24px;
	--fx-toggle-bg:            #d1d5db;
	--fx-toggle-active-bg:     var(--gridpanda-primary, #f97316);
	--fx-toggle-border-radius: calc(var(--fx-toggle-height) / 2);
	--fx-toggle-knob-bg:       #fff;
	--fx-toggle-knob-shadow:   0 1px 4px rgba(0, 0, 0, 0.25);
	/* flex column so label and clear button stack vertically */
	display: flex;
	flex-direction: column;
	align-items: flex-start;
}

/* ── Real checkbox — visually hidden but keyboard/screen-reader accessible.
   Specificity [0,2,0] beats .gridpanda-facet__input[type="checkbox"]:not(...) at [0,2,1]
   by source order (this rule appears later in the file). ── */
.gridpanda-toggle__label .gridpanda-toggle__input {
	position: absolute;
	opacity: 0;
	width: 0;
	height: 0;
	pointer-events: none;
}

/* ── Label row ── */
.gridpanda-toggle__label {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	cursor: pointer;
	user-select: none;
	font-size: 14px;
	color: var(--gridpanda-text, #374151);
}

/* ── Track ── */
.gridpanda-toggle__track {
	position: relative;
	display: inline-flex;
	align-items: center;
	flex-shrink: 0;
	width: var(--fx-toggle-width);
	height: var(--fx-toggle-height);
	background: var(--fx-toggle-bg);
	border-radius: var(--fx-toggle-border-radius);
	transition: background 0.22s ease;
}

/* ── Knob ── */
.gridpanda-toggle__knob {
	position: absolute;
	top: 50%;
	left: 2px;
	width: calc(var(--fx-toggle-height) - 4px);
	height: calc(var(--fx-toggle-height) - 4px);
	background: var(--fx-toggle-knob-bg);
	border-radius: 50%;
	box-shadow: var(--fx-toggle-knob-shadow);
	transform: translateY(-50%);
	transition: left 0.22s ease;
	pointer-events: none;
}

/* ── Active state via :checked sibling selector — zero JS required ── */
.gridpanda-toggle__input:checked + .gridpanda-toggle__track {
	background: var(--fx-toggle-active-bg);
}

.gridpanda-toggle__input:checked + .gridpanda-toggle__track .gridpanda-toggle__knob {
	left: calc(var(--fx-toggle-width) - var(--fx-toggle-height) + 2px);
}

/* ── Focus ring (keyboard nav) ── */
.gridpanda-toggle__input:focus-visible + .gridpanda-toggle__track {
	outline: 2px solid var(--fx-toggle-active-bg);
	outline-offset: 2px;
}

/* ── Hover state ── */
.gridpanda-toggle__label:hover .gridpanda-toggle__track {
	background: var(--fx-toggle-hover-bg, var(--fx-toggle-bg));
}

.gridpanda-toggle__label:hover .gridpanda-toggle__knob {
	background: var(--fx-toggle-hover-knob, var(--fx-toggle-knob-bg));
}

/* ── Text label ── */
.gridpanda-toggle__text {
	font-size: 14px;
	color: var(--gridpanda-text, #374151);
	line-height: 1.4;
}

/* ── Count badge ── */
.gridpanda-toggle__count {
	font-size: 0.75em;
	color: var(--gridpanda-text-light, #6b7280);
	margin-left: 4px;
}

/* ── Clear button ── */
.gridpanda-toggle__clear {
	margin-top: 8px;
}

/* Backward-compat alias — old CSS targeted .gridpanda-toggle__switch */
.gridpanda-toggle__switch {
	display: none; /* hidden; new template uses __track */
}

/* =============================================
   Pagination Structure — additional selectors
   ============================================= */

.gridpanda-pagination__item--prev .gridpanda-pagination__link,
.gridpanda-pagination__item--next .gridpanda-pagination__link {
	font-weight: 600;
}

.gridpanda-pagination__page-info {
	font-size: 0.85em;
	color: var(--gridpanda-text-light, #6b7280);
	margin: 0 8px;
}

/* =============================================
   Card Grid Layout (Multi-Column)
   ============================================= */

.gridpanda-card--grid {
	overflow: hidden;
}

.gridpanda-card__row {
	display: grid;
	gap: 16px;
}

.gridpanda-card__col {
	min-width: 0; /* prevent grid blowout */
}

.gridpanda-card__block-wrapper {
	/* default visible */
}

/* Responsive visibility */
@media (max-width: 768px) {
	.gridpanda-card__row {
		grid-template-columns: var(--fx-row-cols-tablet, 1fr) !important;
	}

	.gridpanda-hide-on-tablet {
		display: none !important;
	}
}

@media (max-width: 480px) {
	.gridpanda-card__row {
		grid-template-columns: var(--fx-row-cols-mobile, 1fr) !important;
	}

	.gridpanda-hide-on-mobile {
		display: none !important;
	}
}

/* Desktop hide class — always applied */
@media (min-width: 769px) {
	.gridpanda-hide-on-desktop {
		display: none !important;
	}
}

/* =============================================
   Container Layout (Elementor-style)
   ============================================= */

/* Custom card templates: the card builder controls all visual styling via
   inline styles on containers/blocks — reset base .gridpanda-card defaults
   so border, shadow, and hover don't leak through when not configured. */
.gridpanda-card--container {
	border: none;
	box-shadow: none;
	background: transparent;
	overflow: hidden;
}
.gridpanda-card--container:hover {
	box-shadow: none;
	transform: none;
}

.gridpanda-container {
	display: flex;
	position: relative;
	min-width: 0; /* prevent flex blowout */
}

.gridpanda-container-wrapper {
	min-width: 0;
}

/* On tablet, stack row containers */
@media (max-width: 768px) {
	.gridpanda-container[style*="flex-direction:row"] {
		flex-direction: column !important;
	}

	.gridpanda-container-wrapper {
		flex: 1 1 auto !important;
	}
}

/* On mobile, ensure everything stacks */
@media (max-width: 480px) {
	.gridpanda-container[style*="flex-direction:row"] {
		flex-direction: column !important;
	}

	.gridpanda-container-wrapper {
		flex: 1 1 auto !important;
	}
}

/* =============================================
   Layout Builder — Composed Grid Layouts
   ============================================= */

.gridpanda-layout {
	display: flex;
	min-width: 0; /* prevent flex blowout */
	box-sizing: border-box;
}

.gridpanda-layout--row {
	flex-direction: row;
}

.gridpanda-layout--column {
	flex-direction: column;
}

/* Grid element wrapper */
.gridpanda-grid-element {
	min-width: 0;
	max-width: 100%;
	box-sizing: border-box;
}

/* Facet element wrapper */
.gridpanda-facet-element {
	min-width: 0;
	max-width: 100%;
	box-sizing: border-box;
	overflow: visible; /* allow dropdowns / tooltips to escape column bounds */
}

/* Facet element content area */
.gridpanda-facet-element__content {
	min-width: 0;
	max-width: 100%;
}

/* Shared base styles for both collapsible toggle and static header */
.gridpanda-facet-element__toggle,
.gridpanda-facet-element__header {
	display: flex;
	align-items: center;
	width: 100%;
	box-sizing: border-box; /* padding + border must not add to 100% width */
	padding: var(--fx-header-padding, 10px 12px);
	border: none;
	border-radius: var(--gridpanda-radius);
	font-size: var(--fx-header-font-size, 14px);
	font-weight: 600;
	color: var(--fx-header-color, var(--gridpanda-text));
	background: var(--fx-header-bg, none);
	margin-bottom: 8px;
}

/* Non-collapsible facet header (static — no toggle, no arrow) */
.gridpanda-facet-element__header {
	justify-content: flex-start;
}

/* Collapsible facet toggle button */
.gridpanda-facet-element__toggle {
	justify-content: space-between;
	cursor: pointer;
	transition: background-color 0.2s ease;
}

.gridpanda-facet-element__toggle:hover {
	background-color: var(--gridpanda-secondary);
}

/* Label + sub-label column layout (inside both toggle button and static header) */
.gridpanda-facet-element__label-wrap {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 2px;
}

/* Sub-label: smaller, muted secondary line under the main label */
.gridpanda-facet-element__sub-label {
	font-size: calc(var(--fx-header-font-size, 14px) * 0.8);
	font-weight: 400;
	color: var(--fx-header-color, var(--gridpanda-muted, #6b7280));
	opacity: 0.75;
	line-height: 1.3;
}

.gridpanda-facet-element__arrow {
	display: inline-block;
	width: 0;
	height: 0;
	border-left: 5px solid transparent;
	border-right: 5px solid transparent;
	border-top: 5px solid currentColor;
	transition: transform 0.2s ease;
}

.gridpanda-facet-element--collapsed .gridpanda-facet-element__arrow {
	transform: rotate(-90deg);
}

.gridpanda-facet-element--collapsed .gridpanda-facet-element__content {
	display: none;
}

/* Responsive: hide per breakpoint */
.gridpanda-hide-desktop {
	/* handled via JS on desktop */
}

@media (max-width: 1024px) {
	/* Stack row layouts on tablet */
	.gridpanda-layout--row {
		flex-wrap: wrap;
	}

	.gridpanda-hide-tablet {
		display: none !important;
	}
}

@media (max-width: 767px) {
	/* Stack everything on mobile */
	.gridpanda-layout--row {
		flex-direction: column !important;
	}

	.gridpanda-hide-mobile {
		display: none !important;
	}
}

/* ═══ Static Content Elements ═══ */

.gridpanda-text-element {
	line-height: 1.6;
}

.gridpanda-heading-element {
	margin: 0;
	line-height: 1.3;
}

.gridpanda-button-element {
	display: inline-flex;
}

.gridpanda-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 10px 20px;
	border-radius: 6px;
	font-size: 14px;
	font-weight: 600;
	line-height: 1;
	text-decoration: none;
	cursor: pointer;
	transition: background-color 0.2s, color 0.2s, border-color 0.2s, box-shadow 0.2s;
}

.gridpanda-button--primary {
	background-color: #2563eb;
	color: #fff;
	border: 2px solid #2563eb;
}
.gridpanda-button--primary:hover {
	background-color: #1d4ed8;
	border-color: #1d4ed8;
}

.gridpanda-button--outline {
	background-color: transparent;
	color: #2563eb;
	border: 2px solid #2563eb;
}
.gridpanda-button--outline:hover {
	background-color: #eff6ff;
}

.gridpanda-button--ghost {
	background-color: transparent;
	color: #374151;
	border: 2px solid transparent;
}
.gridpanda-button--ghost:hover {
	background-color: #f3f4f6;
}

.gridpanda-image-element {
	line-height: 0;
}
.gridpanda-image-element__img {
	display: block;
	max-width: 100%;
	height: auto;
	border-radius: inherit;
}
.gridpanda-image-element--empty {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 100px;
	background-color: #f3f4f6;
	border: 1px dashed #d1d5db;
	border-radius: 4px;
	color: #9ca3af;
	font-size: 13px;
}

.gridpanda-divider-element {
	width: 100%;
}

/* Scroll Anchor widget — invisible marker for JS scroll-to logic. */
.gridpanda-scroll-anchor {
	height: 0;
	overflow: hidden;
	margin: 0;
	padding: 0;
	border: none;
	line-height: 0;
	font-size: 0;
}

.gridpanda-icon-element {
	display: inline-flex;
	align-items: center;
	justify-content: center;
}
.gridpanda-icon-element__link {
	display: inline-flex;
	text-decoration: none;
	color: inherit;
}

.gridpanda-html-element {
	/* No default styles — user controls everything */
}

/* ═══ Collapsible Containers ═══ */

/* ══ Collapsible containers — thin-strip accordion pattern ══
 * Collapsed: narrow strip (default 15px, adjustable via --collapsed-width)
 *   with a small centered arrow icon.
 * Expanded: full width/height with content + toggle at edge.
 * Mode: inline (pushes content) or overlay (slides over). User decides.
 */

.gridpanda-collapsible {
	position: relative;
	transition: width 0.3s ease, height 0.3s ease, min-width 0.3s ease, max-width 0.3s ease;
	background: #fff;
}

/* ── Content area ── */
.gridpanda-collapsible__content {
	transition: opacity 0.25s ease;
	overflow: auto;
}

/* ── Toggle strip — the thin clickable edge bar ── */
.gridpanda-collapsible__toggle {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	margin: 0;
	background: #f0f0f1;
	border: none;
	cursor: pointer;
	color: #787c82;
	transition: background-color 0.15s, color 0.15s;
	flex-shrink: 0;
}
.gridpanda-collapsible__toggle:hover {
	background-color: #dcdcde;
	color: #2271b1;
}

/* Toggle icon (dashicon — e.g. filter funnel) */
.gridpanda-collapsible__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-size: 16px;
	width: 16px;
	height: 16px;
	line-height: 1;
	flex-shrink: 0;
}

/* Label — visible only when expanded, hidden in collapsed strip */
.gridpanda-collapsible__label {
	white-space: nowrap;
	overflow: hidden;
	font-size: 12px;
	font-weight: 600;
	color: #1d2327;
	transition: opacity 0.2s ease;
}


/* ══════════════════════════════════════════════
   Left / Right sidebars — shared base styles
   ══════════════════════════════════════════════ */
.gridpanda-collapsible--left,
.gridpanda-collapsible--right {
	position: relative;
	z-index: 50;
}

/* Toggle strip shared — icon pinned to top, vertical layout */
.gridpanda-collapsible--left .gridpanda-collapsible__toggle,
.gridpanda-collapsible--right .gridpanda-collapsible__toggle {
	flex-direction: column;
	align-items: center;
	justify-content: flex-start;
	padding-top: 8px;
	flex-shrink: 0;
}

/* Hide label in left/right toggle strip (too narrow) */
.gridpanda-collapsible--left .gridpanda-collapsible__label,
.gridpanda-collapsible--right .gridpanda-collapsible__label {
	display: none;
}

/* ─── OVERLAY mode: fixed-strip, content absolute ─── */
.gridpanda-collapsible--left.gridpanda-collapsible--overlay,
.gridpanda-collapsible--right.gridpanda-collapsible--overlay {
	width: var(--collapsed-width, 15px);
	min-width: var(--collapsed-width, 15px);
	max-width: var(--collapsed-width, 15px);
	z-index: 100;
}

/* Overlay toggle fills the fixed container */
.gridpanda-collapsible--left.gridpanda-collapsible--overlay .gridpanda-collapsible__toggle,
.gridpanda-collapsible--right.gridpanda-collapsible--overlay .gridpanda-collapsible__toggle {
	width: 100%;
	height: 100%;
}
.gridpanda-collapsible--left.gridpanda-collapsible--overlay .gridpanda-collapsible__toggle {
	border-right: 1px solid #dcdcde;
}
.gridpanda-collapsible--right.gridpanda-collapsible--overlay .gridpanda-collapsible__toggle {
	border-left: 1px solid #dcdcde;
}

/* Overlay content — absolute panel */
.gridpanda-collapsible--left.gridpanda-collapsible--overlay .gridpanda-collapsible__content {
	position: absolute;
	top: 0;
	left: 100%;
	width: var(--expanded-width, 280px);
	height: 100%;
	background: #fff;
	box-shadow: 4px 0 16px rgba(0, 0, 0, 0.1);
	z-index: 100;
	overflow: auto;
	transition: opacity 0.3s ease, visibility 0.3s ease;
}
.gridpanda-collapsible--right.gridpanda-collapsible--overlay .gridpanda-collapsible__content {
	position: absolute;
	top: 0;
	right: 100%;
	width: var(--expanded-width, 280px);
	height: 100%;
	background: #fff;
	box-shadow: -4px 0 16px rgba(0, 0, 0, 0.1);
	z-index: 100;
	overflow: auto;
	transition: opacity 0.3s ease, visibility 0.3s ease;
}

/* Overlay collapsed — hide content */
.gridpanda-collapsible--left.gridpanda-collapsible--overlay.gridpanda-collapsible--collapsed .gridpanda-collapsible__content,
.gridpanda-collapsible--right.gridpanda-collapsible--overlay.gridpanda-collapsible--collapsed .gridpanda-collapsible__content {
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
}

/* ─── PUSH mode (no --overlay): container width transitions ─── */
.gridpanda-collapsible--left:not(.gridpanda-collapsible--overlay),
.gridpanda-collapsible--right:not(.gridpanda-collapsible--overlay) {
	display: flex;
	width: var(--expanded-width, 280px);
	overflow: hidden;
	transition: width 0.3s ease, min-width 0.3s ease;
}

/* Push collapsed — shrink to strip width */
.gridpanda-collapsible--left:not(.gridpanda-collapsible--overlay).gridpanda-collapsible--collapsed,
.gridpanda-collapsible--right:not(.gridpanda-collapsible--overlay).gridpanda-collapsible--collapsed {
	width: var(--collapsed-width, 15px);
	min-width: var(--collapsed-width, 15px);
	max-width: var(--collapsed-width, 15px);
}

/* Push toggle — fixed-width strip */
.gridpanda-collapsible--left:not(.gridpanda-collapsible--overlay) .gridpanda-collapsible__toggle,
.gridpanda-collapsible--right:not(.gridpanda-collapsible--overlay) .gridpanda-collapsible__toggle {
	width: var(--collapsed-width, 15px);
	min-width: var(--collapsed-width, 15px);
}

/* Left push: toggle first (order:-1), border on right */
.gridpanda-collapsible--left:not(.gridpanda-collapsible--overlay) .gridpanda-collapsible__toggle {
	order: -1;
	border-right: 1px solid #dcdcde;
}

/* Right push: toggle last (DOM order), border on left */
.gridpanda-collapsible--right:not(.gridpanda-collapsible--overlay) .gridpanda-collapsible__toggle {
	border-left: 1px solid #dcdcde;
}

/* Push content — in-flow, takes remaining flex space */
.gridpanda-collapsible--left:not(.gridpanda-collapsible--overlay) .gridpanda-collapsible__content,
.gridpanda-collapsible--right:not(.gridpanda-collapsible--overlay) .gridpanda-collapsible__content {
	flex: 1;
	min-width: 0;
	overflow: auto;
	transition: opacity 0.3s ease;
}

/* Push collapsed — hide content */
.gridpanda-collapsible--left:not(.gridpanda-collapsible--overlay).gridpanda-collapsible--collapsed .gridpanda-collapsible__content,
.gridpanda-collapsible--right:not(.gridpanda-collapsible--overlay).gridpanda-collapsible--collapsed .gridpanda-collapsible__content {
	opacity: 0;
	overflow: hidden;
	pointer-events: none;
}


/* ══════════════════════════════════════════════
   Top / Bottom drawers
   ══════════════════════════════════════════════ */
.gridpanda-collapsible--top,
.gridpanda-collapsible--bottom {
	display: flex;
	flex-direction: column;
}

/* Toggle strip: thin horizontal bar */
.gridpanda-collapsible--top .gridpanda-collapsible__toggle,
.gridpanda-collapsible--bottom .gridpanda-collapsible__toggle {
	height: var(--collapsed-width, 15px);
	min-height: var(--collapsed-width, 15px);
	flex-direction: row;
	gap: 6px;
	border-top: 1px solid #dcdcde;
}
/* Top: toggle at bottom edge */
.gridpanda-collapsible--top .gridpanda-collapsible__toggle {
	order: 2;
	border-top: 1px solid #dcdcde;
	border-bottom: none;
}
/* Bottom: toggle at top edge */
.gridpanda-collapsible--bottom .gridpanda-collapsible__toggle {
	order: -1;
	border-bottom: 1px solid #dcdcde;
	border-top: none;
}

/* Show label inline for top/bottom (there's room horizontally) */
.gridpanda-collapsible--top .gridpanda-collapsible__label,
.gridpanda-collapsible--bottom .gridpanda-collapsible__label {
	display: inline;
}

/* Collapsed top/bottom: only the strip bar visible */
.gridpanda-collapsible--top.gridpanda-collapsible--collapsed .gridpanda-collapsible__content,
.gridpanda-collapsible--bottom.gridpanda-collapsible--collapsed .gridpanda-collapsible__content {
	height: 0;
	opacity: 0;
	pointer-events: none;
	overflow: hidden;
}


/* =============================================
   Autocomplete Facet
   ============================================= */

/* Wrapper — position relative so the dropdown can be absolute */
.gridpanda-autocomplete__wrapper {
	position: relative;
}

/* ── Control row (tags + text input in one pill) ── */
.gridpanda-autocomplete__control {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px;
	min-height: 38px;
	padding: 4px 8px;
	border: 1px solid var(--gridpanda-border, #d1d5db);
	border-radius: 6px;
	background: #fff;
	cursor: text;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.gridpanda-autocomplete__control:focus-within {
	border-color: var(--gridpanda-accent, #6366f1);
	box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15) !important;
	outline: none !important;
}

/* ── Tags ── */
.gridpanda-autocomplete__tags {
	display: contents; /* tags flow inline in the flex parent */
}

.gridpanda-autocomplete__tag {
	display: inline-flex;
	align-items: center;
	gap: 3px;
	padding: 2px 5px 2px 8px;
	background: var(--fx-ac-tag-bg, #ede9fe);
	border: 1px solid var(--fx-ac-tag-border, #c4b5fd);
	border-radius: 4px;
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
	font-size: 12px;
	color: var(--fx-ac-tag-color, #3730a3);
	line-height: 1.5;
	white-space: nowrap;
	max-width: 200px;
}

.gridpanda-autocomplete__tag-text {
	overflow: hidden;
	text-overflow: ellipsis;
}

.gridpanda-autocomplete__tag-remove {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	width: 16px;
	height: 16px;
	border: none !important;
	background: none !important;
	box-shadow: none !important;
	padding: 0;
	cursor: pointer;
	color: var(--fx-ac-tag-remove-color, #7c3aed);
	font-size: 14px;
	line-height: 1;
	border-radius: 2px;
	transition: color 0.12s, background 0.12s;
}

.gridpanda-autocomplete__tag-remove:hover {
	color: #ef4444;
	background: rgba(239, 68, 68, 0.12);
}

/* ── Text input ── */
.gridpanda-autocomplete__input {
	flex: 1 1 120px;
	min-width: 80px;
	border: none !important;
	outline: none !important;
	background: transparent !important;
	box-shadow: none !important;
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
	font-size: 13px;
	padding: 2px 0;
	line-height: 1.5;
	color: inherit;
	height: auto;
	min-height: 0;
}

.gridpanda-autocomplete__input::placeholder {
	color: #9ca3af;
}

/* ── Spinner ── */
.gridpanda-autocomplete__loader {
	display: flex;
	flex-shrink: 0;
	width: 14px;
	height: 14px;
	border: 2px solid #e5e7eb;
	border-top-color: var(--gridpanda-accent, #6366f1);
	border-radius: 50%;
	animation: gridpanda-ac-spin 0.6s linear infinite;
}

@keyframes gridpanda-ac-spin {
	to { transform: rotate(360deg); }
}

/* Respect the HTML `hidden` attribute — overrides display:flex above */
.gridpanda-autocomplete__loader[hidden] {
	display: none;
}

/* ── Results dropdown ── */
.gridpanda-autocomplete__results {
	position: absolute;
	top: calc(100% + 4px);
	left: 0;
	right: 0;
	z-index: 200;
	background: #fff;
	border: 1px solid var(--gridpanda-border, #d1d5db);
	border-radius: 6px;
	box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12);
	max-height: 240px;
	overflow-y: auto;
	overflow-x: hidden;
	overscroll-behavior: contain;
}

/* ── Option row ── */
.gridpanda-autocomplete__option {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 8px 12px;
	cursor: pointer;
	font-size: 13px;
	color: #374151;
	transition: background 0.1s;
	user-select: none;
}

.gridpanda-autocomplete__option:hover,
.gridpanda-autocomplete__option--focused {
	background: #f3f4f6;
}

.gridpanda-autocomplete__option--focused {
	outline: none;
}

.gridpanda-autocomplete__option-text {
	flex: 1;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.gridpanda-autocomplete__option-count {
	flex-shrink: 0;
	margin-left: 10px;
	font-size: 11px;
	color: #9ca3af;
}

/* ── Empty / no-results message ── */
.gridpanda-autocomplete__empty {
	padding: 12px;
	text-align: center;
	font-size: 12px;
	color: #9ca3af;
}



/* ==========================================================================
   Sort Facet
   Render modes: dropdown | radio | button_group
   ========================================================================== */

/* ── CSS custom properties ── */
.gridpanda-sort {
	--fx-sort-focus-ring: 0 0 0 2px rgba(99, 102, 241, 0.35);
	--fx-sort-active-bg: #6366f1;
	--fx-sort-active-color: #fff;
	--fx-sort-hover-bg: #f3f4f6;
	--fx-sort-border: var(--gridpanda-border, #d1d5db);
	--fx-sort-radius: 8px;
	--fx-sort-font-size: 13px;
}

/* ── Dropdown mode ── */
.gridpanda-sort--dropdown {
	position: relative;
}

.gridpanda-sort__select {
	display: block;
	width: 100%;
	padding: 9px 32px 9px 12px;
	font-size: var(--fx-sort-font-size);
	color: #374151;
	background-color: #fff;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 8px center;
	background-size: 16px;
	border: 1px solid var(--fx-sort-border);
	border-radius: var(--fx-sort-radius);
	appearance: none;
	-webkit-appearance: none;
	cursor: pointer;
	transition: border-color 0.15s, box-shadow 0.15s;
	box-sizing: border-box;
}

.gridpanda-sort__select:hover {
	border-color: #9ca3af;
}

.gridpanda-sort__select:focus {
	outline: none;
	border-color: #6366f1;
	box-shadow: var(--fx-sort-focus-ring);
}

/* ── Radio mode ── */
/* Default (vertical): block container + inline-flex children so the
   Inspector's Alignment control (text-align) positions every row.
   This pattern lets a single CSS var drive left/center/right/justify
   without having to switch layout mode per alignment. */
.gridpanda-sort--radio {
	display: block;
	text-align: var(--fx-label-text-align, left);
}

.gridpanda-sort--radio .gridpanda-sort__option {
	margin-top: calc(var(--fx-item-gap, 4px) / 2);
	margin-bottom: calc(var(--fx-item-gap, 4px) / 2);
}

.gridpanda-sort--radio .gridpanda-sort__option:first-child {
	margin-top: 0;
}
.gridpanda-sort--radio .gridpanda-sort__option:last-child {
	margin-bottom: 0;
}

/* ── Horizontal override (Inspector → Orientation → Horizontal) ──
   When --fx-item-layout-direction is set to "row" on the wrapper we switch
   Sort radio mode to an explicit flex-row layout. Per-option margins collapse
   so the flex gap governs spacing. Alignment is delegated to justify-content
   via the --fx-item-layout-align hook (kept as flex-start by default). */
.gridpanda-facet-element[style*="--fx-item-layout-direction:row"] .gridpanda-sort--radio,
.gridpanda-facet-element[style*="--fx-item-layout-direction: row"] .gridpanda-sort--radio,
.gridpanda-facet-element[style*="--fx-item-layout-direction:row"] .gridpanda-sort--buttons,
.gridpanda-facet-element[style*="--fx-item-layout-direction: row"] .gridpanda-sort--buttons {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--fx-item-gap, 6px);
	text-align: initial;
	justify-content: var(--fx-item-layout-align, flex-start);
}

.gridpanda-facet-element[style*="--fx-item-layout-direction:row"] .gridpanda-sort--radio .gridpanda-sort__option,
.gridpanda-facet-element[style*="--fx-item-layout-direction: row"] .gridpanda-sort--radio .gridpanda-sort__option,
.gridpanda-facet-element[style*="--fx-item-layout-direction:row"] .gridpanda-sort--buttons .gridpanda-sort__btn,
.gridpanda-facet-element[style*="--fx-item-layout-direction: row"] .gridpanda-sort--buttons .gridpanda-sort__btn {
	margin: 0;
}

/* ── Vertical override (Inspector → Orientation → Vertical) ──
   Sort's radio and button_group modes default to `display: block` with
   inline-flex children — that makes options flow horizontally on a single
   line (task #33's text-align trick). When the user picks Vertical, switch
   the container to flex-column so every option sits on its own row.
   `align-items` drives horizontal placement since text-align doesn't position
   block-level flex items — we map the three common alignments via a custom
   attribute trick below. */
.gridpanda-facet-element[style*="--fx-item-layout-direction:column"] .gridpanda-sort--radio,
.gridpanda-facet-element[style*="--fx-item-layout-direction: column"] .gridpanda-sort--radio,
.gridpanda-facet-element[style*="--fx-item-layout-direction:column"] .gridpanda-sort--buttons,
.gridpanda-facet-element[style*="--fx-item-layout-direction: column"] .gridpanda-sort--buttons {
	display: flex;
	flex-direction: column;
	flex-wrap: nowrap;
	align-items: flex-start;
	gap: var(--fx-item-gap, 6px);
	text-align: initial;
}

.gridpanda-facet-element[style*="--fx-item-layout-direction:column"] .gridpanda-sort--radio .gridpanda-sort__option,
.gridpanda-facet-element[style*="--fx-item-layout-direction: column"] .gridpanda-sort--radio .gridpanda-sort__option,
.gridpanda-facet-element[style*="--fx-item-layout-direction:column"] .gridpanda-sort--buttons .gridpanda-sort__btn,
.gridpanda-facet-element[style*="--fx-item-layout-direction: column"] .gridpanda-sort--buttons .gridpanda-sort__btn {
	margin: 0;
	display: inline-flex;
	width: fit-content;
}

/* Center/right alignment remap for vertical sort — maps text-align values
   to align-items since text-align doesn't position flex children. */
.gridpanda-facet-element[style*="--fx-item-layout-direction:column"][style*="--fx-label-text-align:center"] .gridpanda-sort--radio,
.gridpanda-facet-element[style*="--fx-item-layout-direction:column"][style*="--fx-label-text-align:center"] .gridpanda-sort--buttons,
.gridpanda-facet-element[style*="--fx-item-layout-direction: column"][style*="--fx-label-text-align: center"] .gridpanda-sort--radio,
.gridpanda-facet-element[style*="--fx-item-layout-direction: column"][style*="--fx-label-text-align: center"] .gridpanda-sort--buttons {
	align-items: center;
}

.gridpanda-facet-element[style*="--fx-item-layout-direction:column"][style*="--fx-label-text-align:right"] .gridpanda-sort--radio,
.gridpanda-facet-element[style*="--fx-item-layout-direction:column"][style*="--fx-label-text-align:right"] .gridpanda-sort--buttons,
.gridpanda-facet-element[style*="--fx-item-layout-direction: column"][style*="--fx-label-text-align: right"] .gridpanda-sort--radio,
.gridpanda-facet-element[style*="--fx-item-layout-direction: column"][style*="--fx-label-text-align: right"] .gridpanda-sort--buttons {
	align-items: flex-end;
}

.gridpanda-sort__option {
	/* inline-flex so the parent container's text-align actually positions
	   each option (center / right / justify). A pure flex child ignores
	   text-align, which is why the Alignment control previously appeared
	   to do nothing. */
	display: inline-flex;
	align-items: center;
	gap: var(--fx-item-gap, 8px);
	/* Per-side padding with shorthand fallback — emitted by SpacingGroupControl. */
	padding-top:    var(--fx-item-padding-top,    var(--fx-item-padding, 8px));
	padding-right:  var(--fx-item-padding-right,  var(--fx-item-padding, 10px));
	padding-bottom: var(--fx-item-padding-bottom, var(--fx-item-padding, 8px));
	padding-left:   var(--fx-item-padding-left,   var(--fx-item-padding, 10px));
	/* Per-side border + radius with shorthand fallback — emitted by BorderGroupControl. */
	border-style: var(--fx-item-border-style, none);
	border-color: var(--fx-item-border-color, transparent);
	border-top-width:    var(--fx-item-border-width-top,    var(--fx-item-border-width, 0));
	border-right-width:  var(--fx-item-border-width-right,  var(--fx-item-border-width, 0));
	border-bottom-width: var(--fx-item-border-width-bottom, var(--fx-item-border-width, 0));
	border-left-width:   var(--fx-item-border-width-left,   var(--fx-item-border-width, 0));
	border-top-left-radius:     var(--fx-item-border-radius-tl, var(--fx-item-border-radius, 6px));
	border-top-right-radius:    var(--fx-item-border-radius-tr, var(--fx-item-border-radius, 6px));
	border-bottom-right-radius: var(--fx-item-border-radius-br, var(--fx-item-border-radius, 6px));
	border-bottom-left-radius:  var(--fx-item-border-radius-bl, var(--fx-item-border-radius, 6px));
	cursor: pointer;
	/* Typography: consume the shared --fx-label-* vars that the Inspector's
	   Items & Labels → Typography panel writes, so Sort rows inherit the
	   same per-facet styling as checkbox/radio/dropdown facets. */
	font-family: var(--fx-label-font-family, inherit);
	font-size: var(--fx-label-font-size, var(--fx-sort-font-size, 14px));
	font-weight: var(--fx-label-font-weight, 400);
	line-height: var(--fx-label-line-height, 1.3);
	letter-spacing: var(--fx-label-letter-spacing, normal);
	text-transform: var(--fx-label-text-transform, none);
	text-decoration: var(--fx-label-text-decoration, none);
	text-align: var(--fx-label-text-align, left);
	color: var(--fx-label-color, #374151);
	background: var(--fx-item-bg, transparent);
	transition: background 0.1s, color 0.1s;
	user-select: none;
}

.gridpanda-sort__option:hover {
	background: var(--fx-item-hover-bg, var(--fx-sort-hover-bg));
	color: var(--fx-label-hover-color, var(--fx-label-color, #374151));
}

.gridpanda-sort__option--selected {
	background: var(--fx-item-hover-bg, #eff6ff);
	color: var(--fx-label-hover-color, var(--fx-label-color, #2563eb));
	font-weight: var(--fx-label-font-weight, 500);
}

.gridpanda-sort__radio {
	flex-shrink: 0;
	width: 15px;
	height: 15px;
	accent-color: #6366f1;
	cursor: pointer;
}

.gridpanda-sort__option-label {
	line-height: inherit;
	font-family: inherit;
	font-size: inherit;
	font-weight: inherit;
	letter-spacing: inherit;
	text-transform: inherit;
	text-decoration: inherit;
	color: inherit;
}

/* ── Button group mode ── */
.gridpanda-sort--buttons {
	display: block;
	text-align: var(--fx-label-text-align, left);
}

.gridpanda-sort--buttons .gridpanda-sort__btn {
	margin: calc(var(--fx-item-gap, 6px) / 2);
}

.gridpanda-sort__btn {
	display: inline-flex;
	align-items: center;
	gap: var(--fx-item-gap, 5px);
	/* Per-side padding with shorthand fallback — emitted by SpacingGroupControl. */
	padding-top:    var(--fx-item-padding-top,    var(--fx-item-padding, 7px));
	padding-right:  var(--fx-item-padding-right,  var(--fx-item-padding, 14px));
	padding-bottom: var(--fx-item-padding-bottom, var(--fx-item-padding, 7px));
	padding-left:   var(--fx-item-padding-left,   var(--fx-item-padding, 14px));
	/* Border: honor the item border group when set; otherwise fall back to the
	   legacy solid pill outline that matches the default Sort button style. */
	border-style: var(--fx-item-border-style, solid);
	border-color: var(--fx-item-border-color, var(--fx-sort-border));
	border-top-width:    var(--fx-item-border-width-top,    var(--fx-item-border-width, 1px));
	border-right-width:  var(--fx-item-border-width-right,  var(--fx-item-border-width, 1px));
	border-bottom-width: var(--fx-item-border-width-bottom, var(--fx-item-border-width, 1px));
	border-left-width:   var(--fx-item-border-width-left,   var(--fx-item-border-width, 1px));
	border-top-left-radius:     var(--fx-item-border-radius-tl, var(--fx-item-border-radius, 20px));
	border-top-right-radius:    var(--fx-item-border-radius-tr, var(--fx-item-border-radius, 20px));
	border-bottom-right-radius: var(--fx-item-border-radius-br, var(--fx-item-border-radius, 20px));
	border-bottom-left-radius:  var(--fx-item-border-radius-bl, var(--fx-item-border-radius, 20px));
	background: var(--fx-item-bg, #fff);
	/* Share --fx-label-* typography with checkbox/radio facets. */
	font-family: var(--fx-label-font-family, inherit);
	font-size: var(--fx-label-font-size, var(--fx-sort-font-size, 14px));
	font-weight: var(--fx-label-font-weight, 500);
	line-height: var(--fx-label-line-height, 1.2);
	letter-spacing: var(--fx-label-letter-spacing, normal);
	text-transform: var(--fx-label-text-transform, none);
	text-decoration: var(--fx-label-text-decoration, none);
	color: var(--fx-label-color, #374151);
	cursor: pointer;
	transition: background 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.15s;
	white-space: nowrap;
	user-select: none;
}

.gridpanda-sort__btn:hover {
	border-color: #9ca3af;
	background: var(--fx-sort-hover-bg);
}

.gridpanda-sort__btn:focus-visible {
	outline: none;
	box-shadow: var(--fx-sort-focus-ring);
}

.gridpanda-sort__btn--active {
	background: var(--fx-sort-active-bg);
	border-color: var(--fx-sort-active-bg);
	color: var(--fx-sort-active-color);
}

.gridpanda-sort__btn--active:hover {
	background: #4f46e5;
	border-color: #4f46e5;
	color: #fff;
}

.gridpanda-sort__btn-icon {
	display: inline-flex;
	align-items: center;
	line-height: 1;
	font-size: 14px;
}

.gridpanda-sort__btn-label {
	line-height: inherit;
	font-family: inherit;
	font-size: inherit;
	font-weight: inherit;
	letter-spacing: inherit;
	text-transform: inherit;
	text-decoration: inherit;
	color: inherit;
}


/* =========================================================
   Active Filters Bar
   ========================================================= */

/* ── CSS custom properties ── */
:root {
	--fx-af-gap:           6px;
	--fx-af-pill-bg:       #eff6ff;
	--fx-af-pill-border:   #bfdbfe;
	--fx-af-pill-color:    #1d4ed8;
	--fx-af-pill-radius:   20px;
	--fx-af-pill-px:       10px;
	--fx-af-pill-py:       4px;
	--fx-af-pill-font:     12px;
	--fx-af-remove-size:   16px;
	--fx-af-remove-color:  #93c5fd;
	--fx-af-remove-hover:  #1d4ed8;
	--fx-af-clear-color:   #6b7280;
	--fx-af-clear-hover:   #111827;
}

/* ── Outer wrapper ── */
.gridpanda-active-filters {
	width: 100%;
	font-size: var(--fx-af-pill-font);
}

/* ── Inner flex row: pills + clear-all ── */
.gridpanda-active-filters__inner {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--fx-af-gap);
}

/* ── Pills strip ── */
.gridpanda-active-filters__pills {
	display: flex;
	flex-wrap: wrap;
	gap: var(--fx-af-gap);
	flex: 1 1 auto;
	min-width: 0;
}

/* ── Single pill ── */
.gridpanda-active-filters__pill {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	padding: var(--fx-af-pill-py) var(--fx-af-pill-px);
	background: var(--fx-af-pill-bg);
	border: 1px solid var(--fx-af-pill-border);
	border-radius: var(--fx-af-pill-radius);
	color: var(--fx-af-pill-color);
	font-size: var(--fx-af-pill-font);
	line-height: 1.4;
	white-space: nowrap;
	max-width: 240px;
}

/* ── Pill label area ── */
.gridpanda-active-filters__pill-label {
	display: inline-flex;
	align-items: center;
	gap: 3px;
	min-width: 0;
	overflow: hidden;
}

/* ── Facet-name prefix (e.g. "Color: ") ── */
.gridpanda-active-filters__pill-facet {
	font-weight: 600;
	opacity: 0.75;
	flex-shrink: 0;
}

/* ── The actual filter value ── */
.gridpanda-active-filters__pill-value {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* ── × remove button ── */
.gridpanda-active-filters__pill-remove {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	width: var(--fx-af-remove-size);
	height: var(--fx-af-remove-size);
	padding: 0;
	margin-left: 2px;
	background: none;
	border: none;
	border-radius: 50%;
	color: var(--fx-af-remove-color);
	font-size: 14px;
	line-height: 1;
	cursor: pointer;
	transition: color 0.15s ease, background 0.15s ease;
}

.gridpanda-active-filters__pill-remove:hover,
.gridpanda-active-filters__pill-remove:focus-visible {
	color: var(--fx-af-remove-hover);
	background: rgba(29, 78, 216, 0.08);
	outline: none;
}

/* ── Clear All button ── */
.gridpanda-active-filters__clear-all {
	flex-shrink: 0;
	padding: var(--fx-af-pill-py) var(--fx-af-pill-px);
	background: none;
	border: 1px solid transparent;
	border-radius: var(--fx-af-pill-radius);
	color: var(--fx-af-clear-color);
	font-size: var(--fx-af-pill-font);
	font-family: inherit;
	cursor: pointer;
	white-space: nowrap;
	transition: color 0.15s ease, border-color 0.15s ease;
}

.gridpanda-active-filters__clear-all:hover,
.gridpanda-active-filters__clear-all:focus-visible {
	color: var(--fx-af-clear-hover);
	border-color: #d1d5db;
	outline: none;
}

/* ── Product Gallery ── */
/* ── Product Categories ── */
.gridpanda-card__product-categories {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	align-items: center;
}
.gridpanda-card__product-categories--list {
	flex-direction: column;
	align-items: flex-start;
	gap: 2px;
}
.gridpanda-card__product-categories--comma {
	display: inline;
}
.gridpanda-card__product-category {
	display: inline-block;
	padding: 2px 8px;
	background: #f3f4f6;
	border-radius: 4px;
	font-size: 12px;
	color: inherit;
	text-decoration: none;
	transition: background 0.15s ease, color 0.15s ease;
	line-height: 1.4;
	box-sizing: border-box;
}
a.gridpanda-card__product-category:hover {
	opacity: 0.85;
}

/* ── Product Gallery ── */
.gridpanda-card__product-gallery {
	display: flex;
	flex-wrap: wrap;
	gap: 4px;
}

.gridpanda-card__product-gallery-img {
	cursor: pointer;
	transition: opacity 0.15s ease;
}
.gridpanda-card__product-gallery-img:hover {
	opacity: 0.85;
}

/* ── Product Gallery Lightbox ── */
.gridpanda-lightbox {
	position: fixed;
	inset: 0;
	z-index: 999999;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(0, 0, 0, 0.88);
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.2s ease, visibility 0.2s ease;
}
.gridpanda-lightbox.is-active {
	opacity: 1;
	visibility: visible;
}
.gridpanda-lightbox__img {
	max-width: 90vw;
	max-height: 85vh;
	object-fit: contain;
	border-radius: 4px;
	box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
	user-select: none;
}
.gridpanda-lightbox__close {
	position: absolute;
	top: 16px;
	right: 16px;
	width: 36px;
	height: 36px;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(255, 255, 255, 0.12);
	border: none;
	border-radius: 50%;
	color: #fff;
	font-size: 20px;
	cursor: pointer;
	transition: background 0.15s ease;
	line-height: 1;
}
.gridpanda-lightbox__close:hover {
	background: rgba(255, 255, 255, 0.25);
}
.gridpanda-lightbox__nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	width: 44px;
	height: 44px;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(255, 255, 255, 0.1);
	border: none;
	border-radius: 50%;
	color: #fff;
	font-size: 22px;
	cursor: pointer;
	transition: background 0.15s ease;
	user-select: none;
}
.gridpanda-lightbox__nav:hover {
	background: rgba(255, 255, 255, 0.22);
}
.gridpanda-lightbox__nav--prev {
	left: 16px;
}
.gridpanda-lightbox__nav--next {
	right: 16px;
}
.gridpanda-lightbox__counter {
	position: absolute;
	bottom: 16px;
	left: 50%;
	transform: translateX(-50%);
	color: rgba(255, 255, 255, 0.7);
	font-size: 13px;
	font-family: inherit;
}

/* ═══════════════════════════════════════════════════════════════════
   Filter Actions — Trigger Buttons
   ═══════════════════════════════════════════════════════════════════ */

.gridpanda-filter-actions {
	position: relative;
	z-index: 10;
}

.gridpanda-filter-action-btn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 8px 16px;
	font-size: 14px;
	font-weight: 500;
	font-family: inherit;
	line-height: 1;
	border: 1px solid #d1d5db;
	border-radius: 6px;
	background: #fff;
	color: #374151;
	cursor: pointer;
	transition: background 0.15s, border-color 0.15s, box-shadow 0.15s, transform 0.15s;
	white-space: nowrap;
	user-select: none;
}
.gridpanda-filter-action-btn:hover {
	background: #f3f4f6;
	border-color: #9ca3af;
}
.gridpanda-filter-action-btn:active {
	transform: scale(0.97);
}

/* Icon inside button */
.gridpanda-fa-icon {
	display: inline-flex;
	align-items: center;
}
.gridpanda-fa-icon svg {
	width: 16px;
	height: 16px;
}

/* Active count badge */
.gridpanda-fa-badge {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 18px;
	height: 18px;
	padding: 0 5px;
	font-size: 11px;
	font-weight: 700;
	line-height: 1;
	color: #fff;
	background: #3b82f6;
	border-radius: 9px;
}

/* Hidden state */
.gridpanda-fa--hidden {
	display: none !important;
}

/* ── FAB style — fixed floating button ── */
.gridpanda-fa--fab {
	position: sticky;
	bottom: 24px;
	z-index: 9998;
	width: 56px;
	height: 56px;
	padding: 0;
	border-radius: 50%;
	background: #3b82f6;
	color: #fff;
	border: none;
	box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
	justify-content: center;
	align-self: flex-end;
	margin-right: 24px;
	flex-shrink: 0;
}
.gridpanda-fa--fab:hover {
	background: #2563eb;
	box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
	transform: scale(1.05);
}
.gridpanda-fa--fab .gridpanda-fa-label { display: none; }
.gridpanda-fa--fab .gridpanda-fa-icon svg { width: 24px; height: 24px; }
.gridpanda-fa--fab .gridpanda-fa-badge {
	position: absolute;
	top: -4px;
	right: -4px;
}

/* ── Pill style ── */
.gridpanda-fa--pill {
	border-radius: 999px;
	padding: 6px 18px;
}

/* ── Pill row — one pill per facet when pill trigger + drawer mode ── */
.gridpanda-fa-pill-row {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
}
.gridpanda-fa-pill-row .gridpanda-fa--pill {
	font-size: 13px;
	font-weight: 500;
	cursor: pointer;
	transition: background 0.15s, border-color 0.15s, transform 0.1s;
}
.gridpanda-fa-pill-row .gridpanda-fa--pill:hover {
	background: #f3f4f6;
	border-color: #9ca3af;
}
.gridpanda-fa-pill-row .gridpanda-fa--pill:active {
	transform: scale(0.97);
}

/* ── Sticky bar style ──
   Two anchor modes are supported, controlled by the per-breakpoint
   `stickyMode` config emitted by the admin builder:
   - container (default)  → position:sticky, bound by the grid wrapper.
   - viewport             → position:fixed, glued to browser viewport.
   The optional `stickyOffset` is exposed via the --gp-sticky-bottom and
   --gp-sticky-top custom properties (see frontend.js). */
/* Shared sticky row — wraps one or more sticky-bar buttons.
   Default position is bottom-edge; --top variant flips to top-edge. */
.gridpanda-sticky-bar-row {
	position: sticky;
	bottom: var(--gp-sticky-bottom, 0px);
	z-index: 100;
	display: flex;
	box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.15);
}
/* Container-anchored — explicit class for clarity (matches default). */
.gridpanda-sticky-bar-row--container {
	position: sticky;
	bottom: var(--gp-sticky-bottom, 0px);
}
/* Viewport-anchored — pinned to bottom of browser viewport regardless
   of grid scroll position. Stretches across the viewport width. */
.gridpanda-sticky-bar-row--viewport {
	position: fixed;
	left: 0;
	right: 0;
	bottom: var(--gp-sticky-bottom, 0px);
	width: 100%;
	z-index: 9999;
}

/* ── Top-edge variant ──
   When the user picks Stick To: Top in the admin, JS adds the --top
   class. These rules flip the anchor: bottom→auto, top→offset, and
   shadow direction inverts so it casts DOWN onto content. */
.gridpanda-sticky-bar-row--top {
	bottom: auto;
	top: var(--gp-sticky-top, 0px);
	box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
}
.gridpanda-sticky-bar-row--container.gridpanda-sticky-bar-row--top {
	bottom: auto;
	top: var(--gp-sticky-top, 0px);
}
.gridpanda-sticky-bar-row--viewport.gridpanda-sticky-bar-row--top {
	bottom: auto;
	top: var(--gp-sticky-top, 0px);
}
/* Top-edge buttons need a softer top border (vs the default top-side
   separator which makes sense when the bar sits at the bottom). */
.gridpanda-sticky-bar-row--top .gridpanda-fa--sticky-bar {
	border-top: none;
	border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.gridpanda-fa--sticky-bar {
	flex: 1 1 0%;
	min-width: 0;
	border-radius: 0;
	padding: 12px 20px;
	justify-content: center;
	background: #1f2937;
	color: #fff;
	border: none;
	border-left: 1px solid rgba(255, 255, 255, 0.08);
	border-top: 1px solid rgba(255, 255, 255, 0.1);
	box-sizing: border-box;
}
.gridpanda-fa--sticky-bar:first-child {
	border-left: none;
}
.gridpanda-fa--sticky-bar:hover {
	background: #111827;
}
.gridpanda-fa--sticky-bar .gridpanda-fa-icon svg { stroke: #fff; }

/* ═══════════════════════════════════════════════════════════════════
   Filter Container — Display Modes
   ═══════════════════════════════════════════════════════════════════ */

/* ── Sticky mode ──
   Container-anchored is the default and matches legacy behaviour.
   Viewport-anchored attaches the filter container to the browser
   viewport so it stays reachable even when the grid scrolls past.
   The --gp-sticky-top var is set by frontend.js from cfg.stickyOffset. */
.gridpanda-fc--sticky,
.gridpanda-fc--sticky--container {
	position: sticky;
	top: var(--gp-sticky-top, 0px);
	z-index: 50;
	align-self: flex-start;
}
.gridpanda-fc--sticky--viewport {
	position: fixed;
	top: var(--gp-sticky-top, 0px);
	left: 0;
	right: 0;
	z-index: 9999;
	align-self: auto;
}

/* ── Collapsible mode ── */
.gridpanda-filter-container[data-fx-display-mode="collapsible"] {
	transition: flex 0.35s ease, max-height 0.35s ease,
	            opacity 0.25s ease, min-width 0.35s ease,
	            padding 0.3s ease, margin 0.3s ease;
	overflow: hidden;
	min-width: 0; /* allow flex to shrink below content size */
}
.gridpanda-fc--collapsible-closed {
	flex: 0 0 0px !important;
	min-width: 0 !important;
	max-height: 0 !important;
	width: 0 !important;
	opacity: 0;
	pointer-events: none;
	overflow: hidden;
	margin: 0 !important;
	padding: 0 !important;
}
/* Smooth gap transition on parent row when filter column collapses */
.gridpanda-layout--row:has(> .gridpanda-filter-container[data-fx-display-mode="collapsible"]) {
	transition: gap 0.35s ease;
}

/* ── FOUC guard: suppress all transitions until JS has initialised ──
   The server-side <style data-gridpanda-fouc> block applies the correct
   initial state. While it is present, disable transitions on the
   container and parent row so there is zero layout shift on load.
   JS removes the FOUC style after init, which also removes this
   cascade — transitions then work normally for user interactions. */
:root:has(style[data-gridpanda-fouc]) .gridpanda-filter-container,
:root:has(style[data-gridpanda-fouc]) .gridpanda-layout--row {
	transition: none !important;
}
.gridpanda-layout--row:has(> .gridpanda-fc--collapsible-closed) {
	gap: 0px !important;
}

/* ── Drawer mode — in-context overlay panel ── */

/* Containing block: section row becomes the positioning context.
   The :has() rule clips left/right drawers even before they're opened,
   preventing the off-screen translateX from causing horizontal overflow.
   The .gridpanda-drawer-context class is added by JS on toggle for legacy compat. */
.gridpanda-layout--row:has(> .gridpanda-fc--drawer-left),
.gridpanda-layout--row:has(> .gridpanda-fc--drawer-right),
.gridpanda-layout--row.gridpanda-drawer-context {
	position: relative;
	overflow: hidden;
}

.gridpanda-fc--drawer {
	position: absolute;
	z-index: 100;
	background: var(--fx-drawer-bg, #fff);
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1), visibility 0s 0.35s;
	box-shadow: var(--fx-drawer-shadow, 0 0 24px rgba(0, 0, 0, 0.12));
	visibility: hidden;
	border-style: var(--fx-drawer-border-style, none);
	border-color: var(--fx-drawer-border-color, transparent);
	border-width: var(--fx-drawer-border-width, 0);
	border-radius: var(--fx-drawer-radius, 0);
}

/* Width for left/right drawers — fill section height */
.gridpanda-fc--drawer.gridpanda-fc--drawer-left,
.gridpanda-fc--drawer.gridpanda-fc--drawer-right {
	top: 0;
	bottom: 0;
	width: var(--fx-drawer-width, 320px);
	max-width: 80%;
}
.gridpanda-fc--drawer.gridpanda-fc--drawer-left {
	left: 0;
	transform: translateX(-100%);
}
.gridpanda-fc--drawer.gridpanda-fc--drawer-right {
	right: 0;
	transform: translateX(100%);
}

/* Top/bottom drawers — viewport-fixed bottom-sheet / top-sheet pattern */
.gridpanda-fc--drawer.gridpanda-fc--drawer-top,
.gridpanda-fc--drawer.gridpanda-fc--drawer-bottom {
	position: fixed;
	left: 0;
	right: 0;
	z-index: 9999;
	max-height: 70vh;
	border-radius: 0;
	/* Center content when max-width is set */
	--fx-content-max-width: none;
}
/* Inner content wrapper — handles max-width constraint & scroll overflow.
   Applies to all drawer directions and fullscreen. */
.gridpanda-drawer-content {
	width: 100%;
}
/* Top/bottom/fullscreen — center-constrained content + internal scroll */
.gridpanda-fc--drawer.gridpanda-fc--drawer-top > .gridpanda-drawer-content,
.gridpanda-fc--drawer.gridpanda-fc--drawer-bottom > .gridpanda-drawer-content,
.gridpanda-fc--fullscreen > .gridpanda-drawer-content {
	max-width: var(--fx-content-max-width, none);
	margin-left: auto;
	margin-right: auto;
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	max-height: calc(70vh - var(--fx-drawer-pt, 20px) - var(--fx-drawer-pb, 20px));
}
/* Left/right drawers — scroll within the fixed height */
.gridpanda-fc--drawer.gridpanda-fc--drawer-left > .gridpanda-drawer-content,
.gridpanda-fc--drawer.gridpanda-fc--drawer-right > .gridpanda-drawer-content {
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	max-height: calc(100vh - var(--fx-drawer-pt, 20px) - var(--fx-drawer-pb, 20px));
}
/* Fullscreen — fill available height */
.gridpanda-fc--fullscreen > .gridpanda-drawer-content {
	max-height: calc(100vh - var(--fx-drawer-pt, 20px) - var(--fx-drawer-pb, 20px));
}
.gridpanda-fc--drawer.gridpanda-fc--drawer-top {
	top: 0;
	transform: translateY(-100%);
	border-radius: 0 0 16px 16px;
	box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
}
.gridpanda-fc--drawer.gridpanda-fc--drawer-bottom {
	bottom: 0;
	transform: translateY(100%);
	border-radius: 16px 16px 0 0;
	box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.15);
}

/* ── Drawer Anchor: grid-context variant ──
   Overrides the viewport-fixed positioning of top/bottom drawers so
   they open inside the grid's section row instead of pinning to the
   browser edge. Triggered by the per-breakpoint setting
   drawerAnchor='grid' (frontend.js adds the gridpanda-fc--drawer--grid
   class). The slide animation still runs from the matching edge of the
   section row.

   Higher specificity than the base viewport-fixed rules above so the
   class order in the markup doesn't matter. */
.gridpanda-fc--drawer.gridpanda-fc--drawer-top.gridpanda-fc--drawer--grid,
.gridpanda-fc--drawer.gridpanda-fc--drawer-bottom.gridpanda-fc--drawer--grid {
	position: absolute;
	left: 0;
	right: 0;
	z-index: 100;
	max-height: 100%;
	box-shadow: var(--fx-drawer-shadow, 0 0 24px rgba(0, 0, 0, 0.12));
}
.gridpanda-fc--drawer.gridpanda-fc--drawer-top.gridpanda-fc--drawer--grid {
	top: 0;
}
.gridpanda-fc--drawer.gridpanda-fc--drawer-bottom.gridpanda-fc--drawer--grid {
	bottom: 0;
}
/* Section row hosting a grid-anchored top/bottom drawer needs the same
   relative+overflow treatment that left/right drawers already get. */
.gridpanda-layout--row:has(> .gridpanda-fc--drawer--grid),
.gridpanda-layout--row.gridpanda-drawer-context {
	position: relative;
	overflow: hidden;
}
/* Cap the inner-content scroll height to the section row when grid-anchored. */
.gridpanda-fc--drawer.gridpanda-fc--drawer-top.gridpanda-fc--drawer--grid > .gridpanda-drawer-content,
.gridpanda-fc--drawer.gridpanda-fc--drawer-bottom.gridpanda-fc--drawer--grid > .gridpanda-drawer-content {
	max-height: calc(100% - var(--fx-drawer-pt, 20px) - var(--fx-drawer-pb, 20px));
}

/* Open state */
.gridpanda-fc--drawer-open {
	transform: translate(0, 0) !important;
	visibility: visible !important;
	transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1), visibility 0s 0s !important;
}

/* Drawer inner padding — applied to the container itself since it carries
   both .gridpanda-fc--drawer and .gridpanda-layout on the same element. */
.gridpanda-fc--drawer {
	padding-top: var(--fx-drawer-pt, 20px);
	padding-right: var(--fx-drawer-pr, 20px);
	padding-bottom: var(--fx-drawer-pb, 20px);
	padding-left: var(--fx-drawer-pl, 20px);
}

/* Close button injected by JS inside drawer/fullscreen containers */
.gridpanda-drawer-close {
	position: absolute;
	top: var(--fx-close-top, 12px);
	right: var(--fx-close-right, 12px);
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: var(--fx-close-size, 36px);
	height: var(--fx-close-size, 36px);
	padding: 0;
	border: none;
	border-radius: var(--fx-close-radius, 50%);
	background: var(--fx-close-bg, #f3f4f6);
	color: var(--fx-close-color, #374151);
	cursor: pointer;
	transition: background 0.15s, color 0.15s;
}
.gridpanda-drawer-close:hover {
	filter: brightness(0.9);
}
.gridpanda-drawer-close:focus-visible {
	outline: 2px solid #3b82f6;
	outline-offset: 2px;
}

/* ── Fullscreen mode ── */
.gridpanda-fc--fullscreen {
	position: fixed !important;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	width: 100% !important;
	max-width: 100vw !important;
	height: 100vh;
	z-index: 10000;
	background: #fff;
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	transform: translateY(100%);
	transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1), visibility 0s 0.35s;
	visibility: hidden;
}
.gridpanda-fc--fullscreen-open {
	transform: translateY(0) !important;
	visibility: visible !important;
	transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1), visibility 0s 0s !important;
}
.gridpanda-fc--fullscreen .gridpanda-layout {
	padding: 24px;
	max-width: 600px;
	margin: 0 auto;
}

/* ── Shared overlay backdrop (section-scoped for left/right drawers) ── */
.gridpanda-drawer-overlay {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 99;
	background: var(--fx-overlay-color, rgba(0, 0, 0, 0.35));
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.3s ease;
	border-radius: inherit;
}
.gridpanda-drawer-overlay--visible {
	opacity: 1;
	pointer-events: auto;
}
/* Click-catcher only — no visible backdrop */
.gridpanda-drawer-overlay--transparent {
	background: transparent !important;
}
/* Viewport-level overlay when appended to body (top/bottom sheets) */
body > .gridpanda-drawer-overlay {
	position: fixed;
	z-index: 9998;
	border-radius: 0;
}
/* Prevent body scroll when viewport-level drawer is open */
body.gridpanda-drawer-active {
	overflow: hidden;
}
