/**
 * WooCommerce: product detail page.
 *
 * Ported from the original design reference (640 lines, frozen signed-off contract).
 * Values are the mockup's. Where the mockup wrote a literal that has a token
 * (11px eyebrows -> --text-eyebrow, #fff -> --white) the token is used instead,
 * so the surface follows Theme Settings; everything else is byte-for-byte.
 *
 * Not ported, deliberately:
 *   .pdp-rating, .pdp-reviews  — star ratings and reviews were removed by the
 *                                design team (product-build-audit §3).
 *   .pdp-detail, .pdp-detail-grid — the old full-width details band, superseded
 *                                by the in-column layout on 17 July. Its only
 *                                remaining user was the Roadtripper quote,
 *                                which now has .pdp-testimonial below.
 *
 * Added, not in the mockup:
 *   .v-input / .v-btn radio pairing — the mockup's variant "buttons" are real
 *                                radio inputs here so the page is purchasable
 *                                without JavaScript. Rendered pixels unchanged.
 *   .pdp-form, .qty-stepper input   — the buy box is a real <form>.
 *   .pdp-notices                    — WooCommerce's own add-to-cart messages.
 *   img rules inside .pdp-main-img / .pdp-thumb / .bt-thumb — the mockup paints
 *                                these as background-image; real <img> elements
 *                                render identically under object-fit: cover.
 */

.pdp {
  /* The torn band above already reads as space, so the top stays tight. */
  padding-block: var(--space-xs) var(--section-space-s);
  padding-inline: var(--space-gutter);
}

/* --- Breadcrumb --- */
.pdp-breadcrumb {
  max-width: var(--container);
  margin-inline: auto;
  margin-bottom: var(--space-s);
  font-size: var(--text-small);
  font-weight: 500;
  color: var(--ink-muted);
}

.pdp-breadcrumb a {
  color: var(--brand-primary);
  transition: color var(--duration-fast);
}

.pdp-breadcrumb a:hover {
  color: var(--brand-accent);
}

.pdp-crumb-sep {
  margin-inline: var(--space-3xs);
}

/* --- WooCommerce notices --- */
.pdp-notices {
  max-width: var(--container);
  margin-inline: auto;
}

.pdp-notices:empty {
  display: none;
}

.pdp-notices .woocommerce-message,
.pdp-notices .woocommerce-info,
.pdp-notices .woocommerce-error {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s);
  margin-bottom: var(--space-l);
  padding: var(--space-s) var(--space-m);
  border: var(--border-thin) solid var(--brand-tint);
  border-radius: var(--radius-md);
  background: var(--brand-tint-soft);
  color: var(--ink);
  font-size: var(--text-small);
  line-height: 1.5;
}

.pdp-notices .woocommerce-error {
  border-color: var(--brand-accent);
  background: var(--surface-rose);
}

.pdp-notices .woocommerce-message a,
.pdp-notices .woocommerce-info a,
.pdp-notices .woocommerce-error a {
  color: var(--brand-primary);
  font-weight: var(--weight-strong);
  text-decoration: underline;
}

.pdp-top {
  max-width: var(--container);
  margin-inline: auto;
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: var(--space-2xl);
  align-items: start;
}

/* --- Gallery --- */
.pdp-gallery {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  min-width: 0;
}

/* Desktop: keep the gallery in view while the buy/detail column scrolls.
   Sticks below the 74px sticky nav, within the .pdp-top grid row. */
@media (min-width: 901px) {
  .pdp-gallery {
    position: sticky;
    top: calc(74px + var(--space-s));
    align-self: start;
  }
}

.pdp-main-img {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background-color: var(--brand-tint-soft);
  border-radius: var(--radius-lg);
}

/* The swipe track: every image side by side, one per "page", snapping.
   Native horizontal scroll, so it swipes with or without JavaScript. */
.pdp-slides {
  position: absolute;
  inset: 0;
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  border-radius: inherit;
}

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

.pdp-slides:focus-visible {
  outline: 3px solid var(--brand-secondary);
  outline-offset: -3px;
}

.pdp-slide {
  position: relative;
  flex: 0 0 100%;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

/* Absolute + object-fit, the same technique .kit-img-photo uses.
   Selector-nested on purpose: WooCommerce's own stylesheet ships
   `.woocommerce img { height: auto }` at (0,1,1), which outranks a lone class,
   and the square box takes its height from aspect-ratio so a bare
   `height: 100%` would fall back to auto and letterbox the photo. */
.pdp-main-img .pdp-main-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* "1 / 5" on the image, phones only: the cue that swiping shows more. */
.pdp-count {
  position: absolute;
  right: var(--space-s);
  bottom: var(--space-s);
  padding: var(--space-3xs) var(--space-xs);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--ink) 72%, transparent);
  color: var(--white);
  font-size: var(--text-xs);
  font-weight: var(--weight-strong);
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  pointer-events: none;
}

