/* ------------------------------------------------------------ *\
	PDP mobile unification tokens — single source for the two values
	the mock keeps constant across the page: the inter-section rhythm
	(80px at every width) and the phone content gutter (12px column,
	vs the per-section 1440 desktop grid). Carousels and full-bleed
	sections derive their bleed from --pdp-gutter so nothing is wired
	to a hardcoded inset. The page stacks at base.css's 835 breakpoint
	and refines for phones at 560.
\* ------------------------------------------------------------ */
.single-product {
	--pdp-space: 80px;
}
@media (max-width: 835px) {
	.single-product { --pdp-gutter: 12px; }
}

.pdp-hero {
	/* Clear the fixed desktop header (~80px) — the theme offsets the header via each
	   first section's own top padding, and the previous 24px was too small for the PDP. */
	padding: 104px 0 var(--pdp-space);
	font-family: var(--bva-font-sans);
	color: var(--bva-black);
}
.pdp-hero__inner {
	position: relative;
	max-width: 1440px;
	margin-inline: auto;
	/* Symmetric 40px rail, matching --bva-bleed-pad and every other V3 section.
	   The mock had 16px left / 103px right (its hero frame was off the grid),
	   which pinned the image to the viewport edge and cut the text short. */
	padding: 0 40px;
	display: flex;
	justify-content: space-between;
	align-items: flex-start;
	/* Floor for the space either side of the rule; the rule's auto margins then
	   share out whatever is left (see .pdp-hero__divider). Without it, both
	   columns shrink until they touch the rule below ~1200px. */
	gap: 24px;
}
/* In flow rather than absolute at a hardcoded 869px (the mock's 1440 offset):
   both columns are shrinkable, so a fixed offset dropped the rule inside the
   text column below 1440. Auto margins on both sides split the free space
   evenly, so the rule sits midway between image and copy instead of hugging
   the copy with a 174px hole on its left. Stretch keeps it the row height. */
.pdp-hero__divider {
	align-self: stretch;
	flex: 0 0 1px;
	width: 1px;
	margin-inline: auto;
	background: var(--bva-line);
}

.pdp-gallery {
	position: sticky;
	top: 24px;
	/* Shrinkable so the 679 + 452 columns never overflow between 835 and
	   ~1290px (no grow: stays 679 once there's room, holding the 1440 ISO). */
	flex: 0 1 679px;
	min-width: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 32px;
}
.pdp-gallery__stage {
	position: relative;
	width: 100%;
	/* 679px ISO mock, but the whole pinned column (stage + 32 gap + 72 thumbs row)
	   must clear the fold: otherwise the thumbs tablist hangs under it for the
	   entire pin and the photo can't be switched by click. Bound the WIDTH by the
	   room, ratio applied — the stage shrinks proportionally (no recrop) and stays
	   centered. Floor at 360px so a very short window degrades sanely. Keep the
	   subtractions in sync with `top: 24px` above, the .pdp-gallery 32px gap and
	   the 72px thumbs row (60px + 2 x 6px padding: `all: unset` on button resets
	   box-sizing to content-box). */
	max-width: min(679px, max(360px, calc((100vh - 24px - 32px - 72px - 24px) * 679 / 682)));
	aspect-ratio: 679 / 682;
	border-radius: 12px;
	overflow: hidden;
}
.pdp-gallery__main { width: 100%; height: 100%; object-fit: cover; display: block; }
.pdp-gallery__nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	display: flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	background: var(--bva-white);
	border: 0;
	border-radius: 4px;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
	cursor: pointer;
}
.pdp-gallery__nav svg { width: 24px; height: 24px; display: block; }
.pdp-gallery__nav--prev { left: 20px; }
.pdp-gallery__nav--prev svg { transform: rotate(180deg); }
.pdp-gallery__nav--next { right: 20px; }

/* Wraps: a thumb occupies 72px (60 + 2 x 6 padding — `all: unset` on button resets
   box-sizing to content-box), so 5+ images overflowed the 351px phone column in both
   directions (centred row) and pushed a horizontal scroll onto the whole document. */
.pdp-gallery__thumbs { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 2px; max-width: 100%; }
.pdp-thumb {
	width: 60px;
	height: 60px;
	padding: 6px;
	border: 0;
	border-radius: 4px;
	background: none;
	opacity: 0.5;
	cursor: pointer;
	transition: opacity 0.15s ease;
}
.pdp-thumb img { width: 100%; height: 100%; object-fit: cover; border-radius: 2px; display: block; }
.pdp-thumb:hover { opacity: 0.85; }
.pdp-thumb.is-active {
	width: 48px;
	height: 48px;
	opacity: 1;
	border: 1px solid var(--bva-black);
}

.pdp-info {
	flex: 0 1 452px;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 40px;
}
.pdp-info__head { display: flex; flex-direction: column; gap: 16px; }

.pdp-badge {
	align-self: flex-start;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 8px;
	border-radius: 2px;
	background: var(--bva-badge-bg);
	font: var(--bva-t-label);
	text-transform: uppercase;
}
.pdp-badge svg { width: 16px; height: 16px; display: block; }

/* One notch bolder than the header-xl token (500 -> 600): set after the `font`
   shorthand, which resets font-weight. Token stays shared/unchanged. */
.pdp-title { margin: 0; font: var(--bva-t-header-xl); color: var(--bva-black); font-weight: 600; }

