/* Renéra · Product detail page (PDP) — bespoke WooCommerce single-product styles.
   --------------------------------------------------------------------------
   Ported from the Claude Design "Product page" project (product-styles.css).
   Extends the global brand language (design-system.css + chrome.css). Loaded
   only on is_product() by reneranutrition_enqueue_product_page() with chrome.css
   as a dependency. Uses var(--renera-*) tokens exclusively — never hard-coded hex. */

/* =========================================
   Legacy DB-CSS counter
   ========================================= */
/* Theme-wide "Additional CSS" in the DB (Elementor-era, still present on
   every env) ships `.woocommerce h2{font-size:18px!important}`, which
   flattens EVERY display heading on the PDP — the body carries the
   .woocommerce class here. Same fight checkout.css documents for its
   section titles: out-specify it AND match the !important until the DB
   block is retired. Mirrors chrome.css's .rn-h-2 sizes exactly. */
body.rn-pdp-page h2.rn-h-display.rn-h-2 { font-size: 56px !important; }
@media (max-width: 980px) {
  body.rn-pdp-page h2.rn-h-display.rn-h-2 { font-size: 40px !important; }
}

/* =========================================
   Breadcrumb
   ========================================= */
.rn-crumbs {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-family: var(--renera-font-mono);
  font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--renera-mute);
  padding: 22px 0 0;
}
.rn-crumbs a { color: var(--renera-mute); text-decoration: none; }
.rn-crumbs a:hover { color: var(--renera-olive-700); }
.rn-crumbs .sep { opacity: 0.45; }
.rn-crumbs .cur { color: var(--renera-olive-700); }

/* =========================================
   PDP grid
   ========================================= */
.rn-pdp {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: 80px;
  padding: 40px 0 68px;
  align-items: start;
}

/* Phone-only PDP piece — the tagline+name header above the gallery. Renders
   always (single template) but only the ≤1080px pass turns it on, where the
   buy box hides its own copies of those lines. */
.rn-pdp__mhead { display: none; }

/* ───── Gallery ───── */
.rn-gallery {
  /* Tile geometry drives both the grid column and the rail's scroll window.
     --rn-thumb-visible is how many tiles the rail shows at once; it mirrors
     $rn_rail_visible in woocommerce/single-product.php (which decides whether
     the step buttons render at all) — keep the two in sync. */
  --rn-thumb: 88px;
  --rn-thumb-gap: 12px;
  --rn-thumb-visible: 4;
  /* Width of the selected tile's outward ring — the scroll box has to be
     padded by this much or overflow:auto clips the ring off. */
  --rn-thumb-ring: 5px;

  display: grid;
  grid-template-columns: var(--rn-thumb) 1fr;
  gap: 20px;
  position: sticky; top: calc(var(--rn-announce-h, 48px) + 100px);
  align-self: start;
}
/* Single real product image — no thumbnail rail, main image spans the column. */
.rn-gallery--single { grid-template-columns: 1fr; }
/* Step button · scroll window · step button. */
.rn-gallery__rail {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  min-height: 0;
}
.rn-gallery__thumbs {
  display: flex; flex-direction: column; gap: var(--rn-thumb-gap);
  /* Exactly N tiles tall (N tiles + N-1 gaps + the ring padding); the rest
     scrolls. offsetTop of a tile must resolve against this box, hence
     position: relative. The negative margin cancels the ring padding so the
     tiles still sit flush where they did before the box existed. */
  position: relative;
  box-sizing: border-box;
  padding: var(--rn-thumb-ring);
  margin: calc(var(--rn-thumb-ring) * -1);
  /* Must stay on ONE line: LiteSpeed's CSS minifier (dev/prod) collapses a
     newline after "+" into nothing, producing ")+var(" — invalid calc(), so
     browsers drop the declaration and the rail loses its scroll window. */
  max-height: calc(var(--rn-thumb) * var(--rn-thumb-visible) + var(--rn-thumb-gap) * (var(--rn-thumb-visible) - 1) + var(--rn-thumb-ring) * 2);
  overflow-y: auto;
  scroll-behavior: smooth;
  /* The rail has its own arrows — a native scrollbar would eat tile width. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.rn-gallery__thumbs::-webkit-scrollbar { display: none; }
/* Round, like the prev/next arrows under the frame — the two sets of gallery
   controls read as one family. */
.rn-gallery__railbtn {
  width: 26px; height: 26px; border-radius: 50%;
  border: 1px solid var(--renera-clay-300);
  background: var(--renera-sand-200);
  color: var(--renera-olive-700);
  cursor: pointer;
  padding: 0; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background var(--renera-dur-fast) var(--renera-ease),
              color var(--renera-dur-fast) var(--renera-ease),
              opacity var(--renera-dur-fast) var(--renera-ease);
}
@media (hover: hover) {
  .rn-gallery__railbtn:hover:not(:disabled) {
    background: var(--renera-iconbtn-bg-hover);
    color: var(--renera-iconbtn-fg-hover);
  }
}
.rn-gallery__railbtn:disabled { opacity: 0.35; cursor: default; }
.rn-gallery__thumb {
  position: relative; cursor: pointer;
  width: var(--rn-thumb); height: var(--rn-thumb);
  /* Without this the flex column squashes tiles instead of overflowing. */
  flex: 0 0 auto;
  border-radius: var(--renera-r-md);
  border: 1px solid var(--renera-clay-300);
  overflow: hidden;
  transition: border-color var(--renera-dur-fast) var(--renera-ease);
  padding: 0;
}
/* Photos fill their rounded tile edge-to-edge (cover) — no letterboxed inset. */
.rn-gallery__thumb img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  padding: 0;
}
/* The selected tile reads at a glance: a 3px olive ring held off the tile by a
   2px page-coloured gap. The ring lives in box-shadow, not border, so the tile
   keeps its exact --rn-thumb box and the 4-tile window math stays true.
   Its outward reach must equal --rn-thumb-ring or the scroll box clips it. */
.rn-gallery__thumb.is-on {
  border-color: var(--renera-olive-700);
  box-shadow: 0 0 0 2px var(--renera-sand-300), 0 0 0 5px var(--renera-olive-700);
}
/* Video tile. Its cover image defaults to the product photo, so the tile can be
   a near-duplicate of slide 1 — the play affordance is what tells them apart and
   has to carry that on its own. A solid olive disc (same round family as the
   rail/nav buttons) over a light wash, sized as a share of the tile so it holds
   its proportions at every responsive --rn-thumb. */
.rn-gallery__play {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.16);
  transition: background var(--renera-dur-fast) var(--renera-ease);
}
.rn-gallery__playdot {
  width: 38%; height: 38%;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--renera-olive-700);
  color: var(--renera-sand-100);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
  transition: transform var(--renera-dur-fast) var(--renera-ease);
}
.rn-gallery__playdot svg { width: 52%; height: 52%; }
.rn-gallery__thumb--video:hover .rn-gallery__play { background: rgba(0, 0, 0, 0.06); }
.rn-gallery__thumb--video:hover .rn-gallery__playdot { transform: scale(1.08); }
/* Frame + its controls stacked in the gallery's right-hand column. */
.rn-gallery__stage {
  display: flex; flex-direction: column; gap: 14px;
  min-width: 0;
}
.rn-gallery__main {
  position: relative;
  border-radius: var(--renera-r-xl);
  overflow: hidden;
  border: 1px solid var(--renera-clay-300);
  aspect-ratio: 1 / 1;
}
/* The photo is scaled up to fill the rounded frame edge-to-edge — the frame's own
   border-radius + overflow:hidden clip it, so the image takes the rounded shape
   instead of floating inside it. No backdrop or centering: nothing shows through.

   Scoped to .rn-gallery__main on purpose: WooCommerce's own stylesheet ships
   `.woocommerce img { height: auto }`, which at (0,1,1) outranks a lone
   `.rn-gallery__photo` (0,1,0) — the photo then collapsed to its intrinsic
   height and left the bottom of the frame empty. Two classes (0,2,0) win. */