.pdp-count[hidden] {
  display: none;
}

@media (min-width: 901px) {
  .pdp-count {
    display: none;
  }
}

.pdp-main-img--placeholder {
  display: grid;
  place-items: center;
}

.pdp-img-note {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3xs);
  color: var(--brand-primary);
  font-size: var(--text-small);
  font-weight: var(--weight-strong);
}

/* Thumbnail strip: one row, four in view, the rest scroll sideways. Phones
   hide it; the swipe track and the counter replace it there. */
.pdp-thumbs-wrap {
  position: relative;
}

.pdp-thumbs {
  display: flex;
  gap: var(--space-2xs);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}

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

.pdp-thumb {
  position: relative;
  flex: 0 0 calc((100% - 3 * var(--space-2xs)) / 4);
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background-color: var(--brand-tint-soft);
  border: 2px solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  padding: 0;
  scroll-snap-align: start;
  transition: border-color var(--duration-fast);
}

.pdp-thumb .pdp-thumb-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* No hover lift: the strip clips vertically, so a lift would be cut off. */
.pdp-thumb:hover {
  border-color: var(--hairline-strong);
}

.pdp-thumb.is-active {
  border-color: var(--brand-accent);
}

/* Inset, because the scrolling strip clips anything drawn outside a thumb. */
.pdp-thumb:focus-visible {
  outline: 2px solid var(--brand-primary);
  outline-offset: -4px;
}

.pdp-thumbs-nav {
  position: absolute;
  top: 50%;
  z-index: 1;
  display: grid;
  place-items: center;
  width: var(--gallery-nav-size);
  height: var(--gallery-nav-size);
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--white);
  color: var(--brand-primary);
  box-shadow: var(--shadow-outline-button);
  cursor: pointer;
  transform: translateY(-50%);
  transition: background-color var(--duration-fast);
}

.pdp-thumbs-nav.is-prev { left: var(--space-3xs); }
.pdp-thumbs-nav.is-next { right: var(--space-3xs); }

.pdp-thumbs-nav:hover {
  background: var(--brand-tint-soft);
}

.pdp-thumbs-nav:focus-visible {
  outline: 3px solid var(--brand-secondary);
  outline-offset: 2px;
}

.pdp-thumbs-nav[hidden] {
  display: none;
}

@media (max-width: 900px) {
  .pdp-thumbs-wrap {
    display: none;
  }
}

.pdp-main-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-l);
  min-width: 0;
}

/* Inline detail blocks (were a separate full-width band; now beside the image) */
.pdp-overview,
.pdp-included,
.pdp-specs {
  border-top: 1px solid var(--hairline);
  padding-top: var(--space-l);
}

/* Full product description (from the docx) */
.pdp-overview p {
  font-size: var(--text-lead);
  color: var(--ink);
  line-height: 1.7;
  max-width: 62ch;
}

/* Siblings spaced by the parent's gap, not by margins on the children. */
.pdp-overview {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

/* The "Details" table every product description ends with. */
.pdp-overview table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-small);
}

.pdp-overview th,
.pdp-overview td {
  padding: var(--space-2xs) 0;
  border-bottom: var(--border-hair) solid var(--hairline);
  text-align: left;
  vertical-align: top;
}

.pdp-overview th {
  width: 36%;
  padding-inline-end: var(--space-s);
  font-weight: var(--weight-strong);
  color: var(--brand-primary);
}

.pdp-overview td {
  color: var(--ink);
}

/* Several store descriptions still carry old catalogue markup — bullet lists
   and a stray heading. base.css strips list markers globally, so they are put
   back here rather than leaving an unreadable run of lines. See the report:
   this content needs a pass, the styling is a holding position. */
.pdp-overview ul,
.pdp-overview ol {
  padding-left: var(--space-m);
  color: var(--ink);
  font-size: var(--text-small);
  line-height: 1.6;
}

.pdp-overview ul {
  list-style: disc;
}

.pdp-overview ol {
  list-style: decimal;
}

.pdp-overview h2 {
  font-size: var(--text-h4);
  font-weight: var(--weight-strong);
  color: var(--brand-primary);
}

.pdp-included h2,
.pdp-specs h2 {
  font-size: var(--text-h3);
  font-weight: var(--weight-strong);
  margin-bottom: var(--space-m);
}

.pdp-included h2 em,
.pdp-specs h2 em {
  font-style: italic;
  font-weight: 500;
  color: var(--brand-accent);
}

