/* ==========================================================================
   Boutique — "ZDESIGNER Boutique"
   Loaded only on WooCommerce archives.
   ========================================================================== */

.zd-shop {
	padding: 26px var(--gutter) 0;
}

/* --------------------------------------------------------- the phone bar */

/*
 * Back, where you are, and a search — a row the phone needs and a wide screen
 * does not, so above the breakpoint it is not drawn at all.
 */
.zd-shop__bar {
	display: none;
}

/* ------------------------------------------------------------ breadcrumb */

.zd-crumbs {
	display: flex;
	align-items: center;
	gap: 9px;
	flex-wrap: wrap;
	font-size: 11.5px;
	letter-spacing: 0.04em;
	color: var(--muted);
}

.zd-crumbs a {
	color: var(--muted);
}

.zd-crumbs__current {
	color: var(--ink);
}

/*
 * A crumb and the arrow after it, as one. Kept together so that the step which
 * is pinned on a phone keeps its own arrow rather than leaving it behind to be
 * crowded by whatever slides past.
 */
.zd-crumbs__step {
	display: inline-flex;
	align-items: center;
}

.zd-crumbs__sep {
	margin-inline-start: 9px;
}

/* ------------------------------------------------------------- head row */

.zd-shop__head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 24px;
	flex-wrap: wrap;
	margin: 26px 0 22px;
}

.zd-shop__title {
	margin: 0;
	font-family: var(--font-display);
	font-weight: 500;
	font-size: clamp(13px, 1.4vw, 18px);
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.zd--ar .zd-shop__title,
.zd--ar .zd-drawer__title,
.zd--ar .zd-sec__head,
.zd--ar .zd-btn,
.zd--ar .zd-card__badge {
	text-transform: none;
	letter-spacing: 0.02em;
}

.zd-filter-btn {
	display: flex;
	align-items: center;
	gap: 9px;
	background: none;
	border: none;
	border-bottom: 1px solid var(--ink);
	padding: 0 0 3px;
	font-family: var(--font-body);
	font-size: 12px;
	font-weight: 400;
	letter-spacing: 0.08em;
	color: var(--ink);
	cursor: pointer;
}

.zd-filter-btn__icon {
	width: 14px;
	height: 14px;
	fill: none;
	stroke: var(--ink);
	stroke-width: 1.3;
}

.zd-filter-btn__knob {
	fill: var(--paper);
}

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

.zd-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 46px 16px;
}

@media (max-width: 1199px) {
	.zd-grid {
		grid-template-columns: repeat(3, 1fr);
	}
}