.rn-gallery__main .rn-gallery__photo {
  width: 100%; height: 100%; object-fit: cover; padding: 0; display: block;
}
/* Video slide — same square frame as a photo, so switching slides doesn't move
   the page. The [hidden] rule has to be as specific as the display:block above
   it, hence the two-class selector; the frame's own overflow:hidden rounds the
   player's corners the way it rounds the photo's. */
.rn-gallery__main.is-video .rn-gallery__photo { display: none; }
.rn-gallery__video {
  position: absolute; inset: 0;
  /* The cover image sits behind the player (inline background-image, set from the
     ACF poster) so an embed shows a still frame instead of a black square during
     the iframe's first paint. Matched to the player's own fill. */
  background-color: var(--renera-ink);
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
}
.rn-gallery__video[hidden] { display: none; }
/* Fills the square edge-to-edge like the photos do, poster included — the frame
   never letterboxes. The browser's controls lay out on the element box, not the
   cropped frame, so they stay fully reachable. A YouTube/Vimeo iframe fills the
   same box, but the provider letterboxes its own 16:9 content inside it; that
   is theirs to decide and cropping it would cut off their player controls. */
.rn-gallery__video video,
.rn-gallery__video iframe {
  width: 100%; height: 100%;
  display: block; border: 0;
  object-fit: cover;
}
/* Sits below the frame, centred on it — outside the rounded shape, so nothing
   covers the photo. Static flow: no absolute offset or blur backdrop needed. */
.rn-gallery__nav {
  display: flex; justify-content: center; gap: 10px;
}
.rn-gallery__nav button {
  width: 32px; height: 32px; border-radius: 50%;
  border: 1px solid var(--renera-clay-300);
  background: var(--renera-sand-200);
  color: var(--renera-olive-700);
  cursor: pointer;
  padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background var(--renera-dur-fast) var(--renera-ease),
              color var(--renera-dur-fast) var(--renera-ease);
}
.rn-gallery__nav button:hover {
  background: var(--renera-olive-700);
  color: var(--renera-sand-200);
}

/* Browsers paint their own blue ring (Chrome: rgb(0,95,204)) on whichever
   gallery control was last clicked or tabbed to. Drop it everywhere in the
   gallery and re-state focus in brand olive for keyboard users only — a mouse
   click leaves no ring behind. On the tiles the ring is inset, because the
   rail is an overflow:auto box and would clip an outward one. */
.rn-gallery :focus { outline: none; }
.rn-gallery__thumb:focus-visible {
  outline: 2px solid var(--renera-olive-700);
  outline-offset: -3px;
}
.rn-gallery__railbtn:focus-visible,
.rn-gallery__nav button:focus-visible {
  outline: 2px solid var(--renera-olive-700);
  outline-offset: 2px;
}

/* ───── Buy box ───── */
.rn-buy { display: flex; flex-direction: column; gap: 28px; padding-top: 4px; }
.rn-buy__title {
  font-family: var(--renera-font-serif);
  font-weight: 400; letter-spacing: -0.015em;
  font-size: 56px; line-height: 1.04; color: var(--renera-ink);
  margin: 0; text-wrap: balance;
}
.rn-buy__title em { color: var(--renera-olive-700); font-style: italic; }
/* Product name as the headline — the full WooCommerce title is long, so it uses
   the same Recoleta serif as the tagline but at a size that reads as a name, not
   a banner. */
.rn-buy__title--name {
  font-size: 44px; line-height: 1.08; letter-spacing: -0.015em;
}
/* "with Marine Collagen Peptides & …, 12 Packets" — the descriptor tail of the
   WooCommerce title, shown small beneath the name as a subtitle. */
.rn-buy__name-sub {
  font-family: var(--renera-font-sans);
  font-size: 14px; line-height: 1.5;
  color: var(--renera-mute);
  margin: -14px 0 0;
}
/* Flavor attribute, directly under the descriptor. Rendered as an outline pill
   rather than a bare mono line: sitting loose under a long grey paragraph it
   read as stray text rather than a product spec. Outline — not the solid olive
   of .rn-price__badge — so it stays secondary to the price. align-self keeps it
   hugging its own content instead of stretching the full flex-column width.
   The negative top margin pulls it out of .rn-buy's 28px gap so it groups with
   the name block, the same trick .rn-buy__name-sub and .rn-stock use; it is
   re-tuned at the 600px breakpoint where that gap drops to 20px. */
.rn-buy__attr {
  align-self: flex-start;
  display: inline-flex; align-items: baseline; gap: 7px;
  margin-top: -14px;
  padding: 6px 12px;
  border: 1px solid var(--renera-clay-300);
  border-radius: var(--renera-r-pill);
  font-family: var(--renera-font-mono);
  font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase;
  line-height: 1;
}
.rn-buy__attr-label { color: var(--renera-mute); }
.rn-buy__attr-label::after { content: " ·"; }
.rn-buy__attr-value { color: var(--renera-olive-700); }
/* "When science meets nature." — scene-setting tagline above the name, not the
   product name itself. Atmospheric italic serif in brand olive. */
.rn-buy__tagline {
  font-family: var(--renera-font-serif);
  font-style: italic; font-weight: 400;
  font-size: 21px; line-height: 1.25;
  color: var(--renera-olive-500);
  margin: 0;
}
.rn-buy__tagline em { color: var(--renera-olive-700); font-style: italic; }
.rn-buy__sub {
  font-family: var(--renera-font-serif); font-style: italic; font-weight: 400;
  font-size: 19px; line-height: 1.45; color: var(--renera-olive-700);
  margin: 0; text-wrap: pretty;
}
.rn-stars {
  display: inline-flex; align-items: center; gap: 12px;
  font-family: var(--renera-font-mono);
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--renera-mute);
}
.rn-stars__icons { display: inline-flex; gap: 2px; color: var(--renera-olive-500); }
.rn-stars__num   { color: var(--renera-ink); font-weight: 500; }

.rn-divider {
  height: 1px; background: var(--renera-clay-300);
  border: 0; margin: 0;
}

/* ───── Tier tiles — One box / 3-box bundle ─────
   Buy-box purchase options on bundle-eligible products (replace the visible
   stepper; see single-product.php + wc-bundle-pricing-functions.php). The
   selected tile carries the olive ring; the other dims and desaturates.
   Source design: Claude Design "Pricing Options" (3a). */