/* --- Info column --- */
.pdp-info {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  align-items: flex-start;
}

.pdp-info h1 {
  font-size: clamp(32px, 3.6vw, 48px);
  font-weight: var(--weight-strong);
  letter-spacing: -0.025em;
  line-height: 1.03;
}

.pdp-price {
  display: flex;
  align-items: baseline;
  gap: var(--space-s);
  width: 100%;
  margin-top: var(--space-2xs);
  padding-top: var(--space-m);
  border-top: 1px solid var(--hairline);
}

.pdp-price .amount {
  font-family: var(--font-heading);
  font-weight: var(--weight-strong);
  font-size: clamp(30px, 3.4vw, 42px);
  color: var(--brand-primary);
  line-height: 1;
}

.pdp-price .from {
  font-size: var(--text-small);
  color: var(--ink-muted);
}

.pdp-desc {
  color: var(--ink);
  line-height: 1.65;
  max-width: 52ch;
}

.pdp-unavailable {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2xs);
  width: 100%;
  padding: var(--space-s) var(--space-m);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-md);
  background: var(--surface-alt);
  color: var(--ink);
  font-size: var(--text-small);
  line-height: 1.5;
  max-width: 52ch;
}

.pdp-unavailable .material-symbols-outlined {
  color: var(--brand-accent);
}

/* --- The cart form -------------------------------------------------------
   The mockup has the variant groups and the buy row as direct children of
   .pdp-info. Wrapping them in a real <form> would swallow that flex gap, so
   the form repeats its parent's layout and the spacing is unchanged. */
.pdp-form {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-s);
  width: 100%;
}

/* --- Variants --- */
.pdp-variants {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  margin-top: var(--space-2xs);
}

.v-fieldset {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  min-width: 0;
  border: 0;
  margin: 0;
  padding: 0;
}

.v-label {
  display: block;
  padding: 0;
  font-size: var(--text-eyebrow);
  font-weight: var(--weight-strong);
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.v-btns {
  position: relative;
  display: flex;
  gap: var(--space-s);
  flex-wrap: wrap;
}

/* The radio is the real control; the label is the mockup's button. Kept in the
   layout (not display:none) so it stays reachable by keyboard. */
.v-input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}

/* Each pill is as wide as its text and the group wraps, rather than every
   pill stretching to a full row (Seth, 12 October 2026). Pills in one group
   share a structure (all with a sub-line or none), and flex rows stretch, so
   they stay one height. Pack size keeps its three-column grid below. */
.v-btn {
  flex: 0 0 auto;
  max-width: 100%;
  white-space: nowrap;
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: left;
  background: var(--surface);
  border: 1.5px solid var(--hairline);
  border-radius: var(--radius-md);
  padding: var(--space-s) var(--space-m);
  font-family: var(--font-heading);
  font-weight: var(--weight-strong);
  color: var(--ink);
  cursor: pointer;
  transition: border-color var(--duration-fast), background var(--duration-fast),
              box-shadow var(--duration-fast);
}

.v-btn small {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--text-small);
  color: var(--ink-muted);
}

.v-btn:hover {
  border-color: var(--brand-tint);
}

.v-input:checked + .v-btn {
  border-color: var(--brand-primary);
  background: var(--brand-tint-soft);
  box-shadow: inset 0 0 0 1px var(--brand-primary);
}

.v-input:checked + .v-btn small {
  color: var(--brand-primary);
}

.v-input:focus-visible + .v-btn {
  outline: 2px solid var(--brand-primary);
  outline-offset: 2px;
}

/* A combination the store does not sell. Struck through rather than hidden, so
   the range on offer still reads as a range. */
.v-btn.is-unavailable {
  opacity: 0.45;
  cursor: not-allowed;
  text-decoration: line-through;
}

.v-btn.is-unavailable:hover {
  border-color: var(--hairline);
}

.v-note {
  font-size: var(--text-small);
  color: var(--ink-muted);
  margin-top: var(--space-2xs);
}

/* --- Buy row --- */
.pdp-buy {
  display: flex;
  align-items: stretch;
  gap: var(--space-s);
  width: 100%;
  flex-wrap: nowrap;
  margin-top: var(--space-2xs);
}

