/**
 * Shop Redesign — Product Archive + Single Product
 * -------------------------------------------------
 * Standalone stylesheet enqueued after `roots_css` (main.min.css) on shop,
 * product and product-category pages. Written in plain CSS (no build step is
 * available on this install — see lib/custom/custom-woocommerce.php enqueue).
 *
 * Design tokens mirror the theme's Tailwind config:
 *   dark-purple  #6E3C4C  (primary maroon / buttons)
 *   deep-purple  #381520  (deep maroon / hover)
 *   Lora (serif display), Poppins (body), Miriam Libre (labels)
 */

:root {
  --ssm-maroon:      #6E3C4C;
  --ssm-maroon-dark: #381520;
  --ssm-ribbon:      #b34a78;
  --ssm-ink:         #2b2426;
  --ssm-muted:       #7b7b7b;
  --ssm-line:        #e7e1e3;
  --ssm-panel:       #f4f1f0;
  --ssm-card-radius: 14px;
  --ssm-serif:       'Lora', Georgia, 'Times New Roman', serif;
  --ssm-sans:        'Poppins', -apple-system, BlinkMacSystemFont, sans-serif;
  --ssm-label:       'Miriam Libre', 'Poppins', sans-serif;
}

/* ============================================================= *
 *  PRODUCT CARD  (used on archive grid + related products)
 * ============================================================= */
.ssm-card {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  background: #fff;
  border: 1px solid var(--ssm-line);
  border-radius: var(--ssm-card-radius);
  overflow: hidden;
  transition: box-shadow .25s ease, transform .25s ease;
}
.ssm-card:hover {
  box-shadow: 0 14px 32px -12px rgba(56, 21, 32, .28);
  transform: translateY(-3px);
}

/* Diagonal "On Sale" ribbon */
.ssm-card__media {
  position: relative;
  display: block;
  padding: 1.75rem 1.75rem 0.5rem;
}
.ssm-ribbon {
  position: absolute;
  top: 18px;
  left: -34px;
  z-index: 3;
  width: 130px;
  transform: rotate(-45deg);
  background: var(--ssm-ribbon);
  color: #fff;
  font-family: var(--ssm-label);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  text-align: center;
  line-height: 1;
  padding: 7px 0;
  box-shadow: 0 3px 6px rgba(56, 21, 32, .25);
  pointer-events: none;
}
/* Image box matched to shop.greatskinkc.com (2026-08-04): a 4:5 portrait box
   at the full tile width, rather than the fixed-height strip this used to be.
   Measured on the reference: tile 282 wide, media 282x353 = exactly 4/5.
   A ratio rather than a pixel height means the image scales with the column
   at every breakpoint, and on a square packshot the product now renders ~280px
   instead of 240 — the "bigger image" half of the brief.

   `contain`, NOT the reference's `cover`. The reference shoots to a 4:5 crop;
   this catalogue is square packshots, and a good number of SKUs are Collections
   and Kits with several bottles side by side. `cover` on 4:5 from a square
   source clips ~20% off both sides, which decapitates exactly those wide
   products. `contain` letterboxes instead — invisible here because the page
   and the images are both white. */
.ssm-card__media img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 5;
  height: auto;
  object-fit: contain;
  margin: 0 auto;
  transition: transform .35s ease;
}
.ssm-card:hover .ssm-card__media img { transform: scale(1.04); }

.ssm-card__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 1 1 auto;
  padding: 0.5rem 1.25rem 1.5rem;
  text-align: center;
}
/* Brand line above the title (2026-08-04), matching the reference's vendor
   line. Kept centred to sit with this card's existing centred type — the
   reference left-aligns its whole tile, which is a separate call. */
.ssm-card__brand {
  display: block;
  font-family: var(--ssm-label);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--ssm-muted);
  margin-bottom: 0.45rem;
  line-height: 1.2;
}

.ssm-card__title {
  display: block;
  font-family: var(--ssm-sans);
  font-size: 0.95rem;
  font-weight: 500;
  line-height: 1.4;
  color: var(--ssm-ink);
  margin-bottom: 0.75rem;
  min-height: 2.6em;                 /* reserve 2 lines so prices align */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  transition: color .2s ease;
}
.ssm-card__title:hover { color: var(--ssm-maroon); }

.ssm-card .price,
.ssm-card__price {
  font-family: var(--ssm-serif);
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--ssm-ink) !important;
  margin: 0 0 1.1rem;
  line-height: 1;
}
.ssm-card .price del { opacity: .5; font-size: .8em; margin-right: .4em; font-weight: 400; }
.ssm-card .price ins { text-decoration: none; }

/* Add To Cart — maroon pill, matches theme .primary-btn.
   min-height 44px keeps the card buttons at the minimum comfortable touch
   target on mobile (they measured 41px); flex centres the label inside it. */
.ssm-card .button,
.ssm-btn--cart {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  max-width: 100%;
  min-height: 44px;
  margin: auto 0 0 !important;
  padding: 0.7rem 1.25rem;
  background: var(--ssm-maroon);
  color: #fff;
  border: 1px solid var(--ssm-maroon);
  border-radius: 6px;
  font-family: var(--ssm-label);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background .2s ease, color .2s ease, box-shadow .2s ease;
}
.ssm-card .button:hover,
.ssm-btn--cart:hover {
  background: var(--ssm-maroon-dark);
  border-color: var(--ssm-maroon-dark);
  color: #fff;
  box-shadow: 0 6px 14px -4px rgba(56, 21, 32, .45);
}
.ssm-card .button.loading { opacity: .75; }
.ssm-card .button.added::after { display: none; }
.ssm-card .added_to_cart {
  display: block;
  margin-top: .5rem;
  font-family: var(--ssm-label);
  font-size: 0.625rem;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--ssm-maroon);
}

/* Call to Order button (card) — shares the maroon pill look */
.ssm-btn--call {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  gap: .5rem;
}
.ssm-btn--call .ssm-call-icon { flex: 0 0 auto; }

/* Call to Order (single product) */
.ssm-call-to-order {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .5rem 1rem;
}
.ll-woocommerce.ll-product .ssm-call-to-order__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  min-width: 200px;
  padding: 0 2rem;
  height: 48px;
  background: var(--ssm-maroon);
  color: #fff;
  border: 1px solid var(--ssm-maroon);
  border-radius: 6px;
  font-family: var(--ssm-label);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  text-decoration: none;
  transition: background .2s ease, box-shadow .2s ease;
}
.ll-woocommerce.ll-product .ssm-call-to-order__btn:hover {
  background: var(--ssm-maroon-dark);
  border-color: var(--ssm-maroon-dark);
  color: #fff;
  box-shadow: 0 6px 14px -4px rgba(56, 21, 32, .45);
}
.ssm-call-to-order__num {
  font-family: var(--ssm-serif);
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--ssm-ink);
}

/* ============================================================= *
 *  ARCHIVE — HERO w/ SEARCH
 * ============================================================= */
/* The page has TWO stacked fixed bars but the theme only reserves one.
   `.follow-banner` (the WPCode "Follow Us" snippet, not theme code) is fixed at
   0-70 and pushes `header.navbar` down to 70-150, while `body` keeps
   `padding-top: 80px` — the navbar's height alone. So the first 70px of every
   page sits under the header. On this hero that clipped the top of the eyebrow
   line (it rendered at 144, the navbar ends at 150). Measured identical at
   360-1920: the banner is 70px and never hidden, so one constant covers it.
   Added to the hero's own padding rather than to body, which would move the
   top of every page on the site — a much bigger change than this bug needs.
   The min-height carries the same offset so the VISIBLE hero (below y=150)
   keeps the height it was designed at rather than losing 70px to the header. */
