/**
 * JAFRA — Components
 *
 * Phase 1 scope only: shared primitives and global chrome.
 * Every value resolves to a token from tokens.css.
 *
 * Authored with logical properties throughout (decision B2). Genuine
 * direction-specific exceptions live in rtl.css.
 *
 * Source of truth for each block is named in its header comment. Values are
 * transcribed from the finalized .dc.html designs verbatim.
 */

/* ==========================================================================
 * BUTTONS
 * Source: .btnp / .btns / .btnl in JAFRA Homepage.dc.html
 *
 * Default metrics are the hero CTA (13px / .1em / 17px 36px). Context
 * modifiers cover the other sizes the designs use.
 * ========================================================================== */

/*
 * `inline-block`, not `inline-flex`.
 *
 * The designs draw most buttons as a plain <a> with padding — the text sits
 * after padding-left in a normal block box. Centring the label with a flex
 * container instead puts the text at the same measured x but on a different
 * sub-pixel rounding path, which showed up as a 1px shift of every glyph in
 * the hero CTA while box and text metrics measured identical.
 *
 * The one exception is --ink (newsletter), which the design DOES author as
 * `display:flex; align-items:center` because it has a fixed 54px height.
 */
.jafra-btn {
	display: inline-block;
	text-align: center;
	padding-block: 17px;
	padding-inline: 36px;
	border: 0;
	border-radius: var(--jafra-radius-sm);
	font-family: var(--jafra-font-body);
	font-size: var(--jafra-text-13);
	font-weight: var(--jafra-weight-semibold);
	letter-spacing: var(--jafra-ls-10);
	text-decoration: none;
	cursor: pointer;
	transition:
		background-color var(--jafra-duration-fast) ease,
		color var(--jafra-duration-fast) ease,
		border-color var(--jafra-duration-fast) ease;
}

/* Primary — burgundy fill. */
.jafra-btn--primary {
	background-color: var(--jafra-color-burgundy);
	color: #fff;
}

.jafra-btn--primary:hover {
	background-color: var(--jafra-color-burgundy-hover);
}

/* Secondary — ink outline that inverts on hover. */
.jafra-btn--secondary {
	background-color: transparent;
	border: var(--jafra-border-input);
	color: var(--jafra-color-ink);
	font-size: var(--jafra-text-12-5);
	letter-spacing: var(--jafra-ls-13);
	padding-block: 16px;
	padding-inline: 44px;
}

.jafra-btn--secondary:hover {
	background-color: var(--jafra-color-ink);
	border-color: var(--jafra-color-ink);
	color: var(--jafra-color-text-on-dark);
}

/* Light — for use on dark imagery; inverts to cream on hover. */
.jafra-btn--light {
	background-color: transparent;
	border: var(--jafra-border-on-dark);
	color: #fff;
	padding-inline: 32px;
}

.jafra-btn--light:hover {
	background-color: var(--jafra-color-bg);
	color: var(--jafra-color-ink);
}

/* Ink fill — newsletter submit. Distinct hover from the primary button.
 * Authored as flex in JafraNewsletter.dc.html because it has a fixed height. */
.jafra-btn--ink {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background-color: var(--jafra-color-ink);
	color: var(--jafra-color-text-on-dark);
	font-size: var(--jafra-text-12-5);
	padding-block: 0;
	padding-inline: 34px;
	block-size: var(--jafra-input-height);
}

.jafra-btn--ink:hover {
	background-color: var(--jafra-color-ink-hover);
}

/* Full-width variant — mobile hero CTA and mobile newsletter submit. */
.jafra-btn--block {
	display: block;
	inline-size: 100%;
}

/* ==========================================================================
 * UNDERLINE LINK
 * Source: .uline / .navi in JAFRA Homepage.dc.html
 * A burgundy rule sweeps 0 -> 100% over .4s on the JAFRA easing curve.
 * ========================================================================== */

.jafra-link-underline {
	position: relative;
	display: inline-flex;
	transition: color var(--jafra-duration-fast) ease;
}

.jafra-link-underline::after {
	content: '';
	position: absolute;
	inset-inline-start: 0;
	inset-block-end: -4px;
	inline-size: 0;
	block-size: 1px;
	background-color: var(--jafra-color-burgundy);
	transition: inline-size var(--jafra-duration-slow) var(--jafra-ease);
}

.jafra-link-underline:hover,
.jafra-link-underline:focus-visible {
	color: var(--jafra-color-burgundy);
}

.jafra-link-underline:hover::after,
.jafra-link-underline:focus-visible::after {
	inline-size: 100%;
}

/* Current page — underline is pre-extended. Source: .navion */
.jafra-link-underline.is-current {
	color: var(--jafra-color-burgundy);
}

.jafra-link-underline.is-current::after {
	inline-size: 100%;
}

/* Text CTA with a trailing arrow ("READ THE MANIFESTO ->"). */
.jafra-link-cta {
	font-size: var(--jafra-text-12-5);
	font-weight: var(--jafra-weight-semibold);
	letter-spacing: var(--jafra-ls-13);
}

/* ==========================================================================
 * ICON BUTTON
 * Source: .icn in JafraHeader.dc.html
 * The design draws a bare 20px icon. A 44px hit area is added via a
 * pseudo-element so touch targets meet the 44px minimum WITHOUT changing the
 * visual layout — see docs/IMPLEMENTATION-DECISIONS.md §11.
 * ========================================================================== */

.jafra-icon-btn {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	color: var(--jafra-color-ink);
	cursor: pointer;
	transition: color var(--jafra-duration-fast) ease;
}

.jafra-icon-btn::before {
	content: '';
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	inline-size: 44px;
	block-size: 44px;
	transform: translate(-50%, -50%);
}

.jafra-icon-btn:hover {
	color: var(--jafra-color-burgundy);
}

