/*!
 * Plugin Name: Izzi's
 * Version:     1.3.13
 * Description: Layout, transitions, and effects for the Izzi's WooCommerce filter block.
 * Author:      Nick Gasior
 * License:     GPL-2.0-or-later
 *
 * Izzi's — Layout + Transitions CSS.
 *
 * Structure:
 *  1. Screen-reader utilities
 *  2. Layout (block, sidebar, grid)
 *  3. Transitions & Effects
 *  4. Mobile drawer (< 768px)
 *  4b. Tablet sidebar column step-down (768px – 1024px)
 *  5. Reduced-motion overrides
 *  6. Very small screens (< 480px)
 *
 * Colors, typography, borders, and decorative styles are
 * intentionally omitted — apply them in your theme.
 * BEM classes are provided as styling hooks.
 */

/* ─────────────────────────────────────────────────────────
   1. Screen-reader utilities (required for accessibility)
───────────────────────────────────────────────────────── */

.izzis-skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 9999;
}

.izzis-skip-link:focus {
	left: 0;
}

/* ─────────────────────────────────────────────────────────
   2. Layout
───────────────────────────────────────────────────────── */

/* Block wrapper — fills its containing column by default */
.izzis-block {
	position: relative;
	width: 100%;
	box-sizing: border-box;
}

/*
 * Full-width alignment: break out of the theme's content container.
 * get_block_wrapper_attributes() outputs `alignfull` when the editor
 * alignment is set to Full Width; render.php also adds it by default.
 *
 * The `wp-block-izzis-products` selector catches themes that apply
 * alignment styles via the block's generated class name.
 */
.izzis-block.alignfull,
.wp-block-izzis-products.alignfull {
	width: 100vw;
	max-width: 100vw;
	margin-left: calc(50% - 50vw);
}

/* Wide alignment: pulls to the theme's wide breakout width */
.izzis-block.alignwide,
.wp-block-izzis-products.alignwide {
	width: calc(100% + 2 * var(--wp--style--root--padding-inline, 0px));
	margin-left: calc(-1 * var(--wp--style--root--padding-inline, 0px));
}

/*
 * JS-forced full-width fallback: applied by izzis.js when the block has
 * alignfull but the CSS breakout is blocked (e.g. inside a flex/grid item
 * where calc(50% - 50vw) produces unexpected results).
 * The actual margin-left, width, and max-width are set as inline styles.
 */
.izzis-block.izzis-force-full {
	position: relative;
}

/* Two-column layout: sidebar + main */
.izzis-layout {
	display: flex;
	align-items: flex-start;
	gap: 0;
}

/* Sidebar on the right — reverse the flex row (desktop only; drawer handles mobile) */
@media (min-width: 768px) {
	.izzis-layout--sidebar-right {
		flex-direction: row-reverse;
	}
}

.izzis-sidebar {
	flex: 0 0 260px;
	width: 260px;
	min-width: 0;
}

.izzis-sidebar__inner {
	position: sticky;
	top: 0;
}

.izzis-main {
	flex: 1 1 0%;
	min-width: 0;
}

/*
 * Filter toggle and close button: hidden on desktop.
 *
 * Using `.izzis-block .izzis-filter-toggle` (specificity 0,2,0) rather than
 * the bare class (0,1,0) so these rules beat the theme's
 * `:root :where(.izzis-filter-toggle/sidebar__close) { display: none }` rules,
 * which also resolve to 0,1,0 but load after the plugin stylesheet.
 */
.izzis-block .izzis-filter-toggle {
	display: none;
}

.izzis-block .izzis-sidebar__close {
	display: none;
}

/* Overlay backdrop — hidden until drawer is open */
.izzis-overlay {
	display: none;
}

/* Sidebar header row (title + close button) — hidden on desktop */
.izzis-sidebar__header {
	display: none;
}

/* Sidebar footer (View Results button) — hidden on desktop, shown in mobile drawer */
.izzis-sidebar__footer {
	display: none;
}