.rn-tiers {
  display: flex; flex-direction: column; gap: 18px;
  margin: 4px 0 2px;
}
.rn-tier {
  position: relative;
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 18px;
  align-items: center;
  width: 100%;
  background: var(--renera-paper);
  border: 1px solid var(--renera-clay-300);
  border-radius: var(--renera-r-lg);
  /* Reset the theme base's global button styling. `white-space: normal` is
     load-bearing: the tile is a <button>, whose global rule sets nowrap, and
     children inherit it — the meta line then overflows its grid column and
     paints over the price on narrow viewports. */
  padding: 20px 24px; margin: 0;
  font-family: inherit; text-align: left; white-space: normal;
  cursor: pointer;
  opacity: 0.55; filter: grayscale(0.85);
  transition:
    opacity var(--renera-dur-fast) var(--renera-ease),
    filter var(--renera-dur-fast) var(--renera-ease),
    box-shadow var(--renera-dur-fast) var(--renera-ease);
}
.rn-tier.is-on {
  opacity: 1; filter: none;
  border-color: var(--renera-olive-700);
  box-shadow: inset 0 0 0 1px var(--renera-olive-700);
}
/* Hover. The tile is a <button>, so brand-base's global button:hover would
   flood it with the terracotta CTA fill (--renera-btn-bg-hover) — far too
   loud for a selection card. Override it: the card keeps its paper ground and
   only warms its hairline, letting opacity/grayscale carry the affordance. */
@media (hover: hover) {
  .rn-tier:hover,
  .rn-tier:not(.is-on):hover {
    background: var(--renera-paper);
    color: var(--renera-ink);
  }
  .rn-tier:not(.is-on):hover {
    opacity: 0.85; filter: grayscale(0.3);
    border-color: var(--renera-clay-300);
  }
  /* Selected tile: nothing repaints — the olive ring is already the state. */
  .rn-tier.is-on:hover { border-color: var(--renera-olive-700); }
}
.rn-tier--bundle { padding-top: 24px; padding-bottom: 24px; }
.rn-tier__info { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.rn-tier__row { display: flex; align-items: center; gap: 10px; flex-wrap: nowrap; min-width: 0; }
.rn-tier__name {
  font-family: var(--renera-font-serif);
  font-size: 22px; letter-spacing: -0.02em; line-height: 1.15;
  color: var(--renera-ink);
  /* The name and its badge share one line (owner request); the badge is the
     part that must never break, so only the name may shrink. */
  white-space: nowrap;
}
.rn-tier__meta {
  font-family: var(--renera-font-mono);
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--renera-mute);
  /* Wraps inside its column instead of running under the price. */
  line-height: 1.45;
}
.rn-tier__price {
  display: flex; align-items: baseline; gap: 10px;
  font-family: var(--renera-font-serif);
  font-size: 28px; letter-spacing: -0.02em; line-height: 1;
  color: var(--renera-ink);
  white-space: nowrap;
}
.rn-tier__price--stack {
  flex-direction: column; align-items: flex-end; gap: 3px;
}
.rn-tier__price--stack .rn-tier__now { line-height: 1; }
.rn-tier__was {
  font-family: var(--renera-font-mono);
  font-size: 13px; letter-spacing: 0.04em;
  color: var(--renera-mute);
  /* <s> already strikes; keep it explicit in case of resets. */
  text-decoration: line-through;
}
.rn-tier__chip {
  position: absolute; z-index: 1; top: -12px; left: 22px;
  background: var(--renera-olive-700); color: var(--renera-sand-200);
  font-family: var(--renera-font-mono);
  font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase;
  padding: 5px 11px; border-radius: var(--renera-r-pill);
  white-space: nowrap;
}
.rn-tier__badge {
  font-family: var(--renera-font-mono);
  font-size: 9px; letter-spacing: 0.16em; text-transform: uppercase;
  background: var(--renera-clay-200); color: var(--renera-olive-800);
  padding: 4px 9px; border-radius: var(--renera-r-pill);
  white-space: nowrap;
}

/* Tiles-mode buy form stacks tiles → total → stock → button; the buy box's
   own 28px gap is too airy inside one form, so the form manages its rhythm. */
.rn-buy form.cart { display: flex; flex-direction: column; gap: 18px; }

/* Selection total under the tiles (tiles mode renders .rn-price INSIDE the
   form): slightly smaller than the legacy standalone price, plus the struck
   list total and the per-serving note. */
form.cart .rn-price { margin: 2px 0 0; }
form.cart .rn-price__now { font-size: 36px; }
.rn-price__serving {
  font-family: var(--renera-font-mono);
  font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--renera-olive-500);
}
/* Tiles mode reuses .rn-price__was for the list total — JS toggles [hidden]. */
.rn-price__was[hidden], .rn-stickybuy__price small[hidden] { display: none; }
form.cart .rn-stock { margin-top: 0; }
form.cart .single_add_to_cart_button { width: 100%; height: 56px; }

/* Tiered buy row: the stepper is always present, in either tier — the same
   control the sticky bar carries, so quantity behaves identically wherever
   the shopper touches it. A tile click just sets its value (1 or 3). */
.rn-buy-row--tiered { margin-top: 2px; }

/* ───── Qty + Add to cart row ───── */
.rn-buy-row {
  display: grid; grid-template-columns: auto 1fr; gap: 14px;
  align-items: stretch;
  margin: 0;
}
.rn-qty {
  display: inline-flex; align-items: center;
  /* Never let a tight grid column squeeze the stepper: the box clips
     (overflow: hidden below), so a squeeze silently eats the + button. */
  min-width: max-content;
  border: 1px solid var(--renera-olive-700);
  border-radius: var(--renera-r-sm);
  background: transparent;
  height: 56px;
  overflow: hidden;
}
.rn-qty button {
  width: 44px; height: 100%; background: transparent;
  border: 0; cursor: pointer;
  /* Reset the theme base's global button padding (0.5rem 1rem) — it otherwise
     shrinks the icon box and flattens the −/+ glyph. */
  padding: 0;
  color: var(--renera-olive-700);
  display: inline-flex; align-items: center; justify-content: center;
  transition: background var(--renera-dur-fast) var(--renera-ease);
}
.rn-qty button svg { flex: 0 0 auto; }
/* Shared icon-button hover — see --renera-iconbtn-* in design-system.css.
   (hover: hover) keeps it off touch, where :hover sticks after a tap. */
@media (hover: hover) {
  .rn-qty button:hover {
    background: var(--renera-iconbtn-bg-hover);
    color: var(--renera-iconbtn-fg-hover);
  }
}
.rn-qty input {
  width: 36px; height: 100%;
  border: 0; outline: none; background: transparent;
  text-align: center;
  font-family: var(--renera-font-mono); font-size: 14px;
  color: var(--renera-olive-700);
  -moz-appearance: textfield;
}
.rn-qty input::-webkit-inner-spin-button,
.rn-qty input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }

.rn-buy-row .rn-btn { width: 100%; height: 56px; }

/* ───── Bullet benefits list ───── */
.rn-bullets {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: 12px;
}
.rn-bullets li {
  display: flex; align-items: flex-start; gap: 12px;
  font-family: var(--renera-font-sans);
  font-size: 14px; line-height: 1.55; color: var(--renera-ink);
}
.rn-bullets svg {
  flex: 0 0 18px; margin-top: 2px;
  color: var(--renera-olive-500);
}

/* ───── Trust strip (3 badges below buy) ───── */
.rn-trust-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px;
  padding-top: 20px;
  border-top: 1px solid var(--renera-clay-300);
}
.rn-trust-tile {
  display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
}
.rn-trust-tile__icon {
  width: 40px; height: 40px; border-radius: 22%;
  background: var(--renera-sand-200);
  border: 1px solid var(--renera-clay-300);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--renera-olive-700);
}
.rn-trust-tile__label {
  font-family: var(--renera-font-mono);
  font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--renera-ink); line-height: 1.4;
}

/* =========================================
   Trust badges row (3 cards)
   ========================================= */