.jafra-icon {
	display: block;
	flex: 0 0 auto;
	fill: none;
	stroke: currentColor;
	stroke-width: var(--jafra-icon-stroke);
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* ==========================================================================
 * FORM FIELDS
 * Source: JafraNewsletter.dc.html and checkout.dc.html
 * 54px tall, 1.5px ink border, transparent ground, 3px radius.
 * ========================================================================== */

.jafra-field {
	display: block;
}

.jafra-field__label {
	display: block;
	margin-block-end: var(--jafra-space-8);
	font-size: var(--jafra-text-11-5);
	font-weight: var(--jafra-weight-semibold);
	letter-spacing: var(--jafra-ls-13);
	text-transform: uppercase;
	color: var(--jafra-color-text-subtle);
}

.jafra-input,
.jafra-select,
.jafra-textarea {
	inline-size: 100%;
	block-size: var(--jafra-input-height);
	padding-inline: 18px;
	border: var(--jafra-border-input);
	border-radius: var(--jafra-radius-sm);
	background-color: transparent;
	font-family: var(--jafra-font-body);
	font-size: var(--jafra-text-15);
	color: var(--jafra-color-ink);
	transition: border-color var(--jafra-duration-fast) ease;
}

.jafra-textarea {
	block-size: auto;
	min-block-size: 140px;
	padding-block: 16px;
	line-height: var(--jafra-lh-160);
}

.jafra-input::placeholder,
.jafra-textarea::placeholder {
	color: var(--jafra-color-text-muted);
	opacity: 1;
}

/* Native select needs its own arrow once appearance is reset. The chevron is
 * inlined rather than pulled from the sprite because CSS cannot reference a
 * sprite symbol as a background image. */
.jafra-select {
	appearance: none;
	padding-inline-end: 44px;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20' fill='none' stroke='%2326221D' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 8l5 5 5-5'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 16px center;
	background-size: 20px 20px;
}

.jafra-input:focus-visible,
.jafra-select:focus-visible,
.jafra-textarea:focus-visible {
	outline: 2px solid var(--jafra-color-burgundy);
	outline-offset: 2px;
}

.jafra-field__error {
	display: block;
	margin-block-start: var(--jafra-space-8);
	font-size: var(--jafra-text-13);
	color: var(--jafra-color-burgundy);
}

/* ==========================================================================
 * ANNOUNCEMENT BAR
 * Source: JafraHeader.dc.html (42px) / JafraHeaderMobile.dc.html (34px)
 * ========================================================================== */

.jafra-announcement {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--jafra-space-16);
	block-size: var(--jafra-announcement-height-mobile);
	background-color: var(--jafra-color-ink);
	color: var(--jafra-color-text-on-dark-2);
	font-size: var(--jafra-text-10-5);
	letter-spacing: var(--jafra-ls-13);
	text-transform: uppercase;
	text-align: center;
}

/* Regular weight on mobile: JafraHeaderMobile.dc.html sets no font-weight on
 * the message, so it inherits 400. Only the desktop design wraps it in a
 * font-weight:500 span. */
.jafra-announcement__message {
	font-weight: var(--jafra-weight-regular);
}

/* The ✦ ornaments appear on desktop only. */
.jafra-announcement__ornament {
	display: none;
	font-size: var(--jafra-text-9);
	opacity: 0.45;
}

/* Desktop and mobile carry DIFFERENT COPY, so both sets are rendered and one
 * is selected here rather than restyled. */
.jafra-announcement--desktop {
	display: none;
}

@media (min-width: 1024px) {
	.jafra-announcement--mobile {
		display: none;
	}

	.jafra-announcement--desktop {
		display: flex;
	}

	.jafra-announcement__ornament {
		display: inline;
	}

	.jafra-announcement {
		block-size: var(--jafra-announcement-height);
		font-size: var(--jafra-text-12-5);
		letter-spacing: var(--jafra-ls-14);
	}

	.jafra-announcement__message {
		font-weight: var(--jafra-weight-medium);
	}
}

/* ==========================================================================
 * HEADER
 * Source: JafraHeader.dc.html (desktop) / JafraHeaderMobile.dc.html (mobile)
 *
 * Both compositions use the same 3-column grid, but differ in height, gutter,
 * logo size and which actions are exposed. They are NOT one layout scaling.
 * ========================================================================== */

.jafra-header {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	block-size: var(--jafra-header-height-mobile);
	padding-inline: var(--jafra-gutter-mobile);
	background-color: var(--jafra-color-bg);
	border-block-end: var(--jafra-border-hairline);
}

/* Pinned header — DESKTOP ONLY.
 *
 * The nav bar stays visible while the page scrolls. Sticking the WRAPPER (not
 * the .jafra-header row) is deliberate: a position:sticky element only stays
 * stuck while its own parent is in view, and .jafra-site-header spans the whole
 * document, so the row keeps pinning all the way down.
 *
 * Progressive enhancement: the base rule pins the whole wrapper at the top
 * (works everywhere). Where :has() is supported the wrapper is offset up by the
 * announcement height so the thin announcement scrolls away and only the nav row
 * remains — and the slim checkout header is never pinned. Mobile is intentionally
 * NOT pinned (client preference). */
@media (min-width: 1024px) {
	.jafra-site-header {
		position: sticky;
		inset-block-start: 0;
		z-index: var(--jafra-z-header);
	}

	.jafra-site-header:has(.jafra-announcement) {
		inset-block-start: calc(-1 * var(--jafra-announcement-height));
	}

	.jafra-site-header:has(.jafra-header--checkout) {
		position: static;
	}

	/* When logged in, WordPress pins its 32px admin bar at the top of the
	 * viewport. Push the sticky header down by that height so the admin bar does
	 * not cover the nav row (and clip the logo). Only affects logged-in admins;
	 * visitors never see the admin bar. */
	body.admin-bar .jafra-site-header {
		inset-block-start: 32px;
	}

	body.admin-bar .jafra-site-header:has(.jafra-announcement) {
		inset-block-start: calc(32px - var(--jafra-announcement-height));
	}
}

