/**
 * Art Gallery for WooCommerce — front-end styles.
 *
 * Minimalist art-gallery look: clean white cards, subtle shadows,
 * sold badges, hover overlay, responsive masonry columns.
 */

/* ---------- Gallery container ---------- */

.art-gallery {
	max-width: 100%;
	margin: 0 auto;
}

/* ---------- Design tokens ----------
 *
 * Declared on :root as well as the two roots the plugin actually renders, so
 * the commission pop-up can read them too — it is printed at wp_footer,
 * outside any .art-gallery wrapper, and used to hard-code every colour.
 *
 * The block / shortcode / Elementor widget print only the title custom
 * properties that differ from these defaults on the .art-gallery wrapper, so
 * an untouched gallery keeps inheriting the theme font.
 */

:root,
.art-gallery,
.art-gallery-popup {
	--ag-title-font: inherit;
	--ag-title-size: 15px;
	--ag-title-weight: 500;
	--ag-title-transform: none;
	--ag-title-spacing: normal;
	--ag-title-line-height: 1.35;

	--ag-accent: #e07b35;
	/* Same hue as --ag-accent; kept separate so re-theming the accent also
	 * re-themes the focus ring, which used to be a hard-coded rgba(). */
	--ag-accent-soft: rgba(224, 123, 53, 0.22);

	--ag-surface: #fff;
	--ag-surface-sunken: #f5f5f5;
	--ag-surface-hover: #e8e8e8;
	--ag-text: #1d1d1f;
	/* 4.6:1 on white — the old #8a8a8a/#94a3b8/#9a9a9a greys were 2.6–3.4:1,
	 * and one of them carries the AJAX error message. */
	--ag-muted: #62626b;
	--ag-border: #dfe3e8;
	/* Dark enough that white overlay text clears 4.5:1 even over a white-ground
	 * watercolour, which is most of what an art gallery actually hangs. */
	--ag-scrim: rgba(14, 14, 16, 0.72);
	/* Text printed on top of a scrim. Stays white in dark mode too — the scrim
	 * darkens in both themes rather than inverting. */
	--ag-on-scrim: #fff;
	--ag-badge-bg: rgba(14, 14, 16, 0.88);
	--ag-danger: #b3261e;
	--ag-success: #2e7d32;
	--ag-pill-border: var(--ag-border);
	--ag-pill-muted: var(--ag-muted);
	--ag-pill-text: var(--ag-text);
	--ag-pill-height: 46px;
	--ag-veil: rgba(255, 255, 255, 0.72);
}

/* Visually hidden, still announced. WordPress ships .screen-reader-text but
 * only on the admin side, so the front end needs its own. */
.art-gallery__sr-only {
	position: absolute !important;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* ---------- Toolbar / filters ----------
 *
 * Pill-shaped search box + dropdowns on a single wrapping row. A pill whose
 * value is no longer the default gets the accent outline, so the visitor can
 * see at a glance which filters are narrowing the grid.
 */

.art-gallery__toolbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 14px;
	margin-bottom: 18px;
}