.ssm-shop-hero {
  --ssm-banner-h: 70px;
  position: relative;
  min-height: calc(340px + var(--ssm-banner-h));
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: #fff;
  overflow: hidden;
  padding: calc(4rem + var(--ssm-banner-h)) 1rem 4rem;
}
.ssm-shop-hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.ssm-shop-hero__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
.ssm-shop-hero__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(43,36,38,.35) 0%, rgba(43,36,38,.55) 100%);
}
.ssm-shop-hero__inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 620px;
}
.ssm-shop-hero__eyebrow {
  font-family: var(--ssm-label);
  font-size: 0.6875rem;
  letter-spacing: 3px;
  text-transform: uppercase;
  margin-bottom: 1rem;
  opacity: .92;
}
.ssm-shop-hero__title {
  font-family: var(--ssm-serif);
  font-size: clamp(1.9rem, 5vw, 3.25rem);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 1px;
  line-height: 1.08;
  margin: 0 0 1.75rem;
  color: #fff;
}
.ssm-shop-search {
  display: flex;
  max-width: 480px;
  margin: 0 auto;
  background: #fff;
  border-radius: 6px;
  overflow: hidden;
  box-shadow: 0 10px 30px -10px rgba(0,0,0,.4);
}
.ssm-shop-search input[type="search"],
.ssm-shop-search .search-field {
  flex: 1 1 auto;
  border: 0 !important;
  height: 52px !important;
  padding: 0 1.1rem !important;
  font-family: var(--ssm-sans);
  font-size: 0.95rem;
  color: var(--ssm-ink);
  background: #fff !important;
  border-radius: 0 !important;
}
.ssm-shop-search input[type="search"]:focus { outline: none; }
.ssm-shop-search button[type="submit"] {
  flex: 0 0 auto;
  border: 0;
  padding: 0 1.6rem;
  background: var(--ssm-maroon);
  color: #fff;
  font-family: var(--ssm-label);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .2s ease;
}
.ssm-shop-search button[type="submit"]:hover { background: var(--ssm-maroon-dark); }

/* ============================================================= *
 *  ARCHIVE — CATEGORY NAV + FILTER PILLS
 * ============================================================= */
.ssm-cat-nav {
  border-bottom: 1px solid var(--ssm-line);
  background: #fff;
}
.ssm-cat-nav__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.25rem 1.75rem;
  list-style: none;
  margin: 0 auto;
  padding: 1.1rem 1rem;
  max-width: 1140px;
}
.ssm-cat-nav__list a {
  font-family: var(--ssm-label);
  font-size: 0.7rem;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--ssm-ink);
  text-decoration: none;
  padding: .25rem 0;
  border-bottom: 2px solid transparent;
  transition: color .2s ease, border-color .2s ease;
}
.ssm-cat-nav__list a:hover,
.ssm-cat-nav__list .current a,
.ssm-cat-nav__list li.current-cat a {
  color: var(--ssm-maroon);
  border-bottom-color: var(--ssm-maroon);
}

.ssm-filter-pills {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem;
  margin: 2rem auto 0;
  padding: 0 1rem;
  max-width: 1140px;
}
.ssm-pill {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .45rem 1.1rem;
  border: 1px solid var(--ssm-line);
  border-radius: 999px;
  background: #fff;
  font-family: var(--ssm-label);
  font-size: 0.65rem;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--ssm-muted);
  cursor: default;                    /* visual only for now */
}
.ssm-pill svg, .ssm-pill .chev { width: 9px; height: 9px; opacity: .6; }

/* ============================================================= *
 *  ARCHIVE — PRODUCT GRID + VIEW ALL
 * ============================================================= */
.ssm-shop-grid-wrap {
  max-width: 1160px;
  margin: 0 auto;
  padding: 2.5rem 1rem 3.5rem;
}
.ssm-shop-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.5rem;
}
.ssm-shop-grid .ssm-grid-item.is-hidden { display: none; }

.ssm-viewall-wrap { text-align: center; margin-top: 2.75rem; }
.ssm-viewall {
  display: inline-block;
  padding: 0.85rem 2.75rem;
  background: var(--ssm-maroon);
  color: #fff;
  border: 1px solid var(--ssm-maroon);
  border-radius: 999px;
  font-family: var(--ssm-label);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .2s ease, box-shadow .2s ease;
}
.ssm-viewall:hover {
  background: var(--ssm-maroon-dark);
  box-shadow: 0 8px 18px -6px rgba(56, 21, 32, .5);
}

/* Sold Out ribbon (muted; overrides the pink On Sale ribbon) */
.ssm-ribbon--soldout {
  background: #8a8a8a;
  box-shadow: 0 3px 6px rgba(0, 0, 0, .2);
}

/* ============================================================= *
 *  BREADCRUMB
 * ============================================================= */
.ssm-breadcrumb {
  padding: 1.75rem 0 0;
  font-family: var(--ssm-sans);
  font-size: 0.78rem;
  color: var(--ssm-muted);
}
.ssm-breadcrumb a { color: var(--ssm-muted); text-decoration: none; }
.ssm-breadcrumb a:hover { color: var(--ssm-maroon); }
.ssm-breadcrumb__sep { margin: 0 .5rem; opacity: .5; }
.ssm-breadcrumb__current { color: var(--ssm-ink); }

/* ============================================================= *
 *  FACETED SHOP — SIDEBAR + TOOLBAR + GRID
 * ============================================================= */
.ssm-shop-form { display: block; }

/* Active-filter chips */
.ssm-active-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .55rem;
  margin-bottom: 1.5rem;
}
.ssm-chip {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .4rem .5rem .4rem .9rem;
  background: var(--ssm-panel);
  border: 1px solid var(--ssm-line);
  border-radius: 999px;
  font-family: var(--ssm-sans);
  font-size: 0.78rem;
  color: var(--ssm-ink);
  text-decoration: none;
  transition: border-color .2s ease, color .2s ease;
}
.ssm-chip:hover { border-color: var(--ssm-maroon); color: var(--ssm-maroon); }
.ssm-chip__x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: rgba(56, 21, 32, .12);
  font-size: 0.85rem;
  line-height: 1;
}
.ssm-chip:hover .ssm-chip__x { background: var(--ssm-maroon); color: #fff; }
.ssm-chip-clear {
  font-family: var(--ssm-label);
  font-size: 0.62rem;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ssm-maroon);
  text-decoration: underline;
  margin-left: .25rem;
}

.ssm-shop-layout {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr);
  gap: 2.5rem;
  align-items: start;
}

/* --- Sidebar --- */
.ssm-shop-sidebar { position: relative; }
.ssm-sidebar__head {
  display: flex;
  align-items: baseline;
  gap: .75rem;
  padding-bottom: .9rem;
  margin-bottom: .5rem;
  border-bottom: 2px solid var(--ssm-ink);
}
.ssm-sidebar__title {
  font-family: var(--ssm-serif);
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--ssm-ink);
  margin: 0;
  text-transform: none;
}
.ssm-clear {
  margin-left: auto;
  font-family: var(--ssm-label);
  font-size: 0.6rem;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ssm-maroon);
  text-decoration: underline;
}
.ssm-sidebar__close {
  display: none;
  background: none;
  border: 0;
  font-size: 1.6rem;
  line-height: 1;
  color: var(--ssm-ink);
  cursor: pointer;
  margin-left: .5rem;
}

.ssm-filter-group { border-bottom: 1px solid var(--ssm-line); }
.ssm-filter-group__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 1rem 0;
  background: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  cursor: pointer;
  font-family: var(--ssm-label);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--ssm-ink) !important;
  text-align: left;
}
.ssm-acc-ico { position: relative; width: 12px; height: 12px; flex: 0 0 auto; }
.ssm-acc-ico::before,
.ssm-acc-ico::after { content: ""; position: absolute; background: var(--ssm-ink); }
.ssm-acc-ico::before { top: 5px; left: 0; width: 12px; height: 2px; }
.ssm-acc-ico::after  { top: 0; left: 5px; width: 2px; height: 12px; transition: opacity .2s ease; }
.ssm-filter-group.is-open .ssm-acc-ico::after { opacity: 0; }