.jafra-header__logo {
	justify-self: center;
	display: block;
}

.jafra-header__logo img {
	block-size: var(--jafra-logo-height-mobile);
	inline-size: auto;
}

.jafra-header__nav {
	display: none;
}

.jafra-header__actions {
	justify-self: end;
	display: flex;
	align-items: center;
	gap: var(--jafra-icon-gap-mobile);
}

/* Mobile action icons are drawn at 19px, not the 20px used on desktop
 * (JafraHeaderMobile.dc.html: width="19" height="19"). The markup carries the
 * 20px attributes, so the mobile size is applied here. */
.jafra-header__actions .jafra-icon {
	inline-size: 19px;
	block-size: 19px;
}

.jafra-header__toggle {
	justify-self: start;
}

/* Cart count badge. */
.jafra-cart-link {
	position: relative;
	display: inline-flex;
}

.jafra-cart-count {
	position: absolute;
	inset-block-start: -6px;
	inset-inline-end: -7px;
	display: flex;
	align-items: center;
	justify-content: center;
	inline-size: 14px;
	block-size: 14px;
	border-radius: var(--jafra-radius-round);
	background-color: var(--jafra-color-burgundy);
	color: #fff;
	font-size: var(--jafra-text-9);
	font-weight: var(--jafra-weight-bold);
	letter-spacing: 0;
}

@media (min-width: 1024px) {
	.jafra-header {
		block-size: var(--jafra-header-height);
		padding-inline: var(--jafra-gutter);
	}

	.jafra-header__logo img {
		block-size: var(--jafra-logo-height);
	}

	.jafra-header__nav {
		display: flex;
		gap: var(--jafra-nav-gap);
		font-size: var(--jafra-text-12-5);
		font-weight: var(--jafra-weight-semibold);
		letter-spacing: var(--jafra-ls-13);
		text-transform: uppercase;
	}

	.jafra-header__actions {
		gap: var(--jafra-icon-gap);
	}

	.jafra-header__actions .jafra-icon {
		inline-size: 20px;
		block-size: 20px;
	}

	.jafra-header__toggle {
		display: none;
	}

	.jafra-cart-count {
		inset-block-start: -7px;
		inset-inline-end: -8px;
		inline-size: 16px;
		block-size: 16px;
		font-size: var(--jafra-text-9-5);
	}
}

/* Desktop-only actions: wishlist and account move into the drawer on mobile. */
.jafra-header__action--desktop {
	display: none;
}

@media (min-width: 1024px) {
	.jafra-header__action--desktop {
		display: inline-flex;
	}
}

/* Slim checkout header — no site navigation.
 * Source: checkout.dc.html. Shared primitive, so it lives in Phase 1. */
.jafra-header--checkout {
	/* Logo left, reassurance right — the design's slim bar is 88px tall. */
	display: flex;
	align-items: center;
	justify-content: space-between;
	block-size: 88px;
	border-block-end: var(--jafra-border-hairline);
}

.jafra-header--checkout .jafra-header__secure {
	justify-self: end;
	display: inline-flex;
	align-items: center;
	gap: var(--jafra-space-8);
	font-size: var(--jafra-text-12-5);
	font-weight: var(--jafra-weight-semibold);
	letter-spacing: var(--jafra-ls-13);
	text-transform: uppercase;
	color: var(--jafra-color-text-subtle);
}

/* ==========================================================================
 * NAV DRAWER (mobile)
 * The mobile artboards show a hamburger but no open-drawer state was designed.
 * Built from the established panel language — see
 * docs/DESIGN-DISCREPANCIES.md §5.
 * ========================================================================== */

.jafra-drawer {
	position: fixed;
	inset-block-start: 0;
	inset-inline-start: 0;
	/* Dynamic viewport height: on mobile the browser UI shrinks the visible area,
	 * and a plain 100vh (or inset-block:0) drawer would run behind that UI and cut
	 * off the footer buttons (Checkout / View cart). dvh tracks the visible area. */
	block-size: 100vh;
	block-size: 100dvh;
	z-index: var(--jafra-z-drawer);
	display: flex;
	flex-direction: column;
	inline-size: min(88vw, 380px);
	background-color: var(--jafra-color-bg);
	box-shadow: var(--jafra-shadow-drawer);
	transform: translateX(-100%);
	transition: transform var(--jafra-duration-normal) var(--jafra-ease);
	visibility: hidden;
}

.jafra-drawer[aria-hidden='false'] {
	transform: translateX(0);
	visibility: visible;
}

.jafra-drawer__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	/* See the close button below for why this alone is not enough. */
	block-size: var(--jafra-header-height-mobile);
	padding-inline: var(--jafra-gutter-mobile);
	border-block-end: var(--jafra-border-hairline);
}

/*
 * The close control sits at the TRAILING edge.
 *
 * `justify-content: space-between` was doing that job, but the navigation
 * drawer's only other child is a visually hidden label — and
 * `.jafra-visually-hidden` is absolutely positioned, so it is out of flow and
 * not a flex item. With one in-flow item, `space-between` puts it at the START:
 * the X was rendering in the drawer's top-LEFT corner.
 *
 * `margin-inline-start: auto` pushes it to the end whatever its siblings are, so
 * the cart drawer (which does have a visible title beside it) is unaffected.
 */
.jafra-drawer__header > [data-jafra-drawer-close] {
	margin-inline-start: auto;
}

.jafra-drawer__nav {
	display: flex;
	flex-direction: column;
	gap: var(--jafra-space-24);
	padding: var(--jafra-space-32) var(--jafra-gutter-mobile-section);
	font-size: var(--jafra-text-13);
	font-weight: var(--jafra-weight-semibold);
	letter-spacing: var(--jafra-ls-13);
	text-transform: uppercase;
}

