/**
 * rc-pdp-rebrand.css — Rebrand PDP (M6 · desktop-first).
 *
 * Styles single-product-rebrand.php. Gated behind the rebrand gate + is_product()
 * (see routinecos-styles.php topic 'rc-styles-pdp-rebrand'). Tokens come from
 * rc-brand.css (--rc-navy, --rc-red, type ramp, --rc-scent-* pairs, --rc-scale).
 *
 * WORKSTREAM 1: page frame — Free Travel banner + two-column desktop layout +
 * stub placeholders. Section internals (gallery, stars, stats, swatches, toggle)
 * are styled in their own workstreams.
 */

/* ── Two-column layout ───────────────────────────────────────────────────── */
.rc-pdp {
	font-family: var(--rc-font);
	color: var(--rc-navy);
	max-width: 1200px;
	margin: 0 auto;
	padding: 40px 24px 64px;
}
.rc-pdp__grid {
	display: grid;
	/* Buy-box column scales with the zoom dial so the whole right column reads at
	   the same 1.25× as the rest of the site (the gallery column flexes). */
	grid-template-columns: minmax(0, 1fr) calc(436px * var(--rc-scale));
	gap: calc(56px * var(--rc-scale));
	align-items: start;
}

/* Left column (gallery) — sticky so the buy box can scroll past a tall gallery.
   Same header clearance as the review chips (2026-09-09): the 24px gap is now measured from
   the bottom of the pinned primary nav rather than from the viewport top, so a tall gallery
   parks below the header instead of behind it. --rc-navh is published on :root by the sticky
   nav controller in footer-rebrand.php; 0px fallback keeps the old behaviour without it. */
.rc-pdp__gallery {
	position: sticky;
	top: calc(var(--rc-navh, 0px) + 24px);
}

/* ── Gallery (WS3): square stage + thumbnail strip (no arrows/dots on desktop) ─ */
.rc-gallery { display: flex; flex-direction: column; gap: calc(16px * var(--rc-scale)); }
.rc-gallery__stage {
	position: relative;
	width: 100%;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	/* White, not a tint. Most product and campaign artwork is a transparent PNG -- 600 of the
	   617 originals in the September batch -- so whatever sits here IS the background the
	   shopper sees behind the bottle, not a neutral field that only shows while an image
	   loads. At #f4f4f4 that read as a grey box against the white page. */
	background: #ffffff;
}
.rc-gallery__img {
	width: 100%;
	height: 100%;
	/* Swipe/drag support (rc-pdp.js). `pan-y` hands the browser the vertical axis so the page
	   still scrolls under a mostly-vertical touch, while we claim horizontal for paging — the
	   default `auto` would let the browser consume the horizontal gesture too.
	   The image also has to stop being draggable: a mouse drag on an <img> otherwise starts a
	   native image drag, which swallows pointerup and kills the desktop gesture. */
	touch-action: pan-y;
	-webkit-user-drag: none;
	-webkit-user-select: none;
	user-select: none;
	/* Crop today's portrait masters to square; real square art will fit cleanly. */
	object-fit: cover;
	object-position: center;
	display: block;
}
/* y808 "whole carousel should be here, shouldn't need to scroll to see images":
   desktop lays the thumbs out as a 4-wide GRID under the hero instead of a scrolling strip.
   Sized at the tile's natural 72px (x dial) and centred, per Moiz's "same size and just center
   below hero image" — deliberately NOT stretched to the stage width.
   Count: thumb 0 is the live per-scent hero + the product gallery images, so the intended set is
   8 (1 + 7) = exactly two rows. Products with more (Hair & Scalp Serum has 9 today) wrap to a
   third row rather than hiding images; products with fewer just part-fill the last row. */
.rc-gallery__thumbs {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(4, calc(72px * var(--rc-scale)));
	justify-content: center;
	gap: calc(12px * var(--rc-scale));
}
.rc-gallery__thumbs::-webkit-scrollbar { display: none; }
/* Pager dots are a MOBILE affordance — the desktop comp navigates with the thumb grid and
   draws no pager, so the container ships at every width but only paints below the
   breakpoint (see the mobile block). */
.rc-gallery__dots { display: none; }
.rc-gallery__thumb {
	flex: 0 0 auto;
	width: calc(72px * var(--rc-scale));   /* Figma thumb ≈ 64.6px × zoom dial */
	height: calc(72px * var(--rc-scale));
	padding: 0;
	border: 1px solid rgba(5, 38, 79, 0.15);
	border-radius: 0;
	background: #f4f4f4;
	cursor: pointer;
	overflow: hidden;
}
.rc-gallery__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* DESKTOP: one row of 8 (team request 2026-09-11), replacing the 4-across/2-row grid above.
   The second row sat below the fold on a MacBook Pro because .rc-pdp__gallery is sticky —
   the hero stays put until the buy-box column has scrolled past, so the thumbs never came
   up to meet the reader.

   Eight tracks of 1fr rather than a fixed thumb width: the gallery column is whatever is
   left of the 1152px content box after the 436px buy-box and the 56px gap, both of which
   are multiplied by --rc-scale, so a hardcoded size would be wrong at any other dial or
   container width. At today's 1.25x that computes to ~54px per thumb, down from 90px —
   smaller is the cost of a single row, and it is the trade the team asked for.

   Supersedes Moiz's earlier "same size and just center below hero image" (which is what the
   4-across centred grid above implements) — that note is older than this request. */
