/* ==========================================================================
   Yazan (Astra Child) — homepage sections
   Comma-style flow → luxury jewelry. Uses design tokens (main.css), motion
   classes (motion.css: .yz-reveal / .yz-hero / [data-img-reveal] / [data-parallax]).
   Loaded only on the front page (see inc/enqueue.php).
   ========================================================================== */

.yz-home { width: 100%; overflow-x: clip; }
.yz-home-section { position: relative; }

/* Headings on DARK sections must be ivory. Astra assigns a dark heading color to the heading
   ELEMENT (higher specificity than the inherited section color), so force it back here. */
.yz-hero__title,
.yz-section--ink h1, .yz-section--ink h2, .yz-section--ink h3,
.yz-cstory h2 { color: var(--yz-ivory); }

/* Section vertical rhythm — luxury = whitespace. */
.yz-home-section > .yz-container { padding-block: var(--yz-section); }
.yz-hero > *, .yz-cstory > * { } /* hero/cstory manage their own spacing */

/* Section heads */
.yz-home-head { margin-bottom: clamp(28px, 4vw, 56px); text-align: center; position: relative; }
.yz-home-head h2 { margin: 0; }
.yz-home-head__intro { color: var(--yz-muted); margin: 10px 0 0; }
.yz-section--ink .yz-home-head__intro { color: var(--yz-silver); }
.yz-home-head__link { position: absolute; inset-inline-end: 0; bottom: 4px; }

/* --------------------------------------------------------------------------
   1b. COLLECTION SWATCHES ROW + BIG IMAGE  (commafootball top strip)
   -------------------------------------------------------------------------- */
.yz-swatches { background: var(--yz-ink); color: var(--yz-ivory); }
.yz-swatches > .yz-container { padding-block: clamp(24px, 3.4vw, 44px); }

/* Horizontal swatch rail — scrolls on small screens, fits on desktop. */
.collection-swatches__grid {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: minmax(120px, 1fr);
	gap: clamp(12px, 1.6vw, 22px);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;
	padding-bottom: 4px;
}
.collection-swatches__grid::-webkit-scrollbar { display: none; }
/* Pinned-products rail (yazan-showcase): the owner may pin 2 rings or 20, so a tile never grows
   past the category-rail size — a short list sits centred instead of stretching to half the page. */
/* Product photos are 3:2 landscape inside a 4:5 tile, so they are cropped (cover). Yazan_Image_Focus
   measures where the ring sits in each photo and prints it as an inline object-position, so the
   crop lands on the ring instead of on the geometric middle of the photo. */
@media (min-width: 768px) {
	.elementor-widget-yazan-showcase .collection-swatches__grid {
		grid-auto-columns: minmax(120px, 168px);
		justify-content: safe center; /* safe: a long rail still scrolls from its first tile */
	}
}

