/*!
 * Rooster X — Femme Fatale brand CSS.
 *
 * theme.json holds tokens, sizes, palette, fontFace declarations and
 * mobile-first per-element typography. This file carries the *behaviours*
 * theme.json can't express: media-query weight/line-height shifts between
 * mobile and desktop, brand-specific block tweaks, and any styling that's
 * easier to live in CSS than as a styles.elements override.
 *
 * Loaded after the parent's base.css via wp_enqueue_scripts in
 * functions.php so it can override the neutral defaults.
 */

@layer roosterx-ff {

	/*
	 * Clip horizontal overflow at the html level. Several brand surfaces
	 * use `100vw` or negative-margin tricks to break out of constrained
	 * layouts (footer full-bleed, recommendations underline, carousel
	 * arrows at right:-36px). On platforms where the scrollbar takes
	 * layout space, `100vw` includes the scrollbar gutter and produces
	 * a few-px phantom overflow even when no content is actually
	 * outside the visible viewport. `clip` (not `hidden`) suppresses
	 * the scrollbar without creating a new scroll container, so sticky
	 * positioning + view transitions still work cleanly.
	 */
	html {
		overflow-x: clip;
	}

	/*
	 * H1 ramps from mobile (50 Light, lh 2.16) → desktop (71 Regular, lh 2.408).
	 * theme.json fluid clamps the size; the weight + line-height jump need
	 * a media query because theme.json fluid doesn't scale those.
	 */
	@media (min-width: 768px) {
		h1, .wp-block-heading.has-h1-style {
			font-weight: 400;
			line-height: 2.408;
		}
	}

	/* Brand body font cascades to the trust tile via inheritance. */
	.roosterx-trust-tile {
		color: var(--wp--preset--color--fg);
	}

	/* ============================================================ */
	/* Announcement bar — 11 Medium, black bg, white text, centered. */
	/* ============================================================ */
	.roosterx-announcement-bar {
		background:    var(--wp--preset--color--fg);
		color:         var(--wp--preset--color--bg);
		font-size:     0.6875rem;     /* 11px */
		font-weight:   500;            /* Medium */
		letter-spacing: 0.038em;
		line-height:   1.5;
		text-align:    center;
		padding:       var(--wp--preset--spacing--2) var(--wp--preset--spacing--4);
	}
	.roosterx-announcement-bar a {
		color: inherit;
		text-decoration: underline;
	}

	/* ── Mobile-only marquee ───────────────────────────────────────
	 * Desktop has plenty of horizontal room — the announcement fits
	 * on one line and scrolling would just be visual noise. On mobile
	 * the message overflows, so we clip the bar, force a single line,
	 * and translate the inner span. `padding-left: 100%` parks the
	 * text off-screen-right at the start; `translateX(-100%)` shifts
	 * it by its OWN width, so the message fully exits left regardless
	 * of length. */
	@media (max-width: 767px) {
		.roosterx-announcement-bar {
			overflow:    hidden;
			white-space: nowrap;
			text-align:  left;
			padding:     var(--wp--preset--spacing--2) 0;
		}
		.roosterx-announcement-bar__text {
			display:      inline-block;
			padding-left: 100%;
			animation:    ff-announce-marquee 30s linear infinite;
			will-change:  transform;
		}
		@keyframes ff-announce-marquee {
			0%   { transform: translateX(0); }
			100% { transform: translateX(-100%); }
		}
		/* Pause when the user touches — easier to read while held. */
		.roosterx-announcement-bar:hover .roosterx-announcement-bar__text { animation-play-state: paused; }
		/* Respect motion-reduce — static line, ellipsis truncation. */
		@media (prefers-reduced-motion: reduce) {
			.roosterx-announcement-bar__text {
				animation:     none;
				padding-left:  0;
				text-overflow: ellipsis;
				overflow:      hidden;
				max-width:     100%;
			}
		}
	}

	/* ============================================================
	 * Header — mobile (default) + desktop variants.
	 *
	 * Both variants live in a single header.html template part. The
	 * actual display toggle is unlayered (further down this file) so it
	 * beats WP's block-layout rules from theme.json.
	 * ============================================================ */
	.ff-header {
		background: var(--wp--preset--color--bg);
		color:      var(--wp--preset--color--fg);
	}

	/* Mobile: logo + actions row (no burger).
	 * The mobile header is rendered from roosterx/parts/header-mobile.html
	 * which uses `.roosterx-header--mobile`, `.roosterx-header__icon-link`
	 * etc. for its own structure. The desktop header still uses
	 * `.ff-header--desktop` / `.ff-header__icon-link` so we cover both
	 * naming families here with shared rule bodies. */
	.roosterx-header--mobile .wp-block-site-logo,
	.roosterx-header--mobile .wp-block-site-logo a,
	.roosterx-header--mobile .wp-block-site-logo img { margin: 0; }
	.roosterx-header__actions,
	.ff-header__actions {
		display: inline-flex;
		gap: 0.5rem;
		align-items: center;
	}
	.roosterx-header__icon-link,
	.ff-header__icon-link,
	.ff-header__action-link {
		color: var(--wp--preset--color--fg);
		text-decoration: none;
		display: inline-flex;
		align-items: center;
		gap: 0.35rem;
		padding: 0.5rem;
	}
	.roosterx-header__icon-link:hover,
	.ff-header__action-link:hover,
	.ff-header__icon-link:hover {
		color: var(--wp--preset--color--accent);
	}

	/* Desktop two-row layout.
	 *   Row 1: logo (left) ─ continuous 2px black line through middle, search
	 *          input sits on top of it with NO border ─ actions on right
	 *   Row 2: centered horizontal nav strip with brand-spec typography,
	 *          NO separator lines above or below
	 */
	.ff-header--desktop .ff-header__row--top {
		position: relative;
		gap: var(--wp--preset--spacing--3);
		align-items: center;
		padding: 0;
		height: 76px;            /* compact row height with breathing room
		                            so the search placeholder + the row's
		                            black line don't visually collide       */
	}
	.ff-header--desktop .ff-header__search input {
		height: 36px !important;
		padding: 0 0.6rem !important;
	}
	/* The full-width 2px black line through the middle of row 1.
	 * Continuous — runs uninterrupted from end of logo to start of
	 * actions, including straight through the search input.            */
	.ff-header--desktop .ff-header__row--top::before {
		content: "";
		position: absolute;
		left: 0;
		right: 0;
		top: 50%;
		height: 2px;
		background: var(--wp--preset--color--fg);
		z-index: 0;
	}
	/* Children sit ABOVE the line. Logo + actions get the white background
	 * so the line is visually capped at the row edges; the search input
	 * stays transparent so the line shows through behind it.            */
	.ff-header--desktop .ff-header__row--top > .ff-header__logo-link,
	.ff-header--desktop .ff-header__row--top > .ff-header__actions--desktop {
		position: relative;
		z-index: 1;
		background: var(--wp--preset--color--bg);
	}
	.ff-header--desktop .ff-header__row--top > .ff-header__search {
		position: relative;
		z-index: 1;
		background: transparent;
		/* Lift the input so its baseline sits ~5px ABOVE the row's
		 * black line (which runs through the row's vertical center).
		 * Row 76px → line at 38px. Input 36px tall, centered → bottom
		 * at 56px. translateY(-23px) shifts it so bottom lands at 33px,
		 * leaving a 5px clear gap above the line.                     */
		transform: translateY(-13px);
	}
	/* FiboSearch input — strip its bottom border so only the row's 2px
	 * black line shows. Background transparent so the line isn't masked.  */
	.ff-header--desktop .ff-header__search input,
	.ff-header--desktop .ff-header__search .dgwt-wcas-search-input,
	.ff-header--desktop .ff-header__search .dgwt-wcas-sf-wrapp,
	.ff-header--desktop .ff-header__search .dgwt-wcas-search-form {
		border: 0 !important;
		box-shadow: none !important;
		background: transparent !important;
	}

	/* WP's `wpautop` wraps the FiboSearch form contents in `<p>` tags,
	 * each carrying the default ~1em top + bottom margin. Four `<p>`
	 * tags inside the form stacks to ~96px of phantom vertical space,
	 * blowing the row up to 150px. Zero them.                           */
	.ff-header--desktop .ff-header__search p,
	.ff-header--desktop .ff-header__search .dgwt-wcas-search-wrapp p,
	.ff-header--desktop .ff-header__search .dgwt-wcas-search-form p {
		margin: 0 !important;
		padding: 0 !important;
		display: contents;     /* let nested input/button flow inline   */
	}
	.ff-header--desktop .ff-header__search br {
		display: none !important;
	}
	.ff-header--desktop .ff-header__search,
	.ff-header--desktop .ff-header__search .wp-block-group__inner-container,
	.ff-header--desktop .ff-header__search .dgwt-wcas-search-wrapp,
	.ff-header--desktop .ff-header__search .dgwt-wcas-search-form,
	.ff-header--desktop .ff-header__search .dgwt-wcas-sf-wrapp {
		margin: 0 !important;
		padding: 0 !important;
	}
	.ff-header--desktop .ff-header__logo {
		display: block;
		max-width: 100%;
		height: auto;
	}
	.ff-header--desktop .ff-header__logo-link {
		flex: 0 0 auto;
		display: inline-flex;
		align-items: center;
		line-height: 0;
		padding-right: var(--wp--preset--spacing--3);
	}
	.ff-header--desktop .ff-header__search {
		flex: 1 1 auto;
		min-width: 0;
		max-width: 480px;
		margin: 0 auto;
		padding: 0 var(--wp--preset--spacing--3);
	}
	.ff-header--desktop .ff-header__search .dgwt-wcas-search-wrapp,
	.ff-header--desktop .ff-header__search form {
		width: 100%;
	}
	.ff-header--desktop .ff-header__actions--desktop {
		display: inline-flex;
		gap: var(--wp--preset--spacing--3);
		align-items: center;
		flex: 0 0 auto;
		padding-left: var(--wp--preset--spacing--3);
	}
	.ff-header--desktop .ff-header__action-link {
		flex-direction: row;        /* icon next to label, like v2 */
		gap: 0.35rem;
		text-decoration: none;
		font-size: 0.8125rem;       /* 13px label */
		line-height: 1.2;
		color: var(--wp--preset--color--fg);
		padding: 0;
	}
	.ff-header--desktop .ff-header__action-link:first-child,
	.ff-header--desktop .ff-header__action-link[href*="katastimata"] {
		color: var(--wp--preset--color--accent); /* Καταστήματα icon = pin in accent */
	}
	.ff-header--desktop .ff-header__action-label {
		color: var(--wp--preset--color--fg);
		font-size: 0.8125rem;
		font-weight: 400;
		white-space: nowrap;
	}
	.ff-header--desktop .ff-header__icon-link {
		color: var(--wp--preset--color--accent);
		padding: 0 0.15rem;
	}
	.ff-header--desktop .ff-header__icon-link:hover,
	.ff-header--desktop .ff-header__action-link:hover .ff-header__action-label {
		color: var(--wp--preset--color--accent);
	}

	/* Bottom row — main navigation. No border above or below; the menu
	 * sits cleanly between the row 1 black line and the page content.
	 * `align-items: flex-start` keeps the inner .ff-menu-strip + button
	 * + ul.ff-simple-menu glued to the row's top edge — without it, the
	 * row's flex layout vertically-centers a ~27px-tall content block
	 * inside ~54px of row, leaving a ~13px phantom gap above the menu
	 * letters. 10px bottom padding kept for breathing room before the
	 * page content. */
	.ff-header--desktop .ff-header__row--nav {
		padding: 0 0 10px !important;
		min-height: 0;
		align-items: flex-start !important;
		justify-content: center;
		border: 0;
	}
	/* Brand-spec menu typography (Aeonik Pro 21 Regular, AV 38, lh 27,
	 * uppercase, accent color per the design). 21/16 = 1.3125rem;
	 * 27/21 = 1.286 line-height; AV 38 → 0.038em letter-spacing. */
	.ff-header--desktop .ff-header__row--nav a,
	.ff-header--desktop .ff-header__row--nav .menu a,
	.ff-header--desktop .ff-header__row--nav .om-desktop-menu a {
		text-decoration: none;
		color: var(--wp--preset--color--accent);
		font-family: var(--wp--preset--font-family--aeonik);
		font-size: 1.3125rem;       /* 21px */
		font-weight: 400;            /* Regular */
		line-height: 1.286;          /* 27/21 */
		letter-spacing: 0.038em;     /* AV 38 */
		text-transform: uppercase;
		padding: 0 var(--wp--preset--spacing--4);
	}
	.ff-header--desktop .ff-header__row--nav a:hover {
		color: var(--wp--preset--color--fg);
	}

	/* Hide desktop-only "store / account" labels on mobile (defensive — */
	/* parts are split at PHP, but Site Editor preview uses one viewport).*/
	@media (max-width: 767px) {
		.ff-header__action-label { display: none; }
	}

	/* ============================================================ */
	/* Footer — black bg, white text.                                 */
	/* Single template part for both viewports:                       */
	/*   Mobile: <details> renders as collapsible accordion.          */
	/*   Desktop: CSS forces all sections open + 4-column grid.       */
	/* Typography is shared (21 Regular menu, 24 Bold "follow us").   */
	/* ============================================================ */

	/* The <footer> template-part wrapper is already at full viewport
	 * width (no `has-global-padding` class on it, so root padding isn't
	 * applied here). The wp:group inside takes its parent's width by
	 * default — no break-out tricks needed. The 50px inner gutter comes
	 * from the wp:group's inline padding-left/right. */
	.ff-footer {
		color: var(--wp--preset--color--bg);
	}
	.ff-footer__logo-link {
		display: inline-block;
		margin-block: var(--wp--preset--spacing--4);
	}
	/* The logo SVG is a base64 PNG (XD export) so currentColor doesn't
	 * work — we invert in CSS so the black wordmark appears white on
	 * the dark footer. The header uses the same file uninverted. */
	.ff-footer__logo {
		filter: invert(1);
		display: block;
		max-width: 260px;
		height: auto;
	}
	.ff-header__logo {
		display: block;
		height: auto;
	}

	/* Section header — same typography in both viewports. */
	.ff-footer__section > summary {
		font-family:    var(--wp--preset--font-family--aeonik);
		font-size:      1.3125rem;     /* 21px */
		font-weight:    400;            /* Regular */
		letter-spacing: 0.038em;
		line-height:    1.3;
		text-transform: uppercase;
		color:          var(--wp--preset--color--bg);
		list-style:     none;           /* hide default marker */
		cursor:         pointer;
		padding:        var(--wp--preset--spacing--4) 0;
		display:        flex;
		align-items:    center;
		justify-content: space-between;
		gap:            1rem;
	}
	.ff-footer__section > summary::-webkit-details-marker { display: none; }
	.ff-footer__section > summary::after {
		content: "";
		width: 12px;
		height: 12px;
		border-right:  2px solid currentColor;
		border-bottom: 2px solid currentColor;
		transform: rotate(45deg);
		transition: transform 200ms ease;
		margin-bottom: 4px;
	}
	.ff-footer__section[open] > summary::after {
		transform: rotate(-135deg);
		margin-bottom: -4px;
	}

	/* Mobile accordion: section row borders for visual separation. */
	.ff-footer__section {
		border-top: 1px solid rgba(255,255,255,0.15);
	}
	.ff-footer__section:last-of-type {
		border-bottom: 1px solid rgba(255,255,255,0.15);
	}

	/* Menu links — 21 Regular shared between viewports. */
	.ff-footer__list {
		list-style: none;
		padding: 0;
		margin: 0 0 var(--wp--preset--spacing--4) 0;
	}
	.ff-footer__list li {
		font-family:    var(--wp--preset--font-family--aeonik);
		font-size:      1.3125rem;     /* 21px */
		font-weight:    400;
		line-height:    1.6;
		padding: 0.25rem 0;
	}
	.ff-footer__list a {
		color: var(--wp--preset--color--bg);
		text-decoration: none;
	}
	.ff-footer__list a:hover {
		color: var(--wp--preset--color--accent);
	}

	/* "Ακολουθήστε μας" heading — 24 Bold per spec, mixed-case Greek (no uppercase). */
	.ff-footer__follow-heading {
		font-family:    var(--wp--preset--font-family--aeonik);
		font-size:      1.5rem;        /* 24px */
		font-weight:    700;            /* Bold */
		letter-spacing: 0.038em;
		line-height:    1.3;
		color:          var(--wp--preset--color--bg);
		margin: 0 0 var(--wp--preset--spacing--3) 0;
	}

	/* Social icons row — circular accent-bg buttons under the heading. */
	.ff-footer__social .wp-block-social-link {
		background-color: var(--wp--preset--color--accent);
	}
	.ff-footer__social .wp-block-social-link:hover {
		background-color: var(--wp--preset--color--accent);
		opacity: 0.85;
	}

	/* Footer is identical mobile + desktop — accordion sections that span */
	/* full width. The wp:group wrapper provides constrained content size  */
	/* via theme.json layout, so it auto-aligns at any viewport.           */
	.ff-footer__follow {
		gap: var(--wp--preset--spacing--4);
		padding-top:    var(--wp--preset--spacing--5);
		padding-bottom: var(--wp--preset--spacing--3);
	}

	.ff-footer__credit {
		opacity: 0.7;
		margin-top: var(--wp--preset--spacing--4);
	}
	.ff-footer__credit a {
		color: inherit;
		text-decoration: underline;
	}
}