.ssm-filter-group__body { padding: 0 0 1rem; }
.ssm-filter-group:not(.is-open) .ssm-filter-group__body { display: none; }

.ssm-check {
  display: flex;
  align-items: center;
  gap: .55rem;
  padding: .35rem 0;
  cursor: pointer;
  font-family: var(--ssm-sans);
  font-size: 0.85rem;
  color: var(--ssm-ink);
}
.ssm-check input { flex: 0 0 auto; accent-color: var(--ssm-maroon); width: 15px; height: 15px; }
.ssm-check__label { flex: 1 1 auto; }
.ssm-count { flex: 0 0 auto; font-size: 0.72rem; color: var(--ssm-muted); }

.ssm-apply {
  display: block;
  width: 100%;
  margin-top: 1.25rem;
  padding: 0.7rem 1rem;
  background: var(--ssm-maroon);
  color: #fff;
  border: 1px solid var(--ssm-maroon);
  border-radius: 6px;
  font-family: var(--ssm-label);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .2s ease;
}
.ssm-apply:hover { background: var(--ssm-maroon-dark); }
.ssm-js .ssm-apply { display: none; }   /* auto-submit when JS is on */

/* --- Main column --- */
.ssm-shop-toolbar {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.75rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--ssm-line);
}
.ssm-result-count {
  margin: 0;
  font-family: var(--ssm-sans);
  font-size: 0.85rem;
  color: var(--ssm-muted);
}
.ssm-sort { display: inline-flex; align-items: center; gap: .5rem; margin-left: auto; }
.ssm-sort__label {
  font-family: var(--ssm-label);
  font-size: 0.62rem;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--ssm-muted);
}
.ssm-sort__select {
  height: 40px !important;
  padding: 0 2rem 0 .9rem !important;
  border: 1px solid var(--ssm-line) !important;
  border-radius: 6px !important;
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='7' viewBox='0 0 10 7'%3E%3Cpath fill='%236E3C4C' d='M0 0l5 6 5-6z'/%3E%3C/svg%3E") no-repeat right .8rem center !important;
  font-family: var(--ssm-sans);
  font-size: 0.82rem;
  color: var(--ssm-ink);
  cursor: pointer;
  appearance: none;
}

.ssm-mobile-filter-toggle {
  display: none;
  align-items: center;
  gap: .45rem;
  padding: .5rem 1rem;
  background: #fff;
  border: 1px solid var(--ssm-ink);
  border-radius: 6px;
  font-family: var(--ssm-label);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--ssm-ink);
  cursor: pointer;
}

.ssm-shop-main .ssm-shop-grid { grid-template-columns: repeat(3, 1fr); }

.ssm-noresults { padding: 3rem 0; text-align: center; }
.ssm-noresults p {
  font-family: var(--ssm-sans);
  color: var(--ssm-muted);
  margin-bottom: 1.25rem;
}

/* ============================================================= *
 *  SINGLE PRODUCT
 * ============================================================= *
 *  Design iteration 2026-07-29 — "wide stage, product floats"
 *  ------------------------------------------------------------
 *  1. The builder container capped the page at 1270px, leaving ~135px of
 *     dead margin each side at 1440. Widened to 1560 for this block only.
 *  2. The product no longer sits in a card. The old treatment stacked three
 *     backgrounds — pale page (#f4f7f7) → blush panel (#f4f1f0) → the photo's
 *     own white — so the product read as double-boxed. The stage is now
 *     white at its centre and dissolves to the exact page colour at its
 *     perimeter, so BOTH edges disappear: the photo's white edge against the
 *     white centre, and the stage's own edge against the page.
 *
 *  NOTE ON THE PHOTOS: every product image is opaque with a hard white
 *  background (sampled: RGB 251–255, alpha 255) — none are cut-outs. That is
 *  why the stage centre must stay white; a tinted panel can never let these
 *  images "float". `mix-blend-mode: multiply` would drop the white without a
 *  white stage, but much of this catalogue is white packaging on white, so it
 *  would dissolve the product too. Deliberately not used.
 * ============================================================= */

/* 1 — reclaim the dead side margins. The shared container steps up in fixed
   jumps (640/768/1024/1270), so it sits narrower than the viewport for most
   of the range above 768 — at 900px it caps at 768 and wastes 66px a side,
   the same complaint as at 1440. One fluid cap replaces all of it for this
   block only, so every other builder page keeps the 1270px measure. */
@media (min-width: 769px) {
  .block--woocommerce-single .container {
    max-width: 1560px;
    padding-left: 40px;
    padding-right: 40px;
  }
}

.ll-woocommerce.ll-product .ssm-single {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 3.5rem;
  align-items: start;
  margin-bottom: 5rem;
}
/* Give the stage the extra width only once there is width to give: at
   769–1024 a 1.5fr split would squeeze the summary to ~296px, well under a
   comfortable measure for the description. */
@media (min-width: 1025px) {
  .ll-woocommerce.ll-product .ssm-single {
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    gap: 5rem;
  }
}

/* 2 — a full-bleed white band behind the product, feathered top and bottom
   into the page tint. This is what actually makes the photos float: a
   gradient painted *inside* the stage can never hide the stage's own straight
   edges, so instead the band spans the full viewport width (no vertical edges
   to see) and dissolves vertically into #f4f7f7 (no horizontal ones either).
   The product then has nothing to sit against.
   Safe to bleed 100vw: .main is overflow:hidden, so it clips rather than
   creating a horizontal scrollbar. */
.ll-woocommerce.ll-product .ssm-single { position: relative; }
.ll-woocommerce.ll-product .ssm-single::before {
  content: "";
  position: absolute;
  z-index: 0;
  top: -3.5rem;
  bottom: -3.5rem;
  left: 50%;
  width: 100vw;
  transform: translateX(-50%);
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0) 0%,
    #ffffff 14%,
    #ffffff 86%,
    rgba(255, 255, 255, 0) 100%
  );
  pointer-events: none;
}
/* z-index alone, deliberately NOT `position: relative`: these are grid items,
   so z-index applies without positioning — and setting position here would
   override the sticky stage below (this selector is more specific). */
.ll-woocommerce.ll-product .ssm-single > * {
  z-index: 1;
}

/* The stage itself carries no background at all — no card, no radius,
   no border. It is purely a centring frame now. */
.ssm-single__media {
  position: relative;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  /* Tight vertical padding on purpose: it removes a band of dead white above
     and below the product, and every pixel saved here becomes sticky travel,
     since a sticky element can only move within its own grid area. */
  padding: 1rem 3rem 2rem;
  border-radius: 0;
  background: transparent;
}
/* The product photo carries its own white field — let it read as the stage.
   No radius and no drop-shadow: the image is an opaque rectangle, so a
   shadow would trace the box we are trying to hide. */
.ssm-single__media img {
  display: block;
  border-radius: 0;
  width: 100%;
  max-width: 560px;
  height: auto;
  /* The gallery wrapper is full-width, so the flex `justify-content: center`
     on the stage centres the wrapper, not the image — centre it here. */
  margin-inline: auto;
}
/* WooCommerce paints this wrapper solid white at exactly the image's width,
   which would re-draw a hard edge inside the wash. */
.ssm-single__media .woocommerce-product-gallery__wrapper,
.ssm-single__media .woocommerce-product-gallery {
  background: transparent;
  width: 100%;
}
.ssm-single__media .onsale { z-index: 3; }

/* 3 — hold the stage in view while the longer summary scrolls.
   Sticky is applied to the MEDIA, not the summary: the summary is the taller
   column (769px vs 557px measured at 1440), and sticky on the taller column
   of a two-column grid has no visible effect. 94px clears the fixed header. */
@media (min-width: 1025px) {
  /* Specificity kept above `.ssm-single > *` so the stacking rule can never
     clobber the sticky positioning again. */
  .ll-woocommerce.ll-product .ssm-single .ssm-single__media {
    position: sticky;
    top: 94px;
  }
}

