/*
Theme Name: Aura Maison
Description: Lightweight custom WordPress theme for the Aura Maison ecommerce storefront.
Version: 0.6.3
Text Domain: aura-maison
*/

/*
Base typography and global style foundations are implemented here and in
theme.json. Header, footer, navigation, homepage, and storefront/product
layout are implemented in later scoped tasks.
*/

/* Box sizing */

*,
*::before,
*::after {
	box-sizing: border-box;
}

/* Responsive images */

img {
	display: block;
	max-width: 100%;
	height: auto;
}

/* Typography role classes (visual roles, not HTML semantics) */

.aura-type-display {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--display);
	font-weight: 400;
	line-height: 1.1;
}

.aura-type-h1 {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--heading-1);
	font-weight: 400;
	line-height: 1.15;
}

.aura-type-h2 {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--heading-2);
	font-weight: 400;
	line-height: 1.2;
}

.aura-type-h3 {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--heading-3);
	font-weight: 400;
	line-height: 1.3;
}

.aura-type-section-label {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--section-label);
	font-weight: 500;
	line-height: 1.4;
	letter-spacing: 0.06em;
}

.aura-type-body-large {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--body-large);
	font-weight: 400;
	line-height: 1.6;
}

.aura-type-body {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--body);
	font-weight: 400;
	line-height: 1.6;
}

.aura-type-body-small {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--body-small);
	font-weight: 400;
	line-height: 1.5;
}

.aura-type-ui {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--ui);
	font-weight: 500;
	line-height: 1;
	letter-spacing: 0.02em;
}

.aura-type-caption {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--caption);
	font-weight: 400;
	line-height: 1.4;
	letter-spacing: 0.03em;
}

/* Desktop typography overrides (approved two-step breakpoint, 1024px only) */

@media (min-width: 1024px) {
	:root {
		--wp--preset--font-size--heading-2: 2rem;
		--wp--preset--font-size--heading-3: 1.5rem;
		--wp--preset--font-size--section-label: 0.9375rem;
	}
}

/* Editorial/content links only — navigation and component links are deferred */

.entry-content a,
.wp-block-post-content a {
	color: var(--wp--preset--color--espresso);
	text-decoration: underline;
}

/* Secondary text utility */

.aura-text-secondary {
	color: var(--wp--preset--color--warm-gray);
}

/* Reduced motion baseline */

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

/* ==========================================================================
   Skip link
   ========================================================================== */

.aura-skip-link {
	position: absolute;
	top: -100%;
	left: 0;
	z-index: 100;
	padding: 8px 16px;
	background-color: var(--wp--preset--color--espresso);
	color: var(--wp--preset--color--soft-white);
	font-family: var(--wp--preset--font-family--body);
	text-decoration: none;
}

.aura-skip-link:focus {
	top: 0;
}

/* ==========================================================================
   Storefront structural shell (1440px max, approved responsive gutters)
   ========================================================================== */

.aura-shell {
	max-width: 1440px;
	margin-left: auto;
	margin-right: auto;
	padding-left: 16px;
	padding-right: 16px;
}

@media (min-width: 768px) {
	.aura-shell {
		padding-left: 24px;
		padding-right: 24px;
	}
}

@media (min-width: 1024px) {
	.aura-shell {
		padding-left: 32px;
		padding-right: 32px;
	}
}

@media (min-width: 1440px) {
	.aura-shell {
		padding-left: 48px;
		padding-right: 48px;
	}
}

/* ==========================================================================
   Announcement bar
   ========================================================================== */

.aura-announcement-bar {
	background-color: var(--wp--preset--color--espresso);
}

.aura-announcement-bar p {
	margin: 0;
	padding: 8px 16px;
	color: var(--wp--preset--color--soft-white);
	text-align: center;
}

/* ==========================================================================
   Site header
   ========================================================================== */

.aura-site-header {
	background-color: var(--wp--preset--color--soft-white);
	border-bottom: 1px solid var(--wp--preset--color--soft-border);
}

/* minmax(0, 1fr), not plain 1fr (Task 12D-R1D): same content-based grid
   track blowout hazard already fixed elsewhere in this file, applied here
   defensively since this header renders on every page. */
.aura-site-header__inner {
	display: grid;
	grid-template-columns: minmax( 0, 1fr ) auto minmax( 0, 1fr );
	align-items: center;
	column-gap: 16px;
	min-height: 64px;
}

.aura-site-header__left {
	justify-self: start;
	display: flex;
	align-items: center;
	gap: 24px;
}

.aura-site-header__logo {
	justify-self: center;
	text-align: center;
}

.aura-site-header__cart {
	justify-self: end;
	display: flex;
	align-items: center;
}

@media (min-width: 1024px) {
	.aura-site-header__inner {
		min-height: 88px;
		grid-template-columns: minmax( 0, 1fr ) auto minmax( 0, 1fr );
		grid-template-areas: "logo nav cart";
	}

	/* DEC-025: logo left, cart right. DEC-026: navigation geometrically
	   centered, not positioned immediately next to the logo. */
	.aura-site-header__logo {
		grid-area: logo;
		justify-self: start;
		text-align: left;
	}

	.aura-site-header__left {
		grid-area: nav;
		justify-self: center;
	}

	.aura-site-header__cart {
		grid-area: cart;
		justify-self: end;
	}
}

/* Logo / site title */

.aura-site-header__logo img {
	max-width: 160px;
	width: auto;
	height: auto;
}

.aura-site-header__site-title {
	color: var(--wp--preset--color--espresso);
	text-decoration: none;
}

/* Desktop navigation */

.aura-nav-desktop {
	display: none;
}

.aura-nav-desktop__list {
	display: flex;
	align-items: center;
	gap: 24px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.aura-nav-desktop__list a {
	color: var(--wp--preset--color--espresso);
	text-decoration: none;
}

@media (min-width: 1024px) {
	.aura-nav-desktop {
		display: flex;
	}
}

/* Cart */

.aura-cart-link {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	color: var(--wp--preset--color--espresso);
	text-decoration: none;
}

.aura-cart-link__badge {
	position: absolute;
	top: 4px;
	right: 4px;
	min-width: 16px;
	height: 16px;
	padding: 0 4px;
	border-radius: 999px;
	background-color: var(--wp--preset--color--espresso);
	color: var(--wp--preset--color--soft-white);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--caption);
	line-height: 16px;
	text-align: center;
}

/* Mobile menu trigger */

.aura-menu-trigger {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 0;
	background: none;
	color: var(--wp--preset--color--espresso);
	cursor: pointer;
}

@media (min-width: 1024px) {
	.aura-menu-trigger {
		display: none;
	}
}

/* Shared focus treatment for new shell interactive elements */

.aura-menu-trigger:focus-visible,
.aura-menu-close:focus-visible,
.aura-cart-link:focus-visible,
.aura-nav-desktop__list a:focus-visible,
.aura-nav-mobile__list a:focus-visible,
.aura-site-footer__menu a:focus-visible,
.aura-site-header__site-title:focus-visible,
.aura-button:focus-visible,
.aura-univers__card-link:focus-visible,
.aura-featured-products__media-link:focus-visible,
.aura-featured-products__name-link:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

/* ==========================================================================
   Mobile full-screen menu
   ========================================================================== */

.aura-mobile-menu {
	position: fixed;
	inset: 0;
	z-index: 200;
	background-color: var(--wp--preset--color--warm-ivory);
	overflow-y: auto;
	opacity: 0;
	visibility: hidden;
	transition: opacity 250ms ease;
}

.aura-mobile-menu.is-open {
	opacity: 1;
	visibility: visible;
}

@media (min-width: 1024px) {
	.aura-mobile-menu {
		display: none !important;
	}
}

/* WordPress admin-bar compatibility: when logged in, begin the fixed overlay
   below the visible toolbar instead of the true viewport top, using the same
   two heights WordPress core's #wpadminbar actually uses at runtime (46px at
   its own <=782px breakpoint, 32px above it). Logged-out layout is untouched. */
body.admin-bar .aura-mobile-menu {
	top: 46px;
}

@media screen and (min-width: 783px) {
	body.admin-bar .aura-mobile-menu {
		top: 32px;
	}
}

.aura-mobile-menu__inner {
	padding-top: 24px;
	padding-bottom: 24px;
}

.aura-menu-close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	margin-left: auto;
	border: 0;
	background: none;
	color: var(--wp--preset--color--espresso);
	cursor: pointer;
}