/*
 * Unlayered overrides — these need to win against WP's auto-generated
 * theme.json styles (which are unlayered too, but specificity here is
 * higher). The previous @layer wrapping made them lose to theme.json's
 * :root :where(...) link rules even with stronger selectors.
 *
 * Footer submenu links: white by default, accent on hover.
 * Header action links: black by default, accent on hover.
 */
.ff-footer .ff-footer__list a {
	color: var(--wp--preset--color--bg);
	text-decoration: none;
}
.ff-footer .ff-footer__list a:hover,
.ff-footer .ff-footer__list a:focus-visible {
	color: var(--wp--preset--color--accent);
}

.ff-footer .ff-footer__credit a {
	color: inherit;
	text-decoration: underline;
}
.ff-footer .ff-footer__credit a:hover {
	color: var(--wp--preset--color--accent);
}

/* Side-cart "Shopping Bag" row layout.
 *
 * The plugin renders each row inside a CSS grid with 5 columns
 * `60px auto auto 1fr auto`:
 *   col 1 = thumbnail (60px), col 2 = qty stepper, col 3 = unit price,
 *   col 4 = filler (1fr), col 5 = line total.
 *
 * The image and name live inside `<a class="aieo-mini-cart-thumb-title">`
 * which the plugin sets to `display: contents` so its children
 * participate in the parent grid directly. When the active theme (or
 * any other CSS rule with higher specificity) sets `display: inline` /
 * `display: block` on `<a>` tags via theme.json link styling, the
 * `display: contents` is lost — the entire `<a>` becomes a single grid
 * item, the image and name stack inside it, and the row layout
 * collapses (image ends up in the wrong column).
 *
 * Force `display: contents` here with high specificity + `!important`
 * so theme.json link styles can't override, and re-assert the grid
 * placement of the image (col 1, spans both rows) and name (col 2-5,
 * row 1) explicitly. */
.aieo-sc-root .aieo-mini-cart .mini_cart_item .aieo-mini-cart-thumb-title,
.aieo-sc-root .aieo-mini-cart-thumb-title {
	display: contents !important;
}
.aieo-sc-root .aieo-mini-cart .mini_cart_item .aieo-mini-cart-img,
.aieo-sc-root .aieo-mini-cart-img {
	grid-column: 1 !important;
	grid-row: 1 / 3 !important;
	width: 60px !important;
	height: 60px !important;
	overflow: hidden;
	display: block !important;
}
.aieo-sc-root .aieo-mini-cart .mini_cart_item .aieo-mini-cart-name,
.aieo-sc-root .aieo-mini-cart-name {
	grid-column: 2 / 6 !important;
	grid-row: 1 !important;
}
/* The actual <img> element — pin to the 60×60 square with cover so any
 * aspect ratio (variation swatch strips, square product photos, tall
 * tubes) renders cleanly without overflowing the row. */
.aieo-sc-root .aieo-mini-cart .aieo-mini-cart-img img,
.aieo-sc-root .aieo-mini-cart .mini_cart_item .aieo-mini-cart-img img,
.aieo-sc-root .aieo-mini-cart .mini_cart_item img:not(.remove img) {
	width: 60px !important;
	height: 60px !important;
	object-fit: cover;
	object-position: center;
	max-width: 60px;
	max-height: 60px;
	border-radius: 4px;
}

/* WC product info tabs → accordion (`[ff_product_tabs]` shortcode output).
 * Same visual treatment as the footer accordion: top-bordered rows, large
 * uppercase summary, chevron rotates on [open]. Sizes follow the spec
 * (18 Regular mobile → 22 Regular desktop with lh 25). */
.ff-product-tabs-mount {
	width: 100%;
	max-width: none;
	padding-inline: 0 !important;
}
.ff-product-tabs {
	width: 100%;
}
.ff-product-tabs__section {
	border-top: 1px solid var(--wp--preset--color--border);
}
.ff-product-tabs__section:last-of-type {
	border-bottom: 1px solid var(--wp--preset--color--border);
}
.ff-product-tabs__section > summary {
	font-family:    var(--wp--preset--font-family--aeonik);
	font-size:      1.125rem;          /* 18px mobile */
	font-weight:    400;
	letter-spacing: 0.038em;
	line-height:    1.39;
	text-transform: uppercase;
	list-style:     none;
	cursor:         pointer;
	padding:        var(--wp--preset--spacing--4) 0;
	display:        flex;
	align-items:    center;
	justify-content: space-between;
	gap:            1rem;
	color:          var(--wp--preset--color--fg);
}
.ff-product-tabs__section > summary::-webkit-details-marker { display: none; }
.ff-product-tabs__section > summary::after {
	content: "";
	width: 12px;
	height: 12px;
	border-right:  2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: rotate(45deg);
	transition: transform 200ms ease;
	margin-bottom: 4px;
}
.ff-product-tabs__section[open] > summary::after {
	transform: rotate(-135deg);
	margin-bottom: -4px;
}
.ff-product-tabs__body {
	padding: 0 0 var(--wp--preset--spacing--4) 0;
	font-size: var(--wp--preset--font-size--md);
	line-height: 1.6;
}
/* WC's description / additional-info / reviews callbacks each emit their
 * own <h2> heading (Description / Επιπλέον πληροφορίες / Αξιολογήσεις)
 * which duplicates the accordion's <summary> title above. Hide it. */
.ff-product-tabs__body > h2:first-child,
.ff-product-tabs__body > .woocommerce-product-attributes-item__label + h2,
#tab-description > h2:first-child,
#tab-additional_information > h2:first-child,
#tab-reviews > h2:first-child,
.ff-product-tabs__body #reviews > h2:first-child,
.ff-product-tabs__body .woocommerce-Reviews-title {
	display: none;
}
@media (min-width: 768px) {
	.ff-product-tabs__section > summary {
		font-size:   1.375rem;         /* 22px desktop */
		line-height: 1.136;            /* 25/22 */
	}
}

/* AIEO recommendations heading — big uppercase 75 Regular with underline
 * spanning full width + 10px gutters (per design spec). Targets the
 * `<h2 class="aieo-recommendations-title">` AIEO emits when filling the
 * `aieo-same-needs-placeholder` div. */
.aieo-recommendations,
section.aieo-recommendations {
	width: 100%;
}
/* Desktop: +50px breathing room between consecutive recommendation
 * carousels so each surface (same-needs / cross-sells / upsells / related
 * / recently-viewed) gets a clearly distinct vertical block. The inline
 * `margin-top: var(--wp--preset--spacing--6)` on each section already
 * covers the base gap; this rule only adds the extra ≥768px space. */
@media (min-width: 768px) {
	.aieo-recommendations + .aieo-recommendations,
	.wp-block-group.aieo-recommendations + .wp-block-group.aieo-recommendations {
		margin-top: calc(var(--wp--preset--spacing--6) + 80px) !important;
	}
}
.aieo-recommendations-title,
.aieo-recommendations > h2 {
	font-family:    var(--wp--preset--font-family--aeonik);
	font-size:      clamp(2.125rem, 1.5rem + 4vw, 4.6875rem);   /* 34px mobile → 75px desktop */
	font-weight:    100;                                          /* Thin */
	letter-spacing: 0.038em;
	line-height:    1.1;
	text-transform: uppercase;
	color:          var(--wp--preset--color--fg);
	margin: 0;
	padding: 0 10px var(--wp--preset--spacing--1);
	position: relative;
	border: 0;
}
/*
 * Underline as a pseudo-element that breaks out to viewport edges with
 * 10px gutters. The `calc(50% - 50vw + 10px)` trick computes the offset
 * needed to reach the viewport's left edge regardless of how deeply the
 * heading is nested in constrained containers; `100vw - 20px` then
 * stretches across to 10px from the right edge.
 */
.aieo-recommendations-title::after,
.aieo-recommendations > h2::after {
	content: "";
	position: absolute;
	bottom: 0;
	left: calc(50% - 50vw + 10px);
	width: calc(100vw - 20px);
	height: 1px;
	background: var(--wp--preset--color--fg);
}
/* Bring the carousel grid up close to the line below the title. */
.aieo-recommendations .aieo-recommendations-grid {
	margin-top: var(--wp--preset--spacing--3);
}

/* ============================================================
 * Recommendations product card — superset for any AIEO carousel
 * (`.aieo-recommendations`, `.aieo-related-products`, `.aieo-best-sellers`).
 * Markup AIEO emits per card:
 *   <a class="aieo-card-link">
 *     <div class="aieo-card-img-wrap"><img><span class="aieo-card-onsale">SALE</span></div>
 *     <div class="aieo-card-body">
 *       <h3 class="aieo-card-name">Title</h3>
 *       <div class="aieo-card-price"><del>old</del><ins>new</ins></div>
 *     </div>
 *   </a>
 *
 * Spec: title 22 Reg accent centered; price 20 centered (sale: del thin
 * strike, ins bold); square border on the card.
 * ============================================================ */

/* Carousel wrapper — horizontal scroll with snap. */
.aieo-recommendations-grid {
	display: flex !important;        /* override any default grid */
	flex-wrap: nowrap;
	gap: var(--wp--preset--spacing--4);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-padding-left: var(--wp--preset--spacing--4);
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;             /* hide scrollbar */
	padding: var(--wp--preset--spacing--3) 10px var(--wp--preset--spacing--4);
}
.aieo-recommendations-grid::-webkit-scrollbar { display: none; }

/* Card frame — exact 284×455 (φ-ratio portrait, 1:1.602). On narrower
 * viewports the width clamps down but `aspect-ratio` keeps the golden
 * rectangle shape so the proportions never break. Single source of
 * truth — every recommendation surface (same-needs / cross-sells /
 * upsells / related / recently-viewed) uses these dimensions. */
.aieo-recommendations-grid > .aieo-card-link,
.aieo-recommendations-grid > * {
	flex: 0 0 auto;
	width: min(284px, 80vw);
	aspect-ratio: 284 / 455;
	scroll-snap-align: start;
	border: 1px solid var(--wp--preset--color--fg);
	border-radius: 0;
	background: var(--wp--preset--color--bg);
	padding: var(--wp--preset--spacing--3);
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--3);
	color: inherit;
	text-decoration: none;
	overflow: hidden;
}
@media (min-width: 768px) {
	.aieo-recommendations-grid > .aieo-card-link,
	.aieo-recommendations-grid > * {
		width: 284px;
		height: 455px;
		aspect-ratio: auto;
	}
}
/* No underline on hover/focus — keep the card visually clean. */
.aieo-recommendations-grid > .aieo-card-link,
.aieo-recommendations-grid > .aieo-card-link:hover,
.aieo-recommendations-grid > .aieo-card-link:focus,
.aieo-recommendations-grid > .aieo-card-link:focus-visible {
	text-decoration: none !important;
}
/* Image takes the flexible space at the top of the φ-card; body locks
 * to its content size at the bottom. `object-fit: contain` keeps each
 * product image at its native aspect ratio without distortion. */
.aieo-recommendations-grid .aieo-card-img-wrap {
	flex: 1 1 auto;
	min-height: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	position: relative;
}
.aieo-recommendations-grid .aieo-card-img-wrap img {
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	display: block;
	object-fit: contain;
}
.aieo-recommendations-grid .aieo-card-body {
	flex: 0 0 auto;
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--2);
	text-align: center;
}

/* Title — 22 Regular accent, centered. The `:where(.aieo-card-link) &`
 * specificity bump ensures we win over WP-generated link element styles
 * that color inherited content with the global link rule. */
.aieo-recommendations-grid .aieo-card-name,
.aieo-recommendations-grid .aieo-card-link .aieo-card-name {
	font-family:    var(--wp--preset--font-family--aeonik);
	font-size:      1.375rem;          /* 22px */
	font-weight:    400;                /* Regular */
	line-height:    1.18;
	letter-spacing: 0.038em;
	color:          var(--wp--preset--color--accent) !important;
	text-align:     center;
	margin: 0;
	text-decoration: none;
}
.aieo-recommendations-grid .aieo-card-link:hover .aieo-card-name,
.aieo-recommendations-grid .aieo-card-link:focus .aieo-card-name,
.aieo-recommendations-grid .aieo-card-link:hover,
.aieo-recommendations-grid .aieo-card-link:focus,
.aieo-recommendations-grid a:hover .aieo-card-name,
.aieo-recommendations-grid a:focus .aieo-card-name {
	color: var(--wp--preset--color--accent);
	text-decoration: none !important;
}

/* Image-overlay badges — SALE / PRO tag rendered by AIEO inside
 * .aieo-card-img-wrap. Position bottom-right small chip on the image. */
.aieo-recommendations-grid .aieo-card-img-wrap {
	position: relative;
}
.aieo-recommendations-grid .aieo-card-onsale,
.aieo-recommendations-grid .aieo-card-role-badge {
	position: absolute;
	right: 8px;
	bottom: 8px;
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--bg);
	font-family: var(--wp--preset--font-family--aeonik);
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.038em;
	text-transform: uppercase;
	padding: 0.25rem 0.6rem;
	border-radius: 9999px;
	z-index: 2;
}

/* Wishlist heart on the card (injected by functions.php JS) */
.aieo-recommendations-grid .ff-card-fav,
.aieo-recommendations-grid .aieo-wishlist-heart--card {
	position: absolute;
	top: 8px;
	right: 8px;
	background: rgba(255, 255, 255, 0.92);
	border: 0;
	width: 32px;
	height: 32px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	border-radius: 50%;
	cursor: pointer;
	color: var(--wp--preset--color--accent);
	z-index: 3;
	transition: transform 150ms ease, background-color 150ms ease;
}
.aieo-recommendations-grid .ff-card-fav:hover,
.aieo-recommendations-grid .ff-card-fav:focus-visible {
	transform: scale(1.08);
	background: var(--wp--preset--color--bg);
}
.aieo-recommendations-grid .ff-card-fav.is-in-list svg path {
	fill: var(--wp--preset--color--accent);
	stroke: var(--wp--preset--color--accent);
}

/* Price block — 20 centered. Sale-state (del + ins) styling: */
.aieo-recommendations-grid .aieo-card-price {
	font-family:    var(--wp--preset--font-family--aeonik);
	font-size:      1.25rem;            /* 20px */
	color:          var(--wp--preset--color--fg);
	text-align:     center;
	display:        flex;
	flex-direction: column;
	align-items:    center;
	gap:            0.15rem;
}
/* When the .price markup wraps amounts in nested spans, normalise. */
.aieo-recommendations-grid .aieo-card-price .woocommerce-Price-amount {
	font: inherit;
}
.aieo-recommendations-grid .aieo-card-price del,
.aieo-recommendations-grid .aieo-card-price del .woocommerce-Price-amount,
.aieo-recommendations-grid .aieo-card-price del bdi {
	font-weight: 300 !important;        /* thin */
	text-decoration: line-through !important;
	color: var(--wp--preset--color--muted);
	opacity: 0.85;
}
.aieo-recommendations-grid .aieo-card-price ins {
	font-weight: 700;                   /* bold (sale price) */
	text-decoration: none;
	color: var(--wp--preset--color--fg);
}
/* Non-sale state: single price renders without del/ins; ensure bold-ish
 * weight without overdoing it (semibold reads better at 20px). */
.aieo-recommendations-grid .aieo-card-price > .woocommerce-Price-amount,
.aieo-recommendations-grid .aieo-card-price > .amount {
	font-weight: 600;
}
/* Variable-product price range: WC emits "<amount> – <amount>" with no
 * del/ins. Treat the *second* (higher) amount as the "old" price —
 * thin + line-through — to match the sale-state visual. The adjacent
 * sibling combinator only matches when there are two amounts in a row. */
.aieo-recommendations-grid .aieo-card-price > .woocommerce-Price-amount + .woocommerce-Price-amount,
.aieo-recommendations-grid .aieo-card-price > .amount + .amount {
	font-weight: 300 !important;
	text-decoration: line-through !important;
	color: var(--wp--preset--color--muted);
	opacity: 0.85;
}

/* Legacy fallbacks — if AIEO ever renders a non-card markup (post-title,
 * loop classic), keep the same accent + center treatment so the design
 * stays consistent across surfaces. */
.aieo-recommendations-grid .wp-block-post-title a,
.aieo-recommendations-grid .product-name,
.aieo-recommendations-grid h3:not(.aieo-card-name),
.aieo-recommendations-grid .woocommerce-loop-product__title {
	color: var(--wp--preset--color--accent);
	text-align: center;
	font-weight: 400;
}

/* Carousel controls — 30×30 prev/next buttons on desktop, injected by
 * the inline JS in functions.php after AIEO renders the recommendations
 * section. Sit INSIDE the section's bounds (so html overflow-x:clip
 * doesn't hide them), with a circular white background + soft shadow
 * to read clearly on top of the card images. Hidden on mobile (native
 * horizontal scroll handles the use case). */
.aieo-recommendations { position: relative; }
.ff-carousel-arrow {
	display: none;
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	width: 44px;
	height: 44px;
	padding: 0;
	border: 0;
	background: var(--wp--preset--color--bg);
	color: var(--wp--preset--color--fg);
	cursor: pointer;
	z-index: 4;
	border-radius: 50%;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
	transition: transform 150ms ease, box-shadow 150ms ease, background-color 150ms ease;
}
.ff-carousel-arrow svg { width: 30px; height: 30px; display: block; pointer-events: none; }
.ff-carousel-arrow:hover,
.ff-carousel-arrow:focus-visible {
	transform: translateY(-50%) scale(1.05);
	box-shadow: 0 3px 12px rgba(0, 0, 0, 0.2);
	background: var(--wp--preset--color--bg);
	color: var(--wp--preset--color--accent);
	outline: none;
}
.ff-carousel-arrow--prev { left: 8px; }
.ff-carousel-arrow--next { right: 8px; }
@media (min-width: 768px) {
	.ff-carousel-arrow { display: inline-flex; align-items: center; justify-content: center; }
}