.rn-badges {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px;
  padding: 64px 0;
  border-top: 1px solid var(--renera-clay-300);
  border-bottom: 1px solid var(--renera-clay-300);
}
.rn-badges__item {
  display: flex; flex-direction: column; align-items: center;
  text-align: center; gap: 16px;
  padding: 0 16px;
}
.rn-badges__icon {
  width: 64px; height: 64px; border-radius: 22%;
  background: var(--renera-paper);
  border: 1px solid var(--renera-clay-300);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--renera-olive-700);
}
.rn-badges__title {
  font-family: var(--renera-font-serif);
  font-size: 19px; line-height: 1.25;
  color: var(--renera-ink);
  margin: 0;
  text-wrap: balance;
}

/* =========================================
   Comparison table
   ========================================= */
.rn-compare {
  background: var(--renera-paper);
  border: 1px solid var(--renera-clay-300);
  border-radius: var(--renera-r-lg);
  overflow: hidden;
}
.rn-compare table {
  width: 100%; border-collapse: collapse;
  font-family: var(--renera-font-sans); font-size: 14px;
  color: var(--renera-ink);
  /* A plugin's base stylesheet gives every table `margin-bottom: 15px`. The
     wrapper's overflow:hidden traps that margin inside the rounded box, so it
     rendered as a dead strip between the last row and the bottom border. */
  margin: 0;
}
/* Neutralize the same plugin's global `table td, table th { border: 1px solid
   grey }` (style.min.css) that .rn-orders-table already has to fight in
   my-account.css. Only the hairlines set below are ours — its borders drew grey
   rules through the design and left a grey line above the header, just inside
   the wrapper's own border.
   !important for the reason my-account.css records: with border-collapse the
   shorthand keeps re-asserting the top border even when a more specific rule
   zeroes it. The hairlines below therefore have to be !important too. */
.rn-compare th,
.rn-compare td { border: 0 !important; }
.rn-compare thead th {
  text-align: left;
  padding: 24px 28px;
  background: var(--renera-sand-300);
  border-bottom: 1px solid var(--renera-clay-300) !important;
}
.rn-compare thead th .colhead-eyebrow {
  font-family: var(--renera-font-mono);
  font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--renera-mute);
  display: block; margin-bottom: 8px;
}
.rn-compare thead th .colhead-title {
  font-family: var(--renera-font-serif);
  font-size: 22px; font-weight: 400; letter-spacing: -0.01em;
  color: var(--renera-ink);
  display: flex; align-items: center; gap: 10px;
}
.rn-compare thead th.is-feature {
  background: var(--renera-olive-700); color: var(--renera-sand-200);
}
.rn-compare thead th.is-feature .colhead-eyebrow { color: color-mix(in srgb, var(--renera-sand-300) 65%, transparent); }
.rn-compare thead th.is-feature .colhead-title { color: var(--renera-sand-200); }

.rn-compare tbody td {
  padding: 18px 28px; border-bottom: 1px solid var(--renera-clay-300) !important;
  /* Top, not middle: cells carry a claim plus optional small print, and a
     two-line cell centred against a one-line one reads as misaligned. */
  vertical-align: top;
}
.rn-compare tbody tr:last-child td { border-bottom: 0 !important; }
/* Column separators, same clay hairline as the rows, so the body reads as a
   grid. Body cells only, and never on the last column: the header row already
   separates its columns with the olive fill, and a light rule drawn over that
   block would read as a stray mark rather than a grid line. The final column
   closes against the wrapper's own border. */
.rn-compare tbody td:not(:last-child) {
  border-right: 1px solid var(--renera-clay-300) !important;
}
/* The body carries no fills at all — every cell is the page's own white. Two
   things had to go for that:
   the plugin stylesheet zebra-stripes every table
   (`table tbody > tr:nth-child(2n+1) > td { background: rgba(128,128,128,.07) }`),
   an off-palette grey that read as a selected row; and the Renéra column used
   to carry a faint olive wash, which read as a selected column. Structure now
   comes from the hairline grid alone, with the olive header block and the tick
   marks doing the work of pointing at the Renéra column.
   The plugin's selector carries a pseudo-class, so the reset has to match that
   weight to win. */
.rn-compare tbody > tr:nth-child(2n+1) > td { background-color: transparent; }
.rn-compare tbody td.feature-name {
  font-family: var(--renera-font-mono);
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--renera-mute);
  width: 30%;
}
/* No fill — the olive text and the tick mark carry the emphasis instead. */
.rn-compare tbody td.is-feature {
  font-weight: 500;
  color: var(--renera-olive-700);
}
.rn-compare tbody td.other { color: var(--renera-mute); }
/* Mark + text, with the mark pinned to the first line so it stays beside the
   claim rather than drifting to the middle of a cell that has small print. */
.rn-compare .compare-check,
.rn-compare .compare-x {
  display: flex; align-items: flex-start; gap: 8px;
  font-weight: 500;
}
.rn-compare .compare-check svg,
.rn-compare .compare-x svg { flex: 0 0 auto; margin-top: 1px; }
.rn-compare .compare-check svg { color: var(--renera-olive-500); }
.rn-compare .compare-x svg { color: var(--renera-clay-500); }
.rn-compare .compare-body { display: block; min-width: 0; }
/* Supporting detail: quieter and smaller than the claim it sits under. */
.rn-compare .compare-note {
  display: block; margin-top: 5px;
  font-weight: 400; font-size: 12px; line-height: 1.5;
  letter-spacing: 0;
  color: var(--renera-mute);
}
.rn-compare td.is-feature .compare-note {
  color: color-mix(in srgb, var(--renera-olive-700) 65%, transparent);
}

/* =========================================
   Sticky buy bar (appears after scrolling past hero)
   ========================================= */
.rn-stickybuy {
  position: fixed; left: 0; right: 0; bottom: 0;
  background: color-mix(in srgb, var(--renera-sand-300) 95%, transparent);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--renera-clay-300);
  z-index: 45;
  transform: translateY(100%);
  transition: transform var(--renera-dur-base) var(--renera-ease);
}
.rn-stickybuy.is-on { transform: translateY(0); }
.rn-stickybuy__row {
  display: grid; grid-template-columns: auto 1fr auto auto;
  gap: 28px; align-items: center;
  padding: 14px 0;
}
.rn-stickybuy__thumb {
  width: 56px; height: 56px; border-radius: var(--renera-r-md);
  border: 1px solid var(--renera-clay-300);
  flex: 0 0 auto; overflow: hidden;
}
/* Fills its rounded tile, same treatment as the gallery it mirrors. */
.rn-stickybuy__thumb img {
  width: 100%; height: 100%; object-fit: cover; padding: 0; display: block;
}
.rn-stickybuy__title {
  font-family: var(--renera-font-serif); font-size: 18px;
  letter-spacing: -0.01em; color: var(--renera-ink);
  margin: 0; line-height: 1.2;
}
.rn-stickybuy__sub {
  font-family: var(--renera-font-mono);
  font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--renera-mute); margin-top: 4px;
}
.rn-stickybuy__price {
  font-family: var(--renera-font-serif);
  font-size: 22px; letter-spacing: -0.01em;
  color: var(--renera-ink);
}
/* Struck list price reads ABOVE what you pay — same order as the tier card,
   at every width (the markup carries the order; this only sets the spacing). */
