/* =============================================================================
   stw2026 — single product page
   Two-column hero (gallery | sticky summary) over full-bleed content bands,
   following the layout proven on the EatProtein product pages, styled to the
   STW design system (Urbanist, pink #F06292, cyan #40BDED).

   Everything is scoped under .stw-product-page or one of the #stw-product-*
   band IDs. Bootstrap utilities do the grid; this file covers what utilities
   can't: the sticky column, the gallery frame, the tick list, the accordion
   restyle and the nutrition tables.

   Standalone rather than a sass/ partial so a product-page tweak doesn't need
   a full bundle recompile plus a cache-buster bump — same reasoning as
   stw-basket.css. Colours come from the --stw-* custom properties that
   _stw-global.scss publishes from _theme_variables.scss; no brand hex is
   repeated here.
   ========================================================================== */

/* ---------- page wrapper ---------------------------------------------------- */

.stw-product-page {
  /* Oatmeal tone, matching the category-page background (--stw-cat-bg in
     sass/category/_category.scss) — duplicated as a literal rather than a
     shared SASS variable since this file lives outside the SASS pipeline.
     Deliberate duplication, not drift. Bands further down this file that set
     their own background (e.g. .stw-product-band--tint) still take
     precedence as deliberate deeper accent bands. */
  background: oklch(0.972 0.008 70);
  padding-top: 24px;
}

/* The bands below the hero are siblings of the .container the hero sits in
   (content-single-product.php closes it and reopens it), so each band owns its
   own vertical rhythm and can carry a full-width background. */
.stw-product-band {
  padding: 48px 0;
}

.stw-product-band + .stw-product-band {
  border-top: 1px solid var(--stw-grey-200);
}

/* A tinted band separates the long reading sections without another rule line. */
.stw-product-band--tint {
  background: var(--stw-grey-50);
  border-top: 0;
}

.stw-product-band--tint + .stw-product-band {
  border-top: 0;
}

/* Prose and tables are unreadable at the site container's 1800px, so the
   reading bands cap themselves well short of it. The promise strip doesn't use
   this — it's a horizontal strip and wants the full width. */
.stw-product-band__inner {
  max-width: 900px;
  margin: 0 auto;
}

.stw-product-band__title {
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  font-weight: 800;
  letter-spacing: -0.01em;
  margin: 0 0 24px;
}

/* ---------- breadcrumb ------------------------------------------------------- */

/* WooCommerce's own woocommerce_breadcrumb() already renders here — it's
   hooked to woocommerce_before_main_content at priority 20, and this page
   only touches priority 10 (the wrapper open/close), so it was never
   removed. No new markup, just restyled to match the design: small grey
   links, "/" separators, current page in ink. */
.stw-product-page .woocommerce-breadcrumb {
  font-size: 13px;
  font-weight: 600;
  color: var(--stw-grey-500);
  margin: 0 0 8px;
}

.stw-product-page .woocommerce-breadcrumb a {
  color: var(--stw-grey-500);
  text-decoration: none;
}

.stw-product-page .woocommerce-breadcrumb a:hover {
  color: var(--stw-ink);
  text-decoration: underline;
}

/* ---------- hero ------------------------------------------------------------ */

.stw-product__hero {
  --bs-gutter-x: clamp(24px, 3vw, 56px);
  row-gap: 32px;
  margin-bottom: 8px;
}

.stw-product__gallery {
  position: relative;
}

/* WooCommerce's own layout stylesheet floats the gallery and summary side by
   side at 48% each (div.product div.images / div.summary). Bootstrap columns
   already do that here, so the float left the gallery at roughly half the width
   of the column it was given. Both are neutralised back to full width. */
#stw-single-product .woocommerce-product-gallery,
#stw-single-product .summary.entry-summary {
  float: none;
  width: 100%;
  margin: 0;
}

/* The frame gives the bare image stack the same soft lozenge as the category
   cards, so the archive and the product page read as one system. */
.stw-product__gallery .woocommerce-product-gallery {
  background: var(--stw-grey-50);
  border-radius: var(--stw-radius-lg);
  overflow: hidden;
}

.stw-product__gallery .woocommerce-product-gallery__wrapper,
.stw-product__gallery .woocommerce-product-gallery__image {
  width: 100%;
  margin: 0;
}

.stw-product__gallery .woocommerce-product-gallery__image img {
  width: 100%;
  height: auto;
  border-radius: var(--stw-radius-lg);
}

/* Thumbnails: WooCommerce lays these out with its own inline flex widths, so
   only the spacing and the selected state need setting here. */
.stw-product__gallery .flex-control-thumbs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  list-style: none;
  margin: 12px 0 0;
  padding: 0 12px 12px;
}

.stw-product__gallery .flex-control-thumbs li {
  width: auto;
  margin: 0;
  flex: 0 0 calc(25% - 6px);
}

.stw-product__gallery .flex-control-thumbs img {
  border-radius: var(--stw-radius-md);
  border: 2px solid transparent;
  cursor: pointer;
  opacity: 0.75;
  transition: opacity 0.15s ease, border-color 0.15s ease;
}

.stw-product__gallery .flex-control-thumbs img:hover,
.stw-product__gallery .flex-control-thumbs img.flex-active {
  opacity: 1;
  border-color: var(--stw-pink);
}

/* Direction-nav arrow — WooCommerce's own flexslider control, switched on via
   the woocommerce_single_product_carousel_options filter
   (includes/woocommerce-single-product.php). Dots aren't used: flexslider's
   controlNav is a single mode, and the existing thumbnail strip below (kept
   from before this redesign) already covers that job. */
.stw-product__gallery .flex-direction-nav {
  margin: 0;
  padding: 0;
  list-style: none;
}

.stw-product__gallery .flex-direction-nav a {
  position: absolute;
  top: 50%;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-top: -22px;
  border-radius: var(--stw-radius-pill);
  background: rgba(255, 255, 255, 0.82);
  box-shadow: var(--stw-shadow-sm);
  color: var(--stw-ink);
  font-size: 0;
  text-indent: -9999px;
  overflow: hidden;
}

.stw-product__gallery .flex-direction-nav a::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 9px;
  height: 9px;
  margin: -5px 0 0 -6px;
  border-top: 2px solid currentColor;
  border-right: 2px solid currentColor;
}

.stw-product__gallery .flex-direction-nav a.flex-next {
  right: 16px;
  transform: rotate(45deg);
}

.stw-product__gallery .flex-direction-nav a.flex-prev {
  left: 16px;
  transform: scaleX(-1) rotate(45deg);
}

.stw-product__gallery .flex-direction-nav a:hover {
  background: #fff;
}

.stw-product__gallery .flex-direction-nav .flex-disabled {
  opacity: 0;
  pointer-events: none;
}