.pdp-rating { display: flex; align-items: center; gap: 8px; }
.pdp-rating__stars { display: inline-flex; align-items: center; gap: 2px; }
.pdp-rating__stars svg { width: 16px; height: 15px; display: block; }
/* Yellow/gold rating stars (recolor the inlined black-star SVGs; empty stars keep fill:none) */
.pdp-rating__stars svg path[fill="#151412"] { fill: #f5a623; }
.pdp-rating__stars svg path[stroke="#151412"] { stroke: #f5a623; }
.pdp-rating__count { font: var(--bva-t-label); text-transform: uppercase; }

.pdp-desc { display: flex; flex-direction: column; gap: 16px; }
.pdp-desc p { margin: 0; font: var(--bva-t-paragraphe); }
/* Lead line one notch bolder (header-s 500 -> 600); weight set after `font`. */
.pdp-desc > p:first-child { font: var(--bva-t-header-s); font-weight: 600; }
.pdp-desc > p:last-child { color: var(--bva-muted); }
.pdp-desc strong { font-weight: 500; }

.pdp-benefits { margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; list-style: none; }
.pdp-benefits li { display: flex; align-items: flex-start; gap: 12px; }
/* Centred on the first line-box (24px line, 14px rule) instead of on the whole
   item: a benefit long enough to wrap kept its marker floating mid-block. */
.pdp-benefits__bar { flex: 0 0 3px; width: 3px; height: 14px; margin-top: 5px; background: var(--bva-black); }
.pdp-benefits strong { font: 600 18px/1.32 var(--bva-font-sans); }

.pdp-cart { margin: 0; }
.pdp-btn-cart {
	width: 100%;
	height: 60px;
	border: 0;
	border-radius: 2px;
	background: var(--bva-black);
	color: var(--bva-white);
	font: var(--bva-t-paragraphe);
	text-align: center;
	cursor: pointer;
	transition: opacity 0.15s ease;
}
.pdp-btn-cart:hover { opacity: 0.9; }

.pdp-accordions { display: flex; flex-direction: column; }
.pdp-accordion { border-top: 1px solid var(--bva-line); }
.pdp-accordions .pdp-accordion:last-child { border-bottom: 1px solid var(--bva-line); }
.pdp-accordion__head {
	width: 100%;
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 12px 0;
	border: 0;
	background: none;
	font: var(--bva-t-label);
	text-transform: uppercase;
	text-align: left;
	cursor: pointer;
}
.pdp-accordion__icon { position: relative; flex: 0 0 11px; width: 11px; height: 11px; }
.pdp-accordion__icon::before,
.pdp-accordion__icon::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 9px;
	height: 1px;
	background: var(--bva-black);
	transform: translate(-50%, -50%);
}
.pdp-accordion__icon::after { transform: translate(-50%, -50%) rotate(90deg); }
.pdp-accordion__head[aria-expanded="true"] .pdp-accordion__icon::after { opacity: 0; }

.pdp-accordion__panel { max-height: 0; overflow: hidden; transition: max-height 0.28s ease; }
.pdp-accordion__head[aria-expanded="true"] + .pdp-accordion__panel { max-height: 480px; }
.pdp-accordion__panel p { margin: 0; padding-bottom: 16px; font: var(--bva-t-paragraphe); }

.pdp-reassurance { margin: 0; padding: 0; display: flex; flex-direction: column; gap: 24px; list-style: none; }
.pdp-reassurance li { display: flex; align-items: center; gap: 24px; }
.pdp-reassurance svg { flex: 0 0 16px; width: 16px; height: 16px; display: block; }
.pdp-reassurance span { font: var(--bva-t-label); text-transform: uppercase; }
.pdp-reassurance__phone { align-items: flex-start; }
.pdp-reassurance__phone > span { display: flex; flex-direction: column; gap: 4px; }
.pdp-reassurance__muted { color: var(--bva-muted); }

/* v3 icons ship with a white stroke for the dark footer; force black on light bg */
.pdp-badge svg [stroke],
.pdp-reassurance svg [stroke],
.pdp-gallery__nav svg [stroke] { stroke: var(--bva-black); }

@media (max-width: 835px) {
	/* base.css swaps in the compact .header-mobile here, so trim the hero top. */
	.pdp-hero { padding-top: 12px; }
	.pdp-hero__inner { flex-direction: column; padding: 0 var(--pdp-gutter); gap: 40px; }
	.pdp-hero__divider { display: none; }
	.pdp-gallery,
	.pdp-info { position: static; flex: 1 1 auto; width: 100%; max-width: 560px; margin-inline: auto; }
	/* Column is no longer pinned here, so drop the viewport-bound cap: it only exists
	   to keep the pinned stage + thumbs row above the fold, and its 72px thumbs-row
	   term stops holding as soon as the row wraps. */
	.pdp-gallery__stage { max-width: 679px; }
	/* Mobile mock flips the bottom of the info column: reassurance sits right under
	   the CTA, accordions move to the end. Reorder via flex (DOM order = desktop). */
	.pdp-info .pdp-accordions { order: 1; }
}

@media (max-width: 560px) {
	/* Hero title steps down from the 48px desktop token to the mobile mock size. */
	.pdp-title { font-size: 36px; }
}

/* Tablet / small laptop, still in the two-column hero: both columns shrink from
   their 679 + 452 bases in proportion, which starved the copy (308px at 900 — the
   48px title broke over four lines). Floor the info column and let the gallery
   give up the room instead; it keeps its 1:1 ratio either way. */
@media (min-width: 836px) and (max-width: 1180px) {
	.pdp-info { min-width: 340px; }
	/* 48px over a ~340px column broke the name over four lines — one step down, still
	   above the 36px phone size. */
	.pdp-title { font-size: 40px; }
}

.pdp-quote {
	max-width: 1440px;
	margin-inline: auto;
	padding: 0 12px var(--pdp-space);
}
.pdp-quote__box {
	position: relative;
	display: flex;
	align-items: center;
	min-height: 494px;
	padding: 40px;
	overflow: hidden;
	border-radius: 12px;
	background: var(--bva-ink);
	color: var(--bva-vitamine-100);
}
.pdp-quote__media {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center top;
	background-repeat: no-repeat;
}
.pdp-quote__scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(to right, var(--bva-ink) 16.5%, rgba(21, 22, 26, 0) 67.3%);
}

.pdp-quote__inner {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: 24px;
	min-height: 310px;
	max-width: 933px;
	margin: 0;
	padding-left: 16px;
	border-left: 1px solid rgba(253, 242, 236, 0.3);
}
.pdp-quote__text {
	margin: 0;
	max-width: 765px;
	font: var(--bva-t-header-l);
}
.pdp-quote__text::before { content: "\201C"; }
.pdp-quote__text::after { content: "\201D"; }

