/*
 * Quantity stepper on the catalogue card.
 *
 * Printed by `Catalog\CardQuantity`, so styled here — the plugin owns every
 * class it writes (docs/design/block-css-contract.md). The row that puts this
 * beside the button belongs to whoever styles the button wrapper, which is the
 * theme.
 */
.gsl-qty {
	display: flex;
	align-items: stretch;
	flex: 1 1 auto;
	height: 40px;
	border: 1px solid var(--wp--preset--color--border-strong);
	border-radius: var(--wp--custom--radius--small);
	overflow: hidden;
	background: var(--wp--preset--color--base);
}

.gsl-qty__step {
	/* Rapid taps near the step must not trigger the browser double-tap
	   zoom — the owner hit it live: a missed «+» zoomed the whole page. */
	touch-action: manipulation;
	width: 26px;
	padding: 0;
	border: 0;
	background: transparent;
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--base);
	line-height: 1;
	cursor: pointer;
	transition: background-color 0.12s, color 0.12s;
}

.gsl-qty__step:hover {
	background: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--brand-action);
}

.gsl-qty__step:focus-visible {
	outline: 2px solid var(--wp--preset--color--brand-action);
	outline-offset: -2px;
}

/* 2ch fits "99" without the field growing per digit; the spinner is hidden
   because the two buttons already do that job and Firefox's arrows would sit
   on top of them. */
.gsl-qty__value {
	width: 2.5ch;
	padding: 0;
	border: 0;
	background: transparent;
	text-align: center;
	font: inherit;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--contrast);
	-moz-appearance: textfield;
	appearance: textfield;
}

.gsl-qty__value::-webkit-outer-spin-button,
.gsl-qty__value::-webkit-inner-spin-button {
	appearance: none;
	margin: 0;
}

.gsl-qty__value:focus-visible {
	outline: 2px solid var(--wp--preset--color--brand-action);
	outline-offset: -2px;
}

/* Scheme B (owner, 13.08): the stepper only ever shows alone — it takes the
   whole line the button vacated, at the same 44 px height, so the swap reads
   as the button changing state rather than a new control appearing. */
@media (max-width: 640px) {
	.gsl-qty {
		flex: 1 0 100%;
		height: 44px;
		justify-content: space-between;
	}

	.gsl-qty__step {
		flex: 0 0 44px;
		width: 44px;
	}

	/* `min-width: 0` is the whole fix, not tidiness. A flex item's automatic
	   minimum is its min-content width, and for an `<input>` that is the browser's
	   default field — around 170 px. Growing the field without it pushed the «+»
	   past the rounded edge, where `overflow: hidden` quietly ate it. */
	.gsl-qty__value {
		flex: 1 1 0;
		width: auto;
		min-width: 0;
	}
}

/* The stepper ships `hidden` and only shows for products already in the
   cart; the attribute must beat the flex display above. */
.gsl-qty[hidden] {
	display: none;
}

/* One blink per add on the header badge — the «something landed up there»
   cue the feedback research asked for. */
@keyframes gsl-badge-pulse {
	0% { transform: scale(1); }
	40% { transform: scale(1.35); }
	100% { transform: scale(1); }
}

.gsl-badge-pulse {
	animation: gsl-badge-pulse 0.35s ease;
}

@media (prefers-reduced-motion: reduce) {
	.gsl-badge-pulse {
		animation: none;
	}
}

/* The little grey cart before the digit (owner, 13.08): it names what the
   number means — «this many in your cart» — without repeating the number
   anywhere. The auto margins pull the glyph and the digit together into one
   centred cluster between the - and + steps. */
.gsl-qty__mark {
	display: flex;
	align-items: center;
	flex: 0 0 auto;
	color: var(--wp--preset--color--muted);
}

@media (max-width: 640px) {
	.gsl-qty__mark {
		margin-left: auto;
	}

	.gsl-qty__value {
		margin-right: auto;
	}
}

/* Design pass (owner, 13.08): the stepper wears the button silhouette - the
   same height and the same pill - with a gold hairline saying «active», so
   the tap reads as the button changing state. The steps are round cream
   chips; the count is the loudest thing in the box: the gold glyph names
   it, the ink digit owns it. */
.gsl-qty {
	box-sizing: border-box;
	align-items: center;
	height: 46px;
	padding: 0;
	border: 1.5px solid var(--wp--preset--color--gold);
	border-radius: var(--wp--custom--radius--pill);
	background: var(--wp--preset--color--base);
}

.gsl-qty__step {
	/* Owner (13.08): the pressed circle must describe the pill end exactly —
	   diameter equals the inner height, no crescent gap against the curve. */
	flex: 0 0 43px;
	width: 43px;
	height: 43px;
	border-radius: 50%;
	background: var(--wp--preset--color--cream);
	color: var(--wp--preset--color--gold-text);
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 700;
}

.gsl-qty__step:hover {
	background: var(--wp--preset--color--gold);
	color: var(--wp--preset--color--ink);
}

.gsl-qty__value {
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 800;
	color: var(--wp--preset--color--ink);
}

.gsl-qty__mark {
	color: var(--wp--preset--color--gold-icon);
}

/* The swap itself: a short pop when the stepper takes the button's place.
   The attribute flip changes the display value, which restarts the
   animation exactly once per appearance. */
@keyframes gsl-qty-in {
	from {
		opacity: 0;
		transform: scale(0.92);
	}

	to {
		opacity: 1;
		transform: scale(1);
	}
}

.gsl-qty:not([hidden]) {
	animation: gsl-qty-in 0.18s ease;
}

@media (prefers-reduced-motion: reduce) {
	.gsl-qty:not([hidden]) {
		animation: none;
	}
}

/* Cards whose product is already in the cart (P1 of the card research —
   Baymard asks stores to highlight these; about 4% do). The ring is an
   overlay laid over the card, not an outline on it: the image box is
   positioned (the heart and the badges hang off it) and painted white, and a
   positioned child paints above its parent's outline, so the outline showed
   on the lower half of the card only (owner, 07.10). An inset shadow on the
   overlay follows the rounded corners and stays inside the silhouette; it
   sits under the heart and the badges (z-index 2) and lets clicks through. */
.gsl-card--incart {
	position: relative;
}

.gsl-card--incart::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	border-radius: inherit;
	box-shadow: inset 0 0 0 1.5px var(--wp--preset--color--gold);
	pointer-events: none;
}

/* «Додано» живёт на плече корзиночки степпера (владелец, 14.08, вместо
   галочки на фото — «на фотке непонятно»): крошечный зелёный кружок с
   галочкой, чуть накрывает корзинку сверху-справа. Зелёный — токен
   «У наявності». Подмигивает на каждый прирост количества. */
.gsl-qty__mark {
	position: relative;
}

.gsl-qty__check {
	position: absolute;
	top: -4px;
	right: -5px;
	display: grid;
	place-items: center;
	width: 11px;
	height: 11px;
	border-radius: 50%;
	background: var(--wp--preset--color--in-stock);
	color: var(--wp--preset--color--base);
	box-shadow: 0 0 0 1.5px var(--wp--preset--color--base);
}

@keyframes gsl-check-pulse {
	0% { transform: scale(1); }
	45% { transform: scale(1.25); }
	100% { transform: scale(1); }
}

.gsl-check-pulse {
	animation: gsl-check-pulse 0.3s ease;
}

@media (prefers-reduced-motion: reduce) {
	.gsl-check-pulse {
		animation: none;
	}
}