.rn-stickybuy__price small {
  font-family: var(--renera-font-mono);
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--renera-mute);
  display: block; margin-bottom: 3px;
  text-decoration: line-through;
}
/* The bar's form holds its own stepper + the button. Keeping the pair inside
   the form cell means none of the three sticky layouts (desktop / <=1080 /
   phone) needs a new grid column. */
.rn-stickybuy .cart { margin: 0; display: flex; align-items: center; gap: 10px; }
.rn-stickybuy .rn-btn { flex: 1 1 auto; }
.rn-qty--sticky { height: 48px; flex: 0 0 auto; }
.rn-qty--sticky button { width: 38px; }
.rn-qty--sticky input { width: 30px; }

/* =========================================
   Spec strip — 3 stats above ritual
   ========================================= */
.rn-spec-strip {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 0;
  border: 1px solid var(--renera-clay-300);
  border-radius: var(--renera-r-lg);
  background: var(--renera-paper);
  overflow: hidden;
}
.rn-spec-strip__cell {
  padding: 36px 32px;
  display: flex; flex-direction: column; gap: 8px;
  border-right: 1px solid var(--renera-clay-300);
}
.rn-spec-strip__cell:last-child { border-right: 0; }
.rn-spec-strip__num {
  font-family: var(--renera-font-serif); font-weight: 400;
  font-size: 52px; line-height: 1; letter-spacing: -0.02em;
  color: var(--renera-olive-700);
}
.rn-spec-strip__num em {
  font-style: italic; font-size: 28px; color: var(--renera-olive-500);
  margin-left: 4px;
}
.rn-spec-strip__label {
  font-family: var(--renera-font-mono);
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--renera-mute);
}
.rn-spec-strip__note {
  font-family: var(--renera-font-sans);
  font-size: 13px; line-height: 1.55;
  color: var(--renera-ink);
  margin-top: 6px;
}

/* =========================================
   Price block (buy box)
   ========================================= */
.rn-price {
  display: flex; align-items: baseline; gap: 16px;
}
.rn-price__now {
  font-family: var(--renera-font-serif); font-weight: 400;
  font-size: 44px; line-height: 1; letter-spacing: -0.02em;
  color: var(--renera-ink);
}
.rn-price__was {
  font-family: var(--renera-font-mono);
  font-size: 15px; letter-spacing: 0.04em;
  text-decoration: line-through;
  color: var(--renera-mute);
}
.rn-price__badge {
  font-family: var(--renera-font-mono);
  font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
  background: var(--renera-olive-700); color: var(--renera-sand-200);
  padding: 5px 11px; border-radius: var(--renera-r-pill);
  align-self: center;
}
.rn-stock {
  display: flex; align-items: center; gap: 10px;
  font-family: var(--renera-font-mono);
  font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--renera-olive-700);
  margin-top: -10px;
}
.rn-stock.is-out { color: var(--renera-mute); }
.rn-stock .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--renera-olive-500);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--renera-olive-500) 18%, transparent);
}
.rn-amazon-link {
  display: inline-flex; align-items: center; gap: 8px;
  margin-top: -12px;
  font-family: var(--renera-font-mono);
  font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--renera-mute); text-decoration: none;
  align-self: flex-start;
  transition: color var(--renera-dur-fast) var(--renera-ease);
}
.rn-amazon-link:hover { color: var(--renera-olive-700); }
.rn-amazon-link svg { opacity: 0.7; }

/* =========================================
   Product story — editorial olive split
   ========================================= */
/* Unify the "When science meets nature" eyebrow: the leading hairline defaults
   to a dimmer shade (0.4) than the text (0.7). Match them so the whole eyebrow
   reads as one color. Scoped to this section so other invert eyebrows (incl. the
   footer on this same page) keep their default two-tone treatment. */
.rn-section--olive .rn-eyebrow--invert::before {
  background: color-mix(in srgb, var(--renera-sand-300) 70%, transparent);
}
.rn-story-grid {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 96px; align-items: center;
  /* padding-block only — the element ALSO carries .container, whose 0 40px
     side padding this shorthand was clobbering (edge-to-edge text on phones,
     where no max-width margin masks it). */
  padding-block: 88px;
}
.rn-story-media {
  position: relative;
}
/* Scaled up to fill its rounded frame, like the gallery — no letterbox bars, so
   no backdrop is needed behind it. */
.rn-story-media img.rn-story-photo {
  width: 100%; height: 540px; object-fit: cover; display: block;
  border-radius: var(--renera-r-lg);
  border: 1px solid color-mix(in srgb, var(--renera-sand-300) 15%, transparent);
}
.rn-story-media .rn-story-frame {
  position: absolute; top: -28px; left: -28px; width: 96px; height: 96px;
  opacity: 0.5; filter: brightness(2.5) saturate(0.3);
  pointer-events: none;
}

/* =========================================
   Supplement Facts — label panel + highlight tiles
   ========================================= */
.rn-facts-grid {
  display: grid; grid-template-columns: minmax(0, 480px) minmax(0, 1fr);
  gap: 64px; align-items: start;
}
.rn-facts-panel {
  background: var(--renera-paper);
  border: 1px solid var(--renera-clay-300);
  border-radius: var(--renera-r-lg);
  padding: 32px;
}
.rn-facts-panel__title {
  font-family: var(--renera-font-serif); font-weight: 400;
  font-size: 27px; color: var(--renera-ink); margin: 0 0 6px;
}
.rn-facts-panel__serving {
  font-family: var(--renera-font-mono); font-size: 11px;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--renera-mute); margin: 0 0 14px;
}
.rn-facts-panel__bar { height: 6px; border-radius: 2px; background: var(--renera-olive-700); }
.rn-facts-panel__cols {
  display: flex; justify-content: space-between; gap: 18px;
  font-family: var(--renera-font-mono); font-size: 10px;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--renera-mute);
  padding: 10px 0 8px; border-bottom: 2px solid var(--renera-olive-700);
}
.rn-facts-row {
  display: flex; align-items: baseline; gap: 14px;
  padding: 9px 0; border-bottom: 1px solid var(--renera-clay-300);
  font-family: var(--renera-font-sans); font-size: 14px; line-height: 1.45;
  color: var(--renera-ink);
}
.rn-facts-row .n { flex: 1; min-width: 0; }
.rn-facts-row .a { white-space: nowrap; font-weight: 500; }
.rn-facts-row .dv { flex: none; width: 44px; text-align: right; color: var(--renera-mute); font-size: 13px; }
.rn-facts-row--sub { padding-left: 16px; }
.rn-facts-row--sub .n { color: var(--renera-mute); font-size: 13px; }
.rn-facts-panel__blend, .rn-facts-panel__foot {
  font-size: 12px; line-height: 1.6; color: var(--renera-mute); margin: 14px 0 0;
}
.rn-facts-panel__blend strong { color: var(--renera-ink); font-weight: 500; }
.rn-facts-aside { display: flex; flex-direction: column; gap: 28px; }
.rn-facts-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.rn-facts-stat {
  background: var(--renera-paper);
  border: 1px solid var(--renera-clay-300);
  border-radius: var(--renera-r-md);
  padding: 20px;
}
.rn-facts-stat b {
  display: block; font-family: var(--renera-font-serif); font-weight: 400;
  font-size: 26px; line-height: 1.1; color: var(--renera-olive-700); margin-bottom: 8px;
}
.rn-facts-stat span {
  font-family: var(--renera-font-mono); font-size: 10px;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--renera-mute);
}
.rn-facts-note h4 {
  font-family: var(--renera-font-mono); font-size: 11px; font-weight: 400;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--renera-olive-500); margin: 0 0 8px;
}
.rn-facts-note p { font-size: 14px; line-height: 1.65; color: var(--renera-ink); margin: 0; max-width: 460px; }