/* Shared pill shape for the search box and every dropdown. */
.art-gallery__search,
.art-gallery__select-wrap {
	box-sizing: border-box;
	display: inline-flex;
	align-items: center;
	height: var(--ag-pill-height);
	background: var(--ag-surface);
	border: 1px solid var(--ag-pill-border);
	border-radius: 999px;
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* Active = value differs from the "all / default" option. */
.art-gallery__search.is-active,
.art-gallery__select-wrap.is-active {
	border: 1.5px solid var(--ag-accent);
}

.art-gallery__select-wrap.is-active::after {
	border-color: var(--ag-accent);
}

.art-gallery__search:focus-within,
.art-gallery__select-wrap:focus-within {
	border-color: var(--ag-accent);
	box-shadow: 0 0 0 3px var(--ag-accent-soft);
}

/* Search box. */
.art-gallery__search {
	flex: 1 1 260px;
	gap: 10px;
	padding: 0 20px;
	min-width: 0;
}

.art-gallery__search svg {
	flex-shrink: 0;
	color: var(--ag-pill-muted);
}

.art-gallery__search-input {
	flex: 1 1 auto;
	min-width: 0;
	height: 100%;
	margin: 0;
	padding: 0;
	font-size: 15px;
	font-family: inherit;
	line-height: normal;
	color: var(--ag-pill-text);
	background: transparent;
	border: none;
	border-radius: 0;
	outline: none;
	box-shadow: none;
	-webkit-appearance: none;
	appearance: none;
}

.art-gallery__search-input::placeholder {
	color: var(--ag-pill-muted);
	opacity: 1;
}

/* Hide the browser's own "clear" affordance — we ship our own button. */
.art-gallery__search-input::-webkit-search-cancel-button,
.art-gallery__search-input::-webkit-search-decoration {
	-webkit-appearance: none;
	appearance: none;
}

.art-gallery__search-clear {
	box-sizing: border-box;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	width: 20px;
	height: 20px;
	min-width: 0;
	min-height: 0;
	margin: 0;
	padding: 0;
	color: var(--ag-pill-muted);
	background: transparent;
	border: none;
	border-radius: 50%;
	box-shadow: none;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
	transition: color 0.15s ease, background 0.15s ease;
}

.art-gallery__search-clear:hover,
.art-gallery__search-clear:focus-visible {
	color: var(--ag-text);
	background: var(--ag-surface-sunken);
}

.art-gallery__search-clear[hidden] {
	display: none;
}

/* Dropdowns. */
.art-gallery__select-wrap {
	position: relative;
	flex: 0 0 auto;
}

.art-gallery__select {
	height: 100%;
	min-width: 150px;
	max-width: 100%;
	margin: 0;
	padding: 0 38px 0 20px;
	font-size: 15px;
	font-family: inherit;
	line-height: normal;
	color: var(--ag-pill-text);
	cursor: pointer;
	outline: none;
	background: transparent !important;
	background-image: none !important;
	border: none !important;
	border-radius: 999px;
	box-shadow: none !important;
	-webkit-appearance: none !important;
	-moz-appearance: none !important;
	appearance: none !important;
}

.art-gallery__select::-moz-focus-inner {
	border: 0;
}

/* Custom chevron — native select arrows differ wildly between browsers. */
.art-gallery__select-wrap::after {
	content: '';
	position: absolute;
	top: 50%;
	right: 18px;
	width: 8px;
	height: 8px;
	border-right: 2px solid var(--ag-pill-muted);
	border-bottom: 2px solid var(--ag-pill-muted);
	transform: translateY(-50%) rotate(45deg);
	pointer-events: none;
}

.art-gallery__toolbar.is-busy .art-gallery__select,
.art-gallery__toolbar.is-busy .art-gallery__search-input {
	cursor: wait;
}

@media (max-width: 680px) {
	.art-gallery__search {
		flex-basis: 100%;
	}

	.art-gallery__select-wrap {
		flex: 1 1 auto;
	}

	.art-gallery__select {
		width: 100%;
		min-width: 0;
	}
}

/* ---------- Count line ---------- */

/* Doubles as the error channel for a failed AJAX refresh, so it has to be
 * properly legible rather than decorative grey. */
.art-gallery__count {
	margin: 0 0 14px;
	font-size: 13px;
	color: var(--ag-muted);
}

/* ---------- Masonry grid ---------- */

.art-gallery__grid {
	position: relative;
	margin: 0 -10px; /* compensates item gutters */
}

.art-gallery__item {
	box-sizing: border-box;
	float: left;
	padding: 0 10px 20px;
	background: transparent;
}

/* Columns: 3 or 4 on desktop, 2 on tablet, 1 on mobile. */
.art-gallery--cols-3 .art-gallery__item { width: 33.3333%; }
.art-gallery--cols-4 .art-gallery__item { width: 25%; }

@media (max-width: 1024px) {
	.art-gallery--cols-3 .art-gallery__item,
	.art-gallery--cols-4 .art-gallery__item { width: 50%; }
}

@media (max-width: 640px) {
	.art-gallery--cols-3 .art-gallery__item,
	.art-gallery--cols-4 .art-gallery__item { width: 100%; }
}

/* ---------- Card ---------- */

.art-gallery__media {
	position: relative;
	overflow: hidden;
	background: var(--ag-surface-sunken);
}

.art-gallery__link {
	display: block;
}

.art-gallery__img {
	display: block;
	width: 100%;
	height: auto;
	transition: transform 0.5s ease;
}

.art-gallery__media:hover .art-gallery__img {
	transform: scale(1.03);
}

/* Sold badge. */
.art-gallery__badge {
	position: absolute;
	top: 12px;
	left: 12px;
	z-index: 2;
	padding: 5px 10px;
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--ag-on-scrim);
	background: var(--ag-badge-bg);
	pointer-events: none;
}

/* Hover overlay. */
.art-gallery__overlay {
	position: absolute;
	inset: 0;
	z-index: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 12px;
	padding: 20px;
	background: var(--ag-scrim);
	opacity: 0;
	transition: opacity 0.3s ease;
}