.qty-stepper {
  display: inline-flex;
  align-items: center;
  border: 1.5px solid var(--hairline);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.qty-stepper .qty-step {
  width: 46px;
  min-height: 50px;
  display: grid;
  place-items: center;
  color: var(--brand-primary);
  background: var(--surface);
  border: 0;
  cursor: pointer;
  transition: background var(--duration-fast);
}

.qty-stepper .qty-step:hover {
  background: var(--surface-alt);
}

.qty-stepper .qty-step:focus-visible {
  outline: 2px solid var(--brand-primary);
  outline-offset: -2px;
}

.qty-stepper .qv {
  width: 42px;
  min-width: 42px;
  padding: 0;
  text-align: center;
  font-family: var(--font-heading);
  font-weight: var(--weight-strong);
  font-size: var(--text-body);
  color: var(--ink);
  background: var(--white);
  border: 0;
  -moz-appearance: textfield;
  appearance: textfield;
}

.qty-stepper .qv::-webkit-outer-spin-button,
.qty-stepper .qv::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.qty-stepper .qv:focus-visible {
  outline: 2px solid var(--brand-primary);
  outline-offset: -2px;
}

/* Quantity, Add to cart and Buy now share one row (Seth, 12 October 2026).
   The two buttons split what the stepper leaves equally. */
.pdp-buy .btn-cart {
  flex: 1 1 0;
  min-width: 0;
  justify-content: center;
  white-space: nowrap;
}

/* --- Trust row --- */
.pdp-trust {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-s);
  width: 100%;
  margin-top: var(--space-s);
  padding-top: var(--space-m);
  border-top: 1px solid var(--hairline);
}

.t-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.t-item .material-symbols-outlined {
  font-size: 26px;
  color: var(--brand-support);
  margin-bottom: 4px;
}

.t-item strong {
  font-family: var(--font-heading);
  font-weight: var(--weight-strong);
  font-size: var(--text-small);
  color: var(--brand-primary);
}

.t-item span {
  font-size: 12px;
  color: var(--ink-muted);
  line-height: 1.35;
}

/* --- Detail: included + specs --- */
.included-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  list-style: none;
  margin: 0;
  padding: 0;
}

.included-list li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-s);
  align-items: start;
  color: var(--ink);
  line-height: 1.5;
  font-size: var(--text-small);
}

.included-list li .material-symbols-outlined {
  color: var(--brand-support);
  font-size: 22px;
  margin-top: 1px;
}

.spec-table {
  width: 100%;
  border-collapse: collapse;
}

.spec-table th,
.spec-table td {
  text-align: left;
  padding: var(--space-s) 0;
  border-bottom: 1px solid var(--hairline);
  vertical-align: top;
  font-size: var(--text-small);
  line-height: 1.45;
}

.spec-table th {
  width: 38%;
  color: var(--brand-primary);
  font-family: var(--font-heading);
  font-weight: var(--weight-strong);
  padding-right: var(--space-s);
}

.spec-table td {
  color: var(--ink-muted);
}

/* --- Owner's note ---------------------------------------------------------
   The mockup builds this out of .pdp-detail plus five inline style attributes.
   Same values, lifted out of the markup so nothing is hardcoded in a template. */
.pdp-testimonial {
  padding-block: var(--section-space-s);
  padding-inline: var(--space-gutter);
  background: var(--surface);
}

.pdp-testimonial-inner {
  max-width: var(--container);
  margin-inline: auto;
}

.pdp-quote p {
  font-family: var(--font-heading);
  font-size: var(--text-h3);
  font-weight: 500;
  font-style: italic;
  color: var(--brand-primary);
  max-width: 60ch;
  line-height: 1.4;
}

.pdp-quote cite {
  display: block;
  margin-top: var(--space-s);
  font-size: var(--text-small);
  font-style: normal;
  font-weight: var(--weight-strong);
  color: var(--ink-muted);
}

/* --- Upsell sections --- */
.pdp-upsell {
  padding-block: var(--section-space-s);
  padding-inline: var(--space-gutter);
}

.pdp-upsell.alt {
  background: var(--surface-alt);
}

.pdp-upsell .section-head {
  max-width: var(--container);
  margin-inline: auto;
}

.pdp-upsell .kit-grid {
  max-width: var(--container);
  margin-inline: auto;
}

/* Trade-up banner */
.trade-up {
  max-width: var(--container);
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-l);
  flex-wrap: wrap;
  background: var(--brand-primary);
  border-radius: var(--radius-lg);
  padding: var(--space-l);
}

.tu-text h2 {
  color: var(--surface);
  font-size: var(--text-h3);
  font-weight: var(--weight-strong);
  max-width: 24ch;
}

.tu-text h2 em {
  font-style: italic;
  font-weight: 500;
  color: var(--brand-tint);
}

.tu-text p {
  color: var(--brand-tint);
  line-height: 1.6;
  margin-top: var(--space-2xs);
  max-width: 56ch;
}

.trade-up .btn-primary {
  flex-shrink: 0;
}