@media (max-width: 899px) {
	/*
	 * Two columns, all but no gutter.
	 *
	 * The pictures run to both edges of the screen and all but meet in the
	 * middle — seven tenths of a CSS pixel, which on the two- and three-times
	 * screens these pages are read on is a hairline of one or two device
	 * pixels. On a plain one-times display it rounds away to nothing and the
	 * two pictures meet.
	 *
	 * The space between rows is the card's own text, so the row gap is the
	 * only real one. The page therefore stops padding its sides and each part
	 * that is not the grid pads its own instead.
	 */
	.zd-grid {
		grid-template-columns: repeat(2, 1fr);
		gap: 26px 0.7px;
	}

	.zd-shop {
		/*
		 * Narrower sides on a phone. Redefined here rather than overridden
		 * rule by rule, so the bar, the trail and the filter row all move in
		 * together — they each lay themselves out against this.
		 */
		--gutter: 16px;

		padding-inline: 0;
		/*
		 * No gap above the bar at all: it carries its own padding, and any gap
		 * here is distance the bar has to travel before it sticks — which is
		 * the bar moving, which is the thing it must not do.
		 */
		padding-top: 0;
	}

	/*
	 * The trail stays on one line and slides.
	 *
	 * Wrapped, a deep category dropped its own name onto a second row and the
	 * page gained a line of height for one word. Nowrap with the overflow left
	 * scrollable keeps the row a row; the scrollbar is hidden because the
	 * cut-off crumb at the end is what says there is more to the right.
	 */
	.zd-crumbs {
		flex-wrap: nowrap;
		overflow-x: auto;
		scrollbar-width: none;
		-webkit-overflow-scrolling: touch;

		/*
		 * Held off the edges by a margin, not a padding.
		 *
		 * Overflow is clipped at the padding box, so with the gutter as padding
		 * the trail scrolled underneath it and the last crumb was cut in half
		 * against the side of the phone. As a margin the gutter is outside the
		 * scrolling box altogether, and the trail disappears a gutter's width
		 * in — with room to spare, as it should.
		 */
		margin-inline: var(--gutter);
		padding-inline: 0;
	}

	.zd-crumbs::-webkit-scrollbar {
		display: none;
	}

	.zd-crumbs > * {
		flex: 0 0 auto;
		white-space: nowrap;
	}

	/*
	 * The trail on Apple's label scale: one ink, graded by opacity rather than
	 * by a second and third grey. Where you are reads at full strength, the
	 * path behind it at their secondary 60%, and the arrows between at the
	 * tertiary 30% — they are punctuation, not steps.
	 */
	.zd-crumbs {
		font-size: 12.5px;
	}

	.zd-crumbs a {
		color: var(--ink);
		opacity: 0.6;
	}

	.zd-crumbs__sep {
		color: var(--ink);
		opacity: 0.3;
	}

	.zd-crumbs__current {
		color: var(--ink);
		opacity: 1;
	}

	/*
	 * The way home holds its place.
	 *
	 * The rest of the trail slides underneath it, so however deep the category
	 * and however narrow the screen, the one crumb that is always worth a tap
	 * is always there.
	 *
	 * The offset is zero: the scrolling box is itself held a gutter in from
	 * each edge, so its own start is where this belongs.
	 *
	 * It carries the page's own paper so the crumbs passing behind it are
	 * hidden rather than printed through it, and a little room after its arrow
	 * so they are not touching as they go.
	 */
	.zd-crumbs > :first-child {
		position: sticky;
		inset-inline-start: 0;
		z-index: 1;
		background: var(--paper);
		padding-inline-end: 6px;
	}

	.zd-shop__bar,
	.zd-shop__head,
	.zd-shop__count,
	.zd-shop__empty,
	.zd-more,
	.zd-found__cats,
	.zd-found__none,
	.zd-shop .woocommerce-notices-wrapper {
		padding-inline: var(--gutter);
	}

	/* Clear of the edge and of the picture beside it, but only just. */
	.zd-card__info {
		padding-inline: 10px;
	}

	/*
	 * The page's name does not move.
	 *
	 * Sticky rather than fixed, and pinned from the very first pixel: the page
	 * leaves no gap above it, so there is no distance to travel before it
	 * sticks and it is already at rest at scroll zero. That is fixed in every
	 * way the eye can tell — the header above it never leaves either — without
	 * taking the bar out of the flow and having to pad the grid back down by
	 * whatever height it happens to be.
	 *
	 * The offset is the header's measured height, --zd-hdr-h from header.js:
	 * that header is one row here, two elsewhere, and taller again while the
	 * search field is open.
	 */
	.zd-shop__bar {
		position: sticky;
		top: var(--zd-hdr-h, 54px);
		z-index: 39;
		display: flex;
		align-items: center;
		gap: 10px;
		padding-block: 10px;
		margin-bottom: 10px;
		background: var(--paper);
	}

	.zd-shop__back,
	.zd-shop__find {
		flex: 0 0 auto;
		display: flex;
		align-items: center;
		justify-content: center;
		width: 34px;
		height: 34px;
		margin-inline: -8px;
		padding: 0;
		background: none;
		border: none;
		color: var(--ink);
		cursor: pointer;
	}

	.zd-shop__back svg,
	.zd-shop__find svg {
		width: 19px;
		height: 19px;
		fill: none;
		stroke: currentColor;
		stroke-width: 1.5;
		stroke-linecap: round;
		stroke-linejoin: round;
	}

	/* The arrow points the way the reader came from, whichever way that is. */
	.zd--rtl .zd-shop__back svg {
		transform: scaleX(-1);
	}

	.zd-shop__bartitle {
		flex: 1 1 auto;
		min-width: 0;
		text-align: center;
		font-family: var(--font-display);
		font-weight: 400;
		font-size: 19px;
		line-height: 1.25;
		letter-spacing: 0.07em;
		text-transform: uppercase;
	}

	.zd--ar .zd-shop__bartitle {
		text-transform: none;
		letter-spacing: 0.02em;
		font-size: 20px;
	}

	/*
	 * The heading row keeps only the filter control: the department's name is
	 * in the bar above, and printing it twice says nothing the second time.
	 */
	.zd-shop__head {
		margin: 16px 0 14px;
	}

	.zd-shop__title {
		display: none;
	}

	/*
	 * Except when a search found nothing. The bar above carries the word that
	 * was typed, not the verdict on it, and without this the only sign that
	 * anything had gone wrong was a line of advice with nothing to explain it.
	 */
	.zd-found__head.is-none .zd-shop__title {
		display: block;
		margin-bottom: 14px;
	}
}