/* WC variations form ("Make Up Χρώμα" + swatches) — stack label ABOVE
 * the swatches instead of WC's default TH-beside-TD table layout, and
 * left-align the swatch row.
 */
.single-product table.variations,
.single-product table.variations tbody {
	display: block;
	width: 100%;
	border: 0;
}
.single-product table.variations tr {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
	margin-bottom: var(--wp--preset--spacing--3);
}
.single-product table.variations th.label,
.single-product table.variations td.value {
	display: block;
	width: 100%;
	padding: 0;
	text-align: left;
}
.single-product table.variations th.label label {
	font-family:    var(--wp--preset--font-family--aeonik);
	font-size:      0.9375rem;          /* 15px */
	font-weight:    700;                 /* Bold */
	letter-spacing: 0.038em;
	margin: 0;
}
/* Force the swatch row inside td.value to align flush left, regardless
 * of which swatch wrapper class the AIEO/legacy plugin emits. */
.single-product table.variations td.value > * {
	margin-left: 0 !important;
	margin-right: auto !important;
	justify-content: flex-start !important;
	text-align: left;
}
.single-product .om-variations-wrapper,
.single-product .om-swatches,
.single-product .aieo-swatches {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	justify-content: flex-start;
}

/* Add-to-cart form — hide the quantity input, make the button full width.
 * The click-counter badge `.ff-add-count` sits inline immediately after the
 * button text (centered as one group), not pinned to the right edge — keeps
 * the "you have N in cart" feedback in the shopper's foveal scan path. */
.single-product form.cart {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--3);
}
.single-product form.cart .quantity {
	display: none !important;
}
.single-product form.cart .single_add_to_cart_button,
.single-product form.cart button[type="submit"] {
	width: 100%;
}
.single-product form.cart .ff-add-count {
	display: inline-block;
	margin-inline-start: 1em;
	font: inherit;
	color: inherit;
	pointer-events: none;
}

/* Archive add-to-cart button — visual parity with the PDP single ATC.
 * WC core renders these as <a class="add_to_cart_button ajax_add_to_cart">
 * inside product loops (shop, category, search, related, etc). Without
 * matching styles they rendered as small flat WC default buttons, out
 * of step with the dark pill PDP main ATC. This block applies the
 * same fill/text/padding so the UX is consistent across surfaces — and
 * the inline `.ff-add-count` badge (qty indicator) lays out the same way.
 *
 * Variable products on archive pages render with `product_type_variable`
 * but no `.ajax_add_to_cart` class — they're a link to the PDP. The
 * styling still applies; the +N badge JS leaves them at qty=0 unless
 * the shopper has variations of that parent in cart. */