/* Frequently bought together */
.bought {
  max-width: var(--container);
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-l);
  flex-wrap: wrap;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-l);
}

.bought-items {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  flex-wrap: wrap;
  flex: 1 1 auto;
}

.bt-item {
  display: grid;
  grid-template-columns: 56px 1fr;
  column-gap: var(--space-s);
  align-items: center;
  min-width: 190px;
}

.bt-thumb {
  grid-column: 1;
  grid-row: 1 / span 3;
  width: 56px;
  height: 56px;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background-color: var(--brand-tint-soft);
}

.bought .bt-thumb img {
  width: 56px;
  height: 56px;
  object-fit: cover;
  display: block;
}

.bt-name {
  grid-column: 2;
  font-weight: var(--weight-strong);
  font-size: var(--text-small);
  color: var(--ink);
  line-height: 1.2;
}

.bt-price {
  grid-column: 2;
  font-family: var(--font-heading);
  font-weight: var(--weight-strong);
  font-size: var(--text-small);
  color: var(--brand-primary);
}

.bt-check {
  grid-column: 2;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--ink-muted);
  cursor: pointer;
}

.bt-check input {
  width: 15px;
  height: 15px;
  accent-color: var(--brand-accent);
}

.bt-check input:focus-visible {
  outline: 2px solid var(--brand-primary);
  outline-offset: 2px;
}

.bt-plus {
  flex-shrink: 0;
  font-size: 24px;
  font-weight: 300;
  color: var(--ink-muted);
}

.bought-buy {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-2xs);
  flex-shrink: 0;
  text-align: right;
}