/* Same lozenge as .stw-card__badge on the archive; inline styles from the ACF
   badge group supply the colours. */
.stw-product__badge {
  position: absolute;
  top: 16px;
  left: 16px;
  z-index: 2;
  padding: 6px 14px;
  border-radius: var(--stw-radius-pill);
  font-size: 0.8125rem;
  font-weight: 700;
  line-height: 1.2;
  box-shadow: var(--stw-shadow-sm);
}

/* ---------- summary column -------------------------------------------------- */

.stw-product__summary {
  margin: 0;
  /* Every element the woocommerce_single_product_summary hooks print
     (rating, title, teaser, price, pricing tiers, features, form, trust
     block…) lands as a direct sibling here — so a flex column + `order` per
     child gets this page's exact visual sequence without touching any hook
     priority, including the stw-pricing-tiers plugin's own hook (registered
     at priority 10, same as WooCommerce's price template, but earlier —
     see includes/woocommerce-single-product.php's comment on this). */
  display: flex;
  flex-direction: column;
}

.stw-product__rating { order: 10; }
.stw-product__summary .product_title { order: 20; }
.stw-product__teaser { order: 30; }
.stw-product__jump-links { order: 40; }
.stw-product__summary .iconic-wlv-variations { order: 45; }
.stw-product__summary .price { order: 50; }
.stw-product__save-badge { order: 55; }
.stw-product__per-meal { order: 60; }
.stw-product__summary .stw-pricing-tiers-wrapper { order: 70; }
.stw-product__features { order: 80; }
.stw-product__subscribe { order: 90; }
.stw-product__summary form.cart { order: 100; }
.stw-product__trust { order: 120; }
.product-delivery-info { order: 106; }

@media (min-width: 992px) {
  /* Sticks against a tall gallery so the price and CTA stay in view; the offset
     clears the site header.

     Deliberately no max-height/overflow pairing here. Capping the column and
     letting it scroll internally puts the add-to-cart button behind an inner
     scrollbar on a short viewport — with ten feature bullets the CTA fell below
     the cap and disappeared. A sticky element taller than the viewport simply
     scrolls with the page, which is the better failure. */
  .stw-product__summary {
    position: sticky;
    top: 96px;
  }
}

.stw-product__summary .product_title {
  font-size: clamp(1.75rem, 3vw, 2.5rem);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin: 0 0 12px;
}

/* ---------- rating ---------------------------------------------------------- */

.stw-product__rating {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

/* Overlay fill technique, matching .stw-card__stars on the archive: a grey row
   of stars with a clipped coloured copy laid over it. */
.stw-product__stars {
  position: relative;
  display: inline-block;
  color: var(--stw-grey-300);
  font-size: 1.05rem;
  letter-spacing: 1px;
  white-space: nowrap;
}

.stw-product__stars-fill {
  position: absolute;
  inset: 0;
  overflow: hidden;
  color: var(--stw-star);
  white-space: nowrap;
}

.stw-product__reviews-link {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--stw-grey-500);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.stw-product__reviews-link:hover {
  color: var(--stw-ink);
}

/* ---------- key features ---------------------------------------------------- */

.stw-product__features {
  list-style: none;
  margin: 20px 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.stw-product__features li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 0.9375rem;
  line-height: 1.45;
}

.stw-product__tick {
  width: 18px;
  height: 18px;
  flex: 0 0 18px;
  margin-top: 2px;
  color: var(--stw-success);
}

/* ---------- teaser, jump links, save badge, per-meal ------------------------ */

.stw-product__teaser {
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--stw-grey-700);
  line-height: 1.5;
  margin: 0 0 10px;
  max-width: 52ch;
}

.stw-product__jump-links {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  margin: 0 0 20px;
}

.stw-product__jump-link {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--stw-cyan-700);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ---------- flavour dropdown (iconic-woo-linked-variations) ----------------- */

/* Plugin markup is a bare, unstyled <table class="variations iconic-wlv-variations">
   (Iconic_WLV_Product::output_linked_variations) — see this file's own
   .stw-product__summary .iconic-wlv-variations order:45 rule above for why
   it needs repositioning at all. No dedicated class exists for the table's
   two <td>s beyond .iconic-wlv-variations__label / __value, so the table
   layout itself is reset to a simple block stack (label line, then the
   dropdown) rather than left as a two-column table row. */
.stw-product__summary .iconic-wlv-variations {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 20px;
}

.stw-product__summary .iconic-wlv-variations tbody,
.stw-product__summary .iconic-wlv-variations__row,
.stw-product__summary td.iconic-wlv-variations__label,
.stw-product__summary .iconic-wlv-variations__value {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
}

/* The plugin reuses the identical class "iconic-wlv-variations__label" on
   both the <td> (block, per above) and the inner <strong> that holds just
   the word "Flavour" — a bare class selector here would force that
   <strong> to display:block too, pushing it onto its own line ahead of the
   trailing ":" + current-selection text that's meant to follow it inline.
   Tag-qualified to the <td> only. */
.stw-product__summary td.iconic-wlv-variations__label {
  margin: 0 0 8px;
  font-size: 0.8125rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--stw-grey-500);
}

/* The dropdown directly below already shows the selected flavour, so the
   label cell's own trailing ":<selection>" would just repeat it — hidden
   rather than restyled, leaving "Flavour" as the whole label. */
.stw-product__summary .iconic-wlv-variations__colon,
.stw-product__summary .iconic-wlv-variations__selection {
  display: none;
}

.stw-product__summary .iconic-wlv-terms--dropdown {
  display: block;
  width: 100%;
  max-width: 320px;
  height: 48px;
  padding: 0 40px 0 16px;
  border: 1px solid var(--stw-grey-300);
  border-radius: var(--stw-radius-pill);
  background: #fff
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23404040' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
    no-repeat right 16px center;
  font-family: inherit;
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--stw-ink);
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  transition: border-color 0.15s ease;
}

.stw-product__summary .iconic-wlv-terms--dropdown:hover,
.stw-product__summary .iconic-wlv-terms--dropdown:focus {
  border-color: var(--stw-pink);
  outline: none;
}

/* WooCommerce's own default stylesheet sets
   `.woocommerce div.product p.price{color:#958e09}` (an olive/mustard
   tone) — 3 classes + 2 elements of specificity — with no theme override
   anywhere in this codebase (confirmed by grepping the compiled bundle for
   a `.price` rule and finding none). A plain `.stw-product__summary .price`
   (2 classes) loses to that rule, so this needs at least 4 classes to win
   on the classes tier alone rather than relying on element-count as a
   tiebreaker. Not a stale-cache or brand-variable issue — both --stw-ink
   and --stw-success are defined and served correctly; this is a genuine
   specificity gap against WooCommerce core CSS. */