.woocommerce ul.products li.product .button.add_to_cart_button,
.wc-block-grid__product .add_to_cart_button,
.wp-block-woocommerce-product-collection .add_to_cart_button,
.products .add_to_cart_button,
a.add_to_cart_button.product_type_simple,
a.add_to_cart_button.product_type_variable {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 66%;
	min-height: 40px;
	padding: 0.55em 1.1em;
	background-color: var(--wp--preset--color--fg, #1a1a1a);
	color: var(--wp--preset--color--bg, #fff);
	border: 1px solid var(--wp--preset--color--fg, #1a1a1a);
	border-radius: 999px;
	font-family: var(--wp--preset--font-family--aeonik);
	font-size: 0.8125rem;
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	text-decoration: none;
	line-height: 1;
	transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
}
.woocommerce ul.products li.product .button.add_to_cart_button:hover,
a.add_to_cart_button.product_type_simple:hover,
a.add_to_cart_button.product_type_variable:hover {
	background-color: var(--wp--preset--color--accent, #c0a37b);
	border-color: var(--wp--preset--color--accent, #c0a37b);
	color: #fff;
}
a.add_to_cart_button .ff-add-count,
.products .add_to_cart_button .ff-add-count {
	display: inline-block;
	margin-inline-start: 1em;
	font: inherit;
	color: inherit;
	pointer-events: none;
}


/* ============================================================
 * Archive cart-button — per-variant visual differentiation
 * ============================================================
 * All three archive cart-button variants share `.add_to_cart_button`
 * styling above. The `aieo-archive-add-to-cart--*` modifiers (emitted
 * by AIEO_DMM_Swatches_Runtime::render_archive_product_wrapper)
 * differentiate the click semantics:
 *   --in-cart      : status badge, NOT a click target
 *   --see-options  : navigation hint → opens the PDP
 *   --swatches     : primary CTA → multi-select cart-add submit
 *
 * The surface prefix (`aieo-archive-`) leaves room for sibling
 * rules later (`.aieo-pdp-add-to-cart--…`, `.aieo-sidecart-…`)
 * without selectors tripping over each other.
 */

/* Variant 1 — already-in-cart status badge.
 * Same brand-button base as --see-options, but filled-dark with reduced
 * opacity so it reads as "completed / non-actionable" rather than a
 * primary CTA. The +N qty badge (.ff-add-count) inherits white from `color`. */
.aieo-archive-add-to-cart--in-cart {
	background: var(--wp--preset--color--fg, #1a1a1a);
	border: 1px solid var(--wp--preset--color--fg, #1a1a1a);
	color: var(--wp--preset--color--bg, #fff);
	padding: 10px 16px;
	font-size: 14px;
	font-weight: 500;
	letter-spacing: 0.038em;
	text-transform: uppercase;
	text-decoration: none;
	cursor: default;
	opacity: 0.65;
	transition: opacity 150ms ease;
}
.aieo-archive-add-to-cart--in-cart:hover,
.aieo-archive-add-to-cart--in-cart:focus {
	/* Explicitly defeat the inherited .add_to_cart_button:hover */
	background: var(--wp--preset--color--fg, #1a1a1a);
	border-color: var(--wp--preset--color--fg, #1a1a1a);
	color: var(--wp--preset--color--bg, #fff);
	opacity: 0.85;
	text-decoration: none;
	transform: none;
}
.aieo-archive-add-to-cart--in-cart .ff-add-count {
	color: inherit;
}

/* Variant 2 — secondary "see options" navigation CTA.
 * Mirrors the .aieo-quick-view-trigger (DISCOVER IT) styling so the
 * pair of secondary actions reads consistently across the card grid. */
.aieo-archive-add-to-cart--see-options {
	background: transparent;
	border: 1px solid var(--wp--preset--color--fg, #1a1a1a);
	color: var(--wp--preset--color--fg, #1a1a1a);
	padding: 10px 16px;
	font-size: 14px;
	font-weight: 500;
	letter-spacing: 0.038em;
	text-transform: uppercase;
	text-decoration: none;
	cursor: pointer;
	transition: background-color 150ms ease, color 150ms ease;
}
.aieo-archive-add-to-cart--see-options:hover,
.aieo-archive-add-to-cart--see-options:focus {
	background: var(--wp--preset--color--fg, #1a1a1a);
	border-color: var(--wp--preset--color--fg, #1a1a1a);
	color: var(--wp--preset--color--bg, #fff);
	text-decoration: none;
	transform: none;
}

/* Variant 3 (`--swatches`) keeps the inherited primary brand CTA look —
 * no override needed; it IS the "real" add-to-cart action. */

/* Hide WC core's auto-appended "View cart" link (`<a class="added_to_cart
 * wc-forward">`) emitted by wc-add-to-cart.js after a successful AJAX add
 * on archive cards. The card already swaps the cart button to the
 * --in-cart variant which conveys the same state without redirecting. */
a.added_to_cart.wc-forward {
	display: none !important;
}

/* ============================================================
 * WC blocks "Save %s" sale badge → "PRO" relabel
 * ============================================================
 * The default Greek translation of WC's `__("Save %s","woocommerce")`
 * comes through as "Αποθήκευση X,XX €" (data-storage sense, not
 * money-saving). On this site the discounted price IS always the
 * professional/role price, so we relabel the badge to "PRO" via a
 * pseudo-element. font-size:0 collapses the actual children
 * (the original text node + the FormattedMonetaryAmount span);
 * ::before paints the new label inside the existing pill.
 */
.wc-block-components-sale-badge {
	font-size: 0 !important;
	line-height: 1;
}
.wc-block-components-sale-badge::before {
	content: "PRO";
	display: inline-block;
	font-size: 0.6875rem;       /* 11px — matches WC's badge default */
	font-weight: 700;
	letter-spacing: 0.04em;
	line-height: 1;
}

/* ============================================================
 * Single-product page typography
 * ============================================================
 * H1 (product name) is a different scale from the archive H1.
 * Archive: 50/300 → 71/400 (theme.json + brand.css media query).
 * Single product: 25 Regular mobile → 31 Regular desktop, same
 * letter-spacing as global headings.
 */
.single-product .wp-block-post-title {
	font-family:    var(--wp--preset--font-family--aeonik);
	font-size:      1.5625rem;        /* 25px mobile */
	font-weight:    400;
	line-height:    1.24;             /* 31/25 */
	letter-spacing: 0.038em;
}
@media (min-width: 768px) {
	.single-product .wp-block-post-title {
		font-size:   1.9375rem;       /* 31px desktop */
		line-height: 1.097;           /* 34/31 */
	}
}

/* Product short description ("22 Bold" per design spec, both viewports). */
.single-product .wp-block-woocommerce-product-summary,
.single-product .wp-block-woocommerce-product-summary p {
	font-size:    1.375rem;            /* 22px */
	font-weight:  700;
	line-height:  1.09;                /* 24/22 */
}

/* Price — 18 Bold mobile → 20 Bold desktop. */
.single-product .wp-block-woocommerce-product-price,
.single-product .price {
	font-size:    1.125rem;            /* 18px mobile */
	font-weight:  700;
}
@media (min-width: 768px) {
	.single-product .wp-block-woocommerce-product-price,
	.single-product .price {
		font-size: 1.25rem;            /* 20px desktop */
	}
}

/* Title row — H1 + AIEO wishlist heart laid out as flex siblings so the
 * heart sits flush top-right of the title and the title flows around it
 * for any number of lines. Built in JS (functions.php) by plucking the
 * `.aieo-wishlist-heart-wrap` AIEO renders inside the summary and
 * inserting it next to the post-title, both wrapped in this row.
 *
 * Per the brand spec the heart is icon-only (label hidden) and ~48px,
 * accent color, no background — it pops against the dense title.      */
.ff-product-title-row {
	display: flex;
	gap: var(--wp--preset--spacing--3);
	/* center-align so an inline brand logo sits visually middle next to
	 * both the H1 (whose visual centre is a bit below text top because of
	 * cap-height) and the wishlist heart. */
	align-items: center;
	justify-content: space-between;
	margin-bottom: var(--wp--preset--spacing--3);
}
/* Inline brand display placed by JS between title and heart. */
.ff-product-title-row .aieo-brand-display--in-title-row {
	flex: 0 0 auto;
	margin: 0;
}
.ff-product-title-row .ff-product-title,
.ff-product-title-row .wp-block-post-title {
	flex: 1 1 auto;
	margin: 0;
	min-width: 0;            /* allow long words to wrap inside flex */
}
.ff-product-title-row .aieo-wishlist-heart-wrap,
.ff-product-title-row .aieo-wishlist-heart--single_product {
	flex: 0 0 auto;
	margin-top: 0.25rem;     /* nudges the heart down to the cap line */
	display: inline-flex;
	align-items: center;
	gap: 0;
}
/* Kill the inline "See your favourites" / "Add to your favourites" link
 * — the brand wants an icon-only button. */
.ff-product-title-row .aieo-wishlist-heart-label,
.ff-product-info  .aieo-wishlist-heart-label {
	display: none !important;
}
/* Enlarge the heart button + SVG. AIEO's default is 22px; brand wants ~48. */
.ff-product-title-row .aieo-wishlist-heart {
	background: transparent !important;
	border: 0 !important;
	padding: 0 !important;
	width:  48px !important;
	height: 48px !important;
	color:  var(--wp--preset--color--accent) !important;
	cursor: pointer;
	box-shadow: none !important;
}
.ff-product-title-row .aieo-wishlist-heart .aieo-wishlist-heart-icon,
.ff-product-title-row .aieo-wishlist-heart svg {
	width:  48px !important;
	height: 48px !important;
	display: block;
}
.ff-product-title-row .aieo-wishlist-heart .aieo-wishlist-heart-fill {
	opacity: 0;
	transition: opacity 150ms ease;
}
.ff-product-title-row .aieo-wishlist-heart.is-in-list .aieo-wishlist-heart-fill {
	opacity: 1;
}
.ff-product-title-row .aieo-wishlist-heart:hover {
	transform: scale(1.06);
}

/* Minimalist black-border boxes for Needs + Complementary sections.
 * Single 1px black border, white inside, all-black typography unless
 * the price element overrides to coral. */
.ff-needs-box,
.ff-complementary-box {
	border: 1px solid var(--wp--preset--color--fg);
	background: var(--wp--preset--color--bg);
	padding: var(--wp--preset--spacing--4);
	margin-block: var(--wp--preset--spacing--4);
	color: var(--wp--preset--color--fg);
}
.ff-needs-box .aieo-product-needs__title,
.ff-needs-box h3,
.ff-complementary-box .om-ppe-product-needs__title,
.ff-complementary-box h3 {
	font-family:    var(--wp--preset--font-family--aeonik);
	font-size:      0.9375rem;        /* 15px */
	font-weight:    500;
	letter-spacing: 0.038em;
	margin: 0 0 var(--wp--preset--spacing--3) 0;
	color: var(--wp--preset--color--fg);
}
.ff-needs-box img,
.ff-complementary-box img {
	max-width: 64px;
	height: auto;
}
.ff-needs-box .price ins,
.ff-needs-box .price .amount,
.ff-complementary-box .price ins,
.ff-complementary-box .price .amount {
	color: var(--wp--preset--color--accent);
	font-weight: 700;
}

/* Security / payment / trust badges row (om-ppe shortcodes output their
 * own DOM; we just stack + center the wrappers and tune spacing). */
.ff-security-row {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--3);
	align-items: center;
	padding-top:    var(--wp--preset--spacing--4);
	padding-bottom: var(--wp--preset--spacing--3);
	border-top: 1px solid var(--wp--preset--color--border);
	margin-top: var(--wp--preset--spacing--4);
}
.ff-security-row img {
	max-height: 32px;
	width: auto;
}

/* Accordion section titles (ΛΕΠΤΟΜΕΡΕΙΕΣ / ΣΥΣΤΑΤΙΚΑ / etc).
 * 18 Regular mobile / lh 25 → 22 Regular desktop / lh 25. */
.single-product .wp-block-accordion-trigger,
.single-product .wp-block-accordion-trigger__label {
	font-family:    var(--wp--preset--font-family--aeonik);
	font-size:      1.125rem;          /* 18px mobile */
	font-weight:    400;
	line-height:    1.39;
	letter-spacing: 0.038em;
	text-transform: uppercase;
}
@media (min-width: 768px) {
	.single-product .wp-block-accordion-trigger,
	.single-product .wp-block-accordion-trigger__label {
		font-size:   1.375rem;         /* 22px desktop */
		line-height: 1.136;            /* 25/22 */
	}
}

/* ============================================================
 * WC product archive — vertical column dividers (current).
 * Diagonal/zigzag variant kept commented below for easy revert.
 * ============================================================
 * The Cart block / product collection block emits products as
 * a flex/grid where each card sits in `.wp-block-post-template`
 * children or `.wc-block-product-template` items. The dividers
 * are decorative thin lines between columns.
 */
@media (min-width: 768px) {
	.wp-block-woocommerce-product-template,
	.wc-block-product-template {
		position: relative;
		align-items: stretch;
	}
	/* Vertical dividers between cards WITHIN a row only — never at the
	 * end of a row. With 3 cards per row, the last card of each row
	 * sits at positions 3, 6, 9, … (every 3n). `:not(:nth-child(3n))`
	 * excludes those, so dividers only appear on cards 1 & 2 of each
	 * row (between 1↔2 and 2↔3), never trailing past card 3.
	 *
	 * Each card is `position: relative` so the absolute-positioned
	 * `::after` anchors to the card and inherits its full row-stretched
	 * height (top:0 / bottom:0). The line sits in the GAP centre by
	 * pulling right by half the grid gap. */
	.wc-block-product-template > li,
	.wp-block-woocommerce-product-template > li {
		position: relative;
	}
	.wp-block-woocommerce-product-template > li:not(:nth-child(3n)):not(:last-child)::after,
	.wc-block-product-template > li:not(:nth-child(3n)):not(:last-child)::after {
		content: "";
		position: absolute;
		top: 0;
		bottom: 0;
		/* Centre the 1px line in the gutter — `gap` is 16px so we
		 * pull 8.5px past the card's right edge. */
		right: calc(var(--wp--preset--spacing--3, 16px) / -2 - 0.5px);
		width: 1px;
		height: auto;
		background: var(--wp--preset--color--fg, #1a1a1a);
		pointer-events: none;
		z-index: 1;
	}
}

/* ── DIAGONAL VARIANT (commented out — uncomment to revert) ──
 * Adds alternating ±3° tilt per row for a zigzag effect.
 * To re-enable: comment out the vertical block above and
 * uncomment the block below.
 * --------------------------------------------------------- */
/*
@media (min-width: 768px) {
	.wp-block-woocommerce-product-template,
	.wc-block-product-template {
		position: relative;
		align-items: stretch;
	}
	.wc-block-product-template > li,
	.wp-block-woocommerce-product-template > li {
		position: relative;
	}
	.wp-block-woocommerce-product-template > li:not(:nth-child(3n)):not(:last-child)::after,
	.wc-block-product-template > li:not(:nth-child(3n)):not(:last-child)::after {
		content: "";
		position: absolute;
		top: 0;
		bottom: 0;
		right: calc(var(--wp--preset--spacing--3, 16px) / -2 - 0.5px);
		width: 1px;
		height: auto;
		background: var(--wp--preset--color--fg, #1a1a1a);
		transform: rotate(3deg);
		transform-origin: center;
		pointer-events: none;
		z-index: 1;
	}
	.wp-block-woocommerce-product-template > li:nth-child(6n+4):not(:nth-child(3n)):not(:last-child)::after,
	.wp-block-woocommerce-product-template > li:nth-child(6n+5):not(:nth-child(3n)):not(:last-child)::after,
	.wc-block-product-template > li:nth-child(6n+4):not(:nth-child(3n)):not(:last-child)::after,
	.wc-block-product-template > li:nth-child(6n+5):not(:nth-child(3n)):not(:last-child)::after {
		transform: rotate(-3deg);
	}
}
*/

/* Swatches column on RIGHT of product image — AIEO renders swatches
 * with class `.aieo-swatches-vertical`. On the archive card we anchor
 * them to the image's right edge; the variant tokens read as "this
 * product comes in N colours" without competing with the price/title
 * stack on the left. */
.wc-block-product-template .aieo-swatches-vertical,
.wp-block-woocommerce-product-template .aieo-swatches-vertical {
	position: absolute;
	top: var(--wp--preset--spacing--3);
	right: var(--wp--preset--spacing--3);
	left: auto;
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
	z-index: 2;
}

/* AIEO Runtime variation swatches (.om-product-swatches--archive renders
 * a WC variations form inside each archive card). Layout split:
 *
 *   1. IMAGE / COLOR attribute rows  → absolute-positioned LEFT column,
 *      vertically centred on the image (the image dominates the upper
 *      half of the card). One variation type → one column; if both
 *      exist they stack within the same column.
 *
 *   2. BUTTON (text) attribute rows  → stay in NATURAL FLOW. The
 *      `aieo/product-card-swatches` block sits AFTER the price block in
 *      the product-template (see brand-archive-page.php +
 *      archive-product.html), so chips like "30ml / 100ml" land between
 *      price and the in-block add-to-cart button — matching the
 *      legacy classic-loop visual.
 *
 * The split is implemented with `:has()` (Chrome 105+, Safari 15.4+,
 * Firefox 121+ — all baseline-supported as of 2026): we target the
 * `<tr>` containing each attribute's wrapper and apply absolute
 * positioning only to the image/color trs.
 *
 * The card `<li>` is `position: relative` (declared above) so the
 * absolute positioning anchors to the card's bounds.
 */

/* Step 1 — base reset shared by every row in the archive variations
 * form: collapse the table semantics so each row/cell behaves like a
 * block element we can position. */
.wc-block-product-template .om-product-swatches--archive .variations,
.wp-block-woocommerce-product-template .om-product-swatches--archive .variations,
.wc-block-product-template .om-product-swatches--archive .variations tbody,
.wp-block-woocommerce-product-template .om-product-swatches--archive .variations tbody,
.wc-block-product-template .om-product-swatches--archive .variations tr,
.wp-block-woocommerce-product-template .om-product-swatches--archive .variations tr,
.wc-block-product-template .om-product-swatches--archive .variations td,
.wp-block-woocommerce-product-template .om-product-swatches--archive .variations td {
	display: block;
	padding: 0;
	border: 0;
	background: transparent;
}

/* Hide the WC `<th class="label">` cell (e.g. "Color:" / "Size:") in
 * every row — neither the left-column image strip nor the in-flow chip
 * row needs the attribute label visible on a card. */
.wc-block-product-template .om-product-swatches--archive .variations .label,
.wp-block-woocommerce-product-template .om-product-swatches--archive .variations .label {
	display: none !important;
}

/* Step 2 — IMAGE / COLOR rows: absolute-position to the LEFT column,
 * vertically centred on the image area. */
.wc-block-product-template .om-product-swatches--archive .variations tr:has(.om-variation-type-image),
.wc-block-product-template .om-product-swatches--archive .variations tr:has(.om-variation-type-color),
.wp-block-woocommerce-product-template .om-product-swatches--archive .variations tr:has(.om-variation-type-image),
.wp-block-woocommerce-product-template .om-product-swatches--archive .variations tr:has(.om-variation-type-color) {
	position: absolute;
	/* The card image occupies roughly the top half of the card (1:1
	   aspect + content stack below). 25% of the card ≈ middle of the
	   image; translateY(-50%) centres the column on that anchor. */
	top: 25%;
	transform: translateY(-50%);
	left: var(--wp--preset--spacing--3);
	right: auto;
	z-index: 5;
	width: auto;
	margin: 0;
}
.wc-block-product-template .om-product-swatches--archive .om-variation-type-image,
.wp-block-woocommerce-product-template .om-product-swatches--archive .om-variation-type-image,
.wc-block-product-template .om-product-swatches--archive .om-variation-type-color,
.wp-block-woocommerce-product-template .om-product-swatches--archive .om-variation-type-color {
	display: flex;
	flex-direction: column;
	align-items: center;
}

/* Step 3 — BUTTON rows: in flow, horizontal chip strip. The runtime's
 * baseline `aieo-swatches.css` gives chips their padding/border/font;
 * here we only flip the layout from vertical-stack (default for
 * `.om-product-swatches--archive`) back to horizontal so multiple text
 * options like "30ml / 100ml" line up beside each other under the
 * price. We DON'T override gap/sizing — the runtime's per-setting CSS
 * (`button_padding_*_shop_archive`, `button_gap_shop_archive`) remains
 * the source of truth. */
.wc-block-product-template .om-product-swatches--archive .variations tr:has(.om-variation-type-button),
.wp-block-woocommerce-product-template .om-product-swatches--archive .variations tr:has(.om-variation-type-button) {
	position: static;
	width: 100%;
	margin-top: 0.5rem;
}
.wc-block-product-template .om-product-swatches--archive .om-variation-type-button,
.wp-block-woocommerce-product-template .om-product-swatches--archive .om-variation-type-button {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
}

/* "+N more" counter on archive swatches — element is
 * `<a class="om-more-variations" data-remaining-count="N">+N</a>`,
 * appended to the swatch column when there are more variations than
 * the visible swatch limit. The runtime CSS gives it a grey box style
 * (32×32, border + radius); we strip all of that and re-render as a
 * plain "+ N" stack: `+` on top, count on the line below, no box.
 *
 * The count is read via `attr(data-remaining-count)` — a stable
 * integer the JS emits — so the visual format is guaranteed regardless
 * of the original `+N` text content. The original text is hidden via
 * `font-size: 0` so it doesn't bleed through. */
.om-more-variations,
.om-product-swatches--archive .om-more-variations {
	font-size: 0 !important;
	display: inline-flex !important;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	background: transparent !important;
	background-color: transparent !important;
	border: 0 !important;
	border-radius: 0 !important;
	width: auto !important;
	height: auto !important;
	min-width: 0 !important;
	min-height: 0 !important;
	padding: 2px 0 !important;
	margin: 0 !important;
	color: var(--wp--preset--color--fg, #1a1a1a) !important;
	text-decoration: none !important;
	line-height: 1.1;
	gap: 0;
}
.om-more-variations::before,
.om-product-swatches--archive .om-more-variations::before {
	content: "+";
	font-size: 32px;            /* ~2.3× the original 14px */
	font-weight: 400;
	line-height: 0.9;
	display: block;
}
.om-more-variations::after,
.om-product-swatches--archive .om-more-variations::after {
	content: attr(data-remaining-count);
	font-size: 16px;            /* up from 12px */
	font-weight: 400;
	line-height: 1.1;
	display: block;
}
.om-more-variations:hover,
.om-more-variations:focus-visible {
	color: var(--wp--preset--color--accent, #F46767) !important;
	background: transparent !important;
	background-color: transparent !important;
	border: 0 !important;
	outline: none;
}

/* The (separate) "Δείτε τις Επιλογές / See all variations" text link
 * stays hidden site-wide — the AIEO swatches admin's
 * `see_all_display_mode` is the canonical control if you ever need it
 * back. */
.om-see-all-variations-link {
	display: none !important;
}

/* Favourite (wishlist) heart on archive cards — push it inward so it
 * doesn't overlap the diagonal divider line at the card's right edge.
 * The actual archive button carries class
 *   `.aieo-wishlist-heart.aieo-wishlist-heart--archive.aieo-wishlist-pos-top-right`
 * so we target both the BEM modifier and the position modifier with
 * `!important` to beat any inline / runtime-emitted positioning. */
.aieo-wishlist-heart--archive.aieo-wishlist-pos-top-right,
.wc-block-product-template .aieo-wishlist-heart--archive,
.wp-block-woocommerce-product-template .aieo-wishlist-heart--archive {
	right: 24px !important;
	top: 12px !important;
}

/* Archive card hygiene — strip noise we don't want inside product cards.
 * Product-needs box: only renders on single-product pages by AIEO design,
 * but if a future build leaks it into the loop we'd never want it on a
 * card. WC "successfully added to cart" inline notice + Block-Cart green
 * confirmation pill are unwanted within cards too — they're noisy when
 * the side-cart drawer is the canonical post-add affordance.
 *
 * AIEO swatches multi-select success overlay (.om-multi-select-success
 * + .om-multi-select-container.om-success-state) — green pill that
 * appears after multi-add. Also unwanted on archive cards because the
 * side-cart drawer already confirms each add. The class names are
 * carried over from the retired om-product-swatches plugin.
 */
.wc-block-product-template .aieo-product-needs,
.wp-block-woocommerce-product-template .aieo-product-needs,
.wc-block-product-template .woocommerce-message,
.wp-block-woocommerce-product-template .woocommerce-message,
.wc-block-product-template .wc-block-components-notice-banner,
.wp-block-woocommerce-product-template .wc-block-components-notice-banner,
.om-multi-select-success {
	display: none !important;
}
/* Strip the green container styling (background / border / padding) so
 * if any other theme/plugin layers content on `.om-success-state` we
 * don't end up with a stray green box around it. */
.om-multi-select-container.om-success-state {
	background: transparent !important;
	border-color: transparent !important;
	padding: 0 !important;
	margin-bottom: 0 !important;
}

/* ── Archive card content alignment + typography + sale-price styling
 * All textual elements inside a product card centre-align: title,
 * description, price, button. Reviews/rating hidden per spec. The
 * image / swatches keep their own positioning (image is full-width
 * inside the card; swatches are absolutely positioned). */
.wc-block-product-template > li,
.wp-block-woocommerce-product-template > li {
	text-align: center;
}
.wc-block-product-template .wp-block-post-title,
.wp-block-woocommerce-product-template .wp-block-post-title,
.wc-block-product-template .wc-block-components-product-price,
.wp-block-woocommerce-product-template .wc-block-components-product-price,
.wc-block-product-template .wc-block-product-template__product-summary,
.wp-block-woocommerce-product-template .wc-block-product-template__product-summary {
	text-align: center;
	justify-content: center;
}

/* ── Typography spec for archive cards ──────────────────────────────
 * Title / price / description sized per the design system. Aeonik
 * Pro Regular (400) so we don't need to declare font-family — it's
 * already the body default in roosterx-ff.
 *
 * Title is constrained to 3/6 (=1/2) of the card's horizontal space so
 * long titles wrap before they reach the tilted divider lines between
 * adjacent cards. Centred via `margin-inline: auto`. */
.wc-block-product-template .wp-block-post-title,
.wp-block-woocommerce-product-template .wp-block-post-title,
.wc-block-product-template .wp-block-post-title a,
.wp-block-woocommerce-product-template .wp-block-post-title a {
	font-size: 23px;
	font-weight: 400;
	line-height: 1.25;
	letter-spacing: 0.01em;
	/* Explicitly normalise so browser-default `<a>` underline and any
	 * inherited italic (from a list / aside parent) don't bleed through.
	 * Without these resets, AJAX-replaced product cards (FiboFilters
	 * filter pass) sometimes show titles + prices as italic + underlined
	 * + accent-coloured because the title link inherits raw styles
	 * before our typography rules cascade. */
	text-decoration: none;
	font-style: normal;
	color: inherit;
}
/* Same defensive reset on the price block — the inner <bdi> tag has a
 * UA-default `unicode-bidi: isolate` plus some browsers apply
 * `font-style: italic` to block-level <bdi> in certain contexts. */
.wc-block-product-template .wc-block-components-product-price,
.wc-block-product-template .woocommerce-Price-amount,
.wc-block-product-template .woocommerce-Price-amount > bdi,
.wp-block-woocommerce-product-template .wc-block-components-product-price,
.wp-block-woocommerce-product-template .woocommerce-Price-amount,
.wp-block-woocommerce-product-template .woocommerce-Price-amount > bdi {
	font-style: normal;
	text-decoration: none;
}
.wc-block-product-template .wp-block-post-title,
.wp-block-woocommerce-product-template .wp-block-post-title {
	max-width: 50%;
	margin-inline: auto;
}
.wc-block-product-template .wc-block-components-product-price,
.wp-block-woocommerce-product-template .wc-block-components-product-price {
	font-size: 20px;
	font-weight: 400;
	line-height: 1.3;
}
.wc-block-product-template .wc-block-product-template__product-summary,
.wp-block-woocommerce-product-template .wc-block-product-template__product-summary,
.wc-block-product-template .wp-block-woocommerce-product-summary,
.wp-block-woocommerce-product-template .wp-block-woocommerce-product-summary {
	font-size: 19px;
	font-weight: 400;
	line-height: 1.35;
}

/* Reviews / rating stars — hidden on archive cards per spec. */
.wc-block-product-template .wc-block-components-product-rating,
.wp-block-woocommerce-product-template .wc-block-components-product-rating,
.wc-block-product-template .wp-block-woocommerce-product-rating,
.wp-block-woocommerce-product-template .wp-block-woocommerce-product-rating,
.wc-block-product-template .star-rating,
.wp-block-woocommerce-product-template .star-rating {
	display: none !important;
}

/* ── Mobile-only typography for archive cards ───────────────────────
 * Per design spec: title 15px Regular, price 16px Bold, buttons 14px
 * Medium. The desktop sizes (23/20/16 from the prior rules) stay in
 * effect from min-width: 768px upward via the cascade. */
@media (max-width: 767px) {
    .wc-block-product-template .wp-block-post-title,
    .wp-block-woocommerce-product-template .wp-block-post-title,
    .wc-block-product-template .wp-block-post-title a,
    .wp-block-woocommerce-product-template .wp-block-post-title a {
        font-size: 15px;
        font-weight: 400;
        line-height: 1.25;
    }
    .wc-block-product-template .wc-block-components-product-price,
    .wp-block-woocommerce-product-template .wc-block-components-product-price {
        font-size: 16px;
        font-weight: 700;
        line-height: 1.3;
    }
    /* Buy + discover buttons */
    .wc-block-product-template .wp-block-button .wp-block-button__link,
    .wp-block-woocommerce-product-template .wp-block-button .wp-block-button__link,
    .wc-block-product-template .wc-block-components-product-button .wp-block-button__link,
    .wp-block-woocommerce-product-template .wc-block-components-product-button .wp-block-button__link,
    .wc-block-product-template .aieo-quick-view-trigger,
    .wp-block-woocommerce-product-template .aieo-quick-view-trigger {
        font-size: 14px;
        font-weight: 500;
    }
}

/* ── Last-row orphan centering ─────────────────────────────────────
 * Force the product collection to use CSS Grid (was flex by default
 * in the WC block, which made transform/auto-margin tricks unreliable)
 * and then explicitly place orphans via `grid-column` + `justify-self:
 * center` + an explicit `width` matching one column.
 *
 * Pattern lifted from the user's working setup elsewhere:
 *   grid-column: 1 / -1     // span all cols
 *   justify-self: center    // centre within that span
 *   width: calc((100% - n_gaps * gap) / n_cols)   // hold to 1-col size
 */

/* Promote the product template to CSS Grid (3-col desktop, 2-col
 * mobile) so `grid-column` / `justify-self` actually take effect. */
.wc-block-product-template,
.wp-block-woocommerce-product-template {
    display: grid !important;
    gap: var(--wp--preset--spacing--3, 16px);
    grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 767px) {
    .wc-block-product-template,
    .wp-block-woocommerce-product-template {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* ── Last-row orphan centering ─────────────────────────────────────
 *
 * 1 orphan: span the full row, centre the card within, hold its
 *           width to a single column. (User's working pattern from
 *           elsewhere — works for both desktop and mobile.)
 *
 * 2 orphans (desktop only): a 3-col grid can't sub-divide a column,
 *           so each orphan gets `transform: translateX(50%)` — visually
 *           shifts it right by half its own width. Result: pair lands
 *           visually centred while the underlying grid placement stays
 *           at cols 1-2.
 */
@media (min-width: 768px) {
    .wc-block-product-template > li:last-child:nth-child(3n+1),
    .wp-block-woocommerce-product-template > li:last-child:nth-child(3n+1) {
        grid-column: 1 / -1;
        justify-self: center;
        width: calc((100% - 2 * var(--wp--preset--spacing--3, 16px)) / 3);
        box-sizing: border-box;
        margin: 0;
    }
    .wc-block-product-template > li:nth-last-child(2):nth-child(3n+1),
    .wp-block-woocommerce-product-template > li:nth-last-child(2):nth-child(3n+1),
    .wc-block-product-template > li:last-child:nth-child(3n+2),
    .wp-block-woocommerce-product-template > li:last-child:nth-child(3n+2) {
        transform: translateX(50%);
    }
}
@media (max-width: 767px) {
    .wc-block-product-template > li:last-child:nth-child(2n+1),
    .wp-block-woocommerce-product-template > li:last-child:nth-child(2n+1) {
        grid-column: 1 / -1;
        justify-self: center;
        width: calc((100% - var(--wp--preset--spacing--3, 16px)) / 2);
        box-sizing: border-box;
        margin: 0;
    }
}

/* DISCOVER IT — never wrap. The 14px Medium label is short ("DISCOVER IT")
 * but the button width (60% of card) on a narrow card was forcing a
 * line break ("DISCOVE" / "R IT"). `nowrap` keeps it on one line. */
.wc-block-product-template .aieo-quick-view-trigger,
.wp-block-woocommerce-product-template .aieo-quick-view-trigger,
.wc-block-product-template .wp-block-button .wp-block-button__link,
.wp-block-woocommerce-product-template .wp-block-button .wp-block-button__link {
    white-space: nowrap;
}

/* ── Mobile-specific button rules ───────────────────────────────────
 * Mobile cards drop the DISCOVER IT trigger entirely (per design —
 * only ΑΓΟΡΑ is shown), and the ΑΓΟΡΑ button reverts to a black filled
 * pill instead of the desktop white-with-accent-border variant. */
@media (max-width: 767px) {
    .wc-block-product-template .aieo-quick-view-trigger,
    .wp-block-woocommerce-product-template .aieo-quick-view-trigger {
        display: none !important;
    }
    .wc-block-product-template .wp-block-button .wp-block-button__link,
    .wp-block-woocommerce-product-template .wp-block-button .wp-block-button__link,
    .wc-block-product-template .wc-block-components-product-button .wp-block-button__link,
    .wp-block-woocommerce-product-template .wc-block-components-product-button .wp-block-button__link {
        background: var(--wp--preset--color--fg, #1a1a1a) !important;
        color: var(--wp--preset--color--bg, #ffffff) !important;
        border: 1px solid var(--wp--preset--color--fg, #1a1a1a) !important;
        border-radius: 9999px !important;     /* pill */
    }
    .wc-block-product-template .wp-block-button .wp-block-button__link:hover,
    .wp-block-woocommerce-product-template .wp-block-button .wp-block-button__link:hover,
    .wc-block-product-template .wc-block-components-product-button .wp-block-button__link:hover,
    .wp-block-woocommerce-product-template .wc-block-components-product-button .wp-block-button__link:hover {
        background: var(--wp--preset--color--accent, #F46767) !important;
        color: var(--wp--preset--color--bg, #ffffff) !important;
        border-color: var(--wp--preset--color--accent, #F46767) !important;
    }
}

/* Equal card heights — push the discover/buy button pair to the
 * card's bottom so siblings in the same row line up at the same
 * vertical position regardless of how many lines the title or
 * description wrap to. `margin-top: auto` on the *first* of the
 * bottom pair (discover, order: 9) pulls everything below it down
 * to the bottom of the flex column. */
.wc-block-product-template .aieo-quick-view-trigger,
.wp-block-woocommerce-product-template .aieo-quick-view-trigger {
    margin-top: auto;
}

/* ── Mobile diagonal dividers (2 cards per row) ────────────────────
 * Mirror of the desktop divider rule but for the mobile 2-column
 * layout. Lines appear on the right edge of every left-column card
 * (positions 1, 3, 5, 7, …) and skip the right-column cards
 * (positions 2, 4, 6, …) which are last in their row.
 *
 * Vertical (current). Diagonal/zigzag variant kept commented
 * below for easy revert. */
@media (max-width: 767px) {
    .wp-block-woocommerce-product-template,
    .wc-block-product-template {
        position: relative;
        align-items: stretch;
    }
    .wc-block-product-template > li,
    .wp-block-woocommerce-product-template > li {
        position: relative;
    }
    .wp-block-woocommerce-product-template > li:not(:nth-child(2n)):not(:last-child)::after,
    .wc-block-product-template > li:not(:nth-child(2n)):not(:last-child)::after {
        content: "";
        position: absolute;
        top: 0;
        bottom: 0;
        right: calc(var(--wp--preset--spacing--3, 16px) / -2 - 0.5px);
        width: 1px;
        height: auto;
        background: var(--wp--preset--color--fg, #1a1a1a);
        pointer-events: none;
        z-index: 1;
    }
}

/* ── DIAGONAL VARIANT — MOBILE (commented out — uncomment to revert) ──
 * Tilt alternates per row: row 1 (cards 1–2) leans +5°, row 2
 * (cards 3–4) leans −3°, row 3 (cards 5–6) leans +5°, …
 * The 4n+3 selector matches the LEFT card of every even row.
 * --------------------------------------------------------- */
/*
@media (max-width: 767px) {
    .wp-block-woocommerce-product-template,
    .wc-block-product-template {
        position: relative;
        align-items: stretch;
    }
    .wc-block-product-template > li,
    .wp-block-woocommerce-product-template > li {
        position: relative;
    }
    .wp-block-woocommerce-product-template > li:not(:nth-child(2n)):not(:last-child)::after,
    .wc-block-product-template > li:not(:nth-child(2n)):not(:last-child)::after {
        content: "";
        position: absolute;
        top: 0;
        bottom: 0;
        right: calc(var(--wp--preset--spacing--3, 16px) / -2 - 0.5px);
        width: 1px;
        height: auto;
        background: var(--wp--preset--color--fg, #1a1a1a);
        transform: rotate(5deg);
        transform-origin: center;
        pointer-events: none;
        z-index: 1;
    }
    .wp-block-woocommerce-product-template > li:nth-child(4n+3):not(:nth-child(2n)):not(:last-child)::after,
    .wc-block-product-template > li:nth-child(4n+3):not(:nth-child(2n)):not(:last-child)::after {
        transform: rotate(-3deg);
    }
}
*/

/* ── Buttons stack: DISCOVER IT above ΑΓΟΡΑ ─────────────────────────
 * The "Discover it" quick-view trigger (from AIEO_DMM_Side_Cart) and
 * WC's add-to-cart button live as siblings inside the card's button
 * row. They sit side-by-side by default; we want them stacked
 * vertically with DISCOVER on top. Two pieces:
 *   1. Force the parent container to column flex with center alignment.
 *   2. Use `order` to put `.aieo-quick-view-trigger` above the
 *      add-to-cart button regardless of DOM order.
 */
.wc-block-product-template > li,
.wp-block-woocommerce-product-template > li {
	display: flex;
	flex-direction: column;
	align-items: center;
}
/* WC's add-to-cart (ΑΓΟΡΑ) button — sized to 3/5 of the card.
 * Square corners, WHITE background, ACCENT border + accent text per
 * spec. The button block wrapper carries the width; the inner
 * `<a class="wp-block-button__link">` fills 100% of that and overrides
 * the theme.json default (black pill) with the new outlined look. */
.wc-block-product-template .wp-block-button,
.wp-block-woocommerce-product-template .wp-block-button,
.wc-block-product-template .wc-block-components-product-button,
.wp-block-woocommerce-product-template .wc-block-components-product-button {
	width: 60%;
	margin-inline: auto;
	order: 10;          /* always renders at the bottom of the card */
}
.wc-block-product-template .wp-block-button .wp-block-button__link,
.wp-block-woocommerce-product-template .wp-block-button .wp-block-button__link,
.wc-block-product-template .wc-block-components-product-button .wp-block-button__link,
.wp-block-woocommerce-product-template .wc-block-components-product-button .wp-block-button__link {
	width: 100%;
	background: var(--wp--preset--color--bg, #ffffff);
	color: var(--wp--preset--color--accent, #F46767);
	border: 1px solid var(--wp--preset--color--accent, #F46767);
	border-radius: 0;
	font-weight: 500;
	letter-spacing: 0.038em;
	text-transform: uppercase;
	transition: background-color 150ms ease, color 150ms ease;
}
.wc-block-product-template .wp-block-button .wp-block-button__link:hover,
.wp-block-woocommerce-product-template .wp-block-button .wp-block-button__link:hover,
.wc-block-product-template .wc-block-components-product-button .wp-block-button__link:hover,
.wp-block-woocommerce-product-template .wc-block-components-product-button .wp-block-button__link:hover {
	background: var(--wp--preset--color--accent, #F46767);
	color: var(--wp--preset--color--bg, #ffffff);
}

/* DISCOVER IT button — sits directly above ΑΓΟΡΑ. Uses `order: 9`
 * (one less than the buy button's `order: 10`) so it lands just above
 * the buy button in the flex column, regardless of where it appears
 * in the DOM. Other card items stay at default `order: 0`, so they
 * still render above this pair. */
.wc-block-product-template .aieo-quick-view-trigger,
.wp-block-woocommerce-product-template .aieo-quick-view-trigger {
	order: 9;
	margin-bottom: 8px;
	width: 60%;          /* match the buy button so the pair reads as a stack */
	background: transparent;
	border: 1px solid var(--wp--preset--color--fg, #1a1a1a);
	color: var(--wp--preset--color--fg, #1a1a1a);
	padding: 10px 16px;
	font-size: 14px;
	font-weight: 500;
	letter-spacing: 0.038em;
	text-transform: uppercase;
	cursor: pointer;
	transition: background-color 150ms ease, color 150ms ease;
}
.wc-block-product-template .aieo-quick-view-trigger:hover,
.wp-block-woocommerce-product-template .aieo-quick-view-trigger:hover {
	background: var(--wp--preset--color--fg, #1a1a1a);
	color: var(--wp--preset--color--bg, #ffffff);
}

/* Sale price layout — WC core wraps the old price in <del> and the
 * new price in <ins> inside the same `.wc-block-components-product-price`
 * element. Old price renders Light + strikethrough; new price stays
 * regular weight without the underline that <ins> ships with. */
.wc-block-components-product-price del,
.woocommerce-Price-amount.amount + del {
	display: inline-block;
	font-weight: 300;
	color: var(--wp--preset--color--muted, #6b6b6b);
	text-decoration: line-through;
	margin-right: 0.5em;
}
.wc-block-components-product-price ins,
.woocommerce-Price-amount.amount + ins {
	text-decoration: none;
	font-weight: 600;
	color: var(--wp--preset--color--fg, #1a1a1a);
}
/* Stack the prices on archive cards so old/strikethrough sits above new. */
.wc-block-product-template .wc-block-components-product-price,
.wp-block-woocommerce-product-template .wc-block-components-product-price {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
}
.wc-block-product-template .wc-block-components-product-price del,
.wp-block-woocommerce-product-template .wc-block-components-product-price del {
	margin-right: 0;
}

/* PRO badge bottom-right corner of card. AIEO emits `.pro-badge`. */
.wc-block-product-template .pro-badge,
.wp-block-woocommerce-product-template .pro-badge {
	position: absolute;
	right: var(--wp--preset--spacing--3);
	bottom: var(--wp--preset--spacing--3);
	background: var(--wp--preset--color--accent);
	color:      var(--wp--preset--color--bg);
	font-size:  0.6875rem;
	font-weight: 700;
	padding: 0.25rem 0.6rem;
	border-radius: 9999px;
	z-index: 3;
}

/* ── Archive badge column — round circles under the favourite heart
 * Active only when the AIEO `archive_badge_position` setting is set to
 * `below_favourite` (which adds the `.aieo-badges-below-fav` body class).
 * The role-pricing module already places badges at top:56px right:12px
 * and stacks PRO under SALE; we reshape them to 76px circles here and
 * override per-badge colours per the FF brand spec.                  */
body.aieo-badges-below-fav ul.products li.product .aieo-pro-badge,
body.aieo-badges-below-fav .products .product .aieo-pro-badge,
body.aieo-badges-below-fav .wc-block-product-template .aieo-pro-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template .aieo-pro-badge,
body.aieo-badges-below-fav ul.products li.product .onsale,
body.aieo-badges-below-fav .products .product .onsale,
body.aieo-badges-below-fav .wc-block-product-template .onsale,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template .onsale,
body.aieo-badges-below-fav ul.products li.product .om-ppe-label,
body.aieo-badges-below-fav .products .product .om-ppe-label,
body.aieo-badges-below-fav .wc-block-product-template .om-ppe-label,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template .om-ppe-label,
body.aieo-badges-below-fav ul.products li.product .aieo-bg-archive-badge,
body.aieo-badges-below-fav .products .product .aieo-bg-archive-badge,
body.aieo-badges-below-fav .wc-block-product-template .aieo-bg-archive-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template .aieo-bg-archive-badge {
	/* 48px circle — smaller than the offer-of-the-month SVG (76) so the
	 * badge reads as a quiet companion to the favourite heart instead
	 * of a competing focal point. The role-pricing inline styles set
	 * min-height/padding/etc with !important; we counter here. */
	width: 48px !important;
	height: 48px !important;
	min-height: 48px !important;
	min-width: 48px !important;
	padding: 0 !important;
	border-radius: 50% !important;
	display: inline-flex !important;
	flex-direction: column !important;
	align-items: center !important;
	justify-content: center !important;
	font-size: 10px !important;
	font-weight: 700 !important;
	line-height: 1.1 !important;
	text-align: center !important;
	white-space: normal !important;
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12) !important;
	letter-spacing: 0.04em !important;
	gap: 1px !important;
}

/* Per-badge colours.
 *   PRO  → grey background, yellow letters (per spec).
 *   SALE → keep brand red as default but on a circle.
 *   GIFT (offer of the month) → yellow circle, fg text.
 */
body.aieo-badges-below-fav ul.products li.product .aieo-pro-badge,
body.aieo-badges-below-fav .products .product .aieo-pro-badge,
body.aieo-badges-below-fav .wc-block-product-template .aieo-pro-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template .aieo-pro-badge {
	background: var(--wp--preset--color--muted, #6b6b6b) !important;
	color: #f4f467 !important;
}
body.aieo-badges-below-fav ul.products li.product .aieo-bg-archive-badge,
body.aieo-badges-below-fav .products .product .aieo-bg-archive-badge,
body.aieo-badges-below-fav .wc-block-product-template .aieo-bg-archive-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template .aieo-bg-archive-badge {
	background: #f4f467 !important;
	color: var(--wp--preset--color--fg, #1a1a1a) !important;
}

/* Absolute positioning + alignment — the role-pricing module's inline
 * CSS only sets `position: absolute` on legacy `ul.products li.product`
 * selectors. The WC product collection block uses
 * `.wc-block-product-template > li` instead, so badges fall to inline
 * flow (below the image) without these explicit rules. We promote them
 * to absolute and anchor under the favourite heart for both contexts. */
/* Hide the default WC "ΠΡΟΣΦΟΡΑ" pill on archive cards —
 * the OM PPE plugin already renders a red round "SALE" label
 * (`.om-ppe-product-labels`) which is the canonical sale signal in
 * the FF design. Showing both makes the card look noisy AND the
 * default pill overlaps the wishlist heart in the top-right corner.
 * Detail pages keep their badges so this is not a styling
 * regression there.
 *
 * Two flavours of this badge exist in WC:
 *   1. Legacy `.onsale` (classic templates, ul.products lists)
 *   2. Block-based `.wc-block-components-product-sale-badge`
 *      (modern WC product collection block — what FF uses)
 * Hide both, since some blocks/widgets fall back to the legacy
 * markup. */
body.aieo-badges-below-fav ul.products li.product .onsale,
body.aieo-badges-below-fav .products .product .onsale,
body.aieo-badges-below-fav .wc-block-product-template > li .onsale,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .onsale,
body.aieo-badges-below-fav .wc-block-product-template .wc-block-components-product-sale-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template .wc-block-components-product-sale-badge,
body.aieo-badges-below-fav ul.products li.product .wc-block-components-product-sale-badge,
body.aieo-badges-below-fav .products .product .wc-block-components-product-sale-badge {
	display: none !important;
}

body.aieo-badges-below-fav ul.products li.product .aieo-pro-badge,
body.aieo-badges-below-fav .products .product .aieo-pro-badge,
body.aieo-badges-below-fav ul.products li.product .aieo-bg-archive-badge,
body.aieo-badges-below-fav .products .product .aieo-bg-archive-badge,
body.aieo-badges-below-fav .wc-block-product-template > li .aieo-pro-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .aieo-pro-badge,
body.aieo-badges-below-fav .wc-block-product-template > li .aieo-bg-archive-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .aieo-bg-archive-badge,
body.aieo-badges-below-fav .wc-block-product-template > li .om-ppe-product-labels,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .om-ppe-product-labels {
	position: absolute !important;
	z-index: 9 !important;
	/* Heart centre lives at right:40 from card edge (right:24 + width 32 / 2).
	 * 48px badge needs `right: 16` so its centre lands at right:16+24=40 —
	 * vertically aligned with the heart on the same vertical axis. */
	right: 16px !important;
	top: 60px !important;         /* below the heart (heart at 12 + ~36 high + ~12 buffer) */
	left: auto !important;
	bottom: auto !important;
}

/* Stacking — sequential badge slots so they don't overlap.
 * 60px (48 badge + 12 gap) per slot keeps the column readable. */
body.aieo-badges-below-fav .wc-block-product-template > li .onsale ~ .aieo-pro-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .onsale ~ .aieo-pro-badge,
body.aieo-badges-below-fav .wc-block-product-template > li .om-ppe-product-labels ~ .aieo-pro-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .om-ppe-product-labels ~ .aieo-pro-badge {
	top: 120px !important;
}
body.aieo-badges-below-fav .wc-block-product-template > li .onsale ~ .aieo-bg-archive-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .onsale ~ .aieo-bg-archive-badge,
body.aieo-badges-below-fav .wc-block-product-template > li .om-ppe-product-labels ~ .aieo-bg-archive-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .om-ppe-product-labels ~ .aieo-bg-archive-badge,
body.aieo-badges-below-fav .wc-block-product-template > li .aieo-pro-badge ~ .aieo-bg-archive-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .aieo-pro-badge ~ .aieo-bg-archive-badge {
	top: 120px !important;
}
body.aieo-badges-below-fav .wc-block-product-template > li .onsale ~ .aieo-pro-badge ~ .aieo-bg-archive-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .onsale ~ .aieo-pro-badge ~ .aieo-bg-archive-badge {
	top: 180px !important;
}

/* ============================================================
 * AIEO product badges — Monthly offer (Προσφορά του Μήνα) + NEW.
 * ============================================================
 *
 * Two custom badges added by AIEO_DMM_Brand_Discounts:
 *   - `.aieo-monthly-offer-badge` — coral round pill, supersedes
 *     the WC sale badge for products imported via the monthly CSV.
 *   - `.aieo-new-badge` — small black pill marking products
 *     published within the configured `new_product_days` window.
 *
 * Stacking rules: NEW always renders LAST in the column so it
 * never displaces a more commercial signal. The monthly-offer
 * badge sits in the same "primary commercial signal" slot as
 * sale / pro / gift, with the sale badge hidden when monthly-
 * offer is also present (shopper sees one or the other, not
 * both — a monthly-offer product is on offer after all). */

.aieo-monthly-offer-badge {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	border-radius: 9999px;
	background: var(--wp--preset--color--accent, #F46767);
	color: #ffffff;
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	line-height: 1.1;
	text-align: center;
	padding: 0 10px;
	min-width: 48px;
	min-height: 48px;
	box-sizing: border-box;
}
.aieo-monthly-offer-badge-text {
	display: block;
	max-width: 70px;
	white-space: normal;
	word-wrap: break-word;
}

.aieo-new-badge {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	border-radius: 9999px;
	background: #1a1a1a;
	color: #ffffff;
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	line-height: 1;
	width: 48px;
	height: 48px;
	box-sizing: border-box;
}

/* Position both new badges in the same below-favourite stack as
 * the existing pro/gift badges. Same `right: 16px` anchor +
 * stacking math so they line up cleanly. */
body.aieo-badges-below-fav ul.products li.product .aieo-monthly-offer-badge,
body.aieo-badges-below-fav .products .product .aieo-monthly-offer-badge,
body.aieo-badges-below-fav .wc-block-product-template > li .aieo-monthly-offer-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .aieo-monthly-offer-badge,
body.aieo-badges-below-fav ul.products li.product .aieo-new-badge,
body.aieo-badges-below-fav .products .product .aieo-new-badge,
body.aieo-badges-below-fav .wc-block-product-template > li .aieo-new-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .aieo-new-badge {
	position: absolute !important;
	z-index: 9 !important;
	right: 16px !important;
	top: 60px !important;
	left: auto !important;
	bottom: auto !important;
}

/* Stacking — append to the existing slot rules. The monthly-offer
 * badge takes the first commercial-signal slot (60px); subsequent
 * badges (pro / gift) move down. The NEW badge always renders
 * LAST so it picks up whatever slot is left below the others.
 *
 * Slot map (approx): 60 → 120 → 180 → 240, with 60px between. */
body.aieo-badges-below-fav .wc-block-product-template > li .aieo-monthly-offer-badge ~ .aieo-pro-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .aieo-monthly-offer-badge ~ .aieo-pro-badge {
	top: 120px !important;
}
body.aieo-badges-below-fav .wc-block-product-template > li .aieo-monthly-offer-badge ~ .aieo-bg-archive-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .aieo-monthly-offer-badge ~ .aieo-bg-archive-badge,
body.aieo-badges-below-fav .wc-block-product-template > li .aieo-monthly-offer-badge ~ .aieo-pro-badge ~ .aieo-bg-archive-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .aieo-monthly-offer-badge ~ .aieo-pro-badge ~ .aieo-bg-archive-badge {
	top: 180px !important;
}

/* NEW badge sits LAST. We push it down past every preceding badge.
 * Use a generous 240px floor — covers up to 3 badges above it. */
body.aieo-badges-below-fav .wc-block-product-template > li .onsale ~ .aieo-new-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .onsale ~ .aieo-new-badge,
body.aieo-badges-below-fav .wc-block-product-template > li .om-ppe-product-labels ~ .aieo-new-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .om-ppe-product-labels ~ .aieo-new-badge,
body.aieo-badges-below-fav .wc-block-product-template > li .aieo-monthly-offer-badge ~ .aieo-new-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .aieo-monthly-offer-badge ~ .aieo-new-badge,
body.aieo-badges-below-fav .wc-block-product-template > li .aieo-pro-badge ~ .aieo-new-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .aieo-pro-badge ~ .aieo-new-badge,
body.aieo-badges-below-fav .wc-block-product-template > li .aieo-bg-archive-badge ~ .aieo-new-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .aieo-bg-archive-badge ~ .aieo-new-badge {
	top: 120px !important;
}
body.aieo-badges-below-fav .wc-block-product-template > li .aieo-monthly-offer-badge ~ .aieo-pro-badge ~ .aieo-new-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .aieo-monthly-offer-badge ~ .aieo-pro-badge ~ .aieo-new-badge,
body.aieo-badges-below-fav .wc-block-product-template > li .aieo-monthly-offer-badge ~ .aieo-bg-archive-badge ~ .aieo-new-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .aieo-monthly-offer-badge ~ .aieo-bg-archive-badge ~ .aieo-new-badge {
	top: 180px !important;
}
body.aieo-badges-below-fav .wc-block-product-template > li .aieo-monthly-offer-badge ~ .aieo-pro-badge ~ .aieo-bg-archive-badge ~ .aieo-new-badge,
body.aieo-badges-below-fav .wp-block-woocommerce-product-template > li .aieo-monthly-offer-badge ~ .aieo-pro-badge ~ .aieo-bg-archive-badge ~ .aieo-new-badge {
	top: 240px !important;
}

/* Sale-badge supersede — hide WC's sale badge entirely on cards
 * AND single-product pages whenever a monthly-offer badge is
 * also present. Already hidden on archive cards globally; this
 * rule extends the supersede onto single product pages. */
body.single-product div.product:has(.aieo-monthly-offer-badge) .onsale,
body.single-product div.product:has(.aieo-monthly-offer-badge) .wc-block-components-product-sale-badge {
	display: none !important;
}

/* ----------------------------------------------------------------
 * Single-product page — badge positioning over the image.
 *
 * The image gallery block (`.wp-block-woocommerce-product-image-gallery`,
 * also exposed as `.woocommerce-product-gallery`) gets `position:
 * relative` so it forms the positioning context for the badges
 * we inject INSIDE it via render_block. The absolute-positioned
 * badges (PRO, monthly-offer, NEW) then anchor over the photo
 * instead of escaping into the right summary column.
 *
 * Stack order — top-left of the image: monthly-offer → PRO → NEW.
 * NEW always sits at the bottom of the column to match archive-card
 * stacking semantics ("never displaces a more commercial signal").
 * --------------------------------------------------------------- */
body.single-product .wp-block-woocommerce-product-image-gallery,
body.single-product .woocommerce-product-gallery {
	position: relative;
}
body.single-product .wp-block-woocommerce-product-image-gallery .aieo-pro-badge,
body.single-product .wp-block-woocommerce-product-image-gallery .aieo-monthly-offer-badge,
body.single-product .wp-block-woocommerce-product-image-gallery .aieo-new-badge,
body.single-product .woocommerce-product-gallery .aieo-pro-badge,
body.single-product .woocommerce-product-gallery .aieo-monthly-offer-badge,
body.single-product .woocommerce-product-gallery .aieo-new-badge {
	position: absolute !important;
	z-index: 9 !important;
	left: 12px !important;
	right: auto !important;
	top: 12px !important;
}
/* Stack — monthly-offer first (top), then PRO, then NEW. The
 * sibling combinators rely on render_block injection order:
 * brand-discounts injects monthly + NEW (priority 12), role-pricing
 * injects PRO (priority 11) — so PRO appears BEFORE monthly in DOM.
 * We therefore offset PRO at the top, monthly-offer below it, NEW
 * last. (The visual hierarchy is maintained by sequential `top`
 * offsets — alphabetical class-order doesn't matter.) */
body.single-product .wp-block-woocommerce-product-image-gallery .aieo-pro-badge ~ .aieo-monthly-offer-badge,
body.single-product .woocommerce-product-gallery .aieo-pro-badge ~ .aieo-monthly-offer-badge {
	top: 56px !important;
}
body.single-product .wp-block-woocommerce-product-image-gallery .aieo-pro-badge ~ .aieo-new-badge,
body.single-product .woocommerce-product-gallery .aieo-pro-badge ~ .aieo-new-badge,
body.single-product .wp-block-woocommerce-product-image-gallery .aieo-monthly-offer-badge ~ .aieo-new-badge,
body.single-product .woocommerce-product-gallery .aieo-monthly-offer-badge ~ .aieo-new-badge {
	top: 56px !important;
}
body.single-product .wp-block-woocommerce-product-image-gallery .aieo-pro-badge ~ .aieo-monthly-offer-badge ~ .aieo-new-badge,
body.single-product .woocommerce-product-gallery .aieo-pro-badge ~ .aieo-monthly-offer-badge ~ .aieo-new-badge {
	top: 110px !important;
}

/* ============================================================
 * AIEO recommendations — product titles use accent (coral red).
 * Standard archive post-titles stay black (overridden via
 * styles.blocks.core/post-title in theme.json).
 * ============================================================
 * AIEO emits recommendation cards inside wrappers like
 * `.aieo-recommendations`, `.aieo-related-products`, or
 * `.aieo-best-sellers`. Targeting these specifically.
 */
.aieo-recommendations .wp-block-post-title a,
.aieo-related-products .wp-block-post-title a,
.aieo-best-sellers    .wp-block-post-title a,
.aieo-recommendations h2.product-name,
.aieo-recommendations h3.product-name,
.aieo-related-products .product-name,
.aieo-best-sellers    .product-name {
	color: var(--wp--preset--color--accent);
}
.aieo-recommendations .wp-block-post-title a:hover,
.aieo-related-products .wp-block-post-title a:hover,
.aieo-best-sellers    .wp-block-post-title a:hover {
	color: var(--wp--preset--color--fg);
}

/* ============================================================
 * FiboSearch skin — only kicks in when the plugin's classes are
 * on the page (`.dgwt-wcas-search-wrapp`). Brand colors + Aeonik.
 * Loads unconditionally; selectors no-op if FiboSearch absent.
 * ============================================================
 */
.dgwt-wcas-search-wrapp {
	font-family: var(--wp--preset--font-family--aeonik);
}
/* FiboSearch input — base brand styling (font, border-bottom, no fill).
 * Centering + line-height are re-asserted at higher specificity below
 * so they beat the plugin's solaris theme rules. */
/* FiboSearch styling has moved to the PARENT theme — see
 *   wp-content/themes/roosterx/assets/css/fibosearch.css
 *   wp-content/themes/roosterx/inc/fibosearch-integration.php
 *
 * The parent enqueues the stylesheet on every Rooster X site, so
 * this child theme inherits it for free. To customise the look on
 * FF, override the documented `--rx-search-*` custom properties on
 * `:root` from anywhere later in the cascade (the override block
 * below holds the FF-specific values — alignment, accents, etc.). */
:root {
	/* FF brand defaults — inherits Aeonik font, accent letter-spacing,
	 * centre-aligned placeholder for the desktop instance. */
	--rx-search-desktop-font:           var(--wp--preset--font-family--aeonik);
	--rx-search-desktop-tracking:       0.038em;
	--rx-search-desktop-color:          var(--wp--preset--color--fg);
	--rx-search-desktop-text-align:     center;
	--rx-search-desktop-placeholder-align: center;
	--rx-search-desktop-placeholder-color: var(--wp--preset--color--muted);
	--rx-search-desktop-border-bottom:  1px solid var(--wp--preset--color--border);
}
.dgwt-wcas-search-submit,
.dgwt-wcas-search-icon {
	background: transparent !important;
	color:      var(--wp--preset--color--fg) !important;
}
/* Voice-search (microphone) icon — paint it black so it matches the
 * rest of the row 1 chrome instead of the plugin's default accent. */
.dgwt-wcas-voice-search,
.dgwt-wcas-voice-search svg,
.dgwt-wcas-voice-search svg path {
	color: #000 !important;
	fill:  #000 !important;
}
.dgwt-wcas-suggestion {
	font-family: var(--wp--preset--font-family--aeonik);
	color:       var(--wp--preset--color--fg);
}
.dgwt-wcas-suggestion:hover,
.dgwt-wcas-suggestion-selected {
	background-color: var(--wp--preset--color--subtle) !important;
	color:            var(--wp--preset--color--accent) !important;
}
.dgwt-wcas-pd-price ins,
.dgwt-wcas-pd-price .amount {
	color: var(--wp--preset--color--accent);
	font-weight: 700;
}

/* ============================================================
 * Tighten root block-gap. WP applies a default
 *     :where(.wp-site-blocks) > * { margin-block-start: <blockGap>; }
 * that injects --wp--preset--spacing--5 between every top-level block
 * (announcement bar, header, main, footer). The brand wants the
 * header sitting flush against the announcement bar with no gap, so
 * we zero out the rule for the immediate site-blocks children.
 * Page-level vertical rhythm inside `<main>` is handled per-block. */
:where(.wp-site-blocks) > * {
	margin-block-start: 0 !important;
}

/* ============================================================
 * Header display toggle — UNLAYERED so it wins over WP block-layout
 * inline rules and parent theme defaults. The mobile variant shows on
 * narrow viewports, the desktop variant on ≥1024px. Both live in the
 * same `header.html` template part.
 * ============================================================ */
.roosterx-header--mobile,
.ff-header--mobile  { display: flex !important;  }
.ff-header--desktop { display: none !important;  }
@media (min-width: 1024px) {
	.roosterx-header--mobile,
	.ff-header--mobile  { display: none  !important; }
	.ff-header--desktop { display: block !important; }
}

/* Desktop nav strip — render the menu list horizontally. The
 * `[preload-desktop-menu]` shortcode emits a default `<ul><li>` tree;
 * the `<ul>` ships with `display: block` so its `<li>`s stack vertically
 * unless we flip it. Unlayered to win against the menu plugin's CSS. */
.ff-header--desktop .ff-header__row--nav,
.ff-header--desktop .ff-header__row--nav .wp-block-group__inner-container {
	width: 100%;
}
.ff-header--desktop .ff-header__row--nav ul,
.ff-header--desktop .ff-header__row--nav .menu,
.ff-header--desktop .ff-header__row--nav .om-desktop-menu,
.ff-header--desktop .ff-header__row--nav .om-desktop-menu > ul {
	display: flex !important;
	flex-direction: row !important;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: var(--wp--preset--spacing--5);
	list-style: none !important;
	margin: 0 !important;
	padding: 0 !important;
}
.ff-header--desktop .ff-header__row--nav li {
	list-style: none !important;
	margin: 0 !important;
	padding: 0 !important;
}

/* Nav row — no top/bottom borders; the menu sits clean between the
 * row 1 black line and the page content. */
.ff-header--desktop .ff-header__row--nav {
	border: 0 !important;
}

/* Hide Max Mega Menu's mobile hamburger toggle inside the desktop nav.
 * The plugin emits `<div class="mega-menu-toggle">…</div>` ahead of the
 * `<ul>` and only shows it on narrow viewports via its own JS, but on
 * the FF desktop header we never want it — desktop visitors get the
 * full inline menu, not a hamburger. */
.ff-header--desktop .mega-menu-toggle {
	display: none !important;
}

/* ============================================================
 * Max Mega Menu overrides — the plugin auto-generates a stylesheet
 * keyed by ID (`#mega-menu-wrap-max_mega_menu_1`,
 * `#mega-menu-max_mega_menu_1`) with hard-coded colors (navy #002147,
 * hot pink #e91d88) and 20px font sizes that override generic class
 * selectors. The plugin instance ID is dynamic (1, 2, …), so we use
 * `[id^="mega-menu-wrap-"]` / `[id^="mega-menu-"]` to win against
 * any instance + match the plugin's selector pattern for specificity.
 * ============================================================ */

/* Force the menu UL to flex horizontally and center. The plugin sets
 * `text-align: center` + `display: inline-block` on items, which CAN
 * center them, but the row's flex parent collapses them to one item
 * width. Switching the UL to flex with `justify-content: center`
 * gives stable horizontal alignment regardless of viewport. */
.ff-header--desktop [id^="mega-menu-wrap-"] [id^="mega-menu-"][id$="_1"],
.ff-header--desktop [id^="mega-menu-wrap-"] > ul,
.ff-header--desktop .mega-menu {
	display: flex !important;
	flex-direction: row !important;
	flex-wrap: wrap;
	justify-content: center !important;
	align-items: center;
	gap: var(--wp--preset--spacing--5);
	margin: 0 !important;
	padding: 0 !important;
	list-style: none !important;
	width: 100%;
}
.ff-header--desktop [id^="mega-menu-wrap-"] [id^="mega-menu-"] > li.mega-menu-item,
.ff-header--desktop [id^="mega-menu-wrap-"] [id^="mega-menu-"] > li.mega-menu-item > a,
.ff-header--desktop [id^="mega-menu-wrap-"] [id^="mega-menu-"] li,
.ff-header--desktop [id^="mega-menu-wrap-"] li.mega-menu-item {
	margin-top: 0 !important;
	margin-bottom: 0 !important;
	margin-left: 0 !important;
	margin-right: 0 !important;
	padding-top: 0 !important;
	padding-bottom: 0 !important;
	display: inline-flex !important;
	align-items: center;
	height: auto !important;
	min-height: 0 !important;
	line-height: 1.286 !important;
	vertical-align: middle !important;
}

/* Hard 10px ceiling on the wrapper levels — no `<div id="mega-menu-wrap-X">`,
 * `<ul id="mega-menu-X">`, or column container is allowed to inject more
 * than 10px of vertical padding/margin. Belt-and-braces against the
 * plugin's auto-CSS regenerating with larger values when the user
 * tweaks Mega Menu theme settings.                                       */
.ff-header--desktop [id^="mega-menu-wrap-"],
.ff-header--desktop [id^="mega-menu-wrap-"] > [id^="mega-menu-"],
.ff-header--desktop [id^="mega-menu-wrap-"] [id^="mega-menu-"] > li.mega-menu-item {
	padding-top: 0 !important;
	padding-bottom: 0 !important;
	margin-top: 0 !important;
	margin-bottom: 0 !important;
}

/* ============================================================
 * Sledgehammer — match the plugin's EXACT ID-selector specificity so
 * we win without needing `!important` to do all the work, and force
 * a hard 27px pixel line-height/height. The plugin's auto-CSS hard-
 * codes `line-height: 60px; height: 60px` on `> a.mega-menu-link`,
 * which is the actual tall element creating the visible vertical
 * space — even with `padding: 0` everywhere else, a 60px-tall link
 * makes the row 60px tall.
 *
 * Selector specificity: `body.single … .ff-header--desktop
 * #mega-menu-wrap-max_mega_menu_1 #mega-menu-max_mega_menu_1 …` =
 * 2 IDs + 3 classes = (0,2,3,2), beating the plugin's (0,2,2,2).
 * `[id^=]` is used as a wildcard for any instance number.
 * ============================================================ */
body .ff-header--desktop [id^="mega-menu-wrap-"] [id^="mega-menu-"] > li.mega-menu-item > a.mega-menu-link,
html body .ff-header--desktop [id^="mega-menu-wrap-"] [id^="mega-menu-"] > li.mega-menu-item > a.mega-menu-link {
	line-height: 27px !important;
	height: 27px !important;
	min-height: 0 !important;
	max-height: 27px !important;
	padding: 0 16px !important;
	margin: 0 !important;
	display: inline-flex !important;
	align-items: center !important;
	box-sizing: content-box !important;
}

/* Anything inside the link (spans, description groups, indicator) — */
/* zero its margin/padding and force the same line-height.           */
body .ff-header--desktop [id^="mega-menu-wrap-"] [id^="mega-menu-"] a.mega-menu-link *,
body .ff-header--desktop [id^="mega-menu-wrap-"] [id^="mega-menu-"] li.mega-menu-item > a > span,
body .ff-header--desktop [id^="mega-menu-wrap-"] .mega-description-group,
body .ff-header--desktop [id^="mega-menu-wrap-"] .mega-menu-title {
	margin: 0 !important;
	padding: 0 !important;
	line-height: 27px !important;
	min-height: 0 !important;
}

/* Kill block-layout-flow margin between children of the nav row's
 * inner-container. WP injects
 *     :where(.is-layout-flow) > * + * { margin-block-start: <gap>; }
 * which adds spacing between consecutive children.                     */
.ff-header--desktop .ff-header__row--nav,
.ff-header--desktop .ff-header__row--nav > *,
.ff-header--desktop .ff-header__row--nav .wp-block-group__inner-container,
.ff-header--desktop .ff-header__row--nav .wp-block-group__inner-container > * {
	margin-top: 0 !important;
	margin-block-start: 0 !important;
	row-gap: 0 !important;
}

/* Brand-spec link styling — wins against plugin's
 * `#mega-menu-wrap-X #mega-menu-X > li.mega-menu-item > a.mega-menu-link`
 * by matching the same specificity (4 IDs/classes) plus our parent
 * `.ff-header--desktop` for the extra class weight, and reinforced
 * with `!important` because the plugin uses `!important` in places.
 *
 * Critical: the plugin hard-codes `line-height: 60px; height: 60px`
 * on these anchors which makes the row balloon. We force them to
 * collapse to the natural 27px line-height. */
.ff-header--desktop [id^="mega-menu-wrap-"] [id^="mega-menu-"] > li.mega-menu-item > a.mega-menu-link,
.ff-header--desktop [id^="mega-menu-wrap-"] [id^="mega-menu-"] > li.mega-menu-item > a.mega-menu-link:visited {
	font-family: var(--wp--preset--font-family--aeonik) !important;
	font-size: 1.3125rem !important;        /* 21px */
	font-weight: 400 !important;             /* Regular */
	line-height: 1.286 !important;            /* 27/21 */
	letter-spacing: 0.038em !important;       /* AV 38 */
	text-transform: uppercase !important;
	color: var(--wp--preset--color--fg) !important;       /* black default */
	background: transparent !important;
	border: 0 !important;
	padding: 0 var(--wp--preset--spacing--3) !important;
	height: auto !important;
	min-height: 0 !important;
	text-decoration: none !important;
	transition: color 150ms ease;
}
.ff-header--desktop [id^="mega-menu-wrap-"] [id^="mega-menu-"] > li.mega-menu-item > a.mega-menu-link:hover,
.ff-header--desktop [id^="mega-menu-wrap-"] [id^="mega-menu-"] > li.mega-menu-item > a.mega-menu-link:focus,
.ff-header--desktop [id^="mega-menu-wrap-"] [id^="mega-menu-"] > li.mega-menu-item.mega-toggle-on > a.mega-menu-link,
.ff-header--desktop [id^="mega-menu-wrap-"] [id^="mega-menu-"] > li.mega-menu-item.mega-current-menu-item > a.mega-menu-link {
	color: var(--wp--preset--color--accent) !important;   /* accent on hover/active */
	background: transparent !important;
	border: 0 !important;
	font-weight: 400 !important;
}

/* Hard override — Max Mega Menu's auto-generated <style> block uses
 * `#mega-menu-wrap-max_mega_menu_1 #mega-menu-max_mega_menu_1 > li > a`
 * which has 2-ID specificity (222 points). Our `[id^=]` selectors
 * only had class-level specificity, so the plugin's `color: #e91d88`
 * (hot pink) was winning despite our `!important`. Match the plugin's
 * exact selector pattern and add `html body` prefix to bump specificity
 * one notch above (234 vs 222).                                        */
html body .ff-header--desktop #mega-menu-wrap-max_mega_menu_1 #mega-menu-max_mega_menu_1 > li.mega-menu-item > a.mega-menu-link,
html body .ff-header--desktop #mega-menu-wrap-max_mega_menu_1 #mega-menu-max_mega_menu_1 > li.mega-menu-item > a.mega-menu-link:visited {
	color: var(--wp--preset--color--fg) !important;
	background: transparent !important;
	border: 0 !important;
	transition: color 150ms ease;
}
html body .ff-header--desktop #mega-menu-wrap-max_mega_menu_1 #mega-menu-max_mega_menu_1 > li.mega-menu-item > a.mega-menu-link:hover,
html body .ff-header--desktop #mega-menu-wrap-max_mega_menu_1 #mega-menu-max_mega_menu_1 > li.mega-menu-item > a.mega-menu-link:focus,
html body .ff-header--desktop #mega-menu-wrap-max_mega_menu_1 #mega-menu-max_mega_menu_1 > li.mega-menu-item.mega-toggle-on > a.mega-menu-link,
html body .ff-header--desktop #mega-menu-wrap-max_mega_menu_1 #mega-menu-max_mega_menu_1 > li.mega-menu-item.mega-current-menu-item > a.mega-menu-link {
	color: var(--wp--preset--color--accent) !important;
	background: transparent !important;
	border: 0 !important;
}

/* Drop the down-arrow indicator that the plugin appends after parent
 * items — the brand spec shows label-only nav. */
.ff-header--desktop [id^="mega-menu-wrap-"] [id^="mega-menu-"] li.mega-menu-item-has-children > a.mega-menu-link > span.mega-indicator {
	display: none !important;
}

/* ============================================================
 * `[ff_simple_menu id="X"]` shortcode — flat single-row WP nav menu
 * (depth=1) plus Fast Finder trigger button. Replaces both the older
 * `[preload-desktop-menu]` and `[menu_optimizer id=…]` paths now that
 * deep navigation moves to the AIEO Navigator command palette.
 *
 * Output structure:
 *   .ff-menu-strip (flex row, items + trigger)
 *     ul.ff-simple-menu (flex row of LIs, centered)
 *       li > a (the 7 marquee items)
 *     button.ff-fast-finder-trigger (icon + ⌘K kbd)
 * ============================================================ */
.ff-header--desktop .ff-menu-strip {
	display: flex;
	flex-direction: row;
	align-items: flex-start;       /* anchor button + ul at the strip's top
	                                  edge so the shorter menu ul doesn't
	                                  vertically-center against the taller
	                                  trigger button (which leaves the menu
	                                  letters floating mid-row). */
	justify-content: center;       /* whole group centered as one unit */
	gap: var(--wp--preset--spacing--4);
	width: 100%;
}
.ff-header--desktop .ff-simple-menu {
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: center;
	gap: var(--wp--preset--spacing--4);
	margin: 0;
	padding: 0;
	list-style: none;
	flex: 0 0 auto;                 /* don't grow — let the strip center */
	min-width: 0;
}
.ff-header--desktop .ff-simple-menu li {
	margin: 0;
	padding: 0;
	list-style: none;
	display: inline-flex;
	align-items: center;
}
.ff-header--desktop .ff-simple-menu li > a,
.ff-header--desktop .ff-simple-menu li > a:visited {
	font-family: var(--wp--preset--font-family--aeonik);
	font-size: 1.3125rem;          /* 21px */
	font-weight: 400;               /* Regular */
	line-height: 1.286;              /* 27/21 */
	letter-spacing: 0.038em;         /* AV 38 */
	text-transform: uppercase;
	color: var(--wp--preset--color--fg);
	background: transparent;
	border: 0;
	padding: 0 var(--wp--preset--spacing--3);
	text-decoration: none;
	transition: color 150ms ease;
}
.ff-header--desktop .ff-simple-menu li > a:hover,
.ff-header--desktop .ff-simple-menu li > a:focus,
.ff-header--desktop .ff-simple-menu li.current-menu-item > a,
.ff-header--desktop .ff-simple-menu li.current-menu-ancestor > a,
.ff-header--desktop .ff-simple-menu li.current-menu-parent > a {
	color: var(--wp--preset--color--accent);
}

/* Fast Finder trigger — magnifier icon + ⌘K (or Ctrl K) kbd badge.
 * Sits flush right inside the strip. Click + Ctrl+K both fire the
 * `aieo:navigator:open` custom event picked up by the AIEO Navigator
 * palette runtime. */
/* Trigger blends visually with menu items — same typography and color
 * tokens, no pill border. The kbd badge is the only visual cue that
 * signals "this opens via Ctrl+K". */
/* Trigger blends visually with menu items — same typography and color
 * tokens, no pill border. The button + its inner contents are all
 * centered vertically against the menu strip's flex line. */
.ff-header--desktop .ff-fast-finder-trigger {
	/* The button itself is centered against the menu strip's row by
	 * the parent's `align-items: center`. Inside the button, icon +
	 * label center against each other on the same flex line. */
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.4em;
	background: transparent;
	border: 0;
	margin: 0;
	padding: 0 var(--wp--preset--spacing--3);
	color: var(--wp--preset--color--fg);
	cursor: pointer;
	flex: 0 0 auto;
	transition: color 150ms ease;
	font-family: var(--wp--preset--font-family--aeonik);
	font-size: 1.3125rem;          /* 21px — sets the em unit for icon */
	line-height: 1.286;             /* match menu items */
	vertical-align: middle;
}
.ff-header--desktop .ff-fast-finder-trigger:hover,
.ff-header--desktop .ff-fast-finder-trigger:focus-visible {
	color: var(--wp--preset--color--accent);
	outline: none;
}
.ff-header--desktop .ff-fast-finder-icon {
	/* 1.3em ≈ 27px at 21px label font-size — slightly larger than the
	 * cap-height so the icon reads as the visual anchor of the trigger.
	 * `display: block` removes inline-baseline ghost descender so flex
	 * centering matches the geometric centre of the icon to the
	 * cap-height middle of the label. */
	width: 1.3em;
	height: 1.3em;
	display: block;
	flex: 0 0 auto;
	/* Lift the icon further up (-0.14em ≈ -3px at 21px) so its visual
	 * centre lands above the line's geometric centre — Aeonik's cap-
	 * height middle is ~50% of cap-height ≈ 35-40% from line top, well
	 * above the icon's own 50% midpoint. */
	transform: translateY(-0.14em);
}
.ff-header--desktop .ff-fast-finder-label {
	/* Inherits the button's font-size (21px) + line-height (1.286).
	 * Just set the brand-spec letter-spacing, weight, and case — no
	 * other typography overrides so the label centers cleanly with
	 * the icon on the same flex line. */
	font-weight: 400;
	letter-spacing: 0.038em;
	text-transform: uppercase;
	display: block;
	line-height: 1.286;
}
.ff-header--desktop .ff-kbd-hint {
	display: inline-flex;
	align-items: baseline;
	gap: 0.1em;
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: 0.6875rem;          /* 11px */
	font-weight: 500;
	line-height: 1;
	letter-spacing: 0.02em;
	color: inherit;
	background: var(--wp--preset--color--subtle);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 4px;
	padding: 0.2rem 0.35rem;
	white-space: nowrap;
}
.ff-fast-finder-trigger:hover .ff-kbd-hint,
.ff-fast-finder-trigger:focus-visible .ff-kbd-hint {
	border-color: var(--wp--preset--color--accent);
}

/* ============================================================
 * Menu Optimizer (`[menu_optimizer id="X"]` shortcode) — public
 * Oxford Metadata plugin output. Replaces the older om-desktop-menu
 * runtime; emits a clean `<ul class="ommo-menu">` instead of Mega
 * Menu's `<ul class="mega-menu">`, so brand.css needs its own rules
 * for this DOM shape. The plugin's own CSS uses `all: initial` on
 * `.ommo-safe-container` which neutralises inherited block-layout
 * styles; we re-style nav-strip semantics from there.
 *
 * Output structure:
 *   .ommo-safe-container.ommo-horizontal.ommo-menu-{id}
 *     #ommo-menu-wrap.ommo-menu-wrap[data-ommo-menu-id="{id}"]
 *       ul#ommo-menu.ommo-menu
 *         li[.menu-item-has-children]#menu-item-{ID}
 *           a[href]
 * ============================================================ */
.ff-header--desktop .ommo-safe-container {
	display: block !important;
	text-align: center;
}
.ff-header--desktop .ommo-menu-wrap {
	width: 100%;
	background: transparent;
}
.ff-header--desktop ul.ommo-menu,
.ff-header--desktop .ommo-menu-wrap > ul {
	display: flex !important;
	flex-direction: row !important;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: var(--wp--preset--spacing--5);
	margin: 0 !important;
	padding: 0 !important;
	list-style: none !important;
	width: 100%;
}
.ff-header--desktop .ommo-menu > li {
	margin: 0 !important;
	padding: 0 !important;
	list-style: none;
	display: inline-flex;
	align-items: center;
	min-height: 0;
	/* Containing block for `position: absolute` submenu — without this,
	 * the plugin's `.sub-menu { position:absolute; left:0; top:100% }` falls
	 * back to `.ommo-safe-container` (which is `position: relative`) and
	 * positions the dropdown at the left edge of the row instead of under
	 * the parent item.                                                    */
	position: relative;
}
/* Hide the `::after { content: "▾" }` arrow the plugin adds to every
 * parent item — brand spec is label-only nav. */
.ff-header--desktop .ommo-menu > li.menu-item-has-children > a::after,
.ff-header--desktop #ommo-menu li.menu-item-has-children > a::after {
	content: none !important;
	display: none !important;
}
/* Override the plugin's hard-coded `#ommo-menu > li > a` rules with our
 * brand spec. The plugin uses `!important` everywhere so we need same
 * specificity (1 ID + 2 classes/elements = 0,0,1,2) plus `!important`,
 * AND we need our rules later in source order than the plugin's CSS.
 * `.ff-header--desktop` prefix bumps specificity to (0,0,2,2 = 22) which
 * beats the plugin's (0,0,1,2 = 12).                                     */
.ff-header--desktop #ommo-menu > li > a {
	color: var(--wp--preset--color--fg) !important;
	font-family: var(--wp--preset--font-family--aeonik) !important;
	font-size: 1.3125rem !important;       /* 21px */
	font-weight: 400 !important;            /* Regular */
	line-height: 1.286 !important;           /* 27/21 */
	letter-spacing: 0.038em !important;      /* AV 38 */
	text-transform: uppercase !important;
	background: transparent !important;
	border: 0 !important;
	height: auto !important;
	padding: 0 var(--wp--preset--spacing--3) !important;
	transition: color 150ms ease !important;
}
.ff-header--desktop #ommo-menu > li > a:hover,
.ff-header--desktop #ommo-menu > li > a:focus,
.ff-header--desktop #ommo-menu > li.current-menu-item > a {
	color: var(--wp--preset--color--accent) !important;
	background: transparent !important;
}
/* Submenu (dropdown) styling — bring the plugin's logistics-menu defaults
 * into FF brand. Keep the plugin's `position: absolute; top: 100%`
 * positioning, only restyle visuals. */
.ff-header--desktop #ommo-menu ul.sub-menu {
	background: var(--wp--preset--color--bg) !important;
	border: 1px solid var(--wp--preset--color--border) !important;
	border-radius: 0 !important;
	box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08) !important;
	min-width: 240px !important;
	padding: var(--wp--preset--spacing--2) 0 !important;
}
.ff-header--desktop #ommo-menu ul.sub-menu li a {
	color: var(--wp--preset--color--fg) !important;
	font-family: var(--wp--preset--font-family--aeonik) !important;
	font-size: 0.9375rem !important;        /* 15px sub-link */
	font-weight: 400 !important;
	letter-spacing: 0.02em !important;
	padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--3) !important;
}
.ff-header--desktop #ommo-menu ul.sub-menu li a:hover,
.ff-header--desktop #ommo-menu ul.sub-menu li a:focus {
	color: var(--wp--preset--color--accent) !important;
	background: var(--wp--preset--color--subtle) !important;
}
/* Top-level link — brand spec: 21 Aeonik Regular, lh 27/21, AV 38,
 * uppercase, black default → accent on hover/focus/current.       */
.ff-header--desktop .ommo-menu > li > a,
.ff-header--desktop .ommo-menu > li > a:visited {
	font-family: var(--wp--preset--font-family--aeonik);
	font-size: 1.3125rem;
	font-weight: 400;
	line-height: 1.286;
	letter-spacing: 0.038em;
	text-transform: uppercase;
	color: var(--wp--preset--color--fg);
	background: transparent;
	border: 0;
	padding: 0 var(--wp--preset--spacing--3);
	text-decoration: none;
	transition: color 150ms ease;
	display: inline-flex;
	align-items: center;
}
.ff-header--desktop .ommo-menu > li > a:hover,
.ff-header--desktop .ommo-menu > li > a:focus,
.ff-header--desktop .ommo-menu > li.current-menu-item > a,
.ff-header--desktop .ommo-menu > li.current-menu-ancestor > a,
.ff-header--desktop .ommo-menu > li.current-menu-parent > a {
	color: var(--wp--preset--color--accent);
}

/* The plugin wraps the menu in `<div id="mega-menu-wrap-X">` which can
 * receive a background-color on desktop (transparent in our case),
 * but the auto-CSS may still set a non-zero min-height/padding. Reset. */
.ff-header--desktop [id^="mega-menu-wrap-"] {
	background: transparent !important;
	border-radius: 0 !important;
	min-height: 0 !important;
	padding: 0 !important;
	margin: 0 !important;
	width: 100%;
}

/* Inner wp-block-group container that wraps the shortcode output —
 * the WP block layout adds inner-container padding on some themes.
 * Zero it inside the nav row. */
.ff-header--desktop .ff-header__row--nav,
.ff-header--desktop .ff-header__row--nav > * {
	margin-block: 0 !important;
}

/* Announcement bar → header: kill the gap. The announcement block
 * may be wrapped in a group whose default block-spacing pushes the
 * header down. Force margin-top on the header to 0. */
.roosterx-header,
.roosterx-header--mobile,
.ff-header,
.ff-header--mobile,
.ff-header--desktop {
	margin-top: 0 !important;
}

/* Row 1 → Row 2 gap inside the desktop header. WP injects
 *     :where(.wp-block-group.is-layout-flow) > * + * {
 *       margin-block-start: var(--wp--style--block-gap);
 *     }
 * which is `--wp--preset--spacing--5` (~30-50px) by default — that's
 * the chunk between the row 1 black line and the menu strip. Zero it
 * for the desktop header so rows 1 and 2 sit flush. */
.ff-header--desktop > *,
.ff-header--desktop .ff-header__row + .ff-header__row,
.ff-header--desktop .ff-header__row--nav {
	margin-top: 0 !important;
	margin-block-start: 0 !important;
}

/* Breadcrumbs (`core/breadcrumbs`) — 11px per the brand spec. The
 * trail itself is trimmed in functions.php (Home + shop-archive
 * dropped) so it starts at the first real category. */
.wp-block-breadcrumbs,
.wp-block-breadcrumbs ol,
.wp-block-breadcrumbs li,
.wp-block-breadcrumbs a,
.wp-block-breadcrumbs span {
	font-size: 0.6875rem !important;   /* 11px */
	line-height: 1.4;
	letter-spacing: 0.038em;
}

/* `.ff-breadcrumb-row` — full-width strip between the header and main
 * content. Carries the same `spacing|6` left/right padding as the
 * desktop header (see parts/header.html → `.ff-header--desktop`), so
 * the breadcrumb's first crumb sits directly underneath the FEMME
 * FATALE logo. The breadcrumb itself is rendered LEFT-aligned + the
 * UA `<ol>` indent is cleared so nothing pushes the trail rightward.
 *
 * Mobile keeps a slimmer indent (`spacing|4`) to mirror the mobile
 * header padding. */
.ff-breadcrumb-row .wp-block-breadcrumbs {
	text-align: left;
}
.ff-breadcrumb-row .wp-block-breadcrumbs ol {
	margin-inline-start: 0;
	padding-inline-start: 0;
	list-style: none;
	justify-content: flex-start;
}
@media (max-width: 1023px) {
	.ff-breadcrumb-row {
		padding-left: var(--wp--preset--spacing--4) !important;
		padding-right: var(--wp--preset--spacing--4) !important;
	}
}

/* ============================================================
 * Product archive — sidebar (FiboFilters) + 3-column grid.
 *
 * Template: roosterx-ff/templates/archive-product.html overrides the
 * parent's 4-column layout. Left column = `.fibofilters-vertical-filters-container`
 * (auto-populated by FiboFilters Pro). Right column = product grid set
 * to columns:3 in the block markup.
 *
 * Mobile: single column — FiboFilters has its own mobile drawer pattern,
 * so we hide the sidebar on small screens; the plugin's
 * `.fibofilters-mobile-filters-container` (if rendered elsewhere) handles
 * the responsive case.
 * ============================================================ */
.ff-archive-layout {
	gap: var(--wp--preset--spacing--5);
}
.ff-archive-sidebar {
	flex: 0 0 260px;
	min-width: 0;
}
.ff-archive-results {
	flex: 1 1 auto;
	min-width: 0;
}

/* FiboFilters Pro layout — we keep `filter_location = sidebar` so
 * the plugin's in-place AJAX product re-render keeps working (filter
 * changes don't trigger a full page reload). In sidebar mode the
 * plugin auto-injects extra placeholder containers around the WC
 * product-collection block — `horizontal`, `mobile`, plus a second
 * `applied-filters-container` — that React renders the SAME chip
 * row into via createPortal. Visible result: duplicate chip rows
 * above the grid. The plugin can't suppress these per-position in
 * sidebar mode, so we hide them via CSS. The portals still mount
 * into the hidden containers (DOM is intact), so AJAX behaviour is
 * preserved — only the visual duplicate goes away.
 *
 * The sidebar `[fibofilters]` shortcode emits its own
 * `applied-filters-container` AND `vertical-filters-container`, so
 * the chips show in the sidebar; the auto-injected ones above the
 * grid are pure noise.
 *
 * Wrapper classes per archive (ALL of them are block-themed and use
 * wp:woocommerce/product-collection — they only differ by the class
 * on the column that wraps the collection):
 *   .ff-archive-results          → /shop/, /product-category/, /product-tag/
 *                                  (template: archive-product.html)
 *   .aieo-brand-archive-main     → /brand/<slug>/
 *                                  (template: taxonomy-product_brand.html →
 *                                   pattern: aieo/brand-archive-page)
 *   .aieo-tax-archive-main       → /need/<slug>/, /product-tag/<slug>/
 *                                  (templates: taxonomy-pa_need.html,
 *                                   taxonomy-product_tag.html → pattern:
 *                                   aieo/taxonomy-archive-page)
 *   [data-block-name="woocommerce/product-collection"] → catch-all for
 *     any future pattern that drops product-collection at the root of
 *     a block-themed template without one of the wrappers above. */
.ff-archive-results > .fibofilters-horizontal-filters-container,
.ff-archive-results > .fibofilters-mobile-filters-container,
.ff-archive-results > .fibofilters-applied-filters-container,
.ff-archive-results > .fibofilters-show-previous-button-container,
.aieo-brand-archive-main > .fibofilters-horizontal-filters-container,
.aieo-brand-archive-main > .fibofilters-mobile-filters-container,
.aieo-brand-archive-main > .fibofilters-applied-filters-container,
.aieo-brand-archive-main > .fibofilters-show-previous-button-container,
.aieo-tax-archive-main > .fibofilters-horizontal-filters-container,
.aieo-tax-archive-main > .fibofilters-mobile-filters-container,
.aieo-tax-archive-main > .fibofilters-applied-filters-container,
.aieo-tax-archive-main > .fibofilters-show-previous-button-container,
[data-block-name="woocommerce/product-collection"] > .fibofilters-horizontal-filters-container,
[data-block-name="woocommerce/product-collection"] > .fibofilters-mobile-filters-container,
[data-block-name="woocommerce/product-collection"] > .fibofilters-applied-filters-container,
[data-block-name="woocommerce/product-collection"] > .fibofilters-show-previous-button-container {
	display: none !important;
}
@media (max-width: 781px) {
	.ff-archive-layout {
		display: block;
	}
	.ff-archive-sidebar {
		display: none;
	}
}

/* ────────────────────────────────────────────────────────────────
 * Sticky-scroll sidebar (desktop ≥1025px).
 *
 * The sidebar carries FiboFilters (price, brand, attribute facets) +
 * "From the Blog" cards + "Other brands you love" — easily 800–1200px
 * of stacked content. Without a sticky container the user has to
 * scroll the entire 12-product grid to reach the related-blog rail
 * at the bottom of the sidebar. Fix: pin the sidebar to the viewport
 * and let it scroll internally.
 *
 * Three column classes share this behaviour:
 *   .aieo-brand-archive-sidebar  → /brand/<slug>/  (brand-archive-page.php)
 *   .ff-archive-sidebar          → /shop/, /product-category/  (archive-product.html)
 *   .aieo-tax-archive-sidebar    → /need/, /product-tag/  (taxonomy-archive-page.php)
 *
 * Required quirks:
 *   `align-self: flex-start` — WP columns use `align-items: stretch`
 *     by default, which forces children to the row's full height.
 *     Sticky positioning is INERT inside a stretched flex item, so
 *     the column must opt out of stretching for sticky to engage.
 *   `top: 1rem` — small offset from the viewport top; if you have a
 *     pinned header bar in future, raise this to its height.
 *   `overscroll-behavior: contain` — prevents scroll-chaining (when
 *     the sidebar bottoms out, the body shouldn't start scrolling).
 *   `scrollbar-gutter: stable` — reserves the scrollbar's space so
 *     the sidebar layout doesn't reflow when the scrollbar appears.
 * ──────────────────────────────────────────────────────────────── */
@media (min-width: 1025px) {
	.aieo-brand-archive-sidebar,
	.ff-archive-sidebar,
	.aieo-tax-archive-sidebar {
		position: sticky;
		top: 1rem;
		align-self: flex-start;
		max-height: calc(100vh - 2rem);
		overflow-y: auto;
		overscroll-behavior: contain;
		scrollbar-gutter: stable;
		padding-right: 0.5rem;
	}

	/* WP admin bar (32px on desktop) is `position: fixed; top: 0`
	 * — sticky elements with `top: 0` (or `top: 1rem`) stick to
	 * viewport top BEHIND the bar. Push the sticky-top below the
	 * bar AND shrink the available max-height to match. WP's mobile
	 * admin bar (46px) is handled in the mobile media query below. */
	body.admin-bar .aieo-brand-archive-sidebar,
	body.admin-bar .ff-archive-sidebar,
	body.admin-bar .aieo-tax-archive-sidebar {
		top: calc(32px + 1rem);
		max-height: calc(100vh - 32px - 2rem);
	}

	/* Slim, theme-tinted scrollbar for the sidebar's internal scroll.
	 * Native UA scrollbars work fine; this is just a polish step so
	 * the scrollbar doesn't look like a foreign system widget on the
	 * Femme Fatale palette. */
	.aieo-brand-archive-sidebar::-webkit-scrollbar,
	.ff-archive-sidebar::-webkit-scrollbar,
	.aieo-tax-archive-sidebar::-webkit-scrollbar {
		width: 6px;
	}
	.aieo-brand-archive-sidebar::-webkit-scrollbar-thumb,
	.ff-archive-sidebar::-webkit-scrollbar-thumb,
	.aieo-tax-archive-sidebar::-webkit-scrollbar-thumb {
		background: rgba(0, 0, 0, 0.2);
		border-radius: 3px;
	}
	.aieo-brand-archive-sidebar::-webkit-scrollbar-thumb:hover,
	.ff-archive-sidebar::-webkit-scrollbar-thumb:hover,
	.aieo-tax-archive-sidebar::-webkit-scrollbar-thumb:hover {
		background: rgba(0, 0, 0, 0.35);
	}
}

/* ─────────────────────────────────────────────────────────────────
 * Newsletter signup (TNP) — Femme Fatale brand override.
 *
 * The parent rooster theme styles `.tnp-submit` with the foreground
 * (near-black) colour, which reads heavy on the FF muted-blue card
 * background and clashes with the accent-coloured privacy link
 * sitting right above it. Switching to the `.aieo-category-chip`
 * pattern — accent-coloured outline, accent-fill on hover, square
 * corners — keeps the brand voice consistent with the subcategory
 * chips on product archives + the GF submit button on the thank-you
 * page.
 *
 * Override is scoped to `.newsletter-banner` so other TNP forms
 * elsewhere on the site (if any) keep the rooster default.
 * Specificity is high enough to win without `!important`, but kept
 * for the colour properties that the parent declares with explicit
 * fallbacks. */
/* Firstname / surname inputs — parent only styled .tnp-email with a
 * white background, so the name fields inherit the card background
 * and read as muted-grey rectangles on FF. Bring them in line with
 * the email input. Same selectors the parent uses for .tnp-email,
 * extended to .tnp-name and .tnp-surname. */
.newsletter-banner .newsletter-form .tnp-name,
.newsletter-banner .newsletter-form .tnp-surname {
	width: 100%;
	box-sizing: border-box;
	padding: 10px 12px;
	border: 1px solid rgba( 0, 0, 0, 0.15 );
	background: #fff;
	font-size: 14px;
}

.newsletter-banner .newsletter-form .tnp-submit {
	background: transparent !important;
	color: var( --wp--preset--color--accent, #F46767 ) !important;
	border-color: var( --wp--preset--color--accent, #F46767 ) !important;
	border-radius: 0;
	font-weight: 400;
	letter-spacing: normal;
	text-transform: none;
}
.newsletter-banner .newsletter-form .tnp-submit:hover,
.newsletter-banner .newsletter-form .tnp-submit:focus-visible {
	background: var( --wp--preset--color--accent, #F46767 ) !important;
	color: #ffffff !important;
	border-color: var( --wp--preset--color--accent, #F46767 ) !important;
	outline: none;
}

/* ============================================================
 * Footer breathing room — keep the page content from butting up
 * against the newsletter banner (the first block in parts/footer.html).
 * Templates render the footer via
 *   <!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->
 * which produces <footer class="wp-block-template-part">.
 * 80px on desktop, halved on phones.
 * ============================================================ */
footer.wp-block-template-part {
	margin-top: 40px;
}
@media (min-width: 768px) {
	footer.wp-block-template-part {
		margin-top: 80px;
	}
}


/* ============================================================
 * Gravity Forms — global overflow protection.
 * GF's default `gform-field-label--type-inline` + `display: inline-block`
 * lets fields and Rank/Survey choices grow to their content width,
 * triggering horizontal page scroll whenever a label is long (Greek text
 * routinely overflows the column on narrow viewports). The same fix was
 * scoped to `.roosterx-ff-thankyou-survey` for the post-purchase survey
 * — this version applies it to EVERY Gravity Forms instance on the site,
 * so the customer-feedback-form / contact form / any future GF embed
 * inherits the protection without needing per-page CSS.
 * ============================================================ */
.gform_wrapper .gfield,
.gform_wrapper .ginput_container {
	width: 100% !important;
	max-width: 100% !important;
	box-sizing: border-box !important;
}
.gform_wrapper .gsurvey-rank {
	list-style: none !important;
	margin: 0 !important;
	padding: 0 !important;
	display: flex !important;
	flex-direction: column !important;
	gap: 6px !important;
	width: 100% !important;
	max-width: 100% !important;
	box-sizing: border-box !important;
}
.gform_wrapper .gsurvey-rank .gsurvey-rank-choice {
	display: block !important;
	position: relative !important;
	width: 100% !important;
	max-width: 100% !important;
	box-sizing: border-box !important;
	white-space: normal !important;
	overflow-wrap: anywhere;
	word-break: break-word;
}
/* Defensive: any GF descendant that GF declares as inline-block tends
 * to spill on narrow viewports. Force them to honour their parent's
 * max-width without changing their flow type more than necessary. */
.gform_wrapper * {
	max-width: 100%;
	box-sizing: border-box;
}
/* Form rows / sections — keep horizontal scroll out of the wrapper
 * itself even if a single child manages to escape these guards. */
.gform_wrapper {
	overflow-x: hidden;
}