.ssm-single__summary { padding-top: 1rem; }

.ssm-badge {
  display: inline-block;
  padding: .35rem .9rem;
  margin-bottom: 1rem;
  background: var(--ssm-panel);
  border: 1px solid var(--ssm-line);
  border-radius: 999px;
  font-family: var(--ssm-label);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--ssm-maroon);
}

/* Title renders as a bare <h1> (woocommerce/single-product/title.php override) */
.ll-woocommerce.ll-product .ssm-single__summary h1,
.ll-woocommerce.ll-product .ssm-single__summary .product_title {
  font-family: var(--ssm-serif) !important;
  font-size: clamp(1.8rem, 3vw, 2.5rem) !important;
  font-weight: 500;
  line-height: 1.15;
  text-transform: none !important;
  color: var(--ssm-ink);
  margin-bottom: 1rem !important;
}
.ll-woocommerce.ll-product .ssm-single__summary .woocommerce-product-details__short-description {
  font-family: var(--ssm-sans);
  color: var(--ssm-muted);
  line-height: 1.6;
  margin-bottom: 1.25rem;
}
/* Price renders as <h3 class="price"> (woocommerce/single-product/price.php override) */
.ll-woocommerce.ll-product .ssm-single__summary h3.price,
.ll-woocommerce.ll-product .ssm-single__summary p.price,
.ll-woocommerce.ll-product .ssm-single__summary .price {
  font-family: var(--ssm-serif) !important;
  font-size: 1.9rem !important;
  font-weight: 700;
  color: var(--ssm-ink) !important;
  margin-bottom: 1.5rem !important;
}
/* de-emphasise the category link on single.
   0.75rem (12px) rather than 0.65rem (10.4px): at 2px letter-spacing the
   smaller size was below a legible floor on mobile. */
.ll-woocommerce.ll-product .ssm-single__summary .product_category_title {
  font-family: var(--ssm-label);
  font-size: 0.75rem;
  letter-spacing: 2px;
  color: var(--ssm-muted);
}
.ll-woocommerce.ll-product .ssm-single__summary .product_category_title::after { display: none; }

/* "Back to All Products" — 24px tall as authored; pad out to a 44px touch
   target without moving the text baseline off the existing layout. */
.ll-woocommerce .back--link {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  min-height: 44px;
}

/* Product Ingredients accordion — native <details>/<summary>, no JS.
   The panel is hidden by the browser when closed, so it stays out of the
   accessibility tree and the tab order (and remains openable without JS). */
.ssm-accordion {
  border-top: 1px solid var(--ssm-line);
  border-bottom: 1px solid var(--ssm-line);
  margin-bottom: 1.75rem;
}
/* Strip the default disclosure triangle (we draw our own +/- icon). */
.ssm-accordion__trigger { list-style: none; }
.ssm-accordion__trigger::-webkit-details-marker { display: none; }
.ssm-accordion__trigger::marker { content: ""; }
/* High specificity + resets so the theme's global button styles
   (uppercase, letter-spacing, border, bg, max-width) don't leak in. */
.ll-woocommerce.ll-product .ssm-accordion__trigger,
.ssm-accordion__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  max-width: none;
  margin: 0;
  padding: 1.1rem 0;
  background: transparent !important;
  background-color: transparent !important;
  background-image: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  cursor: pointer;
  font-family: var(--ssm-sans);
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ssm-ink) !important;
  text-align: left;
}
.ll-woocommerce.ll-product .ssm-accordion__trigger:hover {
  background: transparent !important;
  box-shadow: none !important;
  transform: none !important;
  color: var(--ssm-maroon) !important;
}
.ssm-accordion__trigger .ssm-accordion__icon {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  position: relative;
  transition: transform .25s ease;
}
.ssm-accordion__trigger .ssm-accordion__icon::before,
.ssm-accordion__trigger .ssm-accordion__icon::after {
  content: "";
  position: absolute;
  background: var(--ssm-ink);
}
.ssm-accordion__trigger .ssm-accordion__icon::before { top: 6px; left: 0; width: 14px; height: 2px; }
.ssm-accordion__trigger .ssm-accordion__icon::after  { top: 0; left: 6px; width: 2px; height: 14px; transition: opacity .25s ease; }
.ssm-accordion[open] .ssm-accordion__icon::after { opacity: 0; }

.ssm-accordion__panel-inner {
  padding: 0 0 1.25rem;
  font-family: var(--ssm-sans);
  color: var(--ssm-muted);
  line-height: 1.7;
}
.ssm-accordion__panel-inner p { margin-bottom: 1rem; }

/* Quantity + Add to cart row */
.ll-woocommerce.ll-product form.cart {
  display: flex;
  align-items: stretch;
  gap: .75rem;
  flex-wrap: wrap;
}
.ll-woocommerce.ll-product form.cart div.quantity {
  display: flex;
  align-items: center;
  border: 1px solid var(--ssm-line);
  border-radius: 6px;
  overflow: hidden;
}
.ll-woocommerce.ll-product form.cart .qty {
  width: 56px;
  height: 48px !important;
  border: 0 !important;
  text-align: center;
  font-family: var(--ssm-sans);
}
.ll-woocommerce.ll-product form.cart button.btn,
.ll-woocommerce.ll-product form.cart button[type="submit"] {
  flex: 1 1 auto;
  min-width: 180px;
  padding: 0 2rem;
  height: 48px;
  background: var(--ssm-maroon);
  color: #fff;
  border: 1px solid var(--ssm-maroon);
  border-radius: 6px;
  font-family: var(--ssm-label);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .2s ease, box-shadow .2s ease;
}
.ll-woocommerce.ll-product form.cart button.btn:hover,
.ll-woocommerce.ll-product form.cart button[type="submit"]:hover {
  background: var(--ssm-maroon-dark);
  border-color: var(--ssm-maroon-dark);
  box-shadow: 0 6px 14px -4px rgba(56, 21, 32, .45);
}

/* ============================================================= *
 *  RELATED PRODUCTS (grid, not slider)
 * ============================================================= */
.ssm-related__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.5rem;
}
.ll-woocommerce .related-products--section .header--flex h2,
.ssm-related__heading {
  text-align: center;
}

/* ============================================================= *
 *  CATEGORY ARCHIVE — WooCommerce default loop -> grid
 *  (taxonomy-product_cat.php renders ul.products li.product)
 * ============================================================= */
.ll-woocommerce.ll-shop ul.products {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.5rem;
  margin: 2.5rem 0 0;
  padding: 0;
  list-style: none;
}
.ll-woocommerce.ll-shop ul.products::before,
.ll-woocommerce.ll-shop ul.products::after { display: none; }
.ll-woocommerce.ll-shop ul.products li.product {
  width: auto !important;
  margin: 0 !important;
  padding: 0 !important;
  float: none !important;
}

/* ============================================================= *
 *  RESPONSIVE — faceted shop layout + mobile filter drawer
 * ============================================================= */