.stw-product-page .entry-summary.stw-product__summary .price {
  margin: 0 0 6px;
  font-size: 2.25rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--stw-ink);
}

.stw-product-page .entry-summary.stw-product__summary .price del {
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--stw-grey-500);
  text-decoration: line-through;
  opacity: 1;
  margin-right: 8px;
}

.stw-product-page .entry-summary.stw-product__summary .price ins {
  text-decoration: none;
  color: var(--stw-ink);
  font-weight: 800;
}

.stw-product__save-badge {
  margin: 0 0 4px;
}

.stw-product__save-badge span {
  display: inline-block;
  font-size: 0.8125rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: var(--stw-pink-100);
  color: var(--stw-pink-600);
  padding: 5px 11px;
  border-radius: var(--stw-radius-pill);
}

.stw-product__per-meal {
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--stw-grey-500);
  margin: 0 0 16px;
}

/* ---------- pricing tiers (stw-pricing-tiers plugin) ------------------------ */

/* The tier table's own visual styling (wrapper, header band, row chrome,
   button) moved to assets/css/stw-pricing-tiers-shared.css so it can also be
   enqueued on shop/category archives for stw-quick-view's modal. The only
   rule for this selector that stays in this file is the flex-order rule
   above, under "summary column" (.stw-product__summary .stw-pricing-tiers-wrapper
   { order: 70; }) — it's scoped to this single-product page's buy-box layout
   wrapper, not part of the tier table's own visual styling. */

/* ---------- add to cart ----------------------------------------------------- */

/* Flex row so the button can grow to fill the remaining width next to the
   fixed-width quantity stepper, matching the design — previously the
   quantity/button pair relied on a margin-right spacer with no flex
   context, so the button only ever sized to its own text + padding instead
   of stretching to dominate the row. */
.stw-product__summary form.cart {
  margin-bottom: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 12px;
}

.stw-product__summary form.cart .quantity {
  display: flex;
  align-items: center;
  height: 48px;
  flex: none;
  border: 1px solid var(--stw-grey-300);
  border-radius: var(--stw-radius-pill);
  overflow: hidden;
}

.stw-product__summary form.cart .qty {
  height: 48px;
  width: 44px;
  padding: 0;
  border: 0;
  border-radius: 0;
  text-align: center;
  font-weight: 700;
  background: transparent;
}

/* Stepper buttons flanking the native .qty input — see
   stw2026_product_qty_stepper_minus()/_plus() in
   includes/woocommerce-single-product.php and their wiring in js/custom.js. */
.stw-product__summary form.cart .stw-qty-step {
  width: 36px;
  height: 48px;
  flex: none;
  border: 0;
  background: transparent;
  color: var(--stw-ink);
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: color 0.15s ease;
}

.stw-product__summary form.cart .stw-qty-step:hover,
.stw-product__summary form.cart .stw-qty-step:focus-visible {
  color: var(--stw-pink-600);
}

.stw-product__summary .single_add_to_cart_button {
  flex: 1 1 200px;
  min-height: 48px;
  padding: 0 32px;
  border: 0;
  border-radius: var(--stw-radius-pill);
  background: var(--stw-pink);
  color: #fff;
  font-weight: 800;
  font-size: 1.125rem;
  letter-spacing: 0.01em;
  transition: background 0.15s ease;
}

.stw-product__summary .single_add_to_cart_button:hover,
.stw-product__summary .single_add_to_cart_button:focus {
  background: var(--stw-pink-600);
  color: #fff;
}

/* WooCommerce's own wc_get_stock_html() already renders a `.stock` element
   at the top of the add-to-cart template (add-to-cart/simple.php) — no new
   markup, just a coloured status dot added via ::before and the text
   recoloured off its existing .in-stock / .out-of-stock class. */
.stw-product__summary .stock {
  /* Between the add-to-cart form (100) and the trust block (110) — WC
     renders .stock ahead of the form in the DOM (top of
     add-to-cart/simple.php), but the design wants it read after the CTA. */
  order: 105;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.875rem;
  font-weight: 700;
  margin: 4px 0 0;
}

.stw-product__summary .stock::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: currentColor;
  flex: none;
}

/* Same specificity gap as the .price fix above: WooCommerce's own
   `.woocommerce div.product .stock{color:#958e09}` is 3 classes + 1
   element; the previous 3-class/0-element selector here tied on classes
   and lost on the element tiebreak. Bumped past 3 classes the same way. */
.stw-product-page .entry-summary.stw-product__summary .stock.in-stock {
  color: var(--stw-success);
}

.stw-product-page .entry-summary.stw-product__summary .stock.out-of-stock {
  color: var(--stw-grey-500);
}

/* Subscribe & Save note — editor-owned lc_partial content, see
   stw2026_product_subscribe_note() in includes/woocommerce-single-product.php. */
.stw-product__subscribe {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--stw-grey-100);
  border-radius: var(--stw-radius-md);
  padding: 12px 16px;
  margin-bottom: 4px;
  font-size: 0.84375rem;
  font-weight: 700;
  color: var(--stw-ink);
}

/* Delivery-estimate line, now rendered by stw-delivery-estimator
   (STW_Delivery_Estimator_Frontend::render_product_delivery_info(),
   hooked at the same slot the old stw2026_product_delivery_cutoff() used to
   occupy — see includes/woocommerce-single-product.php). The plugin ships
   no styling of its own for this markup (its frontend.css only covers the
   cart/checkout .stw-delivery-estimate row), so this reproduces the old
   .stw-product__delivery text treatment against the plugin's own class,
   ID-scoped per this file's existing gallery-specificity pattern. */
#stw-single-product .product-delivery-info .delivery-estimate-text {
  font-size: 0.90625rem;
  font-weight: 700;
  color: var(--stw-pink-600);
  margin: 12px 0 0;
}

/* ---------- payment icons ---------------------------------------------------- */

/* Same fixed six-icon set and assets as the basket page
   (woocommerce/cart/cart-totals.php, .stw-trust__payments) — see
   stw2026_product_payment_icons()'s doc comment for why this matches that
   existing precedent. */
/* Specificity note: `.stw-product__trust ul` below (one class + one element)
   outranks a bare `.stw-product__payments` class selector, so without this
   qualified selector the payments list inherits that rule's
   flex-direction: column and stacks vertically instead of wrapping as a row. */
.stw-product__trust .stw-product__payments {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  list-style: none;
  margin: 24px 0 0;
  padding: 0;
}

.stw-product__payments img {
  display: block;
  height: 22px;
  width: auto;
}

/* ---------- trust block ----------------------------------------------------- */

.stw-product__trust {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--stw-grey-200);
  font-size: 0.875rem;
  color: var(--stw-grey-700);
}