.aura-nav-mobile__list {
	margin: 32px 0 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.aura-nav-mobile__list a {
	display: block;
	min-height: 44px;
	padding: 12px 0;
	color: var(--wp--preset--color--espresso);
	text-decoration: none;
}

body.aura-menu-open {
	overflow: hidden;
}

/* ==========================================================================
   Footer
   ========================================================================== */

.aura-site-footer {
	background-color: var(--wp--preset--color--linen-beige);
	border-top: 1px solid var(--wp--preset--color--soft-border);
}

.aura-site-footer__inner {
	display: grid;
	grid-template-columns: 1fr;
	gap: 28px;
	max-width: 1140px;
	margin-inline: auto;
	padding-top: 40px;
	padding-bottom: 28px;
}

/* Brand area: native custom logo (Task 12E-R1) — same markup/behavior as
   the header's own the_custom_logo() call. Restrained, premium sizing;
   never stretched/cropped. */
.aura-site-footer__group--brand .custom-logo {
	display: block;
	width: auto;
	height: auto;
	max-width: 120px;
}

.aura-site-footer__brand-link {
	display: inline-block;
	color: var(--wp--preset--color--espresso);
	text-decoration: none;
}

@media (min-width: 768px) {
	.aura-site-footer__inner {
		grid-template-columns: repeat( 2, minmax( 0, 1fr ) );
	}

	/* Let the Boutique top-level footer-menu item become its own grid
	   item, alongside Brand and the theme-owned Contact column. The <nav>
	   landmark wrapper must also be display:contents so its child <ul>
	   can "promote" the <li> directly into the grid. Brand takes its own
	   full-width row above Boutique/Contact at this width. */
	.aura-site-footer__nav,
	.aura-site-footer__menu {
		display: contents;
	}

	.aura-site-footer__group--brand {
		grid-column: 1 / -1;
	}
}

@media (min-width: 1024px) {
	/* Task 12E-R1-FIX1: a compact, intentional 3-column grid (Brand |
	   Boutique | Contact) contained by .aura-site-footer__inner's own
	   ~1140px max-width above — replaces the previous edge-to-edge
	   `justify-content: space-between` flex row, which read as excessive
	   central whitespace once the columns were pushed to the far left/
	   right of the full 1440px shell. Fractional sizing keeps the three
	   areas visually related rather than stretched apart. */
	.aura-site-footer__inner {
		display: grid;
		grid-template-columns: 1.2fr 1fr 1.1fr;
		align-items: start;
		gap: 40px;
	}

	.aura-site-footer__group--brand {
		grid-column: auto;
	}

	.aura-site-footer__group--brand .custom-logo {
		max-width: 160px;
	}
}

.aura-site-footer__menu {
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: 24px;
}

.aura-site-footer__menu > li {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

/* Top-level footer menu items (Boutique, Contact) are real native links to
   their own Page (Shop, Contact respectively) — Section Label role. Native
   wp_nav_menu() output only, no custom walker or invented content. */
.aura-site-footer__menu > li > a {
	display: block;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--section-label);
	font-weight: 500;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--espresso);
	text-decoration: none;
}

.aura-site-footer__menu > li > a:hover {
	color: var(--wp--preset--color--deep-taupe);
}

/* Child links within a footer group (Body Small) — Boutique's own
   Parures de lit / Bain / À propos. flex-wrap + a forced 100% basis keeps
   each on its own line (their combined content width would otherwise fit
   several per row in a plain flex-wrap container). */
.aura-site-footer__menu .sub-menu {
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.aura-site-footer__menu .sub-menu > li {
	flex: 1 0 100%;
}

.aura-site-footer__menu .sub-menu a {
	display: block;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--body-small);
	font-weight: 400;
	color: var(--wp--preset--color--espresso);
	text-decoration: none;
	overflow-wrap: anywhere;
}

.aura-site-footer__menu .sub-menu a:hover {
	color: var(--wp--preset--color--deep-taupe);
}

.aura-site-footer__menu .sub-menu a:focus-visible,
.aura-site-footer__menu > li > a:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

/* Contact column (Task 12E-R1-FIX1): theme-owned structural markup, not a
   menu — phone/e-mail must render as plain non-interactive text, which a
   native nav menu item cannot express. Heading mirrors Boutique's own
   top-level Section Label treatment for visual consistency. */
.aura-site-footer__contact {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.aura-site-footer__contact-heading {
	display: block;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--section-label);
	font-weight: 500;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--espresso);
	text-decoration: none;
}

a.aura-site-footer__contact-heading:hover {
	color: var(--wp--preset--color--deep-taupe);
}

a.aura-site-footer__contact-heading:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

.aura-site-footer__contact-detail {
	margin: 0;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--body-small);
	font-weight: 400;
	color: var(--wp--preset--color--espresso);
	overflow-wrap: anywhere;
}

.aura-site-footer__social {
	display: flex;
	gap: 8px;
	margin-top: 4px;
}

/* Instagram/Facebook (Task 12E-R1, restructured 12E-R1-FIX1): plain literal
   links in footer.php (no longer native menu items, so phone/e-mail above
   could become plain text instead) carrying the same identification
   classes and CSS mask-icon technique as before — an empty anchor, `aria-
   label` supplies its accessible name, a small monochrome inline-SVG mask
   icon (currentColor, no brand colors/gradients) is the only visible
   content. No icon font, no external framework. */
.aura-footer-social {
	display: inline-block;
	position: relative;
	width: 44px;
	height: 44px;
	color: var(--wp--preset--color--espresso);
}

.aura-footer-social::before {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate( -50%, -50% );
	width: 22px;
	height: 22px;
	background-color: currentColor;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-size: contain;
	mask-size: contain;
}

.aura-footer-social--instagram::before {
	-webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIxLjYiPjxyZWN0IHg9IjMiIHk9IjMiIHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCIgcng9IjUiLz48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSI0LjIiLz48Y2lyY2xlIGN4PSIxNy4zIiBjeT0iNi43IiByPSIwLjkiIGZpbGw9ImJsYWNrIiBzdHJva2U9Im5vbmUiLz48L3N2Zz4K");
	mask-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIxLjYiPjxyZWN0IHg9IjMiIHk9IjMiIHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCIgcng9IjUiLz48Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSI0LjIiLz48Y2lyY2xlIGN4PSIxNy4zIiBjeT0iNi43IiByPSIwLjkiIGZpbGw9ImJsYWNrIiBzdHJva2U9Im5vbmUiLz48L3N2Zz4K");
}

.aura-footer-social--facebook::before {
	-webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIxLjgiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0iTTE1LjUgOC41aC0yLjJjLTEgMC0xLjYuNi0xLjYgMS42VjExaDMuNmwtLjQgM2gtMy4ydjdoLTN2LTdIN3YtM2gxLjlWOS43YzAtMi41IDEuNS00IDQtNGgyLjZ2Mi44WiIvPjwvc3ZnPgo=");
	mask-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIxLjgiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0iTTE1LjUgOC41aC0yLjJjLTEgMC0xLjYuNi0xLjYgMS42VjExaDMuNmwtLjQgM2gtMy4ydjdoLTN2LTdIN3YtM2gxLjlWOS43YzAtMi41IDEuNS00IDQtNGgyLjZ2Mi44WiIvPjwvc3ZnPgo=");
}

.aura-footer-social:hover {
	color: var(--wp--preset--color--deep-taupe);
}

.aura-footer-social:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

.aura-site-footer__legal {
	border-top: 1px solid var(--wp--preset--color--soft-border);
	padding-top: 14px;
	padding-bottom: 14px;
}

.aura-site-footer__legal p {
	margin: 0;
	color: var(--wp--preset--color--espresso);
}

/* ==========================================================================
   Homepage — fixed six-section structure per DEC-028, visually refined per
   DEC-029 (first real desktop 07E review): Hero centered/contained and
   shorter, Trust strip attached directly below Hero, tighter overall rhythm.
   ========================================================================== */

/* Task 07E1-R5: unified outer homepage canvas. Every direct child section
   (Hero, Trust, Nos univers, Featured, Wish Flower, Brand) now shares one
   centered ~1440px page perimeter — sections/backgrounds no longer stretch
   independently to the raw viewport edge at wide viewports / browser
   zoom-out. Existing narrower internal widths (Hero's own 1440 cap, the
   ~1040px Nos Univers grid, Wish Flower's own composition, Brand's 720px
   reading measure) are unaffected — this only sets the outer ceiling they
   already sit inside. */
.aura-homepage {
	width: 100%;
	max-width: 1440px;
	margin-inline: auto;
}

.aura-homepage > section {
	padding-top: var(--wp--preset--spacing--48);
	padding-bottom: var(--wp--preset--spacing--48);
}

@media (min-width: 1024px) {
	.aura-homepage > section {
		padding-top: var(--wp--preset--spacing--64);
		padding-bottom: var(--wp--preset--spacing--64);
	}
}

/* Real interactive CTA (Hero, Wish Flower) — native taxonomy destination,
   Task 07D4A. */
.aura-button {
	display: inline-block;
	padding: 12px 24px;
	background-color: var(--wp--preset--color--espresso);
	color: var(--wp--preset--color--soft-white);
	text-decoration: none;
}

/* Only ever reachable on the Contact form's <button> (the only .aura-button
   that is a real <button>, not an <a>) — inert everywhere else. */
.aura-button:disabled {
	opacity: 0.6;
	cursor: not-allowed;
}

/* Restrained secondary treatment (Brand editorial CTA) — deliberately
   quieter than the solid primary style above so it doesn't compete with the
   Hero's primary CTA. Reuses the existing Espresso token only. */
.aura-button--secondary {
	background-color: transparent;
	color: var(--wp--preset--color--espresso);
	border: 1px solid var(--wp--preset--color--espresso);
}

/* -- 1. Hero --------------------------------------------------------------- */

.aura-hero {
	position: relative;
	padding-top: 0;
	padding-bottom: 0;
}

.aura-hero__media img {
	width: 100%;
	height: auto;
}

.aura-hero__content {
	padding-top: var(--wp--preset--spacing--32);
	padding-bottom: var(--wp--preset--spacing--32);
}

.aura-hero__text {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--wp--preset--spacing--16);
	max-width: 640px;
}

/* Task 07E2B-R1: below 1024, the same specificity bug documented above for
   .aura-trust also affects .aura-hero — .aura-homepage > section (0,0,1,1)
   outranks the plain .aura-hero { padding-top: 0; padding-bottom: 0; }
   (0,0,1,0) above, silently reinstating the generic 48px section padding as
   real, visible blank space above the Hero image and below the Hero content
   (both children are in normal flow below 1024, unlike the absolutely
   positioned desktop layout, which is why this was invisible at >=1024).
   Matching the parent's own compound selector — the same fix already used
   for .aura-trust — wins the cascade without touching the locked >=1024
   rules below. Scoped to max-width so the locked desktop baseline cannot be
   affected even if this reasoning were wrong. */