/* ------------------------------------------------------------------ card */

.zd-card {
	display: flex;
	flex-direction: column;
}

.zd-card__media {
	position: relative;
	display: block;
	aspect-ratio: 3 / 4;
	background: #F7F5F0;
	overflow: hidden;
}

.zd-card__media:hover {
	text-decoration: none;
}

/*
 * Two classes, because one loses.
 *
 * woocommerce-layout.css ships `.woocommerce-page img{height:auto}` at
 * specificity (0,1,1), and every shop and category page carries that body
 * class — so a lone `.zd-card__img` (0,1,0) never got to set a height here.
 * The cards only looked right by accident: a photo taller than the 3:4 frame
 * overflowed it and was clipped, which reads the same as being covered.
 *
 * Anything squarer than 3:4 gave the game away by leaving the bottom of the
 * frame empty — most visibly an attachment whose metadata never generated,
 * which WordPress writes out as width="1" height="1" and the browser then
 * treats as square. Stating the height with enough specificity to win makes
 * object-fit the thing that decides the crop, which is what it was for.
 */
.zd-card__media .zd-card__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: 50% 22%;
	opacity: 0;
	transition: opacity 0.25s ease;
}

.zd-card__img.is-active {
	opacity: 1;
}

.zd-card__img--empty {
	background: #EFEBE3;
	opacity: 1;
}

.zd-card__badge {
	position: absolute;
	inset-inline-start: 0;
	top: 0;
	background: var(--accent);
	color: #FFFFFF;
	font-size: 10px;
	font-weight: 500;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	padding: 5px 8px;
	white-space: nowrap;
}

.zd-card__nav,
.zd-card__cart {
	display: none;
	align-items: center;
	justify-content: center;
	cursor: pointer;
}

.zd-card:hover .zd-card__nav,
.zd-card:focus-within .zd-card__nav,
.zd-card:hover .zd-card__cart,
.zd-card:focus-within .zd-card__cart {
	display: flex;
}

.zd-card__nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	width: clamp(26px, 2.4vw, 34px);
	height: clamp(26px, 2.4vw, 34px);
	mix-blend-mode: difference;
}

.zd-card__nav--prev {
	inset-inline-start: 6px;
}

.zd-card__nav--next {
	inset-inline-end: 6px;
}