.stw-product__trust ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Each reassurance line is a single icon + a short sentence — keep them on
   one row (icon vertically centred against the text, not top-aligned like
   the multi-line key-features ticks above) rather than wrapping icon and
   text onto separate lines. */
.stw-product__trust ul li {
  display: flex;
  align-items: center;
  gap: 11px;
  font-weight: 600;
  color: var(--stw-ink);
}

/* Distinct per-line icon (guarantee / dietician / delivery), not the
   green checkmark tick used by the key-features list above — this block is
   reassurance copy, not a feature checklist, and the design gives each line
   its own icon rather than a repeated tick. */
.stw-product__trust-icon {
  width: 18px;
  height: 18px;
  flex: none;
  color: var(--stw-pink);
}

.stw-product__trust p:last-child {
  margin-bottom: 0;
}

/* ---------- promise strip --------------------------------------------------- */

/* The band's content is fully editor-authored (lc_partial "product-promise-strip",
   seeded on stw-com as one wrapping <div> of 4 card <div>s — see
   stw2026_product_promise_strip()'s doc comment) and expects a flat run of
   blocks, each holding an icon, then an <h3>, then a <p> — no other wrapper
   element inside a card. `#stw-product-promise > div` targets the wrong
   element: the section markup is `<section id="stw-product-promise"><div
   class="container">{partial html}</div></section>`, so the *direct* child
   div of the section is `.container`, not the partial's own wrapping div —
   that's one level deeper. Confirmed live: the grid rule was landing on
   `.container` (a single grid item, so no columns ever appeared) instead of
   the actual 4-card wrapper, rendering the cards as a plain vertical stack
   on every screen size instead of a row on desktop. */
#stw-product-promise > div > div {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

#stw-product-promise > div > div > * {
  padding: 30px 26px;
  border-left: 1px solid var(--stw-grey-200);
  text-align: left;
}

#stw-product-promise > div > div > *:first-child {
  border-left: 0;
}

#stw-product-promise h3 {
  font-size: 1.0625rem;
  font-weight: 800;
  color: var(--stw-ink);
  margin: 14px 0 5px;
}

#stw-product-promise p {
  font-size: 0.875rem;
  color: var(--stw-grey-700);
  line-height: 1.5;
}

#stw-product-promise p:last-child {
  margin-bottom: 0;
}

@media (max-width: 767.98px) {
  #stw-product-promise > div > div > * {
    border-left: 0;
    border-top: 1px solid var(--stw-grey-200);
  }

  #stw-product-promise > div > div > *:first-child {
    border-top: 0;
  }
}

/* ---------- about (two column) ----------------------------------------------- */

/* #stw-product-about doesn't use .stw-product-band__inner's 900px cap — the
   design's two-column layout (label | prose+pills) wants more width than a
   single reading column, so it's centred at a wider max-width of its own. */
#stw-product-about .container {
  max-width: 1240px;
  margin: 0 auto;
}

.stw-product-about {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(28px, 5vw, 88px);
  align-items: flex-start;
}

.stw-product-about__label {
  flex: 0 1 320px;
  min-width: 220px;
}

.stw-product-about__content {
  flex: 1 1 480px;
  min-width: 280px;
}

.stw-product-about__content .stw-product-prose {
  max-width: 70ch;
}

.stw-product-about__pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
}

.stw-product__pill {
  font-size: 0.8125rem;
  font-weight: 700;
  background: #fff;
  border: 1px solid var(--stw-grey-200);
  color: var(--stw-grey-700);
  padding: 7px 14px;
  border-radius: var(--stw-radius-pill);
}

/* ---------- prose ----------------------------------------------------------- */

.stw-product-prose {
  font-size: 1rem;
  line-height: 1.65;
  color: var(--stw-grey-700);
}

.stw-product-prose h2,
.stw-product-prose h3,
.stw-product-prose h4 {
  color: var(--stw-ink);
  font-weight: 700;
  margin: 28px 0 12px;
}

.stw-product-prose h2:first-child,
.stw-product-prose h3:first-child,
.stw-product-prose h4:first-child {
  margin-top: 0;
}

.stw-product-prose ul,
.stw-product-prose ol {
  padding-left: 20px;
  margin-bottom: 16px;
}

.stw-product-prose li {
  margin-bottom: 6px;
}

.stw-product-prose a {
  color: var(--stw-cyan-700);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.stw-product-prose__note {
  margin-top: 16px;
  font-size: 0.875rem;
  color: var(--stw-grey-500);
}

/* ---------- accordion ------------------------------------------------------- */

/* Each panel is its own bordered, rounded white card (matching the FAQ
   band's <details> chevron treatment below) rather than Bootstrap's
   default shared-border, rules-between-rows accordion box. */
.stw-product-accordion {
  --bs-accordion-border-color: var(--stw-grey-200);
  --bs-accordion-border-radius: 14px;
  --bs-accordion-inner-border-radius: 14px;
  --bs-accordion-btn-focus-box-shadow: none;
  --bs-accordion-active-bg: #fff;
  --bs-accordion-active-color: var(--stw-ink);
  --bs-accordion-btn-padding-y: 20px;
  --bs-accordion-btn-padding-x: 24px;
  --bs-accordion-body-padding-x: 24px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.stw-product-accordion .accordion-item {
  border: 1px solid var(--stw-grey-200);
  border-radius: 14px;
  overflow: hidden;
  background: #fff;
}

.stw-product-accordion .accordion-button {
  font-size: 1.0625rem;
  font-weight: 800;
  color: var(--stw-ink);
  background: transparent;
  box-shadow: none;
}

/* Bootstrap's own chevron is a background-image data URI in its own blue —
   dropped in favour of the same diagonal-line chevron the FAQ band uses
   (#stw-product-faq summary::after below), so both disclosure patterns on
   this page read as one visual language. */
.stw-product-accordion .accordion-button::after {
  background-image: none;
  content: "";
  width: 11px;
  height: 11px;
  flex: none;
  border-right: 2px solid var(--stw-grey-500);
  border-bottom: 2px solid var(--stw-grey-500);
  transform: rotate(-45deg);
  transition: transform 200ms ease;
}

.stw-product-accordion .accordion-button:not(.collapsed)::after {
  transform: rotate(45deg);
}

/* ---------- nutrition tables ------------------------------------------------ */

/* Vitamins & minerals can reach six value columns, which overflows a phone.
   The wrapper scrolls rather than the page. */
.stw-product-table__scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.stw-product-table {
  width: 100%;
  min-width: 480px;
  border-collapse: collapse;
  font-size: 0.9375rem;
}

.stw-product-table th,
.stw-product-table td {
  padding: 10px 12px;
  text-align: right;
  border-bottom: 1px solid var(--stw-grey-200);
  white-space: nowrap;
}

.stw-product-table thead th {
  background: var(--stw-cyan-100);
  color: var(--stw-ink);
  font-weight: 700;
  font-size: 0.8125rem;
  line-height: 1.3;
  white-space: normal;
  vertical-align: bottom;
}

/* The row-header column is the only one carrying words, so it's the only one
   left-aligned and allowed to wrap. */
.stw-product-table th:first-child,
.stw-product-table td:first-child {
  text-align: left;
  white-space: normal;
}

.stw-product-table tbody th {
  font-weight: 600;
  color: var(--stw-ink);
}

.stw-product-table tbody tr:nth-child(even) {
  background: var(--stw-grey-50);
}

/* ---------- vitamins & minerals grid ----------------------------------------- */

/* stw2026_product_vitamins_grid() — the one accordion panel with its own
   card-grid-with-bars renderer instead of the generic table above. */
.stw-product-vitamins {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
  gap: 10px;
}

.stw-product-vitamins__card {
  border: 1px solid var(--stw-grey-200);
  border-radius: var(--stw-radius-md);
  padding: 12px 14px;
  background: var(--stw-grey-50);
}

.stw-product-vitamins__name {
  font-size: 0.84375rem;
  font-weight: 700;
  color: var(--stw-ink);
  line-height: 1.3;
}

.stw-product-vitamins__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-top: 6px;
}

.stw-product-vitamins__amount {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--stw-grey-700);
}