/* =========================================
   Ingredient reference — what each ingredient supports
   ========================================= */
.rn-ingref { border-top: 1px solid var(--renera-clay-300); }
.rn-ingref__id { display: flex; align-items: flex-start; gap: 16px; }
.rn-ingref__icon {
  flex: none; width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid var(--renera-clay-300); background: var(--renera-paper);
  display: flex; align-items: center; justify-content: center;
  color: var(--renera-olive-700);
}
.rn-ingref__row {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr) minmax(0, 1.6fr);
  gap: 36px; align-items: start;
  padding: 28px 0; border-bottom: 1px solid var(--renera-clay-300);
}
.rn-ingref__name {
  font-family: var(--renera-font-serif); font-weight: 400;
  font-size: 21px; line-height: 1.2; color: var(--renera-ink); margin: 0 0 10px;
}
.rn-ingref__amount {
  display: inline-block;
  font-family: var(--renera-font-mono); font-size: 10px;
  letter-spacing: 0.14em; text-transform: uppercase; line-height: 1;
  color: var(--renera-olive-700);
  border: 1px solid var(--renera-clay-300); border-radius: var(--renera-r-pill);
  padding: 6px 12px; background: var(--renera-paper);
}
.rn-ingref__bio {
  font-family: var(--renera-font-serif); font-style: italic;
  font-size: 15px; line-height: 1.5; color: var(--renera-olive-500); margin: 2px 0 0;
}
.rn-ingref__supports { font-size: 14px; line-height: 1.7; color: var(--renera-ink); margin: 0; }
.rn-ingref__fine { font-size: 11px; line-height: 1.6; color: var(--renera-mute); margin: 22px 0 0; }

/* =========================================
   How to enjoy — three-step ritual cards
   (ported from the "Product page (2)" mock's RitualSection: numbered
   sand cards with an icon chip and a mono timing footer)
   ========================================= */
.rn-ritual { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.rn-ritual__step {
  position: relative;
  padding: 40px 36px 36px;
  background: var(--renera-sand-300);
  border: 1px solid var(--renera-clay-300);
  border-radius: var(--renera-r-lg);
  display: flex; flex-direction: column; gap: 14px;
  min-height: 280px;
}
.rn-ritual__num {
  position: absolute; top: 24px; right: 28px;
  font-family: var(--renera-font-serif); font-style: italic;
  font-size: 56px; color: var(--renera-clay-300);
  line-height: 1; pointer-events: none;
}
.rn-ritual__icon {
  width: 52px; height: 52px; border-radius: 22%;
  background: var(--renera-olive-700); color: var(--renera-sand-200);
  display: inline-flex; align-items: center; justify-content: center;
}
.rn-ritual__title {
  font-family: var(--renera-font-serif); font-weight: 400;
  font-size: 26px; line-height: 1.2; color: var(--renera-ink);
  margin: 0; letter-spacing: -0.01em;
}
.rn-ritual__title em { color: var(--renera-olive-700); font-style: italic; }
.rn-ritual__body { font-size: 14px; line-height: 1.65; color: var(--renera-mute); margin: 0; }
.rn-ritual__foot {
  margin-top: auto; padding-top: 16px;
  border-top: 1px solid var(--renera-clay-300);
  font-family: var(--renera-font-mono);
  font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--renera-mute);
}
.rn-howto__note { font-size: 12px; line-height: 1.65; color: var(--renera-mute); margin: 28px 0 0; text-align: center; }

/* =========================================
   Benefits — six icon cards
   ========================================= */
.rn-benefits { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.rn-benefits__card {
  background: var(--renera-paper);
  border: 1px solid var(--renera-clay-300);
  border-radius: var(--renera-r-md);
  padding: 26px 24px;
}
.rn-benefits__icon {
  width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid var(--renera-clay-300); background: var(--renera-sand-300);
  display: flex; align-items: center; justify-content: center;
  color: var(--renera-olive-700);
  margin-bottom: 16px;
}
.rn-benefits__title {
  font-family: var(--renera-font-serif); font-weight: 400;
  font-size: 19px; line-height: 1.2; color: var(--renera-ink); margin: 0 0 8px;
}
.rn-benefits__body { font-size: 14px; line-height: 1.65; color: var(--renera-ink-soft); margin: 0; }
.rn-benefits__fine { font-size: 11px; line-height: 1.6; color: var(--renera-mute); margin: 22px 0 0; }

/* =========================================
   Certificate of Analysis — lot chips + grouped test table
   ========================================= */
.rn-coa__meta { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 32px; }
.rn-coa__chip {
  display: inline-flex; align-items: baseline; gap: 7px;
  border: 1px solid var(--renera-clay-300); border-radius: var(--renera-r-pill);
  background: var(--renera-paper); padding: 8px 14px;
  font-family: var(--renera-font-mono); font-size: 11px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--renera-ink);
}
.rn-coa__chip span { color: var(--renera-mute); }
.rn-coa {
  background: var(--renera-paper);
  border: 1px solid var(--renera-clay-300);
  border-radius: var(--renera-r-lg);
  overflow: hidden;
}
.rn-coa table { width: 100%; border-collapse: collapse; }
.rn-coa th {
  text-align: left; font-family: var(--renera-font-mono); font-weight: 400;
  font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--renera-mute); padding: 14px 18px;
  border-bottom: 2px solid var(--renera-olive-700);
}
.rn-coa td {
  padding: 12px 18px; font-size: 14px; line-height: 1.5; color: var(--renera-ink);
  border-bottom: 1px solid var(--renera-clay-300); vertical-align: top;
}
.rn-coa tbody tr:last-child td { border-bottom: 0; }
.rn-coa__group td {
  background: var(--renera-sand-300);
  font-family: var(--renera-font-mono); font-size: 10px;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--renera-olive-700); padding: 10px 18px;
}
.rn-coa__test { font-weight: 500; }
.rn-coa__pass {
  display: inline-block; font-family: var(--renera-font-mono); font-size: 10px;
  letter-spacing: 0.14em; text-transform: uppercase; line-height: 1;
  color: var(--renera-sand-200); background: var(--renera-olive-700);
  border-radius: var(--renera-r-pill); padding: 5px 10px;
}
.rn-coa__fine { font-size: 12px; line-height: 1.65; color: var(--renera-mute); margin: 20px 0 0; max-width: 820px; }

/* =========================================
   WPFront Scroll-Top button ("Component 186") — its custom uploaded PNG isn't
   synced to this env so it renders as a broken image in the corner. The plugin
   prints the container on wp_footer (not gated by an enqueued handle), so we hide
   it here. Keeps the PDP chrome consistent with the rest of the site.
   ========================================= */
#wpfront-scroll-top-container { display: none !important; }

/* =========================================
   WooCommerce native form hygiene — keep WC's own markup invisible where we
   supply our own styling, and surface validation notices in brand style.
   ========================================= */
.rn-buy form.cart { margin: 0; display: contents; }
.rn-buy .woocommerce-variation-add-to-cart,
.rn-buy .quantity.hidden { display: none; }
.rn-buy .single_add_to_cart_button.disabled,
.rn-buy .single_add_to_cart_button:disabled { opacity: 0.5; cursor: not-allowed; }

/* =========================================
   Responsive
   ========================================= */