@media (max-width: 1023px) {
	.aura-homepage > .aura-hero {
		padding-top: 0;
		padding-bottom: 0;
	}

	/* Task 07E2B-R1: .aura-hero__text is a flex column, so its H1/P children's
	   default UA margins stack additively on top of the explicit 16px gap
	   (flex items never collapse margins) — the same class of bug fixed for
	   the Brand editorial content stack in Task 07E1-R6D. Reset only these
	   two component-local elements below 1024 so the flex gap is the sole
	   spacing mechanism; the already-approved >=1024 layout is untouched. */
	.aura-hero__heading,
	.aura-hero__copy {
		margin: 0;
	}
}

@media (min-width: 1024px) {
	/* DEC-029 §B: horizontally centered, controlled wide canvas (~1440px
	   storefront scale) with an explicit reduced desktop height, replacing
	   the previous full-bleed 100vw / aspect-ratio-driven geometry that
	   rendered as an oversized, left-anchored block on wide viewports. */
	.aura-hero {
		max-width: 1440px;
		margin-inline: auto;
		height: clamp( 500px, 40vw, 620px );
		overflow: hidden;
	}

	.aura-hero__media {
		position: absolute;
		inset: 0;
	}

	.aura-hero__media img {
		width: 150%;
		height: 100%;
		object-fit: cover;
		object-position: center;
	}

	.aura-hero__content {
		position: absolute;
		left: 0;
		right: 0;
		top: 50%;
		transform: translateY(-50%);
		padding-top: 0;
		padding-bottom: 0;
	}

	.aura-hero__text {
		position: relative;
		padding: var(--wp--preset--spacing--32);
		background: linear-gradient( 100deg, rgba( 252, 250, 247, 0.88 ) 0%, rgba( 252, 250, 247, 0.6 ) 70%, rgba( 252, 250, 247, 0 ) 100% );
	}
}

/* -- 2. Trust / value reassurance strip (DEC-029 §C/§D) ---------------------- */

.aura-trust {
	background-color: var(--wp--preset--color--warm-ivory);
	padding-top: var(--wp--preset--spacing--12);
	padding-bottom: var(--wp--preset--spacing--12);
}

/* Task 07E1-R5: real root cause of "no visible height change" across every
   previous attempt — .aura-homepage > section (a class + an element-type
   selector, specificity 0,0,1,1) has strictly higher specificity than
   .aura-trust alone (a single class, specificity 0,0,1,0). The generic
   48px/64px section padding was therefore winning over whatever value was
   written on .aura-trust every time, regardless of source order. Matching
   the parent's own compound selector is what actually wins the cascade. */
.aura-homepage > .aura-trust {
	padding-top: var(--wp--preset--spacing--12);
	padding-bottom: var(--wp--preset--spacing--12);
}

/* Task 07E1-R4: dedicated centered wrapper, decoupled from .aura-shell.
   Root cause of the "Trust drifts left while Hero stays centered" bug:
   .aura-shell (defined near the top of this file) sets
   margin-left/right: auto, but .aura-trust__list's own margin: 0 below —
   equal specificity, later in source order — silently won that tie and
   canceled the centering, leaving the list flush against the left edge of
   its 1440px box instead of centered within it. A shared class is fragile
   to exactly this kind of unrelated same-specificity collision, so Trust
   now gets its own wrapper that owns centering with nothing else able to
   touch it, while still replicating the same max-width and the same
   responsive padding scale (16/24/32/48) used by the Hero's own contained
   content — the effective horizontal container contract stays identical. */
.aura-trust__inner {
	width: 100%;
	max-width: 1440px;
	margin-left: auto;
	margin-right: auto;
	padding-left: 16px;
	padding-right: 16px;
}

@media (min-width: 768px) {
	.aura-trust__inner {
		padding-left: 24px;
		padding-right: 24px;
	}
}

@media (min-width: 1024px) {
	.aura-trust__inner {
		padding-left: 32px;
		padding-right: 32px;
	}
}

@media (min-width: 1440px) {
	.aura-trust__inner {
		padding-left: 48px;
		padding-right: 48px;
	}
}

.aura-trust__list {
	margin: 0;
	list-style: none;
	display: grid;
	grid-template-columns: minmax( 0, 1fr );
	gap: var(--wp--preset--spacing--12);
}

.aura-trust__item {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--8);
}

.aura-trust__icon {
	flex: 0 0 auto;
	width: 24px;
	height: 24px;
	color: var(--wp--preset--color--espresso);
}

.aura-trust__text {
	display: flex;
	flex-direction: column;
}

.aura-trust__heading,
.aura-trust__supporting {
	display: block;
}

.aura-trust__heading {
	color: var(--wp--preset--color--espresso);
}

.aura-trust__supporting {
	color: var(--wp--preset--color--warm-gray);
}

@media (min-width: 768px) {
	.aura-trust__list {
		/* minmax(0, 1fr), not plain 1fr: without the explicit 0 minimum, a
		   grid track's automatic minimum is content-based ("auto"), which
		   can let one item's intrinsic content width push its column wider
		   than an equal 1/2 or 1/4 share — producing uneven, left-anchored-
		   looking columns instead of a genuinely stable, equal-width row. */
		grid-template-columns: repeat( 2, minmax( 0, 1fr ) );
	}
}

@media (min-width: 1024px) {
	.aura-trust__list {
		grid-template-columns: repeat( 4, minmax( 0, 1fr ) );
	}
}

/* -- 3. Nos univers ---------------------------------------------------------- */

.aura-univers__heading {
	margin-top: 0;
	margin-bottom: var(--wp--preset--spacing--32);
	color: var(--wp--preset--color--espresso);
	text-align: center;
}

/* minmax(0, 1fr), not plain 1fr (Task 12D-R1B): each card contains a real
   editorial image (up to 819–847px wide at the "large" registered size) —
   without the explicit 0 minimum, a grid track's automatic minimum is
   content-based ("auto"), letting that image's intrinsic width push the
   track — and with it the whole section/document — wider than the mobile
   viewport, the exact same mechanism already documented and fixed for
   .aura-trust__list below. */
.aura-univers__grid {
	display: grid;
	grid-template-columns: minmax( 0, 1fr );
	gap: var(--wp--preset--spacing--32);
}

@media (min-width: 768px) {
	.aura-univers__grid {
		grid-template-columns: repeat( 2, minmax( 0, 1fr ) );
		gap: var(--wp--preset--spacing--48);
	}
}

@media (min-width: 1024px) {
	/* Task 07E1-R2: reduce the cards' desktop visual footprint — contained
	   within a narrower centered width rather than the full shell width. */
	.aura-univers__grid {
		max-width: 1040px;
		margin-inline: auto;
	}
}

.aura-univers__card-media {
	/* DEC-029 §E: contained editorial proportion, replacing the previous
	   4/5 portrait blocks that required excessive scrolling. */
	aspect-ratio: 4 / 3;
	overflow: hidden;
}

.aura-univers__card-image {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Task 07E1-R3: the whole caption area (title + "Découvrir") sits inside one
   barely-visible panel below the image — reuses the existing Warm Ivory
   token only, no new color. Replaces the R2 treatment that put a small
   badge/rectangle around "Découvrir" alone. */
.aura-univers__card-caption {
	display: block;
	margin-top: 0;
	padding: var(--wp--preset--spacing--16);
	background-color: var(--wp--preset--color--warm-ivory);
}

.aura-univers__card-label {
	margin: 0;
	color: var(--wp--preset--color--espresso);
}

.aura-univers__card-cta {
	display: inline-block;
	margin-top: var(--wp--preset--spacing--8);
	color: var(--wp--preset--color--espresso);
	text-decoration: underline;
}

.aura-univers__card-link {
	display: block;
	color: inherit;
	text-decoration: none;
}

/* -- 4. Featured / Selected Products ----------------------------------------- */

/* Narrowly scoped containment backstop (Task 12D-R1D, hardened live via
   real-browser DevTools measurement): `overflow-x: hidden` alone visually
   clips the carousel correctly, but does not reliably stop its unclipped
   layout width from still contributing to `document.documentElement.
   scrollWidth` — confirmed directly (html.scrollWidth matched the
   carousel's own un-clipped content width almost exactly, despite this
   section's and the grid's own boxes both measuring correctly at their
   own viewport-constrained size). `contain: paint` gives the stricter,
   spec-guaranteed containment `overflow: hidden` was expected to but
   didn't fully deliver here: no descendant's overflow can affect anything
   outside this element's own box, full stop — never applied to body/html/
   .site-main. The grid's own `overflow-x: auto` still fully owns and
   permits its horizontal swipe; this only clips at the section boundary,
   it does not disable scrolling. */
.aura-featured-products {
	overflow-x: hidden;
	contain: paint;
}

.aura-featured-products__heading {
	margin-top: 0;
	margin-bottom: var(--wp--preset--spacing--32);
	color: var(--wp--preset--color--espresso);
	text-align: center;
}

/* Task 12D-R1D: horizontal-overflow ownership made explicit. This grid is
   the ONE component intentionally allowed to scroll horizontally on mobile
   (grid-auto-columns/overflow-x/scroll-snap below) — that swipe behavior
   is unchanged. `overscroll-behavior-inline: contain` only stops the
   carousel's own scroll gesture from chaining into a page-level scroll
   attempt at its edges; it does not affect normal scrolling. */
.aura-featured-products__grid {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: 80%;
	gap: var(--wp--preset--spacing--16);
	width: 100%;
	max-width: 100%;
	overflow-x: auto;
	overscroll-behavior-inline: contain;
	scroll-snap-type: x mandatory;
}

.aura-featured-products__grid > * {
	scroll-snap-align: start;
}

@media (min-width: 768px) {
	.aura-featured-products__grid {
		grid-auto-flow: row;
		grid-template-columns: repeat( 2, minmax( 0, 1fr ) );
		overflow-x: visible;
		scroll-snap-type: none;
	}
}

@media (min-width: 1024px) {
	.aura-featured-products__grid {
		grid-template-columns: repeat( 4, minmax( 0, 1fr ) );
	}
}

/* Task 11A-R1: the card is no longer one whole-card anchor (a link cannot
   legally contain another interactive element, and a native add-to-cart
   control is now a third sibling action) — it's an <article> holding two
   independent PDP links (media, name) plus a content column.

   min-width: 0 (Task 12D-R1D): a grid/flex item's own content-based
   automatic minimum size can otherwise refuse to shrink to its assigned
   80%/50%/25% track share (the same hazard already fixed for
   .aura-univers__grid/.aura-trust__list/.aura-site-header__inner) — this
   card is exactly that kind of item, on the one homepage grid genuinely
   carrying real product images. */
.aura-featured-products__card {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--8);
	min-width: 0;
}

