/* LIGHTBOX — the product gallery's full-screen viewer (PhotoSwipe v4), in our own design language.
   Third component migrated, 2026-09-02. Replaces WooCommerce's two bundled sheets, which
   `ostz_drop_woo_gallery_styles()` now dequeues: `photoswipe` and `photoswipe-default-skin`.

   ⚠ READ THIS BEFORE EDITING. The first half of this file is MECHANICS, not decoration — exactly
   the trap that the select2 sheet documented and that was still walked into on this project the
   same day. PhotoSwipe appends its markup to the end of <body> and drives it with transforms it
   computes in JavaScript; without the absolute positioning, the `--open` display switch and the
   transform origin below, the viewer does not merely look wrong, it renders as a stack of raw
   images at the bottom of the document with no way to close it.

   The second half is OURS: the sprite is gone (WooCommerce shipped a PNG for the icons), every
   control is drawn in CSS, and every colour is a token so the viewer follows the light/dark scheme
   like the rest of the site. */

/* ================================================================ MECHANICS
   Reproduced from PhotoSwipe's core stylesheet. Values are load-bearing. */

/*
 * ⚠⚠ PHYSICAL left/top BELOW, NOT the logical properties this codebase uses everywhere else — and
 * that is deliberate, measured, and the opposite of the house rule for a reason.
 *
 * PhotoSwipe positions the slides and the image with transforms it computes in JavaScript, in
 * PHYSICAL pixel coordinates. Writing `inset-inline-start: 0` anchors the image to the RIGHT edge
 * in an RTL document while the script keeps computing offsets from the left, so the two disagree:
 * MEASURED, the photo rendered at x=923 in a 1265px viewport and hung 308px off the screen.
 *
 * The rule «logical properties, never physical» governs OUR layout. It does not govern a
 * third-party widget's internal coordinate space. Our own chrome further down — the top bar, the
 * buttons, the caption, the arrows — is logical, and mirrors correctly.
 */
.pswp {
	display: none;
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	overflow: hidden;
	touch-action: none;
	/*
	 * ⚠ Above the cart's floating button, which sits at 99990. PhotoSwipe's own 1500 left that
	 * button painted on top of the full-screen photo — SEEN in a capture, not reasoned about. A
	 * full-screen viewer has to outrank every piece of persistent chrome on the site.
	 */
	z-index: 100010;
	-webkit-text-size-adjust: 100%;
	backface-visibility: hidden;
	outline: none;
}

.pswp * {
	box-sizing: border-box;
}

/* PhotoSwipe scales the image itself; a max-width would fight the transform. */
.pswp img {
	max-width: none;
}

/* The admin bar is fixed above everything; without this the viewer sits under it for a logged-in
   operator, which is exactly who is checking the gallery after uploading photos. */
.admin-bar .pswp {
	height: calc(100% - var(--wp-admin--admin-bar--height, 0px));
	top: var(--wp-admin--admin-bar--height, 0px);
}

/* 0.001 rather than 0: a true zero opacity skips the paint that makes the opening transition
   smooth. PhotoSwipe's own comment, kept because the reason is not obvious. */
.pswp--animate_opacity {
	opacity: .001;
	will-change: opacity;
	transition: opacity 333ms cubic-bezier(.4, 0, .22, 1);
}

.pswp--open {
	display: block;
}

.pswp--zoom-allowed .pswp__img {
	cursor: zoom-in;
}

.pswp--zoomed-in .pswp__img {
	cursor: grab;
}

.pswp--dragging .pswp__img {
	cursor: grabbing;
}