.zd-card__nav svg {
	width: clamp(13px, 1.15vw, 17px);
	height: clamp(13px, 1.15vw, 17px);
	fill: none;
	stroke: #FFFFFF;
	stroke-width: 1.5;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.zd--rtl .zd-card__nav svg {
	transform: scaleX(-1);
}

.zd-card__cart {
	position: absolute;
	inset-inline-end: 8px;
	bottom: 8px;
	width: 32px;
	height: 32px;
	background: rgba(255, 254, 251, 0.92);
}

.zd-card__cart svg {
	width: 16px;
	height: 16px;
	fill: none;
	stroke: var(--ink);
	stroke-width: 1.5;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.zd-card__cart.is-added {
	background: #1A1A1A;
}

.zd-card__cart.is-added svg {
	stroke: #FFFFFF;
}

.zd-card__info {
	display: flex;
	flex-direction: column;
	gap: 7px;
	padding: 14px 2px 0;
}

.zd-card__row {
	display: flex;
	align-items: flex-start;
	gap: 10px;
}

.zd-card__name {
	flex: 1 1 auto;
	font-size: 12.5px;
	line-height: 1.45;
	color: var(--ink);
	display: -webkit-box;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.zd-card__fav {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 20px;
	height: 20px;
	cursor: pointer;
}

.zd-card__fav svg {
	width: 16px;
	height: 16px;
	fill: none;
	stroke: var(--ink);
	stroke-width: 1.4;
}

.zd-card__fav[aria-pressed="true"] svg {
	fill: var(--ink);
}

.zd-card__prices {
	display: flex;
	align-items: baseline;
	gap: 8px;
	flex-wrap: wrap;
}

.zd-card__old {
	font-size: 12px;
	color: var(--muted);
	text-decoration: line-through;
}

.zd-card__price {
	font-size: 12.5px;
	color: var(--ink);
}

.zd-card__price.is-sale {
	color: var(--sale);
}

.zd-card__prices .woocommerce-Price-amount {
	white-space: nowrap;
}

/* ----------------------------------------------------------- count/pager */

.zd-shop__count {
	display: flex;
	justify-content: center;
	padding: clamp(40px, 5vw, 70px) 0 clamp(18px, 2vw, 26px);
	font-size: 11.5px;
	letter-spacing: 0.08em;
	color: var(--muted);
}

.zd-more {
	display: flex;
	justify-content: center;
	padding: 0 0 clamp(40px, 5vw, 70px);
}

.zd-more__btn {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 15px 30px;
	border-radius: 999px;
	background: #1A1A1A;
	color: #FFFFFF;
	font-family: var(--font-body);
	font-size: 13px;
	font-weight: 500;
	letter-spacing: 0.02em;
	cursor: pointer;
	transition: opacity 0.2s ease;
}

.zd-more__btn:hover {
	text-decoration: none;
	opacity: 0.88;
}

.zd-more__of {
	font-weight: 400;
	opacity: 0.75;
}

.zd-more__btn.is-loading {
	opacity: 0.55;
	pointer-events: none;
}

.zd-shop__empty {
	padding: clamp(40px, 6vw, 90px) 0;
	text-align: center;
	font-size: 13px;
	color: var(--muted);
}

/* ---------------------------------------------------------------- drawer */

.zd-drawer-scrim {
	position: fixed;
	inset: 0;
	background: var(--scrim);
	z-index: 70;
}

.zd-drawer {
	position: fixed;
	top: 0;
	bottom: 0;
	inset-inline-end: 0;
	width: min(92vw, 430px);
	background: var(--paper);
	z-index: 71;
	display: flex;
	flex-direction: column;
}


.zd-drawer__form {
	display: flex;
	flex-direction: column;
	height: 100%;
	min-height: 0;
}

.zd-drawer__top {
	display: flex;
	justify-content: flex-end;
	padding: 18px 22px 0;
}

.zd-drawer__close {
	background: none;
	border: none;
	padding: 6px;
	cursor: pointer;
	line-height: 0;
}

.zd-drawer__close svg {
	width: 16px;
	height: 16px;
	fill: none;
	stroke: var(--ink);
	stroke-width: 1.3;
}

.zd-drawer__title {
	margin: 0;
	padding: 6px 28px 22px;
	font-family: var(--font-display);
	font-weight: 500;
	font-size: 19px;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.zd-drawer__body {
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	padding: 0 28px;
}

.zd-sec {
	border-top: 1px solid var(--rule);
}

.zd-sec__tail {
	border-top: 1px solid var(--rule);
	height: 20px;
}

.zd-sec__head {
	width: 100%;
	display: flex;
	justify-content: space-between;
	align-items: center;
	background: none;
	border: none;
	padding: 20px 0;
	font-family: var(--font-body);
	font-size: 12.5px;
	font-weight: 400;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--ink);
	text-align: start;
	cursor: pointer;
}

.zd-sec__sign {
	color: var(--muted);
	font-size: 14px;
	letter-spacing: 0;
}

.zd-sec__body {
	display: flex;
	flex-direction: column;
	gap: 2px;
	padding: 0 0 18px;
}


.zd-opt {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 8px 0;
	font-size: 12.5px;
	letter-spacing: 0.02em;
	color: var(--ink);
	cursor: pointer;
}

.zd-opt__input {
	position: absolute;
	opacity: 0;
	width: 0;
	height: 0;
}

.zd-opt__box {
	flex: 0 0 auto;
	width: 16px;
	height: 16px;
	border: 1px solid #9B9B96;
	display: flex;
	align-items: center;
	justify-content: center;
}

.zd-opt--single .zd-opt__box {
	border-radius: 50%;
}

.zd-opt__fill {
	display: none;
	width: 10px;
	height: 10px;
	background: var(--ink);
}

.zd-opt--single .zd-opt__fill {
	width: 8px;
	height: 8px;
	border-radius: 50%;
}

.zd-opt__input:checked ~ .zd-opt__box {
	border-color: var(--ink);
}

.zd-opt__input:checked ~ .zd-opt__box .zd-opt__fill {
	display: block;
}

.zd-opt__input:focus-visible ~ .zd-opt__box {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}

.zd-opt__swatch {
	flex: 0 0 auto;
	width: 14px;
	height: 14px;
	border: 1px solid var(--rule);
}

/* ---------------------------------------------------------- price slider */

.zd-slider {
	display: flex;
	flex-direction: column;
	gap: 16px;
	padding: 2px 7px 12px;
}

.zd-slider__labels {
	display: flex;
	justify-content: space-between;
	font-size: 12px;
	letter-spacing: 0.02em;
	color: var(--ink);
}

.zd-slider__track {
	position: relative;
	height: 14px;
	touch-action: none;
}

.zd-slider__rail {
	position: absolute;
	inset-inline: 0;
	top: 6px;
	height: 1.5px;
	background: #1A1A1A;
}

.zd-slider__handle {
	position: absolute;
	top: 0;
	width: 14px;
	height: 14px;
	margin-inline-start: -7px;
	border-radius: 50%;
	background: #1A1A1A;
	cursor: ew-resize;
}

/* ----------------------------------------------------------- drawer foot */

.zd-drawer__foot {
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: 18px 28px 24px;
	border-top: 1px solid var(--rule);
}

.zd-btn {
	display: block;
	width: 100%;
	padding: 15px 0;
	font-family: var(--font-body);
	font-size: 12px;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	text-align: center;
	cursor: pointer;
}

.zd-btn:hover {
	text-decoration: none;
}

.zd-btn--solid {
	background: #1A1A1A;
	border: 1px solid #1A1A1A;
	color: #FFFFFF;
	font-weight: 500;
}

.zd-btn--ghost {
	background: none;
	border: 1px solid var(--rule);
	color: #9B9B96;
	font-weight: 400;
}

.zd-btn--ghost.is-active {
	color: var(--ink);
}

/* ======================================================== results === */

/*
 * The search page is the shop's grid under a different heading, so it borrows
 * .zd-shop wholesale and adds only what the shop has no use for: what was
 * asked, how much was found, and the shelves worth opening instead.
 */

.zd-found__head {
	display: block;
}

.zd-found__n {
	margin: 6px 0 0;
	font-size: 13px;
	color: var(--muted);
}

.zd-found__cats {
	margin: 0 0 clamp(20px, 2.5vw, 30px);
}

.zd-found__h {
	margin: 0 0 11px;
	font-family: var(--font-display);
	font-size: 11.5px;
	font-weight: 500;
	letter-spacing: 0.14em;
	line-height: 1.3;
	text-transform: uppercase;
	color: var(--muted);
}

.zd--ar .zd-found__h {
	text-transform: none;
	letter-spacing: 0.02em;
	font-size: 13px;
}

.zd-found__chips {
	display: flex;
	flex-wrap: wrap;
	gap: 9px;
}

.zd-found__chip {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	min-height: 38px;
	padding: 0 15px;
	border: 1px solid var(--rule);
	font-size: 13px;
	color: var(--ink);
	transition: border-color 0.15s ease, background-color 0.15s ease;
}

.zd-found__chip:hover,
.zd-found__chip:focus-visible {
	border-color: var(--ink);
	text-decoration: none;
}

.zd-found__chip-n {
	font-size: 11.5px;
	color: var(--muted);
}

/*
 * Nothing found is somewhere to carry on from, not a dead end: what to try
 * differently, then the shelves most likely to hold what was meant.
 */
.zd-found__none {
	max-width: 54ch;
	padding-bottom: clamp(30px, 5vw, 60px);
}

.zd-found__hint {
	margin: 0 0 clamp(22px, 3vw, 34px);
	font-size: 14px;
	line-height: 1.6;
	color: var(--muted);
}

@media (max-width: 899px) {
	.zd-found__n {
		font-size: 12.5px;
	}

	.zd-found__chip {
		min-height: 36px;
		padding: 0 13px;
		font-size: 12.5px;
	}
}

/* --------------------------------------------------------- sold out --- */

/*
 * A piece with nothing left in any size.
 *
 * The words, in the same red the sale price is written in, across the middle
 * of the photograph where the eye lands rather than tucked into a corner
 * where they would read as another discount tag.
 *
 * The photograph behind them is drained to black and white. The piece is
 * still perfectly legible — this is a shop, and a sold-out caftan is why
 * somebody comes back next week — but the card reads as unavailable across a
 * grid before a single word is read, and the only colour left on it is the
 * red of that word.
 *
 * It takes the sale badge's place rather than sitting beside it: a card can
 * be both on sale and gone, and a percentage nobody can act on is a promise
 * the shop cannot keep. The struck-through price stays, so the saving is
 * still on the card.
 */

/*
 * The photograph goes to black and white.
 *
 * On the images rather than on the frame, because the frame also holds the
 * word: a filter on the parent would drain the red out of it too, and the red
 * is the whole point. Both stacked shots get it, so stepping through them with
 * the arrows does not reveal a colour one underneath.
 *
 * It leaves the red as the only colour on the card, which does more for the
 * message than any amount of dimming did.
 */
.zd-card.is-sold-out .zd-card__img {
	filter: grayscale(1);
}

.zd-card__out {
	position: absolute;
	z-index: 2;
	top: 50%;
	/*
	 * Centred without a horizontal transform. translateX is physical and does
	 * not flip with the writing direction, so pairing it with a logical offset
	 * centres the words on the French build and pushes them off to one side on
	 * the Arabic one. Stretching the box edge to edge and letting the auto
	 * margins centre it behaves the same in both.
	 */
	inset-inline: 0;
	margin-inline: auto;
	width: fit-content;
	transform: translateY(-50%);
	color: var(--sale);
	/*
	 * The face the home page shouts "jusqu'a 40 % de reduction" in, so the two
	 * red messages in the shop are recognisably the same voice. 700 is the top
	 * of it: Noto Kufi Arabic is loaded as a variable font over 400..700, and
	 * asking for more only gets a synthetic bold that smears the Arabic.
	 */
	font-family: var(--font-display);
	font-size: clamp(20px, 2vw, 32px);
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	text-align: center;
	white-space: nowrap;
}

/*
 * Arabic has no capitals to make, and letter-spacing prises apart letters that
 * are supposed to join. The home page's own red headline is corrected the same
 * way — see .zd--ar .zd-soldes__title.
 */
.zd--ar .zd-card__out {
	text-transform: none;
	letter-spacing: 0;
}