.collection-swatch {
	scroll-snap-align: start;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 12px;
	text-decoration: none;
	color: var(--yz-ivory);
}
.collection-swatch__media {
	display: block; width: 100%; aspect-ratio: 4 / 5; overflow: hidden;
	background: linear-gradient(160deg, #2a2320, var(--yz-ink));
	border: 1px solid var(--yz-hairline);
}
.collection-swatch__media img {
	width: 100%; height: 100%; object-fit: cover; display: block;
	transition: transform 1s var(--mo-ease-out, ease);
}
.collection-swatch:hover .collection-swatch__media img,
.collection-swatch:focus-visible .collection-swatch__media img { transform: scale(1.06); }
.collection-swatch__label {
	font-family: var(--yz-font-body);
	font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase;
	color: var(--yz-silver); text-align: center; line-height: 1.3;
	transition: color 0.3s ease;
}
.collection-swatch:hover .collection-swatch__label,
.collection-swatch:focus-visible .collection-swatch__label { color: var(--yz-sand); }

/* Big image band directly under the swatch rail. */
.yz-bigimage {
	position: relative; display: flex; align-items: flex-end;
	/* Height follows the WIDTH too (42vw), not only the viewport height: the ring photos are 3:2
	   with the ring filling the middle half, so on a short, wide window (1366×768 laptop) a
	   70vh band cropped the ring's top and bottom and it read as off-centre. 42vw keeps the
	   middle ~63% of a 3:2 photo in view, so the centred ring stays whole and centred. */
	min-height: clamp(420px, max(70vh, 42vw), 760px);
	overflow: hidden; isolation: isolate; text-decoration: none;
	color: var(--yz-ivory); background: var(--yz-ink);
}
.yz-bigimage__media {
	position: absolute; inset: 0; z-index: -2;
	background-size: cover; background-position: center;
	transition: transform 1.6s var(--mo-ease-out, ease);
	/* Above-the-fold entrance: pure CSS (no scroll observer), image visible on first paint and
	   gently settling in. Replaces the observer-gated clip-path curtain that flashed the whole
	   fold black for ~1.2s on every load. `backwards` fill so hover-scale still works afterwards. */
	animation: yz-bigimage-settle var(--mo-hero) var(--mo-ease-out) backwards;
}
@keyframes yz-bigimage-settle {
	from { transform: scale(1.05); }
	to   { transform: scale(1); }
}
/* --------------------------------------------------------------------------
   HERO CHOREOGRAPHY — the page's opening statement, staged rather than dumped.

   This band is the homepage's hero and its LCP element. It previously faded its whole content
   block in as one 200ms lump; the three lines now arrive in the order a person reads them —
   category, then promise, then invitation — which is what makes an entrance feel directed instead
   of merely animated.

   The delays are multiples of `--mo-stagger`, so this cascade obeys the store's motion-intensity
   setting like everything else: at 0 the multiplications collapse and all three land together.

   ⚠️ `.yz-bigimage__media` DELIBERATELY HAS NO OPACITY ANIMATION, here or anywhere. It is the
   measured LCP element, and an element at opacity 0 is not "painted" — an entrance fade on it
   would push the site's headline performance metric back by the length of the fade. It scales
   only. See motion.css Part 14.
   -------------------------------------------------------------------------- */
.yz-bigimage__content { animation: none; } /* the children animate, not the wrapper */

.yz-bigimage__eyebrow,
.yz-bigimage__title,
.yz-bigimage__cta {
	animation: yz-fade-up var(--mo-slow) var(--mo-ease-out) backwards;
}

.yz-bigimage__eyebrow { animation-delay: calc(var(--mo-stagger) * 2); }
.yz-bigimage__title   { animation-delay: calc(var(--mo-stagger) * 3.4); }
.yz-bigimage__cta     { animation-delay: calc(var(--mo-stagger) * 5); }

/* The title carries the most weight, so it gets the longest, most damped travel. */
.yz-bigimage__title { animation-duration: var(--mo-hero); }

/* A hairline that draws itself under the eyebrow as the hero settles — the one piece of pure
   decoration in the band, and it costs a pseudo-element and a scaleX. */
.yz-bigimage__eyebrow::after {
	content: '';
	display: block;
	height: 1px;
	margin-block-start: 10px;
	background: currentColor;
	opacity: 0.45;
	transform: scaleX(0);
	transform-origin: left center;
	/* `both`, not "backwards forwards" — animation-fill-mode takes ONE keyword, and the invalid
	   two-word form made the whole shorthand fail to parse, leaving the rule stuck at scaleX(0)
	   (i.e. permanently invisible). Caught by reading the computed ::after transform rather than
	   by looking at the page, where a missing 1px hairline is easy to miss. */
	animation: yz-rule-in var(--mo-hero) var(--mo-ease-out) calc(var(--mo-stagger) * 3) both;
}

@keyframes yz-rule-in {
	from { transform: scaleX(0); }
	to   { transform: scaleX(1); }
}

[dir='rtl'] .yz-bigimage__eyebrow::after { transform-origin: right center; }

@media (prefers-reduced-motion: reduce) {
	.yz-bigimage__media,
	.yz-bigimage__content,
	.yz-bigimage__eyebrow,
	.yz-bigimage__title,
	.yz-bigimage__cta { animation: none; }

	/* The rule must still be drawn, just not drawn *in* — otherwise reduced motion silently
	   deletes a design element rather than stilling it. */
	.yz-bigimage__eyebrow::after { animation: none; transform: scaleX(1); }
}
.yz-bigimage:hover .yz-bigimage__media { transform: scale(1.04); }
.yz-bigimage__scrim {
	position: absolute; inset: 0; z-index: -1;
	background: linear-gradient(0deg, rgba(12,11,10,0.78) 0%, rgba(12,11,10,0.28) 46%, rgba(12,11,10,0.05) 100%);
}
.yz-bigimage__content {
	width: 100%; display: flex; flex-direction: column; align-items: flex-start;
	gap: 16px; padding-block: clamp(40px, 7vh, 88px);
}
.yz-bigimage__eyebrow { color: var(--yz-sand); }
.yz-bigimage__title {
	font-family: var(--yz-font-display); font-weight: 600; line-height: 1.05;
	font-size: clamp(30px, 5vw, 64px); max-width: 18ch; color: var(--yz-ivory);
}
.yz-bigimage__cta { margin-top: 6px; }
@media (max-width: 767px) {
	.collection-swatches__grid { grid-auto-columns: minmax(108px, 42%); }
	.yz-bigimage { min-height: 60vh; }
}

/* --------------------------------------------------------------------------
   2. HERO
   -------------------------------------------------------------------------- */
.yz-hero {
	min-height: 92vh;
	display: flex;
	align-items: flex-end;
	color: var(--yz-ivory);
	background: radial-gradient(120% 90% at 72% 28%, #2a2320 0%, var(--yz-ink) 58%);
	overflow: hidden;
	isolation: isolate;
}
.yz-hero__media {
	position: absolute; inset: 0; z-index: -2;
	background-size: cover; background-position: center;
}
.yz-hero__scrim {
	position: absolute; inset: 0; z-index: -1;
	background: linear-gradient(90deg, rgba(12,11,10,0.72) 0%, rgba(12,11,10,0.35) 45%, rgba(12,11,10,0.1) 100%);
}
.yz-hero__inner { width: 100%; padding-block: clamp(48px, 10vh, 120px); }
.yz-hero__eyebrow { color: var(--yz-sand); margin: 0 0 18px; }
.yz-hero__title {
	font-family: var(--yz-font-display);
	font-weight: 600;
	line-height: 1.04;
	font-size: clamp(40px, 7vw, 88px);
	margin: 0;
}
.yz-hero__intro { max-width: 44ch; margin: 22px 0 30px; color: rgba(245,241,233,0.86); font-size: 1.05rem; }
.yz-hero__scroll {
	position: absolute; inset-inline-start: 50%; bottom: 22px; width: 1px; height: 46px;
	background: linear-gradient(var(--yz-sand), transparent);
	transform: translateX(-50%);
}
@media (max-width: 767px) {
	.yz-hero { min-height: 78vh; }
	.yz-hero__scrim { background: linear-gradient(0deg, rgba(12,11,10,0.8) 0%, rgba(12,11,10,0.25) 100%); }
}

/* --------------------------------------------------------------------------
   3. FEATURED COLLECTIONS
   -------------------------------------------------------------------------- */
.yz-collection-card {
	display: block; position: relative; overflow: hidden;
	text-decoration: none; color: var(--yz-ink);
}
.yz-collection-card__media {
	display: block; aspect-ratio: 3 / 4; background-size: cover; background-position: center;
	background-color: var(--yz-ink);
	background-image: linear-gradient(160deg, #2a2320, var(--yz-ink));
	transition: transform 1.2s var(--mo-ease-out);
}
.yz-collection-card:hover .yz-collection-card__media { transform: scale(1.05); }
.yz-collection-card__body {
	position: absolute; inset-inline: 0; bottom: 0;
	display: flex; align-items: baseline; justify-content: space-between;
	gap: 12px; padding: 18px 20px;
	background: linear-gradient(0deg, rgba(12,11,10,0.7), transparent);
	color: var(--yz-ivory);
}
.yz-collection-card__name { font-family: var(--yz-font-display); font-size: 20px; font-weight: 600; }
.yz-collection-card__cta { color: var(--yz-sand); }

/* --------------------------------------------------------------------------
   4. BEST SELLERS — force a clean 4-up grid regardless of Woo column setting
   -------------------------------------------------------------------------- */
.yz-best__grid ul.products {
	display: grid; grid-template-columns: repeat(4, 1fr); gap: 32px; margin: 0;
}
.yz-best__grid ul.products::before,
.yz-best__grid ul.products::after { content: none; } /* kill Woo clearfix in grid */
.yz-best__grid ul.products li.product { width: auto !important; margin: 0 !important; float: none !important; }
@media (max-width: 991px) { .yz-best__grid ul.products { grid-template-columns: repeat(2, 1fr); gap: 20px; } }

/* --------------------------------------------------------------------------
   5. BRAND STORY (two column, dark)
   -------------------------------------------------------------------------- */
.yz-story__grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(28px, 5vw, 72px); align-items: center; }
.yz-story__media { overflow: hidden; }
.yz-story__img {
	aspect-ratio: 4 / 5; background-size: cover; background-position: center;
	background-image: radial-gradient(90% 80% at 40% 30%, #37302b, var(--yz-ink));
}
.yz-story__text h2 { margin: 8px 0 18px; }
.yz-story__body { color: var(--yz-silver); max-width: 52ch; margin-bottom: 28px; }
@media (max-width: 767px) { .yz-story__grid { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   6. COLLECTION STORIES (full-bleed, parallax)
   -------------------------------------------------------------------------- */
.yz-cstory { min-height: 82vh; display: grid; grid-template-columns: 1fr 1fr; color: var(--yz-ivory); }
.yz-cstory.is-flipped .yz-cstory__media { order: 2; }
.yz-cstory__media { position: relative; overflow: hidden; min-height: 60vh; }
.yz-cstory__img {
	position: absolute; inset-inline: 0; top: -10%; height: 120%;
	background-size: cover; background-position: center;
	background-image: linear-gradient(150deg, #3a201f, var(--yz-ink));
	will-change: transform;
}
.yz-cstory__scrim { position: absolute; inset: 0; background: rgba(12,11,10,0.28); }
.yz-cstory__panel {
	display: flex; flex-direction: column; justify-content: center;
	background: var(--yz-ink);
	padding: clamp(40px, 7vw, 96px) clamp(24px, 6vw, 88px);
}
.yz-cstory__panel h2 { margin: 8px 0 16px; }
.yz-cstory__body { color: var(--yz-silver); max-width: 46ch; margin-bottom: 28px; }
@media (max-width: 900px) {
	.yz-cstory { grid-template-columns: 1fr; }
	.yz-cstory.is-flipped .yz-cstory__media { order: 0; }
}

/* --------------------------------------------------------------------------
   7. TRUST & QUALITY
   -------------------------------------------------------------------------- */
.yz-trust__grid { grid-template-columns: repeat(3, 1fr); text-align: center; }
.yz-trust__item { padding: 8px; }
.yz-trust__icon { display: inline-flex; width: 40px; height: 40px; color: var(--yz-agate); margin-bottom: 14px; }
.yz-trust__icon svg { width: 100%; height: 100%; }
.yz-trust__title { font-family: var(--yz-font-display); font-size: 20px; font-weight: 600; margin: 0 0 6px; }
/* The homepage runs the six promises as one slim row (commafootball's icon line, 2026-09-24), ~190px a
   column. `.yazan h3` (0,1,1) outranks the rule above and set these at 28px, which broke
   "Craftsmanship" mid-word; restated one class deeper, and words are never split. */
.yz-trust .yz-trust__title {
	font-size: clamp(17px, 1.35vw, 20px);
	overflow-wrap: normal;
	hyphens: manual;
}
.yz-trust__desc { color: var(--yz-muted); margin: 0; font-size: 0.95rem; }
@media (max-width: 767px) { .yz-trust__grid { grid-template-columns: 1fr; gap: 28px; } }

/* --------------------------------------------------------------------------
   8. REVIEWS (dark testimonials)
   -------------------------------------------------------------------------- */
.yz-review { margin: 0; text-align: center; padding: 8px; }
.yz-review__stars { color: var(--yz-amber, var(--yz-sand)); letter-spacing: 0.2em; margin-bottom: 16px; }
.yz-review__quote {
	font-family: var(--yz-font-display); font-size: clamp(18px, 1.6vw, 22px);
	line-height: 1.5; color: var(--yz-ivory); margin: 0 0 18px; quotes: "“" "”";
}
.yz-review__by { display: flex; flex-direction: column; gap: 2px; }
.yz-review__name { color: var(--yz-ivory); letter-spacing: 0.04em; }
.yz-review__city { color: var(--yz-silver); font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.12em; }

/* --------------------------------------------------------------------------
   9. NEWSLETTER
   -------------------------------------------------------------------------- */
.yz-newsletter__inner { max-width: 620px; margin-inline: auto; text-align: center; }
.yz-newsletter__title { margin: 10px 0 12px; }
.yz-newsletter__intro { color: var(--yz-muted); margin: 0 0 26px; }
.yz-newsletter__form { display: flex; gap: 10px; max-width: 480px; margin-inline: auto; }
.yz-newsletter__form input[type="email"] {
	flex: 1; border: 1px solid var(--yz-silver); background: transparent;
	padding: 14px 16px; border-radius: 0; color: var(--yz-ink); font-size: 15px;
}
.yz-newsletter__form input[type="email"]:focus { outline: none; border-color: var(--yz-ink); }
.yz-newsletter__note { margin: 12px 0 0; font-size: 0.8rem; color: var(--yz-muted); }
@media (max-width: 480px) { .yz-newsletter__form { flex-direction: column; } }

/* --------------------------------------------------------------------------
   9. ELEMENTOR BRIDGE
   --------------------------------------------------------------------------
   Everything above styles the theme's own template parts. When Elementor owns the homepage the
   SAME components render inside Elementor's wrappers, and a wrapper between a flex/grid parent and
   its child is enough to break a rule that was written for a direct relationship.

   These rules exist only to neutralise that extra element. They add no design of their own, they
   are inert when the theme draws the homepage (no `.elementor-widget` is present), and they are
   scoped so they can never leak onto an Elementor page that is not this one.
   -------------------------------------------------------------------------- */

/* ⚠️ THE SPACING RESET — the single most consequential rule in this section.
   Elementor gives every widget a bottom margin and every container a flex gap of its own. The
   theme's own components already carry their exact vertical rhythm (`.yz-home-head h2 { margin: 0 }`,
   `__intro { margin: 10px 0 0 }`, `__body { margin-bottom: 28px }` …), so Elementor's defaults do
   not replace that rhythm — they are ADDED to it, once per widget and once per container. Measured
   over the eight bands that came to 2276px of page height that the theme never had.
   Zeroing both hands the spacing back to the component styles above, which is where it was
   designed. Anything an editor sets in Elementor is an inline custom property and still wins. */
.yz-home-section.e-con,
.yz-home-section .e-con { --gap: 0px; --row-gap: 0px; --column-gap: 0px; }

/* …except the two bands whose gap IS the design. `.yz-story__grid` and `.yz-cstory` are the theme's
   own two-column grids; Elementor writes `gap: var(--gap)` at the same specificity as their `gap`
   declaration, so the value has to be handed back through the variable rather than fought for. */
.yz-home-section.e-con.yz-story__grid,
.yz-home-section .e-con.yz-story__grid { --gap: clamp(28px, 5vw, 72px); --column-gap: clamp(28px, 5vw, 72px); --row-gap: clamp(28px, 5vw, 72px); }

/* ⚠️ AND THE SAME TIE DECIDES `display` ITSELF.
   `.e-con { display: flex; flex-direction: column }` is one class; so is `.yz-story__grid
   { display: grid }`. On a tie the later stylesheet wins, and Elementor's is not reliably earlier —
   when it won, both two-column bands stacked vertically and the story band grew by 376px with its
   image at full container width. Restating the grid one class deeper settles it in the theme's
   favour permanently. The breakpoints are the originals: 767px for the story, 900px for cstory.

   Both grid bands are built as `full` containers precisely so this rule has the columns as its
   own children. A `boxed` container would insert an `.e-con-inner` between the two, and the grid
   would lay out that single wrapper instead — which collapsed the story band to one 544px column
   until the container type was changed. */
.yz-home-section .e-con.yz-story__grid {
	display: grid; grid-template-columns: 1fr 1fr; align-items: center;
	gap: clamp(28px, 5vw, 72px);
}
.yz-home-section.e-con.yz-cstory {
	display: grid; grid-template-columns: 1fr 1fr; min-height: 82vh;
}
@media (max-width: 767px) {
	.yz-home-section .e-con.yz-story__grid { grid-template-columns: 1fr; }
}
@media (max-width: 900px) {
	.yz-home-section.e-con.yz-cstory { grid-template-columns: 1fr; }
}

/* `:not(:last-child)` mirrors Elementor's own selector so this is not a specificity tie decided by
   whichever stylesheet happens to load second — the extra ancestor class settles it here. */
.yz-home-section .elementor-widget:not(:last-child),
.yz-home-section .elementor-widget { margin-block-end: 0; }

/* THE INNER CONTAINER KEEPS `yz-container` — for `max-width` and the horizontal gutter, which is
   how its contents line up with the header and footer — and gives back only the vertical padding,
   which the band itself already applies. Reproducing the width in Elementor controls instead was
   tried and drifted: `boxed_width` did not survive, columns came out ~85px wider than the theme's
   and every 4:5 image grew with them. */
.yz-home-section > .e-con.yz-container { padding-block: 0; }

/* Tighter vertical rhythm between homepage bands (owner request, 2026-09-22). Each Elementor band
   carries clamp(56px, 8vw, 120px) top AND bottom, so two neighbours sat ~240px apart on desktop.
   Overridden here rather than in the Elementor document so every band changes together; the
   swatch rail (own, smaller padding) and the full-bleed story panels (zero padding) are excluded.
   Elementor writes the padding as --padding-* variables at three-class specificity, hence the
   longer selector. */
.elementor .elementor-element.yz-home-section.e-con:not(.yz-swatches):not(.yz-cstory):not(.yz-rail-band):not(.yz-split-band):not(.yz-feature-banner):not(.yz-poster-band) {
	--padding-top: clamp(36px, 4.5vw, 64px);
	--padding-bottom: clamp(36px, 4.5vw, 64px);
}
.yz-home-section .yz-home-head { margin-bottom: clamp(20px, 2.6vw, 36px); }

/* THE COMMAFOOTBALL RHYTHM (owner request, 2026-09-24). Section headings are gone from the
   homepage — the banner above a product row introduces it, as on the reference — and so is the
   white space they sat in. Measured on commafootball.com at 1440px: 10px between a banner and the
   cards under it, and the next banner follows the prices after little more than a line's height.

   `yz-rail-band`      — a full-width product row (ProductRail): Best Sellers, the category band.
   `yz-split-band`     — the categories as split banners that touch the bands on either side.
   `yz-feature-banner` — the full-bleed photograph between the two rows. Its Elementor padding was
                         always 0, but the general rule above gave it 64px of bare page above and
                         below — most of the empty strip the owner boxed under Best Sellers.

   All three are excluded from the general band padding above rather than out-specified here, so
   the rules can never be decided by source order. */
.elementor .elementor-element.yz-home-section.e-con.yz-rail-band {
	--padding-top: 12px;
	--padding-bottom: clamp(24px, 2.8vw, 40px);
	/* The reference's rows are pure white between its photographs; the page behind them is Astra's
	   cool grey. The surface token is white in Black and the burgundy panel colour in Burgundy. */
	background-color: var(--yz-surface, #fff);
}
/* The Trending / featured row sits on the same dark band as the top tile rail (owner request,
   2026-09-24) — the rail's `yz-section--ink` colours, so both follow the Black ⇄ Burgundy switch
   together. Every text on the product cards is re-coloured for the dark ground. */
.elementor .elementor-element.yz-home-section.e-con.yz-rail-band.yz-feature-row:has(.yzhp-feature--ground-dark) {
	background-color: var(--yz-ink);
	color: var(--yz-ivory);
}
html[data-yz-theme="burgundy"] .elementor .elementor-element.yz-home-section.e-con.yz-rail-band.yz-feature-row:has(.yzhp-feature--ground-dark) {
	background-color: var(--yz-surface-2);
	color: var(--yz-text);
}
.yz-feature-row .yzhp-feature--ground-dark .yzhp-feature__title,
.yz-feature-row .yzhp-feature--ground-dark .yzhp-feature__link,
.yz-feature-row .yzhp-feature--ground-dark .yzhp-carousel__nav,
/* `.yazan … li.product.yz-card` matches woocommerce.css's card rules and adds the band, so it wins
   on specificity, not source order. */
.yazan .yz-feature-row .yzhp-feature--ground-dark ul.products li.product.yz-card .woocommerce-loop-product__title,
.yazan .yz-feature-row .yzhp-feature--ground-dark ul.products li.product.yz-card .price,
.yazan .yz-feature-row .yzhp-feature--ground-dark ul.products li.product.yz-card .price .amount { color: var(--yz-ivory); }
.yazan .yz-feature-row .yzhp-feature--ground-dark ul.products li.product.yz-card:focus-within .woocommerce-loop-product__title { color: var(--yz-sand); }
@media (hover: hover) {
	.yazan .yz-feature-row .yzhp-feature--ground-dark ul.products li.product.yz-card:hover .woocommerce-loop-product__title { color: var(--yz-sand); }
}
.yz-feature-row .yzhp-feature--ground-dark .yzhp-feature__intro,
.yazan .yz-feature-row .yzhp-feature--ground-dark ul.products li.product.yz-card .yz-subject,
.yazan .yz-feature-row .yzhp-feature--ground-dark ul.products li.product.yz-card .ast-woo-product-category { color: var(--yz-silver); }
.yz-feature-row .yzhp-feature--ground-dark .yzhp-feature__link:hover { color: var(--yz-sand); }

/* --------------------------------------------------------------------------
   TRENDING ROW MOTION (2026-09-24) — a directed entrance and a spotlight hover, for the dark band.

   Entrance, in reading order, one focal motion at a time:
     1. the side label: title → intro → "View all", each rising a few px, then a sand hairline
        draws under the title;
     2. the cards, one after another (index-staggered, capped at 4 so a slid-in card is not late):
        the photo SETTLES — from a slight zoom to rest, like light finding the stone — then the
        words rise under it, then the badges arrive.
   Hover (real pointers only): the hovered card stays lit and the others step back (spotlight),
   and a sand hairline draws under its photo — the lift's shadow was invisible on the dark ground.

   Mechanics (frontend-animation skill): transform-family + opacity only, soft ease-out, 400–1400ms.
   The entrance is a one-shot KEYFRAME animation keyed on `.is-inview` (motion.js), not the shared
   `.yz-reveal` transition — a transition-delay would also delay every later hover on the card.
   Individual `scale`/`translate` properties keep the settle, the hover zoom (`transform`) and the
   hover lift (`translate` on the li) on separate channels, so none cancels another.
   Everything scales with --mo-intensity, and reduced motion / no-JS show the final state at once.
   -------------------------------------------------------------------------- */
@keyframes yz-trend-rise   { from { opacity: 0; translate: 0 var(--mo-rise); } }
@keyframes yz-trend-copy   { from { opacity: 0; translate: 0 calc(var(--mo-rise) * 0.5); } }
@keyframes yz-trend-settle { from { opacity: 0; scale: calc(1 + 0.12 * var(--mo-intensity)); } }
@keyframes yz-trend-fade   { from { opacity: 0; } }
@keyframes yz-trend-draw   { from { transform: scaleX(0); } }

/* 1 — the side label. The header itself stays put; its lines carry the motion. */
.yz-feature-row .yzhp-feature__head[data-reveal] { opacity: 1; translate: none; transition: none; }
.yz-feature-row .yzhp-feature__head:not(.is-inview) > * { opacity: 0; }
.yz-feature-row .yzhp-feature__head.is-inview > * {
	animation: yz-trend-rise var(--mo-slow) var(--mo-ease-out) backwards;
}
.yz-feature-row .yzhp-feature__head.is-inview > :nth-child(2) { animation-delay: calc(var(--mo-stagger) * 1.5); }
.yz-feature-row .yzhp-feature__head.is-inview > :nth-child(3) { animation-delay: calc(var(--mo-stagger) * 3); }
.yz-feature-row .yzhp-feature__title::after {
	content: '';
	display: block;
	width: 44px;
	height: 1px;
	margin-block-start: 14px;
	background: var(--yz-sand);
	opacity: 0.7;
	transform-origin: left center;
}
[dir='rtl'] .yz-feature-row .yzhp-feature__title::after { transform-origin: right center; }
.yz-feature-row .yzhp-feature__head.is-inview .yzhp-feature__title::after {
	animation: yz-trend-draw var(--mo-slow) var(--mo-ease-out) calc(var(--mo-stagger) * 4) backwards;
}

/* 2 — the cards. --yz-i is the card's place in the first screenful. */
.yz-feature-row ul.products > li.product:nth-child(2) { --yz-i: 1; }
.yz-feature-row ul.products > li.product:nth-child(3) { --yz-i: 2; }
.yz-feature-row ul.products > li.product:nth-child(n + 4) { --yz-i: 3; }
.yazan .yz-feature-row ul.products > li.product.yz-reveal {
	/* Own the card's motion here: no shared reveal transition, no per-index transition-delay. */
	opacity: 1;
	translate: none;
	transition-delay: 0s;
	--yz-t: calc(var(--yz-i, 0) * var(--mo-stagger) * 1.6);
}
.yazan .yz-feature-row ul.products > li.product.yz-reveal:not(.is-inview) { opacity: 0; }
.yazan .yz-feature-row ul.products > li.product.yz-reveal.is-inview {
	animation: yz-trend-fade var(--mo-med) var(--mo-ease-out) var(--yz-t) backwards;
}
/* The photo settles. The link's ivory ground would flash through the fade on the dark band. */
.yazan .yz-feature-row .yzhp-feature--ground-dark ul.products li.product.yz-card .woocommerce-LoopProduct-link { background: var(--yz-ink); }
.yazan .yz-feature-row ul.products > li.product.is-inview .woocommerce-LoopProduct-link > img:not(.yz-card__img--alt) {
	animation: yz-trend-settle var(--mo-hero) var(--mo-ease-out) var(--yz-t) backwards;
}
.yazan .yz-feature-row ul.products > li.product.is-inview .astra-shop-summary-wrap {
	animation: yz-trend-copy var(--mo-slow) var(--mo-ease-out) calc(var(--yz-t) + 260ms) backwards;
}
.yazan .yz-feature-row ul.products > li.product.is-inview .yz-badges,
.yazan .yz-feature-row ul.products > li.product.is-inview .yz-wish {
	animation: yz-trend-fade var(--mo-slow) var(--mo-ease-out) calc(var(--yz-t) + 520ms) backwards;
}

/* 3 — hover: spotlight + hairline. Pointer devices only (a tap must never leave a card dimmed);
   keyboard focus gets the same treatment on every device. */
.yazan .yz-feature-row ul.products li.product.yz-card .astra-shop-summary-wrap { position: relative; }
.yazan .yz-feature-row ul.products li.product.yz-card .astra-shop-summary-wrap::before {
	content: '';
	position: absolute;
	inset-block-start: 0;
	inset-inline: 0;
	height: 1px;
	background: var(--yz-sand);
	opacity: 0.8;
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform var(--mo-med) var(--mo-ease-out);
}
[dir='rtl'] .yazan .yz-feature-row ul.products li.product.yz-card .astra-shop-summary-wrap::before { transform-origin: right center; }
.yazan .yz-feature-row ul.products > li.product { transition: opacity var(--mo-med) var(--mo-ease-out), translate var(--mo-med) var(--mo-ease-out); }
.yazan .yz-feature-row ul.products:has(> li.product:focus-within) > li.product:not(:focus-within) { opacity: 0.45; }
.yazan .yz-feature-row ul.products li.product.yz-card:focus-within .astra-shop-summary-wrap::before { transform: scaleX(1); }
@media (hover: hover) and (pointer: fine) {
	.yazan .yz-feature-row ul.products:has(> li.product:hover) > li.product:not(:hover) { opacity: 0.45; }
	.yazan .yz-feature-row ul.products li.product.yz-card:hover .astra-shop-summary-wrap::before { transform: scaleX(1); }
	/* The lift stays; its shadow reads as nothing on ink, so it goes. */
	.yazan .yz-feature-row ul.products li.product.yz-card:hover { box-shadow: none; }
}

/* Reduced motion and no-JS: the finished state, immediately. */
@media (prefers-reduced-motion: reduce) {
	.yz-feature-row .yzhp-feature__head > *,
	.yz-feature-row .yzhp-feature__title::after,
	.yazan .yz-feature-row ul.products > li.product,
	.yazan .yz-feature-row ul.products > li.product * { animation: none !important; }
	.yz-feature-row .yzhp-feature__head:not(.is-inview) > *,
	.yazan .yz-feature-row ul.products > li.product.yz-reveal:not(.is-inview) { opacity: 1; }
}
html:not(.yz-js) .yz-feature-row .yzhp-feature__head > *,
html:not(.yz-js) .yazan .yz-feature-row ul.products > li.product.yz-reveal { opacity: 1 !important; }

/* --------------------------------------------------------------------------
   4 — OPTIONAL CARD MOTION (dashboard → Featured row → Card motion; `yzhp-feature--motion-*`).
   One of three, on top of the entrance + spotlight above. The behaviour lives in sections.js
   (drag, depth); this is the look. All three switch off for reduced motion.
   -------------------------------------------------------------------------- */

/* DRAG — grab the row with a mouse; it glides and settles on a card edge. A round "DRAG" ring
   replaces the arrow over the row (sections.js adds it and `.has-drag-cursor`, so a failed script
   never leaves the pointer hidden). Touch keeps its native swipe. */
.yzhp-feature--motion-drag .yzhp-carousel__track.has-drag-cursor { cursor: none; }
.yzhp-feature--motion-drag .yzhp-carousel__track.is-dragging {
	scroll-snap-type: none;
	scroll-behavior: auto;
	user-select: none;
}
.yzhp-drag-cursor {
	position: absolute;
	top: 0;
	left: 0;
	z-index: 5;
	width: 84px;
	height: 84px;
	margin: -42px 0 0 -42px;
	border-radius: 50%;
	border: 1px solid var(--yz-sand);
	background: rgba(20, 18, 16, 0.42);
	color: var(--yz-ivory);
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	font: 500 11px/1 var(--yz-font-body);
	letter-spacing: 0.2em;
	pointer-events: none;
	opacity: 0;
	scale: 0.6;
	transition: opacity var(--mo-fast) var(--mo-ease-out), scale var(--mo-med) var(--mo-ease-out);
}
.yzhp-drag-cursor.is-on { opacity: 1; scale: 1; }
.yzhp-drag-cursor.is-on.is-grabbing { scale: 0.84; }
.yzhp-drag-cursor svg { width: 10px; height: 10px; stroke: var(--yz-sand); fill: none; stroke-width: 1.2; }

/* DEPTH — the photo is set a little larger than its frame and drifts against the row as it moves
   (sections.js writes --yz-px per card from its distance to the row's centre). */
.yazan .yzhp-feature--motion-depth ul.products li.product.yz-card .woocommerce-LoopProduct-link > img {
	scale: 1.14;
	translate: var(--yz-px, 0px) 0;
}

/* SHINE — a soft sweep of warm light crosses each stone once as the card arrives (after the photo
   settles), and again on hover. Two layers so the hover sweep never replays the entrance one:
   the entrance on the link, the hover on the thumbnail wrapper. */
.yzhp-feature--motion-shine .yz-card--rare .woocommerce-LoopProduct-link::after { display: none; } /* one sheen, not two */
.yazan .yzhp-feature--motion-shine ul.products li.product.yz-card .woocommerce-LoopProduct-link::before,
.yazan .yzhp-feature--motion-shine ul.products li.product.yz-card .astra-shop-thumbnail-wrap::before {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 2;
	pointer-events: none;
	background: linear-gradient(105deg, rgba(255, 236, 200, 0) 40%, rgba(255, 236, 200, 0.34) 50%, rgba(255, 236, 200, 0) 60%);
	mix-blend-mode: screen;
	translate: -120% 0;
}
.yazan .yzhp-feature--motion-shine ul.products li.product.yz-card .astra-shop-thumbnail-wrap { position: relative; overflow: hidden; }
.yazan .yzhp-feature--motion-shine ul.products > li.product.is-inview .woocommerce-LoopProduct-link::before {
	animation: yz-shine 1.6s cubic-bezier(0.45, 0, 0.2, 1) calc(var(--yz-t, 0s) + 900ms) both;
}
@media (hover: hover) and (pointer: fine) {
	.yazan .yzhp-feature--motion-shine ul.products li.product.yz-card:hover .astra-shop-thumbnail-wrap::before {
		animation: yz-shine 1.2s cubic-bezier(0.45, 0, 0.2, 1) both;
	}
}
@keyframes yz-shine { from { translate: -120% 0; } to { translate: 120% 0; } }

@media (prefers-reduced-motion: reduce) {
	.yazan .yzhp-feature--motion-depth ul.products li.product.yz-card .woocommerce-LoopProduct-link > img { scale: 1; translate: none; }
	.yazan .yzhp-feature--motion-shine ul.products li.product.yz-card .woocommerce-LoopProduct-link::before,
	.yazan .yzhp-feature--motion-shine ul.products li.product.yz-card .astra-shop-thumbnail-wrap::before { display: none; }
}

.elementor .elementor-element.yz-home-section.e-con.yz-split-band,
.elementor .elementor-element.yz-home-section.e-con.yz-feature-banner,
.elementor .elementor-element.yz-home-section.e-con.yz-poster-band {
	--padding-top: 0px;
	--padding-bottom: 0px;
}

/* A widget wrapper is a block box by default; the media layers inside it are absolutely positioned
   against a box that must therefore fill its column. */
.yz-cstory__panel > .elementor-widget:last-child { margin-bottom: 0; }

/* Only the parallax variant needs to fill its column — it is an absolutely-positioned layer inside
   a box that must therefore have a height. The reveal variant sizes itself from the 4:5 ratio on
   `.yz-story__img`, and forcing 100% there collapsed it to nothing inside a grid cell. */
.elementor-widget-yazan-media:has(.yz-cstory__media),
.elementor-widget-yazan-media:has(.yz-cstory__media) > .elementor-widget-container { height: 100%; }

.yz-media { position: relative; overflow: hidden; }
.yz-media.yz-cstory__media { height: 100%; }

/* The reveal variant has no scrim of its own in the theme (only the parallax band does), so the
   optional overlay gets the one declaration it needs rather than borrowing a cstory class. */
.yz-media__scrim { position: absolute; inset: 0; background: rgba(12, 11, 10, 0.28); }

/* `.yz-home-head` is absolute-positioning ground for the "View all" link. Inside Elementor the
   head is a container of separate widgets, so the anchor is re-established on that container. */
.yz-home-head.e-con { position: relative; }

/* The big-image band is a widget here, not a section: it must still span the full band. */
.elementor-widget-yazan-bigimage,
.elementor-widget-yazan-bigimage > .elementor-widget-container { display: block; width: 100%; }

/* ==========================================================================
   SCROLL STORYTELLING (Motion Blueprint Parts 4-5)

   Applied to the bands the theme already renders, using the scroll-timeline primitives in
   motion.css Part 14. No new markup, no Elementor edits, no JavaScript, and no scroll listener —
   `animation-timeline: view()` is evaluated by the compositor, so a page full of this costs the
   main thread nothing.

   Every rule is an ENHANCEMENT over a correct static layout (motion.css Part 14, rule 1): where
   scroll timelines are unsupported the bands render exactly as they do today. Nothing below is the
   only thing making anything visible.
   ========================================================================== */
@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {

		/* The three full-bleed photographic bands get depth: the image creeps against the page so
		   each reads as a window rather than a pasted rectangle. `.yz-cstory__img` already carries
		   `[data-parallax]` for the GSAP desktop path — this is the same idea delivered for free,
		   so the GSAP file stays the desktop-only enhancement it was always meant to be. */
		/*
		 * ⚠️ NAMED TIMELINES, NOT `view()`. THIS IS THE WHOLE TRICK ON THIS THEME.
		 *
		 * `animation-timeline: view()` resolves against the subject's NEAREST SCROLL CONTAINER, and
		 * every photographic band here sets `overflow: hidden` to clip its own image
		 * (`.yz-bigimage`, `.yz-media`, `[data-img-reveal]`). That makes the band itself the
		 * scrollport for the image inside it — and an absolutely-positioned image pinned to
		 * `inset: 0` never moves relative to its own parent, so the timeline attached correctly,
		 * reported a real ViewTimeline object, and sat at progress 0.000 forever. Measured across
		 * eight scroll positions before the cause was found; nothing about it is visible in the
		 * markup or the computed `animation-timeline`.
		 *
		 * A NAMED timeline is looked up by name rather than by proximity: the band declares it
		 * (the band's own scrollport is the document, which does scroll), and the clipped image
		 * inside consumes it.
		 */
		.yz-bigimage { view-timeline-name: --yz-hero-band; }
		.yz-story__media,
		.yz-media { view-timeline-name: --yz-band; }

		.yz-story__img,
		.yz-media__img {
			animation: yz-drift linear both;
			animation-timeline: --yz-band;
			animation-range: entry 0% exit 100%;
		}

		/*
		 * The hero carries TWO animations at once, and they must be declared together.
		 *
		 * ⚠️ `animation` is a shorthand: a second rule setting it REPLACES the first outright. A
		 * plain `animation: yz-drift …` here silently deleted the entrance settle declared above
		 * (`yz-bigimage-settle`), so the hero image lost its arrival and only gained a scroll
		 * effect. Both are listed in one declaration, with the per-animation `animation-timeline`
		 * and `animation-range` lists aligned index-for-index: the settle runs on the document
		 * timeline (`auto`), the depth on the scroll timeline (`view()`).
		 *
		 * The hero is also the one band anchored to `exit` only: it starts in view, so an
		 * `entry`-anchored range would begin part-way through on first paint and jump. This way it
		 * holds perfectly still while it is the thing being looked at, and recedes as the page
		 * moves past it.
		 */
		.yz-bigimage__media {
			animation:
				yz-bigimage-settle var(--mo-hero) var(--mo-ease-out) backwards,
				yz-hero-depth linear both;
			animation-timeline: auto, --yz-hero-band;
			animation-range: normal, exit 0% exit 100%;
		}

		@keyframes yz-hero-depth {
			from { scale: 1; translate: 0 0; }
			to   { scale: calc(1 + 0.06 * var(--mo-intensity)); translate: 0 calc(4% * var(--mo-intensity)); }
		}

		/* The scrim deepens as the hero leaves, so the band closes itself out instead of simply
		   scrolling off. Opacity here is safe — the scrim is not the LCP element. */
		.yz-bigimage__scrim {
			animation: yz-scrim-deepen linear both;
			animation-timeline: --yz-hero-band; /* same reason as the media above */
			animation-range: exit 0% exit 100%;
		}

		@keyframes yz-scrim-deepen {
			from { opacity: 1; }
			to   { opacity: calc(1 + 0.5 * var(--mo-intensity)); }
		}

		/*
		 * Section heads lead their own band. A heading that arrives fractionally before the grid
		 * beneath it is the difference between "the page is animating" and "the page is being
		 * presented" — and it costs one keyframe.
		 */
		.yz-home-head h2 {
			animation: yz-head-in linear both;
			animation-timeline: view();
			animation-range: entry 10% entry 70%;
		}

		@keyframes yz-head-in {
			from { opacity: 0; translate: 0 calc(var(--mo-rise) * 0.8); letter-spacing: 0.04em; }
			to   { opacity: 1; translate: 0 0; letter-spacing: normal; }
		}
	}
}

/* Empty-catalogue guard: the product/category widgets print nothing when there is no data
   (e.g. before the catalogue is imported), which left bare headings and blank bands.
   Hide the whole section until its widget renders; it reappears on its own once data exists. */
.yz-swatches:not(:has(.elementor-widget-yazan-categories, .elementor-widget-yazan-showcase)),
.yz-collections:not(:has(.elementor-widget-yazan-categories)),
.yz-best:not(:has(.elementor-widget-yazan-products)),
.yz-spotlight:not(:has(.elementor-widget-yazan-category-spotlight)),
/* The two dashboard-driven bands (2026-09-24) render nothing until the dashboard gives them content,
   so they are checked for their own markup rather than for the widget's wrapper. */
.yz-feature-row:not(:has(.yzhp-feature)),
.yz-poster-band:not(:has(.yzhp-poster)) {
	display: none;
}