@media (max-width: 1024px) {
  .ssm-shop-layout { grid-template-columns: 210px minmax(0, 1fr); gap: 1.75rem; }
  .ssm-shop-main .ssm-shop-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
  /* minmax(0, 1fr) rather than 1fr: a bare `1fr` track is minmax(auto, 1fr),
     so it cannot shrink below its content's min-content width. The toolbar's
     min-content was 399px, which forced this column — and therefore every
     product card — to render 399px wide inside a 358px container: 25px was
     clipped off the right by .main{overflow:hidden} and the cards' contents
     sat ~20px right of the screen centre, reading as "off-centre" on mobile.
     minmax(0, …) keeps the column tied to the container regardless of what
     any future child reports as its minimum. */
  .ssm-shop-layout { grid-template-columns: minmax(0, 1fr); }

  /* …and let the toolbar actually reflow, so its content is laid out rather
     than merely clipped. Filters + result count share line one; the sort
     control takes line two at full width. Each item needs min-width:0 to
     override the flex default of min-width:auto. */
  .ssm-shop-toolbar { flex-wrap: wrap; row-gap: .85rem; }
  .ssm-shop-toolbar > * { min-width: 0; }
  .ssm-sort { flex: 1 1 100%; margin-left: 0; }
  .ssm-sort__select { flex: 1 1 auto; min-width: 0; max-width: 100%; }

  .ssm-mobile-filter-toggle { display: inline-flex; }
  .ssm-sidebar__close { display: block; margin-left: auto; }
  .ssm-sidebar__head { align-items: center; }
  .ssm-shop-sidebar {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    z-index: 300;
    width: 320px;
    max-width: 86vw;
    padding: 1.5rem 1.25rem;
    background: #fff;
    overflow-y: auto;
    transform: translateX(-100%);
    transition: transform .3s ease;
    box-shadow: 0 0 40px rgba(0, 0, 0, .25);
  }
  .ssm-shop-sidebar.is-open { transform: none; }
  .ssm-shop-main .ssm-shop-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 480px) {
  .ssm-shop-main .ssm-shop-grid { grid-template-columns: 1fr; }
}

/* ============================================================= *
 *  WIDE SHOP  (2026-07-31)
 * ============================================================= *
 *  .ssm-shop-grid-wrap capped the sidebar + grid at 1160px, so on a wide
 *  monitor the filters floated in from the left edge and the grid stopped
 *  well short of the right. Same complaint — and the same fix — as the
 *  single product page: one fluid cap at 1560, matching
 *  .block--woocommerce-single so shop → product keep a shared measure.
 *
 *  Two thresholds, both chosen so nothing gets NARROWER than it is today.
 *  Both are measured against the 838px main column the old 1160 cap yields:
 *
 *  1240 — where the cap lifts. The wider 40px gutter costs 48px against the
 *  old 1rem one, so lifting the cap too early takes away more than it gives
 *  back. Break-even is a 1208 viewport (838 = vw − 80 − 250 − 40); 1240 as
 *  the query clears it with the ~15px classic scrollbar in play. Measured:
 *  main 838 at 1239, 855 at 1240. Every width above only gains.
 *
 *  1500 — where the 4th column arrives. Cards are 261px here, matching the
 *  263px the 3-up cards render at 1270 today, so the 220px product image
 *  keeps its proportion inside the card. Adding the column any earlier
 *  shrinks them: at 1440 a 4-up card is 249px and the image starts to look
 *  stranded. Between 1240 and 1500 the layout stays 3-up and breathes wider.
 * ============================================================= */
@media (min-width: 1240px) {
  .ssm-shop-grid-wrap {
    /* 2026-07-31: cap removed. At 1560 a ~2000px monitor still wasted 220px a
       side, which is exactly the dead space the sidebar was meant to move into.
       Now edge-to-edge on a 40px gutter, so the filters sit as far left as the
       page allows and every reclaimed pixel goes to the grid.
       NOTE: this deliberately breaks the shared measure with the single
       product page, which stays capped at 1560 (.block--woocommerce-single) —
       a 2-column PDP has nothing useful to do with 2000px, whereas the grid
       does. Shop is now wider than PDP by design. */
    max-width: none;
    padding-left: 40px;
    padding-right: 40px;
  }
}

/* Column count scales with the room actually available, so cards stay in a
   ~265-310px band instead of stretching. Each rule is 0,2,0 and ordered so the
   widest wins where several match. Measured card widths (sidebar 250 + 2.5rem
   gap + 40px gutters + 1.5rem grid gap):
     1500  4-up  265      1800  5-up  267      2300  6-up  285
     1600  4-up  283      1920  5-up  290      2560  6-up  328
     1720  4-up  313      2000  5-up  307
   Thresholds sit where the next column would otherwise start stretching past
   ~310px; crossing one drops card width but never below the 263px the 3-up
   grid rendered at 1270 before any of this work. */
@media (min-width: 1500px) {
  .ssm-shop-main .ssm-shop-grid { grid-template-columns: repeat(4, 1fr); }
}
@media (min-width: 1800px) {
  .ssm-shop-main .ssm-shop-grid { grid-template-columns: repeat(5, 1fr); }
}
@media (min-width: 2300px) {
  .ssm-shop-main .ssm-shop-grid { grid-template-columns: repeat(6, 1fr); }
}

/* ============================================================= *
 *  RESPONSIVE
 * ============================================================= */
@media (max-width: 1024px) {
  .ll-woocommerce.ll-shop ul.products { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 768px) {
  .ll-woocommerce.ll-shop ul.products { grid-template-columns: repeat(2, 1fr); gap: 1rem; }
}
@media (max-width: 480px) {
  .ll-woocommerce.ll-shop ul.products { grid-template-columns: 1fr; }
}

@media (max-width: 1024px) {
  .ssm-shop-grid,
  .ssm-related__grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 1024px) {
  /* Stage keeps the wash but loses the generous padding once space is tight. */
  .ssm-single__media { padding: 2.75rem 1.5rem; }
}
@media (max-width: 768px) {
  .ssm-shop-grid,
  .ssm-related__grid { grid-template-columns: repeat(2, 1fr); gap: 1rem; }
  .ll-woocommerce.ll-product .ssm-single {
    /* minmax(0,…) not a bare 1fr. A bare `1fr` is minmax(auto,1fr) and cannot
       shrink below its content's min-content width — once the gallery has more
       than one image, flexslider lays the slides out in an 11200px-wide list
       and this column was blown out to 608px inside a 320px page, clipped
       silently by .main{overflow:hidden}. Same failure as the shop toolbar. */
    grid-template-columns: minmax(0, 1fr);
    gap: 2rem;
  }
  /* superseded by the 4:5 aspect-ratio on the base rule (2026-08-04) — a fixed
     height here would flatten the box back to a strip on mobile */
  /* same fixed-header offset as the base rule, or the shorter mobile hero
     gives back the 70px it just reserved */
  .ssm-shop-hero { min-height: calc(280px + var(--ssm-banner-h)); }
}
@media (max-width: 480px) {
  .ssm-shop-grid,
  .ssm-related__grid { grid-template-columns: 1fr; }
  .ssm-single__media { padding: 1.5rem; }
  .ll-woocommerce.ll-product form.cart button.btn { min-width: 0; }
}

/* ============================================================= *
 *  CART / CHECKOUT / ORDER RECEIVED  (eshop flow, brand polish)
 * ============================================================= */
.ll-woocommerce.ll-cart,
.ll-woocommerce.ll-checkout,
.ll-woocommerce.ll-thank-you,
.ll-woocommerce.ll-account-page,
.ll-woocommerce.ll-account-login {
  max-width: 1140px;
  margin-left: auto;
  margin-right: auto;
  padding: 0 1rem 4rem;
  font-family: var(--ssm-sans);
  color: var(--ssm-ink);
}
.ll-woocommerce.ll-cart h1,
.ll-woocommerce.ll-checkout h1,
.ll-woocommerce.ll-thank-you h1 {
  font-family: var(--ssm-serif);
  color: var(--ssm-ink);
}

/* Primary buttons across the flow → brand maroon */
.woocommerce .wc-proceed-to-checkout a.checkout-button,
.woocommerce #payment #place_order,
.woocommerce-cart .actions .button,
.woocommerce-checkout .button.alt,
.woocommerce .button.alt {
  background: var(--ssm-maroon) !important;
  color: #fff !important;
  border: 1px solid var(--ssm-maroon) !important;
  border-radius: 6px !important;
  font-family: var(--ssm-label) !important;
  font-size: 0.72rem !important;
  font-weight: 700 !important;
  letter-spacing: 2px !important;
  text-transform: uppercase !important;
  padding: 0.85rem 1.75rem !important;
  transition: background .2s ease, box-shadow .2s ease !important;
}
.woocommerce .wc-proceed-to-checkout a.checkout-button:hover,
.woocommerce #payment #place_order:hover,
.woocommerce-checkout .button.alt:hover,
.woocommerce .button.alt:hover {
  background: var(--ssm-maroon-dark) !important;
  border-color: var(--ssm-maroon-dark) !important;
  box-shadow: 0 6px 14px -4px rgba(56, 21, 32, .45) !important;
}
.woocommerce #payment #place_order { width: 100%; }

/* Secondary buttons (Update cart, Apply coupon) → outlined maroon */
.woocommerce-cart .actions .button[name="update_cart"],
.woocommerce form.woocommerce-cart-form .coupon .button {
  background: #fff !important;
  color: var(--ssm-maroon) !important;
  border: 1px solid var(--ssm-line) !important;
}

/* Cart table */
.woocommerce table.shop_table {
  border: 1px solid var(--ssm-line);
  border-radius: 12px;
  overflow: hidden;
  border-collapse: separate;
}
.woocommerce table.shop_table th {
  font-family: var(--ssm-label);
  font-size: 0.66rem;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--ssm-muted);
  background: var(--ssm-panel);
  padding: 1rem;
}
.woocommerce table.shop_table td { padding: 1.1rem 1rem; border-top: 1px solid var(--ssm-line); }
.woocommerce table.shop_table .product-name a { color: var(--ssm-ink); font-weight: 500; text-decoration: none; }
.woocommerce table.shop_table .product-name a:hover { color: var(--ssm-maroon); }
.woocommerce a.remove {
  color: var(--ssm-maroon) !important;
  border: 1px solid var(--ssm-line);
  font-weight: 400;
}
.woocommerce a.remove:hover { background: var(--ssm-maroon) !important; color: #fff !important; }
.woocommerce .quantity .qty {
  border: 1px solid var(--ssm-line);
  border-radius: 6px;
  padding: .4rem;
  font-family: var(--ssm-sans);
}

/* Cart totals + checkout order review boxes */
.woocommerce .cart_totals,
.woocommerce-checkout #order_review,
.woocommerce .cart-collaterals .cross-sells { font-family: var(--ssm-sans); }
.woocommerce-checkout #order_review {
  background: var(--ssm-panel);
  border: 1px solid var(--ssm-line);
  border-radius: 12px;
  padding: 1.5rem;
}
.woocommerce .cart_totals h2,
.woocommerce-checkout #order_review_heading,
.woocommerce-checkout h3#ship-to-different-address,
.woocommerce-billing-fields h3,
.woocommerce-shipping-fields h3 {
  font-family: var(--ssm-serif);
  font-weight: 600;
  color: var(--ssm-ink);
}
.woocommerce-checkout #order_review .order-total .amount { color: var(--ssm-maroon); }