/* `:focus-within` on the whole card, not just on the overlay: the title link
 * sits in the meta block below the image, outside the overlay entirely, and a
 * keyboard visitor who has reached the card should see the same two actions a
 * mouse visitor gets on hover. */
.art-gallery__media:hover .art-gallery__overlay,
.art-gallery__item:focus-within .art-gallery__overlay {
	opacity: 1;
}

.art-gallery__overlay-view,
.art-gallery__btn {
	box-sizing: border-box;
	display: inline-block;
	max-width: 100%;
	padding: 9px 18px;
	font-size: 13px;
	font-weight: 600;
	line-height: 1.3;
	letter-spacing: 0.04em;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
	transition: background 0.2s ease, color 0.2s ease;
}

.art-gallery__overlay-view {
	color: var(--ag-on-scrim);
	border: 1px solid rgba(255, 255, 255, 0.85);
	background: transparent;
}

.art-gallery__overlay-view:hover,
.art-gallery__overlay-view:focus-visible {
	color: var(--ag-text);
	background: var(--ag-surface);
}

/* Solid buttons — the overlay behind them is dark, so they always carry
 * their own background/colour instead of inheriting the theme's link
 * styles (which used to make the add-to-cart label unreadable). */
.art-gallery__btn--commission,
.art-gallery__btn--cart {
	color: var(--ag-text);
	border: 1px solid var(--ag-surface);
	background: var(--ag-surface);
	box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
}

.art-gallery__btn--commission:hover,
.art-gallery__btn--commission:focus-visible,
.art-gallery__btn--cart:hover,
.art-gallery__btn--cart:focus-visible {
	color: var(--ag-text);
	background: var(--ag-surface-hover);
}

/* Beat theme link colours that would otherwise win on specificity. */
.art-gallery .art-gallery__btn--cart,
.art-gallery .art-gallery__btn--cart:visited {
	color: var(--ag-text);
}

/* Same ring as the card links — the buttons live on the dark scrim, so the
 * accent alone is not always separable; the white halo guarantees it. */
.art-gallery__overlay-view:focus-visible,
.art-gallery__btn:focus-visible {
	outline: 2px solid var(--ag-accent);
	outline-offset: 2px;
	box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.6);
}

/* Meta under the image. */
.art-gallery__meta {
	padding: 12px 2px 0;
	text-align: left;
}

/* Two class names on purpose. The title is an <h3>, and both themes and
 * theme.json global styles target headings — inside the block editor canvas
 * `.editor-styles-wrapper h3` (0,1,1) beat a lone `.art-gallery__title`
 * (0,1,0) and the typography settings appeared to do nothing in the preview. */
.art-gallery .art-gallery__title {
	margin: 0 0 4px;
	font-family: var(--ag-title-font, inherit);
	font-size: var(--ag-title-size, 15px);
	font-weight: var(--ag-title-weight, 500);
	line-height: var(--ag-title-line-height, 1.35);
	letter-spacing: var(--ag-title-spacing, normal);
	text-transform: var(--ag-title-transform, none);
}

