/**
 * Product detail page.
 *
 * ⚠️ EVERY RULE IS SCOPED UNDER `.pdp-page`. NOTHING HERE MAY ESCAPE.
 *
 * The design's own stylesheet styles bare `.btn`, `.wrap`, `.kicker` and
 * `.banner` — names that belong to the site shell. Loading it as written would
 * restyle the header, the footer and every button on every page. So the
 * thirteen classes this page borrows from site.css are re-declared here under
 * the page's own scope, and the file is only ever enqueued on a product page.
 *
 * ⚠️ IT IS ALSO SELF-CONTAINED, DELIBERATELY.
 *
 * An earlier version depended on shop-all.css for the related-product card and
 * the closing banner. That file was rolled back off the live site, which would
 * have left this page half-styled — a dependency on something that is not
 * guaranteed to be there. The card and the banner are defined here instead.
 *
 * ⚠️ THE ACCENT RAMP COMES FROM THE PAGE, NOT FROM HERE.
 *
 * inc/product-single.php writes `--pdp-accent*` onto `.pdp-page` as an inline
 * style, mixed from the product's own carton colour — so one stylesheet serves
 * every product, and the colour is correct in the first painted frame rather
 * than after a script runs. Every rule reads the token with a brand fallback,
 * so a product with no colour on file still renders in the house palette.
 */