/* Checkout form fields */
.woocommerce form .form-row input.input-text,
.woocommerce form .form-row textarea,
.woocommerce form .form-row select,
.woocommerce-checkout .select2-container .select2-selection {
  border: 1px solid var(--ssm-line) !important;
  border-radius: 6px !important;
  padding: .7rem .9rem !important;
  min-height: 46px;
  font-family: var(--ssm-sans);
  background: #fff;
}
.woocommerce form .form-row label { font-size: .82rem; color: var(--ssm-ink); }
.woocommerce .woocommerce-input-wrapper { width: 100%; }

/* Payment box */
.woocommerce-checkout #payment {
  background: transparent;
  border-radius: 12px;
}
.woocommerce-checkout #payment ul.payment_methods {
  border: 1px solid var(--ssm-line);
  border-radius: 12px;
  background: #fff;
}
.woocommerce-checkout #payment div.payment_box {
  background: var(--ssm-panel);
  color: var(--ssm-ink);
}
.woocommerce-checkout #payment div.payment_box::before { border-bottom-color: var(--ssm-panel); }

/* Notices */
.woocommerce-message,
.woocommerce-info { border-top-color: var(--ssm-maroon) !important; }
.woocommerce-message::before,
.woocommerce-info::before { color: var(--ssm-maroon) !important; }

/* Order received / thank-you */
.woocommerce ul.order_details {
  background: var(--ssm-panel);
  border: 1px solid var(--ssm-line);
  border-radius: 12px;
  padding: 1.5rem;
}
.woocommerce ul.order_details li { border-right-color: var(--ssm-line); }
.woocommerce ul.order_details li strong { color: var(--ssm-ink); }