.stw-product-vitamins__rda {
  font-size: 0.75rem;
  font-weight: 800;
  color: var(--stw-cyan-700);
  background: var(--stw-cyan-100);
  padding: 3px 8px;
  border-radius: var(--stw-radius-pill);
  white-space: nowrap;
}

.stw-product-vitamins__bar {
  height: 4px;
  border-radius: 999px;
  background: var(--stw-grey-200);
  margin-top: 9px;
  overflow: hidden;
}

.stw-product-vitamins__bar-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--stw-cyan);
}

/* ---------- mixing instructions step cards ----------------------------------- */

/* stw2026_product_instructions_html() — only used when the field's raw
   content is a flat "1. 2. 3." list (see that function's doc comment for why
   this can't be pure CSS on the field's real <ol>-less content). */
.stw-product-instructions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
  margin: 0 0 16px;
  padding: 0;
  list-style: none;
}

.stw-product-instructions__step {
  background: var(--stw-grey-50);
  border-radius: var(--stw-radius-md);
  padding: 16px 18px;
}

.stw-product-instructions__badge {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  background: var(--stw-yellow);
  color: var(--stw-ink);
  font-size: 0.8125rem;
  font-weight: 800;
  margin-bottom: 10px;
}

.stw-product-instructions__text {
  display: block;
  font-size: 0.90625rem;
  font-weight: 600;
  color: var(--stw-grey-700);
  line-height: 1.5;
}

/* ---------- safety / suitability --------------------------------------------- */

/* Editor-authored content (lc_partial "product-safety") — this sets the
   two-column shell (icon+heading | body+CTAs) the design specifies. */
#stw-product-safety .container > div {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(24px, 4vw, 64px);
  align-items: flex-start;
  max-width: 1240px;
  margin: 0 auto;
}

#stw-product-safety h2 {
  font-size: clamp(1.35rem, 2vw, 1.75rem);
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--stw-ink);
}

#stw-product-safety p {
  font-size: 1rem;
  color: var(--stw-grey-700);
  line-height: 1.6;
}

#stw-product-safety a {
  font-weight: 700;
}

/* ---------- reviews --------------------------------------------------------- */

/* Reviews.io-driven band (stw2026_product_reviews(), replacing the old
   comments_template() output — the .woocommerce-Reviews-title /
   .comment-form rules that used to style that native WC form are removed
   below since this band no longer renders it; see that function's doc
   comment for why Reviews.io is now the source of truth here instead. */
#stw-product-reviews .container {
  max-width: 1240px;
  margin: 0 auto;
}

.stw-product-reviews__summary {
  margin-bottom: 28px;
}

.stw-product-reviews__average {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-top: 4px;
}

.stw-product-reviews__average-figure {
  font-size: 2.75rem;
  font-weight: 800;
  color: var(--stw-ink);
  letter-spacing: -0.02em;
}

.stw-product-reviews__average-outof {
  font-size: 1rem;
  font-weight: 600;
  color: var(--stw-grey-500);
}

.stw-product-reviews__stars-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 4px;
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--stw-grey-700);
}

.stw-product-reviews__stars-row .stw-product__stars {
  font-size: 1.1875rem;
}

.stw-product-reviews__badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 14px;
  background: #fff;
  border: 1px solid var(--stw-grey-200);
  border-radius: 999px;
  padding: 7px 14px;
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--stw-ink);
}

.stw-product-reviews__badge svg {
  color: var(--stw-success);
  flex: none;
}

.stw-product-reviews__cta,
.stw-product-reviews__empty-ctas .stw-product-reviews__cta {
  display: inline-flex;
  align-items: center;
  background: #fff;
  border: 2px solid var(--stw-pink);
  color: var(--stw-ink);
  font-size: 0.9375rem;
  font-weight: 800;
  padding: 11px 22px;
  border-radius: 999px;
  margin-top: 18px;
}

.stw-product-reviews__cta:hover {
  background: var(--stw-pink-100);
  color: var(--stw-ink);
}

.stw-product-reviews__cta--solid {
  background: var(--stw-pink);
  border-color: var(--stw-pink);
  color: #fff;
}

.stw-product-reviews__cta--solid:hover {
  background: #fff;
  color: var(--stw-ink);
}

.stw-product-reviews__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
}

.stw-product-reviews__card {
  background: #fff;
  border: 1px solid var(--stw-grey-200);
  border-radius: var(--stw-radius-lg);
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.stw-product-reviews__card .stw-product__stars {
  font-size: 0.9375rem;
}

.stw-product-reviews__body {
  font-size: 0.9375rem;
  color: var(--stw-grey-700);
  line-height: 1.6;
}

.stw-product-reviews__meta {
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--stw-grey-500);
  margin-top: 6px;
}

.stw-product-reviews__all {
  text-align: center;
  margin-top: 26px;
}

.stw-product-reviews__all a,
.stw-product-reviews__link {
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--stw-cyan-700);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.stw-product-reviews__empty {
  max-width: 900px;
  margin: 0 auto;
  background: #fff;
  border: 1px solid var(--stw-grey-200);
  border-radius: var(--stw-radius-lg);
  padding: clamp(28px, 4vw, 44px);
  text-align: center;
}

.stw-product-reviews__empty h2 {
  font-size: clamp(1.4rem, 2.2vw, 1.85rem);
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--stw-ink);
  margin-bottom: 10px;
}