.bt-total-label {
  font-size: var(--text-eyebrow);
  font-weight: var(--weight-strong);
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.bt-total {
  font-family: var(--font-heading);
  font-weight: var(--weight-strong);
  font-size: clamp(24px, 3vw, 32px);
  color: var(--brand-primary);
  line-height: 1;
}

/* --- Responsive --- */
@media (max-width: 900px) {
  .pdp-top {
    grid-template-columns: 1fr;
    gap: var(--space-xl);
  }

  /* --- Sticky add-to-cart bar ---------------------------------------------
     Driven by assets/js/woo/sticky-add-to-cart.js. Once the buy row scrolls
     out of view the script wraps the SAME `.pdp-buy` element (no clone —
     one quantity input, one submit button, same as always) in
     `.pdp-buy-slot` and adds `.is-pdp-buy-pinned` to pin it here. The slot
     keeps reserving `.pdp-buy`'s normal-flow height for as long as it is
     pinned, so removing it from flow does not shift anything below it.

     With JavaScript off, or above this breakpoint, neither the wrapper nor
     the class ever exist — `.pdp-buy` renders and submits exactly as the
     normal-flow row defined above. */
  .pdp-buy-slot {
    width: 100%;
  }

  .pdp-buy.is-pdp-buy-pinned {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 90;
    margin-top: 0;
    background: var(--white);
    border-top: 1.5px solid var(--hairline);
    padding: var(--space-xs) var(--space-gutter) calc(var(--space-xs) + env(safe-area-inset-bottom));
  }

  /* Phones: the same one row, compacted. The bag icon goes and the padding
     tightens so both labels fit beside the stepper, in flow and pinned. */
  .pdp-buy {
    gap: var(--space-xs);
  }

  .pdp-buy .qty-step {
    width: var(--qty-step-width-compact);
    min-height: var(--btn-min-height-sm);
  }

  .pdp-buy .qv {
    width: var(--qty-step-width-compact);
    min-width: var(--qty-step-width-compact);
  }

  .pdp-buy .btn-cart {
    flex: 1 1 0;
    min-width: 0;
    min-height: var(--btn-min-height-sm);
    padding-inline: var(--space-xs);
    white-space: nowrap;
  }

  .pdp-buy .btn-cart-rest svg {
    display: none;
  }

  /* The page's last lines would sit under the bar; give them room. */
  body:has(.pdp-buy.is-pdp-buy-pinned) {
    padding-bottom: var(--graphique-pinned-buy-height, 0);
  }

  /* The pinned bar spans the full viewport width at the bottom, which would
     otherwise sit on top of the floating back-to-top button (components.css)
     — both are `position: fixed; bottom: ~0`. Lift back-to-top clear of the
     pinned bar's height rather than hide it: a shopper deep in the page
     still has a fast way back to the top, without the two controls
     overlapping.

     The bar's height isn't constant — the quantity stepper and "Add to
     cart" button sit side by side on wider phones but wrap onto two lines
     on narrower ones (`.pdp-buy` is `flex-wrap: wrap`), which roughly
     doubles it. sticky-add-to-cart.js publishes the real measured height as
     --graphique-pinned-buy-height while pinned, so this stays correct at every
     width in the breakpoint instead of guessing one static offset. The
     140px fallback only matters if that script fails to load. */
  body:has(.pdp-buy.is-pdp-buy-pinned) .back-to-top {
    bottom: calc(var(--graphique-pinned-buy-height, 140px) + var(--space-s) + env(safe-area-inset-bottom));
  }
}

@media (max-width: 560px) {
  .bought,
  .trade-up {
    flex-direction: column;
    align-items: stretch;
    text-align: left;
  }

  .bought-buy {
    align-items: stretch;
    text-align: left;
  }

  .bought-buy .btn-primary {
    justify-content: center;
  }

  /* Keep the trust row as a single row (3 columns) on mobile too */
  .pdp-trust {
    gap: var(--space-2xs);
  }

  .pdp-trust .t-item strong {
    font-size: 12px;
  }

  .pdp-trust .t-item span {
    font-size: 10.5px;
  }

  .pdp-trust .t-item .material-symbols-outlined {
    font-size: 22px;
  }
}

/* ---------------------------------------------------------------------------
   NO-SCRIPT PRICE MATRIX
   ---------------------------------------------------------------------------
   Only ever rendered inside <noscript>, so it never reaches a scripted page.
   Styled anyway: a bare table on a designed PDP looks like a fault, and this
   is the one place a JS-off shopper reads prices for anything other than the
   default variation. */

.v-matrix {
  width: 100%;
  border-collapse: collapse;
  margin-block: var(--space-xs);
  font-size: var(--text-small);
}

.v-matrix caption {
  text-align: left;
  font-weight: var(--weight-strong);
  color: var(--ink-muted);
  padding-block-end: var(--space-3xs);
}

.v-matrix th,
.v-matrix td {
  text-align: left;
  padding: var(--space-3xs) var(--space-2xs);
  border-block-end: 1px solid var(--hairline);
}

.v-matrix th {
  font-weight: var(--weight-strong);
  color: var(--brand-primary);
}

.v-matrix td:last-child {
  font-family: var(--font-heading);
  font-weight: var(--weight-strong);
  color: var(--brand-primary);
  white-space: nowrap;
}

/* --- Pack saving, beside the price --- */
.pdp-price {
  flex-wrap: wrap;
}

.pdp-save {
  padding: var(--space-3xs) var(--space-xs);
  border-radius: var(--radius-pill);
  background: var(--brand-tint-pink);
  color: var(--brand-accent);
  font-size: var(--text-small);
  font-weight: var(--weight-strong);
}

.pdp-save[hidden] {
  display: none;
}

/* --- Personalization: a closed accordion above the buy row --- */
.pdp-pz {
  width: 100%;
  min-width: 0;
  border: var(--border-thin) solid var(--brand-tint);
  border-radius: var(--radius-md);
  background: var(--brand-tint-soft);
}

.pdp-pz-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  padding: var(--space-s) var(--space-m);
  list-style: none;
  cursor: pointer;
  border-radius: var(--radius-md);
}

.pdp-pz-summary::-webkit-details-marker {
  display: none;
}

.pdp-pz-summary:hover .pdp-pz-title {
  color: var(--brand-accent);
}

.pdp-pz-summary:focus-visible {
  outline: 2px solid var(--brand-secondary);
  outline-offset: 2px;
}

.pdp-pz-summary-text {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  min-width: 0;
}

.pdp-pz-title {
  font-family: var(--font-heading);
  font-size: var(--text-h4);
  color: var(--brand-primary);
  transition: color var(--duration-fast);
}

.pdp-pz-hint {
  font-size: var(--text-small);
  color: var(--ink-muted);
  overflow-wrap: anywhere;
}

.pdp-pz.is-filled .pdp-pz-hint {
  color: var(--brand-support);
  font-weight: var(--weight-strong);
}

.pdp-pz-caret {
  width: var(--icon-size);
  height: var(--icon-size);
  color: var(--brand-primary);
  transition: transform var(--duration-fast) var(--ease-out);
}

.pdp-pz[open] .pdp-pz-caret {
  transform: rotate(180deg);
}

.pdp-pz-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  min-width: 0;
  margin: 0;
  padding: 0 var(--space-m) var(--space-m);
  /* The fieldset is only there for grouping; drop the browser's groove border. */
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  .pdp-pz-caret {
    transition: none;
  }
}

.pdp-pz-lead,
.pdp-pz-note {
  font-size: var(--text-small);
  color: var(--ink-muted);
}