.jafra-drawer__footer {
	margin-block-start: auto;
	display: flex;
	flex-direction: column;
	gap: var(--jafra-space-16);
	padding: var(--jafra-space-24) var(--jafra-gutter-mobile-section);
	border-block-start: var(--jafra-border-hairline);
	font-size: var(--jafra-text-13);
}

.jafra-scrim {
	position: fixed;
	inset: 0;
	z-index: var(--jafra-z-overlay);
	background-color: rgba(var(--jafra-overlay-rgb), 0.6);
	opacity: 0;
	visibility: hidden;
	transition:
		opacity var(--jafra-duration-normal) var(--jafra-ease),
		visibility var(--jafra-duration-normal) var(--jafra-ease);
}

.jafra-scrim.is-active {
	opacity: 1;
	visibility: visible;
}

/* RTL: the drawer enters from the inline start, which flips with direction. */
[dir='rtl'] .jafra-drawer {
	transform: translateX(100%);
}

[dir='rtl'] .jafra-drawer[aria-hidden='false'] {
	transform: translateX(0);
}

/* ==========================================================================
 * FOOTER
 * Source: JafraFooter.dc.html (desktop) + homepage mobile artboard.
 *
 * Mobile is a separate composition: 2-column link grid, smaller type, a
 * centred single-line legal bar, and SHORTER COPY for the brand blurb and
 * legal line. See docs/DESIGN-DISCREPANCIES.md §13.
 * ========================================================================== */

.jafra-footer {
	background-color: var(--jafra-color-ink-deep);
	color: var(--jafra-color-text-on-dark);
}

/*
 * The two footers nest differently, which is why the bottom padding lives on
 * the legal block at mobile and on the inner wrapper at desktop:
 *
 *   mobile  — one padded box (40px 24px 28px) containing brand, columns AND
 *             the legal line, so the 28px sits BELOW the legal text.
 *   desktop — the legal line is its own full-width container with its own
 *             1240px max-width and 24px/44px padding, outside the inner grid.
 *
 * Putting the 28px on the inner wrapper at mobile pushed the legal line 29px
 * down, because the padding landed above it instead of below.
 */
.jafra-footer__inner {
	max-inline-size: var(--jafra-container);
	margin-inline: auto;
	padding-block: 40px 0;
	padding-inline: var(--jafra-gutter-mobile-section);
}

.jafra-footer__logo img {
	block-size: 52px;
	inline-size: auto;
	margin-inline-start: -5px;
	opacity: 0.94;
	filter: brightness(0) invert(1);
}

/* Mobile blurb runs the full content width — the 270px cap is a DESKTOP-only
 * constraint in JafraFooter.dc.html and applying it here re-wrapped the copy. */
.jafra-footer__blurb {
	margin-block-start: 14px;
	font-size: var(--jafra-text-13);
	line-height: var(--jafra-lh-165);
	color: var(--jafra-color-text-footer-body);
}

/* Desktop and mobile carry DIFFERENT COPY for the blurb and legal line, not
 * just different type sizes. Both ship in the markup; CSS selects one.
 * See docs/DESIGN-DISCREPANCIES.md §13. */
.jafra-footer__blurb--desktop,
.jafra-footer__legal-text--desktop {
	display: none;
}

@media (min-width: 1024px) {
	.jafra-footer__blurb--desktop,
	.jafra-footer__legal-text--desktop {
		display: block;
	}

	.jafra-footer__blurb--mobile,
	.jafra-footer__legal-text--mobile {
		display: none;
	}
}

.jafra-footer__columns {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 26px 14px;
	margin-block-start: 28px;
}

/* Rendered as <h2> for document structure, but the design draws these as plain
 * labels: regular weight, normal leading. Both have to be restated because
 * base.css gives headings 600/1.25, which made the column headings heavier than
 * designed and pushed everything below them down. */
.jafra-footer__heading {
	margin-block-end: 13px;
	font-size: var(--jafra-text-10-5);
	font-weight: var(--jafra-weight-regular);
	line-height: normal;
	letter-spacing: var(--jafra-ls-18);
	text-transform: uppercase;
	color: var(--jafra-color-beige);
}

.jafra-footer__links {
	display: flex;
	flex-direction: column;
	gap: 10px;
	font-size: var(--jafra-text-13);
	color: var(--jafra-color-text-footer-link);
}

.jafra-footer__links a {
	transition: color var(--jafra-duration-fast) ease;
}

.jafra-footer__links a:hover {
	color: var(--jafra-color-text-on-dark);
}

.jafra-footer__legal {
	margin-block-start: 30px;
	padding-block: 20px 28px;
	padding-inline: var(--jafra-gutter-mobile-section);
	border-block-start: 1px solid var(--jafra-color-ink-soft);
	font-size: var(--jafra-text-11-5);
	color: var(--jafra-color-text-footer-meta);
	text-align: center;
}

.jafra-footer__payments {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--jafra-space-8, 8px);
	margin-block-start: 14px;
}

.jafra-pay {
	display: inline-flex;
	line-height: 0;
}

.jafra-pay svg {
	block-size: 24px;
	inline-size: auto;
	border-radius: 4px;
	box-shadow: 0 0 0 1px rgba(0, 0, 0, .06);
}

@media (min-width: 1024px) {
	.jafra-footer__inner {
		display: grid;
		grid-template-columns: 1.5fr 1fr 1fr 1fr;
		gap: var(--jafra-gutter);
		padding-block: 80px 36px;
		padding-inline: var(--jafra-gutter);
	}

	.jafra-footer__logo img {
		block-size: var(--jafra-logo-height-footer);
		margin-inline-start: -6px;
	}

	.jafra-footer__blurb {
		margin-block-start: 18px;
		max-inline-size: 270px;
		font-size: var(--jafra-text-14);
		line-height: var(--jafra-lh-170);
	}

	/* On desktop the columns are direct grid children of the inner wrapper
	 * rather than a nested grid. */
	.jafra-footer__columns {
		display: contents;
	}

	.jafra-footer__heading {
		margin-block-end: 18px;
		font-size: var(--jafra-text-11);
		letter-spacing: var(--jafra-ls-20);
	}

	.jafra-footer__links {
		gap: var(--jafra-space-12);
		font-size: var(--jafra-text-14);
	}

	.jafra-footer__legal {
		display: flex;
		align-items: center;
		justify-content: space-between;
		max-inline-size: var(--jafra-container);
		margin-block-start: 0;
		margin-inline: auto;
		padding-block: var(--jafra-space-24);
		padding-inline: var(--jafra-gutter);
		border-block-start: 1px solid var(--jafra-color-ink-soft);
		font-size: var(--jafra-text-12-5);
		text-align: start;
	}

	.jafra-footer__payments {
		margin-block-start: 0;
		justify-content: flex-end;
	}
}