.stw-product-reviews__empty p {
  font-size: 1rem;
  color: var(--stw-grey-700);
  line-height: 1.6;
  max-width: 56ch;
  margin: 0 auto;
}

.stw-product-reviews__empty-ctas {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
  margin-top: 20px;
}

/* ---------- faq -------------------------------------------------------------- */

/* The partial's internal markup is editor-owned (lc_partial "product-faq")
   — this only styles it IF it uses native <details>/<summary> disclosure,
   matching the design's chevron treatment; it can't dictate that structure. */
#stw-product-faq details {
  border-bottom: 1px solid var(--stw-grey-200);
}

#stw-product-faq details:first-of-type {
  border-top: 1px solid var(--stw-grey-200);
}

#stw-product-faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 4px;
  cursor: pointer;
  list-style: none;
  font-size: 1.0625rem;
  font-weight: 700;
  color: var(--stw-ink);
}

#stw-product-faq summary::-webkit-details-marker {
  display: none;
}

#stw-product-faq summary::after {
  content: "";
  flex: none;
  width: 10px;
  height: 10px;
  border-right: 2px solid var(--stw-grey-500);
  border-bottom: 2px solid var(--stw-grey-500);
  transform: rotate(-45deg);
  transition: transform 200ms ease;
}

#stw-product-faq details[open] summary::after {
  transform: rotate(45deg);
}

#stw-product-faq details > p,
#stw-product-faq details > div {
  padding: 0 4px 20px;
  font-size: 0.96875rem;
  color: var(--stw-grey-700);
  line-height: 1.65;
  max-width: 70ch;
}

/* ---------- related products ------------------------------------------------ */

/* The related loop reuses content-product.php, so the markup is the archive's
   .stw-card — but sass/category/_category.scss scopes every card rule under
   #stw-category, which doesn't exist on this page, so they arrive unstyled.
   The card block below is the subset of those rules the related grid needs
   (media, title, price, add control); the interactive quantity stepper isn't
   reproduced because category.js is only enqueued on the archive, so the Add
   control here is the plain WooCommerce AJAX anchor.

   Duplicated rather than shared because de-scoping the category partial would
   change the archive too, and that file has separate work in flight. Worth
   folding into one scope later — see readme.txt. */
.stw-product-page .related.products {
  padding: 48px 0;
  border-top: 1px solid var(--stw-grey-200);
}

.stw-product-page .related.products > h2 {
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  font-weight: 800;
  letter-spacing: -0.01em;
  margin-bottom: 24px;
}

/* What actually made these cards look cramped/broken on mobile wasn't the
   2-up column count — it was WooCommerce's own mobile stylesheet
   (woocommerce-smallscreen.css) forcing each card to 48% width via a
   selector that outranked ours (fixed below, see the specificity note on
   `.stw-product-page .related.products ul.products li.product`). With that
   fixed, cards correctly stretch to fill their grid track again, so a
   genuine 2-up grid is back below 768px. */
.stw-product-page .related.products ul.products {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  list-style: none;
  margin: 0;
  padding: 0;
}