.art-gallery .art-gallery__title a {
	color: var(--ag-text, #1d1d1f);
	font: inherit;
	letter-spacing: inherit;
	text-transform: inherit;
	text-decoration: none;
}

.art-gallery .art-gallery__title a:hover {
	text-decoration: underline;
}

/* Themes routinely null out the UA focus ring globally, which leaves keyboard
 * visitors with no way to tell which artwork they are on. `.art-gallery__link`
 * (the image) is deliberately absent: it carries tabindex="-1", so it is not a
 * keyboard target and can never match :focus-visible. */
.art-gallery .art-gallery__title a:focus-visible {
	outline: 2px solid var(--ag-accent, #e07b35);
	outline-offset: 3px;
	text-decoration: underline;
}

.art-gallery__price {
	margin-bottom: 4px;
	font-size: 14px;
	color: var(--ag-text);
}

.art-gallery__price del {
	color: var(--ag-muted);
}

.art-gallery__status {
	display: inline-block;
	font-size: 10px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

.art-gallery__status.is-sold {
	color: var(--ag-danger);
}

.art-gallery__status.is-available {
	color: var(--ag-success);
}

/* Empty state. */
.art-gallery__empty {
	padding: 40px 20px;
	text-align: center;
	color: var(--ag-muted);
}

/* Gentle entrance after AJAX refresh. */
@keyframes art-gallery-fade-in {
	from {
		opacity: 0;
		transform: translateY(8px);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

.art-gallery__grid.is-refreshing .art-gallery__item {
	animation: art-gallery-fade-in 0.45s ease both;
}

/* ---------- Loading state ----------
 *
 * A filter change that needs the server used to look like nothing happened
 * until the new cards appeared. The grid now veils itself and shows a spinner
 * near the top of the grid (not its vertical centre — a tall masonry grid
 * would push a centred spinner off screen).
 */

.art-gallery__grid.is-loading {
	pointer-events: none;
}

.art-gallery__grid.is-loading::before {
	content: '';
	position: absolute;
	inset: -10px;
	z-index: 3;
	background: var(--ag-veil);
	animation: art-gallery-fade-in 0.15s ease both;
}

.art-gallery__grid.is-loading::after {
	content: '';
	position: absolute;
	top: 28px;
	left: 50%;
	z-index: 4;
	width: 28px;
	height: 28px;
	margin-left: -14px;
	border: 2px solid var(--ag-border);
	border-top-color: var(--ag-accent, #e07b35);
	border-radius: 50%;
	animation: art-gallery-spin 0.7s linear infinite;
}

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

/* ---------- Commission pop-up ---------- */

.art-gallery-popup {
	position: fixed;
	inset: 0;
	z-index: 99999;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 20px;
	visibility: hidden;
	opacity: 0;
	transition: opacity 0.25s ease, visibility 0.25s ease;
}

.art-gallery-popup.is-open {
	visibility: visible;
	opacity: 1;
}

.art-gallery-popup__backdrop {
	position: absolute;
	inset: 0;
	background: var(--ag-scrim);
}

.art-gallery-popup__dialog {
	position: relative;
	box-sizing: border-box;
	width: 100%;
	max-width: 580px;
	max-height: 90vh;
	overflow-y: auto;
	padding: 46px 30px 30px;
	background: var(--ag-surface);
	box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}

/* Close button — an SVG glyph inside a flex-centred square, so the cross
 * sits dead centre regardless of the theme's font metrics/line-height
 * (a text "×" is optically off-centre in most typefaces). */
.art-gallery-popup__close {
	position: absolute;
	top: 10px;
	right: 10px;
	box-sizing: border-box;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	min-width: 0;
	min-height: 0;
	margin: 0;
	padding: 0;
	font-size: 0;
	line-height: 0;
	color: var(--ag-text);
	cursor: pointer;
	border: none;
	border-radius: 50%;
	background: none;
	box-shadow: none;
	-webkit-appearance: none;
	appearance: none;
	transition: color 0.2s ease, background 0.2s ease;
}

.art-gallery-popup__close svg {
	display: block;
	width: 18px;
	height: 18px;
}

.art-gallery-popup__close:hover,
.art-gallery-popup__close:focus-visible {
	color: var(--ag-danger);
	background: var(--ag-surface-sunken);
}

.art-gallery-popup__close:focus-visible {
	outline: 2px solid var(--ag-accent);
	outline-offset: 2px;
}

.art-gallery-popup__content {
	display: flex;
	gap: 20px;
	align-items: flex-start;
	margin-bottom: 20px;
}

.art-gallery-popup__thumb {
	width: 160px;
	/* Fixed square rather than height:auto — the image arrives only when the
	 * dialog opens, and a height that depends on it would reflow the form the
	 * moment it loads. */
	aspect-ratio: 1;
	flex: 0 0 160px;
	object-fit: cover;
	background: var(--ag-surface-sunken);
}

/* No artwork image on the product — the <img> is left without a src and would
 * otherwise render as a broken-image glyph. */
.art-gallery-popup__thumb:not([src]),
.art-gallery-popup__thumb[src=""] {
	display: none;
}

.art-gallery-popup__title {
	margin: 0 0 8px;
	font-size: 18px;
	font-weight: 600;
}

.art-gallery-popup__hint {
	margin: 0;
	font-size: 14px;
	line-height: 1.5;
	color: var(--ag-muted);
}

/* Built-in form. */
.art-gallery-popup__field {
	margin: 0 0 14px;
}

.art-gallery-popup__field label {
	display: block;
	margin-bottom: 5px;
	font-size: 13px;
	font-weight: 500;
}

.art-gallery-popup__field input,
.art-gallery-popup__field textarea {
	box-sizing: border-box;
	width: 100%;
	padding: 10px 12px;
	font-size: 14px;
	font-family: inherit;
	color: var(--ag-text);
	background: var(--ag-surface);
	border: 1px solid var(--ag-border);
	border-radius: 2px;
}

.art-gallery-popup__field input:focus,
.art-gallery-popup__field textarea:focus {
	outline: none;
	border-color: var(--ag-accent);
	box-shadow: 0 0 0 3px var(--ag-accent-soft);
}

.art-gallery-popup__submit {
	padding: 11px 24px;
	font-size: 14px;
	font-weight: 600;
	/* Deliberately surface-on-text rather than #fff-on-#1d1d1f: the pair
	 * inverts by itself when the dark tokens kick in. */
	color: var(--ag-surface);
	cursor: pointer;
	border: none;
	background: var(--ag-text);
	transition: background 0.2s ease;
}

.art-gallery-popup__submit:hover {
	background: var(--ag-muted);
}

.art-gallery-popup__submit:focus-visible {
	outline: 2px solid var(--ag-accent);
	outline-offset: 2px;
}

.art-gallery-popup__submit:disabled {
	opacity: 0.6;
	cursor: wait;
}

.art-gallery-popup__result {
	margin-top: 12px;
	font-size: 14px;
}

.art-gallery-popup__result.is-success {
	color: var(--ag-success);
}

.art-gallery-popup__result.is-error {
	color: var(--ag-danger);
}

@media (max-width: 640px) {
	.art-gallery-popup__content {
		flex-direction: column;
	}

	.art-gallery-popup__thumb {
		width: 100%;
		aspect-ratio: 16 / 9;
		flex-basis: auto;
	}
}

/* ---------- Reduced motion ----------
 *
 * The masonry re-layout is animated from JS (art-gallery.js reads this same
 * preference), so what is left here is everything CSS owns: the image zoom,
 * the overlay and pill transitions, the entrance animation and the spinner —
 * which is slowed rather than stopped, because a frozen spinner reads as a
 * hung page.
 */

@media (prefers-reduced-motion: reduce) {
	.art-gallery__img,
	.art-gallery__overlay,
	.art-gallery__overlay-view,
	.art-gallery__btn,
	.art-gallery__search,
	.art-gallery__select-wrap,
	.art-gallery__search-clear,
	.art-gallery-popup,
	.art-gallery-popup__close,
	.art-gallery-popup__submit {
		transition: none !important;
	}

	.art-gallery__media:hover .art-gallery__img {
		transform: none;
	}

	.art-gallery__grid.is-refreshing .art-gallery__item,
	.art-gallery__grid.is-loading::before {
		animation: none;
	}

	.art-gallery__grid.is-loading::after {
		animation-duration: 2s;
	}
}

/* ---------- Print ----------
 *
 * Masonry positions every card absolutely and sets an explicit height on the
 * grid, which prints as one page of overlapping cards followed by blank space.
 * Undoing the inline layout hands the flow back to the browser, which then
 * paginates properly.
 */

@media print {
	.art-gallery__toolbar,
	.art-gallery__overlay,
	.art-gallery__search,
	.art-gallery-popup,
	.art-gallery noscript {
		display: none !important;
	}

	.art-gallery__grid {
		height: auto !important;
		margin: 0;
	}

	.art-gallery__item {
		position: static !important;
		left: auto !important;
		top: auto !important;
		width: 50% !important;
		padding: 0 8px 16px;
		transform: none !important;
		/* Never split a card across a page break. */
		break-inside: avoid;
		page-break-inside: avoid;
	}

	.art-gallery__media {
		background: none;
	}

	.art-gallery__img {
		transform: none !important;
	}

	.art-gallery__badge {
		color: #000;
		background: none;
		border: 1px solid #000;
	}

	/* A printed catalogue is useless without a way back to the listing. */
	.art-gallery .art-gallery__title a::after {
		content: " — " attr(href);
		font-size: 10px;
		font-weight: 400;
		word-break: break-all;
	}
}

/* ---------- Forced colours (Windows high-contrast) ----------
 *
 * The overlay and badge rely on a translucent dark background that the mode
 * discards, leaving white-on-white. Repainting them in system colours keeps
 * them readable, and the card gains a real border where the shadow used to be.
 */

@media (forced-colors: active) {
	.art-gallery__overlay,
	.art-gallery__badge {
		background: Canvas;
		color: CanvasText;
		border: 1px solid CanvasText;
		forced-color-adjust: none;
	}

	.art-gallery__overlay-view,
	.art-gallery__btn {
		color: LinkText;
		border: 1px solid LinkText;
		background: Canvas;
	}

	.art-gallery__search,
	.art-gallery__select-wrap,
	.art-gallery-popup__dialog {
		border: 1px solid CanvasText;
	}

	.art-gallery .art-gallery__title a:focus-visible,
	.art-gallery__overlay-view:focus-visible,
	.art-gallery__btn:focus-visible,
	.art-gallery-popup__close:focus-visible,
	.art-gallery-popup__submit:focus-visible {
		outline: 2px solid Highlight;
		outline-offset: 2px;
		box-shadow: none;
	}
}