.aura-featured-products__media-link {
	display: block;
}

.aura-featured-products__content {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	gap: var(--wp--preset--spacing--8);
}

.aura-featured-products__name-link {
	display: block;
	color: inherit;
	text-decoration: none;
}

.aura-featured-products__card-image {
	aspect-ratio: 4 / 5;
	width: 100%;
	object-fit: cover;
}

.aura-featured-products__card-name {
	color: var(--wp--preset--color--espresso);
}

.aura-featured-products__card-price {
	color: var(--wp--preset--color--warm-gray);
}

/* Pushes the action row to the bottom of the content column so a
   two-line product name never changes where the button sits relative to
   its neighbors in the grid/carousel row. */
.aura-featured-products__actions {
	margin-top: auto;
}

/* -- 5. Brand / editorial (consolidated, DEC-030) --------------------------- */

.aura-brand-editorial__media img {
	width: 100%;
	height: auto;
}

.aura-brand-editorial__logo {
	max-width: 140px;
	width: auto;
	height: auto;
}

.aura-brand-editorial__content {
	/* Task 07E1-R6C: explicit dedicated padding, replacing the previous
	   .aura-shell class on this element. .aura-shell added its own
	   16/24/32/48px responsive padding on top of the flex `gap` already
	   provided by the parent .aura-brand-editorial at desktop — the two
	   stacked, pushing the text column much further from the image than
	   intended. This element now owns only the padding it actually needs:
	   a small mobile/tablet gutter (no flex gap applies below 1024px), and
	   none at desktop, where the parent's `gap` alone controls the
	   image/text relationship. */
	padding-top: var(--wp--preset--spacing--32);
	padding-bottom: var(--wp--preset--spacing--32);
	padding-left: 16px;
	padding-right: 16px;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	/* Task 07E1-R6D: single explicit vertical-rhythm mechanism — see the
	   h2/p margin reset directly below for why this alone is now sufficient. */
	gap: var(--wp--preset--spacing--24);
}

/* Task 07E1-R6D: root cause of the excessive logo→heading and
   heading→paragraph spacing — flex items never collapse margins, so the
   browser's own default UA margin-block on <h2>/<p> (never reset anywhere
   in this theme; theme.json's styles.elements and the .aura-type-* utility
   classes only ever set typography, never margin) was adding its full
   value on top of the flex `gap` above, independently at every boundary.
   Scoped to this component only — not a global heading/paragraph change. */
.aura-brand-editorial__content h2,
.aura-brand-editorial__content p {
	margin: 0;
}

@media (min-width: 768px) {
	.aura-brand-editorial__content {
		padding-left: 24px;
		padding-right: 24px;
	}
}

@media (min-width: 1024px) {
	/* Task 07E1-R2: contain the section within the storefront scale so the
	   image no longer starts flush against the raw viewport edge — desktop
	   only, mobile/tablet full-width behavior below is unaffected. */
	.aura-brand-editorial {
		display: flex;
		align-items: center;
		/* Task 07E1-R3: tighter image/text rhythm (was 48px). */
		gap: var(--wp--preset--spacing--24);
		max-width: 1440px;
		margin-inline: auto;
		padding-left: 32px;
		padding-right: 32px;
	}

	.aura-brand-editorial__media {
		/* DEC-029 §F / Task 07E1-R2: controlled, smaller editorial frame,
		   preventing the portrait source's natural aspect ratio from
		   driving an excessively tall or dominant desktop section. */
		flex: 0 1 42%;
		height: clamp( 360px, 28vw, 460px );
		overflow: hidden;
	}

	.aura-brand-editorial__media img {
		height: 100%;
		object-fit: cover;
	}

	.aura-brand-editorial__content {
		flex: 1 1 58%;
		padding-top: 0;
		padding-bottom: 0;
		/* Intentional Product Steering desktop override: a small retained
		   left inset (20px), not 0 — normalized from an invalid unitless
		   declaration to valid CSS without changing the intended value. */
		padding-left: 20px;
		padding-right: 0;
		max-width: 560px;
	}
}

/* ==========================================================================
   Contact page (Task 07E2C-R1) — reuses existing shell/typography/color
   tokens only, no new palette.
   ========================================================================== */

.aura-contact {
	padding-top: var(--wp--preset--spacing--48);
	padding-bottom: var(--wp--preset--spacing--48);
}

.aura-contact__title {
	margin: 0 0 var(--wp--preset--spacing--24);
}

.aura-contact__notice {
	padding: 12px 16px;
	margin-bottom: var(--wp--preset--spacing--24);
	border: 1px solid var(--wp--preset--color--soft-border);
	background-color: var(--wp--preset--color--warm-ivory);
	color: var(--wp--preset--color--espresso);
}

.aura-contact__layout {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--48);
}

.aura-contact__details h2 {
	margin: 0 0 var(--wp--preset--spacing--16);
}

.aura-contact__details-content p {
	margin: 0 0 var(--wp--preset--spacing--16);
}

.aura-contact__details-content a {
	color: var(--wp--preset--color--espresso);
}

@media (min-width: 1024px) {
	.aura-contact__layout {
		flex-direction: row;
		align-items: flex-start;
	}

	.aura-contact__details {
		flex: 0 1 38%;
	}

	.aura-contact__form-wrap {
		flex: 1 1 62%;
	}
}

/* Contact form */

.aura-contact-form__heading {
	margin: 0 0 var(--wp--preset--spacing--16);
}

.aura-contact-form {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--16);
	max-width: 560px;
}

/* Honeypot: visually hidden, out of tab order, hidden from assistive tech —
   a real visitor never sees or fills this field. */
.aura-contact-form__hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
	margin: 0;
}

.aura-contact-form__row {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--16);
}

@media (min-width: 768px) {
	.aura-contact-form__row {
		flex-direction: row;
	}
}

.aura-contact-form__field {
	display: flex;
	flex-direction: column;
	gap: 4px;
	flex: 1 1 0;
}

.aura-contact-form__field label {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--body-small);
	color: var(--wp--preset--color--espresso);
}

.aura-contact-form__required-mark {
	color: var(--wp--preset--color--warm-gray);
}

.aura-contact-form__field input,
.aura-contact-form__field textarea {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--body);
	color: var(--wp--preset--color--espresso);
	background-color: var(--wp--preset--color--soft-white);
	border: 1px solid var(--wp--preset--color--soft-border);
	padding: 12px 16px;
}

.aura-contact-form__field textarea {
	resize: vertical;
	min-height: 120px;
}

.aura-contact-form__field input:focus-visible,
.aura-contact-form__field textarea:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

/* Restrained, monochrome error state — no new palette. A slightly thicker
   Espresso border (matching the existing 2px focus-outline weight used
   elsewhere in the theme) rather than an introduced red/error hue. */
.aura-contact-form__field--error input,
.aura-contact-form__field--error textarea {
	border-color: var(--wp--preset--color--espresso);
	border-width: 2px;
}

.aura-contact-form__error {
	margin: 0;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--body-small);
	color: var(--wp--preset--color--espresso);
}

.aura-contact-form__privacy {
	color: var(--wp--preset--color--warm-gray);
	margin: 0;
}

.aura-contact-form button[type="submit"] {
	align-self: flex-start;
}

/* ==========================================================================
   Product Listing Page (Task 08B) — one reusable, data-driven native
   product_cat taxonomy archive. Related to, but intentionally independent
   from, the locked homepage Featured card/grid — no homepage rule is reused
   or modified here.
   ========================================================================== */

.aura-plp {
	padding-top: var(--wp--preset--spacing--48);
	padding-bottom: var(--wp--preset--spacing--48);
}

/* Restrained catalog breadcrumb (Task 12D-R1B) — understated, small,
   muted-until-hover, never WooCommerce's own generic breadcrumb output
   (which this template never calls). Separators are decorative CSS
   content on every item but the first, not real characters — screen
   readers get the list/link semantics without a spoken "slash". */
.aura-catalog-breadcrumb {
	margin-bottom: var(--wp--preset--spacing--16);
}

.aura-catalog-breadcrumb__list {
	display: flex;
	flex-wrap: wrap;
	list-style: none;
	margin: 0;
	padding: 0;
}

.aura-catalog-breadcrumb__item {
	display: flex;
	align-items: center;
	color: var(--wp--preset--color--warm-gray);
	font-size: var(--wp--preset--font-size--body-small);
}

.aura-catalog-breadcrumb__item:not(:first-child)::before {
	content: '/';
	margin: 0 var(--wp--preset--spacing--8);
	color: var(--wp--preset--color--warm-gray);
}

.aura-catalog-breadcrumb__link {
	color: var(--wp--preset--color--warm-gray);
	text-decoration: none;
}