@media (min-width: 768px) {
  .stw-product-page .related.products ul.products {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.stw-product-page .related.products ul.products::before,
.stw-product-page .related.products ul.products::after {
  content: none;
}

/* WooCommerce floats loop items at 22.05% by default, which fights the grid. */
/* Specificity note: WooCommerce's own mobile-only stylesheet
   (woocommerce-smallscreen.css, media="max-width: 768px") carries
   `.woocommerce ul.products[class*=columns-] li.product { width:48%;
   float:left; clear:both; }` — 2 element selectors + 4 classes/attributes,
   which narrowly outranks a bare `.stw-product-page .related.products
   li.product` (1 element + 4 classes: same class count, fewer elements).
   Below 768px that rule was winning, forcing every related-product card to
   48% width with clear:both inside our single-column grid track — each
   card left-aligned in half the row with the other half empty. Repeating
   `ul.products` in the selector here (5 classes + 2 elements) outranks it
   on both axes, on every viewport, not just above 768px. */
.stw-product-page .related.products ul.products li.product {
  float: none;
  clear: none;
  width: auto;
  margin: 0;
  padding: 14px 14px 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  height: 100%;
  border-radius: 18px;
  background: #fff;
  box-shadow: var(--stw-shadow-sm);
}

.stw-product-page .related.products .stw-card__media {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: 10px;
  aspect-ratio: 1 / 1;
}

.stw-product-page .related.products .stw-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.stw-product-page .related.products .stw-card__badge {
  position: absolute;
  top: 12px;
  left: 12px;
  padding: 6px 12px;
  border-radius: var(--stw-radius-pill);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.stw-product-page .related.products .stw-card__title {
  margin: 0;
  font-size: 17px;
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.25;
  text-wrap: pretty;
}

.stw-product-page .related.products .stw-card__title a:hover {
  color: var(--stw-pink-600);
}

.stw-product-page .related.products .stw-card__meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.stw-product-page .related.products .stw-card__price {
  font-size: 19px;
  font-weight: 800;
}

.stw-product-page .related.products .stw-card__price del {
  margin-right: 8px;
  color: var(--stw-grey-500);
  font-size: 15px;
  font-weight: 500;
}

.stw-product-page .related.products .stw-card__price ins {
  color: var(--stw-pink-600);
  text-decoration: none;
}

.stw-product-page .related.products .stw-card__rating {
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.stw-product-page .related.products .stw-card__stars {
  position: relative;
  display: inline-block;
  color: var(--stw-grey-200);
  font-size: 14px;
  letter-spacing: 1.5px;
  line-height: 1;
}

.stw-product-page .related.products .stw-card__stars-fill {
  position: absolute;
  top: 0;
  left: 0;
  overflow: hidden;
  color: var(--stw-star);
  white-space: nowrap;
}

.stw-product-page .related.products .stw-card__reviews {
  color: var(--stw-grey-500);
  font-size: 13px;
  font-weight: 600;
}

.stw-product-page .related.products .stw-card__cart {
  margin-top: auto;
}

.stw-product-page .related.products .stw-card__add {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 12px;
  border: 2px solid var(--stw-pink);
  border-radius: var(--stw-radius-md);
  background: var(--stw-pink);
  color: #fff;
  cursor: pointer;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-align: center;
  text-transform: uppercase;
  white-space: nowrap;
}

.stw-product-page .related.products .stw-card__add:hover {
  background: #fff;
  color: var(--stw-ink);
}

/* The stepper and its "View basket" link are revealed by category.js, which is
   only enqueued on the archive. Without it they would sit there permanently
   expanded, so this grid uses the plain Add anchor alone. */
.stw-product-page .related.products .stw-card__qty,
.stw-product-page .related.products .stw-card__basket,
.stw-product-page .related.products .added_to_cart {
  display: none;
}

.stw-product-page .related.products .stw-card__oos {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 44px;
  padding: 0 14px;
  border-radius: var(--stw-radius-md);
  background: var(--stw-grey-100);
}

.stw-product-page .related.products .stw-card__oos-label {
  color: var(--stw-grey-500);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.stw-product-page .related.products .stw-card__oos-link {
  border-bottom: 2px solid var(--stw-pink);
  color: var(--stw-pink-600);
  font-size: 13px;
  font-weight: 800;
  white-space: nowrap;
}

/* ---------- mobile ---------------------------------------------------------- */

@media (max-width: 991.98px) {
  .stw-product-band {
    padding: 36px 0;
  }

  .stw-product__hero {
    margin-bottom: 0;
  }
}

/* ---------- mobile sticky add-to-cart bar ------------------------------------ */

/* stw2026_product_mobile_bar(), printed on wp_footer. Hidden at the same
   992px breakpoint the sticky summary column switches on at, so exactly one
   of "sticky column" / "sticky bar" is ever active. Bottom padding on the
   page keeps the bar from covering the last band's content below it. */
#stw-mobile-bar {
  display: none;
}

@media (max-width: 991.98px) {
  .stw-product-page {
    padding-bottom: 76px;
  }

  #stw-mobile-bar {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    align-items: center;
    gap: 12px;
    background: #fff;
    border-top: 1px solid var(--stw-grey-200);
    box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.08);
    padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
  }
}

.stw-mobile-bar__price {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 1.25rem;
  font-weight: 800;
  color: var(--stw-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.stw-mobile-bar__price del {
  margin-right: 6px;
  font-size: 1rem;
  font-weight: 600;
  color: var(--stw-grey-500);
}

.stw-mobile-bar__price ins {
  text-decoration: none;
}

/* Quantity stepper, revealed by js/custom.js on the first tap of the CTA
   button below — same ~44px touch targets and --stw-pink treatment as the
   category archive's card stepper (sass/category/_category.scss
   .stw-card__qty), so the two feel like one design system. Unconditional
   display:flex here is safe: the `hidden` attribute's `display:none!important`
   (Bootstrap reboot) always wins over this regardless of load order, same
   pattern the category stepper relies on. */
.stw-mobile-bar__qty {
  display: flex;
  align-items: stretch;
  flex: 0 0 auto;
  height: 44px;
  overflow: hidden;
  border: 2px solid var(--stw-pink);
  border-radius: var(--stw-radius-md);
  background: #fff;
}

.stw-mobile-bar__qty-btn {
  flex: 0 0 44px;
  border: 0;
  background: var(--stw-pink);
  color: #fff;
  cursor: pointer;
  font-size: 20px;
  font-weight: 800;
  line-height: 1;
}

.stw-mobile-bar__qty-btn:hover {
  background: var(--stw-pink-600);
}

.stw-mobile-bar__qty-val {
  display: flex;
  flex: 1 1 auto;
  min-width: 28px;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  font-weight: 800;
}

.stw-mobile-bar__cta {
  flex: 0 0 auto;
  background: var(--stw-pink);
  color: #fff;
  border: 0;
  border-radius: var(--stw-radius-md);
  font-size: 1rem;
  font-weight: 800;
  padding: 13px 26px;
  cursor: pointer;
}

.stw-mobile-bar__cta:hover {
  background: var(--stw-pink-600);
  color: #fff;
}

/* ---------- Mix and Match sticky mobile footer reskin ------------------------ */

/* wc-mnm-mobile-styles plugin's own sticky footer bar (.mnm-mobile-container,
   printed via WC_MNM_Mobile_Styles::attach_hooks()'s wp_footer closure whenever
   a Mix and Match bundle product page loads) previously rendered with the
   plugin's own default plain styling (white bg, thin box-shadow-only edge, a
   default-coloured button, a near-black progress-bar accent via
   var(--wp--preset--color--contrast,#222)) — nothing like this theme's brand —
   and it sits on top of and fully covers #stw-mobile-bar above. Site owner
   decision (2026-08-11): restyle the plugin's bar to match brand rather than
   hide either bar. #stw-mobile-bar's own PHP/markup is untouched, only
   visually covered on the rare page where both would otherwise render — in
   practice a Mix and Match bundle's summary column has no single .quantity
   wrapper for stw2026_product_mobile_bar()'s own JS to attach to, so
   #stw-mobile-bar isn't even printed on these pages (see that function's own
   doc comment) — but z-index is still kept above it here as the documented
   contract for whichever bar is present. The plugin's own !important rules
   already hide the real .single_add_to_cart_button in the underlying
   .mnm_form and substitute this container's own button, so
   .mnm-mobile-container IS the interactive control whenever it's present.

   Every rule below relies on 'wc_mnm_mobile' being listed as a dependency of
   this stylesheet (includes/woocommerce-single-product.php) so it reliably
   wins the cascade on equal selector specificity, rather than depending on
   undocumented hook-priority ordering between the two plugins. No new
   font-family rule is needed: the plugin ships none for this container, and
   body's own Urbanist font-family (sass/_stw-global.scss) already cascades
   into it uncontested. */
.mnm-mobile-container {
  position: fixed;
  bottom: 0;
  z-index: 999;
  border-top: 1px solid var(--stw-grey-200);
  box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.08);
  padding-bottom: calc(1em + env(safe-area-inset-bottom));
}

/* The `button` type selector below is load-bearing, not decorative — found by
   re-checking with Playwright after v2.28.29 shipped: WooCommerce's own
   compiled Bootstrap-alt-button rules in bundle.css already give this button
   a matching --stw-pink background when it's enabled (the "alt" button
   convention here happens to already be brand pink), but the *disabled*
   state a Mix and Match bundle starts in before enough items are selected —
   `.woocommerce button.button.alt.disabled` — ties this rule's class count
   (4 apiece: .mnm-mobile-container/.single_add_to_cart_button/.button/.alt
   vs .woocommerce/.button/.alt/.disabled) and CSS specificity's tie-break
   compares type-selector count next: their rule has one (`button`), v2.28.29's
   fix had none, so it still lost regardless of stylesheet load order — the
   button rendered WooCommerce's pale pink/dark-text disabled tint instead of
   brand pink/white. Adding `button` here matches their type-selector count
   too, so the final tie-break falls to source order, where stw-product.css
   is guaranteed to load after (see the enqueue dependency in
   includes/woocommerce-single-product.php). No !important. */
.mnm-mobile-container button.single_add_to_cart_button.button.alt {
  background: var(--stw-pink);
  color: #fff;
  border: 0;
  border-radius: var(--stw-radius-md);
  font-weight: 800;
}

.mnm-mobile-container button.single_add_to_cart_button.button.alt:hover {
  background: var(--stw-pink-600);
  color: #fff;
}

.mnm-mobile-container .mnm_price,
.mnm-mobile-container .mnm_price .price {
  font-weight: 800;
  color: var(--stw-ink);
}

/* Prominence for the running total itself (2026-08-11) — this bar's .mnm_price
   is the ONLY place a customer sees the live per-product-pricing total change
   as they add pricier bar items (bars cost more per unit than shakes/
   breakfast/meals in this bundle, so the total genuinely moves above the
   advertised baseline price). It sits right next to the Add to Cart button
   in this same fixed bar already (.column.col-1/.col-2 above), so no
   repositioning is needed — only enough visual weight that the number
   changing actually registers.

   Originally written against a broken plugin render (wc-mnm-mobile-styles'
   own .mnm_price component never populated a price on this site — see
   stw2026's CLAUDE.md for the trace) and paired with a js/custom.js
   MutationObserver mirror to compensate. As of v2.28.40 the plugin itself is
   fixed directly (a total→totalPrice key mismatch and a nonexistent
   display_price fallback in its product-price.js) and the mirror has been
   removed as redundant — this rule now styles the plugin's own real render,
   del/ins markup included, with no mirror or marker class involved. See the
   caveat left in js/custom.js: that plugin fix has no git repo backing it,
   so a future plugin update can silently revert it. */
.mnm-mobile-container .mnm_price {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35em;
  background: var(--stw-pink-100);
  border: 1px solid var(--stw-pink);
  border-radius: var(--stw-radius-md);
  padding: 0.35em 0.75em;
}

.mnm-mobile-container .mnm_price:has(.price)::before {
  content: "Bundle total:";
  font-weight: 600;
  color: var(--stw-ink);
}

/* MNM core's own "Total:" word inside .mnm_price (shown only once the price
   differs from the container minimum) duplicates the ::before "Bundle
   total:" label above — hidden rather than styled so it doesn't read as
   "Bundle total: Total: 12.34 €". Was previously scoped to the .stw-mnm-
   mobile-total mirror wrapper (removed in v2.28.40); now applies directly
   to the plugin's own .total span since that's the only one rendered. */
.mnm-mobile-container .mnm_price .total {
  display: none;
}

.mnm-mobile-container .mnm_price del {
  margin-right: 0.35em;
  font-size: 0.85em;
  font-weight: 600;
  color: var(--stw-grey-500);
}

.mnm-mobile-container .mnm_price ins {
  text-decoration: none;
  color: var(--stw-ink);
}

/* Pre-existing bug, unrelated to the price mirror above, found while
   verifying it (2026-08-11): Bootstrap's own grid width utilities
   `.col-1{width:8.33%}` / `.col-2{width:16.67%}` (sass/bootstrap5, loaded
   site-wide) apply to ANY element carrying those class names, and this
   plugin's compiled `mobile-footer.js` uses `class="column col-1"` /
   `"column col-2"` purely as its own positional labels — no Bootstrap
   grid nesting or intent at all. Verified live: this squeezed the
   ENTIRE bar's content column to ~30px and its button column to ~60px on
   a 390px viewport, wrapping the Add to cart button, "Clear selections"
   link and the validation message one word per line — not something this
   session introduced, just not previously visible enough to flag before
   the price mirror gave that squeezed column real content dense enough
   to make the collapse obvious.

   `width: 100%` below the plugin's own 568px breakpoint restores its
   intended single-column mobile stack (`.mnm-mobile-content` is plain
   `display: block` there, so both columns already stack — they just
   weren't allowed to be full width). `width: auto` at that breakpoint
   cancels Bootstrap's percentage so it stops winning as the flex-basis
   (`flex-basis: auto` defers to the `width` property), letting the
   plugin's own `flex-grow: 2` / `flex-grow: 1` rules a few lines up
   determine the proportions they were always meant to. */
.mnm-mobile-container .column.col-1,
.mnm-mobile-container .column.col-2 {
  width: 100%;
}

@media screen and (min-width: 568px) {
  .mnm-mobile-container .column.col-1,
  .mnm-mobile-container .column.col-2 {
    width: auto;
  }
}

.mnm-mobile-container progress.mnm-container-progress[value] {
  accent-color: var(--stw-pink);
}

.mnm-mobile-container progress.mnm-container-progress::-webkit-progress-value {
  background-color: var(--stw-pink);
}

.mnm-mobile-container progress.mnm-container-progress::-moz-progress-bar {
  background-color: var(--stw-pink);
}

/* stw-social-proof's "customer bought" toast (stw-social-proof.php,
   #stw-social-proof) is sitewide, fixed bottom-right (Bootstrap's
   `bottom-0 end-0`, both !important) at z-index 1070 — far above this
   bar's z-index:40 (or z-index:999 on the plugin's own .mnm-mobile-container
   rule). The toast pops up directly on top of this bar's "Add to cart"
   button on every viewport where the bar renders, silently swallowing the
   click/tap: confirmed by a user report of taps doing nothing on Android
   Chrome, isolated to this button, with no JS error candidate found and a
   fresh/incognito reload making no difference. An earlier version of this
   comment claimed desktop was safe on the assumption the add-to-cart button
   always lives in the sticky summary column — wrong specifically for
   Mix & Match bundle pages (e.g. /shop/bundles/build-my-30-day-bundle/),
   where wc-mnm-mobile-styles' sticky footer bar renders at desktop widths
   too, confirmed live via Playwright (bar visible/fixed/bottom:0 at
   1400px, toast's bounding box overlapping the button's, and
   elementFromPoint at the button's centre returning the toast card, not
   the button). Only scoped here (this page's own CSS, loaded only on
   is_product()) rather than changed plugin-wide, since the toast's default
   bottom-right position is fine on every other page type. Pushed above the
   bar instead of lowering the toast's z-index, so the notification stays
   visible (just relocated) rather than silently rendering underneath the
   bar's opaque background.

   Offsets are the bar's own rendered height plus a ~16px gap, measured live
   via Playwright rather than guessed: mobile (max-width: 991.98px) bar
   height ~116px at 390px viewport → 88px offset (pre-existing, unchanged).
   Desktop (min-width: 992px) bar height varies 108px–122px depending on
   viewport width (the bar's internal columns reflow around ~1230px), so
   the desktop rule uses the larger 122px figure + gap to stay clear of the
   button across the whole desktop range rather than adding a second
   breakpoint for a few px of difference. */
@media (max-width: 991.98px) {
  #stw-social-proof {
    bottom: 88px !important;
  }
}

@media (min-width: 992px) {
  #stw-social-proof {
    bottom: 140px !important;
  }
}