.pdp-page {
  /* The design's palette, taken from brand.css where it already exists. */
  --pdp-green:      var(--xg-green, #123023);
  --pdp-green-mid:  var(--xg-green-mid, #1c4632);
  --pdp-green-dark: var(--xg-green-dark, #0e2a1e);
  --pdp-cream:      var(--xg-cream, #f7f4ee);
  --pdp-cream-2:    var(--xg-cream-2, #efe9dd);
  --pdp-cream-ink:  var(--xg-cream-ink, #f4eddf);

  --pdp-accent:      var(--xg-accent, #b98f42);
  --pdp-accent-hi:   var(--xg-accent-hi, #dcbb74);
  --pdp-accent-soft: var(--xg-accent-soft, #e2c68a);
  --pdp-accent-ink:  var(--xg-accent-ink, #7e5320);
  --pdp-accent-deep: #4a4429;
  --pdp-accent-wash: #fdf3ea;

  --pdp-serif: var(--xg-serif, "Instrument Serif", Georgia, serif);
  --pdp-sans:  var(--xg-sans, "Jost", Helvetica, Arial, sans-serif);

  font-family: var(--pdp-sans);
  color: var(--pdp-green);
}

/*
 * ⚠️ THE 96px BOTTOM PADDING WAS REMOVED.
 *
 * It existed on phones only (a `min-width: 640px` rule zeroed it again) and was
 * almost certainly clearance for a sticky Add-to-bag bar. There is no such bar
 * on this page — the buy column is sticky on DESKTOP, where the padding was
 * already zero — so on mobile it sat under the sign-off as 96px of nothing,
 * before the footer's own 64px margin. 160px of dead space, phones only.
 *
 * If a sticky mobile buy bar is ever added, put the clearance back on that bar's
 * own rule rather than here, so the two cannot get out of step.
 */

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

.pdp-page img,
.pdp-page svg { display: block; max-width: 100%; }

/*
 * ⚠️ `:where()` HOLDS THESE AT THE DESIGN'S OWN SPECIFICITY. DO NOT UNWRAP IT.
 *
 * The design styles bare `a` — specificity (0,0,1), which loses to any class.
 * That is load-bearing: `.concern--dark` (0,1,0) sets cream text on its dark
 * card and wins, so the card's own colour shows through the link.
 *
 * Written as `.pdp-page a` this becomes (0,1,1) and starts *beating* the card,
 * which painted the "Pigmentation & tan" heading dark green on dark green —
 * invisible. `:where()` contributes nothing to specificity, so the rule is
 * still scoped to the page but competes exactly as the design's does.
 */
:where(.pdp-page) a { color: var(--pdp-green); text-decoration: none; }
:where(.pdp-page) a:hover { color: #8a6a2f; }

/*
 * ⚠️ THE THEME COLOURS EVERY HEADING. THAT MUST NOT REACH INTO THIS PAGE.
 *
 * style.css sets `h1, h2, h3, h4 { font-family; font-weight: 600; color:
 * var(--x-ink); text-wrap: balance }`. The design has no such rule — its
 * headings inherit from whatever band they sit in and set their own face.
 *
 * A *direct* declaration always beats an inherited value, however specific the
 * ancestor, so the banner's `<h2>` took the theme's dark ink instead of the
 * cream it inherits from `.pdp-banner__body` — dark type on the dark banner.
 * Resetting to `inherit` here restores the design's behaviour; this sits above
 * the component rules so anything that sets its own face still wins.
 */
.pdp-page :is(h1, h2, h3, h4, h5, h6) {
  color: inherit;
  font-family: inherit;
  font-weight: 400;
  margin: 0;
  text-wrap: initial;
}

/* The design's `.wrap`, scoped so it cannot touch the shell's containers. */
/*
 * ⚠️ WOOCOMMERCE'S SUMMARY WRAPPER IS TAKEN OUT OF THE LAYOUT.
 *
 * The design's buy column, `.pdp__buy`, used to be a direct child of `.pdp-grid`.
 * Now that WooCommerce renders the page, whatever the summary hook prints lands
 * inside `<div class="summary entry-summary">` — one level deeper, so the column
 * stopped being a grid item and the two-column layout collapsed.
 *
 * `display: contents` removes the wrapper from the box tree while leaving its
 * child in the document, which hands `.pdp__buy` straight back to the grid. The
 * alternative was restyling the column against a class this theme does not own,
 * and inheriting whatever WooCommerce does to it next.
 */
/*
 * ⚠️ WOOCOMMERCE'S PRODUCT DIV IS A GRID. THIS PAGE NEEDS IT TO BE A BLOCK.
 *
 * `woocommerce.css` styles `.woocommerce div.product` as a two-column grid — the
 * stock layout, gallery beside summary. That div is now `.pdp-page`, so the
 * design's own full-width sections became grid items and were dealt into
 * columns: the whole page rendered in the right-hand half, 783px from the left,
 * with 72px of overflow on a phone.
 *
 * ⚠️ THE SELECTOR IS LONG ON PURPOSE. `.woocommerce div.product` is (0,2,1);
 * `.pdp-page.product` is (0,2,0) and loses however late this file loads. Matching
 * its shape at (0,3,1) is what makes this apply — the same trap the shop
 * stylesheet hit four times.
 */
.woocommerce div.product.pdp-page {
  display: block;
  gap: 0;
}

/* The stock gallery/summary column rules belong to that grid and have nothing
   to size here; the design's own `.pdp-grid` does the two columns. */
.woocommerce div.product.pdp-page > .summary.entry-summary,
.woocommerce div.product.pdp-page > div.images { width: auto; float: none; }

.pdp-page .pdp-grid > .summary.entry-summary { display: contents; }

/*
 * Notices now print where WooCommerce puts them — before the product wrapper,
 * on `woocommerce_before_single_product` — rather than inside a `.pdp-notices`
 * div the renderer used to open. That hook is core's own position for them and
 * is left alone; this just gives them the page's measure.
 */
.woocommerce-notices-wrapper:not(:empty) {
  max-width: 77.5rem;
  margin-inline: auto;
  padding-inline: clamp(12px, 4vw, 40px);
  padding-top: 16px;
}

.pdp-wrap {
  max-width: 1240px;
  margin: 0 auto;
  padding-inline: clamp(12px, 4vw, 40px);
}

.pdp-kicker {
  display: block;
  font-size: 11px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: #8a6a2f;
}

.pdp-kicker--light { color: var(--pdp-accent-soft); }

/* ────────────────────────────────────────────────────────────────────────────
 * Buttons — the design's, scoped
 * ──────────────────────────────────────────────────────────────────────────── */

.pdp-page .pdp-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 44px;
  padding: 11px 10px;
  border: 0;
  border-radius: 999px;
  font-family: inherit;
  font-size: 12px;
  letter-spacing: .05em;
  text-transform: uppercase;
  cursor: pointer;
  text-align: center;
  transition: background .25s ease, color .25s ease, filter .25s ease, transform .2s ease;
}

.pdp-page .pdp-btn:active { transform: scale(.98); }

.pdp-page .pdp-btn--inline { width: auto; padding: 12px 20px; font-size: 13px; }

.pdp-page .pdp-btn--dark { background: var(--pdp-green); color: var(--pdp-cream-ink); }
.pdp-page .pdp-btn--dark:hover { background: var(--pdp-green-mid); color: var(--pdp-cream-ink); }

.pdp-page .pdp-btn--ghost {
  background: transparent;
  color: var(--pdp-green);
  border: 1px solid rgba(18, 48, 35, .25);
}

.pdp-page .pdp-btn--ghost:hover { background: var(--pdp-cream-2); }

/*
 * ⚠️ THE ACCENT BUTTON'S GRADIENT MUST STAY DARK END TO END.
 *
 * Its label is white. The design's own comment says the same thing, and it is
 * why the ramp has an `-ink` and a `-deep` step rather than simply tinting the
 * brand colour — a light carton colour would otherwise put white text on a pale
 * gradient and lose 4.5:1 contrast entirely.
 */
.pdp-page .pdp-btn--accent {
  width: auto;
  min-height: 50px;
  padding: 15px 28px;
  font-size: 13.5px;
  letter-spacing: .06em;
  background: linear-gradient(135deg, var(--pdp-accent-ink), var(--pdp-accent-deep));
  color: #fff;
}

.pdp-page .pdp-btn--accent:hover { filter: brightness(1.12); color: #fff; }

/*
 * WooCommerce's notices, aligned to the content measure.
 *
 * ⚠️ `:empty` MATTERS HERE. The wrapper is printed on every load, notices or
 * not, so without this every product page carried its top padding as a gap
 * above the breadcrumbs.
 */
.pdp-notices { padding-top: 14px; }
.pdp-notices:has(.woocommerce-notices-wrapper:empty) { padding-top: 0; }
.pdp-notices .woocommerce-notices-wrapper:empty { display: none; }

/* ────────────────────────────────────────────────────────────────────────────
 * Breadcrumbs
 * ──────────────────────────────────────────────────────────────────────────── */

.pdp-crumbs {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 12.5px;
  letter-spacing: .04em;
  color: rgba(18, 48, 35, .72);
  padding-top: 14px;
}

.pdp-crumbs a { color: inherit; }

/* The site's own breadcrumb markup, made to sit like the design's. */
.pdp-crumbs .x-crumbs {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
  font-size: inherit;
  letter-spacing: inherit;
  color: inherit;
}

/* ────────────────────────────────────────────────────────────────────────────
 * The two columns
 * ──────────────────────────────────────────────────────────────────────────── */

.pdp-grid {
  display: grid;
  gap: clamp(18px, 2.6vw, 44px);
  padding-top: clamp(14px, 2.4vw, 26px);
}

/*
 * ⚠️ WITHOUT THIS THE PHOTOGRAPH SETS THE PAGE WIDTH ON A PHONE.
 *
 * A grid item defaults to `min-width: auto`, which means it will not shrink
 * below its content's minimum. The gallery holds WooCommerce's `single` image
 * at 748px, so the column became 748px wide inside a 390px screen and the whole
 * page scrolled sideways — `overflow: hidden` on `.pdp-gal` could not help,
 * because the gallery itself was the thing that was too wide.
 *
 * It never appeared in local testing because no product there has a photograph:
 * the empty hatched slide has no intrinsic width to push with. It appeared the
 * moment the patch met the real catalogue.
 */
.pdp-grid > * { min-width: 0; }
.pdp-gal__slide { min-width: 0; }

@media (min-width: 900px) {
  .pdp-grid { grid-template-columns: 1.05fr .95fr; align-items: start; }
  .pdp__buy { position: sticky; top: 96px; }
}

/* ────────────────────────────────────────────────────────────────────────────
 * Gallery
 * ──────────────────────────────────────────────────────────────────────────── */

.pdp-gal {
  position: relative;
  border-radius: 20px;
  overflow: hidden;
  background: var(--pdp-cream-2);
}

.pdp-gal__track { display: flex; transition: transform .45s cubic-bezier(.4, 0, .2, 1); }

/*
 * ⚠️ 4:5 BELOW 900px, SQUARE ABOVE IT — AND 900 IS NOT ARBITRARY.
 *
 * That is the breakpoint where the PDP becomes two columns. Below it the gallery
 * is the full width of the screen, where a square reads squat and gives the
 * product photograph less height than it was shot with. Above it the gallery
 * shares the row with the buy column, and a taller frame would push the price
 * and Add button further down for no gain.
 *
 * ⚠️ IT ALSO STOPS THE CROP ON PHONES.
 *
 * Product photography here is 4:5. The square frame was cutting 10% off the top
 * and 10% off the bottom of every shot via `object-fit: cover` — which is why a
 * bottle composed to fill its frame lost its cap and base on its own product
 * page while looking perfect on the shop grid. At 4:5 the phone now shows the
 * whole photograph. Desktop still crops, so keep the subject inside the central
 * square when shooting.
 */
.pdp-gal__slide {
  flex: 0 0 100%;
  aspect-ratio: 4 / 5;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.pdp-gal__slide img { width: 100%; height: 100%; object-fit: cover; }

/*
 * ⚠️ THE HATCH IS THE DESIGN'S OWN EMPTY STATE, SO IT IS KEPT AS THE DESIGN HAS IT.
 *
 * An earlier version substituted a wash of the product's carton colour. It read
 * well, but it is a different thing from the design — and eight of the twelve
 * products have no photograph, so this is what most of them actually show.
 */
.pdp-gal__slide {
  background: repeating-linear-gradient(135deg, #e7e0d1 0 14px, #dfd7c5 14px 28px);
  font: 11px/1.4 ui-monospace, Menlo, monospace;
  letter-spacing: .1em;
  color: rgba(18, 48, 35, .6);
}

/* A slide holding a real photograph does not need the hatch behind it. */
.pdp-gal__slide:has(img) { background: none; }

/*
 * ⚠️ THE SQUARE COMES BACK HERE, NOT IN THE 900px BLOCK ABOVE.
 *
 * There is an existing `@media (min-width: 900px)` earlier in this file, and
 * putting this rule in it would do nothing: the 4:5 base rule is declared AFTER
 * it, so at equal specificity the later declaration wins at every width. A
 * mobile-first override has to sit below the rule it overrides.
 */
@media (min-width: 900px) {
  .pdp-gal__slide { aspect-ratio: 1 / 1; }
}

/*
 * ⚠️ QUIETER AND SMALLER THAN THE DESIGN'S STICKER, AND NOT THE ACCENT COLOUR.
 *
 * This was 82x32px in the product's own accent gradient, sitting at the top-left
 * corner of a full-width photograph — the first thing the eye landed on, ahead
 * of the product itself. The accent ramp is per-product, so on the correcting
 * serum it rendered a strong orange against a pale packshot.
 *
 * It is kept rather than deleted because the percentage does work the price
 * block does not: "₹599 ₹479" requires the reader to do the arithmetic. But it
 * is a label on a photograph, not a promotion in its own right.
 *
 * The muted tone is `.pdp-card__badge.is-mute`'s, already defined further down
 * this file for the related-product cards — so the two badges on one page now
 * agree instead of one shouting. Translucent dark also reads consistently over
 * any photograph, which an accent-coloured pill cannot promise across twelve
 * products with twelve different ramps.
 */
.pdp-gal__badge {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 2;
  pointer-events: none;
  background: rgba(18, 48, 35, .72);
  color: var(--pdp-cream-ink);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: 4px 9px;
  border-radius: 999px;
}

.pdp-gal__btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  border-radius: 999px;
  border: 1px solid rgba(18, 48, 35, .12);
  background: rgba(247, 244, 238, .92);
  backdrop-filter: blur(8px);
  color: var(--pdp-green);
  font-size: 17px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 3;
  padding: 0;
}

.pdp-gal__btn:hover { background: var(--pdp-cream); }
.pdp-gal__btn--prev { left: 12px; }
.pdp-gal__btn--next { right: 12px; }

/*
 * ⚠️ SMALLER AND DIMMER BELOW THE TWO-COLUMN BREAKPOINT ONLY.
 *
 * On a phone the gallery is the full width of the screen and the photograph is
 * the point; two 44px cream discs sitting on top of it compete with the product.
 * At half the size and 40% opacity they say "there is more here" without being
 * the first thing the eye lands on. product.js brings them to full opacity for
 * half a second whenever the slide changes — by arrow, dot, thumbnail or swipe.
 *
 * ⚠️ THE CIRCLE SHRINKS. THE TAP TARGET DOES NOT.
 *
 * 22px is less than half the 44px minimum a touch target should be, and a
 * control that is pretty and hard to hit is a worse control. The `::after`
 * below extends the hit area back out to 44px with nothing drawn in it, so the
 * button looks 22px and behaves like 44px.
 *
 * ⚠️ FOCUS OVERRIDES THE DIMMING.
 *
 * A keyboard user tabbing to a 40%-opacity control has no idea where they are,
 * and the wake timer never fires for them because nothing has moved yet.
 */
@media (max-width: 899.98px) {
  .pdp-gal__btn {
    width: 22px;
    height: 22px;
    font-size: 11px;
    opacity: .4;
    transition: opacity .3s ease;
  }

  .pdp-gal__btn::after {
    content: "";
    position: absolute;
    inset: -11px;
  }

  .pdp-gal__btn.is-awake,
  .pdp-gal__btn:focus-visible { opacity: 1; }
}

/* The fade is decoration; with reduced motion the arrows simply stay visible. */
@media (max-width: 899.98px) and (prefers-reduced-motion: reduce) {
  .pdp-gal__btn { opacity: 1; transition: none; }
}

.pdp-gal__dots {
  position: absolute;
  bottom: 14px;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  gap: 6px;
  z-index: 2;
}

.pdp-gal__dot {
  width: 10px;
  height: 6px;
  border-radius: 99px;
  border: 0;
  padding: 0;
  cursor: pointer;
  background: rgba(18, 48, 35, .3);
  transition: width .3s, background .3s;
}

.pdp-gal__dot.is-active { width: 26px; background: var(--pdp-green); }

/*
 * ⚠️ A RAIL, NOT A ROW — THE DESIGN'S VERSION ONLY HELD THREE.
 *
 * The mockup shows three thumbnails on a desktop column, where a plain flex row
 * fits. Real products carry five and more, and at 76px each they ran to 764px
 * and pushed the page sideways on a phone: this was the actual cause of the
 * horizontal scroll, still there after the gallery itself was fixed.
 *
 * Scrolling inside its own box is the same thing the related-products rail does
 * lower down the page, so the gesture is already familiar here. The scrollbar is
 * hidden because the thumbnails themselves show there is more to the right.
 */
.pdp-thumbs {
  display: flex;
  gap: 8px;
  padding-top: 10px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.pdp-thumbs::-webkit-scrollbar { display: none; }

.pdp-thumb {
  /* `flex: 0 0 76px` already stops it shrinking; the snap point is what makes
     the rail come to rest on a thumbnail rather than between two. */
  scroll-snap-align: start;
  flex: 0 0 76px;
  height: 76px;
  border-radius: 12px;
  overflow: hidden;
  padding: 0;
  cursor: pointer;
  background: var(--pdp-cream-2);
  border: 1px solid rgba(18, 48, 35, .14);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
  font-size: 10.5px;
  letter-spacing: .06em;
  color: rgba(18, 48, 35, .6);
  text-transform: uppercase;
}

.pdp-thumb img { width: 100%; height: 100%; object-fit: cover; }

/*
 * ⚠️ THE ACTIVE BORDER MUST NOT RESIZE THE BOX.
 *
 * The design goes from a 1px border to a 2px one. On a fixed 76px tile that
 * shifts the image by a pixel on every step, which reads as the strip twitching.
 * An inset shadow draws the second pixel inside the existing border instead.
 */
.pdp-thumb.is-active { border: 2px solid var(--pdp-green); }

/* ────────────────────────────────────────────────────────────────────────────
 * Buy column
 * ──────────────────────────────────────────────────────────────────────────── */

.pdp__buy { display: flex; flex-direction: column; gap: 16px; padding-top: clamp(18px, 2.4vw, 8px); }

.pdp__meta { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

.pdp__cat {
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--pdp-accent-ink);
}

.pdp__tag {
  background: var(--pdp-accent-ink);
  color: #fff;
  font-size: 10.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  padding: 6px 14px;
  border-radius: 999px;
}

.pdp-page .pdp__title {
  font-family: var(--pdp-serif);
  font-weight: 400;
  font-size: clamp(34px, 9vw, 50px);
  line-height: 1.04;
  margin: 0;
  /* style.css sets `text-wrap: balance` sitewide, which re-breaks the design's
     headings. The design does not use it. */
  text-wrap: initial;
}

/*
 * ⚠️ NO MEASURE CAP HERE, DELIBERATELY — THE DESIGN HAS ONE.
 *
 * The design caps this at 24ch and the blurb below at 46ch, which is the right
 * reading measure for the mockup's short copy. Against the real taglines it
 * broke lines early and left a ragged column with white space beside it while
 * the buy card carried on to the full width. Removed by explicit decision; the
 * column's own width is the measure now.
 */
.pdp__line {
  margin: 0;
  font-family: var(--pdp-serif);
  font-style: italic;
  font-size: clamp(19px, 2.2vw, 23px);
  line-height: 1.35;
  color: var(--pdp-accent-ink);
}

.pdp__blurb { margin: 0; }

/* Uncapped for the same reason as `.pdp__line` above. */
.pdp__blurb p {
  margin: 0;
  font-size: 16px;
  line-height: 1.6;
  color: rgba(18, 48, 35, .75);
  font-weight: 300;
}

/*
 * ⚠️ `order` PUTS THE LIVE PRICE FIRST. WOOCOMMERCE EMITS IT SECOND.
 *
 * The design reads "₹479.00  ₹599.00  incl. GST" — the price you pay, large,
 * then what it was. `get_price_html()` emits `<del>` (was) before `<ins>` (now),
 * so in source order the page led with the struck-through number, which reads
 * as the price until you notice the line through it.
 *
 * Reordering here rather than in PHP leaves `get_price_html()` untouched, so
 * sale logic, currency and tax suffix all still come from WooCommerce.
 * `order` is visual only — the DOM order the screen reader follows is unchanged.
 */
.pdp__price { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; padding-top: 4px; }

.pdp__price ins,
.pdp__price > .amount,
.pdp__price > span:not(.woocommerce-price-suffix):not(.screen-reader-text):not(.x-price-note) { order: 1; }
.pdp__price del { order: 2; }
/* ⚠️ THE SUFFIX IS THE THEME'S `.x-price-note`, NOT WOOCOMMERCE'S OWN CLASS.
   Matching only `.woocommerce-price-suffix` left "incl. GST" sorted with the
   live price, so the row read "₹519  incl. GST  ₹649". */
.pdp__price .woocommerce-price-suffix,
.pdp__price .x-price-note { order: 3; }

/*
 * ⚠️ `get_price_html()` IS `<del>`/`<ins>`, NOT `<s>`/`<b>`.
 *
 * The design writes the price by hand. WooCommerce emits a strikethrough as
 * `<del><span class="amount">` and the live price as `<ins>`, plus a
 * screen-reader sentence and a tax suffix. Styling `s` and `b` — which a
 * straight port does — matches nothing at all.
 */
.pdp__price ins,
.pdp__price > .amount,
.pdp__price > span:not(.woocommerce-price-suffix):not(.screen-reader-text) > .amount {
  text-decoration: none;
  font-size: clamp(28px, 7vw, 36px);
  font-weight: 500;
}

.pdp__price del { font-size: 17px; color: rgba(18, 48, 35, .55); opacity: 1; }
.pdp__price del .amount { font-size: 17px; font-weight: 400; }

.pdp__price .woocommerce-price-suffix {
  font-size: 12.5px;
  color: rgba(18, 48, 35, .7);
  font-weight: 300;
}

/* Kept in the DOM for assistive tech, out of the visual line. */
.pdp__price .screen-reader-text {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.pdp__stock {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  color: var(--pdp-green-mid);
}

.pdp__stock i { width: 7px; height: 7px; border-radius: 99px; background: #2f8055; flex: 0 0 auto; }
.pdp__stock--out { color: rgba(18, 48, 35, .6); }
.pdp__stock--out i { background: rgba(18, 48, 35, .35); }

/*
 * ⚠️ THE QUANTITY FIELD IS HIDDEN, NOT REMOVED.
 *
 * It is still WooCommerce's field, still carrying `max` and its validation,
 * and it still posts — the form sends its default of 1. Removing it in PHP
 * would take the stock ceiling with it. The count is asked for after the fact,
 * through `.pdp__inbag`.
 */
.pdp__buy form.cart .quantity { display: none !important; }

/*
 * ⚠️ ONCE IT IS IN THE BAG, ADD AND BUY NOW BOTH GO AWAY.
 *
 * Both post another add-to-cart. Beside a control reading "1 in bag" they look
 * like "check out with this one", but pressing either quietly makes it two —
 * the same trap the listing cards already avoid, for the same reason. The
 * − / + control and the bag are how the quantity changes from here.
 */
.pdp__buy.is-inbag form.cart,
.pdp__buy.is-inbag .pdp__buynow { display: none; }

.pdp__inbag {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  min-height: 52px;
  padding: 4px 6px;
  border: 1px solid rgba(18, 48, 35, .2);
  border-radius: 999px;
  background: #fff;
}

.pdp__inbag[hidden] { display: none; }

/* Mid-request, the control is not to be pressed again. */
.pdp__inbag.is-busy { opacity: .6; pointer-events: none; }

.pdp__inbag-label {
  font-size: 14px;
  letter-spacing: .04em;
  color: var(--pdp-green);
}

.pdp__inbag-label b { font-weight: 500; }

.pdp__inbag .pdp-step {
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font-family: inherit;
  font-size: 19px;
  line-height: 1;
  color: var(--pdp-green);
  cursor: pointer;
  transition: background .2s ease;
}

.pdp__inbag .pdp-step:hover { background: var(--pdp-cream-2); }
.pdp__inbag .pdp-step:active { transform: scale(.94); }

/* ────────────────────────────────────────────────────────────────────────────
 * WooCommerce's add-to-cart form, dressed as the design's row
 *
 * ⚠️ EVERY RULE HERE IS SCOPED UNDER `.pdp__buy`.
 *
 * These are WooCommerce's own class names. Unscoped they would restyle the
 * cart page's quantity boxes and every add-to-cart button on the site.
 * ──────────────────────────────────────────────────────────────────────────── */

.pdp__buy form.cart {
  display: flex;
  gap: 10px;
  align-items: stretch;
  flex-wrap: wrap;
  padding-top: 4px;
  margin: 0;
}

/*
 * ⚠️ THE `margin: 0` ABOVE HAS NEVER APPLIED. WOOCOMMERCE OUT-SPECIFIES IT.
 *
 * woocommerce.css sets `.woocommerce div.product form.cart { margin-bottom: 2em }`
 * — specificity (0,2,2) against this file's `.pdp__buy form.cart` at (0,1,1). So
 * the computed margin was 24px top and bottom on every product, at every width,
 * while the stylesheet plainly said zero. It is the same trap noted at the top
 * of this file for `.woocommerce div.product`, hit again.
 *
 * Matching WooCommerce's shape and adding the page's own classes takes this to
 * (0,4,1), which wins without `!important` — so a future rule can still override
 * it normally.
 *
 * ⚠️ BOTH MARGINS, AND ONLY WHERE THE COLUMN IS STACKED.
 *
 * Below 900px the buy column sits between the price and the Buy Now button, and
 * WooCommerce's 24px stacked with each of their own spacings — a 40px gap
 * between two controls that belong together. Both are dropped so the group reads
 * as one block; the form keeps its own 4px `padding-top` for separation from the
 * price, which is enough at this width.
 *
 * Desktop keeps both, where the column has the room for them.
 */
@media (max-width: 899.98px) {
  .woocommerce div.product.pdp-page .pdp__buy form.cart {
    margin-top: 0;
    margin-bottom: 0;
  }
}

.pdp__buy form.cart .quantity {
  display: flex;
  align-items: center;
  border: 1px solid rgba(18, 48, 35, .2);
  border-radius: 999px;
  overflow: hidden;
  background: #fff;
  min-height: 52px;
  margin: 0;
  float: none;
}

/*
 * ⚠️ THE NUMBER INPUT IS KEPT; ONLY ITS SPINNERS GO.
 *
 * product.js adds the design's − / + around this input rather than replacing
 * it, so WooCommerce's `min`, `max` and `step` — the stock ceiling among them —
 * still apply and a keyboard user can still type. The browser's own spinner
 * arrows beside ours would be two of the same control.
 */
.pdp__buy form.cart .quantity input.qty {
  width: 46px;
  min-width: 0;
  border: 0;
  background: transparent;
  text-align: center;
  font-family: inherit;
  font-size: 16px;
  color: var(--pdp-green);
  padding: 0;
  -moz-appearance: textfield;
  appearance: textfield;
}

.pdp__buy form.cart .quantity input.qty::-webkit-outer-spin-button,
.pdp__buy form.cart .quantity input.qty::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.pdp-step {
  background: none;
  border: 0;
  width: 46px;
  align-self: stretch;
  font-size: 19px;
  line-height: 1;
  cursor: pointer;
  color: var(--pdp-green);
  font-family: inherit;
  padding: 0;
}

.pdp-step:hover { background: var(--pdp-cream-2); }

/*
 * ⚠️ `!important` IS REQUIRED — woocommerce.css USES IT ON THIS BUTTON.
 *
 * A rule of equal or greater specificity still loses to it. Same fight the
 * checkout's `#place_order` needed, same answer: match the declaration and keep
 * the scope tight.
 */
.pdp__buy form.cart .single_add_to_cart_button {
  flex: 1 1 190px;
  width: auto;
  min-height: 52px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 11px 20px !important;
  border: 0;
  border-radius: 999px !important;
  font-family: inherit;
  font-size: 14px !important;
  letter-spacing: .07em;
  text-transform: uppercase;
  cursor: pointer;
  background: var(--pdp-green) !important;
  color: var(--pdp-cream-ink) !important;
  transition: background .25s ease, filter .25s ease, transform .2s ease;
}

.pdp__buy form.cart .single_add_to_cart_button:hover { background: var(--pdp-green-mid) !important; }
.pdp__buy form.cart .single_add_to_cart_button:active { transform: scale(.98); }

/* WooCommerce prints its own stock line inside the form template; ours carries
   the dot and the dispatch promise, so its duplicate is hidden. */
.pdp__buy p.stock { display: none; }

.pdp__buynow { margin: 0; }
.pdp__buynow .pdp-btn { width: 100%; min-height: 52px; font-size: 14px; letter-spacing: .07em; }

/* ────────────────────────────────────────────────────────────────────────────
 * Promo strip, facts, accordions
 * ──────────────────────────────────────────────────────────────────────────── */

.pdp__promo {
  border-radius: 16px;
  border: 1px dashed var(--pdp-accent);
  background: var(--pdp-accent-wash);
  padding: 14px 16px;
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
}

.pdp__promo span:first-child {
  font-family: ui-monospace, Menlo, monospace;
  letter-spacing: .16em;
  font-size: 13.5px;
  color: var(--pdp-accent-ink);
}

.pdp__promo span:last-child { font-size: 13.5px; color: rgba(18, 48, 35, .72); font-weight: 300; }

.pdp__facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 130px), 1fr));
  gap: 10px;
}

.pdp__fact { background: var(--pdp-cream-2); border-radius: 14px; padding: 14px; }
.pdp__fact b { display: block; font-size: 13.5px; font-weight: 500; }

.pdp__fact span {
  display: block;
  font-size: 12.5px;
  color: rgba(18, 48, 35, .72);
  font-weight: 300;
  margin-top: 3px;
}

.pdp-accs { border-top: 1px solid rgba(18, 48, 35, .12); padding-top: 6px; }
.pdp-acc { border-bottom: 1px solid rgba(18, 48, 35, .12); }

.pdp-acc summary {
  list-style: none;
  cursor: pointer;
  padding: 16px 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  font-size: 15px;
  letter-spacing: .04em;
}

.pdp-acc summary::-webkit-details-marker { display: none; }
.pdp-acc summary::after { content: "+"; font-size: 18px; opacity: .5; }
.pdp-acc[open] summary::after { content: "\2013"; }

.pdp-acc__body {
  padding: 0 0 18px;
  font-size: 14.5px;
  line-height: 1.65;
  color: rgba(18, 48, 35, .75);
  font-weight: 300;
}

.pdp-acc__body p { margin: 0 0 10px; }
.pdp-acc__body p:last-child { margin-bottom: 0; }
.pdp-acc__body ul { margin: 0 0 10px; padding-left: 18px; }
.pdp-acc__body li { margin-bottom: 6px; }
.pdp-acc__body strong { font-weight: 500; color: var(--pdp-green); }

/* The pack facts are a definition list written as a `<ul>` with the label in a
   `<span>`. Two columns, so "Net content" and "30 mL" line up down the stack
   rather than running together as one sentence. */
.pdp-acc__body .x-pdp__facts { list-style: none; padding-left: 0; }

.pdp-acc__body .x-pdp__facts li {
  display: grid;
  grid-template-columns: minmax(0, 8.5rem) 1fr;
  gap: 8px;
  padding: 5px 0;
  border-bottom: 1px solid rgba(18, 48, 35, .07);
}

.pdp-acc__body .x-pdp__facts li:last-child { border-bottom: 0; }

.pdp-acc__body .x-pdp__facts span {
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(18, 48, 35, .55);
  align-self: center;
}

/* A wall of Latin reads better a shade smaller and looser. */
.pdp-acc__body .x-pdp__inci { font-size: 13px; line-height: 1.7; }

/* ────────────────────────────────────────────────────────────────────────────
 * Carton story
 * ──────────────────────────────────────────────────────────────────────────── */

.pdp-story {
  margin-top: clamp(36px, 6vw, 72px);
  background: var(--pdp-accent-wash);
  padding-block: clamp(36px, 6vw, 64px);
}

.pdp-page .pdp-story__head {
  font-family: var(--pdp-serif);
  font-weight: 400;
  font-size: clamp(30px, 8vw, 46px);
  line-height: 1.05;
  margin: 10px 0 6px;
  max-width: 22ch;
  text-wrap: initial;
}

/*
 * ⚠️ THE DESIGN'S SIZE, KEPT.
 *
 * This was stepped down at one point because the real copy puts a
 * three-sentence paragraph in a slot the mockup fills with one line. That was a
 * judgement about the copy, not about the design — and the brief is to match
 * the design. If the paragraph reads too heavy here, shorten the paragraph.
 */
.pdp-story__line {
  margin: 0 0 24px;
  font-family: var(--pdp-serif);
  font-style: italic;
  font-size: clamp(19px, 2.4vw, 24px);
  line-height: 1.45;
  color: var(--pdp-accent-ink);
  max-width: 62ch;
}

.pdp-story__line p { margin: 0 0 10px; }
.pdp-story__line p:last-child { margin-bottom: 0; }

.pdp-actives {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: 12px;
}

.pdp-active {
  background: #fff;
  border: 1px solid rgba(18, 48, 35, .08);
  border-radius: 18px;
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.pdp-page .pdp-active h3 {
  font-family: var(--pdp-serif);
  font-weight: 400;
  font-size: clamp(23px, 5.4vw, 28px);
  margin: 0;
  line-height: 1.15;
  text-wrap: initial;
}

.pdp-active p { margin: 0; font-size: 14.5px; line-height: 1.65; color: rgba(18, 48, 35, .75); font-weight: 300; }

.pdp-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: 12px;
  margin-top: 12px;
}

/* .pdp-makers* removed with the "Meet the makers" card. */

.pdp-ritual {
  border-radius: 18px;
  padding: 24px;
  background: #fff;
  border: 1px solid rgba(18, 48, 35, .08);
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.pdp-ritual__flow { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 15px; }

.pdp-pill { background: var(--pdp-accent-wash); border-radius: 999px; padding: 9px 16px; }
.pdp-pill--dark { background: var(--pdp-green); color: var(--pdp-cream-ink); font-weight: 500; }
.pdp-arrow { opacity: .45; }

.pdp-ritual p { margin: 0; font-size: 14.5px; line-height: 1.65; color: rgba(18, 48, 35, .72); font-weight: 300; }

/* ────────────────────────────────────────────────────────────────────────────
 * Concern tiles
 * ──────────────────────────────────────────────────────────────────────────── */

.pdp-concerns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: 12px;
  margin-top: clamp(36px, 6vw, 72px);
}

.pdp-concern {
  border-radius: 18px;
  padding: 24px;
  min-height: 170px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 12px;
}

.pdp-concern__name { font-family: var(--pdp-serif); font-size: clamp(23px, 5.4vw, 29px); line-height: 1.1; }
.pdp-concern__note { font-size: 13.5px; font-weight: 300; }

.pdp-concern--dark {
  background: linear-gradient(150deg, var(--pdp-green-mid), var(--pdp-green-dark));
  color: var(--pdp-cream-ink);
}

.pdp-concern--dark:hover { filter: brightness(1.12); color: var(--pdp-cream-ink); }
.pdp-concern--dark .pdp-concern__note { color: rgba(244, 237, 223, .78); }

.pdp-concern--cream { background: linear-gradient(150deg, #f4eddf, #e2d8c2); }
.pdp-concern--cream:hover { filter: brightness(1.04); }
.pdp-concern--cream .pdp-concern__note { color: rgba(18, 48, 35, .7); }

.pdp-concern--gold {
  background: linear-gradient(150deg, var(--pdp-accent-hi), var(--pdp-accent));
  color: var(--pdp-green);
}

.pdp-concern--gold .pdp-btn { align-self: flex-start; }

/* ────────────────────────────────────────────────────────────────────────────
 * The banner — from site.css, scoped so the shell keeps its own
 * ──────────────────────────────────────────────────────────────────────────── */

.pdp-banner { position: relative; overflow: hidden; margin-top: clamp(32px, 5vw, 64px); }

.pdp-banner__img {
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(135deg, #e7e0d1 0 14px, #dfd7c5 14px 28px);
  display: flex;
  align-items: center;
  justify-content: center;
  font: 11px/1.4 ui-monospace, Menlo, monospace;
  letter-spacing: .1em;
  color: rgba(18, 48, 35, .6);
}

.pdp-banner__img img { width: 100%; height: 100%; object-fit: cover; }

/*
 * ⚠️ THE LAST STOP MUST NOT DROP BELOW ~.6 ALPHA — the design says so.
 *
 * The label over it is cream on a photograph that may be light. Thinning the
 * scrim is the one change here that can silently make the headline unreadable.
 */
.pdp-banner__scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(var(--dir, 105deg), rgba(14, 42, 30, .9) 0%, rgba(18, 48, 35, .78) 52%, rgba(120, 90, 40, .66) 100%);
}

.pdp-banner__body { position: relative; padding-block: clamp(40px, 7vw, 84px); color: var(--pdp-cream-ink); }

.pdp-page .pdp-banner__head {
  font-family: var(--pdp-serif);
  font-weight: 400;
  font-size: clamp(30px, 8.5vw, 52px);
  line-height: 1.04;
  margin: 12px 0;
  max-width: 20ch;
  text-wrap: initial;
}

.pdp-banner__sub {
  margin: 0 0 22px;
  max-width: 46ch;
  font-size: 15.5px;
  line-height: 1.65;
  color: rgba(244, 237, 223, .86);
  font-weight: 300;
}

/* ────────────────────────────────────────────────────────────────────────────
 * Related rail
 * ──────────────────────────────────────────────────────────────────────────── */

.pdp-related { margin-top: clamp(36px, 6vw, 72px); }

.pdp-page .pdp-related h2 {
  font-family: var(--pdp-serif);
  font-weight: 400;
  font-size: clamp(30px, 7.5vw, 44px);
  margin: 6px 0 20px;
  line-height: 1.05;
  text-wrap: initial;
}

.pdp-rail {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 6px;
  scrollbar-width: none;
}

.pdp-rail::-webkit-scrollbar { height: 0; }
.pdp-rail > * { scroll-snap-align: start; flex: 0 0 72%; }

/*
 * ⚠️ `scroll-padding-inline` IS WHAT KEEPS THE FIRST CARD OFF THE SCREEN EDGE.
 *
 * The rail breaks out of the section's gutter with a negative margin and puts it
 * back as padding, so the cards line up with the heading above them. That is
 * correct — and `scroll-snap-align: start` then undid it.
 *
 * A snap position aligns the child's start edge with the SCROLLPORT's start
 * edge, and the scrollport ignores padding. So the browser scrolled the rail by
 * exactly the padding to satisfy the snap: measured `scrollLeft: 16` on a phone,
 * with the heading at x=16 and the first card at x=0, flush against the screen.
 *
 * `scroll-padding-inline` is the property that tells snapping about the inset.
 * The same fix is already documented in bestsellers.css for the same reason;
 * this rail simply never got it.
 */
@media (max-width: 639px) {
  .pdp-rail {
    padding-inline: clamp(12px, 4vw, 20px);
    margin-inline: calc(-1 * clamp(12px, 4vw, 20px));
    scroll-padding-inline: clamp(12px, 4vw, 20px);
  }
}

@media (min-width: 640px) {
  .pdp-rail { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 18px; overflow: visible; }
  .pdp-rail > * { flex: none; }
}

.pdp-card {
  background: #fff;
  border: 1px solid rgba(18, 48, 35, .07);
  border-radius: 18px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.pdp-card__media { position: relative; display: block; aspect-ratio: 4/5; background: var(--pdp-cream-2); }

/*
 * ⚠️ ABSOLUTELY POSITIONED, OR THE IMAGE DICTATES THE BOX INSTEAD OF FILLING IT.
 *
 * `aspect-ratio: 4/5` above is a preferred size, not a rule. This is a flex item
 * inside `.pdp-card`, flex items carry `min-height: auto`, and an in-flow child
 * taller than the ratio therefore stretches the box rather than being cropped.
 *
 * It only surfaced when the card started requesting `woocommerce_single`, which
 * is width-constrained and RATIO-PRESERVING rather than a 4:5 crop. Products
 * shot at 3:4 then produced a 3:4 image, and the card measured 256x342 — ratio
 * 0.75 — while the stylesheet plainly said 4/5. With the old square thumbnail
 * the bug was invisible, because a square is shorter than the box.
 *
 * Out of flow, the image cannot influence its parent's height and `aspect-ratio`
 * is authoritative for every product whatever its source ratio.
 *
 * This is the third place in this codebase where a percentage-sized image in a
 * flex or grid cell has silently resized its own container — see `.cnt__img` in
 * concerns.css and `.x-cat__video` in categories.css for the same fix.
 */
.pdp-card__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pdp-card__badge {
  position: absolute;
  top: 10px;
  left: 10px;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: 6px 11px;
  border-radius: 999px;
  pointer-events: none;
}

.pdp-card__badge.is-dark { background: linear-gradient(135deg, var(--pdp-green), #2a5c42); color: var(--pdp-cream-ink); }
.pdp-card__badge.is-mute { background: rgba(18, 48, 35, .72); color: var(--pdp-cream-ink); }
.pdp-card__badge.is-gold { background: linear-gradient(135deg, #dcbb74, #b98f42); color: var(--pdp-green); }

.pdp-card__body { padding: 14px 14px 16px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.pdp-card__format { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: rgba(18, 48, 35, .65); }

.pdp-page .pdp-card__name {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
  line-height: 1.3;
  font-family: var(--pdp-sans);
  text-wrap: initial;
}

/*
 * The card price carries the same `<del>`-before-`<ins>` order as the buy
 * column, and the same fix. See the note on `.pdp__price`.
 */
.pdp-card__price ins,
.pdp-card__price > .amount,
.pdp-card__price > span:not(.woocommerce-price-suffix):not(.screen-reader-text):not(.x-price-note) { order: 1; }
.pdp-card__price del { order: 2; }
/* ⚠️ THE SUFFIX IS THE THEME'S `.x-price-note`, NOT WOOCOMMERCE'S OWN CLASS.
   Matching only `.woocommerce-price-suffix` left "incl. GST" sorted with the
   live price, so the row read "₹519  incl. GST  ₹649". */
.pdp-card__price .woocommerce-price-suffix,
.pdp-card__price .x-price-note { order: 3; }

.pdp-card__price { display: flex; align-items: baseline; gap: 8px; margin-top: auto; flex-wrap: wrap; }
.pdp-card__price ins, .pdp-card__price .amount { text-decoration: none; font-size: 18px; font-weight: 500; }
.pdp-card__price del { font-size: 13.5px; color: rgba(18, 48, 35, .6); opacity: 1; }
.pdp-card__price del .amount { font-size: 13.5px; font-weight: 400; }
.pdp-card__price .woocommerce-price-suffix { display: none; }
.pdp-card__price .screen-reader-text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

.pdp-card .pdp-btn { min-height: 46px; font-size: 13.5px; letter-spacing: .07em; margin-top: 4px; }

/* ────────────────────────────────────────────────────────────────────────────
 * Reviews and sign-off
 * ──────────────────────────────────────────────────────────────────────────── */

.pdp-reviews { margin-top: clamp(36px, 6vw, 72px); }

.pdp-reviews__card {
  background: #fff;
  border: 1px solid rgba(18, 48, 35, .08);
  border-radius: 20px;
  padding: clamp(22px, 3vw, 34px);
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: flex-start;
}

/* The gap does the spacing, so WooCommerce's own margins would double it. */
.pdp-reviews__card > * { margin-block: 0; }

/*
 * The design's "Write a review" button. It is a `<summary>`, so the disclosure
 * triangle has to go in two ways — `display` for Chrome and Safari's own
 * pseudo-element, `list-style` for Firefox.
 */
.pdp-reviews__form { width: 100%; }

.pdp-reviews__form > summary {
  list-style: none;
  cursor: pointer;
  width: auto;
  display: inline-flex;
}

.pdp-reviews__form > summary::-webkit-details-marker { display: none; }
.pdp-reviews__form > summary::marker { content: ""; }

/* Once open, the button has done its job and the form is what matters. */
.pdp-reviews__form[open] > summary { margin-bottom: 20px; }

/* WooCommerce prints its own "Leave a Reply" heading inside the form; the
   summary above it already says the same thing. */
.pdp-reviews__form #reply-title { display: none; }

.pdp-stars { color: var(--pdp-accent-ink); letter-spacing: .2em; font-size: 13px; }

.pdp-page .pdp-reviews__card h2,
.pdp-page .pdp-reviews__card h3 {
  font-family: var(--pdp-serif);
  font-weight: 400;
  font-size: clamp(24px, 6vw, 32px);
  /* The card is a flex column with `gap: 12px`; a margin here would double it. */
  margin: 0;
  line-height: 1.1;
  text-wrap: initial;
}

.pdp-reviews__card p {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.6;
  color: rgba(18, 48, 35, .72);
  font-weight: 300;
  max-width: 48ch;
}

.pdp-signoff { margin-top: clamp(32px, 5vw, 56px); text-align: center; }

.pdp-signoff__line {
  margin: 0;
  font-family: var(--pdp-serif);
  font-style: italic;
  font-size: clamp(22px, 5vw, 30px);
  color: var(--pdp-accent-ink);
}

.pdp-signoff__note { margin: 10px 0 0; font-size: 13px; color: rgba(18, 48, 35, .7); font-weight: 300; }

/* ────────────────────────────────────────────────────────────────────────────
 * The existing mobile buy bar, dressed to match
 *
 * ⚠️ THE DESIGN'S OWN `.buybar` IS NOT USED, AND THAT IS THE POINT.
 *
 * mu-plugins/xl-product-mobile.php already fixes one to the viewport, and it
 * submits the REAL add-to-cart form rather than carrying a second one — which
 * is what keeps quantity, stock checks and every validation filter on a single
 * path. Adding the design's would put two bars on the page and fork the buying
 * logic. This restyles the one that exists.
 * ──────────────────────────────────────────────────────────────────────────── */

@media (max-width: 47.99rem) {
  body.single-product .x-buybar {
    background: rgba(247, 244, 238, .94);
    backdrop-filter: blur(14px);
    border-top: 1px solid rgba(18, 48, 35, .12);
  }

  body.single-product .x-buybar__inner { gap: 12px; }
  body.single-product .x-buybar__name { font-size: 13px; font-weight: 500; color: var(--xg-green, #123023); }
  body.single-product .x-buybar__price { font-size: 13px; color: rgba(18, 48, 35, .72); font-weight: 400; }
  body.single-product .x-buybar__price del { opacity: .6; }

  body.single-product .x-buybar__cta {
    min-height: 48px;
    padding: 13px 24px;
    font-size: 13px;
    white-space: nowrap;
    border-radius: 999px;
  }
}

/* ────────────────────────────────────────────────────────────────────────────
 * Motion
 * ──────────────────────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .pdp-gal__track,
  .pdp-gal__dot,
  .pdp-page .pdp-btn { transition: none; }
}