.pswp__bg {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	opacity: 0;
	transform: translateZ(0);
	backface-visibility: hidden;
	will-change: opacity;
	transition: opacity 333ms cubic-bezier(.4, 0, .22, 1);
	/* OURS: the page's own ground rather than a flat black, so the viewer belongs to the site. */
	background: var(--ostz-bg, #0b0c10);
}

.pswp__scroll-wrap {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	overflow: hidden;
}

/*
 * ⚠ `left/right/top/bottom: 0` rather than the `inset: 0` shorthand, and not for tidiness: an
 * absolutely positioned box given left AND right AND an explicit width is over-constrained, and
 * the side CSS discards depends on DIRECTION — it drops `right` in LTR and `left` in RTL. The
 * zoom-wrap below is exactly that box. Spelling the sides out keeps its origin at the physical
 * left in both directions, which is where PhotoSwipe's own transform maths puts it.
 */
.pswp__container,
.pswp__zoom-wrap {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	touch-action: none;
	backface-visibility: hidden;
}

.pswp__container,
.pswp__img {
	user-select: none;
	-webkit-user-select: none;
	-webkit-tap-highlight-color: transparent;
	-webkit-touch-callout: none;
}

.pswp__zoom-wrap {
	position: absolute;
	right: auto;
	left: 0;
	width: 100%;
	transform-origin: left top;
	transition: transform 333ms cubic-bezier(.4, 0, .22, 1);
}

.pswp--animated-in .pswp__bg,
.pswp--animated-in .pswp__zoom-wrap {
	transition: none;
}

.pswp__item {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	overflow: hidden;
}

.pswp__img {
	position: absolute;
	top: 0;
	left: 0;
	width: auto;
	height: auto;
}

.pswp__img--placeholder {
	backface-visibility: hidden;
}

.pswp__img--placeholder--blank {
	background: var(--ostz-bg-raised, #15171e);
}

/* PhotoSwipe hides controls the current view does not support by adding this class. It has to beat
   whatever the control's own rule says, which is why the platform ships it as !important — one of
   the two sanctioned uses. */
.pswp__element--disabled {
	display: none !important;
}

.pswp__error-msg {
	position: absolute;
	top: 50%;
	left: 0;
	width: 100%;
	margin-block-start: -8px;
	text-align: center;
	font-family: var(--ostz-font, Vazirmatn, Tahoma, sans-serif);
	font-size: var(--ostz-text-base);
	line-height: var(--ostz-leading-snug);
	color: var(--ostz-text-dim, #aab0be);
}

.pswp__error-msg a {
	color: var(--ostz-accent, #00e0d5);
	text-decoration: underline;
}

/* ================================================================ OUR SKIN
   No sprite. Every control is drawn here, so it recolours with the scheme and stays crisp at any
   pixel density — the PNG WooCommerce shipped needed a second copy for retina. */

.pswp__ui {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	visibility: visible;
	opacity: 1;
	z-index: 100020;
	transition: opacity 333ms cubic-bezier(.4, 0, .22, 1);
}

.pswp__top-bar {
	position: absolute;
	inset-block-start: 0;
	inset-inline: 0;
	display: flex;
	align-items: center;
	gap: var(--ostz-space-1, 4px);
	height: 56px;
	padding-inline: var(--ostz-space-3, 12px);
	background: color-mix(in srgb, var(--ostz-bg, #0b0c10) 78%, transparent);
	backdrop-filter: blur(8px);
}

/* ⚠ RTL: the controls belong at the inline END of the bar, and the counter at the start. Using
   `margin-inline-start: auto` rather than a physical side is what keeps that true in both
   directions — the viewer is chrome we own, so it follows the document, not PhotoSwipe's LTR
   assumption. */
.pswp__button {
	position: relative;
	flex: 0 0 auto;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 0;
	border-radius: var(--ostz-radius-sm, 10px);
	background: transparent;
	box-shadow: none;
	color: var(--ostz-text, #f2f4f8);
	cursor: pointer;
	opacity: .8;
	transition: opacity .18s ease, background .18s ease;
	appearance: none;
	-webkit-appearance: none;
}

.pswp__button:first-of-type {
	margin-inline-start: auto;
}

.pswp__button:hover,
.pswp__button:focus-visible {
	opacity: 1;
	background: var(--ostz-bg-raised-2, #1b1e27);
}

.pswp__button:focus-visible {
	outline: 2px solid var(--ostz-accent, #00e0d5);
	outline-offset: 2px;
}

.pswp__button::-moz-focus-inner {
	padding: 0;
	border: 0;
}

/*
 * ⚠ The GLYPHS below are positioned physically (top/left/right/bottom) while the BUTTONS that hold
 * them are placed logically. That split is deliberate: where a control sits in the bar must mirror
 * with the document, but the drawing inside it must not. Positioning the parts of an icon with
 * logical properties mirrors them independently and takes the icon apart — MEASURED and looked at:
 * the magnifier's lens and its handle ended up on opposite sides and read as a speech balloon, and
 * the fullscreen brackets kept their LTR border sides while moving to the opposite corners.
 */

/* CLOSE — two bars crossed. */
.pswp__button--close::before,
.pswp__button--close::after {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	width: 17px;
	height: 2px;
	border-radius: 2px;
	background: currentColor;
}

.pswp__button--close::before {
	transform: translate(-50%, -50%) rotate(45deg);
}

.pswp__button--close::after {
	transform: translate(-50%, -50%) rotate(-45deg);
}

/* ZOOM — a lens with a handle. The handle flips to the other diagonal when zoomed in, so the two
   states differ by SHAPE and not only by which tooltip is showing. */
.pswp__button--zoom::before {
	content: '';
	position: absolute;
	top: 12px;
	left: 12px;
	width: 15px;
	height: 15px;
	border: 2px solid currentColor;
	border-radius: 50%;
}

.pswp__button--zoom::after {
	content: '';
	position: absolute;
	top: 26px;
	left: 25px;
	width: 9px;
	height: 2px;
	border-radius: 2px;
	background: currentColor;
	transform: rotate(45deg);
	transform-origin: left center;
}

.pswp--zoomed-in .pswp__button--zoom::after {
	transform: rotate(-45deg);
}

/* FULLSCREEN — two opposing corner brackets. */
.pswp__button--fs::before,
.pswp__button--fs::after {
	content: '';
	position: absolute;
	width: 12px;
	height: 12px;
	border: 2px solid currentColor;
}

.pswp__button--fs::before {
	top: 13px;
	left: 13px;
	border-width: 2px 0 0 2px;
}

.pswp__button--fs::after {
	bottom: 13px;
	right: 13px;
	border-width: 0 2px 2px 0;
}

/* SHARE — WooCommerce leaves this off, but the control exists in the template and an unstyled
   square in the bar would read as broken. Three nodes and two links. */
.pswp__button--share::before {
	content: '';
	position: absolute;
	top: 15px;
	left: 17px;
	width: 11px;
	height: 15px;
	border: 2px solid currentColor;
	border-radius: 3px;
}

/* ARROWS — chevrons, and they MIRROR: in an RTL document «next» points to the left, which is
   already what PhotoSwipe's left button does, so only the glyph needs turning. */
.pswp__button--arrow--left,
.pswp__button--arrow--right {
	position: absolute;
	inset-block-start: 50%;
	width: 56px;
	height: 88px;
	margin-block-start: -44px;
	border-radius: var(--ostz-radius, 16px);
	background: color-mix(in srgb, var(--ostz-bg, #0b0c10) 55%, transparent);
	opacity: .75;
}

.pswp__button--arrow--left {
	inset-inline-start: 8px;
}

.pswp__button--arrow--right {
	inset-inline-end: 8px;
}

.pswp__button--arrow--left::before,
.pswp__button--arrow--right::before {
	content: '';
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	width: 15px;
	height: 15px;
	border-style: solid;
	border-color: currentColor;
	border-width: 2px 2px 0 0;
}

.pswp__button--arrow--left::before {
	transform: translate(-30%, -50%) rotate(-135deg);
}

.pswp__button--arrow--right::before {
	transform: translate(-70%, -50%) rotate(45deg);
}

/* Touch devices have no hover, so the arrows stay visible there. */
.pswp--touch .pswp__button--arrow--left,
.pswp--touch .pswp__button--arrow--right {
	visibility: visible;
}

.pswp__counter {
	flex: 0 0 auto;
	height: 56px;
	padding-inline: var(--ostz-space-3, 12px);
	color: var(--ostz-text-dim, #aab0be);
	font-family: var(--ostz-font, Vazirmatn, Tahoma, sans-serif);
	font-size: var(--ostz-text-sm);
	font-weight: var(--ostz-weight-bold);
	line-height: 56px;
	opacity: .9;
	/* A «۲ / ۵» run is Latin-ordered digits inside an RTL bar; isolate or it reads backwards. */
	unicode-bidi: isolate;
}

.pswp__caption {
	position: absolute;
	inset-block-end: 0;
	inset-inline: 0;
	min-height: 44px;
	background: color-mix(in srgb, var(--ostz-bg, #0b0c10) 78%, transparent);
	backdrop-filter: blur(8px);
}

.pswp__caption__center {
	max-width: 760px;
	margin-inline: auto;
	padding: 12px 16px;
	color: var(--ostz-text-dim, #aab0be);
	font-family: var(--ostz-font, Vazirmatn, Tahoma, sans-serif);
	font-size: var(--ostz-text-sm);
	line-height: var(--ostz-leading-body);
	text-align: center;
}

.pswp__caption--empty {
	display: none;
}

.pswp__caption--fake {
	visibility: hidden;
}

/* PRELOADER — one ring, no sprite and no donut geometry. */
.pswp__preloader {
	position: absolute;
	inset-block-start: 6px;
	inset-inline-start: 50%;
	width: 44px;
	height: 44px;
	margin-inline-start: -22px;
	opacity: 0;
	transition: opacity .25s ease;
	will-change: opacity;
}

.pswp__preloader--active {
	opacity: 1;
}

.pswp__preloader__icn {
	position: absolute;
	inset-block-start: 12px;
	inset-inline-start: 12px;
	width: 20px;
	height: 20px;
	border: 2px solid color-mix(in srgb, var(--ostz-text, #f2f4f8) 25%, transparent);
	border-block-start-color: var(--ostz-accent, #00e0d5);
	border-radius: 50%;
	animation: ostz-pswp-spin .9s linear infinite;
}

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

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

	.pswp__preloader__icn {
		animation-duration: 3s;
	}

	.pswp--animate_opacity,
	.pswp__bg,
	.pswp__zoom-wrap,
	.pswp__ui {
		transition-duration: 1ms;
	}
}

/* The share sheet, styled so it is not a white box on a dark viewer if it is ever switched on. */
.pswp__share-modal {
	position: absolute;
	inset: 0;
	display: block;
	padding: 10px;
	background: color-mix(in srgb, var(--ostz-bg, #0b0c10) 60%, transparent);
	opacity: 0;
	z-index: 100030;
	transition: opacity .25s ease;
	will-change: opacity;
	-webkit-backdrop-filter: blur(6px);
	backdrop-filter: blur(6px);
}

.pswp__share-modal--hidden {
	display: none;
}

.pswp__share-modal--fade-in {
	opacity: 1;
}

.pswp__share-tooltip {
	position: absolute;
	inset-block-start: 56px;
	inset-inline-end: 44px;
	width: 220px;
	border: 1px solid var(--ostz-line-strong, #333846);
	border-radius: var(--ostz-radius, 16px);
	background: var(--ostz-bg-raised, #15171e);
	box-shadow: 0 18px 40px rgba(0, 0, 0, .55);
	overflow: hidden;
	transform: translateY(6px);
	transition: transform .25s ease;
	will-change: transform;
	z-index: 100040;
}

.pswp__share-modal--fade-in .pswp__share-tooltip {
	transform: translateY(0);
}

.pswp__share-tooltip a {
	display: block;
	padding: 10px 14px;
	color: var(--ostz-text, #f2f4f8);
	font-family: var(--ostz-font, Vazirmatn, Tahoma, sans-serif);
	font-size: var(--ostz-text-base);
	text-decoration: none;
}

.pswp__share-tooltip a:hover {
	background: var(--ostz-bg-raised-2, #1b1e27);
	color: var(--ostz-accent, #00e0d5);
}

/* ---- UI states PhotoSwipe toggles ---- */

.pswp__ui--hidden .pswp__top-bar,
.pswp__ui--hidden .pswp__caption,
.pswp__ui--hidden .pswp__button--arrow--left,
.pswp__ui--hidden .pswp__button--arrow--right {
	opacity: 0;
}

.pswp__ui--idle .pswp__top-bar,
.pswp__ui--idle .pswp__button--arrow--left,
.pswp__ui--idle .pswp__button--arrow--right {
	opacity: 0;
}

.pswp__ui--one-slide .pswp__button--arrow--left,
.pswp__ui--one-slide .pswp__button--arrow--right,
.pswp__ui--one-slide .pswp__counter {
	display: none;
}

.pswp__ui--fit .pswp__top-bar,
.pswp__ui--fit .pswp__caption {
	background: color-mix(in srgb, var(--ostz-bg, #0b0c10) 55%, transparent);
}