/* Active filter count badge on toggle button — hidden when empty */
.izzis-filter-toggle__count:empty {
	display: none;
}

/* Sort toolbar — right-aligned on desktop */
/*
 * Topbar: active filter chips on the left, sort dropdown on the right.
 * On mobile (< 600px) the two sections stack vertically.
 */
.izzis-topbar {
	display: flex;
	flex-direction: row;
	align-items: center;
	gap: 0.75rem;
	flex-wrap: wrap;
}

.izzis-topbar .izzis-active-filters {
	flex: 1 1 auto;
	min-width: 0;
}

.izzis-topbar .izzis-toolbar {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
}

/* Active filters chips row */
.izzis-active-filters {
	min-width: 0;
}

/*
 * Sort dropdown — styled to match the theme's input aesthetic.
 * Uses the same CSS variables the theme uses so swapping palettes
 * automatically updates the select too.
 */
.izzis-block .izzis-sort {
	box-sizing: border-box;
	padding: 0.625rem 1rem;
	border: 3px solid var(--wp--preset--color--contrast, #111111);
	border-radius: 12px;
	background-color: var(--wp--preset--color--base, #ffffff);
	color: var(--wp--preset--color--contrast, #111111);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	cursor: pointer;
}

.izzis-chips {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.izzis-chips__item {
	display: flex;
	align-items: center;
	gap: 0.25rem;
}

/* Product grid */
.izzis-products {
	display: grid;
	grid-template-columns: repeat(var(--izzis-columns, 3), 1fr);
	gap: 1rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.izzis-block[data-columns="2"] .izzis-products { grid-template-columns: repeat(2, 1fr); }
.izzis-block[data-columns="3"] .izzis-products { grid-template-columns: repeat(3, 1fr); }
.izzis-block[data-columns="4"] .izzis-products { grid-template-columns: repeat(4, 1fr); }

/* Image ratio — constrain the image link wrapper and cover-fit the image */
.izzis-block[data-image-ratio="square"] .izzis-product__image-link,
.izzis-block[data-image-ratio="landscape"] .izzis-product__image-link,
.izzis-block[data-image-ratio="portrait"] .izzis-product__image-link {
	overflow: hidden; /* already set globally; restated here for clarity */
}

.izzis-block[data-image-ratio="square"] .izzis-product__image-link    { aspect-ratio: 1 / 1; }
.izzis-block[data-image-ratio="landscape"] .izzis-product__image-link { aspect-ratio: 4 / 3; }
.izzis-block[data-image-ratio="portrait"] .izzis-product__image-link  { aspect-ratio: 3 / 4; }

.izzis-block[data-image-ratio="square"] .izzis-product__image,
.izzis-block[data-image-ratio="landscape"] .izzis-product__image,
.izzis-block[data-image-ratio="portrait"] .izzis-product__image {
	height: 100%;
	object-fit: cover;
}

.izzis-product {
	display: flex;
	flex-direction: column;
}

.izzis-product__inner {
	display: flex;
	flex-direction: column;
	height: 100%;
}

.izzis-product__image-link {
	display: block;
	width: 100%;
	overflow: hidden;
}

.izzis-product__image {
	display: block;
	width: 100%;
	height: auto;
}

.izzis-product__body {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
}

.izzis-product__actions {
	margin-top: auto;
}

/* Pagination */
.izzis-pagination {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 0.25rem;
	width: 100%;
}

.izzis-pagination__btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.25rem;
	min-height: 2.25rem;
	padding: 0 0.5rem;
	cursor: pointer;
	line-height: 1;
	white-space: nowrap;
}

.izzis-pagination__btn--prev,
.izzis-pagination__btn--next {
	min-width: 2.75rem;
}

.izzis-pagination__btn--disabled {
	cursor: not-allowed;
	pointer-events: none;
	opacity: 0.35;
}

.izzis-pagination__ellipsis {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.25rem;
	min-height: 2.25rem;
	pointer-events: none;
	user-select: none;
}

.izzis-pagination__info {
	width: 100%;
	text-align: center;
}

/* Filter panels / fieldsets */
.izzis-filters {
	width: 100%;
}

.izzis-filter-panel {
	border: 0;
	margin: 0;
	padding: 0;
}

/* Accordion panel toggle button inside the legend */
.izzis-filter-panel__toggle {
	cursor: pointer;
	background: none;
	border: none;
	padding: 0;
	width: 100%;
	text-align: left;
	font: inherit;
}

/* CSS-only collapsed fallback (belt-and-suspenders alongside JS hidden attr) */
.izzis-filter-panel__toggle[aria-expanded="false"] + .izzis-filter-panel__body,
.izzis-filter-panel__toggle[aria-expanded="false"] ~ .izzis-filter-panel__body {
	display: none;
}

.izzis-filter-panel__list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.izzis-filter-panel__item {
	display: flex;
	align-items: flex-start;
}

.izzis-filter-panel__item[hidden] {
	display: none;
}

/* Show more / fewer button */
.izzis-show-more {
	background: none;
	border: none;
	cursor: pointer;
	padding: 0.25rem 0;
	display: block;
	font: inherit;
}

.izzis-checkbox {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	cursor: pointer;
}

/* Price range dual slider */
.izzis-price-range__slider {
	position: relative;
	width: 100%;
	height: 2em;
}

.izzis-price-range__input {
	position: absolute;
	top: 50%;
	left: 0;
	width: 100%;
	transform: translateY(-50%);
	pointer-events: none;
	-webkit-appearance: none;
	appearance: none;
	background: transparent;
}

.izzis-price-range__input::-webkit-slider-thumb {
	pointer-events: all;
	-webkit-appearance: none;
	appearance: none;
	cursor: pointer;
}

.izzis-price-range__input::-moz-range-thumb {
	pointer-events: all;
	cursor: pointer;
}

.izzis-price-range__inputs {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	flex-wrap: wrap;
}

.izzis-price-range__label {
	position: absolute !important;
	clip: rect(1px, 1px, 1px, 1px);
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.izzis-price-range__number {
	width: 5em;
	min-width: 0;
}

/* ─────────────────────────────────────────────────────────
   3. Transitions & Effects
───────────────────────────────────────────────────────── */

/* --- Custom properties (override in theme to tune speeds) --- */
:root {
	--izzis-speed-fast:   0.15s;
	--izzis-speed-base:   0.25s;
	--izzis-speed-slow:   0.4s;
	--izzis-ease:         cubic-bezier(0.4, 0, 0.2, 1);
	--izzis-ease-bounce:  cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* --- Product card hover lift --- */
.izzis-product__inner {
	transition:
		transform var(--izzis-speed-base) var(--izzis-ease),
		box-shadow var(--izzis-speed-base) var(--izzis-ease);
	will-change: transform;
}

.izzis-product__inner:hover {
	transform: translateY(-5px);
}

/* --- Product image zoom on hover --- */
.izzis-product__image {
	transition: transform var(--izzis-speed-slow) var(--izzis-ease);
	will-change: transform;
}

.izzis-product__image-link:hover .izzis-product__image,
.izzis-product__image-link:focus-within .izzis-product__image {
	transform: scale(1.07);
}

/* --- AJAX grid loading fade --- */
.izzis-grid {
	transition: opacity var(--izzis-speed-fast) var(--izzis-ease);
}

.izzis-grid[aria-busy="true"] {
	pointer-events: none;
	opacity: 0.35;
}

/* --- Loading skeleton pulse --- */
@keyframes izzis-skeleton-pulse {
	0%   { opacity: 1; }
	50%  { opacity: 0.4; }
	100% { opacity: 1; }
}

.izzis-grid[aria-busy="true"] .izzis-product__image,
.izzis-grid[aria-busy="true"] .izzis-product__title,
.izzis-grid[aria-busy="true"] .izzis-product__price {
	animation: izzis-skeleton-pulse 1.2s var(--izzis-ease) infinite;
}

/* --- Product stagger entrance (class added by JS) --- */
@keyframes izzis-product-enter {
	from {
		opacity: 0;
		transform: translateY(16px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

.izzis-product--entering {
	animation: izzis-product-enter var(--izzis-speed-slow) var(--izzis-ease) both;
}

/* --- Active filter chip entrance --- */
@keyframes izzis-chip-enter {
	from {
		opacity: 0;
		transform: scale(0.85) translateY(-4px);
	}
	to {
		opacity: 1;
		transform: scale(1) translateY(0);
	}
}

.izzis-chips__item {
	animation: izzis-chip-enter var(--izzis-speed-fast) var(--izzis-ease-bounce) both;
}

/* --- Chip remove button hover --- */
.izzis-chips__remove {
	transition:
		transform var(--izzis-speed-fast) var(--izzis-ease-bounce),
		opacity   var(--izzis-speed-fast) var(--izzis-ease);
}

.izzis-chips__remove:hover,
.izzis-chips__remove:focus-visible {
	transform: scale(1.3) rotate(10deg);
}

/* --- Clear-all chip button pulse on hover --- */
.izzis-chips__clear-all {
	transition: transform var(--izzis-speed-fast) var(--izzis-ease);
}

.izzis-chips__clear-all:hover,
.izzis-chips__clear-all:focus-visible {
	transform: scale(1.05);
}

/* --- Pagination button transitions --- */
.izzis-pagination__btn {
	transition:
		transform var(--izzis-speed-fast) var(--izzis-ease),
		opacity   var(--izzis-speed-fast) var(--izzis-ease);
}

.izzis-pagination__btn:hover:not(.izzis-pagination__btn--active):not(.izzis-pagination__btn--disabled),
.izzis-pagination__btn:focus-visible:not(.izzis-pagination__btn--disabled) {
	transform: translateY(-2px);
}

.izzis-pagination__btn:active:not(.izzis-pagination__btn--disabled) {
	transform: scale(0.93);
}

/* --- Filter toggle button scale --- */
.izzis-filter-toggle {
	transition: transform var(--izzis-speed-fast) var(--izzis-ease);
}

.izzis-filter-toggle:active {
	transform: scale(0.95);
}

/* --- Checkbox ripple on check --- */
.izzis-checkbox__input {
	transition: transform var(--izzis-speed-fast) var(--izzis-ease-bounce);
}

.izzis-checkbox__input:checked {
	transform: scale(1.15);
}

/* --- Price range thumb scale on drag --- */
.izzis-price-range__input::-webkit-slider-thumb:active {
	transform: scale(1.3);
}

.izzis-price-range__input::-moz-range-thumb:active {
	transform: scale(1.3);
}

/* --- Filter panel title — contains accordion toggle button (see .izzis-filter-panel__toggle) --- */
.izzis-filter-panel__title {
	display: block;
}

/* --- No-products message fade in --- */
.izzis-no-products {
	animation: izzis-product-enter var(--izzis-speed-base) var(--izzis-ease) both;
}

/* --- Error message fade in --- */
.izzis-error {
	animation: izzis-product-enter var(--izzis-speed-base) var(--izzis-ease) both;
}

/* ─────────────────────────────────────────────────────────
   4. Mobile: drawer mode  (< 768px)
───────────────────────────────────────────────────────── */

/*
 * Mobile drawer mode (< 768px).
 *
 * ALL selectors here use `.izzis-block` as a prefix so their specificity is
 * 0,2,0 instead of 0,1,0.  This is necessary because the site theme loads its
 * own stylesheet AFTER the plugin CSS and uses:
 *
 *   :root :where(.izzis-filter-toggle) { display: none }      — specificity 0,1,0
 *   :root :where(.izzis-sidebar)       { position: static }   — specificity 0,1,0
 *   :root :where(.izzis-sidebar__close){ display: none }      — specificity 0,1,0
 *
 * Equal-specificity rules declared later win the cascade, so the plugin's own
 * 0,1,0 rules would be silently overridden.  Using 0,2,0 here ensures the
 * plugin's functional mobile behaviour cannot be defeated by theme aesthetics.
 */
@media (max-width: 767px) {

	/* Show the filter toggle button */
	.izzis-block .izzis-filter-toggle {
		display: block;
	}

	/* Show the sidebar header row (title + close button) */
	.izzis-block .izzis-sidebar__header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		flex-shrink: 0;
		padding: 1rem;
	}

	/* Show the close button — header flex handles its position */
	.izzis-block .izzis-sidebar__close {
		display: block;
	}

	/*
	 * Take sidebar out of normal flow and position as a fixed off-canvas drawer.
	 * The theme overrides .izzis-sidebar to position:static at ≤1024px; the
	 * higher specificity here (.izzis-block .izzis-sidebar = 0,2,0) wins.
	 */
	.izzis-block .izzis-sidebar {
		position: fixed;
		top: 0;
		left: 0;
		width: 80vw;
		max-width: 320px;
		height: 100%;
		z-index: 100001;
		background-color: #fff;
		/*
		 * The sidebar itself does NOT scroll. overflow:hidden keeps it a clean
		 * fixed rectangle. Only the filters form inside scrolls (see below).
		 * display:flex + flex-direction:column let the inner fill the full height.
		 */
		overflow: hidden;
		display: flex;
		flex-direction: column;
		transform: translateX(-100%);
		transition: transform var(--izzis-speed-base) var(--izzis-ease);
		flex: none;
	}

	/* Sidebar open state */
	.izzis-block.izzis-block--drawer-open .izzis-sidebar {
		transform: translateX(0);
	}

	/* Main takes full width on mobile */
	.izzis-block .izzis-main {
		width: 100%;
	}

	/*
	 * Overlay backdrop (non-portaled) — always in layout on mobile, invisible until open.
	 * The :not() guard prevents double-styling after JS moves it to <body>.
	 */
	.izzis-block .izzis-overlay:not(.izzis-overlay--portaled) {
		display: block;
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		z-index: 100000;
		background-color: rgba(0, 0, 0, 0.5);
		opacity: 0;
		pointer-events: none;
		visibility: hidden;
		transition:
			opacity    var(--izzis-speed-base) var(--izzis-ease),
			visibility var(--izzis-speed-base) var(--izzis-ease);
	}

	.izzis-block.izzis-block--drawer-open .izzis-overlay:not(.izzis-overlay--portaled) {
		opacity: 1;
		pointer-events: auto;
		visibility: visible;
	}

	/*
	 * Sidebar inner fills the full sidebar height as a flex child,
	 * then acts as a flex column for its own children.
	 * min-height:0 is required — without it a flex child's implicit
	 * min-height:auto prevents it from shrinking below content size,
	 * which is exactly what broke scrolling before.
	 */
	.izzis-block .izzis-sidebar__inner {
		display: flex;
		flex-direction: column;
		position: static;
		flex: 1 1 auto;
		min-height: 0;
		overflow: hidden;
	}

	/*
	 * The filters form is the ONLY scrollable area inside the drawer.
	 * flex:1 makes it fill all remaining space between the close button
	 * (top) and the View Results footer (bottom). min-height:0 is again
	 * required so flex allows it to shrink and the overflow actually fires.
	 * -webkit-overflow-scrolling:touch enables iOS momentum / inertia.
	 */
	.izzis-block .izzis-filters {
		flex: 1 1 auto;
		min-height: 0;
		overflow-y: auto;
		padding: 0 1rem;
		-webkit-overflow-scrolling: touch;
		overscroll-behavior: contain;
	}

	/* Two-column grid on larger mobile (600–767px) for all column settings */
	.izzis-block .izzis-products,
	.izzis-block[data-columns="2"] .izzis-products,
	.izzis-block[data-columns="3"] .izzis-products,
	.izzis-block[data-columns="4"] .izzis-products {
		grid-template-columns: repeat(2, 1fr);
	}

	/*
	 * Right-side drawer: when the desktop layout puts the sidebar on the right,
	 * the mobile drawer should slide in from the right edge instead of the left.
	 * The JS only toggles .izzis-block--drawer-open; CSS handles the direction.
	 */
	.izzis-block .izzis-layout--sidebar-right .izzis-sidebar {
		left: auto;
		right: 0;
		transform: translateX(100%);
	}

	.izzis-block.izzis-block--drawer-open .izzis-layout--sidebar-right .izzis-sidebar {
		transform: translateX(0);
	}

	/* Stack topbar sections vertically on mobile */
	.izzis-topbar {
		flex-direction: column;
		align-items: stretch;
	}

	.izzis-topbar .izzis-active-filters,
	.izzis-topbar .izzis-toolbar {
		flex: 1 1 auto;
		width: 100%;
	}

	.izzis-sort {
		width: 100%;
	}

	/* ── Touch target minimums (WCAG 2.5.5 / Apple HIG 44px) ── */

	.izzis-block .izzis-filter-toggle,
	.izzis-block .izzis-sidebar__close {
		min-height: 44px;
		min-width: 44px;
	}

	.izzis-block .izzis-checkbox {
		min-height: 44px;
		padding-block: 0.35rem;
	}

	/* ── Price slider — larger thumbs for touch ── */

	.izzis-price-range__input::-webkit-slider-thumb {
		width: 28px;
		height: 28px;
	}

	.izzis-price-range__input::-moz-range-thumb {
		width: 28px;
		height: 28px;
	}

	/* ── Prevent iOS viewport zoom when focusing number inputs ── */

	.izzis-price-range__number {
		font-size: max(16px, 1em);
	}

	/*
	 * View Results footer — flex-shrink:0 keeps it pinned at the bottom of
	 * the flex column. No sticky needed since flex already handles placement.
	 */
	.izzis-block .izzis-sidebar__footer {
		display: block;
		flex-shrink: 0;
		padding: 1rem;
	}

	/*
	 * View Results CTA — full-width solid primary button matching the theme's
	 * "Add to Cart" style so it feels intentional, not like a default browser
	 * button.  Uses the same CSS variables as the theme palette.
	 */
	.izzis-block .izzis-view-results {
		display: block;
		width: 100%;
		box-sizing: border-box;
		text-align: center;
		background-color: var(--wp--preset--color--contrast, #111111);
		color: var(--wp--preset--color--base, #ffffff);
		font-weight: 700;
		text-transform: uppercase;
		letter-spacing: 0.05em;
		padding: 0.875rem 1.5rem;
		border: 3px solid var(--wp--preset--color--contrast, #111111);
		border-radius: 12px;
		cursor: pointer;
		transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
	}

	.izzis-block .izzis-view-results:hover {
		background-color: var(--wp--preset--color--accent-1, #e91e8c);
		border-color: var(--wp--preset--color--contrast, #111111);
		transform: translateY(-2px);
		box-shadow: 0 4px 0 var(--wp--preset--color--contrast, #111111);
	}

}

/* ─────────────────────────────────────────────────────────
   4b. Tablet: step down column count when sidebar is present (768px – 1024px)
───────────────────────────────────────────────────────── */

/*
 * At tablet widths (768–1024px) a 260px sidebar eats enough horizontal space
 * that 3- and 4-column grids produce unworkably narrow cards (~160px).
 * The `.izzis-block--has-sidebar` class is added by render.php only when the
 * filter sidebar is rendered, so blocks with filters disabled are unaffected.
 */
@media (max-width: 1024px) and (min-width: 768px) {

	.izzis-block--has-sidebar[data-columns="3"] .izzis-products {
		grid-template-columns: repeat(2, 1fr);
	}

	.izzis-block--has-sidebar[data-columns="4"] .izzis-products {
		grid-template-columns: repeat(3, 1fr);
	}

}

/*
 * Portaled overlay — JS appends .izzis-overlay to <body> and adds
 * .izzis-overlay--portaled so it escapes any ancestor stacking context,
 * overflow:hidden, or CSS transform that would misplace a fixed element.
 * Open / close state is toggled via .izzis-overlay--open directly.
 */
.izzis-overlay.izzis-overlay--portaled {
	display: block;
	position: fixed;
	inset: 0;
	z-index: 100000;
	background-color: rgba(0, 0, 0, 0.5);
	opacity: 0;
	pointer-events: none;
	visibility: hidden;
	transition:
		opacity    var(--izzis-speed-base) var(--izzis-ease),
		visibility var(--izzis-speed-base) var(--izzis-ease);
}

.izzis-overlay.izzis-overlay--portaled.izzis-overlay--open {
	opacity: 1;
	pointer-events: auto;
	visibility: visible;
}

/* ─────────────────────────────────────────────────────────
   5. Reduced-motion overrides
───────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {

	/* Kill all custom animations */
	.izzis-product--entering,
	.izzis-chips__item,
	.izzis-no-products,
	.izzis-error {
		animation: none;
	}

	/* Kill all transitions */
	.izzis-product__inner,
	.izzis-product__image,
	.izzis-grid,
	.izzis-chips__remove,
	.izzis-chips__clear-all,
	.izzis-pagination__btn,
	.izzis-block .izzis-filter-toggle,
	.izzis-checkbox__input,
	.izzis-block .izzis-sidebar,
	.izzis-overlay,
	.izzis-overlay.izzis-overlay--portaled {
		transition: none;
		animation: none;
	}

	/* Keep hover lifts off */
	.izzis-product__inner:hover,
	.izzis-product__image-link:hover .izzis-product__image {
		transform: none;
	}

}

/* ─────────────────────────────────────────────────────────
   6. Phones (< 600px) — single column + prevent overflow
───────────────────────────────────────────────────────── */

/*
 * On phones narrower than 600px, a 2-column grid produces cards that are
 * too narrow and causes horizontal overflow when the block uses alignfull
 * or alignwide alignment.
 *
 * The alignment breakout works by setting margin-left: calc(50% - 50vw)
 * and width: 100vw.  When the page has horizontal padding (e.g. the theme's
 * default 2rem = 32px per side), this formula creates a 32px right overflow
 * at any phone width, resulting in an unwanted horizontal scrollbar.
 *
 * Fix: reset the breakout on phones so the block respects the content area,
 * and force a single product column so no card content is ever clipped.
 *
 * Net result: 1-col < 600px, 2-col 600–767px, multi-col 768px+.
 */
@media (max-width: 599px) {

	/* Single-column product grid */
	.izzis-block .izzis-products,
	.izzis-block[data-columns="2"] .izzis-products,
	.izzis-block[data-columns="3"] .izzis-products,
	.izzis-block[data-columns="4"] .izzis-products {
		grid-template-columns: 1fr;
	}

	/*
	 * Reset alignment breakout — the calc(50% - 50vw) trick relies on the
	 * block sitting in a centered content column; at phone widths the rounding
	 * differences between 50% (of the padded content) and 50vw (of the full
	 * viewport) produce horizontal overflow.  Let the block sit naturally
	 * within the theme's content padding instead.
	 */
	.izzis-block.alignfull,
	.wp-block-izzis-products.alignfull,
	.izzis-block.alignwide,
	.wp-block-izzis-products.alignwide {
		width: 100%;
		max-width: 100%;
		margin-left: 0;
	}

}