.pdp-pz-fineprint {
  font-size: var(--text-xs);
  color: var(--ink-muted);
}

/* Packs read as one row of three, smallest to largest. */
[data-pdp-axis="pa_pack-size"] .v-btns {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

[data-pdp-axis="pa_pack-size"] .v-btn {
  min-width: 0;
  padding-inline: var(--space-s);
  white-space: normal;
}

/* Slimmer variant pills: less block padding, smaller type (Seth, 12 Oct 2026). */
.v-btns {
  gap: var(--space-xs);
}

.v-btn,
[data-pdp-axis="pa_pack-size"] .v-btn {
  gap: 0;
  padding: var(--space-2xs) var(--space-xs);
  font-size: var(--text-small);
  line-height: 1.3;
}

.v-btn small {
  font-size: var(--text-xs);
}

/* Very narrow phones (320px class): three controls no longer fit one row, so
   Buy now drops to its own full-width row, in flow and pinned. */
@media (max-width: 359px) {
  .pdp-buy {
    flex-wrap: wrap;
  }

  .pdp-buy .btn-buy-now {
    flex-basis: 100%;
  }
}

/* --- Pop-up image viewer -------------------------------------------------
   Driven by assets/js/woo/pdp-lightbox.js. A native <dialog> in the top
   layer, so the sticky gallery and nav cannot sit over it. Full viewport;
   images fit inside it whole, never cropped. */
.pdp-slide-link {
  position: absolute;
  inset: 0;
  display: block;
  cursor: zoom-in;
}

.pdp-slide-link:focus-visible {
  outline: 3px solid var(--brand-secondary);
  outline-offset: -3px;
  border-radius: inherit;
}

.pdp-lightbox {
  width: 100vw;
  height: 100dvh;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--white);
  overflow: hidden;
}

.pdp-lightbox::backdrop {
  background: color-mix(in srgb, var(--ink) 94%, transparent);
}

/* Stop the page behind scrolling while the viewer is open. */
html:has(.pdp-lightbox[open]) {
  overflow: hidden;
}

.lb-track {
  display: flex;
  height: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  overscroll-behavior: contain;
  scrollbar-width: none;
}

.lb-track::-webkit-scrollbar {
  display: none;
}

.lb-slide {
  flex: 0 0 100%;
  display: grid;
  place-items: center;
  margin: 0;
  padding: var(--space-2xl) var(--space-m);
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

/* Nested for the same reason as .pdp-main-photo: Woo's `.woocommerce img`. */
.pdp-lightbox .lb-photo {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: calc(100dvh - 2 * var(--space-2xl));
  object-fit: contain;
  border-radius: var(--radius-md);
  background-color: var(--brand-tint-soft);
}

.lb-btn {
  position: fixed;
  z-index: 1;
  display: grid;
  place-items: center;
  width: var(--btn-min-height-sm);
  height: var(--btn-min-height-sm);
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--white);
  color: var(--brand-primary);
  box-shadow: var(--shadow-outline-button);
  cursor: pointer;
  transition: background-color var(--duration-fast), opacity var(--duration-fast);
}

.lb-btn:hover {
  background: var(--brand-tint-soft);
}

.lb-btn:focus-visible {
  outline: 3px solid var(--brand-secondary);
  outline-offset: 3px;
}

.lb-btn:disabled {
  opacity: 0.35;
  cursor: default;
}

.lb-close {
  top: var(--space-s);
  right: var(--space-s);
}

.lb-nav {
  top: 50%;
  transform: translateY(-50%);
}

.lb-nav.is-prev { left: var(--space-s); }
.lb-nav.is-next { right: var(--space-s); }

.lb-count {
  position: fixed;
  left: 50%;
  bottom: var(--space-s);
  transform: translateX(-50%);
  padding: var(--space-3xs) var(--space-xs);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--ink) 72%, transparent);
  color: var(--white);
  font-size: var(--text-xs);
  font-weight: var(--weight-strong);
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}

/* Phones: arrows sit over the photo edges, so tuck them to the bottom
   beside the counter, where they do not cover the picture. */
@media (max-width: 600px) {
  .lb-nav {
    top: auto;
    bottom: var(--space-s);
    transform: none;
  }
}

/* --- Reviews (single-product/graphique-reviews.php, inc/woo-reviews.php) ---
   WooCommerce's native review list and form, restyled to the theme's fields
   and buttons. The star glyphs and the clickable star picker come from
   woocommerce.css, which the PDP keeps; its review rules use ID selectors,
   so the overrides below repeat those IDs to win on specificity. */

.pdp-rating {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  width: fit-content;
  font-size: var(--text-small);
  color: var(--ink-muted);
  text-decoration: none;
}