/* ==========================================================================
 * NEWSLETTER
 * Source: JafraNewsletter.dc.html (desktop) + homepage mobile artboard.
 *
 * Mobile stacks the input above a full-width button, uses smaller type and
 * SHORTER body copy. Another separate composition, not a reflow.
 * ========================================================================== */

/*
 * Box structure follows the designs exactly, and it differs by breakpoint:
 *
 *   mobile  — padding sits on the BAND (48px 24px), no inner max-width, so the
 *             content box is 390 - 48 = 342px.
 *   desktop — the band is flush and the INNER wrapper is max 720px with
 *             96px/40px padding inside it, so the content box is 640px.
 *
 * Putting the desktop padding on the band instead would give a 720px content
 * box and re-wrap the body copy.
 */
.jafra-newsletter {
	background-color: var(--jafra-color-beige-newsletter);
	padding-block: 48px;
	padding-inline: var(--jafra-gutter-mobile-section);
	text-align: center;
}

.jafra-newsletter__inner {
	margin-inline: auto;
}

.jafra-newsletter__heading-ar {
	font-size: 32px;
	font-weight: var(--jafra-weight-semibold);
	color: var(--jafra-color-ink);
}

.jafra-newsletter__heading-en {
	margin-block-start: 2px;
	font-size: var(--jafra-text-22);
	font-style: italic;
	color: #4A4133;
}

.jafra-newsletter__body {
	margin-block-start: 10px;
	font-size: var(--jafra-text-13-5);
	color: #5A5140;
}

.jafra-newsletter__form {
	margin-block-start: 20px;
	max-inline-size: var(--jafra-container-form);
	margin-inline: auto;
}

.jafra-newsletter__form .jafra-input {
	block-size: 50px;
	padding-inline: 16px;
	font-size: var(--jafra-text-14);
}

/* Mobile: stacked, full width under the input. */
.jafra-newsletter__form .jafra-btn {
	inline-size: 100%;
	margin-block-start: 10px;
	padding-block: 15px;
	padding-inline: 0;
	block-size: auto;
}

@media (min-width: 1024px) {
	.jafra-newsletter {
		padding: 0;
	}

	.jafra-newsletter__inner {
		max-inline-size: var(--jafra-container-editorial);
		padding-block: 96px;
		padding-inline: 40px;
	}

	.jafra-newsletter__heading-ar {
		font-size: var(--jafra-text-42);
	}

	.jafra-newsletter__heading-en {
		margin-block-start: 4px;
		font-size: var(--jafra-text-30);
	}

	.jafra-newsletter__body {
		margin-block-start: 14px;
		font-size: var(--jafra-text-15-5);
	}

	.jafra-newsletter__form {
		margin-block-start: var(--jafra-space-32);
	}

	.jafra-newsletter__row {
		display: flex;
		gap: var(--jafra-space-12);
	}

	.jafra-newsletter__row .jafra-input {
		flex: 1;
		block-size: var(--jafra-input-height);
		padding-inline: 18px;
		font-size: var(--jafra-text-15);
	}

	/* Desktop: sits beside the input, sized by its own padding. */
	.jafra-newsletter__row .jafra-btn {
		flex: 0 0 auto;
		inline-size: auto;
		margin-block-start: 0;
		padding-block: 0;
		padding-inline: 34px;
		block-size: var(--jafra-input-height);
	}
}

/* Form feedback — the provider is not wired up in Phase 1, but the markup and
 * live region are in place for it.
 *
 * The live region must stay in the DOM so assistive tech is already observing
 * it when a message arrives, but it must occupy NO space while empty, or it
 * adds height the design does not have. `:empty` collapses it without removing
 * it from the accessibility tree. */
.jafra-newsletter__status {
	margin-block-start: var(--jafra-space-12);
	font-size: var(--jafra-text-13-5);
	color: #5A5140;
}

.jafra-newsletter__status:empty {
	margin-block-start: 0;
	display: block;
	block-size: 0;
	overflow: hidden;
}

/* Desktop and mobile carry different newsletter body copy (as with the
 * footer). Both ship; CSS selects one. */
.jafra-newsletter__body--desktop {
	display: none;
}

@media (min-width: 1024px) {
	.jafra-newsletter__body--desktop {
		display: block;
	}

	.jafra-newsletter__body--mobile {
		display: none;
	}
}

/* The heading is one <h2> containing two visually distinct lines, so the
 * accessible name stays a single coherent string. */
.jafra-newsletter__headings {
	display: block;
	font-weight: inherit;
	line-height: inherit;
}

.jafra-newsletter__heading-ar,
.jafra-newsletter__heading-en {
	display: block;
}

/* ==========================================================================
 * MOVED FROM pages/home.css IN PHASE 3
 *
 * These are COMPONENTS, not homepage layout: the product card, the collection
 * card, the art-directed <picture> and the section eyebrow are all reused by
 * shop, collection and product detail.
 *
 * They were originally written into the homepage page-stylesheet, which is
 * enqueued on the front page only — so the shop grid rendered completely
 * unstyled the first time it was built. Shared components belong here, where
 * every template gets them.
 * ========================================================================== */