.aura-catalog-breadcrumb__link:hover {
	color: var(--wp--preset--color--espresso);
	text-decoration: underline;
}

.aura-catalog-breadcrumb__link:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

.aura-catalog-breadcrumb__current {
	color: var(--wp--preset--color--espresso);
}

.aura-plp__title {
	margin: 0 0 var(--wp--preset--spacing--16);
}

.aura-plp__description {
	margin: 0 0 var(--wp--preset--spacing--24);
	max-width: 720px;
}

.aura-plp__subnav {
	margin: 0 0 var(--wp--preset--spacing--24);
}

.aura-plp__subnav-list {
	display: flex;
	flex-wrap: wrap;
	column-gap: var(--wp--preset--spacing--24);
	row-gap: var(--wp--preset--spacing--8);
	list-style: none;
	margin: 0;
	padding: 0;
}

/* Controlled, editorial underline — offset from the text (not jammed at the
   baseline like a default browser link) and muted at rest, darkening only on
   hover/focus. Generic to any number of child terms, any category. */
.aura-plp__subnav-link {
	display: inline-block;
	padding-bottom: 3px;
	color: var(--wp--preset--color--espresso);
	text-decoration: none;
	border-bottom: 1px solid var(--wp--preset--color--soft-border);
	transition: border-color 150ms ease;
}

.aura-plp__subnav-link:hover {
	border-bottom-color: var(--wp--preset--color--espresso);
}

.aura-plp__subnav-link:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
	border-bottom-color: var(--wp--preset--color--espresso);
}

/* Current-category state (Task 08B-R2A) — a non-interactive span, never a
   self-referencing link. Distinguished from siblings by more than color
   alone: a permanently solid (not hover-only) underline plus a heavier
   weight (existing UI-role 500 weight, no new weight introduced). */
.aura-plp__subnav-link--current {
	border-bottom-color: var(--wp--preset--color--espresso);
	font-weight: 500;
}

/* Restrained textual "back to parent" affordance — quieter than the
   sibling-nav links (muted Warm Gray at rest) since it's a secondary,
   wayfinding-only action, not a primary navigation choice. */
.aura-plp__parent-link {
	display: inline-block;
	margin: 0 0 var(--wp--preset--spacing--8);
	color: var(--wp--preset--color--warm-gray);
	text-decoration: none;
}

.aura-plp__parent-link:hover {
	color: var(--wp--preset--color--espresso);
}

.aura-plp__parent-link:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

.aura-plp__parent-link-arrow {
	display: inline-block;
}

.aura-plp__result-count {
	color: var(--wp--preset--color--warm-gray);
	margin: 0 0 var(--wp--preset--spacing--24);
}

.aura-plp__empty {
	color: var(--wp--preset--color--warm-gray);
}

/* Browsing/comparison grid — deliberately not the homepage Featured
   carousel pattern (no horizontal scroll-snap here). */
.aura-plp__grid {
	display: grid;
	grid-template-columns: repeat( 2, 1fr );
	gap: var(--wp--preset--spacing--24);
	list-style: none;
	margin: 0;
	padding: 0;
}

@media (min-width: 1024px) {
	.aura-plp__grid {
		grid-template-columns: repeat( 3, 1fr );
	}
}

@media (min-width: 1280px) {
	.aura-plp__grid {
		grid-template-columns: repeat( 4, 1fr );
	}
}

.aura-plp__pagination-list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--8);
	list-style: none;
	margin: var(--wp--preset--spacing--32) 0 0;
	padding: 0;
}

.aura-plp__pagination-list a,
.aura-plp__pagination-list span {
	display: inline-block;
	padding: 8px 12px;
	color: var(--wp--preset--color--espresso);
	text-decoration: none;
}

.aura-plp__pagination-list a:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

/* Shared PLP product card (Task 08B, restructured in Task 11A-R1: the card
   is no longer one whole-card anchor — a link cannot legally contain
   another interactive element, and a native add-to-cart control is now a
   third sibling action — it's an <article> holding two independent PDP
   links, a content column, and an actions row). */

.aura-product-card {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--8);
}

.aura-product-card__media-link {
	display: block;
}

.aura-product-card__media {
	display: block;
}

.aura-product-card__image {
	width: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
}

.aura-product-card__no-image {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 5;
	background-color: var(--wp--preset--color--warm-ivory);
}

.aura-product-card__content {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	gap: var(--wp--preset--spacing--8);
}

.aura-product-card__name-link {
	display: block;
	color: inherit;
	text-decoration: none;
}

.aura-product-card__name {
	color: var(--wp--preset--color--espresso);
}

.aura-product-card__price {
	color: var(--wp--preset--color--warm-gray);
}

.aura-product-card__stock {
	color: var(--wp--preset--color--warm-gray);
}

.aura-product-card__media-link:focus-visible,
.aura-product-card__name-link:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

/* Pushes the action row to the bottom of the content column so a two-line
   product name never changes where the button sits relative to its
   neighbors in the grid row. */
.aura-product-card__actions {
	margin-top: auto;
}

/* Native card-level add-to-cart button (Task 11A-R1) — reuses
   `woocommerce_template_loop_add_to_cart()` unmodified, so the markup is
   `<a class="button product_type_simple add_to_cart_button ajax_add_to_cart">`.
   WooCommerce's own frontend stylesheet targets the plain (non-".alt")
   loop button via ".woocommerce:where(...) a.button" — specificity 0/2/1
   (".woocommerce" + the "button" class + the "a" type; ":where()" itself
   contributes zero). Including the real ".add_to_cart_button" class
   (always present whenever the product is purchasable/in stock, exactly
   the case this button renders for) alongside the card-scoping class
   raises this rule to 0/3/0 — enough to win on specificity alone,
   regardless of stylesheet source order, without any `!important` and
   without touching the global `.button`/`.woocommerce button` selectors
   that also govern Cart/Checkout. Loading/added state feedback is left to
   WooCommerce's own native opacity/class handling — never hidden here. */
.aura-product-card__actions .button.add_to_cart_button,
.aura-featured-products__actions .button.add_to_cart_button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	padding: 10px 16px;
	background-color: var(--wp--preset--color--espresso);
	border: 1px solid var(--wp--preset--color--espresso);
	border-radius: 0;
	color: var(--wp--preset--color--soft-white);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--ui);
	font-weight: 500;
	text-decoration: none;
	text-align: center;
	text-shadow: none;
	box-shadow: none;
	cursor: pointer;
	transition: background-color 150ms ease, border-color 150ms ease;
}

.aura-product-card__actions .button.add_to_cart_button:hover,
.aura-featured-products__actions .button.add_to_cart_button:hover {
	background-color: var(--wp--preset--color--deep-taupe);
	border-color: var(--wp--preset--color--deep-taupe);
}

.aura-product-card__actions .button.add_to_cart_button:focus-visible,
.aura-featured-products__actions .button.add_to_cart_button:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

/* WooCommerce inserts this native "Voir le panier" link as a sibling right
   after the button once an AJAX add succeeds — kept visible (never a
   custom toast), styled as a restrained secondary text link, not a second
   filled button. */
.aura-product-card__actions .added_to_cart,
.aura-featured-products__actions .added_to_cart {
	display: block;
	margin-top: var(--wp--preset--spacing--8);
	text-align: center;
	color: var(--wp--preset--color--warm-gray);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--body-small);
	text-decoration: underline;
}

.aura-product-card__actions .added_to_cart:hover,
.aura-featured-products__actions .added_to_cart:hover {
	color: var(--wp--preset--color--espresso);
}

.aura-product-card__actions .added_to_cart:focus-visible,
.aura-featured-products__actions .added_to_cart:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

.aura-product-card__actions .aura-added-feedback,
.aura-featured-products__actions .aura-added-feedback {
	display: block;
	margin-top: var(--wp--preset--spacing--8);
	text-align: center;
	color: var(--wp--preset--color--espresso);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--body-small);
}

/* Mobile-only text rhythm refinement: a tighter, scoped line-height on the
   PLP card name (never the shared .aura-type-body-large role class used
   elsewhere, e.g. homepage Featured) keeps a wrapped two-line product name
   compact and controlled rather than loosely spaced, and a slightly
   tightened card gap reads more deliberate at narrow widths — without any
   ellipsis/line-clamp/fixed height, so full names always remain readable at
   any length. */
@media (max-width: 767px) {
	.aura-product-card {
		gap: var(--wp--preset--spacing--4);
	}

	.aura-product-card__name {
		line-height: 1.3;
	}
}

/* ==========================================================================
   Product Detail Page (Task 09C1 / DEC-033) — structural foundation only.
   Namespaced under .aura-pdp/.aura-product-gallery/.aura-product-summary;
   no PLP selector is reused or modified. Final mobile swipe/scroll-snap
   polish, position indicator, and pixel-level visual QA belong to a later
   task — this establishes the desktop two-column/sticky structure and a
   safe single-column stack below it.
   ========================================================================== */

/* Native breadcrumb visual integration (Task 09C2) — scoped to the
   single-product body class only (native, added by WooCommerce itself via
   body_class()), so Shop/PLP breadcrumbs are completely unaffected. Mirrors
   .aura-shell's exact box model (1440px canvas, same responsive gutters)
   without touching or duplicating that rule. */
body.single-product .woocommerce-breadcrumb {
	display: block;
	width: 100%;
	max-width: 1440px;
	margin-left: auto;
	margin-right: auto;
	margin-top: 0;
	margin-bottom: var(--wp--preset--spacing--16);
	padding-top: var(--wp--preset--spacing--24);
	padding-left: 16px;
	padding-right: 16px;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--body-small);
	color: var(--wp--preset--color--warm-gray);
}