.pdp-quote__author {
	display: flex;
	align-items: flex-end;
	gap: 16px;
	width: 345px;
	max-width: 100%;
	padding-bottom: 6px;
	border-bottom: 1px solid rgba(253, 242, 236, 0.3);
}
.pdp-quote__brand { font: var(--bva-t-label); text-transform: uppercase; }
.pdp-quote__sign { font: 300 40px/1.1 'Zeyada', cursive; }

@media (max-width: 835px) {
	.pdp-quote__box { min-height: 0; padding: 32px 24px; }
	.pdp-quote__scrim { background: linear-gradient(to right, var(--bva-ink) 40%, rgba(21, 22, 26, 0.4) 100%); }
	.pdp-quote__text { font-size: 22px; }
}
@media (max-width: 560px) {
	/* Mock stacks the author block: BIOVANCIA label above the Équipe R&D signature. */
	.pdp-quote__author { flex-direction: column; align-items: flex-start; gap: 4px; width: auto; }
}

.pdp-testimonials {
	max-width: 1440px;
	margin-inline: auto;
	padding: 0 40px var(--pdp-space);
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 40px;
}
.pdp-testimonials__title {
	margin: 0;
	font: 500 24px/1.1 var(--bva-font-sans);
	font-weight: 600;
	text-transform: uppercase;
	text-align: center;
	color: var(--bva-black);
}
.pdp-testimonials__grid {
	width: 100%;
	display: grid;
	/* 4-up at the mock's 1440 (328px cards), then it drops a column on its own:
	   a hard repeat(4) squeezed the cards to 193px of 24px-padded copy at 900. */
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 16px;
}

.pdp-review {
	display: flex;
	flex-direction: column;
	gap: 24px;
	padding: 24px;
	border-radius: 4px;
	background: var(--bva-myrtille-100);
}
.pdp-review__body { display: flex; flex-direction: column; gap: 24px; }
.pdp-review__head { display: flex; flex-direction: column; gap: 12px; }
.pdp-review__stars { display: inline-flex; gap: 2px; }
.pdp-review__stars svg { width: 13px; height: 12px; display: block; }
.pdp-review__title { margin: 0; font: 500 20px/1.2 var(--bva-font-sans); color: var(--bva-dark-brown); font-weight: 600; }
.pdp-review__text { margin: 0; font: var(--bva-t-paragraphe); color: rgba(28, 26, 23, 0.6); }
.pdp-review__name { margin: 0; font: var(--bva-t-label); text-transform: uppercase; color: var(--bva-dark-brown); font-weight: 400; }

@media (max-width: 835px) {
	.pdp-testimonials { padding: 0 var(--pdp-gutter) var(--pdp-space); }
	.pdp-testimonials__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
	/* Swipeable carousel (.pdp-carousel): ~1 card in view, next peeks. */
	.pdp-testimonials__grid { --pdp-carousel-card: 84%; }
}

/* ------------------------------------------------------------ *\
	Problem / Solution / Résultat — desktop pins the section and scroll
	scrubs the 3 steps (each crossfades its own photo + text), then
	releases into Ingredients. Mobile: the steps stack (déroulé).
	One markup (.pdp-ps__step = panel + photo) serves both modes.
\* ------------------------------------------------------------ */
.pdp-ps {
	/* Sticky chrome height — the pin sticks below it so the tabs scroll-spy never
	   hides under the header. The V3 announcement topbar is fixed above the header
	   and pushes it down by --v3-topbar-h (0 when dismissed, set by v3.js otherwise),
	   so it must be added in or the tabs slip under the header when the bar shows.
	   +32px when the WP admin bar is present. */
	--pdp-header-h: calc(80px + var(--v3-topbar-h, 0px));
	position: relative;
	height: calc(var(--pdp-ps-steps, 3) * 100vh);
	margin: 0 0 var(--pdp-space);
	border-block: 1px solid rgba(0, 0, 0, 0.12);
	color: var(--bva-black);
}
.admin-bar .pdp-ps { --pdp-header-h: calc(112px + var(--v3-topbar-h, 0px)); }
.pdp-ps__pin {
	position: sticky;
	top: var(--pdp-header-h);
	height: calc(100vh - var(--pdp-header-h));
	overflow: hidden;
}

.pdp-ps__tabs {
	position: absolute;
	top: 0;
	left: 0;
	z-index: 2;
	display: flex;
	gap: 40px;
	padding: 40px var(--bva-bleed-pad) 0;
}
.pdp-ps__tab {
	padding: 0;
	border: 0;
	background: none;
	font: var(--bva-t-label);
	text-transform: uppercase;
	color: var(--bva-black);
	white-space: nowrap;
	cursor: pointer;
	opacity: 0.5;
	transition: opacity 0.2s ease;
}
.pdp-ps__tab.is-active { opacity: 1; }

.pdp-ps__steps { position: absolute; inset: 0; }
.pdp-ps__step {
	position: absolute;
	inset: 0;
	display: grid;
	grid-template-columns: calc(var(--bva-bleed-pad) + 520px) 1fr;
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.5s ease;
}
.pdp-ps__step.is-active { opacity: 1; pointer-events: auto; }

.pdp-ps__panel {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 24px;
	/* Clear the absolute tabs (top) + promo (bottom); align text to the rail. */
	padding: 150px 40px 150px var(--bva-bleed-pad);
}
.pdp-ps__title { margin: 0; font: var(--bva-t-header-l); font-weight: 500; }
.pdp-ps__text { font: var(--bva-t-paragraphe); }
.pdp-ps__text p { margin: 0 0 12px; }
.pdp-ps__text p:last-child { margin-bottom: 0; }
/* A bold-only paragraph is a phase label (e.g. "Dès les premiers jours") —
   render it as the Geist Mono caption above its lines, like the mock. */
.pdp-ps__text strong { font: var(--bva-t-label); text-transform: uppercase; color: var(--bva-muted); }
.pdp-ps__text p:has(> strong) { margin: 24px 0 8px; }
.pdp-ps__text p:first-child:has(> strong) { margin-top: 0; }

/* Long copy stays pinned ISO mock: product.js caps the text column (inline
   max-height) and it scrolls in place — the wheel reads the copy through,
   then chains back to the page scroll that drives the steps. The fades mark
   the edges that hide lines (has-above / has-below, synced on scroll). */