@media (max-width: 768px) {
  .woocommerce #payment #place_order,
  .woocommerce .wc-proceed-to-checkout a.checkout-button { width: 100%; text-align: center; }

  /* ------------------------------------------------------------------ *
   *  Cart / checkout — mobile fit
   * ------------------------------------------------------------------
   *  Measured at 390px: the cart table rendered 430px wide inside a 290px
   *  column and the overflow was CLIPPED by .main{overflow:hidden} (the
   *  document never became scrollable), so product names were truncated and
   *  every price, subtotal, quantity box, remove ✕ and "Apply Coupon" sat
   *  off-screen and unreachable.
   *
   *  Two compounding causes, both addressed below:
   *   1. The builder's .container keeps 50px gutters at every width — 100px
   *      of a 390px screen, leaving 290px.
   *   2. td.actions had a 426px min-content, driven entirely by the coupon
   *      row: label (67px) + input (121px) + button (170px) laid out with
   *      flex-wrap:nowrap and the default min-width:auto, so nothing could
   *      shrink.
   * ------------------------------------------------------------------ */

  /* 25px exactly matches the .row (-25px) / .col (+25px) gutter pair, so
     reclaiming this space introduces no residual overflow of its own.
     Scoped inside .main so the shared header/footer keep their own spacing. */
  body.woocommerce-cart .main .container,
  body.woocommerce-checkout .main .container {
    padding-left: 25px;
    padding-right: 25px;
  }

  /* Let the coupon row wrap: input takes the remaining space on line one,
     the button drops to its own full-width line. */
  .woocommerce form.woocommerce-cart-form .coupon {
    flex-wrap: wrap;
    gap: .5rem;
  }
  .woocommerce form.woocommerce-cart-form .coupon label { flex: 0 0 auto; }
  .woocommerce form.woocommerce-cart-form .coupon input#coupon_code,
  .woocommerce form.woocommerce-cart-form .coupon .input-text {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
  }
  .woocommerce form.woocommerce-cart-form .coupon .button {
    flex: 1 0 100%;
    min-width: 0;
  }

  /* Full-width action buttons read better on a phone. */
  .woocommerce-cart .actions .button,
  .woocommerce-cart .actions .button[name="update_cart"] { width: 100%; }

  /* Safety net: should any future content (a long product name, a wider
     currency string) still exceed the column, let the table scroll rather
     than be silently clipped by .main{overflow:hidden}. */
  .woocommerce form.woocommerce-cart-form {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* ============================================================= *
 *  BORDERLESS PRODUCT TILES  (2026-07-31)
 * ============================================================= *
 *  Reference: shop.greatskinkc.com — products sit straight on a white page,
 *  no card, no border, no radius, no shadow.
 *
 *  Dropping the card is only half of it. The reason the reference reads as
 *  "floating" is that its body is #fff and its packshots are white-cornered,
 *  so each photo's own edge has nothing to contrast against. Our page is
 *  #f4f7f7 (painted on SECTION.ll-woocommerce.ll-shop), so a borderless tile
 *  on its own would just trade a soft rounded white card for a hard-edged
 *  white rectangle — strictly worse. The band below is what does the work;
 *  same conclusion .ssm-single reached on the product page.
 *
 *  Catalogue check (all 145 featured images sampled by corner alpha/colour,
 *  2026-07-29):
 *    42 (29%)  transparent PNGs, shadows baked in ... float perfectly
 *    85 (59%)  opaque, corners >= RGB 246 .......... float cleanly on white
 *    18 (12%)  opaque, corners NOT white ........... soft rectangle remains
 *  So 127/145 read as intended. The remaining 18 are mostly the Omnilux
 *  .webp files (corners RGB 217–232). The reference has the identical
 *  failure mode — its ALASTIN tile shows a grey box for exactly this reason
 *  — so this is the ceiling of the approach, not a defect in the build.
 *  A real fix means re-cutting those 18 images, not more CSS.
 *
 *  NOT used: mix-blend-mode:multiply. It is the usual "drop the white
 *  background" trick, but much of this catalogue is white packaging shot on
 *  white, so it dissolves the product along with its background.
 * ============================================================= */

/* The white band. Painted on the WooCommerce page wrapper rather than the
   inner .block, because `.ll-woocommerce { background:#f4f7f7; padding-top:
   5rem }` would otherwise leave an 80px pale strip above the white — a seam
   right under the hero. The wrapper is edge-to-edge, so a plain background
   is enough; no 100vw bleed trick needed, unlike .ssm-single which sits
   inside a centred .container. 0,2,0 beats the theme's 0,1,0 rule, so no
   !important. `.ll-shop` is emitted for the main shop AND for category/tag
   archives (my_theme_wrapper_start), so all three match; the single product
   page is `.ll-product` and keeps its pale surround. */
.ll-woocommerce.ll-shop { background: #fff; }

/* ---- Vertical rhythm below the hero (2026-07-31) -------------------------
   348px sat between the hero and the first product card, 244px of it stacked
   padding that nothing was deliberately asking for:
     80  .ll-woocommerce padding-top (theme, 5rem)
     40  breadcrumb wrap padding-top
     28  .ssm-breadcrumb own padding-top
     56  breadcrumb wrap padding-BOTTOM
     40  layout wrap padding-top
   The 56+40 pair is the real culprit — shop-body.php emits TWO sibling
   `.ssm-shop-grid-wrap` blocks (breadcrumb, then the form holding the grid) and
   the shared rule charges each one a full 2.5rem/3.5rem, so the gap between
   breadcrumb and filters was paying for both. Split by context rather than
   loosening the shared rule, which the grid still needs for its bottom margin.
   Now 87px hero → filters, all of it intentional. Horizontal padding is set
   with longhands so the ≥1240 40px-gutter rule is left alone. */
.ll-woocommerce.ll-shop { padding-top: 0; }

.ll-shop-redesign > .ssm-shop-grid-wrap {   /* breadcrumb strip */
  padding-top: 40px;
  padding-bottom: 0;
}
.ssm-breadcrumb { padding: 0; }

.ssm-shop-form > .ssm-shop-grid-wrap {      /* sidebar + toolbar + grid */
  padding-top: 28px;
}

/* Selector must be `article.ssm-card`, not `.ssm-card`.
   assets/css/new-header.css:218 carries a legacy
   `.block--woocommerce article { background:#fff; padding:20px; overflow:hidden }`
   at 0,1,1 which outranks a bare `.ssm-card` at 0,1,0 — so a plain
   `background: transparent` here silently loses and the tile stays white.
   That is invisible on the archive (white band behind it) but showed up
   immediately on the product page, where the related tiles kept painting
   white cards on the pale surround. 0,2,1 settles it without !important.
   The same legacy rule is also why every card has carried an undocumented
   20px inset and an overflow:hidden all along — both cleared here. */
.block--woocommerce article.ssm-card {
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 0;
  overflow: visible;                 /* nothing left to clip */
}
/* A lift-and-shadow hover implies a card edge to lift. Without one it just
   makes the product jitter, so the hover is now carried entirely by the
   image scale + title colour that were already defined above. */
.block--woocommerce article.ssm-card:hover { transform: none; box-shadow: none; }

/* Reclaim the padding that only existed to inset content from the card edge.
   The 1.5rem grid gap is what separates products now. */
.ssm-card__media { padding: 0 0 1rem; }
.ssm-card__body  { padding: 0 0 0.25rem; }

/* With the inset gone there is room for the product itself to grow. Gated at
   769 so it cannot override the 180px mobile height set further up. */
@media (min-width: 769px) {
  /* superseded by the 4:5 aspect-ratio on the base rule (2026-08-04) */
}

/* The sale flag was a rotated banner bled off the corner and clipped by the
   card's overflow:hidden — with no card it would hang in mid-air. Reduced to
   a plain uppercase label. It sits over the top-left of the image box, which
   is dead space on these packshots (square product centred in a wider box),
   and the struck-through price already carries the same message. */
.ssm-ribbon {
  top: 0;
  left: 0;
  width: auto;
  padding: 0;
  transform: none;
  background: none;
  box-shadow: none;
  color: var(--ssm-maroon);
  text-align: left;
}
.ssm-ribbon--soldout { color: var(--ssm-muted); }

/* Related products on the single product page share .ssm-card, so they go
   borderless too — which closes the "related products still look like cards"
   mismatch left open on 2026-07-29. They sit inside a centred .container on
   the pale page, so unlike the archive they DO need the 100vw bleed to get a
   white band. Safe because .main is overflow:hidden (verified: no horizontal
   scrollbar). Children are lifted with position+z-index rather than z-index
   alone, which does nothing on a static block — no sticky in this subtree,
   so the trap .ssm-single hit does not apply here. */
.related-products--section { position: relative; }
.related-products--section::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 100vw;
  transform: translateX(-50%);
  /* Solid through the middle, feathered at top and bottom. A hard-edged
     white block on the pale page would just be a bigger card — the whole
     thing this change is trying to get rid of. 100vw kills the vertical
     edges, the gradient kills the horizontal ones. Same reasoning as
     .ssm-single::before above. */
  background: linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0) 0,
    #fff 72px,
    #fff calc(100% - 72px),
    rgba(255, 255, 255, 0) 100%
  );
  z-index: 0;
}
.related-products--section > * {
  position: relative;
  z-index: 1;
}

/* ============================================================= *
 *  PRODUCT GALLERY — THUMBNAIL RAIL  (2026-08-03)
 * ============================================================= *
 *  Additional product images as a sliding rail under the main image.
 *
 *  No new JS. WooCommerce already declares `wc-product-gallery-slider` +
 *  `-lightbox`, so flexslider and PhotoSwipe are ALREADY being downloaded on
 *  every product page whether or not anything uses them — it builds the
 *  slider, syncs the active slide and emits `ol.flex-control-thumbs` with a
 *  `.flex-active` class on the current thumb. All that was missing is CSS:
 *  the theme doesn't load WooCommerce's own gallery stylesheet, so the rail
 *  was rendering as a stack of full-width 744x560 images (measured) below the
 *  product. Adding a second slider library here would have shipped a third
 *  gallery script for no gain.
 *
 *  The rail scrolls rather than shrinking, so it stays a usable "slider bar"
 *  no matter how many images a product has.
 * ============================================================= */
/* The theme never loads WooCommerce's own gallery stylesheet, so flexslider
   runs without the layout rules it assumes. Its viewport has no overflow
   clipping of its own, which let the slide list (measured 11200px across 10
   images) set the column's min-content width. These three lines are the
   minimum of that missing stylesheet needed here — everything visual is
   handled below. `min-width: 0` lets the media column shrink as a flex/grid
   child regardless of what the slider reports as its intrinsic size. */
.ssm-single__media { min-width: 0; }
.ssm-single__media .woocommerce-product-gallery { width: 100%; max-width: 100%; }
.ssm-single__media .flex-viewport { overflow: hidden; max-width: 100%; }

.ssm-single__media .flex-control-thumbs {
  display: flex;
  gap: 0.625rem;
  max-width: 560px;                  /* line up with the main image cap */
  margin: 1.25rem auto 0;
  padding: 0 0 0.25rem;
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}
/* A rail of one is just the main image again. :has() rather than a PHP body
   class so it stays correct if the gallery is ever filtered at runtime. */