@media (min-width: 768px) {
	body.single-product .woocommerce-breadcrumb {
		padding-left: 24px;
		padding-right: 24px;
	}
}

@media (min-width: 1024px) {
	body.single-product .woocommerce-breadcrumb {
		padding-left: 32px;
		padding-right: 32px;
	}
}

@media (min-width: 1440px) {
	body.single-product .woocommerce-breadcrumb {
		padding-left: 48px;
		padding-right: 48px;
	}
}

body.single-product .woocommerce-breadcrumb a {
	color: var(--wp--preset--color--warm-gray);
	text-decoration: none;
}

body.single-product .woocommerce-breadcrumb a:hover,
body.single-product .woocommerce-breadcrumb a:focus-visible {
	color: var(--wp--preset--color--espresso);
}

body.single-product .woocommerce-breadcrumb a:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

/* Reduced top padding vs. the PLP's 48px: the breadcrumb above now already
   establishes its own top rhythm (24px padding + 16px margin), so the PDP
   itself needs a smaller, controlled follow-on gap rather than stacking a
   second full 48px on top of it. Bottom padding is unchanged. */
.aura-pdp {
	padding-top: var(--wp--preset--spacing--24);
	padding-bottom: var(--wp--preset--spacing--48);
}

.aura-pdp__layout {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--32);
}

@media (min-width: 1024px) {
	.aura-pdp__layout {
		flex-direction: row;
		align-items: flex-start;
		gap: var(--wp--preset--spacing--48);
	}

	.aura-pdp__gallery-col {
		flex: 1 1 55%;
		min-width: 0;
	}

	.aura-pdp__summary-col {
		flex: 1 1 45%;
		min-width: 0;
		position: sticky;
		top: var(--wp--preset--spacing--32);
	}
}

/* Product gallery — one semantic image list only. Everything below this
   comment that isn't inside a media query is shared by both layout modes;
   the desktop hero/mosaic (>=1024px) and the mobile/tablet horizontal
   swipe gallery (<1024px, Task 09C3) are each fully contained in their own
   media query further down, so there is never a gap or overlap between
   them and no rule here needs to be reset by the other. */
.aura-product-gallery__list {
	list-style: none;
	margin: 0;
	padding: 0;
}

/* Task 09C3-R2: positioning context for the decorative swipe-hint chevrons
   below, so they can be anchored to the image area alone (not the counter
   text under it). `position: relative` has no visual effect at any
   breakpoint on its own — desktop is unaffected. */
.aura-product-gallery__viewport {
	position: relative;
}

.aura-product-gallery__image {
	width: 100%;
}

/* Task 09C2-R3: every real gallery image is wrapped in a link to its own
   full-size attachment (a genuine no-JS fallback), progressively enhanced
   by assets/js/product-lightbox.js to open the fullscreen viewer instead.
   `display: block` avoids the few px of inline-image baseline gap a
   default inline anchor would introduce; it changes nothing about the
   image's own sizing/aspect-ratio rules above or in the mosaic below. */
.aura-product-gallery__link {
	display: block;
	cursor: zoom-in;
}

.aura-product-gallery__link:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

.aura-product-gallery__no-image {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 5;
	background-color: var(--wp--preset--color--warm-ivory);
}

/* Mobile/tablet horizontal swipe gallery (Task 09C3, frame corrected in
   09C3-R1) — the same semantic <ul>/<li> list above becomes a native
   horizontal scroller below the 1024px desktop breakpoint. Swipe itself
   needs no JavaScript at all: it's plain `overflow-x: auto` +
   `scroll-snap-type`. assets/js/product-gallery.js only adds the position
   indicator/keyboard layer on top, and only runs below this same
   breakpoint.
   Frame/fidelity strategy (09C3-R1 correction): every slide uses a square
   1/1 frame with `object-fit: contain` + `object-position: center` and a
   neutral Warm Ivory background. This is the SAME final ratio the desktop
   paired mosaic tiles ended up on (Task 09C2-R2C) — but that's a
   coincidence of two separately-reasoned decisions landing on the same
   number, not one being derived from or justified by the other; the
   contexts (one full-width slide at a time here vs. two tiles sharing a
   row there) remain independent and are styled by entirely separate rules
   below/above. The prior 4/5 mobile frame was rejected here because it
   produced excessive slide height (especially near 768px) and delayed
   access to title/price/cart. This keeps the gallery a predictable,
   non-absurd height across mixed portrait/landscape source photos without
   ever cropping — unlike the desktop mosaic there is no separate "hero"
   treatment on mobile, since every slide already gets its own full
   viewport width here. The scrollbar is hidden purely cosmetically;
   overflow-x/keyboard access are never disabled. */
@media (max-width: 1023px) {
	.aura-product-gallery__list {
		display: flex;
		flex-direction: row;
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
	}

	.aura-product-gallery__list::-webkit-scrollbar {
		display: none;
	}

	.aura-product-gallery__list:focus-visible {
		outline: 2px solid var(--wp--preset--color--espresso);
		outline-offset: 2px;
	}

	.aura-product-gallery__item {
		flex: 0 0 100%;
		min-width: 0;
		scroll-snap-align: start;
	}

	.aura-product-gallery__image {
		aspect-ratio: 1 / 1;
		object-fit: contain;
		object-position: center;
		background-color: var(--wp--preset--color--warm-ivory);
	}

	.aura-product-gallery__counter {
		margin: var(--wp--preset--spacing--12) 0 0;
		text-align: center;
		color: var(--wp--preset--color--warm-gray);
		font-family: var(--wp--preset--font-family--body);
		font-size: var(--wp--preset--font-size--body-small);
	}

	/* Swipe-hint chevrons (Task 09C3-R2) — a discoverability hint only, not
	   a second navigation system: aria-hidden, pointer-events:none (swipe
	   and the existing image-link tap both pass straight through), no
	   background shape/pill/shadow-block, just a soft-white glyph with a
	   subtle text-shadow for legibility over any photo. Reuses the exact
	   same active-slide state assets/js/product-gallery.js already tracks
	   for the "1 / N" counter — the JS only toggles the two classes below,
	   no second observer/state.
	   Truthful-edge default: the gallery always starts on slide 1, so the
	   "prev" hint is hidden by default (no JS class needed) and only
	   revealed once assets/js/product-gallery.js confirms the active slide
	   is no longer the first — this is correct even before JS finishes
	   loading, matching the counter's own no-flash-of-wrong-state
	   approach. "next" is hidden only once JS confirms the last slide is
	   active.
	   09C3-R2A root-cause correction: this used to be a single
	   `display:flex; justify-content:space-between;` row holding both
	   hints as siblings. On slide 1, hiding "prev" via `display:none`
	   removes it from flex layout entirely, leaving "next" as the ONLY
	   flex item — and `justify-content:space-between` places a lone item
	   at flex-start (left), not the end, since there is nothing left to
	   distribute space "between". That's exactly why the lone `›` on
	   slide 1 rendered on the left. Fix: each hint is now independently
	   `position:absolute` with its own fixed `left`/`right` anchor inside
	   this wrapper, so hiding one can never move the other — there is no
	   longer any sibling-dependent layout at all. */
	.aura-product-gallery__swipe-hints {
		position: absolute;
		inset: 0;
		pointer-events: none;
	}

	.aura-product-gallery__swipe-hint {
		position: absolute;
		top: 0;
		bottom: 0;
		display: flex;
		align-items: center;
		color: var(--wp--preset--color--soft-white);
		font-size: 22px;
		line-height: 1;
		text-shadow: 0 1px 4px rgba(63, 53, 47, 0.55);
	}

	.aura-product-gallery__swipe-hint--prev {
		left: var(--wp--preset--spacing--12);
		display: none;
	}

	.aura-product-gallery__swipe-hint--next {
		right: var(--wp--preset--spacing--12);
	}

	.aura-product-gallery__swipe-hints.is-not-first .aura-product-gallery__swipe-hint--prev {
		display: flex;
	}

	.aura-product-gallery__swipe-hints.is-last .aura-product-gallery__swipe-hint--next {
		display: none;
	}
}

/* Desktop mosaic composition (Task 09C2-R1, refining DEC-033's original
   single-column description): a dominant full-width first image followed
   by a balanced 2-column mosaic for the rest. The markup is still the one
   semantic <ul>/<li> list above — only its layout mode changes at this
   breakpoint, via CSS Grid auto-placement, so this stays generic for any
   image count without per-product/per-count hardcoding:
   - the first image (the hero) always spans the full width;
   - every other image auto-places two-per-row;
   - if that leaves a single trailing image with no partner (i.e. the
     gallery has an even total image count), that last image also spans
     full width instead of being stranded at half width — this is what
     makes a 2-image product render both images full-width and stacked,
     never one full + one orphaned half.
   The hero (first) image keeps its natural aspect ratio uncropped. Every
   other ("secondary") image is given a uniform tile ratio (Task 09C2-R2)
   so mosaic rows read as evenly matched regardless of each source photo's
   own native ratio — see the secondary-image rule below for why and how.
   Nothing here is scroll-linked, animated, or JS-driven — it's a static
   grid that scrolls with the page like any other content. Below 1024px
   the mobile/tablet horizontal swipe gallery (Task 09C3, above) takes over
   instead — the two media queries are mutually exclusive, so nothing here
   needs to guard against the other. */