@media (min-width: 1025px) {
	.rc-gallery__thumbs {
		grid-template-columns: repeat(8, minmax(0, 1fr));
		justify-content: stretch;
	}
	/* The track sizes the thumb now; aspect-ratio keeps it square as it flexes. */
	.rc-gallery__thumb {
		width: auto;
		height: auto;
		aspect-ratio: 1;
	}
}
.rc-gallery__thumb.is-active { border-color: var(--rc-navy); }
.rc-pdp .rc-gallery__thumb:hover,
.rc-pdp .rc-gallery__thumb:focus { background: #f4f4f4 !important; border-color: var(--rc-navy); outline: none; }

/* Right column (buy box) — fixed 436px per comp. The top info block
   (stars · title · description · stats) is centered per Figma. */
.rc-pdp__buybox {
	display: flex;
	flex-direction: column;
	/* Published as a variable so a single seam can cancel it with a negative margin
	   (see the coupon -> ADD TO CART seam below) without hardcoding the number twice. */
	--rc-buybox-gap: calc(20px * var(--rc-scale));
	gap: var(--rc-buybox-gap);
}

/* ── Dynamic title + description (WS4) — Figma: H1 30/33 Medium, Large Body 16/24 ── */
/* h1.rc-pdp__title + !important: the theme's product-title h1 forces UPPERCASE + bold
   + an oversized font that otherwise wins — pin it to the comp (Title Case, Medium). */
.rc-pdp h1.rc-pdp__title {
	margin: 0;
	font-size: var(--rc-text-h1-size) !important;   /* 30 × scale */
	line-height: var(--rc-text-h1-lh) !important;   /* 33 × scale */
	font-weight: var(--rc-weight-medium) !important;
	text-transform: none !important;                /* comp is Title Case, not caps */
	color: var(--rc-navy);
	text-align: center;
}
.rc-pdp__subtitle {
	font-size: calc(16px * var(--rc-scale));         /* Figma "Desktop/Large Body Copy" 16/24 */
	line-height: calc(24px * var(--rc-scale));
	font-weight: var(--rc-weight-regular);
	color: var(--rc-navy);
	text-align: center;
}
/* Set color on the <p> directly with extra specificity — the theme has a
   generic `p { color:#666 }` that otherwise wins over the wrapper. */
.rc-pdp .rc-pdp__subtitle p,
.rc-pdp .rc-pdp__subtitle li {
	margin: 0;
	color: var(--rc-navy);
}

/* ── Star summary + review count (WS4) ───────────────────────────────────── */
.rc-stars {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	text-decoration: none;
	align-self: center; /* centered in the column, per Figma */
}
.rc-stars__wrap {
	position: relative;
	display: inline-block;
	font-size: calc(16px * var(--rc-scale));
	line-height: 1;
	letter-spacing: 2px;
	white-space: nowrap;
}
.rc-stars__off { color: rgba(5, 38, 79, 0.18); }
.rc-stars__on {
	position: absolute;
	top: 0;
	left: 0;
	width: var(--rc-rating, 0%);
	overflow: hidden;
	color: var(--rc-red);
}
.rc-stars__count {
	font-size: var(--rc-text-body-size);
	font-weight: var(--rc-weight-medium);
	letter-spacing: 1px;
	text-transform: uppercase;
	color: var(--rc-red);
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* ── Stats / percentage row (WS4) ────────────────────────────────────────── */
.rc-stats {
	display: flex;
	align-items: stretch;
	gap: 0;
	margin: 4px 0;
}
.rc-stats__item {
	flex: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: calc(4px * var(--rc-scale));
	padding: 0 calc(14px * var(--rc-scale));
	text-align: center;
}
.rc-stats__item + .rc-stats__item {
	border-left: 1px solid rgba(5, 38, 79, 0.2);
}
.rc-stats__value {
	font-size: var(--rc-text-h2-size);   /* 32 */
	line-height: 1;
	font-weight: var(--rc-weight-regular); /* Figma: Jost Regular 400 (not Medium) */
	color: var(--rc-navy);
}
.rc-stats__label {
	font-size: calc(10px * var(--rc-scale));   /* Figma "Desktop/Descriptor" 10/14 Medium */
	line-height: calc(14px * var(--rc-scale));
	letter-spacing: 0.4px;
	text-transform: uppercase;
	font-weight: var(--rc-weight-medium);
	color: var(--rc-navy);               /* Figma #05264F (was 0.7 opacity) */
}

/* ── Price line (WS5; updated live by rc-pdp.js) ─────────────────────────── */
.rc-pdp__price {
	font-size: var(--rc-text-product-size);
	line-height: var(--rc-text-product-lh);
	font-weight: var(--rc-weight-medium);
	color: var(--rc-navy);
}
.rc-pdp__price .amount { font-weight: var(--rc-weight-medium); }
.rc-pdp__price del { opacity: 0.5; margin-right: 6px; font-weight: var(--rc-weight-regular); }

/* ── SELECT SCENT (WS5) ──────────────────────────────────────────────────── */
.rc-scents { margin: 4px 0; }

/* Section label with side rules ("SELECT SCENT"). */
.rc-scents__label {
	display: flex;
	align-items: center;
	gap: calc(14px * var(--rc-scale));
	margin-bottom: calc(16px * var(--rc-scale));
	color: var(--rc-navy);
}
.rc-scents__label::before,
.rc-scents__label::after {
	content: "";
	flex: 1;
	height: 2px;
	background: #D7F9FB;
}
.rc-scents__label span {
	text-transform: uppercase;
	letter-spacing: 0.33px;
	font-size: calc(11px * var(--rc-scale));   /* Figma: Jost SemiBold 11/14 #868787 */
	font-weight: var(--rc-weight-semibold);
	color: #868787;
}

/* Swatch grid — 4 up per the comp. */
.rc-scents__grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: calc(12px * var(--rc-scale));
}

/* Group divider ("Limited Edition Scents 🔥") spans the full grid width.
   Per Figma this is centered text only — NO side rules (unlike SELECT SCENT). */
.rc-scents__header {
	grid-column: 1 / -1;
	display: flex;
	align-items: center;
	justify-content: center;
	margin: 4px 0;
	color: var(--rc-navy);
}
.rc-scents__header span {
	text-transform: uppercase;
	letter-spacing: 0.33px;                /* Figma: SemiBold 11/14 navy */
	font-size: calc(11px * var(--rc-scale));
	font-weight: var(--rc-weight-semibold);
	color: var(--rc-navy);
	white-space: nowrap;
}

/* One tile = white CARD (rounded, bordered, drop shadow) wrapping a SQUARE color
   swatch (sharp corners) + the name below — per Figma. The card owns the rounding
   and shadow; the swatch is sharp. --rc-swatch-tint is set inline (token, DB-hex fallback). */
.rc-scent {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	padding: 0;
	cursor: pointer;
	font-family: var(--rc-font);
	text-align: center;
	background: var(--rc-white, #fff);
	border: 1px solid rgba(5, 38, 79, 0.12);
	border-radius: 0;                      /* fully square tile (swatch + name card) */
	overflow: hidden;
	box-shadow: 0 2px 8px rgba(5, 38, 79, 0.10);
	transition: box-shadow 0.12s ease, border-color 0.12s ease;
	/* Logo tint (Path B): wordmark = scent primary (the tile tint); arc = secondary,
	   set inline per tile (--rc-logo-arc: token or lightened primary). */
	--rc-logo-primary: var(--rc-swatch-tint);
}
/* The tile is a <button>, so the theme's `button { margin-bottom: 20px }` applies to it —
   and grid rows size to the item's MARGIN box, not its border box. MEASURED: every row was
   148.9px tall against a 128.9px tile, i.e. ~20px of dead space under every scent row, so the
   grid read with an 11px horizontal gutter and a 31px vertical one. Zeroing the margin takes
   the rows to 128.9 and the whole grid from 503 -> 443px at 390px wide; tile and name-card
   heights are unchanged. Same root cause and same fix as .rc-offer__ddbtn above — assume this
   trap on any PDP control we render as a <button>.
   NB: this corrects DESKTOP as well as mobile; the dead space was present at every width. */
.rc-pdp .rc-scent { margin: 0; }

/* Scent-colored swatch holding the bottle art. Landscape ~100:74 per Figma
   (the colored area = badge zone + field). Sharp corners — the card provides the
   rounding + shadow. */
.rc-scent__field {
	position: relative;
	display: block;
	width: 100%;
	aspect-ratio: 100 / 74;
	background: var(--rc-swatch-tint, #ccc);
	overflow: hidden;
}

/* Bottles are sized by WIDTH and anchored to the TOP (below the badge zone), tall
   enough that their lower body is CROPPED at the swatch bottom — per comp. This
   keeps the pump + logo in view with little empty white beneath the logo. */
.rc-scent__bottles {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: flex-start;
	justify-content: center;
	gap: 3%;
	/* Uniform top offset = the banner zone, reserved on EVERY tile so the banner
	   never shifts the bottles (badged vs un-badged tiles align — per Figma).
	   No sides/bottom → bigger bottles, cropped at the swatch edge. */
	padding: 19% 0 0;
}
/* Each bottle = white base image + logo overlay positioned to the measured
   footprint on the render (left 11% / top 30.5% / width 78% of the bottle). */
.rc-scent__bottle {
	position: relative;
	display: block;
	width: 40%;
}
.rc-scent__bottle-img {
	display: block;
	width: 100%;
	height: auto;
}
.rc-scent__logo {
	position: absolute;
	left: 11%;
	top: 30.5%;
	width: 78%;
	height: auto;
	overflow: visible;   /* the tagline sits above the viewBox origin */
}
/* Single-pack (Shampoo / Conditioner): one centered bottle; the combo shows two.
   rc-pdp.js flips data-pack-bottles on the container per pack change. */
.rc-scents[data-pack-bottles="single"] .rc-scent__bottle--2 { display: none; }
.rc-scents[data-pack-bottles="single"] .rc-scent__bottle { width: 46%; }

/* Art that holds the PAIR in ONE image (the 3oz travel set): it carries its own margins, so it
   takes the whole swatch rather than 40% of it, and the pack toggle must not shrink it to 46%.
   Its two logo lockups are positioned individually from PHP -- see rc_scent_bottle_art -- so
   the `left/top/width` above is overridden per lockup rather than applying to both. */
/* MEASURED, not guessed (Round 5 #9, 2026-09-25 — "more space above bottle").
   At 8% the travel pair's caps sat flush under the badge band: rendered field 123x91, badge
   20 tall, image square at 123 with its own 8.9% top margin, which put the visible cap at
   20.85px — a 0.85px gap, 0.9% of the field. Figma `1317:4519` draws the same tile at 100x74
   with a 12px badge and the caps at y19, i.e. a 7px gap = 9.5% of the field.
   Matching the comp's GAP rather than its absolute cap position, because our badge renders
   taller than the comp's (22% of the field against 16.2%) and the two targets cannot both be
   hit; the gap is what the ask is about. 9.5% of 91 = 8.65px, so the image must start
   8.65 + 20 - 10.95 = 17.7px down, and padding-% resolves against the container WIDTH (123),
   giving 14.4%. Bottles still crop at the swatch bottom, which is the comp's own treatment.
   Un-badged tiles move with them: the banner zone is reserved on every tile so a badge never
   shifts the artwork, and the comp keeps its un-badged tiles on the same line. */
.rc-scent__bottles--pair { padding-top: 14.4%; }
.rc-scents[data-pack-bottles] .rc-scent__bottle--pair,
.rc-scent__bottle--pair { width: 100%; }

/* Badge ribbon — full-width strip at the top of the swatch (source:
   routinecos_badges_config). Lighter tint of the scent color, scent-color text.
   Bottles drop below it when a tile is badged. */
.rc-scent__badge {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	z-index: 1;
	padding: calc(4px * var(--rc-scale)) calc(4px * var(--rc-scale));
	text-align: center;
	font-size: calc(8px * var(--rc-scale));
	line-height: 1;
	font-weight: var(--rc-weight-semibold);
	letter-spacing: 0.3px;
	text-transform: uppercase;
	color: var(--rc-swatch-tint, var(--rc-navy));
	background: color-mix(in srgb, var(--rc-swatch-tint) 28%, #fff);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.rc-scent__name {
	/* The tiles are grid items, so every tile in a row stretches to the tallest — a two-line name
	   ("Jasmine & Orange Blossom") made its whole row taller. The name card did not grow with it,
	   so a one-line neighbour (Unscented) was left with ~18px of bare tile below the card. That
	   was invisible while the card was white; filling it with the scent tint on selection (y556)
	   turned it into a white rectangle. Two parts to the fix:
	   1. flex-grow, so the card always reaches the bottom of its tile — no slack to show;
	   2. reserve two lines, so one- and two-line names give identical tiles in EVERY row, not
	      just within a row. Names longer than two lines would still grow the row (none today). */
	flex: 1 1 auto;
	display: flex;
	/* Column + stretch, so text-align does the horizontal centering — see .rc-packs__name. */
	flex-direction: column;
	align-items: stretch;
	justify-content: center;
	text-align: center;
	min-height: calc(46px * var(--rc-scale));   /* 2 x 13px line-height + 9px/11px padding */
	padding: calc(9px * var(--rc-scale)) calc(6px * var(--rc-scale)) calc(11px * var(--rc-scale));
	font-size: calc(11px * var(--rc-scale));   /* Figma: Jost SemiBold 11, Title Case, scent-colored */
	line-height: calc(13px * var(--rc-scale));
	letter-spacing: 0.3px;
	font-weight: var(--rc-weight-semibold);
	color: var(--rc-swatch-tint, var(--rc-navy));
	text-transform: none;                  /* override the theme's global button uppercase — comp is Title Case */
}
/* Keep the card white on hover/focus/active — the theme's global button:hover /
   :focus / :active paint the background blue with !important, so override in kind.
   This half has to keep :focus and :active, or a clicked tile goes blue. */
.rc-pdp .rc-scent:hover,
.rc-pdp .rc-scent:focus,
.rc-pdp .rc-scent:active,
.rc-pdp .rc-scent:focus-visible {
	background: var(--rc-white, #fff) !important;
}
/* The scent-coloured edge is a HOVER affordance ONLY (2026-09-09, Daniel: "if I click and
   drag the mouse, the selected item has a CSS state that gives it a thick border — that
   border is not needed"). It used to sit on :focus and :active too, so a tile kept a
   coloured border after any mouse click, and a drag that merely STARTED on a tile focused
   it without ever selecting it — leaving a persistent border on a tile the user had not
   chosen. Pointer focus sticks until something else takes it, so it never cleared. */
.rc-pdp .rc-scent:hover { border-color: var(--rc-swatch-tint, var(--rc-navy)); }
/* Keyboard focus still needs a visible ring. :focus-visible fires for the keyboard but not
   for a mouse press — exactly the distinction that was missing. !important clears the
   blanket `.rc-pdp button:focus-visible { outline: none !important }` further down. */
.rc-pdp .rc-scent:focus-visible {
	outline: 2px solid var(--rc-navy) !important;
	outline-offset: 2px;
}
/* ...and a mouse press leaves nothing behind. */
.rc-pdp .rc-scent:focus:not(:focus-visible) { outline: none !important; }
/* Selected state. Spec is PDP Figma `631:313` (and `322:508` for the Fall Seasonal scents),
   which Daniel linked on 2026-09-09 for the review item "Selected scent card should be
   secondary color (what we're using for the arches)".
   SAMPLED from those nodes rather than eyeballed: the selected tile's edge is #05264F —
   brand navy, 3px — NOT the scent colour the ring used to be drawn in. It was briefly
   removed the same day and then put back, on the comp's authority: it is a deliberate
   heavy edge, not an accident.
   OUTLINE, not box-shadow. Two active custom-css-js snippets (9076797 "shop category /
   checkout / homepage" and 9651363 "Admin top search FOOTER #2") each ship a site-wide
   `* { box-shadow: none !important }`, so every box-shadow on this page — including the ring
   this rule used to draw, and .rc-scent's own resting shadow — is dead. VERIFIED via
   getComputedStyle: box-shadow resolves to `none` on the selected tile. That is the real
   reason y556 had to move the selected state onto the name card.
   1px border + 2px outline = the 3px navy edge measured in Figma, and outline is drawn
   outside the border box so it costs no layout. !important clears
   `.rc-pdp button:hover/:focus/:active { outline: none !important }` further down — which is
   also why the states are restated immediately below. */
.rc-scent.is-active {
	border-color: var(--rc-navy);
	outline: 2px solid var(--rc-navy) !important;
	outline-offset: 0;
}
/* The selected tile keeps looking selected while it is hovered or pressed. Without this the
   hover rule above (0,3,0) outranks `.rc-scent.is-active` (0,2,0) and repaints the border in
   the scent colour, while `.rc-pdp button:hover { outline: none !important }` drops the navy
   ring — so just moving the mouse over the chosen tile un-indicated the selection.
   MEASURED before that fix, via forced pseudo-states: every one of :hover / :focus / :active /
   :focus-visible resolved to `border: 1px solid rgb(160,35,126); outline: none`. */
.rc-pdp .rc-scent.is-active:hover,
.rc-pdp .rc-scent.is-active:focus,
.rc-pdp .rc-scent.is-active:active,
.rc-pdp .rc-scent.is-active:focus-visible {
	border-color: var(--rc-navy);
	outline: 2px solid var(--rc-navy) !important;
	outline-offset: 0;
}
/* y556 "click effect on white background so you know what you've selected" put the selected
   state on the WHITE name card. It filled the card with the scent PRIMARY and inverted the
   label to white; Figma fills it with the scent's lighter SECONDARY and keeps the label in
   the primary — which is what the review asked for.
   `--rc-logo-arc` is exactly "what we're using for the arches": scents.php sets it per tile
   to the per-scent secondary token when one exists, else a lightened primary. Reusing that
   variable (rather than a second color-mix here) means the card and the logo arc can never
   drift, and both upgrade the moment Michelle's real --rc-scent-secondary-* tokens land.
   RESOLVED 2026-09-10 (#45, Stephanie: "contrast isn't great"): the fallback is now 28%, the
   value Figma's cards measure (Rose Hips #EFB9E0), instead of 45% which rendered #D58CC4 and
   left the full-strength tint text sitting on too close a background. Changed in BOTH places
   that spell it — scents.php's inline --rc-logo-arc and the fallback below — which must stay
   in step. Real --rc-scent-secondary-* tokens, when they land, override both and are used as
   authored. */
.rc-scent.is-active .rc-scent__name {
	background: var(--rc-logo-arc, color-mix(in srgb, var(--rc-swatch-tint) 28%, #fff));
	color: var(--rc-swatch-tint, var(--rc-navy));
}

/* ── Tiles built from delivered per-scent artwork ───────────────────────────────────
   Everything above assumes Path B: a white bottle base recolored by an overlaid logo,
   which only works over a saturated field. Where the real product renders have been
   delivered (scents.php sets .rc-scents--art when EVERY tile in the grid has one), the
   comps invert that — a full-colour product render over the LIGHT field, selection carried
   by the name card. Built so far: Leave-In Conditioner (`1168:486` / `1170:495` / `1170:502`)
   and Hydrating Hair Mask (`1168:464` / `1168:472` / `1168:479`).

   Field = the scent's own --rc-scent-<slug>-bg, exactly (Rose Hips #EFB9E0, Coconut &
   Vanilla #F3CEB2 — both already in rc-brand.css, and both what the comps measure at 4x).

   The art carries its own placement. Each asset IS the field box: a transparent 100:74
   canvas with the product already scaled and positioned where the comp puts it, overflow
   cropped into the file. So this rule needs no per-product numbers, which is the point —
   the Leave-In bottle is 34.75% of the field wide and hangs off the bottom, the Hair Mask
   jar is 69% and sits low, and both are just `width: 100%` here. Where a new product's
   subject goes is a design decision, and it belongs in the artwork with the designer, not
   in a magic percentage in this file. Prep recipe: images/rebrand/README.md.

   `height: auto`, NOT `height: 100%`. MEASURED: a percentage height resolves to auto
   against .rc-scent__field, whose own height comes from aspect-ratio and is not definite
   for a percentage child — an earlier cut set `height: 160%`, got auto, fell back to the
   file's intrinsic size, hit the theme's `img { max-width: 100% }` and rendered 123x368 in
   a 123x91 field, so only the bottle's white cap ever showed. Width resolves fine, and the
   canvas shares the field's 100:74 ratio, so auto height lands exactly on the field.

   The comps themselves draw no border in either state, but the edges stay (Daniel,
   2026-09-18): unselected keeps the 1px light-grey hairline, selected keeps the 3px #05264F
   edge the rest of the PDP uses. Both come from the shared .rc-scent rules above — art mode
   only changes what fills the name card — so there is nothing to restate here. */
.rc-scents--art .rc-scent__field { background: var(--rc-swatch-bg, var(--rc-swatch-tint, #ccc)); }

/* Shared by BOTH selectors' art tiles — .rc-scent__field here and .rc-packs__field below.
   The asset is the field box, so there is exactly one rule and no per-product geometry. */
.rc-tile-art {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: auto;
}
.rc-scents--art .rc-scent.is-active .rc-scent__name {
	background: var(--rc-swatch-tint, var(--rc-navy));
	color: var(--rc-white, #fff);
}

/* Scent tiles are NEVER hidden or dimmed — the grid always shows the full scent range.
   Moiz, 2026-09-10 (#39): "When selecting CONDITIONER I wouldn't hide Wildflower & Christmas
   Eve. I would just make it so you go to shampoo and conditioner if you select either of
   those." Picking a scent the current pack does not carry switches the PACK (rc-pdp.js,
   setScent -> firstPackForScent), so there is nothing to gate here.

   This replaced a `display: none` rule, and rc-pdp.js no longer sets .is-unavailable on a
   tile at all. Third call on this axis (09-03 "revert to existing logic", 09-08 "don't grey
   out, should be removed", now this) and the first that is not a hide rule — so re-hiding
   scents is new feedback, not a restoration. Availability now lives entirely on the pack
   row below. */

/* ── SELECT PRODUCT / pack-type toggle (WS6) ─────────────────────────────── */
.rc-packs { margin: 4px 0; }
.rc-packs__label {
	display: flex;
	align-items: center;
	gap: calc(14px * var(--rc-scale));
	margin-bottom: calc(14px * var(--rc-scale));
	color: var(--rc-navy);
}
.rc-packs__label::before,
.rc-packs__label::after {
	content: "";
	flex: 1;
	height: 2px;
	background: #D7F9FB;
}
.rc-packs__label span {
	text-transform: uppercase;
	letter-spacing: 0.33px;
	font-size: calc(11px * var(--rc-scale));   /* Figma: Jost SemiBold 11/14 #868787 (matches SELECT SCENT) */
	font-weight: var(--rc-weight-semibold);
	color: #868787;
}
.rc-packs__grid {
	display: flex;
	gap: calc(10px * var(--rc-scale));
}
.rc-packs__btn {
	flex: 1;
	padding: calc(12px * var(--rc-scale)) calc(8px * var(--rc-scale));
	font-family: var(--rc-font);
	font-size: calc(16px * var(--rc-scale));   /* y1344: was 13px (=16.25 at the dial), asked for 20 */
	line-height: 1.1;
	font-weight: var(--rc-weight-medium);
	color: var(--rc-navy);
	background: var(--rc-white);
	border: 1px solid rgba(5, 38, 79, 0.25);   /* unselected: light navy hairline per comp */
	border-radius: 0;                          /* square per comp */
	text-transform: none;                      /* comp is Title Case (theme uppercases buttons) */
	cursor: pointer;
	transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.rc-packs__btn:hover { border-color: var(--rc-navy); }
.rc-packs__btn.is-active {
	background: var(--rc-navy);
	color: var(--rc-white);
	border-color: var(--rc-navy);
}

/* Single-option toggle: it is a confirmation of what is being bought rather than a
   choice, so it carries the price — name left, price right, as production renders the
   Complete Bundle. A modifier class rather than :has(), which the theme's older browser
   floor cannot be assumed to support. Multi-option toggles never get it. */
/* Packs the SELECTED SCENT is not sold in are hidden — but they keep their slot, so the
   remaining option does NOT stretch to fill the row.

   `visibility: hidden` rather than `display: none` is the whole point of the rule. Moiz,
   2026-09-10 (#37): "When selecting Christmas Eve, I wouldn't resize Shampoo & Conditioner
   box. I would just hide Shampoo/Conditioner and leave boxes as is." The buttons are
   `flex: 1` inside a flex row, so display:none handed the survivor the full width and the
   box visibly grew on every scent change — that resize is what the comment is about.
   visibility:hidden also drops the button from the tab order, and rc-pdp.js sets `disabled`
   besides. Do not "simplify" this back to display:none. */
.rc-packs__btn.is-unavailable {
	visibility: hidden;
}

.rc-packs__btn--priced {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: calc(12px * var(--rc-scale));
	text-align: left;
}
.rc-packs__price {
	font-weight: var(--rc-weight-semibold);
	white-space: nowrap;
}
/* The price is rendered by wc_price(), which wraps it in WooCommerce's own markup. */
.rc-packs__price .amount,
.rc-packs__price bdi {
	color: inherit;
}

/* ── Scent description panel (WS5) ─────────────────────────────────────────
   Redesigned 2026-09-11 against comp `969:765` (desktop, 437x121) and its mobile
   twin `968:566` (360x140). What changed from the first build:
     - the lilac wash is gone; the card is plain white;
     - the name is left-aligned 13/15 BOLD in the scent color (was 18/24 medium, centred);
     - the columns swapped — STRENGTH left, NOTES right (source order follows);
     - a 1px #CECECE rule sits between them instead of a plain gap;
     - notes/strength body copy is navy at every scent (was tinted with the accent);
       only the name and the lit dots carry the scent color now.
   Every px below is measured off those two frames. Desktop numbers ride --rc-scale
   because the whole PDP does; the comp's 437 card is the 1.0 reference. */
.rc-scent-panel {
	margin-top: calc(22px * var(--rc-scale));
	padding: calc(13px * var(--rc-scale)) calc(23px * var(--rc-scale)) calc(21px * var(--rc-scale));
	background: #fff;
	border-radius: 0;   /* square per comp */
}
/* Scoped under .rc-pdp so it beats the theme's generic `p { color:#666 }` (the name
   is a <p>; without the extra class the grey wins, unlike the sibling spans). */
.rc-pdp .rc-scent-panel__name {
	/* 22px line box, not 15px: the comp's name sits in a 22-tall frame with the glyph
	   line centred in it, and 13 + 22 + 10 puts the descriptor row at y=45 exactly. */
	margin: 0 0 calc(10px * var(--rc-scale));
	text-align: left;
	font-size: calc(13px * var(--rc-scale));
	line-height: calc(22px * var(--rc-scale));
	font-weight: var(--rc-weight-bold);
	/* Recolored per scent by rc-pdp.js (--rc-panel-accent = M.scents[slug].color);
	   fallback navy so gate-off / no-color is byte-identical. */
	color: var(--rc-panel-accent, var(--rc-navy));
}
/* Fixed left column + 1fr, not 1fr 1fr: the comp puts the rule at x=167 of a 437 card,
   which is 38% — an even split would push it to the middle and crowd the notes, whose
   copy is 3-4x longer than "Balanced". The rule itself is the notes column's
   border-left, so it stretches to the taller column (the comp draws it to the bottom
   of the notes on mobile, where they wrap to three lines). */
.rc-scent-panel__cols {
	display: grid;
	grid-template-columns: calc(144px * var(--rc-scale)) minmax(0, 1fr);
}
.rc-scent-panel__heading {
	display: block;
	text-transform: uppercase;
	letter-spacing: calc(0.4px * var(--rc-scale));
	font-size: calc(10px * var(--rc-scale));
	line-height: calc(14px * var(--rc-scale));
	font-weight: var(--rc-weight-medium);
	color: #868787;                        /* neutral grey per comp — NOT the scent accent */
	margin-bottom: calc(5px * var(--rc-scale));
}
/* Flex columns so the dots' margins can't collapse into the heading's — the 10px and
   7px below are the measured gaps and have to survive as written. */
.rc-scent-panel__notes,
.rc-scent-panel__strength {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	font-size: calc(13px * var(--rc-scale));
	line-height: calc(18px * var(--rc-scale));
	color: var(--rc-navy);
}
.rc-scent-panel__notes {
	border-left: 1px solid #CECECE;
	padding-left: calc(20px * var(--rc-scale));
}
/* Strength hidden (scent absent from rc_pdp_scent_strength_map) leaves a rule with
   nothing on its left, so the notes take the full card. Needs strength to be the
   preceding sibling — see the source-order note in scents.php. */
.rc-scent-panel__strength[hidden] + .rc-scent-panel__notes {
	grid-column: 1 / -1;
	border-left: 0;
	padding-left: 0;
}
.rc-scent-panel__dots {
	display: flex;
	gap: calc(5px * var(--rc-scale));
	margin-top: calc(5px * var(--rc-scale));
}
.rc-dot {
	width: calc(6px * var(--rc-scale));
	height: calc(6px * var(--rc-scale));
	border-radius: 50%;
	background: #CECECE;
}
.rc-dot.is-on { background: var(--rc-panel-accent, var(--rc-navy)); }
.rc-scent-panel__strength-label { margin-top: calc(7px * var(--rc-scale)); }

/* ── Scaffold stubs (removed as each workstream fills its section) ────────── */
.rc-pdp__stub {
	border: 1px dashed rgba(5, 38, 79, 0.35);
	border-radius: 6px;
	padding: 24px;
	text-align: center;
	color: rgba(5, 38, 79, 0.6);
	font-size: 13px;
	letter-spacing: 1px;
	text-transform: uppercase;
	background: rgba(5, 38, 79, 0.02);
}
.rc-pdp__stub--sm { padding: 14px; }
.rc-pdp__gallery .rc-pdp__stub {
	aspect-ratio: 1 / 1;
	display: flex;
	align-items: center;
	justify-content: center;
}

/* ── SELECT OFFER / ADD TO CART — hide the legacy form UI ─────────────────────
   The real WC form renders inside #rc-pdp-offer. The NATIVE scent grid, pack toggle,
   and SELECT OFFER (.rc-offer) replace its raw TM-EPO scent/pack pickers + the
   revive-eo subscribe widget + the (prod) coupon box, so hide all of that legacy UI.
   It stays FUNCTIONAL — rc-pdp.js .click()s the hidden radios / subscribe / frequency
   controls (programmatic clicks fire on display:none). Only qty + ATC + ships stay. */
#rc-pdp-offer .tm-extra-product-options,
#rc-pdp-offer .nav-edit-revive-eo-shop-actions-wrapper,
#rc-pdp-offer .revive-eo-submenu-wrapper,
#rc-pdp-offer .revive-eo-wrapper-cart-subscription,
#rc-pdp-offer .tmcp-reviveeo-wrap,
#rc-pdp-offer .tabs-variation-categories-wrapper,
/* Travel Size nests this wrapper DIRECTLY under .variations_form rather than inside
   .tabs-variation-categories-wrapper, so the line above misses it and every scent's
   description rendered stacked under the picker -- the "remove second scent description"
   report. Hiding the inner wrapper too covers both nestings. */
#rc-pdp-offer .tab-content-variation-category-wrapper,
#rc-pdp-offer .speero-coupon-container,
#rc-pdp-offer .variations,
#rc-pdp-offer .woocommerce-variation-description,
#rc-pdp-offer .woocommerce-variation-price,
#rc-pdp-offer .single_variation .price,
#rc-pdp-offer input[type="text"],
#rc-pdp-offer input[type="email"] {
	display: none !important;
}
#rc-pdp-offer .single_variation_wrap,
#rc-pdp-offer .woocommerce-variation-add-to-cart { display: block !important; }

/* ── SELECT OFFER — native subscribe/one-time/frequency + coupon (per comp) ── */
.rc-offer { margin: 4px 0; font-family: var(--rc-font); color: var(--rc-navy); }
.rc-offer__label {
	display: flex;
	align-items: center;
	gap: calc(14px * var(--rc-scale));
	margin-bottom: calc(14px * var(--rc-scale));
}
.rc-offer__label::before,
.rc-offer__label::after { content: ""; flex: 1; height: 2px; background: #D7F9FB; }
.rc-offer__label span {
	text-transform: uppercase;
	letter-spacing: 0.33px;
	font-size: calc(11px * var(--rc-scale));
	font-weight: var(--rc-weight-semibold);
	color: #868787;
}
.rc-offer__box {
	border: 1px solid rgba(5, 38, 79, 0.14);
	border-radius: 0;   /* square per comp */
	overflow: visible;  /* square now — let the frequency dropdown menu escape the box */
	background: var(--rc-white, #fff);
}
/* The SELECTED option carries the pale warm shading (comp #FFFAF8); the other white. */
.rc-offer__opt { background: var(--rc-white, #fff); padding: calc(16px * var(--rc-scale)) calc(18px * var(--rc-scale)); }
.rc-offer__opt.is-active { background: #FFFAF8; }
/* y1657: the frequency row is the last child of the subscribe option. The dead space under the
   dropdown was really the ddbtn margin (see .rc-offer__ddbtn below); with that gone the box only
   needs its normal bottom padding back, matching the 16px it carries on the other three sides. */
.rc-offer__opt--subscribe { padding-bottom: calc(16px * var(--rc-scale)); }
.rc-offer__box--onetime { margin-top: calc(12px * var(--rc-scale)); }
.rc-offer__opt--onetime .rc-offer__benefits {
	border-top: 1px solid rgba(5, 38, 79, 0.12);
	padding-top: calc(14px * var(--rc-scale));
	margin-top: calc(14px * var(--rc-scale));
}
.rc-offer__banner {
	background: var(--rc-navy);
	color: var(--rc-white, #fff);
	text-align: center;
	font-weight: var(--rc-weight-semibold);
	font-size: calc(13px * var(--rc-scale));
	letter-spacing: 0.3px;
	padding: calc(6px * var(--rc-scale)) calc(12px * var(--rc-scale));   /* y1414 */
}
.rc-offer__head {
	display: flex;
	align-items: center;
	gap: calc(10px * var(--rc-scale));
	width: 100%;
	padding: 0;
	background: none;
	border: 0;
	cursor: pointer;
	font-family: var(--rc-font);
	text-align: left;
	color: var(--rc-navy);   /* head is a <button>; avoid inheriting the theme's white text */
	margin: 0;               /* ...and the theme's `button { margin: 0 0 1.25rem }` -- see below */
}

/* Round 5 #4, "eliminate this empty space" on the Discovery Set.
 *
 * The head is a <button>, so the theme's `button, .button { margin: 0 0 1.25rem }` was putting
 * 20px under it -- the same trap this rule already guards against for padding, border and colour,
 * just missed for margin. The box measured 16 (pad) + 22 (head) + 20 (that margin) + 16 (pad) =
 * 74px, and the 20px is the empty strip.
 *
 * It is only empty when nothing follows. On a subscription product the head is followed by
 * .rc-offer__benefits and .rc-offer__freq and the 20px reads as the separation between them, so
 * it is restated here as a deliberate value rather than left as an inherited accident. Measured:
 * Discovery Set's head is its parent's only child; S&C's is not, in both offer boxes.
 *
 * 20px literal, not `calc(20px * var(--rc-scale))` -- the theme value it replaces is unscaled,
 * and scaling it would silently widen the desktop gap it is meant to preserve.
 */
.rc-offer__head.rc-offer__head:not(:last-child) {
	margin-bottom: 20px;
}
.rc-offer__check {
	flex: none;
	width: calc(22px * var(--rc-scale));
	height: calc(22px * var(--rc-scale));
	border: 1.5px solid var(--rc-navy);   /* lighter stroke per comp */
	border-radius: 0;   /* square per comp */
	background: var(--rc-white, #fff);
	position: relative;
}
.rc-offer__opt.is-active .rc-offer__check { background: var(--rc-navy); }
.rc-offer__opt.is-active .rc-offer__check::after {
	content: "";
	position: absolute;
	left: 50%; top: 45%;
	width: calc(5px * var(--rc-scale)); height: calc(10px * var(--rc-scale));
	border: solid var(--rc-white, #fff);
	border-width: 0 calc(2.5px * var(--rc-scale)) calc(2.5px * var(--rc-scale)) 0;
	transform: translate(-50%, -50%) rotate(45deg);
}
.rc-offer__name {
	flex: 1;
	color: var(--rc-navy);
	text-transform: uppercase;
	font-weight: var(--rc-weight-semibold);
	font-size: calc(13px * var(--rc-scale));
	letter-spacing: 0.5px;
}
.rc-offer__price { font-size: calc(15px * var(--rc-scale)); font-weight: var(--rc-weight-semibold); white-space: nowrap; }
.rc-offer__price .rc-offer__reg { color: rgba(5, 38, 79, 0.45); font-weight: var(--rc-weight-regular); margin-right: calc(6px * var(--rc-scale)); text-decoration: line-through; }
.rc-offer__price .rc-offer__reg .amount { text-decoration: line-through; }
.rc-offer__opt--subscribe .rc-offer__sub { color: var(--rc-red); text-decoration: none; }
.rc-offer__opt--onetime .rc-offer__sub { color: var(--rc-navy); text-decoration: none; }
/* A discounted one-time price goes red, matching production ("$49.99 $39.99" under ?qmid=SELF20)
   and the subscribe tile beside it. Keyed on the struck price actually being present rather than
   on a qmid class, so the undiscounted PDP keeps its navy and no state list has to be maintained:
   offer.php emits the <del> always and marks it [hidden] when there is nothing to strike. */
.rc-offer__opt--onetime .rc-offer__reg:not([hidden]) ~ .rc-offer__sub { color: var(--rc-red); }
.rc-offer__benefits { list-style: none; margin: calc(12px * var(--rc-scale)) 0 0; padding: 0; }
.rc-offer__benefits li {
	position: relative;
	padding-left: calc(26px * var(--rc-scale));
	margin-bottom: calc(9px * var(--rc-scale));
	font-size: calc(13px * var(--rc-scale));
	line-height: 1.3;
	/* y1569 "center checkmarks": the disc was pinned to top:0 while the text line is
	   1.3em tall, so it rode high. Centre it on the FIRST line (not the whole li, which
	   would drift on any item that wraps). The tick keeps its 3px offset from the disc. */
	--rc-check-top: calc(0.65em - (8px * var(--rc-scale)));
}
.rc-offer__benefits li:last-child { margin-bottom: 0; }
.rc-offer__benefits li::before {
	content: "";
	position: absolute;
	left: calc(3px * var(--rc-scale));   /* y1569: centre the 20px disc under the 27.5px checkbox */
	top: var(--rc-check-top);
	width: calc(16px * var(--rc-scale)); height: calc(16px * var(--rc-scale));
	border-radius: 50%;
	background: var(--rc-navy);
}
.rc-offer__benefits li::after {
	content: "";
	position: absolute;
	left: calc(8px * var(--rc-scale));   /* tracks the disc's 3px shift */
	top: calc(var(--rc-check-top) + (3px * var(--rc-scale)));
	width: calc(4px * var(--rc-scale)); height: calc(8px * var(--rc-scale));
	border: solid var(--rc-white, #fff);
	border-width: 0 2px 2px 0;
	transform: rotate(45deg);
}
/* Frequency dropdown. */
.rc-offer__freq {
	display: flex;
	align-items: center;
	gap: calc(12px * var(--rc-scale));
	margin-top: calc(16px * var(--rc-scale));
	padding-top: calc(16px * var(--rc-scale));
	border-top: 1px solid rgba(5, 38, 79, 0.12);   /* line above Select Frequency per comp */
}
.rc-offer__freqlabel { font-size: calc(13px * var(--rc-scale)); font-weight: var(--rc-weight-medium); }
.rc-offer__dd {
	position: relative;
	flex: 1;
}
/* The wrapper measured 60px against a 40px button, which pushed "Select Frequency" 10px below
   centre and left 20px of dead space under the dropdown inside the subscribe box.
   MEASURED CAUSE: the theme gives every <button> `margin-bottom: 20px`, and .rc-offer__ddbtn is
   a block-level flex container, so its margin counts toward the wrapper's height. It was not the
   absolutely-positioned menu (display:none, 0x0) and not the whitespace text nodes — stripping
   both left the height at 60. Zero the button's margin and the wrapper hugs it exactly. */
.rc-offer__ddbtn { margin: 0 !important; }
.rc-offer__ddbtn {
	width: 100%;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: calc(8px * var(--rc-scale));
	padding: calc(6px * var(--rc-scale)) calc(12px * var(--rc-scale));   /* y1637 */
	background: var(--rc-white, #fff);
	border: 1px solid rgba(5, 38, 79, 0.3);
	border-radius: 0;   /* square per comp */
	font-family: var(--rc-font);
	font-size: calc(13px * var(--rc-scale));
	color: var(--rc-navy);
	text-transform: none;   /* comp is "Deliver every 3 months" (Title/sentence case) */
	cursor: pointer;
}
.rc-offer__ddmenu {
	position: absolute;
	left: 0; right: 0; top: 100%;
	z-index: 20;   /* above the sibling One-Time box when open */
	margin: 0;
	padding: calc(4px * var(--rc-scale)) 0;
	list-style: none;
	background: var(--rc-white, #fff);
	border: 1px solid rgba(5, 38, 79, 0.2);
	border-radius: 0;
	box-shadow: 0 6px 18px rgba(5, 38, 79, 0.14);
	display: none;
}
.rc-offer__dd.is-open .rc-offer__ddmenu { display: block; }
.rc-offer__ddopt {
	padding: calc(9px * var(--rc-scale)) calc(14px * var(--rc-scale));
	font-size: calc(13px * var(--rc-scale));
	cursor: pointer;
}
/* Neutral grey highlight (not navy-tinted, which reads as blue). */
.rc-offer__ddopt:hover,
.rc-offer__ddopt.is-selected { background: rgba(0, 0, 0, 0.05); }

/* ── Kill the theme's button :hover/:focus/:active blue on every PDP control ── */
.rc-pdp button:hover,
.rc-pdp button:focus,
.rc-pdp button:active,
.rc-pdp button:focus-visible { outline: none !important; box-shadow: none !important; }
.rc-pdp .rc-packs__btn:hover,
.rc-pdp .rc-packs__btn:focus,
.rc-pdp .rc-packs__btn:active {
	background: var(--rc-white) !important;
	/* y1344: the theme's button:hover sets color:#fff, so forcing the background back to
	   white left white-on-white text — the label vanished on hover. Hold navy. */
	color: var(--rc-navy) !important;
	border-color: var(--rc-navy) !important;
}
.rc-pdp .rc-packs__btn.is-active:hover,
.rc-pdp .rc-packs__btn.is-active:focus,
.rc-pdp .rc-packs__btn.is-active:active {
	background: var(--rc-navy) !important;
	color: var(--rc-white) !important;
}
.rc-pdp .rc-offer__head:hover,
.rc-pdp .rc-offer__head:focus,
.rc-pdp .rc-offer__head:active { background: transparent !important; }
.rc-pdp .rc-offer__ddbtn:hover,
.rc-pdp .rc-offer__ddbtn:focus,
.rc-pdp .rc-offer__ddbtn:active { background: var(--rc-white) !important; color: var(--rc-navy) !important; }
#rc-pdp-offer .single_add_to_cart_button:hover,
#rc-pdp-offer .single_add_to_cart_button:focus,
#rc-pdp-offer .single_add_to_cart_button:active { background: var(--rc-red) !important; }
/* y1957: give the button a hover state (the rule above kills the theme's blue). */
#rc-pdp-offer .single_add_to_cart_button:hover,
#rc-pdp-offer .single_add_to_cart_button:focus { opacity: 0.88; }
#rc-pdp-offer .quantity button:hover,
#rc-pdp-offer .quantity button:focus,
#rc-pdp-offer .quantity button:active { background: none !important; }
.rc-pdp .rc-scent:hover,
.rc-scent:focus,
.rc-scent:active { background: var(--rc-white) !important; }

/* Coupon row — golden band, angled centered tag, checkbox, kit thumb. */
.rc-offer__coupon {
	display: flex;
	align-items: center;
	gap: calc(12px * var(--rc-scale));
	margin-top: calc(14px * var(--rc-scale));
	/* Vertical padding 10px -> 5px. Moiz 2026-09-10 (#56 desktop / #55 mobile): "increase size
	   without making yellow area larger", and the meeting note "reduce padding on top and bottom
	   and make image a bit bigger". The thumb is the tallest thing in the row, so the band's
	   height is thumb + 2x padding; growing the thumb by 10px of design space and giving back
	   5px of padding on each side keeps the yellow EXACTLY the height it was (MEASURED 90px at
	   1440). Change the two together or the band grows. */
	padding: calc(5px * var(--rc-scale)) calc(14px * var(--rc-scale)) calc(5px * var(--rc-scale)) 0;
	background: #FFFAE4;   /* pale yellow band per comp */
	border-radius: 0;      /* square (incl. right side) per comp */
	overflow: hidden;
}
.rc-offer__coupontag {
	flex: none;
	align-self: center;   /* centered flag, NOT full height */
	padding: calc(6px * var(--rc-scale)) calc(20px * var(--rc-scale)) calc(6px * var(--rc-scale)) calc(14px * var(--rc-scale));
	background: #F2CB4C;   /* golden */
	color: var(--rc-navy);
	font-weight: var(--rc-weight-semibold);
	font-size: calc(12px * var(--rc-scale));
	text-transform: uppercase;
	letter-spacing: 0.5px;
	clip-path: polygon(0 0, 100% 0, calc(100% - 10px) 50%, 100% 100%, 0 100%);
}
/* margin:0 is load-bearing. This is a <label>, and the theme gives labels margin-top 8px /
   margin-bottom 1px. align-items:center centres the MARGIN box, so that 7px asymmetry pushed
   the checkbox and the coupon text 3.5px below the middle of the yellow band -- visible on the
   thumbless campaigns (NEW10, BEST10, SELF20), where the band is only 40px tall. Same family as
   the theme's button margin-bottom trap. */
.rc-offer__couponbody { flex: 1; display: flex; align-items: center; gap: calc(10px * var(--rc-scale)); cursor: pointer; margin: 0; }
.rc-offer__couponthumb {
	flex: none;
	width: calc(62px * var(--rc-scale));   /* 52 -> 62 (#56); paired with the padding drop above */
	height: auto;
	margin-left: calc(8px * var(--rc-scale));
}
.rc-offer__couponcheck { position: absolute; opacity: 0; width: 0; height: 0; }
.rc-offer__couponcheckbox {
	flex: none;
	width: calc(20px * var(--rc-scale));
	height: calc(20px * var(--rc-scale));
	border: 1.5px solid var(--rc-navy);   /* lighter stroke per comp */
	border-radius: 0;   /* square per comp */
	background: var(--rc-white, #fff);
	position: relative;
}
.rc-offer__couponcheck:checked + .rc-offer__couponcheckbox { background: var(--rc-navy); }
.rc-offer__couponcheck:checked + .rc-offer__couponcheckbox::after {
	content: "";
	position: absolute;
	left: 50%; top: 46%;
	width: calc(4px * var(--rc-scale)); height: calc(8px * var(--rc-scale));
	border: solid var(--rc-white, #fff);
	border-width: 0 2px 2px 0;
	transform: translate(-50%, -50%) rotate(45deg);
}
/* 2026-09-08 review: "Increase font size to 15px". Literal px — `calc(15px * 1.25)` would
   render 18.75px on desktop.
   2026-09-10 (#41): "Change to font size 16px and line height 1.6". Still literal px. */
.rc-offer__couponlabel { font-size: 16px; line-height: 1.6; color: var(--rc-navy); text-transform: none; }

/* Desktop-only sentence break — hidden on mobile, see offer.php and the mobile block. */

/* Coupon band -> ADD TO CART seam (#42 "Remove 20px gap here", and the meeting note
   "make the yellow around 10px apart"). DESKTOP ONLY — the mobile seam was measured and
   set separately on 2026-09-09 and is deliberately left at the buy-box's 14px rhythm.

   MEASURED at 1440 before the change: 39px, made of exactly three things —
     .rc-offer margin-bottom            4px
     .rc-pdp__buybox row gap           25px  (= 20px design x the 1.25 desktop dial)
     .variations_button margin-top     10px
   The "20px" in the comment is that row gap in design space, so cancelling it and the 4px
   leaves the button's own 10px — which is the "around 10px" from the meeting. The two
   readings agree; do not also zero .variations_button or the band and button will touch. */
@media (min-width: 769px) {
	.rc-pdp .rc-pdp__selectoffer .rc-offer { margin-bottom: 0; }
	.rc-pdp .rc-pdp__offer { margin-top: calc(-1 * var(--rc-buybox-gap)); }
}

/* ── ADD TO CART + quantity + ships (real form, restyled to the comp) ─────── */
/* Collapse the form wrappers' spacing so ATC → ships isn't a big gap. */
#rc-pdp-offer form.cart,
#rc-pdp-offer .woocommerce-variation-add-to-cart,
#rc-pdp-offer .single_variation_wrap,
#rc-pdp-offer .single_variation { margin: 0 !important; }
#rc-pdp-offer .woocommerce-variation-add-to-cart { padding-bottom: 0 !important; }
#rc-pdp-offer .quantity {
	flex: none;
	display: inline-flex;
	align-items: center;
	border: 1px solid rgba(5, 38, 79, 0.3);
	border-radius: 0 !important;   /* square per comp */
	overflow: hidden;
	background: var(--rc-white, #fff);
}
/* the theme rounds the qty box + its −/+ buttons — force square. */
#rc-pdp-offer .quantity,
#rc-pdp-offer .quantity * { border-radius: 0 !important; }
/* y1969: the -/+ controls read too heavy in navy, and their hit boxes overlapped the digit. */
#rc-pdp-offer .quantity .qty-enhanced-wrapper {
	width: calc(74px * var(--rc-scale)) !important;   /* was 72px flat — too narrow for 35+35 */
	border: 0 !important;                             /* .quantity already draws the box */
}
#rc-pdp-offer .quantity .qty-enhanced-btn {
	flex: none !important;
	width: calc(22px * var(--rc-scale)) !important;
	color: #7d7d7d !important;
}
#rc-pdp-offer .quantity .qty-enhanced-btn svg line { stroke: #7d7d7d !important; }
#rc-pdp-offer .quantity .qty-enhanced-value {
	flex: 1 1 auto !important;
	display: flex !important;
	align-items: center;
	justify-content: center;
	color: var(--rc-navy) !important;
	font-size: calc(15px * var(--rc-scale)) !important;
}
#rc-pdp-offer .quantity input.qty {
	width: calc(34px * var(--rc-scale));
	text-align: center;
	border: 0;
	background: none;
	font-family: var(--rc-font);
	font-size: calc(15px * var(--rc-scale));
	color: var(--rc-navy);
	-moz-appearance: textfield;
}
#rc-pdp-offer .quantity input.qty::-webkit-outer-spin-button,
#rc-pdp-offer .quantity input.qty::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
#rc-pdp-offer .single_add_to_cart_button {
	border-radius: 0 !important;
	background: var(--rc-red) !important;
	color: var(--rc-white, #fff) !important;
	font-weight: var(--rc-weight-semibold) !important;
	letter-spacing: 0.5px;
	text-transform: uppercase;
	border: 0 !important;
	padding: calc(15px * var(--rc-scale)) calc(20px * var(--rc-scale)) !important;
	/* y1957: label sat off-centre — the theme leaves a line-height/inline-block seam. */
	/* 2026-09-08 review: "Decrease size of ATC button to 16px". Literal px, not the --rc-scale
	   dial: at >=1200px `calc(16px * 1.25)` renders 20px, not the 16 that was asked for. */
	font-size: 16px !important;
	line-height: 1.2 !important;
	text-align: center;
	display: inline-flex;   /* NOT flex: block-level would drop it below the qty box */
	align-items: center;
	justify-content: center;
	vertical-align: middle;
	/* y1989: give the qty box and the button some air between them. */
	margin-left: calc(10px * var(--rc-scale));
	transition: opacity 0.15s ease;
}
/* Ships line — now rendered by the template (<p class="rc-offer__ships">), not read from the
   custom-css-js "ShipsFromAligner" snippet (703127082). That snippet JS-injects a
   .shipsfrom-wrapper after .single_variation_wrap and leaves two more shipsfrom nodes in the
   form; the rebrand used to mask its copy with font-size:0 + an ::after replacement, which was
   fragile and left duplicates in the DOM. Hide the legacy nodes on the PDP only — the snippet
   still drives cart/checkout, which this PDP-scoped sheet never touches. */
.rc-pdp .shipsfrom-wrapper,
.rc-pdp p.shipsfrom,
.rc-pdp .shipsfrom-spacer { display: none !important; }

/* Scoped under .rc-pdp: the theme's `.single-product p { color:#666 }` and
   `.single-product h4, .single-product p { font-size: 1em }` are (0,1,1) and were beating a bare
   .rc-offer__ships (0,1,0) — the line rendered grey at 16px, not navy at our size. Same cause as
   the accordion disclaimers. */
.rc-pdp .rc-offer__ships {
	display: block;
	text-align: center;
	font-family: var(--rc-font);
	/* Solid 10px, deliberately NOT run through the zoom dial (Daniel, 2026-08-31, per the
	   meeting-note action "decrease size of 'Ships Within 24 Hours' text to ~10px"). Fixed so it
	   stays 10px at every width instead of shrinking below the 1200px dial breakpoint. */
	font-size: 10px;
	line-height: 1.4;
	color: var(--rc-navy);
	/* ~10px of air under ADD TO CART (Daniel, 2026-08-31) + room below before the trust icons.
	   4px x dial = 5px, on top of the ~5px the form wrapper already contributes -> 10px measured. */
	margin: calc(4px * var(--rc-scale)) 0 0;
	padding: 0 0 calc(14px * var(--rc-scale));
	/* 2026-09-08 review: "Center the 'ships within 24 hours' to ATC button, not column width."
	   The <p> is a sibling of form.cart, so text-align:center alone centres it on the whole
	   buy-box. MEASURED at 1440 (dial 1.25): buy-box 751..1296, qty box 751..845.5, button
	   858..1296 — so the line was centred at 1023.5 where the button centres at 1077, 53.5px
	   out. Indenting by the qty column + the button's own gap leaves a box that ends at the
	   same right edge as the button and is therefore exactly its width, so text-align:center
	   now centres on the button. Built from the same tokens as the row itself (.quantity is
	   74px x dial + its 1px borders; the button carries margin-left 10px x dial) so it tracks
	   any future change to either instead of hard-coding 107px. */
	margin-left: calc(74px * var(--rc-scale) + 2px + 10px * var(--rc-scale));
}
#rc-pdp-offer .clearfix:empty { display: none; }
/* TM Extra Product Options' running-total bar. It renders EMPTY on this template — MEASURED
   26px tall and made entirely of its own 10px/16px padding, with no content — because the
   rebrand shows price in the SELECT OFFER box instead. It sat between the coupon row and the
   ADD TO CART row and was most of the 54px gap there (comp wants 11px).
   Display only: the node stays in the DOM, so any TM-EPO script that writes into it still
   works — this is not the options-container snapshot mechanism. Worth a test add-to-cart. */
.rc-pdp .tc-totals-form,
.rc-pdp .tc-epo-totals { display: none !important; }
/* Stray boxes below ATC — unused revive-eo after-ATC wrapper + legacy check-marks
   table + the after-ATC featured-reviews widget (reviews are a separate, deferred
   section). This sheet is PDP-only, so the unscoped selectors are safe. */
.revive-after-add-to-cart-wrapper,
.product-check-marks,
.rc-pdp__buybox .dynamic-sidebar-after-add-to-cart,
.rc-pdp__buybox .featured-reviews { display: none !important; }

/* ── Trust-icon row (Figma ICONS) — brand-level, product-invariant ────────────
   Five icon columns across the buy-box width. Icons are the designer's raster
   PNGs (images/rebrand/pdp/trust-*.png; 56px display). Spacing comes from the
   buy-box column gap, so no top margin here. */
.rc-trust {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	justify-content: space-between;
	gap: calc(8px * var(--rc-scale));
	/* 2026-09-08 review: "more space below icons" -> "Add 13px of padding bottom below icons".
	   Padding, not margin: the buy-box is a flex column with its own 20px gap, and a margin
	   here would collapse-compete with that gap instead of reading as 13px.
	   Literal px, not the --rc-scale dial — 13 means 13 on screen. */
	padding-bottom: 13px;
}
.rc-trust__item {
	flex: 0 0 auto;
	width: calc(75px * var(--rc-scale));   /* Figma icon-column width */
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: calc(8px * var(--rc-scale));
	text-align: center;
}
.rc-trust__icon {
	display: block;
	width: calc(56px * var(--rc-scale));
	height: calc(56px * var(--rc-scale));
}
.rc-trust__label {
	font-size: calc(10px * var(--rc-scale));   /* Figma "Descriptor" 10/13 uppercase navy */
	line-height: calc(13px * var(--rc-scale));
	letter-spacing: 0.4px;
	text-transform: uppercase;
	font-weight: var(--rc-weight-medium);
	color: var(--rc-navy);
}

/* ── Written-claims checklist (Figma CLAIMS) — brand-level, product-invariant ──
   Navy-disc checkmark (inline SVG) + text with a semibold lead phrase, then the
   centered clinical-testing disclaimer. */
.rc-claims { margin: 0; color: var(--rc-navy); }
.rc-claims__list { list-style: none; margin: 0; padding: 0; }
.rc-claims__item {
	display: flex;
	align-items: flex-start;
	gap: calc(16px * var(--rc-scale));
	margin-bottom: calc(14px * var(--rc-scale));
}
.rc-claims__item:last-child { margin-bottom: 0; }
.rc-claims__check {
	flex: none;
	width: calc(18px * var(--rc-scale));
	height: calc(18px * var(--rc-scale));
	margin-top: calc(2px * var(--rc-scale));   /* optical-align disc to first text line */
}
.rc-claims__text {
	font-size: calc(15px * var(--rc-scale));
	line-height: calc(21px * var(--rc-scale));
	font-weight: var(--rc-weight-regular);
	color: var(--rc-navy);
}
.rc-claims__text strong { font-weight: var(--rc-weight-semibold); }
/* Scoped under .rc-pdp so it beats the theme's generic `p { color:#666 }`. */
.rc-pdp .rc-claims__disclaimer {
	margin: calc(12px * var(--rc-scale)) 0 0;
	font-size: var(--rc-text-footnote-size);
	line-height: var(--rc-text-footnote-lh);
	/* y2320: was rendering Brandon Grotesque in grey. The theme sets font-family on <p>
	   directly, which beats inheritance from .rc-claims — so force Jost here, same root
	   cause (and same fix) as the reviews text elements below. Colour -> brand navy. */
	font-family: var(--rc-font) !important;
	color: var(--rc-navy);
	text-align: center;
}

/* ── Accordions (Figma Expanded Overlay frames) ──────────────────────────────
   Native <details>/<summary>: independent toggles, all collapsed by default.
   Content = _rc_pdp_content meta (+ brand-level claims in code). */
.rc-acc { margin: 0; font-family: var(--rc-font); color: var(--rc-navy); }
.rc-acc__item { border-top: 1px solid rgba(5, 38, 79, 0.14); }
.rc-acc__item:last-child { border-bottom: 1px solid rgba(5, 38, 79, 0.14); }

/* Header row (title + sign). Strip the native disclosure triangle. */
.rc-acc__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: calc(12px * var(--rc-scale));
	padding: calc(18px * var(--rc-scale)) 0;
	cursor: pointer;
	list-style: none;
	color: var(--rc-navy);
}
.rc-acc__head::-webkit-details-marker { display: none; }
.rc-acc__title {
	/* 2026-09-08 review. Stephanie: "these accordion headings got even larger since last time
	   ... too large?" -> Moiz: "Make 24px please".
	   LITERAL px, NOT calc(24px * --rc-scale). At >=1200px the dial is 1.25, so the old
	   `calc(23px * scale)` RENDERED at 28.75px — which is what they were looking at and called
	   too large. Writing `calc(24px * scale)` would render 30px, i.e. bigger, the opposite of
	   the ask. A literal 24px renders 24px, the reviewed number. Same convention the primary
	   nav already uses for reviewed sizes (see the nav gap note in rc-shell.css). */
	font-size: 24px;
	line-height: 1.2;
	font-weight: var(--rc-weight-medium);
	text-transform: none;
	color: var(--rc-navy);
}
/* +/- sign, swapped on [open]. */
.rc-acc__sign {
	flex: none;
	width: calc(20px * var(--rc-scale));
	text-align: center;
	font-size: calc(24px * var(--rc-scale));
	line-height: 1;
	font-weight: var(--rc-weight-regular);
	color: var(--rc-navy);
}
.rc-acc__sign::before { content: "+"; }
.rc-acc__item[open] > .rc-acc__head .rc-acc__sign::before { content: "\2013"; } /* en dash */

/* y2501: 50px right padding on the interior accordion (Moiz approved). */
.rc-acc__body { padding: 0 calc(50px * var(--rc-scale)) calc(24px * var(--rc-scale)) 0; }

/* — Why You'll Love Us — */
.rc-acc-stats {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	row-gap: calc(20px * var(--rc-scale));
	margin: calc(4px * var(--rc-scale)) 0 calc(14px * var(--rc-scale));
}
.rc-acc-stats__item {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: calc(4px * var(--rc-scale));
	padding: 0 calc(8px * var(--rc-scale));
	text-align: center;
}
.rc-acc-stats__value {
	font-size: calc(28px * var(--rc-scale));
	line-height: 1;
	font-weight: var(--rc-weight-regular);
	color: var(--rc-navy);
}
.rc-acc-stats__label {
	font-size: calc(10px * var(--rc-scale));
	line-height: calc(13px * var(--rc-scale));
	letter-spacing: 0.4px;
	text-transform: uppercase;
	font-weight: var(--rc-weight-medium);
	color: var(--rc-navy);
}
.rc-pdp .rc-acc-love__disclaimer {
	margin: 0 0 calc(16px * var(--rc-scale));
	font-size: var(--rc-text-footnote-size);
	line-height: var(--rc-text-footnote-lh);
	/* y2320 reply ("Same goes in Why You'll Love Us") — see .rc-claims__disclaimer. */
	font-family: var(--rc-font) !important;
	color: var(--rc-navy);
	text-align: center;
}
.rc-acc-love__panel {
	background: #EAF7FA;   /* pale blue wash, per comp */
	padding: calc(24px * var(--rc-scale));
}
.rc-acc-love__block + .rc-acc-love__block { margin-top: calc(18px * var(--rc-scale)); }
.rc-acc-love__title {
	margin: 0 0 calc(6px * var(--rc-scale));
	font-size: calc(15px * var(--rc-scale));
	line-height: 1.3;
	font-weight: var(--rc-weight-semibold);
	color: var(--rc-navy);
	/* UPPERCASE per Moiz's Figma comment ("Capitalize titles:") whose attached mockup renders
	   SAFE FOR COLOR TREATED HAIR / NO HARSH INGREDIENTS / MONEY BACK GUARANTEE, confirmed by
	   Daniel 2026-09-09. The meeting list quoted the same three strings in Title Case, which is
	   why this shipped as Title Case first — the comment's IMAGE is the spec, not its text. */
	text-transform: uppercase;
}
.rc-pdp .rc-acc-love__text {
	margin: 0;
	font-size: calc(13px * var(--rc-scale));
	line-height: calc(19px * var(--rc-scale));
	font-weight: var(--rc-weight-regular);
	color: var(--rc-navy);
}

/* — What Makes it Work (ingredient table) — */
.rc-ingredients { list-style: none; margin: 0; padding: 0; }
.rc-ingredients__row {
	display: grid;
	grid-template-columns: 40% 1fr;
	gap: calc(16px * var(--rc-scale));
	align-items: start;
	padding: calc(14px * var(--rc-scale)) 0;
	border-bottom: 1px solid rgba(5, 38, 79, 0.12);
}
.rc-ingredients__row:last-child { border-bottom: 0; }
.rc-ingredients__name {
	font-size: calc(14px * var(--rc-scale));
	line-height: 1.3;
	font-weight: var(--rc-weight-semibold);
	color: var(--rc-navy);
}
.rc-ingredients__source {
	display: block;
	margin-top: calc(2px * var(--rc-scale));
	font-size: calc(13px * var(--rc-scale));
	line-height: calc(18px * var(--rc-scale));
	font-weight: var(--rc-weight-regular);
	color: var(--rc-navy);
}
.rc-ingredients__benefit {
	font-size: calc(13px * var(--rc-scale));
	line-height: calc(18px * var(--rc-scale));
	font-weight: var(--rc-weight-regular);
	color: var(--rc-navy);
}

/* — Common Questions (nested FAQ) — */
.rc-faq__item { border-bottom: 1px solid rgba(5, 38, 79, 0.12); }
.rc-faq__item:last-child { border-bottom: 0; }
.rc-faq__q {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: calc(12px * var(--rc-scale));
	padding: calc(14px * var(--rc-scale)) 0;
	cursor: pointer;
	list-style: none;
	font-size: calc(14px * var(--rc-scale));
	/* 2026-09-14 team review: lighter than the accordion headings above them. */
	font-weight: var(--rc-weight-regular);
	color: var(--rc-navy);
}
.rc-faq__q--static { cursor: default; }
.rc-faq__q::-webkit-details-marker { display: none; }
.rc-faq__sign {
	flex: none;
	width: calc(18px * var(--rc-scale));
	text-align: center;
	font-size: calc(20px * var(--rc-scale));
	line-height: 1;
	color: var(--rc-navy);
}
.rc-faq__sign::before { content: "+"; }
.rc-faq__item[open] > .rc-faq__q .rc-faq__sign::before { content: "\2013"; }
.rc-pdp .rc-faq__a {
	padding: 0 0 calc(14px * var(--rc-scale));
	font-size: calc(13px * var(--rc-scale));
	line-height: calc(19px * var(--rc-scale));
	font-weight: var(--rc-weight-regular);
	color: var(--rc-navy);
}

/* — How to Use — */
.rc-howto__step + .rc-howto__step { margin-top: calc(16px * var(--rc-scale)); }
.rc-howto__title {
	margin: 0 0 calc(6px * var(--rc-scale));
	font-size: calc(15px * var(--rc-scale));
	font-weight: var(--rc-weight-semibold);
	color: var(--rc-navy);
	text-transform: none;
}
.rc-pdp .rc-howto__body {
	margin: 0;
	font-size: calc(13px * var(--rc-scale));
	line-height: calc(19px * var(--rc-scale));
	font-weight: var(--rc-weight-regular);
	color: var(--rc-navy);
}
.rc-howto__protip {
	margin-top: calc(18px * var(--rc-scale));
	margin-left: calc(44px * var(--rc-scale));   /* Figma: Pro Tip block indented from the step text */
	padding-left: calc(12px * var(--rc-scale));
	border-left: calc(2px * var(--rc-scale)) solid var(--rc-navy);
}
.rc-howto__protip-title {
	margin: 0 0 calc(6px * var(--rc-scale));
	font-size: calc(14px * var(--rc-scale));
	font-weight: var(--rc-weight-semibold);
	color: var(--rc-navy);
	text-transform: none;
}
.rc-pdp .rc-howto__protip-body {
	margin: 0;
	font-size: calc(13px * var(--rc-scale));
	line-height: calc(19px * var(--rc-scale));
	font-weight: var(--rc-weight-regular);
	color: var(--rc-navy);
}

/* Casing, stated at a specificity that out-ranks the theme's `.woocommerce h4` (0,1,1) without
   `!important` — `.rc-pdp .rc-*` is (0,2,0), so it wins on specificity and source order never
   comes into it. VERIFIED by measuring the computed values with no flag present.
   The two groups genuinely differ, which is why they are no longer one rule:
     - Why You'll Love Us titles are UPPERCASE (Moiz's Figma comment mockup). The theme happens
       to agree, but we state it rather than inherit it — `.woocommerce h4` only applies inside
       a .woocommerce wrapper, so relying on it would break the day this block moves.
     - How to Use titles ("Shampoo (14oz)", "Pro Tip") stay Title Case. That comment did not
       cover them, so they are deliberately left as the comp has them. */
.rc-pdp .rc-acc-love__title { text-transform: uppercase; }
.rc-pdp .rc-howto__title,
.rc-pdp .rc-howto__protip-title { text-transform: none; }

/* "View …" links + arrow ("View Full Ingredient List", "View all FAQs"). */
.rc-acc-more {
	display: inline-flex;
	align-items: center;
	gap: calc(6px * var(--rc-scale));
	margin-top: calc(16px * var(--rc-scale));
	font-size: calc(13px * var(--rc-scale));
	font-weight: var(--rc-weight-medium);
	color: var(--rc-navy);
	text-decoration: underline;
	text-underline-offset: 2px;
	text-transform: none;
}
.rc-acc-more .rc-arrow { flex: none; display: inline-block; }
.rc-pdp .rc-acc-more:hover { opacity: 0.75; }

/* Money Back "FAQ" link — underlined navy. */
.rc-pdp .rc-acc-love__link {
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* Rebrand surfaces color <a> with the brand red — force these accordion links navy
   over any anchor rule (arrow inherits via currentColor). Needs !important + the
   a.<class> specificity to beat the red link rule (present on rebrand, not local). */
.rc-pdp a.rc-acc-more,
.rc-pdp a.rc-acc-more:link,
.rc-pdp a.rc-acc-more:visited,
.rc-pdp a.rc-acc-more:hover,
.rc-pdp a.rc-acc-more:focus,
.rc-pdp a.rc-acc-love__link,
.rc-pdp a.rc-acc-love__link:link,
.rc-pdp a.rc-acc-love__link:visited,
.rc-pdp a.rc-acc-love__link:hover,
.rc-pdp a.rc-acc-love__link:focus { color: var(--rc-navy) !important; }

/* Kill the theme's button/summary blue hover on the accordion controls. */
.rc-pdp .rc-acc__head:hover,
.rc-pdp .rc-faq__q:hover { background: transparent !important; }

/* Below the desktop breakpoint the columns stack (mobile comp = later round). */
@media (max-width: 1024px) {
	/* `1fr` is shorthand for minmax(auto, 1fr), so the stacked column could never shrink below
	   its widest child's MIN-CONTENT. MEASURED on a 360px viewport: the column resolved to
	   492px, the document scrolled sideways to 516px and 265 elements sat outside the viewport
	   — i.e. the PDP had no working narrow layout at all, on tablet as well as phone.
	   minmax(0, 1fr) removes the min-content floor; that one change took the 360px overflow
	   from 265 elements to 9 (the rest were the trust icons, handled in the mobile block). */
	.rc-pdp__grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 32px;
		/* Cap + centre the stacked column. Unconstrained, a 768px tablet drew a 734px-square
		   hero that filled the whole viewport before a word of copy. 560px keeps the stacked
		   gallery in line with the desktop gallery column (measured 537px at 1440). */
		max-width: 560px;
		margin-left: auto;
		margin-right: auto;
	}
	.rc-pdp__gallery { position: static; }
	.rc-pdp__buybox { max-width: 560px; }
	/* y808: desktop only. Below the stack breakpoint the thumbs stay the horizontal scroll
	   strip they are today — mobile is explicitly unchanged for this round. */
	.rc-gallery__thumbs {
		display: flex;
		grid-template-columns: none;
		justify-content: flex-start;
		overflow-x: auto;
		scrollbar-width: none;
	}
	.rc-gallery__thumbs::-webkit-scrollbar { display: none; }
}
/* ── Reviews section (Figma REVIEWS 284:29) ────────────────────────────────────
   Composed in woocommerce/rebrand-parts/reviews.php from pieces we own: YITH's summary +
   histogram (still plugin-rendered), our chips + card list (rc-reviews-render.php) and our
   Add-a-Review form (rc-reviews-form.php). The legacy [revive-eo-reviews] / [reviews_tags]
   shortcodes are no longer involved, which is why this file no longer needs to neutralise a
   Foundation `.large-8.xlarge-6` wrapper, hide a duplicate `#reviews > #comments` list, or
   skin `.tab-review-tags-*` panes. See Projects/"Rebrand PDP Reviews — Legacy Decoupling". */
.rc-reviews {
	max-width: 1200px;
	margin: calc(48px * var(--rc-scale)) auto 0;
	padding: 0 24px;
	font-family: var(--rc-font);
	color: var(--rc-navy);
	text-align: center;
	/* Figma's EXACT star path (PDP Figma "5 Stars" 284:123 / card 284:33). One star per
	   16.0907-wide cell (= Figma's 80.4534 / 5) so repeat-x spacing matches the design. */
	/* Vote-control grey. The thumb buttons' box and the "Was this review helpful to you?"
	   label are the same colour by request (2026-09-09), so they share one declaration and
	   cannot drift apart. */
	--rc-vote-line: #cecece;
	/* The thumb GLYPH ink, sampled from rc-thumb-up.png / rc-thumb-down.png (core stroke
	   #737373-#747474; the lighter #BABABA/#CBCBCB pixels there are antialiasing). Separate
	   from --rc-vote-line because the box outline and the glyph inside it are two different
	   greys. Cannot be derived in CSS -- the thumbs are PNGs -- so resample the images if they
	   are ever redrawn. */
	--rc-vote-ink: #747474;
	--rc-star: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16.0907 15'%3E%3Cpath d='M7.49992 0L9.26326 5.0729L14.6328 5.18232L10.3531 8.42696L11.9083 13.5675L7.49992 10.4999L3.09158 13.5675L4.64678 8.42696L0.367074 5.18232L5.73659 5.0729L7.49992 0Z'/%3E%3C/svg%3E");
}
/* Top divider — a full-width horizontal rule under the accordions ("How to Use") and
   above the REVIEWS heading, spanning the gallery + details columns. .rc-reviews shares
   .rc-pdp's box (max-width 1200 / padding 0 24 → 1152 content), so this block ::before
   fills exactly the columns' content width. The .rc-reviews margin-top is the gap above
   the line; margin-bottom here is the gap below it before REVIEWS. */
.rc-reviews::before {
	content: "";
	display: block;
	/* 2026-09-14 team review: "Remove the line above Reviews". Kept as a pure spacer so the
	   gap above the REVIEWS heading does not collapse with the rule. */
	margin: 0 0 calc(40px * var(--rc-scale));
}
/* Figma puts the whole reviews body — summary, chips, cards and the Add-a-Review form —
   in one 660px column (x 418..1078 of the 1440 frame; the form boxes are exactly 660 wide).
   Scaling it with --rc-scale keeps every inner measurement at "Figma px x dial". */
/* 2026-09-08 review: "Expand the width of reviews to take whole block. See the existing site."
   Figma drew the whole reviews body in one 660px column; the team want the list to use the
   full block instead, like the live site. Dropping the cap hands the list .rc-reviews' own box
   (max-width 1200 - 2x24px padding = 1152 content), the same width as the gallery + buy-box
   columns above, so the divider above REVIEWS now spans exactly the list under it.
   Deliberately NOT applied to the Add-a-Review form: #review_form_wrapper carries its own
   660px cap (see the form block below), which is what keeps the four inputs at their designed
   size rather than stretching them across 1152px. The ask was about the reviews, not the form.

   ⚠️ SUPERSEDED 2026-09-10 by #43: "Narrow this by 10% so widht is 90%" (meeting note: "narrow
   the width from 100 to 90%, and centered in column"). This is a deliberate PARTIAL revert of
   the 09-08 expansion above, not a regression — the older Figma thread still reads "expand",
   so check the date before "restoring" it. The full-block expansion stays in the sense that
   the cap is a percentage of .rc-reviews' box rather than the original fixed 660px column;
   90% of the 1152 content box = ~1037, centered by the existing `margin: 0 auto`. */
.rc-reviews__inner { max-width: 90%; margin: 0 auto; }

/* The theme sets font-family:brandon-grotesque directly on h2/h3/h4/p, which beats an
   inherited font-family — so force Jost (style guide) explicitly on the reviews TEXT
   elements. Deliberately NOT applied to spans/links (star/vote icons keep their fonts). */
.rc-pdp .rc-reviews__heading,
.rc-pdp .rc-reviews__subhead,
.rc-pdp .rc-reviews .description,
.rc-pdp .rc-reviews .description p,
.rc-pdp .rc-reviews .description .review_title,
.rc-pdp .rc-reviews .description .review_content,
.rc-pdp .rc-reviews .author-meta strong,
.rc-pdp .rc-reviews .comment-text p { font-family: var(--rc-font) !important; }

/* Scoped under .rc-pdp so these beat the theme's generic `.rc-pdp h2` / `p{color:#666}`. */
.rc-pdp .rc-reviews__heading {
	font-size: calc(32px * var(--rc-scale));   /* Figma 284:139: Jost Medium 32 / 38, ls 0 */
	line-height: 1.1875;
	font-weight: var(--rc-weight-medium) !important;
	letter-spacing: 0;
	color: var(--rc-navy);
	margin: 0 0 calc(10px * var(--rc-scale));
}
.rc-pdp .rc-reviews__subhead {
	font-size: calc(20px * var(--rc-scale));   /* Figma 284:138: Jost Regular 20 / 24, navy */
	font-weight: 400;
	line-height: 1.2;
	color: var(--rc-navy);
	margin: 0 0 calc(32px * var(--rc-scale));
}

/* Average-review summary: the YITH star row and the "N reviews" line MEASURED as overlapping
   by 4px (stars bottom 3374 vs count top 3370) — the count sits 4px higher than the star row's
   box. Comp `588:4549` wants 6px of air between them, so the margin has to cover both: 10px
   nets the 6px (verified 2px at 6px of margin, 6px at 10px).
   NB: there are TWO .woocommerce-product-rating nodes in the reviews section — a zero-height
   legacy one first in the DOM and the real `ywar_summary_prepend-f` one. Anything measuring
   this block must pick the one with height, not querySelector's first match. */
.rc-pdp .rc-reviews .woocommerce-product-rating .star-rating {
	display: block;
	margin-bottom: calc(10px * var(--rc-scale));
}

/* Hide the native duplicate headings — rebrand supplies REVIEWS + subhead. */
.rc-reviews #reviews-summary-single > h4,
.rc-reviews__body h4 {
	position: absolute !important;
	width: 1px; height: 1px; padding: 0; margin: -1px;
	overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Summary: compact, centered; drop the empty-histogram column gap (0-data local). */
.rc-reviews .reviews-summary-single { margin: 0 0 calc(20px * var(--rc-scale)); }
.rc-reviews .reviews-summary-single .row { display: flex; flex-wrap: wrap; justify-content: center; gap: calc(24px * var(--rc-scale)); }
.rc-reviews .reviews-summary-single .column-left,
.rc-reviews .reviews-summary-single .column-right { width: auto; float: none; padding: 0; }
.rc-reviews .reviews_bar:empty { display: none; }
/* Average Review label (Figma 284:137): Jost Medium 10, uppercase, navy. */
.rc-reviews .star-rating-average-review {
	font-weight: var(--rc-weight-medium);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	font-size: calc(10px * var(--rc-scale));
	line-height: 1.4;
	color: var(--rc-navy);
	margin: 0 0 calc(6px * var(--rc-scale));
}
.rc-reviews .woocommerce-revive-eo-average-product-rating { text-align: center; }
.rc-reviews .woocommerce-revive-eo-average-product-rating .star-rating { margin: 0 auto calc(6px * var(--rc-scale)); }
/* Count + rating value (Figma 284:130): navy, no parens (stripped in reviews.php),
   Jost Medium 14, stacked on two centered lines. */
.rc-reviews .review-rating-value,
.rc-reviews .ywar_review_count {
	display: block;
	color: var(--rc-navy) !important;
	font-weight: var(--rc-weight-medium);
	font-size: calc(14px * var(--rc-scale));
	letter-spacing: 0.04em;
	line-height: 1.45;
}
.rc-reviews .ywar_review_count br { display: none; }
/* Histogram row count (Figma 284:101): small red number, no parens (stripped in reviews.php). */
.rc-reviews .ywar_num_reviews { font-size: calc(9px * var(--rc-scale)); color: var(--rc-red); }


/* ── Filter chips (Figma 628:288) ──────────────────────────────────────────────
   Ours now (rc_reviews_render_chips). Square, 0.5px #868787 border, white, navy 14 text;
   active chip inverts to navy. Filtering is client-side over each card's data-review-tags,
   so a chip is a <button>, not a link into a server-rendered pane. */
.rc-reviews__chips {
	display: flex; flex-wrap: wrap; justify-content: center;
	gap: calc(8px * var(--rc-scale));
	/* 2026-09-08 review, "Reduce margin below claims to 1px" — resolved 2026-09-09: the
	   "claims" is the .rc-reviews__chips-note disclaimer directly above this row ("...do not
	   represent product claims"), so the margin below it is THIS row's margin-top. Moiz was
	   editing exactly this declaration in DevTools. Was 24px x dial.
	   Literal px, not calc(1px * --rc-scale): the reviewed number is the rendered one.
	   NB the other half of the pair — "reduce space above the disclaimer", i.e. the note's own
	   margin-top, still 20px x dial — has no number yet and is left alone. */
	margin: 1px 0 0;
	/* Sticky while scrolling the list — this replaces the theme's ReviewStickyNav JS
	   (js/review-sticky-nav.js), which toggled a `.fixed` class and cloned the disclaimer
	   into a full-bleed band. position:sticky needs no JS and no clone.
	   The "check it clears any sticky site header" note above came true on 2026-09-09, when
	   the primary nav became sticky: at top:0 this row pinned to the viewport top and the
	   nav (z-index 1200 vs 20) painted straight over it. Offset by the pinned nav's measured
	   height instead — --rc-navh is published on :root by the controller in
	   footer-rebrand.php, and falls back to 0 if that script never runs. */
	position: sticky; top: var(--rc-navh, 0px); z-index: 20;
	background: #fff;
	padding: calc(10px * var(--rc-scale)) 0;
}
/* Once the chips take the sticky slot from the primary nav (rc-reviews.js sets
   .rc-nav-yielded on <html>), they pin to the very top rather than sitting under a nav that
   is no longer there. Desktop only, matching where the chips are sticky at all. */
html.rc-nav-yielded .rc-reviews__chips { top: 0; }
/* Flow marker used to detect when the chips have pinned. A sticky element's own rect reports
   its PINNED position, so it can never report that it is stuck; this stays in normal flow and
   gives an honest reading. No box of its own. */
.rc-reviews__chips-sentinel { height: 0; margin: 0; padding: 0; }
.rc-pdp .rc-reviews .rc-chip {
	margin: 0;
	padding: calc(4px * var(--rc-scale)) calc(16px * var(--rc-scale));
	border: 0.5px solid #868787;
	border-radius: 0;
	background: #fff;
	box-shadow: none;
	font-family: var(--rc-font);
	font-size: calc(14px * var(--rc-scale));
	line-height: calc(22px * var(--rc-scale));
	letter-spacing: 0.04em;
	font-weight: 400;
	text-transform: none;
	color: var(--rc-navy);
	cursor: pointer;
	-webkit-appearance: none; appearance: none;
	transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.rc-pdp .rc-reviews .rc-chip:hover { border-color: var(--rc-navy); }
.rc-pdp .rc-reviews .rc-chip.is-active {
	background: var(--rc-navy); border-color: var(--rc-navy); color: var(--rc-white, #fff);
}
.rc-reviews .rc-chip:focus-visible { outline: 2px solid var(--rc-navy); outline-offset: 2px; }
/* A canonical chip with no cards in the loaded set (a brand-new tag, say) — still clickable, but
   de-emphasised, and rc-reviews.js shows .rc-reviews__empty instead of a blank list. */
.rc-pdp .rc-reviews .rc-chip.is-empty { color: #868787; border-color: #dcdcdc; }
.rc-pdp .rc-reviews__empty {
	margin: calc(28px * var(--rc-scale)) 0 0;
	font-size: calc(14px * var(--rc-scale));
	color: #868787;
	text-align: center;
}

/* Disclaimer ABOVE the chips (Figma 413:785 — 8px there; 12 is the reviewed size). It used to be
   injected with hardcoded inline color/font-size by snippet 702083141 — it is ours now, so
   no !important needed. */
.rc-pdp .rc-reviews .rc-reviews__chips-note {
	color: var(--rc-navy);
	font-size: calc(12px * var(--rc-scale));
	line-height: 1.4;
	max-width: calc(660px * var(--rc-scale));
	margin: calc(20px * var(--rc-scale)) auto 0;
}

/* Card list. No `commentlist` class on the <ol> — that is what dragged the legacy
   `.commentlist > li…` rules (and the ReviewGallery snippet) onto our own cards. */
.rc-reviews .rc-reviews__list { list-style: none; margin: 0; padding: 0; text-align: left; }

/* Crisp 5-point stars. Two flavours of the same mask:
   - `.rc-stars` is OUR markup (review cards, rc-reviews-render.php) — no legacy baggage.
   - `.star-rating` is WooCommerce/YITH markup and is now only reached by the SUMMARY block,
     which is still rendered by the YITH template. It keeps the defensive rules (core ships
     `.woocommerce .star-rating { float: right }` plus em-based sizing); the cards no longer
     need them. Both are driven by an inline width:% on the fill element. */
.rc-reviews .rc-stars {
	position: relative; display: block;
	width: calc(80.4534px * var(--rc-scale));
	height: calc(15px * var(--rc-scale));
	overflow: hidden;
}
.rc-reviews .rc-stars::before,
.rc-reviews .rc-stars__fill::before {
	content: ""; position: absolute; inset: 0;
	-webkit-mask: var(--rc-star) left center / calc(16.0907px * var(--rc-scale)) 100% repeat-x;
	        mask: var(--rc-star) left center / calc(16.0907px * var(--rc-scale)) 100% repeat-x;
}
.rc-reviews .rc-stars::before { background: #e0e0e0; }
.rc-reviews .rc-stars__fill {
	position: absolute; top: 0; left: 0; height: 100%; display: block; overflow: hidden;
}
.rc-reviews .rc-stars__fill::before { background: var(--rc-red); }

.rc-reviews .star-rating {
	position: relative; display: inline-block;
	float: none !important;   /* WooCommerce core floats .star-rating right — that is what put
	                             the card's stars ~110px off under the body column, not the
	                             meta column's text-align. */
	width: calc(80.4534px * var(--rc-scale)) !important;
	height: calc(15px * var(--rc-scale)) !important;   /* !important: empty-span summary star collapses to 0 otherwise */
	font-size: 0 !important; line-height: 0; overflow: hidden; vertical-align: middle;
}
.rc-reviews .star-rating::before {
	content: ""; position: absolute; inset: 0; background: #e0e0e0;
	-webkit-mask: var(--rc-star) left center / calc(16.0907px * var(--rc-scale)) 100% repeat-x;
	        mask: var(--rc-star) left center / calc(16.0907px * var(--rc-scale)) 100% repeat-x;
}
.rc-reviews .star-rating > span {
	position: absolute; top: 0; left: 0; height: 100%; display: block; overflow: hidden;
}
.rc-reviews .star-rating > span::before {
	content: ""; position: absolute; inset: 0; background: var(--rc-red);
	-webkit-mask: var(--rc-star) left center / calc(16.0907px * var(--rc-scale)) 100% repeat-x;
	        mask: var(--rc-star) left center / calc(16.0907px * var(--rc-scale)) 100% repeat-x;
}
/* block1's rating value lives INSIDE its star-rating span — hide it (only the
   standalone sibling review-rating-value should print "5.00 out of 5 stars"). */
.rc-reviews .star-rating .review-rating-value { display: none !important; }
/* "Sharper stars on the Reviews right side" (2026-09-08 review). The rating histogram's
   stars are not artwork — they are FontAwesome text glyphs, from the child theme's own
   `span.ywar_stars_value.review-N-stars:before { content: "\f005..." }` (style.css ~461).
   A font glyph hints and anti-aliases as text, which is exactly why it reads soft next to the
   masked SVG stars used everywhere else in this section. Nothing to extract or redraw: repaint
   these with the SAME --rc-star path the cards and the rating selector already use, so all
   three star treatments on the page come from one source and stay crisp at any DPR.
   YITH also ships `min-width: 80px` on this span (yit-advanced-reviews.css:334), which would
   hold every row at 5 stars' width — reset it and size per star-count class instead. */
.rc-reviews .ywar_stars_value::before { content: none !important; }
.rc-reviews .ywar_stars_value {
	display: inline-block;
	min-width: 0;
	height: calc(15px * var(--rc-scale));
	background: var(--rc-red);
	-webkit-mask: var(--rc-star) left center / calc(16.0907px * var(--rc-scale)) 100% repeat-x;
	        mask: var(--rc-star) left center / calc(16.0907px * var(--rc-scale)) 100% repeat-x;
}
/* BOTH spellings on the one-star row. YITH pluralises the class off the count, so the row
   emits `review-1-star` and only rows 2-5 get `review-N-stars` — verified in the served
   markup. The plural-only selector left the 1-star span at `min-width: 0` and no width, i.e.
   0 x 18.75, so that row printed its "(376)" and bar against no stars at all while every
   other row looked right. */
.rc-reviews .ywar_stars_value.review-1-star,
.rc-reviews .ywar_stars_value.review-1-stars { width: calc(16.0907px * var(--rc-scale)); }
.rc-reviews .ywar_stars_value.review-2-stars { width: calc(32.1814px * var(--rc-scale)); }
.rc-reviews .ywar_stars_value.review-3-stars { width: calc(48.2721px * var(--rc-scale)); }
.rc-reviews .ywar_stars_value.review-4-stars { width: calc(64.3628px * var(--rc-scale)); }
.rc-reviews .ywar_stars_value.review-5-stars { width: calc(80.4534px * var(--rc-scale)); }

.rc-reviews .ywar_review_row {
	display: grid;
	grid-template-columns: calc(80.4534px * var(--rc-scale)) 50px 1fr;
	align-items: center;
}
/* Lifts YITH's filter-link wrapper out of the way: it is only emitted on rows above 0%, so
   without this the wrapped and unwrapped rows land in different grid cells. */
.rc-reviews .ywar_review_row > [class^="ywar_filter_reviews"] { display: contents; }

/* Average-review stars are larger in Figma (284:131 = 108.506×20.23, vs card 80.45). */
.rc-reviews .woocommerce-revive-eo-average-product-rating .star-rating {
	width: calc(108.506px * var(--rc-scale)) !important;
	height: calc(20.23px * var(--rc-scale)) !important;
	margin: calc(4px * var(--rc-scale)) auto calc(6px * var(--rc-scale));
}
.rc-reviews .woocommerce-revive-eo-average-product-rating .star-rating::before,
.rc-reviews .woocommerce-revive-eo-average-product-rating .star-rating > span::before {
	-webkit-mask-size: calc(21.7px * var(--rc-scale)) 100%;
	        mask-size: calc(21.7px * var(--rc-scale)) 100%;
}

/* ============================================================================
   Rebrand "All" pane — custom Figma-284:29 cards (rc-reviews-render.php).
   The rules ABOVE style the legacy YITH float markup still used by the per-tag
   panes; the rules BELOW style our own .rc-review markup in the All pane, which
   is a clean CSS grid (meta | body | photo) with the reused YITH vote block
   spanning full width beneath. rc-reviews.js reveals 15 cards per "See more".
   ============================================================================ */
/* The list carries no `commentlist` class and the cards no `has-thumbnail`, so none of the
   legacy `.commentlist > li…` styling reaches them any more. The .rc-pdp scope is kept only
   so these still outrank the theme's generic `.single-product p` / `p { color:#666 }` rules. */
.rc-pdp .rc-reviews li.rc-review {
	background: none;
	margin: 0;
}
.rc-pdp .rc-reviews li.rc-review {
	display: grid;
	/* Figma 628:287 measures the three columns as offsets 0 / 169 / 448 inside the 660px
	   content column, i.e. meta 169 | body 279 | photo 212 with no gutter of its own (the
	   body text box is 267 wide, so the 12px gutter is padding on the body — see below).
	   Everything rides --rc-scale, and so does .rc-reviews__inner, so the proportions hold. */
	/* The third track is the stars' corner even with no photo to sit under them. */
	grid-template-columns: calc(169px * var(--rc-scale)) minmax(0, 1fr) auto;
	column-gap: 0;
	align-items: start;
	/* Figma: 40px between one card's vote row and the next card's title, split either side
	   of the divider. */
	padding: calc(20px * var(--rc-scale)) 0;
	border-bottom: 1px solid rgba(5, 38, 79, 0.14);
	overflow: visible;
}
/* Each Figma Review component carries its own divider at the top, so the list opens with a
   rule as well as closing with one. */
/* No rule above the first card. Its border-top landed exactly on the chip block's bottom
   edge (both measured y=3754), so it read as an underline on the filter buttons — which the
   comp does not have (`588:4486` -> `588:4471` run straight into each other). The per-card
   bottom borders still separate the list. */
.rc-pdp .rc-reviews li.rc-review--has-photo {
	grid-template-columns: calc(169px * var(--rc-scale)) minmax(0, 1fr) calc(212px * var(--rc-scale));
}
.rc-reviews li.rc-review.is-hidden { display: none !important; }
/* Pre-JS cloak: hide the 16th+ card until rc-reviews.js takes over (no FOUC). */
.rc-reviews .rc-reviews__list.rc-reviews__precloak > li.rc-review:nth-child(n+16) { display: none; }

/* Meta column: name → VERIFIED PURCHASE → stars (stacked, top-left).
   text-align:left defeats the section-level `.rc-reviews{text-align:center}` so the
   inline-block star row lines up with the name + VERIFIED PURCHASE at the column's left. */
/* Relative to the card's title at y0, Figma stacks the meta column name y2 (21px box) →
   VERIFIED PURCHASE y23 (19px to the stars) → 5 stars y42. text-align:left defeats the
   section-level `.rc-reviews{text-align:center}` so the inline-block star row lines up with
   the name at the column's left edge. */
.rc-reviews .rc-review__meta { grid-column: 1; grid-row: 1 / span 2; text-align: left; padding-top: calc(2px * var(--rc-scale)); }
/* Top-right corner, on the title's line, with the photo (where there is one) below it. */
.rc-reviews .rc-review__stars { grid-column: 3; grid-row: 1; justify-self: end; }
.rc-reviews .rc-review__stars .rc-stars { margin: 0; }
.rc-pdp .rc-reviews .rc-review__author {
	display: block; font-weight: var(--rc-weight-semibold);
	font-size: calc(15px * var(--rc-scale)); line-height: calc(21px * var(--rc-scale));
	letter-spacing: 0.03em; color: var(--rc-navy); margin: 0;
}
.rc-reviews .rc-review__verified {
	display: block; font-weight: var(--rc-weight-medium);
	font-size: calc(10px * var(--rc-scale)); line-height: calc(19px * var(--rc-scale));
	letter-spacing: 0.04em; text-transform: uppercase; color: #CA681A; margin: 0;
}
/* Byline line 2 (2026-09-09): "MOST HELPFUL REVIEW" on curated reviews, the post date on all
   the rest — matching the live site, which the Figma comp does not draw. Both sit between the
   author name and VERIFIED PURCHASE.
   On the live site the flag is grey and slightly larger than VERIFIED PURCHASE (which is the
   orange/grey small caps below it), and the date shares that treatment — one rule for both, so
   the line does not jump height as cards switch between the two. */
.rc-pdp .rc-reviews .rc-review__helpful,
.rc-pdp .rc-reviews .rc-review__date {
	display: block;
	font-family: var(--rc-font) !important;   /* theme sets font-family on <time>/<span> */
	font-weight: var(--rc-weight-regular);
	font-size: calc(12px * var(--rc-scale));
	line-height: calc(19px * var(--rc-scale));
	letter-spacing: 0.02em;
	color: #868787;
	margin: 0;
	text-transform: none;
}
.rc-pdp .rc-reviews .rc-review__helpful { text-transform: uppercase; }
/* `hidden` on the featured card's <time> keeps the schema.org date in the markup without
   showing it. The theme sets `time { display: inline }`, which beats the UA sheet's
   [hidden] rule, so restate it. */
.rc-pdp .rc-reviews .rc-review__date[hidden] { display: none !important; }

/* Body column: title (18) above content (16), navy. */
/* Figma's body text box is 267 wide inside a 279 track — the 12px remainder is the gutter
   before the photo. */
.rc-reviews .rc-review__body { grid-column: 2; grid-row: 1 / span 2; min-width: 0; padding-right: calc(12px * var(--rc-scale)); }
/* padding-bottom: style.css puts 20px on a bare `.review_title`, which sits under the margin
   below and opened a 30px hole between the title and the review's first line. The margin is
   the spacing this card wants. */
.rc-pdp .rc-reviews .rc-review__body .review_title {
	display: block; font-weight: var(--rc-weight-medium);
	font-size: calc(18px * var(--rc-scale)); line-height: calc(22px * var(--rc-scale));
	color: var(--rc-navy); margin: 0 0 calc(10px * var(--rc-scale)); padding-bottom: 0;
}
.rc-pdp .rc-reviews .rc-review__body .review_content {
	display: block; font-size: calc(16px * var(--rc-scale));
	line-height: calc(24px * var(--rc-scale)); color: var(--rc-navy);
	word-wrap: break-word; overflow-wrap: anywhere;
}
/* A review body pasted from a document arrives wrapped in `<p>` (`data-pm-slice` from
   ProseMirror editors, `class="isSelectedEnd"` from Docs). The navy above reaches the text by
   INHERITANCE, and the child theme's `.single-product p { color: #666666 }` matches that `<p>`
   directly -- a direct match beats an inherited value at any specificity, so the whole review
   rendered gray while its unwrapped neighbors stayed navy. Reviews were being hand-edited to
   strip the wrapper; this is the fix for all of them, and for every future paste.
   Font size and line height are inherited unopposed, so only color and the theme's paragraph
   margins need restating. */
.rc-pdp .rc-reviews .rc-review__body .review_content p {
	color: inherit;
	margin: 0 0 calc(16px * var(--rc-scale));
}
.rc-pdp .rc-reviews .rc-review__body .review_content p:last-child {
	margin-bottom: 0;
}

/* Photo column — Figma 611:5433 is a fixed 212×211 crop starting 34px below the card top,
   so the box is sized in both axes and the (portrait/landscape) source is cover-cropped
   rather than letting its own aspect ratio drive the row height. */
.rc-reviews .rc-review__photo { grid-column: 3; grid-row: 2; padding-top: calc(12px * var(--rc-scale)); }
.rc-reviews .rc-review__photo img.review-thumbnail {
	/* !important to clear the legacy-card rule above (`height: auto !important`) and
	   `.woocommerce img { height: auto }`; higher specificity keeps it winning. */
	display: block;
	width: calc(212px * var(--rc-scale)) !important; max-width: 100% !important;
	height: calc(211px * var(--rc-scale)) !important; object-fit: cover;
	border-radius: 0; margin: 0 !important;   /* no rounded corners in this design */
}

/* Helpful-vote thumbs. The glyphs are the EXACT pixels the design shows: Figma 611:5419 is a
   screenshot of the live control, whose icons came from `#tab-reviews a.ywar_votereview` in
   css/nativecos.plugins.*.css — images/sprites.png framed by hardcoded background-position
   offsets. Round B removed the #tab-reviews wrapper, so those offsets stopped applying and the
   buttons rendered as empty boxes.

   Rather than substitute lookalike icons (a first attempt used filled Material glyphs — wrong:
   Figma's are OUTLINE), each sprite cell was extracted at its legacy offset into its own file
   under ../images/. That keeps the design pixel-exact, drops the sprite-offset arithmetic, and
   makes routinecos-styles self-contained instead of reaching into the theme for an asset.

     rest      up  -44 -46   down  -93 -47
     selected  up    8 -46   down   10   7   (the green / red variants in the same sprite)

   Box is Figma-measured 29x23 with a 5px gap (the mock places the screenshot at ~81%, so at the
   desktop --rc-scale of 1.25 this lands back on the sprite's natural 36x28 cell). */
.rc-reviews li.rc-review a.ywar_votereview {
	display: inline-block;
	width: calc(29px * var(--rc-scale));
	height: calc(23px * var(--rc-scale));
	border: 1px solid var(--rc-vote-line);
	background-repeat: no-repeat;
	background-position: center;
	background-size: contain;
	background-image: none;
	text-indent: 0;
	overflow: hidden;
	transition: border-color .15s ease;
}
.rc-reviews li.rc-review a.ywar_votereview.yes { background-image: url("../images/rc-thumb-up.png"); }
.rc-reviews li.rc-review a.ywar_votereview.not { background-image: url("../images/rc-thumb-down.png"); }
.rc-reviews li.rc-review a.ywar_votereview:hover { border-color: #6f6f6f; }
.rc-reviews li.rc-review a.ywar_votereview.yes.vote_selected {
	background-image: url("../images/rc-thumb-up-selected.png"); border-color: #028439;
}
.rc-reviews li.rc-review a.ywar_votereview.not.vote_selected {
	background-image: url("../images/rc-thumb-down-selected.png"); border-color: #bd0000;
}

/* Helpful-vote block (reused from YITH) — full width below, right-aligned. */
.rc-reviews li.rc-review .review_vote {
	grid-column: 1 / -1; grid-row: 3;
	display: flex; align-items: center; justify-content: flex-end;
	gap: calc(5px * var(--rc-scale)); margin: calc(16px * var(--rc-scale)) 0 0; text-align: right;
}
/* Figma sets the label ~12px off the first button; the 5px gap above is between the buttons. */
.rc-reviews li.rc-review .review_vote .review_helpful { margin-right: calc(7px * var(--rc-scale)); }
.rc-pdp .rc-reviews li.rc-review .review_vote .review_helpful,
.rc-pdp .rc-reviews li.rc-review .review_vote .ywar_review_helpful {
	font-size: calc(11px * var(--rc-scale)); line-height: calc(16px * var(--rc-scale));
	letter-spacing: 0.04em;
	/* Matched to the thumb GLYPHS, not the box outline around them (2026-09-24: "should be
	   same color as thumbs"). It was on --rc-vote-line, the box's #cecece, which left the
	   label visibly paler than the icons beside it. Supersedes the 2026-09-09 reading of
	   "same color as the grey box around the thumbs". Also lifts the contrast from ~1.6:1
	   to ~4.2:1, which is the right direction for a label. */
	color: var(--rc-vote-ink);
}

/* "See more" — reveals 15 more per click (rc-reviews.js), hidden when all are shown. */
.rc-reviews__more { text-align: center; margin: calc(28px * var(--rc-scale)) 0 0; }
/* 2026-09-09: "Make the See More button red background, white text."
   The button now carries `.rc-btn.rc-btn--primary` (rc-reviews-render.php), so the canonical
   CTA in rc-buttons.css owns the fill, the label colour and every state — including the inset
   box-shadow that survives the global `* { box-shadow: none !important }`. Nothing about the
   red is restated here; duplicating it is how the two drift.
   What stays local is only what makes THIS button different from a page CTA: it is a list
   control, so it keeps its own 14px label rather than the CTA's 11px, and it must not carry
   the theme's `button { margin-bottom: 20px }` — that has now caused four rebrand layout bugs
   (freq dropdown, scent tiles, mobile nav toggle, and it would push the Add-a-Review block
   down here). */
.rc-reviews__more-btn.rc-reviews__more-btn {
	font-size: calc(14px * var(--rc-scale));
	letter-spacing: 0.06em;
	margin-bottom: 0;
}

/* ============================================================================
   Add-a-Review form — Figma 610:5343 (markup: rc-reviews-form.php).
   Column is the same 660 (x --rc-scale) as the review list. Figma vertical rhythm,
   measured from the "Add a Review" label at y0:
     y0   Add a Review            Jost Medium 14 / 24, navy
     y34  SELECT YOUR RATING:     Jost Medium 11 / 13, +0.03em, uppercase, #868787
     y57  star selector           5 groups of 1..5 stars, 16px tall, hairline dividers
     y89  Name          |
     y139 Email Address | 36px tall, 1px #cecece, 14/18 placeholder #878787,
     y189 Review Title  | 28.34px left inset, 50px pitch (= 14px apart)
     y239 textarea (122.114 tall, same insets)
     y384 SUBMIT        197x44 red — reuses the canonical .rc-btn--primary (rc-buttons.css)
   ============================================================================ */
/* Fragment landing spots. #add-a-review is the deep-link target for review-request emails
   (rc-reviews-form.php); #reviews_summary is where in-page "N Reviews" links point. With the
   primary nav pinned, a bare jump parks either one underneath it — scroll-margin-top pushes
   the anchor down by the nav's measured height plus a little air. --rc-navh is published on
   :root by the sticky-nav controller; 0 if it never runs. */
#add-a-review,
#product-reviews,
#reviews_summary { scroll-margin-top: calc(var(--rc-navh, 0px) + 16px); }

.rc-reviews #review_form_wrapper {
	text-align: left;
	max-width: calc(660px * var(--rc-scale));
	margin: calc(20px * var(--rc-scale)) auto 0;
}
.rc-pdp .rc-reviews #respond .comment-reply-title {
	font-family: var(--rc-font) !important;
	font-size: calc(14px * var(--rc-scale)) !important;
	line-height: calc(24px * var(--rc-scale));
	font-weight: var(--rc-weight-medium) !important;
	letter-spacing: 0;
	text-transform: none;
	text-align: left;          /* #reply-title (id) centres it */
	color: var(--rc-navy) !important;
	/* Figma gap is 13px measured off a 21px text box; a real 24px line box already eats
	   ~4 of that, so 10px lands the label on the design's y34. */
	margin: 0 0 calc(10px * var(--rc-scale));
	padding: 0;                /* #reply-title adds 5px below */
}
.rc-reviews #respond .comment-reply-title small { display: none; }

/* --- "SELECT YOUR RATING:" star selector (Figma 588:4860) --- */
.rc-reviews .rc-review-form__rating { margin: 0 0 calc(16px * var(--rc-scale)); }
.rc-pdp .rc-reviews .rc-review-form__rating-label {
	display: block; font-family: var(--rc-font);
	font-weight: var(--rc-weight-medium);
	font-size: calc(11px * var(--rc-scale)); line-height: calc(13px * var(--rc-scale));
	letter-spacing: 0.03em; text-transform: uppercase; color: #868787;
	margin: 0 0 calc(10px * var(--rc-scale));
}
/* Figma total width 323.8 for 15 stars (1+2+3+4+5) at 16.0907 each = 241.4, leaving
   ~20.6 between groups; the divider sits in the middle of that gap. */
.rc-stars-select { display: flex; align-items: center; column-gap: calc(20.6px * var(--rc-scale)); }
.rc-stars-select__opt {
	position: relative; display: block; padding: 0; margin: 0; border: 0; border-radius: 0;
	background: none; box-shadow: none; cursor: pointer; line-height: 0;
	-webkit-appearance: none; appearance: none;
	height: calc(15px * var(--rc-scale));
}
.rc-stars-select__opt + .rc-stars-select__opt::before {
	content: ""; position: absolute; top: 0; bottom: 0;
	left: calc(-10.3px * var(--rc-scale)); width: 1px; background: #dcdcdc;
}
.rc-stars-select__opt:focus-visible { outline: 2px solid var(--rc-navy); outline-offset: 2px; }
/* Same exact Figma star path the cards use (--rc-star, defined on .rc-reviews). */
.rc-stars-select__stars {
	display: block; height: calc(15px * var(--rc-scale)); background: #cecece;
	-webkit-mask: var(--rc-star) left center / calc(16.0907px * var(--rc-scale)) 100% repeat-x;
	        mask: var(--rc-star) left center / calc(16.0907px * var(--rc-scale)) 100% repeat-x;
}
.rc-stars-select__opt[data-rating="1"] .rc-stars-select__stars { width: calc(16.0907px * var(--rc-scale)); }
.rc-stars-select__opt[data-rating="2"] .rc-stars-select__stars { width: calc(32.1814px * var(--rc-scale)); }
.rc-stars-select__opt[data-rating="3"] .rc-stars-select__stars { width: calc(48.2721px * var(--rc-scale)); }
.rc-stars-select__opt[data-rating="4"] .rc-stars-select__stars { width: calc(64.3628px * var(--rc-scale)); }
.rc-stars-select__opt[data-rating="5"] .rc-stars-select__stars { width: calc(80.4534px * var(--rc-scale)); }
/* Figma only draws the resting state; selected/hover take the same red as the card stars. */
.rc-stars-select__opt.is-on .rc-stars-select__stars { background: var(--rc-red); }

/* 2026-09-08 review: "Review form - has a hover over affect should be gone." Hovering a star
   group painted a blue box behind it — Foundation's `button:hover/focus { #007095 }` in
   shopkeeper-theme-01.css, which loads AFTER this sheet, so a single class ties on
   specificity and loses on source order. Doubled class to outrank it, and every state
   restated because the theme sets them all. Same trap as the other rebrand buttons.
   :focus-visible is deliberately NOT reset — the keyboard ring below stays. */
.rc-stars-select__opt.rc-stars-select__opt:hover,
.rc-stars-select__opt.rc-stars-select__opt:focus,
.rc-stars-select__opt.rc-stars-select__opt:active {
	background: none !important;
	box-shadow: none !important;
	border: 0 !important;
	outline: none;
}

/* 2026-09-08 review: "Review form - remove 2nd stars." WooCommerce's own star picker
   (`<p class="stars">`, five <a> links) is injected client-side by wc-single-product.js next
   to the `#rating` field, which our star selector renders as a hidden input — so it lands
   INSIDE .rc-review-form__rating and draws a second, softer row under ours. It is not in the
   server HTML, which is why it does not show up in a page-source check.
   Hidden rather than suppressed at the source: WC's handler writes to the same #rating input
   we do, so leaving it in the DOM is harmless, and dequeuing or unbinding the script would
   reach well beyond this one row. */
.rc-reviews .rc-review-form__rating p.stars { display: none !important; }

/* --- Fields: no labels, in-field placeholders --- */
/* Figma pitches the four fields 50px apart (36px tall + 14px gap). The theme sets
   `#commentform p { padding: 5px 0 }` and `.woocommerce #review_form #respond p
   { margin: 0 0 10px }` — plus a `margin-bottom: 0` override on .comment-form-author alone,
   which is what made the gaps come out 10 / 25 / 10 — and both outweigh a class selector
   here, so the reset has to be !important. */
.rc-reviews #commentform .comment-form-author,
.rc-reviews #commentform .comment-form-email,
.rc-reviews #commentform .comment-form-title,
.rc-reviews #commentform .comment-form-comment {
	margin: 0 0 calc(14px * var(--rc-scale)) !important;
	padding: 0 !important;
}
.rc-reviews #commentform label { display: none; }
.rc-reviews #commentform input[type="text"],
.rc-reviews #commentform input[type="email"],
.rc-reviews #commentform textarea {
	display: block; box-sizing: border-box; width: 100%;
	background: #fff !important;
	border: 1px solid #cecece !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	font-family: var(--rc-font) !important;
	font-size: calc(14px * var(--rc-scale)) !important;
	line-height: calc(18px * var(--rc-scale));
	color: var(--rc-navy);
	padding: 0 calc(28.34px * var(--rc-scale)) 0 10px;
	height: calc(36px * var(--rc-scale));
	-webkit-appearance: none; appearance: none;
}
.rc-reviews #commentform textarea {
	height: calc(122.114px * var(--rc-scale));
	padding: calc(11px * var(--rc-scale)) calc(28.34px * var(--rc-scale)) calc(11px * var(--rc-scale)) 10px;
	resize: vertical;
}
.rc-reviews #commentform input:focus,
.rc-reviews #commentform textarea:focus { border-color: var(--rc-navy) !important; outline: none; }
.rc-reviews #commentform ::-webkit-input-placeholder { color: #878787; opacity: 1; }
.rc-reviews #commentform ::placeholder { color: #878787; opacity: 1; }

/* --- Submit (Figma 588:4902) --- */
/* `#review_form #respond p.comment-form-comment { margin-top:-10px !important }` (two ids)
   outweighs even an !important class rule — it exists to close the gap the old visible
   "Your Review" label left behind, and there is no label here. */
.rc-reviews #review_form #respond p.comment-form-comment { margin-top: 0 !important; }

.rc-reviews #commentform .form-submit {
	text-align: center;
	margin: calc(23px * var(--rc-scale)) 0 0 !important;
	padding: 0 !important;
}
.rc-reviews #commentform .form-submit .submit { float: none; }
.rc-reviews #commentform .error.empty-review {
	display: block; font-family: var(--rc-font);
	font-size: calc(12px * var(--rc-scale)); color: var(--rc-red);
	margin: 0 0 calc(8px * var(--rc-scale));
}


/* Reviews at phone width. Breakpoint aligned 767 -> 768 so the PDP has ONE mobile
   boundary, matching rc-shell.css (769-1199 tablet band, <=768 mobile). */
@media (max-width: 768px) {
	/* .rc-pdp-scoped to match the desktop rules above — without the matching scope the
	   single-column collapse loses to them and the tracks stay at the desktop widths. */
	/* Two tracks, not one: the byline keeps the left and the stars stay in the top-right
	   corner (2026-09-08 review, "stars should be on right side of the name"). Everything
	   below the first row spans both. */
	.rc-pdp .rc-reviews li.rc-review,
	.rc-pdp .rc-reviews li.rc-review--has-photo { grid-template-columns: minmax(0, 1fr) auto; row-gap: calc(12px * var(--rc-scale)); }
	.rc-reviews .rc-review__meta { grid-column: 1; grid-row: 1; }
	.rc-reviews .rc-review__stars { grid-column: 2; grid-row: 1; justify-self: end; }
	.rc-reviews .rc-review__body,
	.rc-reviews .rc-review__photo { grid-column: 1 / -1; }
	.rc-reviews .rc-review__body { grid-row: 2; padding-right: 0; }
	/* 2026-09-08 review: "Reviews - Center the image" (mobile). MEASURED at 390px: the photo
	   container is the full 322px card width but the image inside is 212px starting at the
	   same x — i.e. left-aligned in a box nearly 50% wider than it. The container is a plain
	   block and the image has `margin: 0 !important` from the desktop rule, so centring has
	   to come from text-align on the box (the img is display:block, so `margin: auto` would
	   need to beat that !important; text-align does not fight it).
	   Desktop keeps the left edge: there the photo is its own narrow grid column, already
	   flush where the comp wants it. */
	.rc-reviews .rc-review__photo { grid-row: 3; padding-top: 0; text-align: center; }
	.rc-reviews .rc-review__photo img.review-thumbnail { margin-left: auto !important; margin-right: auto !important; }
	.rc-reviews li.rc-review .review_vote { grid-column: 1 / -1; grid-row: 4; }
	/* The chip block wraps to 4-5 rows on a phone; pinned at the viewport top that would
	   cover most of the screen while scrolling the list. Sticky is a desktop affordance. */
	.rc-reviews__chips { position: static; padding: 0; }
	/* The 5-group selector is 324px wide at scale 1 and the column is ~294px on a 390px
	   phone — tighten the gaps and let the last group wrap rather than overflow. */
	.rc-stars-select { flex-wrap: wrap; column-gap: calc(10px * var(--rc-scale)); row-gap: 8px; }
	.rc-stars-select__opt + .rc-stars-select__opt::before { left: calc(-5px * var(--rc-scale)); }
}

/* ============================================================================
   MOBILE PASS — Figma "PDP Page — Desktop — Mobile" MOBILE-PDP PAGE `588:4250`
   (file yaalFsG2VY659Xgcuy35Qa), a 360px frame with 17px gutters => 326px of
   content. Closes P5 in Projects/"PDP Build"; 86% of orders are mobile.

   Everything above this point is the desktop build; the only narrow-width rules
   that existed were the 1024px column collapse and the reviews block. Geometry
   below is taken from the comp's node offsets and was verified by measuring the
   live page over CDP at 360 / 414 / 768 / 1024 — not by eye.

   Deliberately NOT here (flagged, not lost):
   - The comp's hero DOTS pager (`588:4348`). The rebrand gallery is a static
     stage + thumb strip with no carousel behaviour, so dots would need new
     markup + JS — a build, not a responsive rule. The thumb strip already
     provides navigation on mobile.
   - The comp puts the ships line under the ADD TO CART button only (x93, the
     button's left edge). We keep it centred across the row: the comp copy is
     "…from Wisconsin", which y2018 removed, so that line is superseded anyway.
   ========================================================================= */
@media (max-width: 768px) {

	/* Page gutter 24 -> 17px, to the comp's 326px content width. The top padding
	   drops 40 -> 10px: the comp leaves 9px between the travel banner and the hero. */
	.rc-pdp { padding: 10px 17px 40px; }
	/* Thumb strip -> stars. The comp's node offsets give 22px, but Figma text frames carry
	   their full line box (its title and subtitle boxes actually overlap), so measuring gaps
	   off them overstates the air. Tightened to 14px on Daniel's side-by-side read. */
	.rc-pdp__grid { gap: 14px; }

	/* — Gallery — comp thumb strip `628:294`: six 46px tiles, 10px apart.
	   The strip stays the horizontal scroller set up in the 1024 block. */
	.rc-gallery { gap: 14px; }
	.rc-gallery__thumbs { gap: 10px; }
	.rc-gallery__thumb { width: 46px; height: 46px; }
	/* — Gallery dots — comp `588:4348`: six 6px dots on an 11px pitch (5px gap), centered
	   BETWEEN the hero and the thumb strip. They used to overlay the hero 10px above its
	   bottom edge; the 2026-09-25 comp moved them into the flow (image bottom 562, dots 570,
	   thumbs 584), so they are now a flex child of .rc-gallery rather than absolute.
	   The -6px margins take .rc-gallery's 14px column gap down to the comp's 8px on each
	   side — the gap and the margin add, so this is the only way to hit 8 without changing
	   the stage-to-thumbs spacing on a product that has no pager at all.
	   :empty collapses the row on single-image products, where rc-pdp.js builds no dots and
	   a bare flex child would otherwise still take its share of the column gap.
	   The comp paints every dot #CECECE, so it records no current slide; a pager needs one,
	   so the active dot takes brand navy. margin:0 on the dots themselves because they are
	   <button>s and the theme's `button { margin-bottom: 20px }` would otherwise push the
	   thumb strip down — same trap as .rc-scent / .rc-offer__ddbtn. */
	.rc-gallery__dots {
		display: flex;
		justify-content: center;
		gap: 5px;
		margin: -6px 0;
	}
	.rc-gallery__dots:empty { display: none; }
	.rc-pdp .rc-gallery__dot {
		width: 6px;
		height: 6px;
		padding: 0;
		margin: 0;
		border: 0;
		border-radius: 50%;
		background: #CECECE;
		cursor: pointer;
	}
	.rc-pdp .rc-gallery__dot.is-active { background: var(--rc-navy); }
	/* The theme repaints any button background on hover/focus — hold the pager colours. */
	.rc-pdp .rc-gallery__dot:hover,
	.rc-pdp .rc-gallery__dot:focus,
	.rc-pdp .rc-gallery__dot:active { background: #CECECE !important; }
	.rc-pdp .rc-gallery__dot.is-active:hover,
	.rc-pdp .rc-gallery__dot.is-active:focus,
	.rc-pdp .rc-gallery__dot.is-active:active { background: var(--rc-navy) !important; }

	/* — Stats — the comp keeps the DESKTOP 32px value on mobile (Figma `588:4738`: Jost
	   Regular 32, leading 16). An earlier pass read the node's 19.71px frame height as the
	   type size and shrank it to 20px — that was the box, not the line. Three 32px values
	   fit 326px; only the column padding needs to come in.
	   The row also carried 4px of its own margin on top of the buy-box gap, which read as too
	   much air above and below the percentages — the buy-box gap alone is enough here. */
	.rc-stats__item { padding: 0 8px; }
	.rc-stats { margin: 0; }

	/* The buy box stacks every section on one uniform gap; 20px (the desktop value) reads
	   loose at phone width. 14px across the column, with the two seams that need more air
	   putting it back locally (see .rc-offer below). */
	.rc-pdp__buybox { --rc-buybox-gap: 14px; }

	/* — SELECT SCENT — comp `588:4355`: 3-up, 100px tiles on an 11px gutter
	   (3x100 + 2x11 = 322 in 326). Desktop is 4-up. */
	.rc-scents__grid { grid-template-columns: repeat(3, 1fr); gap: 11px; }
	/* Scent panel, mobile — comp `968:566` (2026-09-11 redesign; supersedes `588:4296`).
	   --rc-scale is 1.0 here, so the desktop rules already render the comp's shared numbers
	   (13/22 bold name, 10/14 headings, 13/18 body, 6px dots). The type no longer differs
	   between breakpoints at all — the old mobile ramp (name 16/24, headings 11/13 tracking
	   .33, body 14/18, which carried the 2026-09-08 "Scent name -> 16px" comment) is dropped
	   because the new comp draws desktop and mobile identically. Only the box differs:

	     - 360x140 card, content inset 35px from the left and 17px from the right;
	     - the rule sits at x=180, i.e. dead centre of the phone (35 + 145);
	     - notes clear the rule by 17px, not the desktop 20px.

	   The 35px left inset is deliberate, not a spec-sheet artifact: desktop insets the panel
	   text 23px inside a 437px column whose tiles start at 0, and this is the same move at
	   phone width (tiles at 17, panel text at 35). It is also what puts the rule on centre. */
	.rc-scent-panel { padding: 13px 17px 22px 35px; }
	.rc-scent-panel__cols { grid-template-columns: 145px minmax(0, 1fr); }
	.rc-scent-panel__notes { padding-left: 17px; }

	/* ── 2026-09-08 review + Figma comments, MOBILE sizing ─────────────────────
	   Literal px throughout: --rc-scale is 1.0 below 1200px, so these are also the numbers
	   that render. Measured "before" values are noted so a later change can tell whether it
	   is moving a reviewed number or an unreviewed one. */

	/* "Coupon box, weight 500, font size 16px" (2026-09-08). The weight survives; the SIZE was
	   superseded on 2026-09-10 by #44 (14px / 1.5) — see the coupon block lower in this same
	   media query, which is where the live values now are. */

	/* "15px padding-top above the disclaimer". Was padding-top 0 with a 12px margin-top, so
	   the gap on screen read as 12px. Zeroing the margin and giving it 15px of padding makes
	   the measured gap exactly the 15px asked for, rather than 27px of the two stacked. */
	.rc-pdp .rc-claims__disclaimer { margin-top: 0; padding-top: 15px; }

	/* "What makes it work section, right column font to 15px." The right column is the
	   benefit text beside each ingredient name. Was 13px. */
	.rc-pdp .rc-ingredients__benefit { font-size: 15px; }

	/* #60: scent TILE label 11/13 -> 13/15. This re-points the 2026-09-08 "scent name -> 16px"
	   ask, which had been applied to the PANEL name on the assumption the tiles could not take
	   it. The meeting note names the tiles explicitly — "currently 11px, increase to 13px, 15px
	   line height" — and 13px does fit the 3-up row. The panel name is no longer involved: the
	   2026-09-11 redesign (comp `968:566`) sets it to 13/22 Bold at both breakpoints, which
	   retired the 16px override. Tiles and panel are separate elements and separate asks. */
	.rc-pdp .rc-scent__name { font-size: 13px; line-height: 15px; }
	/* Two lines reserved at the new line-height (2 x 15 + the card's 9/11px padding), so a
	   one-line name and a two-line name still produce identical tiles across rows. Was 46px,
	   sized for the old 13px line-height — leaving it would let a two-line name overflow its
	   card. See the .rc-scent__name block for why the reservation exists at all. */
	.rc-pdp .rc-scent__name { min-height: 50px; }

	/* #61: "Make these 9 px" — the per-scent badge ribbon. MEASURED at 8px before. The meeting
	   note said 10px; 9px is the written annotation and was confirmed as the number. */
	.rc-pdp .rc-scent__badge { font-size: 9px; }

	/* — SELECT PRODUCT — comp `588:4286`: 3 x 102px on a 10px gutter = exactly 326. */
	.rc-packs__grid { gap: 10px; }
	/* Comp: the pack buttons end at 1693.4 and the SELECT OFFER banner starts at 1713 — ~20px.
	   MEASURED 28px, because the buy-box's own 20px row gap is joined by 4px of margin from
	   each of .rc-packs and .rc-offer. Drop those two at this seam only. */
	.rc-packs { margin-bottom: 0; }
	.rc-offer { margin-top: 6px; margin-bottom: 0; }   /* 14 + 6 = the comp's ~20px at this seam */

	/* Coupon row -> ADD TO CART. Comp (`588:4271` bottom 2166 -> `588:4266` top 2177) is 11px;
	   ours MEASURED 54, made of four things: the empty TM-EPO totals bar (26px — hidden above),
	   .rc-offer's 4px bottom margin, the 14px buy-box gap, and the theme's 10px margin-top on
	   .variations_button. With the first, second and fourth cleared the seam falls back to the
	   buy-box's own 14px rhythm — 3px off the comp and consistent with the rest of the column,
	   which is a better trade than a negative margin to buy those 3px.
	   Only the TOP margin is zeroed: .variations_button's 5px margin-bottom is exactly what
	   produces the comp's 5px gap under the button, so it has to stay. */
	#rc-pdp-offer .variations_button { margin-top: 0; }

	/* — Coupon — tighten the gutters so the label keeps the comp's ~153px of text
	   width once the tag, checkbox and kit thumb have taken their share. */
	.rc-offer__coupon { gap: 8px; padding-right: 10px; }
	/* Mobile vertical padding 10 -> 5 (the #55/#56 trade). MEASURED at 390: band 91.4 -> 68px.
	   ⚠️ The mobile THUMB deliberately stays at 58px — #55 asked for it bigger, and it briefly
	   was (68px), but the thumb and the label compete for the same row. At 68px the label is
	   left ~138px and the sentence wraps to THREE lines, which is exactly what #44 asked to
	   stop. Daniel's call 2026-09-11: keep the two-line label, give up the larger thumb here.
	   MEASURED at 14px: 68px thumb -> label 138.4px -> 3 lines; 58px thumb -> 148.4px -> 2.
	   Desktop is unaffected and keeps the enlarged thumb — it has the room.
	   A third option exists and is NOT taken: trimming the angled "Coupon" flag's padding frees
	   ~14px and gives 2 lines WITH the 68px thumb (measured: label 152.4, band 78). Left alone
	   because it restyles an element nobody asked to change. */
	.rc-offer__coupon { padding-top: 5px; padding-bottom: 5px; }
	.rc-offer__couponthumb { width: 58px; margin-left: 4px; }
	/* #44: "Lets remove line break after 'a' so we dont' have it 3 lines ever."
	   The break was not, on its own, what made it three lines — MEASURED before any change,
	   the label was ALREADY wrapping to 3 lines at 16px in a 148px column. Two lines needs
	   BOTH halves: the break gone (here) and enough width (the 58px thumb above). Either one
	   alone leaves it at three. Verified at 390: 2 lines, band 68px. */
	/* #44: "Font size 14px / Line height 1.5" — supersedes the 16px set on 2026-09-09. */
	.rc-pdp .rc-offer__couponlabel { font-size: 14px; line-height: 1.5; font-weight: 500; }

	/* — Quantity + ADD TO CART — comp: 64px qty box, 12px gap, then the button
	   filling the rest of the row (251px of 326). The button is a flex item inside
	   .single_add_to_cart_button-wrapper (NB: the real wrapper is .variations_button
	   from the theme's variable-subscription template — NOT WooCommerce's
	   .woocommerce-variation-add-to-cart, which this page never renders).
	   The 10px gap moves onto the wrapper so a width:100% button can't overflow it. */
	#rc-pdp-offer .quantity .qty-enhanced-wrapper { width: 64px !important; }
	#rc-pdp-offer .single_add_to_cart_button-wrapper { flex: 1 1 auto; min-width: 0; margin-left: 12px; }
	#rc-pdp-offer .single_add_to_cart_button { width: 100%; margin-left: 0; }

	/* Ships line. Comp `588:4265`: 5px under the button, 18px before the icon row. Ours
	   measured 9px above and 28px below (its 14px bottom padding plus the buy-box gap).
	   margin-left re-derived for THIS row: the qty box is 64px + 2px of border here and the
	   button wrapper's gap is 12px (see the two rules above), so the button starts at 78px.
	   Without this the desktop 107px indent would leak in and push the line off-centre. */
	.rc-pdp .rc-offer__ships { margin-top: 0; padding-bottom: 4px; margin-left: 78px; }

	/* — Trust icons — the desktop 75px columns needed 407px and were the last thing
	   overflowing a 326px row after the grid fix. Comp `608:2908`: 35px icons, five
	   across, two-line labels. */
	.rc-trust { gap: 6px; }
	.rc-trust__item { width: auto; flex: 1 1 0; min-width: 0; gap: 6px; }
	.rc-trust__icon { width: 35px; height: 35px; }
	.rc-trust__label { font-size: 9px; line-height: 12px; letter-spacing: 0.2px; }

	/* — Claims — comp `588:4253` sets the checkmark gutter at 10px (desktop 16px). */
	.rc-claims__item { gap: 10px; }

	/* — Accordions — comp `588:4560` rows are 58px; desktop padding gives 63.6.
	   The 50px body inset (y2501, for the nested +/- on desktop) is too much of a
	   326px column, and the Pro Tip's 44px indent leaves too little for its text. */
	.rc-acc__head { padding: 15px 0; }
	.rc-acc__body { padding-right: 30px; }
	.rc-howto__protip { margin-left: 16px; }

	/* — Reviews — same 17px gutter as the rest of the page (its own inner
	   660px column still governs the body). */
	.rc-reviews { padding: 0 17px; }
	/* The section's ::before rule and the last accordion's bottom border drew TWO lines
	   between "How to Use" and REVIEWS. On desktop the ::before earns its place — it spans
	   both columns while the accordion sits only in the right one — but stacked they are the
	   same width and simply duplicate. Comp `588:4560` ends with one rule (`Vector 12`) and
	   the REVIEWS heading follows 24px later, so drop ours and carry that 24px on the section
	   (the ::before was also contributing its own 40px bottom margin). */
	.rc-reviews::before { display: none; }
	.rc-reviews { margin-top: 24px; }
	/* Comp `588:4558` is Jost Medium 16/24 — at our 20px it wrapped onto a second line. */
	.rc-pdp .rc-reviews__subhead { font-size: 16px; line-height: 24px; font-weight: 500; }
}

/* Full-bleed treatments — phone only. The comp draws the hero and the scent panel
   edge to edge (both 360 wide on the 360 frame). Above ~600px the stacked column is
   capped at 560 and centred, so bleeding by the 17px gutter there would just make
   two elements slightly wider than their neighbours instead of reaching the edge. */
@media (max-width: 600px) {
	/* Release the 560px cap here, or the two bleeding elements stop short: between 594px
	   (= 560 + the two 17px gutters) and 600px the column is capped and centred, so the
	   bleed reaches 594 of a 600px viewport instead of the edge. */
	.rc-pdp__grid { max-width: none; }
	.rc-gallery__stage,
	.rc-scent-panel {
		margin-left: -17px;
		margin-right: -17px;
		width: calc(100% + 34px);
	}
}

/* ===================== FULL INGREDIENT LIST MODAL ===================== */
/* Figma `939:447` "Pop-Up Full Ingredient List": 475x618 white card, 24px gutters, X at the
   top right. Title 18/20 w500; component heading 14/24 w500; list 12/16 w400; all #05264F.

   The comp is drawn for S&C's TWO components. Complete Bundle has six, which at the comp's own
   metrics is ~1600px, so the panel is capped and the BODY scrolls rather than the card growing
   off-screen. Height is min(618px, viewport - 48px) so short lists keep the drawn proportions
   and long ones never exceed the window.

   Sizes ride --rc-scale like the rest of the PDP; the 475px width does NOT, because a modal is
   viewport-anchored rather than part of the scaled page grid — scaling it would overflow a
   small laptop at the 1.25x dial. */
.rc-ingmodal[hidden] { display: none; }
.rc-ingmodal {
	position: fixed;
	inset: 0;
	z-index: 10000;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px;
}
.rc-ingmodal__overlay {
	position: absolute;
	inset: 0;
	background: rgba(5, 38, 79, 0.45);
}
.rc-ingmodal__panel {
	position: relative;
	display: flex;
	flex-direction: column;
	width: 475px;
	max-width: 100%;
	max-height: min(618px, calc(100vh - 48px));
	padding: 20px 24px 24px;
	background: #fff;
	color: var(--rc-navy);
	box-shadow: 0 10px 40px rgba(5, 38, 79, 0.25);
}
.rc-ingmodal__close {
	position: absolute;
	top: 20px;
	right: 24px;
	width: 15px;
	height: 15px;
	margin: 0;            /* the theme puts margin-bottom:20px on every <button> */
	padding: 0;
	border: 0;
	background: none;
	color: var(--rc-navy);
	cursor: pointer;
	line-height: 0;
}
.rc-pdp .rc-ingmodal__close:hover,
.rc-pdp .rc-ingmodal__close:focus { background: none !important; outline: none; opacity: 0.7; }
.rc-ingmodal__title {
	margin: 0 0 30px;
	padding-right: 30px;   /* clear of the X */
	font-size: 18px;
	line-height: 20px;
	font-weight: var(--rc-weight-medium);
	color: var(--rc-navy);
	text-transform: none;
}
.rc-ingmodal__body {
	overflow-y: auto;
	overscroll-behavior: contain;
}
.rc-ingmodal__component + .rc-ingmodal__component { margin-top: 24px; }
.rc-ingmodal__component-title {
	margin: 0 0 4px;
	font-size: 14px;
	line-height: 24px;
	font-weight: var(--rc-weight-medium);
	color: var(--rc-navy);
	text-transform: none;
}
.rc-pdp .rc-ingmodal__list {
	margin: 0;
	font-size: 12px;
	line-height: 16px;
	font-weight: var(--rc-weight-regular);
	color: var(--rc-navy);
}
.rc-pdp .rc-ingmodal__list + .rc-ingmodal__list { margin-top: 12px; }
/* The trigger is a <button> now rather than an <a>, so it needs the anchor's look back and the
   theme's blanket button margin removed. */
.rc-acc-more--btn {
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	cursor: pointer;
	font: inherit;
}
/* 2026-09-14 team review: "after you click VIEW FULL INGREDIENTS the link disappears", and
   "hover over hides this". shopkeeper-theme-01.css loads after this sheet and carries
   `button:hover,button:focus{color:#fff}` alongside its background rule — we were resetting
   the background but not the colour, so the label went white on white. Closing the modal
   returns focus to the trigger, which is why it vanished on the way BACK from the modal.
   Doubled class so a single class cannot lose on source order, and every state restated. */
.rc-pdp .rc-acc-more--btn.rc-acc-more--btn,
.rc-pdp .rc-acc-more--btn.rc-acc-more--btn:hover,
.rc-pdp .rc-acc-more--btn.rc-acc-more--btn:focus,
.rc-pdp .rc-acc-more--btn.rc-acc-more--btn:focus-visible,
.rc-pdp .rc-acc-more--btn.rc-acc-more--btn:active {
	background: none !important;
	background-color: transparent !important;
	background-image: none !important;
	color: var(--rc-navy) !important;
	border: 0 !important;
	box-shadow: none !important;
	text-shadow: none !important;
	text-decoration: underline;
	outline: none;
}
@media (max-width: 480px) {
	.rc-ingmodal { padding: 16px; }
	.rc-ingmodal__panel { padding: 16px 18px 20px; max-height: calc(100vh - 32px); }
	.rc-ingmodal__title { margin-bottom: 22px; }
	.rc-ingmodal__close { top: 16px; right: 18px; }
}

/* Set while the ingredient modal is open — without it a trackpad scrolls the page behind the
   dialog instead of the dialog's own body. */
body.rc-modal-open { overflow: hidden; }


/* ============================================================================
   Reviews — mobile (2026-09-14 team review)
   ============================================================================ */
@media (max-width: 768px) {

	/* "The Average Reviewed section is not centered under Reviews header."
	   The legacy summary markup carries .col-xs-offset-3-native, and a DB snippet offsets it
	   by `calc(50% - 71px)` to centre a 142px-wide block on the OLD layout. Inside the rebrand
	   section that column is a different width, so the offset lands it off-centre. Four
	   classes here outrank the snippet's two, whatever the source order. Desktop is left
	   alone — it reads correctly there and was not what the team flagged. */
	.rc-pdp .rc-reviews .column-left.col-xs-offset-3-native {
		margin-left: 0;
		width: 100%;
		text-align: center;
	}
	.rc-pdp .rc-reviews .column-right { width: 100%; float: none; }

	/* "Reduce side padding." The section's own gutter plus .rc-reviews__inner's 90% cap
	   stacked into a narrow column on a phone; drop the cap and trim the gutter. */
	.rc-reviews { padding: 0 12px; }
	.rc-reviews__inner { max-width: 100%; }

}

/* ============================================================================
   Gallery prev/next arrows (2026-09-14 team review)
   "Add arrows to the desktop gallery, have the arrow be outside the image. See current
   site." The current site hangs FontAwesome angle glyphs off its thumbnail strip at
   left/right -40px, tightening to -25px and then -5px as the viewport narrows; the offsets
   below mirror that. They sit on .rc-gallery__stagewrap because .rc-gallery__stage clips
   (overflow:hidden crops portrait masters to the square) and would cut them off.
   ============================================================================ */
.rc-gallery__stagewrap { position: relative; }

/* Doubled class + every state restated: shopkeeper-theme-01.css loads after this sheet with
   `button:hover,button:focus{background-color:#007095}` and `{color:#fff}`, and its blanket
   `button { margin-bottom: 20px }` would otherwise push these off centre. Same trap as
   .rc-scent, .rc-offer__ddbtn and the gallery dots. */
.rc-gallery__nav.rc-gallery__nav,
.rc-gallery__nav.rc-gallery__nav:hover,
.rc-gallery__nav.rc-gallery__nav:focus,
.rc-gallery__nav.rc-gallery__nav:focus-visible,
.rc-gallery__nav.rc-gallery__nav:active {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	display: flex;
	align-items: center;
	justify-content: center;
	width: calc(44px * var(--rc-scale));
	height: calc(44px * var(--rc-scale));
	margin: 0 !important;
	padding: 0;
	border: 0 !important;
	background: none !important;
	background-color: transparent !important;
	background-image: none !important;
	box-shadow: none !important;
	text-shadow: none !important;
	outline: none;
	color: var(--rc-navy) !important;
	cursor: pointer;
	z-index: 2;
}
.rc-gallery__nav[hidden] { display: none !important; }
.rc-gallery__nav svg {
	width: calc(26px * var(--rc-scale));
	height: calc(26px * var(--rc-scale));
	display: block;
}
.rc-gallery__nav--prev { left: calc(-40px * var(--rc-scale)); }
.rc-gallery__nav--next { right: calc(-40px * var(--rc-scale)); }
.rc-gallery__nav.rc-gallery__nav:hover { opacity: 0.7; }
/* stepTo() clamps rather than wraps, so an arrow at the end of the strip does nothing —
   show that rather than leaving a live-looking control that no longer responds. */
.rc-gallery__nav.rc-gallery__nav:disabled {
	opacity: 0.25;
	cursor: default;
	pointer-events: none;
}

@media (max-width: 1024px) {
	.rc-gallery__nav--prev { left: -25px; }
	.rc-gallery__nav--next { right: -25px; }
}
@media (max-width: 395px) {
	.rc-gallery__nav--prev { left: -5px; }
	.rc-gallery__nav--next { right: -5px; }
}

/* Offer box with no subscription (Travel Size, Sampler, Discovery Set, both bundles):
   the one-time tile is the only option and is forced selected, so the tick is decoration
   that reads as a control. 2026-09-14 team review — "remove the checkbox and left align
   ONE-TIME PURCHASE". Hiding the indicator leaves the name to sit at the tile's left edge,
   which is the "left align" half of the request. */
.rc-offer--single .rc-offer__check { display: none; }

/* Subtitle that is an inventory rather than a sentence (the Discovery Set, the Travel Size
   Sampler): left aligned, because a centred list is ragged on both edges. 2026-09-14 team
   review — "have bullets and left align on what is included". The class is applied by
   single-product-rebrand.php on a blank-line block of three or more lines.

   The bullets are the 2026-09-16 half of that same request: the block was left aligned at the
   time but rendered as <br>-separated lines, which cannot carry markers, so it is a real <ul>
   now. Markers are `outside` with matching padding — a wrapped scent name then aligns with the
   line above it rather than under its own bullet. The gaps are 09-16 too: subtitle <p>s are
   flush by design (margin:0 above), so the list opens the only breaks in the block — above it,
   and below it so the coupon disclaimer stops running straight on from the last scent. */
.rc-pdp .rc-pdp__subtitle--list,
.rc-pdp .rc-pdp__subtitle--list p { text-align: left; }
.rc-pdp .rc-pdp__subtitle--list ul {
	margin: calc(24px * var(--rc-scale)) 0;
	padding-left: 1.2em;
	list-style: disc outside;
	text-align: left;
}
.rc-pdp .rc-pdp__subtitle--list ul li {
	margin: 0;
	list-style: inherit;
}

/* Stat values that are a PHRASE rather than a figure — "12 Weeks" vs "82%". The Vitamins and
   both sets measure in weeks, and at the comp's 32px those crowd their neighbours (2026-09-14
   review: "the 3 week section is off, make space different"). Michelle's answer in the thread:
   20pt for the "XX Weeks" callouts. The class is applied by shape, so a future unit follows. */
.rc-pdp .rc-stats__value--phrase { font-size: calc(20px * var(--rc-scale)); line-height: 1.2; }
.rc-pdp .rc-acc-stats__value--phrase { font-size: calc(20px * var(--rc-scale)); line-height: 1.2; }

/* SELECT PRODUCT tiles carrying artwork (2026-09-14 review: "images for the select product with
   caption"). Opt-in per product via the parent's `_rc_pack_images` map; pack-toggle.php only
   adds .rc-packs--art when EVERY visible pack has an image, so a partial asset set stays on the
   text tiles rather than rendering a half-and-half row. The name becomes the caption under the
   bottle, so the button stacks instead of running inline. */
.rc-packs--art .rc-packs__btn.rc-packs__btn {
	flex-direction: column;
	align-items: center;
	gap: calc(6px * var(--rc-scale));
	padding: calc(10px * var(--rc-scale)) calc(8px * var(--rc-scale));
	height: auto;
}
.rc-packs--art .rc-packs__img {
	display: block;
	/* Auto margins, not the wrapper's align-items: the button is still an inline-block, so the
	   flex-direction/align-items/gap above it are inert and never centered this. A block box with
	   a max-width and no auto margins sits hard against the left padding. Centering the image
	   itself is also display-agnostic -- it holds whether or not the button ever becomes flex. */
	margin-left: auto;
	margin-right: auto;
	width: 100%;
	max-width: calc(96px * var(--rc-scale));
	height: auto;
	aspect-ratio: 1 / 1;
	object-fit: contain;
	mix-blend-mode: multiply;   /* the masters are on white; keeps the tile background clean */
}
.rc-packs--art .rc-packs__name {
	text-align: center;
	line-height: 1.25;
}

/* Selected state on ART tiles is the border alone, never the navy fill the text tiles use.
   The bottle masters are on white and blend `multiply`, so filling the tile navy multiplied the
   artwork down into the background and the bottle all but disappeared — the selected option was
   the one you could not see. Border-only keeps the product visible, which is the whole point of
   putting artwork here.

   2px border with 1px trimmed off the padding, so selecting a tile does not shift the row. Not
   `outline` or `box-shadow`: the theme resets both to none !important on hover/focus/active
   (see .rc-pdp button:hover above), so the ring would vanish the moment the cursor touched it.
   The :hover/:focus/:active copies exist for the same reason — those rules force the navy fill
   back with !important and would otherwise re-break the tile on hover. */
.rc-pdp .rc-packs--art .rc-packs__btn.is-active,
.rc-pdp .rc-packs--art .rc-packs__btn.is-active:hover,
.rc-pdp .rc-packs--art .rc-packs__btn.is-active:focus,
.rc-pdp .rc-packs--art .rc-packs__btn.is-active:active {
	background: var(--rc-white) !important;
	color: var(--rc-navy) !important;
	border-color: var(--rc-navy) !important;
	border-width: 2px;
	padding: calc(10px * var(--rc-scale) - 1px) calc(8px * var(--rc-scale) - 1px);
}

/* ── SELECT PRODUCT tiles built from delivered comp artwork ─────────────────────────
   Figma `1168:443` / `1168:450` / `1168:457` (Hair Oil / Scalp Serum / the pair) and
   `1170:560` / `1170:567` / `1170:581` (Hair Growth Vitamins 1 / 2 / 3 Pack). The comps
   give the pack tile the SAME component as SELECT SCENT — product on a light field, caption
   below, selection carried on the caption bar — so this block is the .rc-scent tile with a
   fixed field colour instead of a per-scent one.

   Distinct from .rc-packs--art above, which is the older attachment-map path: those are
   square masters on white, centred and multiplied into a plain tile, and two products still
   use it (Purple Toning, whose tiles have no comp). Restyling those onto this field would be
   redesigning a product from no spec, so the two treatments stay apart and pack-toggle.php
   picks one — file art wins where it exists.

   MEASURED off the tile components at 4x: field #D7F9FB (brand light blue, flat across every
   pack tile — there is no per-pack colour), 1px hairline at rest, 3px #05264F when selected
   with the caption bar filled navy and the label knocked to white. The comp samples the
   caption fill at #063661 while drawing its border #05264F; that is a two-navy tile three
   pixels apart, so both take --rc-navy here. */
/* Column flex, not block: a <button> centers its content box, so on a tile whose caption is
   shorter than its neighbors' the whole stack floated and left bare card above and below
   the navy bar. */
.rc-pdp .rc-packs--tile .rc-packs__btn.rc-packs__btn {
	display: flex;
	flex-direction: column;
	padding: 0;
	overflow: hidden;
	background: var(--rc-white);
	border: 1px solid rgba(5, 38, 79, 0.12);
	text-align: center;
}
.rc-packs--tile .rc-packs__field {
	position: relative;
	display: block;
	width: 100%;
	aspect-ratio: 100 / 74;
	background: var(--rc-packs-field, var(--rc-light-blue, #D7F9FB));
	overflow: hidden;
}
/* The caption reserves two lines so a one-line tile ("Hair Oil") and a two-line neighbour
   ("Hair Oil & Scalp Serum") give identical tiles — the same reservation, and the same
   reason, as .rc-scent__name. It also takes the row's leftover height, so the bar reaches
   the bottom of the card whatever the tallest tile in the row turns out to be. */
.rc-packs--tile .rc-packs__name {
	display: flex;
	flex: 1 1 auto;
	/* Column + stretch, so text-align does the horizontal centering: a one-line caption is an
	   anonymous flex item that shrink-wraps, and iOS leaves it at the padding edge. */
	flex-direction: column;
	align-items: stretch;
	justify-content: center;
	text-align: center;
	min-height: calc(46px * var(--rc-scale));
	padding: calc(9px * var(--rc-scale)) calc(6px * var(--rc-scale)) calc(11px * var(--rc-scale));
	font-size: calc(13px * var(--rc-scale));
	line-height: calc(16px * var(--rc-scale));
	font-weight: var(--rc-weight-semibold);
	color: var(--rc-packs-caption, var(--rc-navy));
	text-transform: none;
}
/* Selected: navy caption bar + the 3px edge, restated across the states because
   `.rc-pdp button:hover/:focus/:active` further up forces its own fill and clears the
   outline with !important. 1px border + 2px outline = the comp's 3px edge, and outline is
   drawn outside the border box so selecting a tile costs no layout. */
.rc-pdp .rc-packs--tile .rc-packs__btn.is-active,
.rc-pdp .rc-packs--tile .rc-packs__btn.is-active:hover,
.rc-pdp .rc-packs--tile .rc-packs__btn.is-active:focus,
.rc-pdp .rc-packs--tile .rc-packs__btn.is-active:active {
	background: var(--rc-white) !important;
	border-color: var(--rc-navy) !important;
	outline: 2px solid var(--rc-navy) !important;
	outline-offset: 0;
}
.rc-pdp .rc-packs--tile .rc-packs__btn.is-active .rc-packs__name {
	background: var(--rc-packs-caption-selected-bg, var(--rc-navy));
	color: var(--rc-packs-caption-selected, var(--rc-white));
}

/* Purple Toning (Figma 1196:446 / 1196:457 / 1196:467). The comp gives this product its own
   field, and a caption that stays purple on a lilac bar rather than knocking to white on navy.
   Keyed on the post id, not the slug: the September import re-slugged much of the catalogue
   while the ids stayed put, and the tile art beside it is keyed the same way. */
body.postid-705370470 .rc-packs--tile {
	--rc-packs-field: #6C6AC0;
	--rc-packs-caption: #6C6AC0;
	--rc-packs-caption-selected-bg: #D3D3FA;
	--rc-packs-caption-selected: #6C6AC0;
}
/* Hover is the scent grid's affordance: colour the edge, never the card. */
.rc-pdp .rc-packs--tile .rc-packs__btn:hover,
.rc-pdp .rc-packs--tile .rc-packs__btn:focus,
.rc-pdp .rc-packs--tile .rc-packs__btn:active {
	background: var(--rc-white) !important;
}
.rc-pdp .rc-packs--tile .rc-packs__btn:hover { border-color: var(--rc-navy); }
.rc-pdp .rc-packs--tile .rc-packs__btn:focus-visible {
	outline: 2px solid var(--rc-navy) !important;
	outline-offset: 2px;
}

/* ===================== Round 5 — mobile PDP type ===================== */
@media (max-width: 768px) {
	/* Scent Description name +2px (13 -> 15). Only the panel's name moves; the scent TILE
	   label is .rc-scent__name and stays at 13px, where the two-line reservation above it is
	   measured from. */
	.rc-pdp .rc-scent-panel__name {
		font-size: calc(15px * var(--rc-scale));
	}
	/* SELECT OFFER heading 11 -> 14px. The flanking rules are ::before/::after on the flex
	   parent and stay 2px, so only the word grows. */
	.rc-offer__label span {
		font-size: calc(14px * var(--rc-scale));
	}
	/* AVERAGE REVIEW block centred. Its column already carries text-align:center, but the
	   block is float:left -- a float shrink-wraps and hugs the left edge, so the alignment
	   could never reach it (measured 132px wide at the column's left edge inside a 442px
	   column). Dropping the float and letting auto margins do the work keeps the box its
	   own width, so the stars and the two lines under them stay where they are relative to
	   each other and only the box moves. Mobile only; the desktop two-column summary still
	   wants the float. */
	.rc-pdp .rc-reviews .woocommerce-product-rating {
		float: none;
		width: fit-content;
		margin-left: auto;
		margin-right: auto;
	}
	/* Gallery arrows need to read as controls. Below 1024px they move onto the image
	   (-25px, then -5px under 395px), where a navy glyph on a white bottle has almost no
	   edge. Shadow the GLYPH via filter rather than the button: the button rule sets
	   `box-shadow: none !important` five selectors deep, and a box-shadow would outline a
	   44px square rather than the arrow.
	   Two shadows on purpose -- the white halo separates the arrow from dark photography,
	   the navy one gives it depth on the light bottles. */
	.rc-gallery__nav.rc-gallery__nav svg {
		filter: drop-shadow(0 0 2px rgba(255, 255, 255, 0.9))
		        drop-shadow(0 1px 3px rgba(5, 38, 79, 0.35));
	}
}

/* Gallery arrows must not reach past the viewport. Below 600px .rc-gallery__stage bleeds to
   the screen edges (margin -17px / width calc(100% + 34px)), but the arrows are absolutely
   positioned against .rc-gallery__stagewrap, which is NOT bled -- so a -25px offset puts them
   17px outside the gutter and 8px outside the screen: measured prev L=-8, next R=508 in a
   500px viewport, which is the whole of the page's 8px horizontal scroll.

   -17px is the bleed itself, so the arrow sits flush with the screen edge at any width in this
   range rather than at a fixed inset that only happens to fit at some of them. This also
   subsumes the old max-width:395px special case, which existed because -25px overflowed the
   narrowest phones -- the same bug, patched one breakpoint at a time.

   Placed after those rules: same specificity, so source order decides. */
@media (max-width: 600px) {
	.rc-gallery__nav--prev { left: -17px; }
	.rc-gallery__nav--next { right: -17px; }
}

/* ============== SUB-NAV: RETURN ON SCROLL UP (mobile PDP) ============== */
/* Round 5 #1, 2026-09-24: "Keep this navigation (Reviews, Shampoo & Conditioner, Shop All)
   present when user is scrolling up". The shop page has had this since 2026-09-10; this is the
   same behaviour on the PDP, and the same controller in footer-rebrand.php drives both -- it
   now gates on `.rc-shop, .rc-pdp` and publishes --rc-navh and --rc-cath either way.

   Mobile only. The desktop PDP keeps pin-once-and-stay, which is the behaviour the primary nav
   was built for; the controller running there is harmless because these rules do not apply.

   Pinned under the primary nav at its measured height, one step below it in z so the mega
   dropdown still covers the category row. */
@media (max-width: 768px) {
	#rc-header.is-stuck.is-catnav-up .rc-catnav {
		position: fixed;
		top: var(--rc-navh, 0px);
		left: 0;
		right: 0;
		z-index: 1190;                   /* primary nav 1200; mobile drawer 20050 */
		background: var(--rc-white);
		box-shadow: 0 2px 8px rgba(5, 38, 79, 0.06);
	}
	/* Holds the row's height while it is out of flow, or the page jumps by that height the
	   instant it pins. */
	#rc-header.is-stuck.is-catnav-up .rc-catnav__spacer {
		height: var(--rc-cath, 0px);
	}
}

/* ===================== Round 6 — mobile ===================== */
@media (max-width: 768px) {
	/* Move the disclaimer's space from above it to below it (2026-09-24 round 6 #1: "Remove
	   margin here under the reviews and add margin under the 'These filters and product
	   reviews...' text"). Measured before the change: a 20px gap above, entirely this element's
	   own margin-top, and 0 below — so it read as attached to the filter chips rather than to
	   the histogram it describes. Nothing else contributes a margin on either side, so this is
	   a straight move rather than a new value. */
	.rc-pdp .rc-reviews .rc-reviews__chips-note {
		margin-top: 0;
		margin-bottom: calc(20px * var(--rc-scale));
	}
}

/* ===================== ROUND 4 #2 — PDP product name (mobile only) =====================
 * Business ask 2026-09-25: 35px / 500 / 42px line-height on mobile. The base rule pins the h1 to
 * the comp with !important (the theme's own h1 forces uppercase + bold and otherwise wins), so
 * this has to carry !important too, and sits at the end of the file to clear it on equal
 * specificity. Desktop keeps --rc-text-h1-size (30 × scale).
 */
@media (max-width: 768px) {
	.rc-pdp h1.rc-pdp__title {
		font-size: 35px !important;
		line-height: 42px !important;
		font-weight: 500 !important;
	}

	/*
	 * Round 4 #2b: centre the star row between the gallery and the name. The BOXES were already
	 * symmetric -- 14px above and below -- so this is not a box-model gap, it is INK. The gallery
	 * leaves trailing space under the thumbnails and the 42px line box leaves ~3.5px of leading
	 * above the caps, which put the row 34.7px below the thumbnails and 24.0px above the title.
	 *
	 * Measured off the rendered pixels (first/last non-white row per band), not the layout boxes,
	 * because the layout boxes say it is already centred.
	 *
	 * The pair is the point: -5 alone would lift the row AND everything after it, leaving the gap
	 * below unchanged. Cancelling it with +5 keeps the row's contribution to the flow identical,
	 * so the title does not move and the 10.7px asymmetry is split.
	 *
	 * Optical, and tuned to this size -- revisit if the h1 or the gallery spacing changes.
	 */
	.rc-pdp__buybox > .rc-stars {
		margin-top: -5px;
		margin-bottom: 5px;
	}
}

/* ===================== ROUND 1 #5 — offer box type (mobile only) =====================
 * Business ask 2026-09-26, against a mobile screenshot with arrows on SUBSCRIBE, ONE-TIME
 * PURCHASE and every benefit line: "increase font size here to 14px inside boxes". Both were
 * 13px — calc(13px * --rc-scale), and --rc-scale is 1 below 1200px, so they rendered literally.
 *
 * Confirmed OUT of scope with Daniel: "Select Frequency" (.rc-offer__freqlabel, also 13px) stays
 * as it is, and the prices stay at 15px. So this names the two selectors the arrows land on and
 * nothing else — the sizes in this box are no longer one shared number, which is the point.
 *
 * Mobile only. Desktop resolves the same tokens through the 1.25 dial (16.25px) and was not
 * raised; a literal 14px here would have SHRUNK it. At the end of the file for source order —
 * the base rules are earlier in this sheet at equal specificity.
 */
@media (max-width: 768px) {
	.rc-offer__name {
		font-size: 14px;
	}
	.rc-offer__benefits li {
		font-size: 14px;
	}
}

/* ===================== ROUND 6 #1 — gallery taps must not zoom =====================
 * "When I scroll through carousels, I often end up zooming in unintentionally while hitting
 * arrows." Confirmed on the PDP at 390 with an iPhone UA: the gallery's tap targets all compute
 * `touch-action: auto`, which leaves iOS's double-tap-to-zoom gesture armed on them. Two quick
 * taps on an arrow — exactly what paging through a gallery looks like — is a double-tap.
 *
 *   .rc-gallery__nav--prev / --next   44x44   auto
 *   .rc-gallery__dot                   6x6    auto
 *   .rc-gallery__thumb                46x46   auto
 *
 * `manipulation` is the narrow fix: it keeps panning and PINCH zoom (so a shopper who wants to
 * zoom the product still can, and nothing about accessibility zoom changes) and drops only the
 * double-tap gesture on these controls. It also removes iOS's ~300ms click delay, so paging gets
 * more responsive as a side effect.
 *
 * The image itself is deliberately NOT included: `.rc-gallery__img` is already `pan-y` for the
 * swipe-to-page handler, and `manipulation` would hand the horizontal axis back to the browser
 * and break paging.
 *
 * SCOPE: Daniel asked for the carousel only. The same `auto` is on the quantity stepper
 * (.qty-enhanced-btn) and the checkout inputs are 14px, which makes iOS zoom on focus — both in
 * the P2-13 finding, neither changed here. The Klaviyo `touch-action: none` in that finding is
 * NOT a bug: it is that popup's scroll-lock while it is open, which is correct.
 */
.rc-gallery__nav.rc-gallery__nav,
.rc-gallery__dot.rc-gallery__dot,
.rc-gallery__thumb.rc-gallery__thumb {
	touch-action: manipulation;
}

/* iOS zoom — the review form. The rule above pins these to calc(14px * var(--rc-scale)), which
   is under iOS Safari's 16px focus-zoom threshold, so tapping any of them zooms the page and
   leaves it scaled. rc-brand.css cannot fix it: same specificity, and this sheet loads later.
   Touch devices only, so the desktop review form keeps its scaled 14px. */
@media (hover: none) and (pointer: coarse) {
	.rc-reviews #commentform input[type="text"],
	.rc-reviews #commentform input[type="email"],
	.rc-reviews #commentform input[type="url"],
	.rc-reviews #commentform textarea {
		font-size: 16px !important;
	}
}