/* ==========================================================================
 * ART-DIRECTED IMAGES
 * The focal point differs per breakpoint, so it arrives as a custom property
 * on the <picture> rather than inline on the <img>.
 * ========================================================================== */

.jafra-picture {
	display: block;
}

.jafra-picture img {
	object-position: var(--jafra-focal-mobile, 50% 50%);
}

@media (min-width: 1024px) {
	.jafra-picture img {
		object-position: var(--jafra-focal-desktop, 50% 50%);
	}
}

/* ==========================================================================
 * SHARED SECTION FURNITURE
 * The eyebrow above a section heading repeats across sections 05, 06, 07, 08
 * with the same treatment and different colours.
 * ========================================================================== */

.jafra-section-eyebrow {
	margin-block-end: 10px;
	font-size: var(--jafra-text-10-5);
	letter-spacing: var(--jafra-ls-28);
	text-transform: uppercase;
	color: var(--jafra-color-beige-mid);
}

@media (min-width: 1024px) {
	.jafra-section-eyebrow {
		margin-block-end: 18px;
		font-size: var(--jafra-text-11-5);
		letter-spacing: var(--jafra-ls-30);
	}
}

/* ==========================================================================
 * COLLECTION CARD
 * Source: section 05. Reused by the collection and shop pages later.
 * ========================================================================== */

.jafra-collection-card {
	display: block;
}

.jafra-collection-card__frame {
	position: relative;
	aspect-ratio: var(--jafra-ratio-product);
	overflow: hidden;
	background-color: var(--jafra-color-surface-sand);
}

.jafra-collection-card__image {
	position: absolute;
	inset: 0;
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
	transition: transform var(--jafra-duration-zoom) var(--jafra-ease);
}

/* A 52%-tall gradient rising from the foot of the card. */
.jafra-collection-card__scrim {
	position: absolute;
	inset-inline: 0;
	inset-block-end: 0;
	block-size: 52%;
	background-image: linear-gradient(
		0deg,
		rgba(var(--jafra-overlay-rgb), 0.7) 0%,
		rgba(var(--jafra-overlay-rgb), 0) 100%
	);
}

.jafra-collection-card__label {
	position: absolute;
	inset-inline: 12px;
	inset-block-end: 12px;
	color: var(--jafra-color-text-on-dark);
	transition: transform var(--jafra-duration-label) var(--jafra-ease);
}

.jafra-collection-card__tag {
	display: block;
	margin-block-end: 4px;
	font-size: 8.5px;
	letter-spacing: var(--jafra-ls-18);
	text-transform: uppercase;
	color: var(--jafra-color-beige-tag);
}

.jafra-collection-card__name-ar {
	display: block;
	font-size: var(--jafra-text-22);
	font-weight: var(--jafra-weight-semibold);
	line-height: var(--jafra-lh-100);
}

.jafra-collection-card__foot {
	display: block;
	margin-block-start: 3px;
	font-size: var(--jafra-text-11);
}

/* Desktop only. */
.jafra-collection-card__shop {
	display: none;
	color: var(--jafra-color-beige-eyebrow);
}

@media (min-width: 1024px) {
	.jafra-collection-card__scrim {
		background-image: linear-gradient(
			0deg,
			rgba(var(--jafra-overlay-rgb), 0.72) 0%,
			rgba(var(--jafra-overlay-rgb), 0) 100%
		);
	}

	.jafra-collection-card__label {
		inset-inline: 20px;
		inset-block-end: 20px;
	}

	.jafra-collection-card__tag {
		margin-block-end: 7px;
		font-size: var(--jafra-text-10-5);
		letter-spacing: var(--jafra-ls-22);
	}

	.jafra-collection-card__name-ar {
		font-size: var(--jafra-text-30);
	}

	.jafra-collection-card__foot {
		display: flex;
		align-items: center;
		justify-content: space-between;
		margin-block-start: 6px;
		font-size: var(--jafra-text-13);
		letter-spacing: var(--jafra-ls-03);
	}

	.jafra-collection-card__shop {
		display: inline;
	}

	.jafra-collection-card:hover .jafra-collection-card__image {
		transform: scale(1.05);
	}

	.jafra-collection-card:hover .jafra-collection-card__label {
		transform: translateY(-4px);
	}
}

/* ==========================================================================
 * PRODUCT CARD
 * Source: section 07. Reused across shop, collection, search and wishlist.
 * ========================================================================== */

.jafra-product-card {
	position: relative;
}

.jafra-product-card__frame {
	position: relative;
	aspect-ratio: var(--jafra-ratio-product);
	overflow: hidden;
	background-color: var(--jafra-color-surface-alt);
}

.jafra-product-card__image {
	position: absolute;
	inset: 0;
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
	transition: opacity var(--jafra-duration-tile) ease;
}

.jafra-product-card__image--hover {
	opacity: 0;
}

.jafra-product-card__badge {
	position: absolute;
	inset-block-start: 10px;
	inset-inline-start: 10px;
	z-index: var(--jafra-z-raised);
	padding: 3px 8px;
	border-radius: var(--jafra-radius-xs);
	color: #fff;
	font-size: var(--jafra-text-9);
	font-weight: var(--jafra-weight-semibold);
	letter-spacing: var(--jafra-ls-08);
	text-transform: uppercase;
}

/*
 * Mobile: always visible at 30px. Desktop: 36px and revealed on hover.
 * A touch device has no hover, so hiding it there would make it unreachable.
 */
.jafra-product-card__wish {
	position: absolute;
	inset-block-start: 9px;
	inset-inline-end: 9px;
	z-index: var(--jafra-z-raised);
	display: flex;
	align-items: center;
	justify-content: center;
	inline-size: 30px;
	block-size: 30px;
	border-radius: var(--jafra-radius-round);
	background-color: var(--jafra-color-scrim-light);
}

/* Saved state — the heart fills solid so a saved product reads at a glance.
 * `fill` (CSS) overrides the icon's inline `fill="none"`. Shared by the card
 * heart and the product-gallery heart. */