.ssm-single__media .flex-control-thumbs:not(:has(li:nth-child(2))) { display: none; }

.ssm-single__media .flex-control-thumbs li {
  flex: 0 0 72px;
  margin: 0;
  scroll-snap-align: start;
}
/* Beats `.ssm-single__media img { max-width:560px }` on specificity (0,3,1 vs
   0,1,1), so the rail is unaffected by the main image's sizing. */
.ssm-single__media .flex-control-thumbs img {
  display: block;
  width: 72px;
  height: 72px;
  object-fit: contain;
  margin: 0;
  padding: 2px;
  background: #fff;
  border: 1px solid var(--ssm-line);
  border-radius: 4px;
  opacity: .55;
  cursor: pointer;
  transition: opacity .2s ease, border-color .2s ease;
}
.ssm-single__media .flex-control-thumbs img:hover { opacity: .85; }
.ssm-single__media .flex-control-thumbs img.flex-active {
  opacity: 1;
  border-color: var(--ssm-maroon);
}
/* Keyboard users get the same affordance as the hover state. */
.ssm-single__media .flex-control-thumbs img:focus-visible {
  outline: 2px solid var(--ssm-maroon);
  outline-offset: 2px;
  opacity: 1;
}

@media (max-width: 768px) {
  .ssm-single__media .flex-control-thumbs { gap: .5rem; margin-top: 1rem; }
  .ssm-single__media .flex-control-thumbs li { flex: 0 0 60px; }
  .ssm-single__media .flex-control-thumbs img { width: 60px; height: 60px; }
}

/* ============================================================= *
 *  CARD TYPE + BUTTON SCALE  (2026-08-04)
 * ============================================================= *
 *  The 4:5 image box made the text block underneath read heavy by comparison,
 *  so title, price and the add-to-cart are all stepped down. This also moves
 *  the card closer to the reference, whose type is 12/13/14px against our
 *  15/22px.
 *
 *  The button is reduced at >=769 ONLY. Its 44px min-height and 12px label are
 *  not styling — they came from the 2026-07-28 accessibility pass (tap targets
 *  measured 41px and labels 11px). Shrinking those on a phone would walk that
 *  fix back, so touch widths keep the full target and only pointer widths get
 *  the smaller button.
 * ============================================================= */
.ssm-card__title {
  font-size: 0.875rem;                 /* 15.2px -> 14px */
}
.ssm-card .price,
.ssm-card__price {
  font-size: 1rem;                     /* 22.4px -> 16px */
  margin-bottom: 0.85rem;
}

/*  Selector has to be `.block--woocommerce article.ssm-card a.button` (0,3,2).
    assets/css/new-header.css sets `.block--woocommerce article a.button
    { height: 50px; padding: 0 }` at 0,2,2 — and an explicit `height` beats a
    `min-height` outright, so the obvious `.ssm-card .button { min-height }`
    silently did nothing. Same legacy stylesheet that kept the card background
    white on 2026-07-31. `height` must be overridden, not just min-height. */
@media (min-width: 769px) {
  .block--woocommerce article.ssm-card a.button,
  .block--woocommerce article.ssm-card button.button,
  .block--woocommerce article.ssm-card .ssm-btn--cart,
  .block--woocommerce article.ssm-card .ssm-btn--call {
    height: 36px;                      /* 50 -> 36, pointer input only */
    min-height: 36px;
    padding: 0 1rem;
    font-size: 0.6875rem;              /* 14px -> 11px */
    letter-spacing: 1.5px;
  }
}

/* ============================================================= *
 *  GALLERY: VERTICAL RAIL + ARROWS  (2026-08-04)
 * ============================================================= *
 *  Reference PDP puts the thumbnails in a column to the LEFT of the main
 *  image with prev/next arrows flanking it. The rail was horizontal-below
 *  when it was first built (2026-08-03); this turns it vertical on desktop
 *  and keeps it horizontal on narrow screens, where a side column would eat
 *  a third of the width.
 *
 *  `:has(.flex-control-thumbs)` gates the two-column grid so a product with a
 *  single image doesn't get an empty 72px gutter shifting its photo off-centre
 *  — flexslider only emits the rail when there is more than one slide.
 * ============================================================= */
@media (min-width: 1025px) {
  .ssm-single__media .woocommerce-product-gallery:has(.flex-control-thumbs) {
    display: grid;
    grid-template-columns: 72px minmax(0, 1fr);
    gap: 1.25rem;
    align-items: start;
  }
  /* Both live in row 1; the rail is placed first visually despite coming
     second in flexslider's DOM order. */
  .ssm-single__media .flex-viewport { grid-column: 2; grid-row: 1; }

  .ssm-single__media .flex-control-thumbs {
    grid-column: 1;
    grid-row: 1;
    flex-direction: column;
    max-width: 72px;
    /* Main image caps at 560 wide and the normalised art is 4:5, so the stage
       tops out ~700 tall — match it and scroll past that rather than letting a
       long rail stretch the grid row. */
    max-height: 700px;
    overflow-x: hidden;
    overflow-y: auto;
    margin: 0;
    padding: 0 0.25rem 0 0;
    scroll-snap-type: y proximity;
  }
  .ssm-single__media .flex-control-thumbs li { flex: 0 0 72px; }

  /* Put the arrow list in the IMAGE cell and let it be the positioning
     context. Anchored to .woocommerce-product-gallery instead, `left: 8px`
     lands the prev arrow on top of the thumbnail rail, since the gallery box
     now starts at the rail column. */
  .ssm-single__media .flex-direction-nav {
    grid-column: 2;
    grid-row: 1;
    position: relative;
    align-self: stretch;
    pointer-events: none;              /* only the arrows themselves are hit */
  }
  .ssm-single__media .flex-direction-nav a { pointer-events: auto; }
}

/* --- prev / next arrows (flexslider emits these once directionNav is on) --- */
.ssm-single__media .flex-direction-nav {
  list-style: none;
  margin: 0;
  padding: 0;
}
.ssm-single__media .flex-direction-nav a {
  position: absolute;
  top: 50%;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin-top: -20px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .82);
  color: var(--ssm-ink);
  text-indent: -9999px;               /* flexslider ships a text label */
  overflow: hidden;
  opacity: 0;
  transition: opacity .2s ease, background .2s ease;
}
.ssm-single__media .woocommerce-product-gallery:hover .flex-direction-nav a,
.ssm-single__media .flex-direction-nav a:focus-visible { opacity: 1; }
.ssm-single__media .flex-direction-nav a:hover { background: #fff; }
/* Chevrons drawn with a rotated border so there is no icon dependency. */
.ssm-single__media .flex-direction-nav a::after {
  content: "";
  position: absolute;
  width: 10px;
  height: 10px;
  border-top: 2px solid var(--ssm-ink);
  border-right: 2px solid var(--ssm-ink);
  text-indent: 0;
}
.ssm-single__media .flex-direction-nav .flex-prev { left: 8px; }
.ssm-single__media .flex-direction-nav .flex-next { right: 8px; }
.ssm-single__media .flex-direction-nav .flex-prev::after { transform: rotate(-135deg); margin-left: 3px; }
.ssm-single__media .flex-direction-nav .flex-next::after { transform: rotate(45deg); margin-right: 3px; }
/* flexslider adds .flex-disabled when a end is reached and looping is off */
.ssm-single__media .flex-direction-nav .flex-disabled { opacity: 0 !important; pointer-events: none; }
/* The arrows are absolutely positioned against the slider viewport. */
.ssm-single__media .flex-viewport,
.ssm-single__media .woocommerce-product-gallery { position: relative; }

/* Touch: no hover to reveal arrows, and a side rail would cost too much
   width — keep the horizontal rail and leave the arrows hidden (swipe works). */
@media (max-width: 1024px) {
  .ssm-single__media .flex-direction-nav { display: none; }
}