@media (max-width: 1080px) {
  .rn-pdp { grid-template-columns: 1fr; gap: 32px; }
  .rn-gallery { position: static; grid-template-columns: 1fr; }
  /* Main image first, thumbnails beneath as ONE smaller swipeable line — the
     row never wraps; extra tiles scroll horizontally (swipe). The prev/next
     arrows under the frame and the rail's step buttons are dropped: tapping a
     thumb (or swiping the row) is the whole navigation. */
  /* Cap the frame — uncapped, the 1:1 square runs the full single-column width
     (huge on tablets, taller than the viewport with the header on phones).
     Same centred max-width treatment as .rn-story__image-stack below. */
  .rn-gallery__stage { order: 1; width: min(100%, 400px); margin: 0 auto; }
  .rn-gallery__rail { order: 2; }
  .rn-gallery__railbtn, .rn-gallery__nav { display: none; }
  .rn-gallery { --rn-thumb: 64px; }
  /* stretch, NOT center: with align-items:center WebKit sizes the thumbs box
     to its CONTENT width (10 tiles ≈ 630px), which widens the whole page and
     iOS Safari zooms out to fit — the row must be container-bound so
     overflow-x can actually scroll. min-width:0 stops the grid item from
     growing to its content's min-content width for the same reason. */
  .rn-gallery__rail { align-items: stretch; min-width: 0; }
  .rn-gallery__thumbs {
    flex-direction: row; flex-wrap: nowrap;
    justify-content: flex-start; /* a centred scroll row clips its left end */
    max-width: 100%;
    max-height: none; overflow-y: visible;
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    scrollbar-width: none; -ms-overflow-style: none;
  }
  .rn-gallery__thumbs::-webkit-scrollbar { display: none; }
  /* Tagline + name move above the gallery; hide the buy box's own copies.
     (The .rn-buy scope keeps the .rn-pdp__mhead reuses of these classes alive.) */
  .rn-pdp__mhead { display: flex; flex-direction: column; gap: 10px; }
  .rn-pdp__mhead .rn-buy__name-sub { margin: 0; }
  .rn-buy .rn-buy__tagline,
  .rn-buy .rn-buy__title--name,
  .rn-buy .rn-buy__name-sub { display: none; }
  /* The pill's -14px pull-up grouped it with the name block, which is hidden
     here — flush margin so it doesn't ride up into the gallery gap. */
  .rn-buy__attr { margin-top: 0; }
  .rn-buy__title { font-size: 40px; }
  .rn-buy__title--name { font-size: 27px; }
  .rn-badges, .rn-spec-strip { grid-template-columns: 1fr; }
  .rn-spec-strip__cell { border-right: 0; border-bottom: 1px solid var(--renera-clay-300); }
  .rn-spec-strip__cell:last-child { border-bottom: 0; }
  /* Without a min-width the table crushes its columns instead of scrolling —
     the "Other Brands" column disappeared entirely at phone widths. */
  .rn-compare { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .rn-compare table { min-width: 640px; }
  /* One row: name | price | button (thumb + flavor sub are hidden here). */
  .rn-stickybuy__row { grid-template-columns: minmax(0, 1fr) auto auto; gap: 16px; }
  .rn-stickybuy__thumb, .rn-stickybuy__sub { display: none; }
  .rn-stickybuy__title {
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .rn-story-grid { grid-template-columns: 1fr; gap: 44px; padding-block: 52px; }
  .rn-facts-grid { grid-template-columns: 1fr; gap: 40px; }
  .rn-ingref__row { grid-template-columns: 1fr; gap: 12px; padding: 24px 0; }
  .rn-ingref__name { margin-bottom: 8px; }
  .rn-ritual { grid-template-columns: 1fr; gap: 16px; }
  .rn-ritual__step { min-height: 0; }
  .rn-benefits { grid-template-columns: repeat(2, 1fr); }
  .rn-story-media img.rn-story-photo { height: 360px; }
}

/* ── Phone tuning ─────────────────────────────────────────────── */
/* Mirrors "Products Mobile.html" (Product page (2) mock) — the dedicated
   phone-width pass: tighter gallery/type scale, comparison-table-as-cards,
   and a stripped-down price+button sticky bar. */
@media (max-width: 600px) {
  .rn-tiers { gap: 16px; }
  .rn-tier { padding: 14px 16px; gap: 10px; border-radius: 14px; align-items: start; }
  .rn-tier__info { gap: 4px; }
  /* Two short lines read better than one long wrap at this width. */
  .rn-tier__meta { line-height: 1.4; }
  .rn-tier--bundle { padding-top: 16px; padding-bottom: 16px; }
  .rn-tier__name { font-size: 17px; }
  .rn-tier__meta { font-size: 10px; letter-spacing: 0.04em; }
  .rn-tier__price { font-size: 24px; gap: 8px; }
  .rn-tier__was { font-size: 11px; }
  .rn-tier__chip { top: -11px; left: 14px; font-size: 9px; letter-spacing: 0.14em; padding: 5px 10px; }
  .rn-tier__badge { font-size: 8px; padding: 4px 7px; }
  form.cart .rn-price__now { font-size: 28px; }
  .rn-pdp { padding: 18px 0 36px; gap: 22px; }
  /* min(100%, 400px) from the 1080px pass is still the full column on a phone —
     cap harder here so the photo doesn't swallow the first screen before the
     price/CTA. */
  .rn-gallery__stage { width: min(100%, 300px); }
  .rn-gallery { --rn-thumb: 52px; }
  .rn-buy { gap: 20px; }
  .rn-buy__title--name { font-size: 30px; }
  .rn-buy__tagline { font-size: 18px; }
  .rn-buy__sub { font-size: 17px; }
  .rn-price__now { font-size: 36px; }
  .rn-buy-row { grid-template-columns: 1fr; }
  .rn-buy-row .rn-qty { justify-self: start; }
  .rn-badges { padding: 40px 0; gap: 32px; }
  .rn-story-grid { padding-block: 56px; gap: 32px; }
  /* CoA table → stacked label/value rows per test (same device as .rn-compare
     cards): 5 columns can't fit a phone. Labels come from each td's data-th. */
  .rn-coa table, .rn-coa tbody, .rn-coa tr, .rn-coa td { display: block; width: auto; }
  .rn-coa thead { display: none; }
  .rn-coa tr { border-bottom: 1px solid var(--renera-clay-300); }
  .rn-coa tr:last-child { border-bottom: 0; }
  .rn-coa td {
    display: flex; justify-content: space-between; align-items: baseline; gap: 18px;
    border-bottom: 0; padding: 4px 16px;
  }
  .rn-coa td::before {
    content: attr(data-th);
    font-family: var(--renera-font-mono); font-size: 9px;
    letter-spacing: 0.16em; text-transform: uppercase; color: var(--renera-mute);
    flex: none; padding-top: 3px;
  }
  .rn-coa td:last-child { padding-bottom: 14px; }
  .rn-coa__test { padding-top: 14px; }
  .rn-coa td[data-th]:not(.rn-coa__test) { text-align: right; }
  .rn-coa__group td { display: block; padding: 10px 16px; }
  .rn-coa__group td::before { content: none; }
  .rn-facts-panel { padding: 22px 18px; }
  .rn-facts-stats { gap: 10px; }
  .rn-facts-stat { padding: 16px; }
  .rn-facts-stat b { font-size: 22px; }
  .rn-ritual__step { padding: 32px 28px; }
  .rn-benefits { grid-template-columns: 1fr; gap: 14px; }
  .rn-story-media img.rn-story-photo { height: 300px; }

  /* Comparison table → stacked cards. A horizontally-scrolling table crushes
     the "Other Brands" column at phone widths; each row becomes a labeled
     card instead (one per feature, Renéra/Others prefixed inline). */
  .rn-compare { overflow-x: visible; border: 0; background: transparent; border-radius: 0; }
  .rn-compare table { min-width: 0; }
  .rn-compare table, .rn-compare tbody, .rn-compare tr, .rn-compare td { display: block; width: auto; }
  .rn-compare thead { display: none; }
  .rn-compare tr {
    background: var(--renera-paper);
    border: 1px solid var(--renera-clay-300);
    border-radius: var(--renera-r-md);
    margin-bottom: 14px;
    overflow: hidden;
  }
  .rn-compare tr:last-child { margin-bottom: 0; }
  .rn-compare td {
    border: 0 !important;
    border-bottom: 1px solid var(--renera-clay-300) !important;
    padding: 13px 18px !important;
  }
  /* The cells are stacked into a card here, not laid out in columns, so the
     desktop column separator would draw a stray rule down the card's right
     edge. Matches the desktop selector's specificity to switch it off. */
  .rn-compare tbody td:not(:last-child) { border-right: 0 !important; }
  .rn-compare td:last-child { border-bottom: 0 !important; }
  /* tbody in the selector on purpose: the desktop rule is
     `.rn-compare tbody td.feature-name { width: 30% }`, which outranks a
     two-class override — the label band then covered only a third of the
     card instead of spanning it. */
  .rn-compare tbody td.feature-name {
    background: var(--renera-sand-300);
    font-size: 11px; color: var(--renera-olive-700); width: auto;
  }
  .rn-compare td.is-feature,
  .rn-compare td.other { position: relative; padding-left: 108px !important; }
  .rn-compare td.is-feature::before,
  .rn-compare td.other::before {
    position: absolute; left: 18px; top: 13px;
    font-family: var(--renera-font-mono); font-size: 9px;
    letter-spacing: 0.16em; text-transform: uppercase; color: var(--renera-mute);
    width: 80px;
  }
  .rn-compare td.is-feature::before { content: "Renéra"; color: var(--renera-olive-500); }
  .rn-compare td.other::before { content: "Others"; }

  /* Sticky buy bar → price + full-width button only; name/thumb dropped for
     a cleaner phone bar (mirrors the mock's native mobile buy bar). The
     __info wrapper (title+sub) must be hidden too, not just its children —
     display:none on the children alone left an empty grid cell that pushed
     the price/button out of the intended 2-column row. */
  .rn-stickybuy__row { grid-template-columns: auto 1fr; gap: 14px; padding: 12px 0; }
  .rn-stickybuy__info { display: none; }
  .rn-stickybuy__price { font-size: 17px; }
  .rn-stickybuy .rn-btn { height: 48px; padding: 0 14px; width: 100%; }
  .rn-stickybuy .cart { gap: 8px; }
  /* Compact enough to sit beside the CTA on a 390px screen without either
     being squeezed (.rn-qty's min-width: max-content forbids clipping). */
  .rn-qty--sticky { height: 48px; }
  .rn-qty--sticky button { width: 34px; }
  .rn-qty--sticky input { width: 26px; font-size: 13px; }
}

/* Small phones (≤400px): the name + Best value badge share one line by
   request, so at this width the pair is tightened rather than wrapped —
   without it the row overruns its column by ~8px on a 360px screen. */
@media (max-width: 400px) {
  .rn-tier__name { font-size: 16px; }
  .rn-tier__row { gap: 8px; }
  .rn-tier__badge { font-size: 8px; letter-spacing: 0.08em; padding: 4px 6px; }
}

/* ═══════════════════════════════════════════════════════════════
   Customer reviews — brand skin over WooCommerce's native
   single-product-reviews.php markup (#reviews / .commentlist /
   #review_form). Structure + behaviour stay 100% native WC (star
   rating, verified-buyer gating, comment moderation); only the
   presentation is tokenised here. Renders only when comments are
   open or reviews exist (see single-product.php).
   ═══════════════════════════════════════════════════════════════ */
.rn-reviews { max-width: 760px; }
.rn-reviews .woocommerce-Reviews-title {
  font-family: var(--renera-font-serif); font-size: var(--renera-fs-lg);
  color: var(--renera-ink); margin: 0 0 28px;
}
.rn-reviews .woocommerce-Reviews-title span { font-style: italic; }
.rn-reviews .commentlist { list-style: none; margin: 0 0 40px; padding: 0; }
.rn-reviews .commentlist li.review { padding: 22px 0; border-bottom: 1px solid var(--renera-clay-300); }
.rn-reviews .commentlist li.review:first-child { padding-top: 0; }
.rn-reviews .comment_container { display: flex; gap: 16px; align-items: flex-start; }
.rn-reviews img.avatar {
  width: 46px; height: 46px; border-radius: var(--renera-r-pill);
  border: 1px solid var(--renera-clay-300); margin: 0;
}
.rn-reviews .comment-text { flex: 1; }
.rn-reviews .meta { font-size: var(--renera-fs-sm); color: var(--renera-mute); margin: 6px 0 10px; }
.rn-reviews .meta strong { color: var(--renera-ink); font-weight: 600; }
.rn-reviews .description p { color: var(--renera-ink-soft); line-height: var(--renera-lh-normal); margin: 0; }
.rn-reviews .star-rating { color: var(--renera-olive-500); font-size: 14px; }
.rn-reviews .woocommerce-noreviews {
  color: var(--renera-mute); font-style: italic; margin: 0 0 32px;
}

/* Review form */
.rn-reviews #review_form_wrapper { border-top: 1px solid var(--renera-clay-300); padding-top: 32px; }
.rn-reviews .comment-reply-title {
  font-family: var(--renera-font-serif); font-size: var(--renera-fs-md);
  color: var(--renera-ink); display: block; margin-bottom: 18px;
}
.rn-reviews .comment-form-rating label { display: block; margin-bottom: 6px; font-size: var(--renera-fs-sm); color: var(--renera-ink); }
.rn-reviews .comment-form p { margin: 0 0 16px; }
.rn-reviews .comment-form label { font-size: var(--renera-fs-sm); color: var(--renera-ink); }
.rn-reviews .comment-form input[type="text"],
.rn-reviews .comment-form input[type="email"],
.rn-reviews .comment-form textarea {
  width: 100%; margin-top: 6px; padding: 12px 14px;
  border: 1px solid var(--renera-clay-300); border-radius: var(--renera-r-md);
  background: var(--renera-paper); color: var(--renera-ink);
  font-family: var(--renera-font-sans); font-size: var(--renera-fs-base);
}
.rn-reviews .comment-form input:focus,
.rn-reviews .comment-form textarea:focus {
  outline: none; border-color: var(--renera-olive-500);
}
.rn-reviews .stars a { color: var(--renera-olive-500); }
.rn-reviews #submit {
  appearance: none; cursor: pointer;
  background: var(--renera-olive-700); color: var(--renera-paper);
  border: 0; border-radius: var(--renera-r-pill);
  font-family: var(--renera-font-sans); font-size: var(--renera-fs-sm);
  letter-spacing: 0.02em; padding: 13px 28px;
  transition: background var(--renera-dur-fast) var(--renera-ease);
}
.rn-reviews #submit:hover { background: var(--renera-olive-800); }