@media (min-width: 1024px) {
	.aura-product-gallery__list {
		display: grid;
		grid-template-columns: repeat(2, 1fr);
		gap: var(--wp--preset--spacing--24);
	}

	.aura-product-gallery__image {
		height: auto;
	}

	.aura-product-gallery__counter {
		display: none;
	}

	.aura-product-gallery__swipe-hints {
		display: none;
	}

	.aura-product-gallery__item:first-child {
		grid-column: 1 / -1;
	}

	.aura-product-gallery__item:last-child:nth-child(even) {
		grid-column: 1 / -1;
	}

	/* Task 09C2-R2, scope-corrected in 09C2-R2A, fidelity-corrected in
	   09C2-R2B: uniform tile dimensions, but ONLY for a secondary image
	   that actually shares a two-column row with another image. A
	   secondary image that spans the full width on its own — the trailing
	   odd-one-out handled by the ":last-child:nth-child(even)" rule above
	   — keeps its native ratio just like the hero, since forcing this
	   treatment on a standalone full-width image was never the goal
	   (09C2-R2A correction). The selector below is the exact negation of
	   the two full-width conditions above (":first-child" and
	   ":last-child:nth-child(even)"), so it stays generic for any
	   product/image count — never a specific ID/slug, and never a
	   count-specific rule of its own.
	   09C2-R2B correction: `object-fit: cover` was rejected because it
	   visibly cropped real product detail (e.g. embroidery) out of the
	   frame — Aura Maison product fidelity outranks edge-to-edge tile
	   filling. `object-fit: contain` guarantees the entire source photo is
	   always visible, scaled (never stretched/distorted) to fit inside the
	   same uniform tile frame, so paired tiles stay equal in size without
	   ever cutting anything off. Different source ratios can leave empty
	   space inside the tile; that space is filled with Warm Ivory — the
	   same neutral surface already used by this gallery's own
	   zero-image-placeholder above, not a newly invented color — so the
	   letterboxing reads as an intentional, calm surface rather than a
	   gap. The source media file itself is never touched, reprocessed, or
	   re-uploaded either way.
	   09C2-R2C correction: real-browser QA confirmed the tile sizing/
	   contain/fidelity approach itself works, but 4/5 strongly favors
	   portrait source photos and left excessive top/bottom letterboxing on
	   landscape ones. Changed to a square (1/1) frame as a more neutral
	   compromise across mixed source ratios — chosen because it favors
	   neither orientation, not because it is claimed to be universally
	   optimal; this is still a provisional visual baseline pending
	   real-browser QA, exactly like 4/5 was. `object-position: center` is
	   stated explicitly (matching the already-default centering) so the
	   centering behavior is documented, not implicit. */
	.aura-product-gallery__item:not(:first-child):not(:last-child:nth-child(even)) .aura-product-gallery__image {
		aspect-ratio: 1 / 1;
		object-fit: contain;
		object-position: center;
		background-color: var(--wp--preset--color--warm-ivory);
	}
}

/* ==========================================================================
   PDP fullscreen product-image lightbox (Task 09C2-R3 / DEC-033 refinement).
   One <dialog> per product page, one active image at a time — see
   template-parts/product-lightbox.php and assets/js/product-lightbox.js.
   Dark, restrained, quiet-luxury overlay; the image is the only real
   content on screen. Nothing here changes the gallery/mosaic rules above.
   ========================================================================== */
.aura-lightbox {
	position: fixed;
	inset: 0;
	width: 100vw;
	height: 100vh;
	max-width: 100vw;
	max-height: 100vh;
	margin: 0;
	padding: 0;
	border: none;
	background: transparent;
}

.aura-lightbox::backdrop {
	background-color: rgba(63, 53, 47, 0.92);
}

.aura-lightbox[open] {
	display: flex;
}

.aura-lightbox__frame {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	padding: var(--wp--preset--spacing--24);
}

.aura-lightbox__image {
	display: block;
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	object-fit: contain;
}

.aura-lightbox__close,
.aura-lightbox__prev,
.aura-lightbox__next {
	position: absolute;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	background-color: transparent;
	border: 1px solid var(--wp--preset--color--soft-white);
	color: var(--wp--preset--color--soft-white);
	cursor: pointer;
}

.aura-lightbox__close:hover,
.aura-lightbox__prev:hover,
.aura-lightbox__next:hover {
	background-color: rgba(252, 250, 247, 0.12);
}

.aura-lightbox__close:focus-visible,
.aura-lightbox__prev:focus-visible,
.aura-lightbox__next:focus-visible {
	outline: 2px solid var(--wp--preset--color--soft-white);
	outline-offset: 2px;
}

.aura-lightbox__close {
	top: var(--wp--preset--spacing--16);
	right: var(--wp--preset--spacing--16);
}

.aura-lightbox__prev {
	left: var(--wp--preset--spacing--16);
}

.aura-lightbox__next {
	right: var(--wp--preset--spacing--16);
}

.aura-lightbox__counter {
	position: absolute;
	bottom: var(--wp--preset--spacing--16);
	left: 0;
	right: 0;
	margin: 0;
	text-align: center;
	color: var(--wp--preset--color--soft-white);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--body-small);
}

/* Product summary — targets WooCommerce's own native output classes
   (product_title, price, short-description wrapper, cart form) confirmed
   via direct source/render inspection, plus the theme's own eyebrow/details
   elements. Typography values below intentionally mirror the existing
   .aura-type-h1/.aura-type-section-label roles rather than introducing new
   ones — the theme's own role classes can't be added to WooCommerce's
   hard-coded native title/price markup, so the same values are restated
   here instead. */

/* Task 10D4: the eyebrow is now always a plain text label (real tag, or the
   product's own design name with its type prefix stripped) — never a link,
   so the previous hover/focus-visible/border-bottom link treatment no
   longer applies to anything and was removed rather than left as dead
   styling for an element that can't be focused or clicked. */
.aura-product-summary__eyebrow {
	display: inline-block;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--section-label);
	font-weight: 500;
	line-height: 1.4;
	letter-spacing: 0.06em;
	margin: 0 0 var(--wp--preset--spacing--12);
	color: var(--wp--preset--color--warm-gray);
}

.aura-product-summary .product_title {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--heading-1);
	font-weight: 400;
	line-height: 1.15;
	color: var(--wp--preset--color--espresso);
	margin: 0 0 var(--wp--preset--spacing--12);
}

.aura-product-summary .price {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--body-large);
	font-weight: 400;
	color: var(--wp--preset--color--espresso);
	margin: 0 0 var(--wp--preset--spacing--16);
}

.aura-product-summary .woocommerce-product-details__short-description {
	margin: 0 0 var(--wp--preset--spacing--16);
}

/* Truthful stock state (Task 09C1-R1 / DEC-033) — restrained text only, no
   pill/badge shape, no bright ecommerce-green. Out-of-stock uses the same
   Espresso ink (not a new red/urgent hue) simply at full text weight rather
   than the muted in-stock tone, so it still reads as slightly more
   noteworthy without introducing scarcity styling. */
.aura-product-summary__stock {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--body-small);
	margin: 0 0 var(--wp--preset--spacing--16);
	color: var(--wp--preset--color--warm-gray);
}

.aura-product-summary__stock--out-of-stock {
	color: var(--wp--preset--color--espresso);
}

/* Cart form — a calm, integrated purchasing row: [ quantity ][ Ajouter au
   panier ] side by side when width allows, wrapping safely otherwise. Only
   presentation is touched; the native <input type="number"> and <button
   type="submit"> keep every native attribute/behavior. */
.aura-product-summary form.cart {
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
	gap: var(--wp--preset--spacing--12);
	margin: 0 0 var(--wp--preset--spacing--24);
}

.aura-product-summary form.cart .quantity {
	display: flex;
	align-items: stretch;
	margin: 0;
}

.aura-product-summary form.cart .qty {
	width: 4.5em;
	padding: 12px 16px;
	border: 1px solid var(--wp--preset--color--soft-border);
	background-color: var(--wp--preset--color--soft-white);
	color: var(--wp--preset--color--espresso);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--body);
}

.aura-product-summary form.cart .qty:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

/* Add-to-cart button — same visual language as the shared .aura-button
   primary CTA (Espresso fill, Soft White text, no radius, no gradient),
   restated here rather than reused because WooCommerce hard-codes its own
   button classes and this selector must stay scoped to the PDP only (never
   the global .button/.woocommerce button selectors, which also govern
   Cart/Checkout).

   Root cause of the prior purple render (Task 09C2-R1): WooCommerce's own
   frontend stylesheet targets this button via
   ".woocommerce:where(body:not(.woocommerce-block-theme-has-button-styles))
   button.button.alt" (assets/css/woocommerce.css). The ":where()" wrapper
   itself contributes zero specificity, but the selector still resolves to
   0 ids / 3 classes / 1 type (".woocommerce" + ".button" + ".alt" + the
   "button" element). The prior rule here, ".aura-product-summary
   .single_add_to_cart_button", was only 0/2/0 — lower specificity always
   loses regardless of stylesheet source order, which is why the override
   silently had no visual effect. Prefixing with the native ".single-product"
   body class (present only on the PDP) and this template's own ".aura-pdp"
   section class raises this rule to 0/4/1 without touching the global
   .button/.woocommerce button selectors or anything on Cart/Checkout. */
body.single-product .aura-pdp .aura-product-summary .single_add_to_cart_button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 12px 24px;
	background-color: var(--wp--preset--color--espresso);
	border: 1px solid var(--wp--preset--color--espresso);
	color: var(--wp--preset--color--soft-white);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--ui);
	font-weight: 500;
	text-decoration: none;
	cursor: pointer;
	transition: background-color 150ms ease, border-color 150ms ease;
}

body.single-product .aura-pdp .aura-product-summary .single_add_to_cart_button:hover {
	background-color: var(--wp--preset--color--deep-taupe);
	border-color: var(--wp--preset--color--deep-taupe);
}

body.single-product .aura-pdp .aura-product-summary .single_add_to_cart_button:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