.pdp-rating:hover .pdp-rating-count {
  color: var(--brand-primary);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.pdp-rating .star-rating,
.pdp-reviews .star-rating {
  float: none;
  margin: 0;
  color: var(--brand-accent);
}

.pdp-reviews {
  padding-block: var(--section-space-s);
  padding-inline: var(--space-gutter);
  border-top: thin solid var(--hairline);
}

.pdp-reviews-inner {
  max-width: var(--container-text);
}

.pdp-reviews #reviews,
.pdp-reviews #comments,
.pdp-reviews #review_form,
.pdp-reviews .comment-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

.pdp-reviews #reviews {
  gap: var(--space-m);
}

.pdp-reviews .woocommerce-Reviews-title,
.pdp-reviews .comment-reply-title {
  display: block;
  margin: 0;
  font-family: var(--font-heading);
  font-size: var(--text-h3);
  color: var(--brand-primary);
}

.pdp-reviews .woocommerce-noreviews,
.pdp-reviews .comment-notes,
.pdp-reviews .must-log-in,
.pdp-reviews .woocommerce-verification-required {
  margin: 0;
  font-size: var(--text-small);
  color: var(--ink-muted);
}

.pdp-reviews #reviews #comments ol.commentlist {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  margin: 0;
  padding: 0;
  list-style: none;
}

.pdp-reviews #reviews #comments ol.commentlist li .comment_container {
  display: flex;
  gap: var(--space-s);
  padding: var(--space-s);
  border: thin solid var(--hairline);
  border-radius: var(--radius-md);
  background: var(--white);
}

/* Woo floats a 32px avatar beside each review; the theme uses no avatars. */
.pdp-reviews #reviews #comments ol.commentlist li img.avatar {
  display: none;
}

.pdp-reviews #reviews #comments ol.commentlist li .comment-text {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  margin: 0;
  padding: 0;
  border: 0;
}

.pdp-reviews #reviews #comments ol.commentlist li .meta {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--ink-muted);
}

.pdp-reviews .woocommerce-review__author {
  font-weight: var(--weight-strong);
  color: var(--ink);
}

.pdp-reviews .woocommerce-review__verified {
  color: var(--brand-support);
  font-style: normal;
}

.pdp-reviews #reviews #comments ol.commentlist li .description p {
  margin: 0;
  font-size: var(--text-small);
  color: var(--ink);
}

.pdp-reviews .comment-form > p,
.pdp-reviews .comment-form-rating {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  margin: 0;
}

.pdp-reviews .comment-form label {
  font-size: var(--text-small);
  font-weight: var(--weight-strong);
  color: var(--ink);
}

.pdp-reviews .comment-form .required {
  color: var(--brand-accent);
  text-decoration: none;
}

.pdp-reviews #review_form #respond .comment-form input[type="text"],
.pdp-reviews #review_form #respond .comment-form input[type="email"],
.pdp-reviews #review_form #respond .comment-form textarea {
  width: 100%;
  min-height: var(--tap-target);
  padding: var(--space-2xs) var(--space-xs);
  background-color: var(--white);
  color: var(--ink);
  border: var(--border-thin) solid var(--brand-tint);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: var(--text-small);
}

.pdp-reviews .comment-form textarea {
  min-height: calc(var(--tap-target) * 3);
  resize: vertical;
}

.pdp-reviews .comment-form input:focus,
.pdp-reviews .comment-form textarea:focus {
  outline: none;
  border-color: var(--brand-secondary);
  box-shadow: 0 0 0 3px var(--hairline-soft);
}

.pdp-reviews .comment-form-cookies-consent {
  flex-direction: row;
  align-items: flex-start;
  gap: var(--space-2xs);
}

.pdp-reviews .comment-form-cookies-consent label {
  font-weight: normal;
  color: var(--ink-muted);
}

.pdp-reviews p.stars {
  margin: 0;
  font-size: var(--text-h3);
}

.pdp-reviews p.stars a {
  color: var(--brand-accent);
}

.pdp-reviews #review_form #respond .form-submit input[type="submit"] {
  width: fit-content;
  min-height: var(--tap-target);
  padding: var(--space-2xs) var(--space-m);
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--brand-accent);
  color: var(--white);
  font: inherit;
  font-weight: var(--weight-strong);
  cursor: pointer;
}

.pdp-reviews #review_form #respond .form-submit input[type="submit"]:hover {
  background: var(--brand-accent-hover);
}

.pdp-reviews #review_form #respond .form-submit input[type="submit"]:focus-visible {
  outline: 2px solid var(--brand-secondary);
  outline-offset: 2px;
}