.pdp-ps__step.is-scrollable .pdp-ps__text {
	overflow-y: auto;
	scrollbar-width: thin;
	scrollbar-color: rgba(28, 26, 23, 0.25) transparent;
}
.pdp-ps__step.is-scrollable .pdp-ps__text.has-below {
	-webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent);
	mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent);
}
.pdp-ps__step.is-scrollable .pdp-ps__text.has-above {
	-webkit-mask-image: linear-gradient(to bottom, transparent, #000 28px);
	mask-image: linear-gradient(to bottom, transparent, #000 28px);
}
.pdp-ps__step.is-scrollable .pdp-ps__text.has-above.has-below {
	-webkit-mask-image: linear-gradient(to bottom, transparent, #000 28px, #000 calc(100% - 28px), transparent);
	mask-image: linear-gradient(to bottom, transparent, #000 28px, #000 calc(100% - 28px), transparent);
}
/* Top-aligned when capped: centering would push the sized column out of the
   paddings (bottom clipped under the pin) the moment the copy fills the room.
   The mock's 150px paddings also shrink to give the copy more window — 116px
   still clears the tabs overlay (55px + 40px + air), 80px of air at the foot
   (product.js reserves more when the promo banner is there). Keep in sync
   with the room formula in updateFit. */
.pdp-ps__step.is-scrollable .pdp-ps__panel {
	justify-content: flex-start;
	padding-top: 116px;
	padding-bottom: 80px;
}

.pdp-ps__photo {
	background-color: var(--bva-myrtille-100);
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}

.pdp-ps .pdp-promo {
	position: absolute;
	left: 0;
	bottom: 0;
	z-index: 2;
	width: calc(var(--bva-bleed-pad) + 520px);
	padding: 0 40px 40px var(--bva-bleed-pad);
}

/* Tablet / small laptop, pin kept (see CLAUDE.md — no layout switch): the copy column
   is a fixed 40 + 520px, so the photo was left with 340px over 778px of height at 900 —
   a vertical sliver of a square master. Split the pin in proportion instead. Keep the
   promo banner's width in sync: it sits over the same column. */
@media (min-width: 836px) and (max-width: 1180px) {
	.pdp-ps__step { grid-template-columns: minmax(0, 48%) 1fr; }
	.pdp-ps .pdp-promo { width: 48%; }
}

@media (max-width: 835px) {
	/* Mobile: no pin — steps stack, each panel above its photo (déroulé). */
	.pdp-ps { height: auto; }
	.pdp-ps__pin { position: static; height: auto; overflow: visible; }
	/* Tabs stay on one line and stick under the fixed header so the scroll-spy
	   stays visible while the steps scroll past (déroulé). */
	.pdp-ps__tabs {
		position: sticky;
		/* Under the real mobile chrome: .header-mobile is 46px and the announcement bar
		   above it is 44-49px depending on whether its text wraps. The flat 70px left
		   the tablist hidden behind the header when the bar shows, and floating 24px
		   below it once dismissed. Same fallbacks as topbar.css. */
		top: 46px;
		z-index: 3;
		flex-wrap: nowrap;
		justify-content: space-between;
		gap: 8px;
		padding: 16px var(--pdp-gutter);
		background: var(--bva-canelle-100);
		border-bottom: 1px solid rgba(0, 0, 0, 0.12);
		/* Labels come from the DB ("01 - PROBLÈME"): three nowrap tabs already blow past
		   a 320px screen (+36px), and the overflow landed on the document, shifting the
		   whole page sideways. Contain it in the bar instead. */
		overflow-x: auto;
		scrollbar-width: none;
	}
	.pdp-ps__tabs::-webkit-scrollbar { display: none; }
	body.has-topbar .pdp-ps__tabs { top: calc(46px + var(--v3-topbar-h, 44px)); }
	.pdp-ps__steps { position: static; }
	.pdp-ps__step {
		position: static;
		display: block;
		opacity: 1;
		pointer-events: auto;
	}
	.pdp-ps__panel { justify-content: flex-start; gap: 16px; padding: 32px var(--pdp-gutter); }
	.pdp-ps__photo { height: 320px; }
	.pdp-ps .pdp-promo { position: static; width: auto; padding: 0 var(--pdp-gutter) 32px; }
}

/* Tablet: the phone's fixed 320px photo height turns into a 2.4:1 letterbox on a
   768px screen, and the masters are square (1600x1600) — `cover` then crops away
   two thirds of the subject. Drive the height off the width instead (66vw ~ 3:2),
   capped on the viewport so the step still reads as one screenful. Height, not
   `aspect-ratio` + `max-height`: on a full-width block Chrome honours the ratio by
   shrinking the WIDTH, which left an empty band beside the photo. */
@media (min-width: 561px) and (max-width: 835px) {
	.pdp-ps__photo { height: min(66vw, 56vh); }
}
/* Narrowest phones: 3 nowrap tabs need ~367px at 14px. Step the mono label down so
   they fit without the bar scrolling. */
@media (max-width: 400px) {
	.pdp-ps__tab { font-size: 10px; }
	.pdp-ps__tabs { gap: 6px; }
}

/* ------------------------------------------------------------ *\
	Promo Banner — urgency countdown + CTA, rendered inside the Problem panel (left column)
\* ------------------------------------------------------------ */
.pdp-promo {
	width: 100%;
	padding: 0;
}
.pdp-promo__inner {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 16px 20px;
	border-radius: 16px;
	background: linear-gradient(to right, #dc2626, #d97706);
	color: var(--bva-white);
	box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}
.pdp-promo__text {
	margin: 0;
	font: 600 16px/1.3 var(--bva-font-sans);
	text-align: center;
}
.pdp-promo__action {
	display: flex;
	align-items: center;
	gap: 12px;
	flex-shrink: 0;
}
.pdp-promo__timer {
	padding: 6px 12px;
	border-radius: 8px;
	background: rgba(255, 255, 255, 0.2);
	backdrop-filter: blur(4px);
	font: 600 18px/1 var(--bva-font-mono);
	letter-spacing: 0.05em;
}
.pdp-promo__btn {
	padding: 10px 18px;
	border: 0;
	border-radius: 9999px;
	background: var(--bva-white);
	color: #b45309;
	font: 600 14px/1 var(--bva-font-sans);
	white-space: nowrap;
	text-decoration: none;
	cursor: pointer;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
	transition: opacity 0.2s ease;
}
.pdp-promo__btn:hover { opacity: 0.9; }

@media (min-width: 561px) {
	.pdp-promo__inner { flex-direction: row; }
	.pdp-promo__text { text-align: left; }
}

.pdp-ingredients {
	margin-bottom: var(--pdp-space);
	background: var(--bva-badge-bg);
}
.pdp-ingredients__inner {
	max-width: 1440px;
	margin-inline: auto;
	padding: var(--pdp-space) 40px;
	display: flex;
	flex-direction: column;
	gap: 40px;
	color: var(--bva-black);
}
.pdp-ingredients__title {
	margin: 0;
	max-width: 570px;
	font: 500 24px/1.1 var(--bva-font-sans);
	font-weight: 600;
	text-transform: uppercase;
}
.pdp-ingredients__rows { display: flex; flex-direction: column; gap: 40px; }
.pdp-ingredients__row {
	display: grid;
	/* minmax(0, 1fr), not 1fr: the auto minimum sized the tracks on each card's
	   min-content, so the row stayed 1302px wide whatever the viewport and pushed a
	   horizontal scroll onto the whole page from 836 to 1301px. */
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 16px 19px;
	padding-top: 19px;
	border-top: 1px solid var(--bva-line);
}

.pdp-ingredient { display: flex; align-items: flex-start; gap: 16px; }
/* Shrinkable, ratio-driven: at the mock's 1440 the card is 177 + 16 + 215 = 408px,
   but both halves used to be `flex: 0 0` so a 3-up row could never go under 1302px —
   the whole PDP scrolled sideways from 836 to 1301px. Shrink (never grow) keeps the
   ISO desktop size and lets the card fit narrower columns; the ratio replaces the
   fixed 259px height so the photo scales instead of cropping harder. */
.pdp-ingredient__media {
	flex: 0 1 177px;
	width: 177px;
	/* Floor: proportional shrink alone took the thumbnail down to 48px in a 2-up
	   tablet column, which is smaller than the phone one. */
	min-width: 104px;
	aspect-ratio: 177 / 259;
	border-radius: 2px;
	background-color: var(--bva-canelle-100);
	background-size: cover;
	background-position: center bottom;
	background-repeat: no-repeat;
}
.pdp-ingredient__body {
	flex: 0 1 215px;
	width: 215px;
	min-width: 0;
	min-height: 259px;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: 16px;
}
.pdp-ingredient__head { display: flex; flex-direction: column; gap: 4px; }
/* Latin names ("Pterocarpus marsupium") set the column's min-content width — break
   them rather than let one word widen the whole grid. */
.pdp-ingredient__name { margin: 0; font: var(--bva-t-header-s); font-weight: 600; overflow-wrap: break-word; }
.pdp-ingredient__dose { font: var(--bva-t-label); text-transform: uppercase; }
.pdp-ingredient__desc p { margin: 0 0 12px; font: var(--bva-t-paragraphe); }
/* "En savoir plus" toggles the clamp on a long description (JS reveals the
   button only when the text actually overflows). */
.pdp-ingredient__text.is-clamped {
	display: -webkit-box;
	-webkit-line-clamp: 4;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.pdp-ingredient__more {
	padding: 0;
	border: 0;
	background: none;
	font: var(--bva-t-paragraphe);
	color: var(--bva-black);
	text-decoration: underline;
	cursor: pointer;
}

@media (max-width: 835px) {
	.pdp-ingredients__inner { padding: var(--pdp-space) var(--pdp-gutter); }
}
/* Outside the 3-up ISO column: give the copy an explicit 215px basis (it was `auto`,
   i.e. max-content, so the whole shrink landed on the photo and pinned it to its
   104px floor) and let it take the slack of a wider 2-up track. The 259px floor goes
   too — it only aligns the ISO desktop row, and here it opened a gap between the dose
   and the description. */
@media (max-width: 1180px) {
	.pdp-ingredient__body { flex: 1 1 215px; width: auto; min-height: 0; }
}
/* 2-up from 700 to 1180: a 3-up row can't hold the mock's 177 + 215 card under
   ~1342px (columns collapsed to ~135px of copy, so every ingredient name wrapped
   over 3-4 lines). The PHP chunks items in threes with one divider per row — in a
   2-col grid the third card of each row left a hole beside it, so flatten the rows
   into one continuous grid (`display: contents`) and carry the single divider on the
   wrapper. Single-column widths keep the per-row dividers: nothing can be orphaned. */
@media (min-width: 700px) and (max-width: 1180px) {
	.pdp-ingredients__rows {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 32px 19px;
		padding-top: 19px;
		border-top: 1px solid var(--bva-line);
	}
	.pdp-ingredients__row { display: contents; }
}
/* Below 700 a 2-up column is narrower than the phone card — stack instead. */
@media (max-width: 699px) {
	.pdp-ingredients__row { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 560px) {
	/* Shrink the thumbnail and drop the fixed 259px card height on a phone. */
	.pdp-ingredient__media { flex: 0 0 104px; width: 104px; min-width: 0; height: 152px; aspect-ratio: auto; }
}

.pdp-before-after {
	margin-bottom: var(--pdp-space);
}
.pdp-before-after__inner {
	max-width: 1440px;
	margin-inline: auto;
	padding: 0 36px;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 40px;
}
.pdp-before-after__head {
	max-width: 656px;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 8px;
	text-align: center;
}
.pdp-before-after__title { margin: 0; font: var(--bva-t-header-l); color: var(--bva-black); font-weight: 500; }
.pdp-before-after__subtitle { margin: 0; font: var(--bva-t-paragraphe); color: rgba(21, 20, 18, 0.6); }

.pdp-before-after__grid {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 16px;
}
.pdp-video {
	position: relative;
	width: 328px;
	max-width: 100%;
	border-radius: 4px;
	overflow: hidden;
	background: #000;
}
.pdp-video__poster {
	width: 100%;
	padding-top: 177.44%; /* 582 / 328 */
	background-color: var(--bva-myrtille-100);
	background-size: cover;
	background-position: center;
}
.pdp-video__controls {
	position: absolute;
	inset: auto 0 0 0;
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 16px 15px;
}
.pdp-video__controls svg { display: block; }

@media (max-width: 835px) {
	.pdp-before-after__inner { padding: 0 var(--pdp-gutter); }
}
/* Tablet only (phones keep the swipe carousel, desktop keeps the 328px mock size):
   the fixed 328px width wrapped to 2 + 1, leaving a hole beside the last video.
   One row, width shared, capped at the mock size so it never grows past it. The
   poster's padding-top ratio follows the new width — nothing is recropped. */
@media (min-width: 561px) and (max-width: 1180px) {
	/* align-self, else the row keeps its intrinsic width (the parent centres its
	   children) and `flex: 1 1 0` cards resolve to zero. */
	.pdp-before-after__grid { flex-wrap: nowrap; align-self: stretch; justify-content: center; }
	.pdp-video { flex: 1 1 0; width: auto; min-width: 0; max-width: 328px; }
}
@media (max-width: 560px) {
	/* One full-width video per view, swiped left-to-right like testimonials. */
	.pdp-before-after__grid { --pdp-carousel-card: 100%; }
}

.pdp-reviews {
	margin: 0 0 var(--pdp-space);
	padding-left: var(--bva-bleed-pad);
	display: flex;
	align-items: flex-start;
	gap: 118px;
}
.pdp-reviews__col {
	flex: 0 0 578px;
	display: flex;
	flex-direction: column;
	gap: 56px;
}
.pdp-reviews__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; }
.pdp-reviews__note { display: flex; align-items: center; gap: 12px; }
.pdp-reviews__score { font: var(--bva-t-header-l); color: var(--bva-black); white-space: nowrap; }
.pdp-reviews__note-text { margin: 0; width: 321px; font: var(--bva-t-paragraphe); color: var(--bva-black); }

.pdp-stars { display: inline-flex; align-items: center; gap: 2px; }
.pdp-stars > svg { flex: 0 0 19px; width: 19px; height: 18px; display: block; }
.pdp-star-half { position: relative; flex: 0 0 19px; width: 19px; height: 18px; }
.pdp-star-half svg { position: absolute; inset: 0; width: 19px; height: 18px; display: block; }
.pdp-star-half svg:last-child { clip-path: inset(0 50% 0 0); }

.pdp-reviews__list { display: flex; flex-direction: column; gap: 56px; }
.pdp-review-item {
	display: flex;
	justify-content: space-between;
	gap: 24px;
	padding-top: 24px;
	border-top: 1px solid var(--bva-line);
}
.pdp-review-item[hidden] { display: none; }
.pdp-review-item__meta {
	flex: 0 0 122px;
	display: flex;
	flex-direction: column;
	font: var(--bva-t-label);
	text-transform: uppercase;
	color: var(--bva-black);
}
.pdp-review-item__content { flex: 0 0 317px; display: flex; flex-direction: column; gap: 24px; }
.pdp-review-item__title { display: flex; flex-direction: column; gap: 12px; }
.pdp-review-item__stars { display: inline-flex; gap: 2px; }
.pdp-review-item__stars svg { width: 13px; height: 12px; display: block; }
.pdp-review-item__heading { margin: 0; font: var(--bva-t-header-s); color: var(--bva-black); font-weight: 600; }
.pdp-review-item__text { margin: 0; font: var(--bva-t-paragraphe); color: rgba(28, 26, 23, 0.6); }
.pdp-review-item__more {
	padding: 0;
	border: 0;
	background: none;
	font: var(--bva-t-paragraphe);
	color: rgba(28, 26, 23, 0.6);
	text-decoration: underline;
	cursor: pointer;
}

.pdp-reviews__pagination { display: flex; align-items: center; gap: 8px; }
.pdp-reviews__pagination[hidden] { display: none; }
.pdp-page {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 40px;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 1px solid rgba(0, 0, 0, 0.16);
	border-radius: 2px;
	background: none;
	font: var(--bva-t-label);
	text-transform: uppercase;
	color: var(--bva-black);
	cursor: pointer;
}
.pdp-page.is-active { background: var(--bva-black); color: var(--bva-white); border-color: var(--bva-black); }
.pdp-page--arrow { border: 0; }
.pdp-page--arrow svg { width: 24px; height: 24px; display: block; }
.pdp-page--arrow svg [stroke] { stroke: var(--bva-black); }
.pdp-page--prev svg { transform: rotate(180deg); }
.pdp-page[disabled] { opacity: 0.35; cursor: default; }
.pdp-page--ellipsis { flex: 0 0 auto; width: auto; border: 0; background: none; cursor: default; }

.pdp-reviews__media { flex: 1 1 auto; align-self: stretch; min-width: 0; }
.pdp-reviews__media-inner {
	position: sticky;
	top: 24px;
	/* Mock height, capped to the room the viewport actually leaves (900 + 24 needs
	   924px): past that the pinned block hangs under the fold for its whole pin.
	   `cover` recrops, so nothing is clipped. */
	height: min(900px, calc(100vh - 24px - 40px));
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}

/* Tablet / small laptop: the list column is a fixed 578px next to a 118px gap, so the
   full-bleed lifestyle image was down to 164px wide over 836px of height at 900 (0.2
   ratio — an unreadable crop of the master). Below the width where it can still read as
   a portrait (~1154px) drop it, like the mobile mock does, and centre the list. */
@media (min-width: 836px) and (max-width: 1180px) {
	.pdp-reviews { padding-inline: var(--bva-bleed-pad); justify-content: center; }
	.pdp-reviews__media { display: none; }
}

@media (max-width: 835px) {
	.pdp-reviews {
		flex-direction: column;
		padding: 0 var(--pdp-gutter);
		gap: 40px;
	}
	.pdp-reviews__col { flex: 1 1 auto; width: 100%; }
	/* The mobile mock drops the sticky lifestyle image — list + pagination only. */
	.pdp-reviews__media { display: none; }
}
@media (max-width: 560px) {
	/* Stack the score over its note text (fixed 321px width overflows 375px). */
	.pdp-reviews__head { flex-direction: column; gap: 16px; }
	.pdp-reviews__note-text { width: auto; }
	.pdp-reviews__list { gap: 32px; }
	.pdp-review-item { flex-direction: column; gap: 12px; }
	.pdp-review-item__content { flex: 1 1 auto; }
	/* Mock puts the author name + date BELOW the review body, not above it. */
	.pdp-review-item__meta { order: 1; }
}

.pdp-faq-image {
	max-width: 1440px;
	margin: 0 auto var(--pdp-space);
	padding: 0 40px;
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 87px;
}
.pdp-faq-image__media {
	flex: 0 0 671px;
	width: 671px;
	height: 671px;
	max-width: 48%;
	border-radius: 4px;
	background-color: var(--bva-canelle-100);
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}
.pdp-faq-image__col {
	flex: 0 1 602px;
	display: flex;
	flex-direction: column;
	gap: 40px;
}
.pdp-faq-image__title { margin: 0; font: var(--bva-t-header-l); color: var(--bva-black); font-weight: 500; }
.pdp-faq-image__list { width: 100%; }

@media (max-width: 835px) {
	.pdp-faq-image {
		flex-direction: column;
		align-items: stretch;
		gap: 32px;
		padding: 0 var(--pdp-gutter);
	}
	.pdp-faq-image__media { flex: 1 1 auto; width: 100%; max-width: none; height: auto; aspect-ratio: 1; }
	.pdp-faq-image__col { flex: 1 1 auto; }
}

.pdp-innovation {
	margin: 0 0 var(--pdp-space);
	display: flex;
	align-items: stretch;
	gap: 2px;
}
.pdp-innovation__panel {
	flex: 1 1 0;
	min-width: 0;
	padding: 40px;
	/* Left panel bleeds to the screen edge; pull its content back onto the 1440 grid (half-width panel → viewport-based) */
	padding-left: max(40px, calc(50vw - 680px));
	background: var(--bva-myrtille-500);
	color: var(--bva-white);
	display: flex;
	flex-direction: column;
}
.pdp-innovation__label { font: var(--bva-t-label); text-transform: uppercase; }
.pdp-innovation__content {
	margin-top: auto;
	width: 499px;
	max-width: 100%;
	display: flex;
	flex-direction: column;
	gap: 32px;
}
.pdp-innovation__text { display: flex; flex-direction: column; gap: 16px; }
.pdp-innovation__title { margin: 0; font: var(--bva-t-header-l); font-weight: 500; }
.pdp-innovation__desc { margin: 0; max-width: 446px; font: var(--bva-t-paragraphe); opacity: 0.6; }
.pdp-innovation__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 166px;
	height: 40px;
	border-radius: 2px;
	background: var(--bva-white);
	color: var(--bva-black);
	font: 500 12px/1.1 var(--bva-font-sans);
	text-transform: uppercase;
	text-decoration: none;
}
.pdp-innovation__media {
	flex: 1 1 0;
	min-width: 0;
	min-height: 671px;
	background-color: var(--bva-myrtille-100);
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}

@media (max-width: 835px) {
	.pdp-innovation { flex-direction: column; }
	.pdp-innovation__panel { padding: 32px var(--pdp-gutter); gap: 32px; }
	.pdp-innovation__content { margin-top: 0; width: 100%; }
	/* Mock stacks the molecular image ABOVE the dark text panel on mobile. */
	.pdp-innovation__media { min-height: 360px; order: -1; }
}
/* Same letterbox problem as the P/S/R photo: 768 x 360 crops the master to a 2.1:1
   band. Ratio-driven height, capped so it doesn't eat a whole tablet screen. */
@media (min-width: 561px) and (max-width: 835px) {
	/* flex: 0 0 auto, else the column's `flex: 1 1 0` basis collapses the block to 0
	   height and the sizing never applies. */
	.pdp-innovation__media { flex: 0 0 auto; min-height: 0; height: min(75vw, 56vh); }
}

.pdp-band {
	/* Full-width feature banner with a slim 16px gutter so it nearly touches the
	   edges (no 1440 cap). Figma 2229:9516 → x=16 in a 1440 frame. */
	margin: 0 0 var(--pdp-space);
	padding: 0 16px;
}
.pdp-band__inner {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: flex-end;
	gap: 24px;
	min-height: 690px;
	padding: 0 40px 40px;
	border-radius: 12px;
	overflow: hidden;
	background-color: var(--bva-black);
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
	text-align: center;
	color: var(--bva-white);
}
.pdp-band__inner::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.4) 75%);
	pointer-events: none;
}
.pdp-band__title-group {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 12px;
}
.pdp-band__title { margin: 0; font: 500 24px/1.1 var(--bva-font-sans); text-transform: uppercase; font-weight: 600; }
.pdp-band__subtitle { margin: 0; max-width: 600px; font: var(--bva-t-paragraphe); }
.pdp-band__link {
	position: relative;
	z-index: 1;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 166px;
	height: 40px;
	border-radius: 2px;
	background: var(--bva-white);
	color: #0c0c0c;
	font: 500 14px/1.3 var(--bva-font-sans);
	text-transform: uppercase;
	text-decoration: none;
}

@media (max-width: 835px) {
	.pdp-band__inner { min-height: 480px; padding: 0 var(--pdp-gutter) 32px; }
}

.pdp-journal {
	max-width: 1440px;
	margin: 0 auto var(--pdp-space);
	padding: 0 40px;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 32px;
}
.pdp-journal__title {
	margin: 0;
	width: 100%;
	font: 500 24px/1.1 var(--bva-font-sans);
	font-weight: 600;
	text-transform: uppercase;
	text-align: center;
	color: var(--bva-black);
}
.pdp-journal__grid {
	width: 100%;
	display: grid;
	/* 4-up at 1440 (331px cards), one column less as the room runs out. */
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	align-items: start;
	gap: 12px;
}
.pdp-journal__card {
	display: flex;
	flex-direction: column;
	gap: 16px;
	color: var(--bva-black);
	text-decoration: none;
}
.pdp-journal__media {
	display: block;
	width: 100%;
	aspect-ratio: 331 / 265;
	border-radius: 4px;
	background-color: var(--bva-myrtille-100);
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}
/* Mock staggers the grid: even cards (2,4) are taller than odd (1,3) */
.pdp-journal__card:nth-child(even) .pdp-journal__media { aspect-ratio: 331 / 321; }
.pdp-journal__content { display: flex; flex-direction: column; gap: 12px; }
.pdp-journal__category { font: var(--bva-t-label); text-transform: uppercase; }
.pdp-journal__heading { font: var(--bva-t-header-s); font-weight: 600; }
a.pdp-journal__card:hover .pdp-journal__heading { text-decoration: underline; }

@media (max-width: 835px) {
	.pdp-journal { padding: 0 var(--pdp-gutter); }
	.pdp-journal__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 12px; }
}
@media (max-width: 560px) {
	/* Swipeable carousel (.pdp-carousel): ~1.5 cards in view. */
	.pdp-journal__grid { --pdp-carousel-card: 66%; }
	/* Flatten the desktop stagger so carousel cards share one height. */
	.pdp-journal__card:nth-child(even) .pdp-journal__media { aspect-ratio: 331 / 265; }
}

/* ------------------------------------------------------------ *\
	Price box — price + offers-CTA encart inside the hero info column,
	swapped in for the description's price line. Self-contained accent
	(--pricebox-*); clear the "Prix mis en avant" field to restore the
	V3 price line + classic buy button.
\* ------------------------------------------------------------ */

/* When the encart is on: hide the description's price line (last paragraph) and the
   add-to-cart form (kept in the DOM — the popup needs #form-cart / #cart-product-id). */
.pdp-info--pricebox .pdp-desc > p:last-child { display: none; }
.pdp-info--pricebox .pdp-cart { display: none; }

.pdp-pricebox {
	--pricebox-accent: var(--bva-vitamine-400);
	/* Cream surface = same as the page, so the box fades out and only the
	   price + CTA read on the canela background. */
	--pricebox-surface: var(--bva-canelle-100);
	font-family: var(--bva-font-sans);
	color: var(--bva-black);
}
.pdp-pricebox__card {
	width: 100%;
	padding: 8px 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 24px;
	background: var(--pricebox-surface);
	text-align: center;
}
.pdp-pricebox__price {
	margin: 0;
	font: 400 28px/1.2 var(--bva-font-sans);
}
.pdp-pricebox__amount {
	color: var(--pricebox-accent);
	font-weight: 600;
	font-size: 1.4em;
}
.pdp-pricebox__unit { color: var(--bva-black); }

/* Match the maquette's primary CTA (.pdp-btn-cart): black, square-ish, same height/typo. */
.pdp-pricebox__cta {
	width: 100%;
	height: 60px;
	border: 0;
	border-radius: 2px;
	background: var(--bva-black);
	color: var(--bva-white);
	font: var(--bva-t-paragraphe);
	text-align: center;
	cursor: pointer;
	transition: opacity 0.15s ease;
}
.pdp-pricebox__cta:hover { opacity: 0.9; }

/* ------------------------------------------------------------ *\
	Mobile carousel — reusable horizontal scroll-snap primitive.
	A grid opts in with .pdp-carousel and sets the card width via
	--pdp-carousel-card (default 84%); the bleed is derived from
	--pdp-gutter so the row reaches the screen edge and the next card
	peeks, regardless of the section's gutter. The dashes indicator
	(.pdp-carousel-dots) is injected by product.js, one dash per card.
\* ------------------------------------------------------------ */
.pdp-carousel-dots { display: none; }

@media (max-width: 560px) {
	.pdp-carousel {
		display: flex;
		flex-wrap: nowrap;
		/* flex-start, not the grids' desktop justify-content (e.g. center on
		   before-after) — centring traps the first card off the scroll origin. */
		justify-content: flex-start;
		align-self: stretch;
		gap: 12px;
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		margin-inline: calc(-1 * var(--pdp-gutter));
		padding-inline: var(--pdp-gutter);
		scrollbar-width: none;
	}
	.pdp-carousel::-webkit-scrollbar { display: none; }
	.pdp-carousel > * { flex: 0 0 var(--pdp-carousel-card, 84%); scroll-snap-align: start; }

	/* Breathing room so the dashes don't butt against the next section (e.g. the
	   footer FAQ right below the journal carousel). */
	.pdp-carousel-dots { display: flex; justify-content: center; gap: 4px; margin: 24px 0; }
	.pdp-carousel-dots__dot {
		width: 24px;
		height: 2px;
		padding: 0;
		border: 0;
		background: rgba(0, 0, 0, 0.16);
		cursor: pointer;
	}
	.pdp-carousel-dots__dot.is-active { background: var(--bva-black); }
}

/* ------------------------------------------------------------ *\
	Sticky add-to-cart — mobile-only bar pinned to the bottom of the
	viewport, revealed by JS (.is-visible) once the hero CTA scrolls out
	of view. Opens the same offers popup as the hero (.btn-add-cart).
\* ------------------------------------------------------------ */
.pdp-sticky-cart {
	position: fixed;
	inset: auto 0 0 0;
	z-index: 60;
	display: none;
	padding: 12px var(--pdp-gutter);
	padding-bottom: calc(12px + env(safe-area-inset-bottom));
	background: var(--bva-canelle-100);
	box-shadow: 0 -2px 16px rgba(0, 0, 0, 0.1);
}
.pdp-sticky-cart__btn {
	width: 100%;
	height: 56px;
	border: 0;
	border-radius: 2px;
	background: var(--bva-black);
	color: var(--bva-white);
	font: var(--bva-t-paragraphe);
	text-align: center;
	cursor: pointer;
	transition: opacity 0.15s ease;
}
.pdp-sticky-cart__btn:hover { opacity: 0.9; }
@media (max-width: 835px) {
	.pdp-sticky-cart.is-visible { display: block; }
	/* Hide the sticky buy-bar while any full-screen overlay is open — the
	   drawer, search and offers popup all add body.no-scroll. Belt-and-suspenders
	   with the drawer's z-index:80 lift so the bar never shows over an overlay. */
	body.no-scroll .pdp-sticky-cart { display: none; }
}