body.single-product .aura-pdp .aura-product-summary .single_add_to_cart_button:disabled,
body.single-product .aura-pdp .aura-product-summary .single_add_to_cart_button.disabled {
	background-color: var(--wp--preset--color--soft-border);
	border-color: var(--wp--preset--color--soft-border);
	color: var(--wp--preset--color--warm-gray);
	cursor: not-allowed;
}

/* Details disclosure — native <details>/<summary>, no JS. A quiet top
   separator, a comfortable clickable summary row, and a custom +/− marker
   (replacing the default browser triangle) communicate open/closed state
   without relying on color alone. */
.aura-product-summary__details {
	border-top: 1px solid var(--wp--preset--color--soft-border);
	padding-top: var(--wp--preset--spacing--16);
	padding-bottom: var(--wp--preset--spacing--16);
}

.aura-product-summary__details-summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--16);
	cursor: pointer;
	color: var(--wp--preset--color--espresso);
	padding: 4px 0;
}

.aura-product-summary__details-summary::-webkit-details-marker {
	display: none;
}

.aura-product-summary__details-summary::after {
	content: '+';
	color: var(--wp--preset--color--warm-gray);
}

.aura-product-summary__details[open] .aura-product-summary__details-summary::after {
	content: '\2212';
}

.aura-product-summary__details-summary:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

.aura-product-summary__details-content {
	margin-top: var(--wp--preset--spacing--16);
	color: var(--wp--preset--color--espresso);
}

.aura-product-summary__details-content p {
	margin: 0 0 var(--wp--preset--spacing--16);
}

.aura-product-summary__details-content p:last-child {
	margin-bottom: 0;
}

/* ==========================================================================
   Cart / Checkout premium foundation (Task 12B-R1). Native WooCommerce Cart
   and Checkout Blocks, unmodified — no template override, no block
   replacement. Both pages fall through the theme's generic `index.php`
   fallback (no page-cart.php/page-checkout.php/woocommerce.php exists),
   which wraps `the_content()` in a plain `<article>`/`.entry-content` with
   none of WordPress's block-layout classes — so neither page ever picked up
   the Aura Maison storefront canvas, and the pre-existing "editorial content
   links" rule (`.entry-content a`, above) unintentionally reached the native
   Cart submit-button anchor, since it also happens to render as an `<a>`
   inside that same wrapper.
   ========================================================================== */

/* Canvas: reuses .aura-shell's exact max-width/gutter values (never .aura-shell
   itself, to keep this fully independent of PDP/PLP/homepage) — covers both
   the page title (<h1>) and the WooCommerce block, since both are children
   of the same <article> rendered by index.php. No .alignwide override. */
body.woocommerce-cart article,
body.woocommerce-checkout article {
	max-width: 1440px;
	margin-left: auto;
	margin-right: auto;
	padding-left: 16px;
	padding-right: 16px;
}

@media (min-width: 768px) {
	body.woocommerce-cart article,
	body.woocommerce-checkout article {
		padding-left: 24px;
		padding-right: 24px;
	}
}

@media (min-width: 1024px) {
	body.woocommerce-cart article,
	body.woocommerce-checkout article {
		padding-left: 32px;
		padding-right: 32px;
	}
}

@media (min-width: 1440px) {
	body.woocommerce-cart article,
	body.woocommerce-checkout article {
		padding-left: 48px;
		padding-right: 48px;
	}
}

/* Task 12D-R1B: Checkout only — same shared canvas rule above still applies
   for centering/gutters, this narrows just the maximum width (Cart stays
   1440px; the two-column checkout form/summary reads as excessively wide
   at that width, unlike Cart's simpler single content block). Same
   selector as the shared rule, so identical specificity — wins purely by
   coming later in source order, no !important needed. WooCommerce's own
   internal two-column layout is untouched, it simply has less room to work
   with. */
body.woocommerce-checkout article {
	max-width: 1240px;
}

/* System-page breadcrumb vertical rhythm (Task 12D-R1D) — a dedicated
   modifier class, not a change to `.aura-catalog-breadcrumb` itself (that
   class keeps its existing category-archive appearance untouched). Gives
   Cart/Checkout's breadcrumb the same "comfortable editorial breathing
   space" below the header that the category archive already gets for
   free from `.aura-plp`'s own padding-top — this fallback template has no
   equivalent, so the breadcrumb previously sat flush against the header.
   Mobile gets a proportionately smaller gap; ≥768px matches the category
   page's flat 48px rhythm. Structural spacing on the breadcrumb nav itself,
   not an arbitrary margin on the H1. */
.aura-system-breadcrumb {
	margin-top: var(--wp--preset--spacing--24);
}

@media (min-width: 768px) {
	.aura-system-breadcrumb {
		margin-top: var(--wp--preset--spacing--48);
	}
}

/* Cart primary CTA + the new empty-cart "Découvrir la boutique" button:
   both render as a plain <a class="wp-element-button ..."> inside
   .wp-block-woocommerce-cart, which sits inside .entry-content — so the
   editorial-link rule above (specificity 0,1,1) was winning over WordPress's
   own zero-specificity `:where(.wp-element-button, .wp-block-button__link)`
   global button rule, leaving Espresso text on an Espresso background.
   Scoped two-class selectors here (specificity 0,2,0 / 0,2,1) reliably beat
   `.entry-content a` with no !important. Checkout's own primary button is
   confirmed to render as a native <button> (no `href` passed to the shared
   component), so `.entry-content a` never reaches it and no override is
   added there. */
.wp-block-woocommerce-cart .wc-block-cart__submit-button,
.wp-block-woocommerce-cart .wp-block-button__link {
	color: var(--wp--preset--color--soft-white);
	background-color: var(--wp--preset--color--espresso);
	text-decoration: none;
}

.wp-block-woocommerce-cart .wc-block-cart__submit-button:hover,
.wp-block-woocommerce-cart .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--deep-taupe);
}

.wp-block-woocommerce-cart .wc-block-cart__submit-button:focus-visible,
.wp-block-woocommerce-cart .wp-block-button__link:focus-visible {
	outline: 2px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
}

/* Suppress only WooCommerce Blocks' native empty-cart mask-image icon
   (confirmed source: cart.css, `.with-empty-cart-icon:before`) — the class
   itself is left in the markup, only its pseudo-element is hidden, scoped
   narrowly to the Cart page's empty-cart heading so no other icon anywhere
   else in the site is affected. */
body.woocommerce-cart
.wp-block-woocommerce-cart
.wc-block-cart__empty-cart__title.with-empty-cart-icon::before {
	display: none;
}

/* ==========================================================================
   Checkout field spacing/overflow safety (Task 12D-R1B). Scoped strictly to
   WooCommerce's own native address-form field classes, never a generic
   input/select/form selector — Contact and PDP are unaffected.

   Confirmed directly in the installed checkout.css (not assumed): WooCommerce
   Blocks pairs `.wc-block-components-text-input` /`-select-input`/
   `-state-input` at `flex: 1 0 calc(50% - 12px)` inside
   `.wc-block-components-address-form`, whose own `gap: 0 12px` sets row-gap
   to exactly zero, and every field wrapper explicitly resets `margin-top` to
   0 — so wrapped rows (e.g. Prénom/Nom) get no vertical breathing room by
   design, not by theme accident.

   None of these field-wrapper classes set `min-width`, so a flex item's
   default `min-width: auto` lets its own content (a native <select>'s
   longest option text — e.g. a long region/department name) refuse to
   shrink below that width even though its declared flex-basis is only 50%,
   which is the actual overflow risk on the region/department field — fixed
   here with `min-width: 0`, the standard, minimal fix for exactly this
   class of bug; the native <select> element itself is untouched.
   ========================================================================== */

body.woocommerce-checkout .wc-block-components-address-form {
	gap: var(--wp--preset--spacing--16) var(--wp--preset--spacing--16);
}

body.woocommerce-checkout .wc-block-components-address-form .wc-block-components-text-input,
body.woocommerce-checkout .wc-block-components-address-form .wc-block-components-select-input,
body.woocommerce-checkout .wc-block-components-address-form .wc-block-components-state-input {
	min-width: 0;
}

/* Mobile: stack every paired field to full width instead of the native 50/50
   pairing — address_1/address_2/country/company/checkbox are already 100%
   natively and untouched here. The gap above still applies as real vertical
   spacing between the now fully-stacked rows. */
@media (max-width: 767px) {
	body.woocommerce-checkout .wc-block-components-address-form .wc-block-components-text-input,
	body.woocommerce-checkout .wc-block-components-address-form .wc-block-components-select-input,
	body.woocommerce-checkout .wc-block-components-address-form .wc-block-components-state-input {
		flex: 1 0 100%;
	}
}

/* ==========================================================================
   Cart empty-state Featured suggestions (Task 12C-R1B). Dynamic content
   appended by aura_maison_append_cart_empty_suggestions() in functions.php
   — never part of the Cart Page's own stored content. Sits inside the same
   `body.woocommerce-cart article` canvas already constrained in 12B-R1, so
   no separate .aura-shell wrapper is needed here. Reuses the existing
   .aura-plp__grid 2/3/4-column responsive rhythm (base/1024/1280) and the
   shared product-card partial as-is — no new grid breakpoints, no fixed
   card heights.
   ========================================================================== */

.aura-cart-suggestions {
	margin-top: var(--wp--preset--spacing--64);
	padding-top: var(--wp--preset--spacing--48);
	border-top: 1px solid var(--wp--preset--color--soft-border);
}

.aura-cart-suggestions__heading {
	margin-top: 0;
	margin-bottom: var(--wp--preset--spacing--24);
	color: var(--wp--preset--color--espresso);
}