.jafra-product-card__wish.is-saved,
.jafra-gallery__wish.is-saved {
	color: var(--jafra-color-ink);
}
.jafra-product-card__wish.is-saved svg,
.jafra-gallery__wish.is-saved svg {
	fill: currentColor;
}

/* Desktop only. */
.jafra-product-card__quick {
	display: none;
}

.jafra-product-card__info {
	padding-block-start: var(--jafra-space-12);
}

.jafra-product-card__name-ar {
	display: block;
	font-size: var(--jafra-text-17);
	font-weight: var(--jafra-weight-semibold);
	line-height: var(--jafra-lh-100);
}

.jafra-product-card__name-en {
	display: block;
	margin-block-start: var(--jafra-space-4);
	font-size: var(--jafra-text-12);
	color: var(--jafra-color-text-muted);
}

.jafra-product-card__prices {
	display: flex;
	align-items: center;
	gap: var(--jafra-space-8);
	margin-block-start: 6px;
}

.jafra-product-card__price {
	font-size: var(--jafra-text-13);
	font-weight: var(--jafra-weight-semibold);
}

.jafra-product-card__was {
	font-size: var(--jafra-text-12);
	color: var(--jafra-color-beige-mid);
	text-decoration: line-through;
}

@media (min-width: 1024px) {
	.jafra-product-card__badge {
		inset-block-start: 14px;
		inset-inline-start: 14px;
		padding: 5px 11px;
		font-size: var(--jafra-text-10-5);
		letter-spacing: var(--jafra-ls-10);
	}

	.jafra-product-card__wish {
		inset-block-start: 12px;
		inset-inline-end: 12px;
		inline-size: 36px;
		block-size: 36px;
		opacity: 0;
		transform: translateY(-6px);
		transition: all var(--jafra-duration-normal) ease;
	}

	.jafra-product-card__quick {
		position: absolute;
		inset-inline: 14px;
		inset-block-end: 14px;
		z-index: var(--jafra-z-raised);
		display: block;
		padding-block: var(--jafra-space-12);
		background-color: var(--jafra-color-scrim-light-strong);
		color: var(--jafra-color-ink);
		font-size: var(--jafra-text-12);
		font-weight: var(--jafra-weight-semibold);
		letter-spacing: var(--jafra-ls-13);
		text-align: center;
		text-transform: uppercase;
		opacity: 0;
		transform: translateY(10px);
		transition: all var(--jafra-duration-normal) ease;
	}

	.jafra-product-card:hover .jafra-product-card__wish,
	.jafra-product-card__wish:focus-visible,
	.jafra-product-card__wish.is-saved,
	.jafra-product-card:hover .jafra-product-card__quick {
		opacity: 1;
		transform: translateY(0);
	}

	.jafra-product-card.has-hover:hover .jafra-product-card__image--primary {
		opacity: 0;
	}

	.jafra-product-card:hover .jafra-product-card__image--hover {
		opacity: 1;
	}

	.jafra-product-card__info {
		padding-block-start: var(--jafra-space-16);
	}

	.jafra-product-card__name-ar {
		font-size: var(--jafra-text-20);
	}

	.jafra-product-card__name-en {
		margin-block-start: 6px;
		font-size: var(--jafra-text-13-5);
	}

	.jafra-product-card__prices {
		gap: 10px;
		margin-block-start: 9px;
	}

	.jafra-product-card__price {
		font-size: var(--jafra-text-14-5);
	}

	.jafra-product-card__was {
		font-size: var(--jafra-text-13-5);
	}
}


/* ==========================================================================
 * QUANTITY STEPPER
 *
 * Moved here from pages/commerce-product.css in Phase 4: the cart uses the same
 * stepper, and that sheet is only enqueued on a product page — so on the cart
 * the input rendered with the browser's own border instead. Same rules, shared
 * home, no second implementation.
 * ========================================================================== */

.jafra-qty__btn {
	inline-size: 46px;
	font-size: var(--jafra-text-18);
	color: var(--jafra-color-ink);
	transition: color var(--jafra-duration-fast) ease;
}

.jafra-qty__btn:hover {
	color: var(--jafra-color-burgundy);
}

.jafra-qty__input {
	inline-size: 34px;
	border: 0;
	background: transparent;
	text-align: center;
	font-size: var(--jafra-text-14);
	font-weight: var(--jafra-weight-semibold);
	appearance: textfield;
	-moz-appearance: textfield;
}

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

/* ==========================================================================
 * CART DRAWER
 *
 * The frame is the Phase 1 `.jafra-drawer` — position, transition, scrim and
 * focus behaviour are all inherited. Only three things differ: it comes from the
 * trailing edge rather than the leading one, it is a little wider, and its body
 * scrolls independently of the footer so the subtotal and CTAs stay in view.
 * ========================================================================== */

.jafra-cart-drawer {
	inset-inline-start: auto;
	inset-inline-end: 0;
	inline-size: min(92vw, 420px);
	transform: translateX(100%);
}

.jafra-cart-drawer[aria-hidden='false'] {
	transform: translateX(0);
}

.jafra-cart-drawer__title {
	margin: 0;
	font-size: var(--jafra-text-14);
	font-weight: var(--jafra-weight-semibold);
	letter-spacing: var(--jafra-ls-14);
	text-transform: uppercase;
}

.jafra-cart-drawer__body {
	flex: 1;
	min-block-size: 0;
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

.jafra-cart-drawer__body .jafra-ship-progress {
	margin: var(--jafra-space-16) var(--jafra-gutter-mobile) 0;
	flex: 0 0 auto;
}

.jafra-mini-cart__list {
	flex: 1;
	min-block-size: 0;
	overflow-y: auto;
	margin: 0;
	padding: var(--jafra-space-16) var(--jafra-gutter-mobile);
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: var(--jafra-space-16);
}

.jafra-mini-cart__item {
	position: relative;
	display: grid;
	grid-template-columns: 72px 1fr auto;
	gap: 14px;
	align-items: start;
}

.jafra-mini-cart__frame {
	display: block;
	inline-size: 72px;
	block-size: 94px;
	overflow: hidden;
	background-color: var(--jafra-color-surface-alt);
	border-radius: 2px;
}

.jafra-mini-cart__frame a,
.jafra-mini-cart__frame img {
	display: block;
	inline-size: 100%;
	block-size: 100%;
	object-fit: cover;
	object-position: var(--jafra-focal, 50% 50%);
}

.jafra-mini-cart__text {
	display: flex;
	flex-direction: column;
	min-inline-size: 0;
}

.jafra-mini-cart__name-ar {
	font-size: var(--jafra-text-18);
	font-weight: var(--jafra-weight-semibold);
	line-height: var(--jafra-lh-100);
}

.jafra-mini-cart__name {
	margin-block-start: 3px;
	font-size: var(--jafra-text-12-5);
	color: var(--jafra-color-text-copy);
}

.jafra-mini-cart__name a {
	color: inherit;
}

.jafra-mini-cart__meta {
	margin-block-start: 4px;
	font-size: var(--jafra-text-11-5);
	color: var(--jafra-color-text-muted);
}

.jafra-mini-cart__line {
	margin-block-start: var(--jafra-space-8);
	font-size: var(--jafra-text-13);
	font-weight: var(--jafra-weight-semibold);
}

.jafra-mini-cart__remove {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 14px;
	margin: -14px;
	color: var(--jafra-color-beige-mid);
}

.jafra-mini-cart__remove:hover,
.jafra-mini-cart__remove:focus-visible {
	color: var(--jafra-color-burgundy);
}

.jafra-mini-cart__foot {
	flex: 0 0 auto;
	padding: var(--jafra-space-16) var(--jafra-gutter-mobile) calc(var(--jafra-space-24) + env(safe-area-inset-bottom));
	border-block-start: var(--jafra-border-hairline);
	background-color: var(--jafra-color-bg);
}

.jafra-mini-cart__subtotal {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	margin: 0 0 var(--jafra-space-16);
	font-size: var(--jafra-text-14);
	color: var(--jafra-color-text-copy);
}

.jafra-mini-cart__subtotal .amount {
	font-size: var(--jafra-text-20);
	font-weight: var(--jafra-weight-semibold);
	color: var(--jafra-color-ink);
}

/*
 * WooCommerce prints "View cart" and "Checkout" through
 * `woocommerce_widget_shopping_cart_buttons`, in that order.
 */
.jafra-mini-cart__actions {
	display: flex;
	flex-direction: column;
	gap: 10px;
	margin: 0;
}

.jafra-mini-cart__actions .button {
	display: flex;
	align-items: center;
	justify-content: center;
	block-size: 52px;
	border-radius: var(--jafra-radius-sm);
	border: var(--jafra-border-width-input) solid var(--jafra-color-ink);
	color: var(--jafra-color-ink);
	font-size: var(--jafra-text-12-5);
	font-weight: var(--jafra-weight-semibold);
	letter-spacing: var(--jafra-ls-10);
	text-transform: uppercase;
}

.jafra-mini-cart__actions .checkout {
	order: -1;
	background-color: var(--jafra-color-burgundy);
	border-color: var(--jafra-color-burgundy);
	color: var(--jafra-color-text-on-dark);
}

.jafra-mini-cart__actions .checkout:hover {
	background-color: var(--jafra-color-burgundy-hover);
	border-color: var(--jafra-color-burgundy-hover);
}

.jafra-mini-cart__empty {
	flex: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--jafra-space-16);
	padding: var(--jafra-gutter-mobile);
	text-align: center;
}

.jafra-mini-cart__empty p {
	margin: 0;
	font-size: var(--jafra-text-14);
	color: var(--jafra-color-text-copy);
}


/* ==========================================================================
 * BREADCRUMB
 *
 * Moved here from pages/commerce.css in Phase 5: the breadcrumb is a shared
 * component used by commerce AND editorial pages, but its styling lived in the
 * commerce-only sheet — so on Shipping & Returns and the Size Guide the trail
 * rendered as a bare numbered list. Its home is the always-loaded components
 * sheet. Still desktop-only, as every artboard that carries it draws it only
 * there (docs/DESIGN-DISCREPANCIES.md §32).
 * ========================================================================== */

/* ==========================================================================
 * BREADCRUMB
 * Source: all three commerce designs — 12px, .04em, muted, current in ink.
 * ========================================================================== */

/*
 * Breadcrumbs are DESKTOP ONLY across all three commerce designs — shop,
 * collection and product mobile artboards all omit them. Hidden rather than
 * dropped from the markup so the trail stays available to assistive tech and
 * to search engines on every breakpoint.
 * See docs/DESIGN-DISCREPANCIES.md §32.
 */
.jafra-breadcrumb {
	position: absolute;
	inline-size: 1px;
	block-size: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

@media (min-width: 1024px) {
	.jafra-breadcrumb {
		position: static;
		inline-size: auto;
		block-size: auto;
		margin: 0;
		overflow: visible;
		clip-path: none;
		white-space: normal;
	}
}

.jafra-breadcrumb__list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: var(--jafra-text-12);
	letter-spacing: var(--jafra-ls-04);
	color: var(--jafra-color-text-muted);
}

/* Separators are decorative, so they are drawn rather than written — a screen
 * reader announces the list, not a run of slashes. */
.jafra-breadcrumb__item + .jafra-breadcrumb__item::before {
	content: '/';
	margin-inline: var(--jafra-space-8);
	color: var(--jafra-color-text-muted);
}

.jafra-breadcrumb__link {
	transition: color var(--jafra-duration-fast) ease;
}

.jafra-breadcrumb__link:hover {
	color: var(--jafra-color-burgundy);
}

.jafra-breadcrumb__current {
	color: var(--jafra-color-ink);
}

