/* ==========================================================================
   ShopFront — Product page
   --------------------------------------------------------------------------
   Loaded by product.html only. styles.css already ships everything the two
   pages share — header, footer, drawer, buttons, badges, price, product
   card, rails, section headings — so nothing here re-implements any of it.
   What follows is the product view and nothing else.

   Same rules as styles.css, and they are not negotiable:
     · no raw colour, no raw shadow, no off-grid spacing — tokens only;
     · logical properties throughout (dir="rtl", so inline-start = right);
     · the design is FLAT. Surfaces separate by border and tone. The only
       shadows are on layers that float over arbitrary page content — the
       sticky buy bar and the lightbox — which is the one exception
       tokens.css allows.

   Page-level knobs are declared on the component root rather than :root,
   so tokens.css stays the single source of truth for anything global.

   Contents
     01  Breadcrumb
     02  Product layout
     03  Gallery
     04  Identity & options
     05  Buy box
     06  Highlights
     07  Bundle
     08  Details tabs
     09  Reviews
     10  Related rail
     11  Sticky buy bar
     12  Lightbox
     13  Responsive
     14  Motion & print
   ========================================================================== */


/* ==========================================================================
   01 · BREADCRUMB
   ========================================================================== */

.breadcrumb {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--gap-inline-md);
  margin-block-start: var(--space-6);
}

.breadcrumb__list {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--gap-inline-sm);
  margin: 0;
  color: var(--fg-subtle);
  font-size: var(--text-sm);
}

/* The separator is drawn, not typed: a "/" or "«" character would have to
   be mirrored by hand and would land in the accessibility tree. */
.breadcrumb__item + .breadcrumb__item::before {
  content: "";
  display: inline-block;
  inline-size: var(--space-1);
  block-size: var(--space-1);
  margin-inline-end: var(--gap-inline-sm);
  border-radius: var(--radius-circle);
  background: var(--border-strong);
  vertical-align: middle;
}

.breadcrumb__item a {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline-xs);
  color: var(--fg-muted);
  transition: var(--transition-colors);
}
.breadcrumb__item a:hover {
  color: var(--brand-text);
}
.breadcrumb__item .icon {
  font-size: var(--icon-sm);
}

.breadcrumb__item [aria-current="page"] {
  color: var(--fg-default);
  font-weight: var(--weight-bold);
}

.breadcrumb__back {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline-xs);
  color: var(--fg-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  transition: var(--transition-colors);
}
.breadcrumb__back:hover {
  color: var(--brand-text);
}
.breadcrumb__back .icon {
  font-size: var(--icon-md);
  transition: var(--transition-transform);
}
.breadcrumb__back:hover .icon {
  transform: translateX(-3px);
}


/* Stand-in notice: this page is authored for one product, and any other
   ?p= lands on it. Amber rather than red — nothing has gone wrong, the
   visitor is just not looking at what they clicked. */
.pdp-note {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--gap-inline-md);
  margin-block-start: var(--space-4);
  padding: var(--space-3) var(--space-5);
  border: var(--border-hairline) solid var(--warning);
  border-radius: var(--radius-lg);
  background: var(--warning-subtle);
  color: var(--warning-text);
  font-size: var(--text-md);
}
.pdp-note[hidden] {
  display: none;
}
.pdp-note .icon {
  flex: none;
}
.pdp-note b {
  font-weight: var(--weight-extrabold);
}
.pdp-note a {
  margin-inline-start: auto;
  font-weight: var(--weight-bold);
  text-decoration: underline;
  text-underline-offset: 0.25em;
}


/* ==========================================================================
   02 · PRODUCT LAYOUT
   --------------------------------------------------------------------------
   Three columns: gallery, the product's own story and options, then the buy
   box. The buy box is a fixed width because it is a form — it holds a price,
   a stepper and a button, and none of those get better by being wider. The
   other two share what is left.
   ========================================================================== */

.pdp {
  --pdp-col-gallery: 30rem;
  --pdp-col-buy: 21.5rem;
  display: grid;
  grid-template-columns:
    minmax(0, var(--pdp-col-gallery))
    minmax(0, 1fr)
    var(--pdp-col-buy);
  gap: var(--space-10);
  margin-block-start: var(--space-6);
  align-items: start;
}


/* ==========================================================================
   03 · GALLERY
   ========================================================================== */

.gallery {
  display: grid;
  grid-template-columns: 4.75rem minmax(0, 1fr);
  gap: var(--gap-inline-md);
  align-items: start;
}

/* Columns are assigned, not auto-placed. The frame comes first in the
   markup because it is the content and the thumbnails only change it; the
   strip still paints at the inline-start (right, in RTL), which is where a
   Persian reader looks for it. */
.gallery__stage {
  grid-column: 2;
  grid-row: 1;
  position: relative;
  min-inline-size: 0;
}
.gallery__thumbs {
  grid-column: 1;
  grid-row: 1;
  display: flex;
  flex-direction: column;
  gap: var(--gap-inline-sm);
}

.gallery__flags {
  position: absolute;
  z-index: var(--z-raised);
  inset-block-start: var(--space-4);
  inset-inline-start: var(--space-4);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  pointer-events: none;
}

/* Extends .badge. A quiet, bordered fill for labels that are informational
   rather than promotional — the discount badge has to stay the loudest
   thing in this corner. */
.badge--soft {
  padding: var(--space-1-5) var(--space-2-5);
  border: var(--border-hairline) solid var(--border-brand);
  border-radius: var(--radius-pill);
  background: var(--bg-brand-subtle);
  color: var(--brand-text);
  font-size: var(--text-2xs);
}
.badge--soft .icon {
  font-size: var(--icon-sm);
}

/* ---- Image frames -----------------------------------------------------
   Every fixed-size picture box on this page — the gallery frame and its
   thumbnails, the packing-list photo, the bundle rows, the sticky bar — is
   a plain BLOCK with a definite block-size, and the image inside fills it
   at 100%/100% with object-fit doing the letterboxing.

   Not a grid. In a grid the image is a grid item, and its `block-size: 100%`
   resolves against a row that is itself sized by that image — circular, so
   the percentage is dropped, the picture takes its intrinsic ratio and
   spills out of the box. A block container with a definite height has no
   such circularity. Worth knowing before "tidying" any of these into a
   centred grid. */
.gallery__frame {
  position: relative;
  display: block;
  inline-size: 100%;
  aspect-ratio: 4 / 3;
  padding: var(--space-8);
  border: var(--border-hairline) solid var(--border-subtle);
  border-radius: var(--card-radius);
  background: var(--card-bg);
  overflow: hidden;
  cursor: zoom-in;
  transition: var(--transition-colors);
}
.gallery__frame:hover {
  border-color: var(--border-brand);
}

.gallery__frame img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
  transition: transform var(--duration-slow) var(--ease-out);
}

/* Photographs fill the frame; cutouts must not. Cropping a cutout pushes
   the object's edges outside the box and the silhouette stops reading —
   the same rule the product card follows. */
.gallery__frame--cover {
  padding: 0;
}
.gallery__frame--cover img {
  object-fit: cover;
}

/* Pointer-only: a scale on tap would fight the dialog the frame opens. */
@media (hover: hover) and (pointer: fine) {
  .gallery__frame:hover img {
    transform: scale(1.06);
  }
}

.gallery__zoom {
  position: absolute;
  inset-block-end: var(--space-4);
  inset-inline-end: var(--space-4);
  display: grid;
  place-items: center;
  inline-size: var(--space-10);
  block-size: var(--space-10);
  border: var(--border-hairline) solid var(--border-subtle);
  border-radius: var(--radius-circle);
  background: var(--bg-surface);
  color: var(--fg-muted);
  transition: var(--transition-colors);
}
.gallery__frame:hover .gallery__zoom {
  border-color: transparent;
  background: var(--brand);
  color: var(--fg-on-brand);
}

.gallery__hint {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--gap-inline-sm);
  margin-block-start: var(--space-3);
  color: var(--fg-subtle);
  font-size: var(--text-xs);
}
.gallery__hint .icon {
  font-size: var(--icon-sm);
}

/* A block image frame — see the note on .gallery__frame. */
.gallery__thumb {
  display: block;
  inline-size: 100%;
  aspect-ratio: 1;
  padding: var(--space-1-5);
  border: var(--border-hairline) solid var(--border-default);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  overflow: hidden;
  transition: var(--transition-colors), var(--transition-transform);
}
.gallery__thumb img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
}
.gallery__thumb:hover {
  border-color: var(--border-brand);
  transform: translateY(-2px);
}

/* Two cues, not one: the border colour carries the state for everyone, the
   inner ring makes it survive a greyscale or high-contrast rendering. */
.gallery__thumb.is-active {
  border-color: var(--brand);
  box-shadow: inset 0 0 0 var(--border-thin) var(--brand);
}


/* ==========================================================================
   04 · IDENTITY & OPTIONS
   ========================================================================== */

.pdp-main {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-inline-size: 0;
}

.pdp-eyebrow {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--gap-inline-sm);
}

.pdp-eyebrow__brand,
.pdp-eyebrow__line {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline-xs);
  padding: var(--space-1-5) var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}

.pdp-eyebrow__brand {
  background: var(--bg-brand-subtle);
  color: var(--brand-text);
}

.pdp-eyebrow__line {
  border: var(--border-hairline) solid var(--border-default);
  color: var(--fg-muted);
  transition: var(--transition-colors);
}
.pdp-eyebrow__line:hover {
  border-color: var(--border-brand);
  color: var(--brand-text);
}
.pdp-eyebrow .icon {
  font-size: var(--icon-sm);
}

.pdp-title {
  font-size: var(--text-5xl);
  font-weight: var(--weight-black);
  line-height: var(--leading-tight);
}

.pdp-subtitle {
  margin-block-start: calc(var(--space-3) * -1);
  color: var(--fg-subtle);
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-wide);
}

.pdp-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--gap-inline-md);
  padding-block-end: var(--space-5);
  border-block-end: var(--border-hairline) solid var(--border-subtle);
  color: var(--fg-muted);
  font-size: var(--text-sm);
}

.pdp-meta__rating {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline-sm);
  transition: var(--transition-colors);
}
.pdp-meta__rating:hover .pdp-meta__reviews {
  color: var(--brand-text);
}
.pdp-meta__reviews {
  text-decoration: underline;
  text-decoration-color: var(--border-strong);
  text-underline-offset: 0.25em;
  transition: var(--transition-colors);
}

.pdp-meta__sold {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline-xs);
}
.pdp-meta .icon {
  font-size: var(--icon-sm);
}

.pdp-meta__dot {
  inline-size: var(--space-1);
  block-size: var(--space-1);
  border-radius: var(--radius-circle);
  background: var(--border-strong);
}

.pdp-meta__sku b {
  color: var(--fg-body);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
}

/* ---- Key points ------------------------------------------------------- */
.pdp-points {
  display: grid;
  gap: var(--space-2-5);
  margin: 0;
  color: var(--fg-body);
  font-size: var(--text-lg);
}

.pdp-points li {
  display: flex;
  align-items: flex-start;
  gap: var(--gap-inline-sm);
  line-height: var(--leading-snug);
}

.pdp-points .icon {
  flex: none;
  margin-block-start: 0.2em;
  padding: 0.15em;
  border-radius: var(--radius-circle);
  background: var(--bg-brand-subtle);
  color: var(--brand);
  font-size: var(--icon-md);
}

/* ---- Option groups ---------------------------------------------------- */
.pdp-options {
  display: grid;
  gap: var(--space-5);
  padding-block: var(--space-5);
  border-block: var(--border-hairline) solid var(--border-subtle);
}

.option-group {
  min-inline-size: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.option-group__label {
  display: flex;
  align-items: baseline;
  gap: var(--gap-inline-sm);
  padding: 0;
  margin-block-end: var(--space-3);
  color: var(--fg-muted);
  font-size: var(--text-md);
}

.option-group__value {
  color: var(--fg-default);
  font-weight: var(--weight-bold);
}

.option-group__set {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-inline-sm);
}

.option {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline-sm);
  min-block-size: var(--tap-min);
  padding-inline: var(--space-4);
  border: var(--border-thin) solid var(--border-default);
  border-radius: var(--radius-pill);
  background: var(--bg-surface);
  color: var(--fg-body);
  font-size: var(--text-md);
  font-weight: var(--weight-bold);
  line-height: var(--leading-none);
  white-space: nowrap;
  transition: var(--transition-colors), var(--transition-transform);
}
.option small {
  color: var(--fg-subtle);
  font-size: var(--text-xs);
  font-weight: var(--weight-normal);
  font-variant-numeric: tabular-nums;
}
.option:hover {
  border-color: var(--border-brand);
  color: var(--brand-text);
  transform: translateY(-2px);
}

.option.is-selected {
  border-color: var(--brand);
  background: var(--bg-brand-subtle);
  color: var(--brand-text);
}
.option.is-selected small {
  color: var(--brand-text);
  opacity: 0.75;
}

/* Swatches stand for printed artwork and for the physical colour of the
   ceramic, so — like --brandmark-* and the trust seal in tokens.css — they
   are fixed artefacts that must NOT invert with the theme. That is why
   these are the only rules in this file reaching past the semantic layer.
   A white mug is white in dark mode too. */
.option__swatch {
  inline-size: var(--space-6);
  block-size: var(--space-6);
  border: var(--border-hairline) solid var(--border-inverse);
  border-radius: var(--radius-xs);
}
.option__swatch--candle { background: var(--gradient-brand-vivid); }
.option__swatch--bull   { background: var(--gradient-accent); }
.option__swatch--quote  { background: var(--brandmark-amber); }

.option__dot {
  inline-size: var(--space-5);
  block-size: var(--space-5);
  border: var(--border-hairline) solid var(--border-strong);
  border-radius: var(--radius-circle);
}
.option__dot--white { background: var(--slate-0); }
.option__dot--black { background: var(--slate-1000); }
.option__dot--brand { background: var(--teal-600); }

/* ---- Gift wrap -------------------------------------------------------- */
.giftwrap {
  display: flex;
  align-items: flex-start;
  gap: var(--gap-inline-md);
  padding: var(--space-4);
  border: var(--border-hairline) dashed var(--border-strong);
  border-radius: var(--radius-lg);
  cursor: pointer;
  transition: var(--transition-colors);
}
.giftwrap:hover {
  border-color: var(--brand);
  background: var(--bg-brand-subtle);
}

/* The native box is hidden from sight but not from the accessibility tree
   or the keyboard: it still takes focus, and the drawn box mirrors it. */
.giftwrap__input {
  position: absolute;
  opacity: 0;
  inline-size: 1px;
  block-size: 1px;
}

.giftwrap__box,
.bundle-item__box {
  flex: none;
  display: grid;
  place-items: center;
  inline-size: var(--space-6);
  block-size: var(--space-6);
  border: var(--border-thin) solid var(--border-strong);
  border-radius: var(--radius-xs);
  background: var(--bg-surface);
  color: transparent;
  font-size: var(--icon-sm);
  transition: var(--transition-colors);
}

.giftwrap__input:checked ~ .giftwrap__box,
.bundle-item__input:checked ~ .bundle-item__box {
  border-color: var(--brand);
  background: var(--brand);
  color: var(--fg-on-brand);
}
.giftwrap__input:focus-visible ~ .giftwrap__box,
.bundle-item__input:focus-visible ~ .bundle-item__box {
  outline: var(--ring-width) solid var(--ring-color);
  outline-offset: var(--ring-offset);
}

.giftwrap__text {
  display: grid;
  gap: var(--space-1);
}
.giftwrap__text b {
  display: flex;
  align-items: center;
  gap: var(--gap-inline-sm);
  color: var(--fg-default);
  font-size: var(--text-lg);
}
.giftwrap__text b .icon {
  color: var(--brand);
}
.giftwrap__text small {
  color: var(--fg-muted);
  font-size: var(--text-sm);
}

.pdp-selection {
  color: var(--fg-muted);
  font-size: var(--text-sm);
}
.pdp-selection b {
  color: var(--fg-default);
  font-weight: var(--weight-bold);
}


/* ==========================================================================
   05 · BUY BOX
   ========================================================================== */

/* align-self overrides .pdp's `align-items: start`, and it is what makes the
   sticky child work at all: a sticky element can only travel inside its own
   containing block, so if this column shrank to its content there would be
   nothing to travel through. Stretched, it is as tall as the row. */
.buybox {
  align-self: stretch;
  min-inline-size: 0;
}

/* Sticky, offset by the collapsed header. The scroll padding on the shell
   already clears anchors; this has to clear the header itself. */
.buybox__inner {
  position: sticky;
  inset-block-start: calc(var(--header-height-compact) + var(--space-4));
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  border: var(--border-hairline) solid var(--border-default);
  border-radius: var(--card-radius);
  background: var(--card-bg);
}

.buybox__seller {
  display: flex;
  align-items: center;
  gap: var(--gap-inline-md);
  padding-block-end: var(--space-4);
  border-block-end: var(--border-hairline) solid var(--border-subtle);
}
.buybox__seller-mark {
  flex: none;
  display: grid;
  place-items: center;
  inline-size: var(--space-10);
  block-size: var(--space-10);
  border-radius: var(--radius-circle);
  background: var(--bg-brand-subtle);
  color: var(--brand);
}
.buybox__seller b {
  display: block;
  color: var(--fg-default);
  font-size: var(--text-md);
  font-weight: var(--weight-bold);
}
.buybox__seller small {
  color: var(--fg-subtle);
  font-size: var(--text-xs);
}

.buybox__price {
  display: grid;
  gap: var(--space-2);
}

.buybox__saving {
  display: flex;
  align-items: center;
  gap: var(--gap-inline-xs);
  color: var(--success-text);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
}
.buybox__saving .icon {
  font-size: var(--icon-sm);
}

/* The timer's cells are surface-coloured, so on the card they need a tinted
   bed to sit in or they disappear into it. */
.buybox__countdown {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-inline-sm);
  padding: var(--space-3);
  border-radius: var(--radius-lg);
  background: var(--bg-inset);
}
.buybox__countdown-label {
  display: flex;
  align-items: center;
  gap: var(--gap-inline-xs);
  color: var(--fg-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}
.buybox__countdown-label .icon {
  color: var(--brand);
  font-size: var(--icon-md);
}
.buybox__countdown .timer {
  --timer-cell-w: 2rem;
  --timer-cell-h: 1.875rem;
  --timer-value-size: var(--text-lg);
  gap: var(--space-1);
}
.buybox__countdown .timer__unit small {
  color: var(--fg-subtle);
}
.buybox__countdown .timer__value {
  border: var(--border-hairline) solid var(--border-subtle);
}

/* ---- Stock ------------------------------------------------------------ */
.stock {
  display: grid;
  gap: var(--space-2);
}

.stock__line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-inline-sm);
  font-size: var(--text-sm);
}
.stock__count {
  color: var(--fg-muted);
}
.stock__count b {
  color: var(--warning-text);
  font-weight: var(--weight-extrabold);
  font-variant-numeric: tabular-nums;
}

.stock__bar {
  display: block;
  block-size: var(--space-1-5);
  border-radius: var(--radius-pill);
  background: var(--bg-inset);
  overflow: hidden;
}
/* Amber, not brand: this bar reports scarcity, and painting it in the
   brand colour would read as a progress bar filling up. */
.stock__fill {
  display: block;
  inline-size: var(--stock, 50%);
  block-size: 100%;
  border-radius: inherit;
  background: var(--warning);
}

/* ---- Quantity --------------------------------------------------------- */
.qty {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-inline-md);
}
.qty__label {
  color: var(--fg-muted);
  font-size: var(--text-md);
  font-weight: var(--weight-bold);
}

.qty__control {
  display: flex;
  align-items: center;
  border: var(--border-hairline) solid var(--border-default);
  border-radius: var(--radius-pill);
  background: var(--bg-surface);
  overflow: hidden;
}

.qty__btn {
  display: grid;
  place-items: center;
  inline-size: var(--tap-min);
  block-size: var(--tap-min);
  color: var(--fg-body);
  transition: var(--transition-colors);
}
.qty__btn:hover:not(:disabled) {
  background: var(--bg-brand-subtle);
  color: var(--brand-text);
}
.qty__btn:disabled {
  color: var(--fg-subtle);
  cursor: not-allowed;
}

.qty__input {
  inline-size: 3rem;
  border: 0;
  border-inline: var(--border-hairline) solid var(--border-subtle);
  background: none;
  color: var(--fg-default);
  font-size: var(--text-xl);
  font-weight: var(--weight-extrabold);
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.qty__input:focus-visible {
  outline-offset: calc(var(--ring-offset) * -1);
}

.buybox__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--gap-inline-sm);
  padding-block-start: var(--space-4);
  border-block-start: var(--border-hairline) solid var(--border-subtle);
  color: var(--fg-muted);
  font-size: var(--text-md);
}
.buybox__total b {
  color: var(--fg-default);
  font-size: var(--text-3xl);
  font-weight: var(--weight-black);
  font-variant-numeric: tabular-nums;
}
.buybox__total small {
  color: var(--fg-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
}

.buybox__secondary {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gap-inline-sm);
}
.buybox__secondary .btn {
  font-size: var(--text-md);
  padding-inline: var(--space-3);
}

/* The wishlist control is a full button here rather than the bare heart the
   cards use. .wishlist-btn is declared after .btn in styles.css and would
   otherwise win on every property they share, so the label-bearing shape
   has to be restated: a centred flex row, not a 32px grid cell. */
.wishlist-btn--wide {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--gap-inline-sm);
  inline-size: auto;
  block-size: auto;
  margin-inline-end: 0;
  border-radius: var(--btn-radius);
}
.wishlist-btn--wide[aria-pressed="true"] {
  background: var(--bg-brand-subtle);
  color: var(--brand-text);
}

.assurance-list {
  display: grid;
  gap: var(--space-3);
  margin: 0;
  padding-block-start: var(--space-4);
  border-block-start: var(--border-hairline) solid var(--border-subtle);
}
.assurance-list li {
  display: flex;
  align-items: center;
  gap: var(--gap-inline-md);
  color: var(--fg-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}
.assurance-list b {
  color: var(--fg-default);
  font-weight: var(--weight-bold);
}

.buybox__bulk {
  display: flex;
  align-items: center;
  gap: var(--gap-inline-md);
  padding: var(--space-3-5);
  border-radius: var(--radius-lg);
  background: var(--bg-accent-subtle);
  color: var(--fg-muted);
  font-size: var(--text-xs);
  line-height: var(--leading-snug);
  transition: var(--transition-colors);
}
.buybox__bulk b {
  display: block;
  color: var(--accent-text);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
}
.buybox__bulk > .icon {
  flex: none;
  color: var(--accent-text);
}
.buybox__bulk-go {
  margin-inline-start: auto;
  transition: var(--transition-transform);
}
.buybox__bulk:hover .buybox__bulk-go {
  transform: translateX(-3px);
}


/* ==========================================================================
   06 · HIGHLIGHTS
   --------------------------------------------------------------------------
   The strip that closes the fold. Same idea as .assurance on the home page,
   but per-product rather than per-store, and four across instead of three.
   ========================================================================== */

.pdp-highlights {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--gap-grid);
  margin-block-start: var(--space-10);
  padding: var(--space-5) var(--space-7);
  border: var(--border-hairline) solid var(--border-subtle);
  border-radius: var(--radius-xl);
  background: var(--bg-surface);
}

.pdp-highlight {
  display: flex;
  align-items: center;
  gap: var(--gap-inline-md);
  color: var(--fg-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}
.pdp-highlight b {
  display: block;
  color: var(--fg-default);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
}

/* Divider between tiles, dropped from the last one. Drawn rather than a
   border for the same reason as the best-seller rows: it belongs in the
   gutter, not on the tile. */
.pdp-highlight:not(:last-child) {
  position: relative;
}
.pdp-highlight:not(:last-child)::after {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-end: calc(var(--gap-grid) / -2);
  inline-size: var(--border-hairline);
  background: var(--border-subtle);
}


/* ==========================================================================
   07 · BUNDLE
   ========================================================================== */

.bundle__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 19rem;
  gap: var(--gap-grid-lg);
  align-items: start;
}

.bundle__items {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.bundle__plus {
  display: grid;
  place-items: center;
  inline-size: var(--space-8);
  block-size: var(--space-8);
  margin-inline-start: var(--space-8);
  border-radius: var(--radius-circle);
  background: var(--bg-inset);
  color: var(--fg-subtle);
}

.bundle-item {
  display: flex;
  align-items: center;
  gap: var(--gap-inline-md);
  padding: var(--space-3);
  border: var(--border-hairline) solid var(--border-subtle);
  border-radius: var(--radius-xl);
  background: var(--bg-surface);
  cursor: pointer;
  transition: var(--transition-colors);
}
.bundle-item:hover {
  border-color: var(--border-brand);
}
/* The anchor product is always in the set, so its row states that rather
   than offering a control that cannot be operated. */
.bundle-item:has(.bundle-item__input:disabled) {
  background: var(--bg-surface-2);
  cursor: default;
}
.bundle-item:has(.bundle-item__input:checked) {
  border-color: var(--border-brand);
}

.bundle-item__input {
  position: absolute;
  opacity: 0;
  inline-size: 1px;
  block-size: 1px;
}
.bundle-item__input:disabled ~ .bundle-item__box {
  opacity: 0.6;
}

/* A block image frame — see the note on .gallery__frame. */
.bundle-item__media {
  flex: none;
  display: block;
  inline-size: var(--space-16);
  block-size: var(--space-16);
  padding: var(--space-1);
  border-radius: var(--radius-md);
  background: var(--bg-surface-2);
}
.bundle-item__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
}

.bundle-item__text {
  display: grid;
  gap: var(--space-0-5);
  min-inline-size: 0;
}
.bundle-item__text b {
  color: var(--fg-default);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
}
.bundle-item__text small {
  color: var(--fg-subtle);
  font-size: var(--text-xs);
}

.bundle-item__price {
  margin-inline-start: auto;
  padding-inline-start: var(--space-3);
  color: var(--fg-default);
  font-size: var(--text-lg);
  font-weight: var(--weight-extrabold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.bundle-item:has(.bundle-item__input:not(:checked)) .bundle-item__price,
.bundle-item:has(.bundle-item__input:not(:checked)) .bundle-item__text b {
  color: var(--fg-subtle);
}

/* The dark editorial panel, borrowed from the store-picks block on the home
   page so the two read as the same family. */
.bundle__summary {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-6);
  border-radius: var(--panel-radius);
  background: var(--panel-bg);
  color: var(--panel-fg);
}

.bundle__count {
  font-size: var(--text-sm);
  opacity: 0.8;
}
.bundle__count b {
  font-weight: var(--weight-extrabold);
  font-variant-numeric: tabular-nums;
}

.bundle__sum,
.bundle__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--gap-inline-sm);
  font-size: var(--text-md);
}
.bundle__sum {
  opacity: 0.75;
  font-variant-numeric: tabular-nums;
}
.bundle__total {
  padding-block-start: var(--space-3);
  border-block-start: var(--border-hairline) solid var(--border-inverse);
}
.bundle__total b {
  font-size: var(--text-4xl);
  font-weight: var(--weight-black);
  font-variant-numeric: tabular-nums;
}
.bundle__total small {
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  opacity: 0.8;
}

.bundle__saving {
  display: flex;
  align-items: center;
  gap: var(--gap-inline-xs);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-pill);
  background: oklch(0 0 0 / 0.18);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
}
.bundle__saving .icon {
  font-size: var(--icon-md);
}

.bundle__summary .btn--primary {
  margin-block-start: var(--space-1);
}


/* ==========================================================================
   08 · DETAILS TABS
   ========================================================================== */

.tabs__list {
  display: flex;
  gap: var(--gap-inline-sm);
  /* Room for the hover lift and the focus ring, which would otherwise be
     clipped by the horizontal scroll container. */
  padding-block: var(--space-1);
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs__list::-webkit-scrollbar {
  display: none;
}

.tab {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline-sm);
  flex: none;
  min-block-size: var(--btn-height);
  padding-inline: var(--space-5);
  border: var(--border-hairline) solid var(--border-default);
  border-radius: var(--radius-pill);
  background: var(--bg-surface);
  color: var(--fg-muted);
  font-size: var(--btn-font-size);
  font-weight: var(--weight-bold);
  white-space: nowrap;
  transition: var(--transition-colors), var(--transition-transform);
}
.tab:hover {
  border-color: var(--border-brand);
  color: var(--brand-text);
  transform: translateY(-2px);
}
.tab .icon {
  color: var(--fg-subtle);
  transition: var(--transition-colors);
}
.tab:hover .icon {
  color: var(--brand);
}

.tab.is-active,
.tab.is-active:hover {
  border-color: transparent;
  background: var(--gradient-brand-vivid);
  color: var(--fg-on-brand);
  transform: none;
}
.tab.is-active .icon {
  color: inherit;
}

.tabs__panel {
  margin-block-start: var(--space-5);
  padding: var(--space-8);
  border: var(--border-hairline) solid var(--border-subtle);
  border-radius: var(--card-radius);
  background: var(--bg-surface);
}
.tabs__panel[hidden] {
  display: none;
}

/* ---- Description ------------------------------------------------------
   Copy sits at a readable measure and the leftover width carries the
   packing list rather than being left as dead space — a 1360px panel with
   a 60ch column in it reads as a layout that failed, not as breathing
   room. */
.desc {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 21rem;
  gap: var(--gap-grid-lg);
  align-items: start;
}

.desc__aside {
  display: grid;
  gap: var(--space-4);
  padding: var(--space-5);
  border: var(--border-hairline) solid var(--border-subtle);
  border-radius: var(--radius-xl);
  background: var(--bg-surface-2);
}
.desc__aside h3 {
  display: flex;
  align-items: center;
  gap: var(--gap-inline-sm);
  font-size: var(--text-2xl);
}
.desc__aside h3 .icon {
  color: var(--brand);
}
.desc__aside .prose__list li {
  color: var(--fg-body);
  font-size: var(--text-md);
  line-height: var(--leading-snug);
}

/* A block image frame — see the note on .gallery__frame. */
.desc__media {
  display: block;
  block-size: 9rem;
  padding: var(--space-3);
  border-radius: var(--radius-lg);
  background: var(--bg-surface);
}
.desc__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
}

/* ---- Prose ------------------------------------------------------------ */
.prose {
  max-inline-size: 62ch;
  color: var(--fg-body);
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
}
.prose > * + * {
  margin-block-start: var(--space-5);
}
.prose h3 {
  font-size: var(--text-3xl);
  font-weight: var(--weight-extrabold);
}

.prose__quote {
  display: flex;
  align-items: flex-start;
  gap: var(--gap-inline-md);
  margin-inline: 0;
  padding: var(--space-5);
  border-inline-start: var(--border-heavy) solid var(--brand);
  border-radius: var(--radius-md);
  background: var(--bg-brand-subtle);
  color: var(--fg-default);
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  line-height: var(--leading-snug);
}
.prose__quote .icon {
  flex: none;
  margin-block-start: 0.15em;
  color: var(--brand);
}

.prose__list {
  display: grid;
  gap: var(--space-2-5);
  margin: 0;
  padding: 0;
}
.prose__list li {
  position: relative;
  padding-inline-start: var(--space-6);
  font-size: var(--text-md);
}
.prose__list li::before {
  content: "";
  position: absolute;
  inset-block-start: 0.6em;
  inset-inline-start: 0;
  inline-size: var(--space-2);
  block-size: var(--space-2);
  border-radius: var(--radius-circle);
  background: var(--brand);
}

/* ---- Spec table ------------------------------------------------------- */
.spec-table {
  inline-size: 100%;
  border-collapse: collapse;
  font-size: var(--text-md);
}
.spec-table tr + tr {
  border-block-start: var(--border-hairline) solid var(--border-subtle);
}
.spec-table th,
.spec-table td {
  padding: var(--space-3) var(--space-2);
  text-align: start;
  vertical-align: top;
}
.spec-table th {
  inline-size: 32%;
  color: var(--fg-muted);
  font-weight: var(--weight-medium);
}
.spec-table td {
  color: var(--fg-default);
  font-weight: var(--weight-bold);
}

/* ---- Care ------------------------------------------------------------- */
.care {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gap-grid-lg);
}

.care__col h3 {
  display: flex;
  align-items: center;
  gap: var(--gap-inline-sm);
  margin-block-end: var(--space-4);
  font-size: var(--text-2xl);
}
.care__col ul {
  display: grid;
  gap: var(--space-2-5);
  margin: 0;
  color: var(--fg-body);
  font-size: var(--text-md);
}
.care__col li {
  position: relative;
  padding-inline-start: var(--space-6);
  line-height: var(--leading-snug);
}
.care__col li::before {
  content: "";
  position: absolute;
  inset-block-start: 0.55em;
  inset-inline-start: 0;
  inline-size: var(--space-2);
  block-size: var(--space-2);
  border-radius: var(--radius-circle);
}

.care__col--do h3 .icon    { color: var(--success); }
.care__col--do li::before  { background: var(--success); }
.care__col--dont h3 .icon  { color: var(--danger); }
.care__col--dont li::before { background: var(--danger); }

.care__note,
.shipping__note {
  display: flex;
  align-items: flex-start;
  gap: var(--gap-inline-md);
  margin-block-start: var(--space-6);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  background: var(--bg-inset);
  color: var(--fg-muted);
  font-size: var(--text-md);
  line-height: var(--leading-snug);
}
.care__note .icon,
.shipping__note .icon {
  flex: none;
  margin-block-start: 0.1em;
  color: var(--brand);
}

/* ---- Shipping --------------------------------------------------------- */
.shipping__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gap-grid);
  margin: 0;
}
.shipping__list li {
  display: flex;
  align-items: flex-start;
  gap: var(--gap-inline-md);
  color: var(--fg-muted);
  font-size: var(--text-md);
  line-height: var(--leading-snug);
}
.shipping__list b {
  display: block;
  margin-block-end: var(--space-1);
  color: var(--fg-default);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
}


/* ==========================================================================
   09 · REVIEWS
   ========================================================================== */

.reviews__body {
  display: grid;
  grid-template-columns: 20rem minmax(0, 1fr);
  gap: var(--gap-grid-lg);
  align-items: start;
}

.review-summary {
  display: grid;
  gap: var(--space-5);
  padding: var(--space-6);
  border: var(--border-hairline) solid var(--border-subtle);
  border-radius: var(--card-radius);
  background: var(--bg-surface);
}

.review-summary__score {
  display: grid;
  justify-items: center;
  gap: var(--space-1);
  text-align: center;
}
.review-summary__score b {
  color: var(--fg-default);
  font-size: var(--text-6xl);
  font-weight: var(--weight-black);
  line-height: var(--leading-none);
  font-variant-numeric: tabular-nums;
}
.review-summary__stars {
  display: flex;
  gap: var(--space-0-5);
  color: var(--rating);
  font-size: var(--icon-md);
}
.review-summary__score small {
  color: var(--fg-subtle);
  font-size: var(--text-sm);
}

.review-bars {
  display: grid;
  gap: var(--space-2);
}

.review-bar {
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr) 2rem;
  align-items: center;
  gap: var(--gap-inline-sm);
  color: var(--fg-muted);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
}
.review-bar__track {
  block-size: var(--space-1-5);
  border-radius: var(--radius-pill);
  background: var(--bg-inset);
  overflow: hidden;
}
.review-bar__fill {
  display: block;
  inline-size: var(--pct, 0%);
  block-size: 100%;
  border-radius: inherit;
  background: var(--rating);
}
.review-bar__count {
  text-align: end;
}

.review-summary__recommend {
  display: flex;
  align-items: center;
  gap: var(--gap-inline-sm);
  padding-block-start: var(--space-4);
  border-block-start: var(--border-hairline) solid var(--border-subtle);
  color: var(--fg-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}
.review-summary__recommend .icon {
  flex: none;
  color: var(--success);
}
.review-summary__recommend b {
  color: var(--fg-default);
  font-weight: var(--weight-extrabold);
}

/* ---- List & filters --------------------------------------------------- */
.review-list {
  display: grid;
  gap: var(--space-4);
  align-content: start;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-inline-sm);
}

.chip {
  display: inline-flex;
  align-items: center;
  min-block-size: var(--space-9);
  padding-inline: var(--space-4);
  border: var(--border-hairline) solid var(--border-default);
  border-radius: var(--radius-pill);
  background: var(--bg-surface);
  color: var(--fg-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  transition: var(--transition-colors);
}
.chip:hover {
  border-color: var(--border-brand);
  color: var(--brand-text);
}
.chip.is-active {
  border-color: transparent;
  background: var(--accent);
  color: var(--fg-on-accent);
}

.review-list__status {
  color: var(--fg-subtle);
  font-size: var(--text-xs);
}

.review {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-5);
  border: var(--border-hairline) solid var(--border-subtle);
  border-radius: var(--card-radius);
  background: var(--bg-surface);
  transition: var(--transition-colors);
}
.review:hover {
  border-color: var(--border-default);
}
.review[hidden] {
  display: none;
}

.review__head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--gap-inline-md);
}

.review__avatar {
  flex: none;
  display: grid;
  place-items: center;
  inline-size: var(--space-11);
  block-size: var(--space-11);
  border-radius: var(--radius-circle);
  background: var(--bg-brand-subtle);
  color: var(--brand-text);
  font-size: var(--text-2xl);
  font-weight: var(--weight-extrabold);
}

.review__who {
  display: grid;
  gap: var(--space-0-5);
}
.review__who b {
  color: var(--fg-default);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
}

.review__badge {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline-xs);
  color: var(--success-text);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}
.review__badge .icon {
  font-size: var(--icon-sm);
}
.review__badge--guest {
  color: var(--fg-subtle);
  font-weight: var(--weight-normal);
}

.review__stars {
  display: flex;
  gap: var(--space-0-5);
  margin-inline-start: auto;
  color: var(--rating);
  font-size: var(--icon-sm);
}
/* The unfilled remainder of a rating still has to be visible, or a 3-star
   review reads as a 3-star scale. */
.review__stars .icon:not(.icon--fill) {
  color: var(--border-strong);
  fill: currentColor;
  stroke: none;
}

.review__date {
  color: var(--fg-subtle);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
}

.review__variant {
  color: var(--fg-subtle);
  font-size: var(--text-xs);
}

.review__body {
  color: var(--fg-body);
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
}

.review__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-inline-sm);
}

.review-tag {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-2-5);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}
.review-tag--pro {
  background: var(--success-subtle);
  color: var(--success-text);
}
.review-tag--con {
  background: var(--warning-subtle);
  color: var(--warning-text);
}

.review__foot {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--gap-inline-md);
  padding-block-start: var(--space-3);
  border-block-start: var(--border-hairline) solid var(--border-subtle);
  color: var(--fg-subtle);
  font-size: var(--text-xs);
}

.review__vote {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline-xs);
  min-block-size: var(--space-8);
  padding-inline: var(--space-3);
  border: var(--border-hairline) solid var(--border-default);
  border-radius: var(--radius-pill);
  color: var(--fg-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  transition: var(--transition-colors);
}
.review__vote:hover {
  border-color: var(--border-brand);
  background: var(--bg-brand-subtle);
  color: var(--brand-text);
}
.review__vote.is-voted {
  border-color: transparent;
  background: var(--bg-brand-subtle);
  color: var(--brand-text);
}

.review-list__empty {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--gap-inline-md);
  padding: var(--space-12);
  border: var(--border-hairline) dashed var(--border-strong);
  border-radius: var(--card-radius);
  color: var(--fg-subtle);
  font-size: var(--text-lg);
}
.review-list__empty[hidden] {
  display: none;
}


/* ==========================================================================
   10 · RELATED RAIL
   --------------------------------------------------------------------------
   .rail and .product-card do the work; only the card width is this
   section's business.
   ========================================================================== */

.related-rail {
  --rail-gap: var(--space-6);
}


/* ==========================================================================
   11 · STICKY BUY BAR
   --------------------------------------------------------------------------
   Floats over arbitrary page content, so it is one of the few things in
   this design allowed an elevation token — the same licence the toast and
   the drawer have.
   ========================================================================== */

.buybar {
  position: fixed;
  z-index: var(--z-sticky);
  inset-block-end: 0;
  inset-inline: 0;
  padding: var(--space-3) var(--container-inline);
  border-block-start: var(--border-hairline) solid var(--border-default);
  background: var(--header-bg-scrolled);
  box-shadow: var(--shadow-overlay);
  animation: buybar-in var(--duration-base) var(--ease-out);
}
.buybar[hidden] {
  display: none;
}

@supports (backdrop-filter: blur(1px)) {
  .buybar {
    backdrop-filter: blur(var(--header-blur)) saturate(160%);
  }
}

@keyframes buybar-in {
  from { translate: 0 100%; }
  to   { translate: 0 0; }
}

.buybar__inner {
  display: flex;
  align-items: center;
  gap: var(--gap-inline-lg);
}

.buybar__product {
  display: flex;
  align-items: center;
  gap: var(--gap-inline-md);
  min-inline-size: 0;
}
/* A block image frame — see the note on .gallery__frame. */
.buybar__media {
  flex: none;
  display: block;
  inline-size: var(--space-12);
  block-size: var(--space-12);
  padding: var(--space-1);
  border-radius: var(--radius-md);
  background: var(--bg-surface-2);
}
.buybar__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
}
.buybar__text {
  display: grid;
  gap: var(--space-0-5);
  min-inline-size: 0;
}
.buybar__text b {
  color: var(--fg-default);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
}
.buybar__text small {
  color: var(--fg-subtle);
  font-size: var(--text-xs);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.buybar__price {
  margin-inline-start: auto;
  display: flex;
  align-items: baseline;
  gap: var(--gap-inline-sm);
  color: var(--fg-muted);
  font-size: var(--text-xs);
  white-space: nowrap;
}
.buybar__price b {
  color: var(--fg-default);
  font-size: var(--text-2xl);
  font-weight: var(--weight-black);
  font-variant-numeric: tabular-nums;
}
.buybar__price small {
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
}


/* ==========================================================================
   12 · LIGHTBOX
   ========================================================================== */

.lightbox {
  position: fixed;
  z-index: var(--z-modal);
  inset: 0;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--gap-inline-lg);
  padding: var(--space-6) var(--container-inline);
  background: var(--overlay);
  animation: lightbox-in var(--duration-base) var(--ease-out);
}
.lightbox[hidden] {
  display: none;
}

@supports (backdrop-filter: blur(1px)) {
  .lightbox {
    backdrop-filter: blur(6px);
  }
}

@keyframes lightbox-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.lightbox__figure {
  display: grid;
  justify-items: center;
  gap: var(--space-4);
  margin: 0;
  min-inline-size: 0;
}
.lightbox__figure img {
  max-block-size: 72vh;
  inline-size: auto;
  border-radius: var(--card-radius);
  background: var(--bg-surface);
  object-fit: contain;
}

/* Carries its own dark chip rather than trusting the scrim: --overlay is
   only 42% opaque, so over a light page the caption would sit on whatever
   happens to be behind it. Fixed light-on-dark, and deliberately not
   theme-following — the same exception the trust seal takes in tokens.css. */
.lightbox__caption {
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  background: oklch(0 0 0 / 0.55);
  color: var(--slate-0);
  font-size: var(--text-md);
  text-align: center;
}

.lightbox__close,
.lightbox__nav {
  display: grid;
  place-items: center;
  inline-size: var(--btn-height-lg);
  block-size: var(--btn-height-lg);
  border: var(--border-hairline) solid var(--border-inverse);
  border-radius: var(--radius-circle);
  background: oklch(0 0 0 / 0.35);
  color: var(--slate-0);
  transition: var(--transition-colors), var(--transition-transform);
}
.lightbox__close:hover,
.lightbox__nav:hover {
  background: var(--brand);
  border-color: transparent;
  transform: scale(1.06);
}

.lightbox__close {
  position: absolute;
  inset-block-start: var(--space-5);
  inset-inline-end: var(--space-5);
}

.lightbox__nav--prev { grid-column: 1; }
.lightbox__figure    { grid-column: 2; }
.lightbox__nav--next { grid-column: 3; }


/* ==========================================================================
   13 · RESPONSIVE
   --------------------------------------------------------------------------
   Same breakpoints as styles.css, so the two sheets reflow together.
   ========================================================================== */

@media (max-width: 1240px) {
  .pdp {
    --pdp-col-gallery: 26rem;
    --pdp-col-buy: 19.5rem;
    gap: var(--space-6);
  }
}

/* The three-column fold stops working before the header does: the middle
   column runs out of room for a pill row of options first. Gallery and copy
   pair up, and the buy box takes the full width beneath them — where it no
   longer needs to be sticky, because it is a screen tall. */
@media (max-width: 1150px) {
  .pdp {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
  .buybox {
    grid-column: 1 / -1;
  }
  .buybox__inner {
    position: static;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--space-8);
    align-items: start;
  }
  .buybox__seller,
  .buybox__bulk {
    grid-column: 1 / -1;
  }
  .assurance-list {
    grid-column: 1 / -1;
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .bundle__body {
    grid-template-columns: minmax(0, 1fr);
  }
  .reviews__body {
    grid-template-columns: minmax(0, 1fr);
  }
  .review-summary {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: center;
  }
  .review-summary__recommend {
    grid-column: 1 / -1;
  }
}

@media (max-width: 800px) {
  .breadcrumb__back {
    display: none;
  }

  .pdp {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-8);
  }

  /* Thumbnails become a swipeable strip under the frame. */
  .gallery {
    grid-template-columns: minmax(0, 1fr);
  }
  .gallery__stage {
    grid-column: 1;
    grid-row: 1;
  }
  .gallery__thumbs {
    grid-column: 1;
    grid-row: 2;
    flex-direction: row;
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    scrollbar-width: none;
  }
  .gallery__thumbs::-webkit-scrollbar {
    display: none;
  }
  .gallery__thumb {
    flex: 0 0 4.5rem;
  }

  .pdp-title {
    font-size: var(--text-4xl);
  }

  .buybox__inner {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
  }
  .assurance-list {
    grid-template-columns: minmax(0, 1fr);
  }

  .pdp-highlights {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--gap-inline-lg);
    padding: var(--space-5);
  }
  /* The drawn divider assumes one row. */
  .pdp-highlight:not(:last-child)::after {
    display: none;
  }

  .tabs__panel {
    padding: var(--space-5);
  }
  .desc,
  .care,
  .shipping__list {
    grid-template-columns: minmax(0, 1fr);
  }

  .review-summary {
    grid-template-columns: minmax(0, 1fr);
  }
  .review__stars {
    margin-inline-start: 0;
    inline-size: 100%;
    order: 3;
  }

  /* On a phone the bar is the primary buy control, so the price and the
     button take the width and the product identity steps aside. The price
     also stacks its label over its value: side by side, the two of them
     plus a full-width button overrun a 390px viewport and the button's
     label gets cut off at the edge. */
  .buybar__product {
    display: none;
  }
  .buybar__price {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    margin-inline-start: 0;
  }
  .buybar__inner .btn {
    flex: 1;
    min-inline-size: 0;
    padding-inline: var(--space-4);
  }

  .lightbox {
    grid-template-columns: minmax(0, 1fr);
    padding-block: var(--space-16) var(--space-6);
  }
  .lightbox__figure {
    grid-column: 1;
    grid-row: 1;
  }
  .lightbox__nav {
    grid-row: 2;
  }
  .lightbox__nav--prev { grid-column: 1; justify-self: start; }
  .lightbox__nav--next { grid-column: 1; justify-self: end; }
}

@media (max-width: 540px) {
  .pdp-highlights {
    grid-template-columns: minmax(0, 1fr);
  }
  .buybar__price b {
    font-size: var(--text-xl);
  }
  .breadcrumb__list {
    font-size: var(--text-xs);
  }
  .option {
    padding-inline: var(--space-3);
  }
  .review__head {
    gap: var(--gap-inline-sm);
  }
  .tabs__panel {
    padding: var(--space-4);
  }
  .prose {
    font-size: var(--text-md);
  }
}


/* ==========================================================================
   14 · MOTION, CONTRAST & PRINT
   --------------------------------------------------------------------------
   styles.css §29 covers everything the two pages share; these are the
   product page's own components, handled the same way.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .gallery__frame img,
  .buybar,
  .lightbox {
    animation: none;
    transition: none;
  }
  .gallery__frame:hover img {
    transform: none;
  }
  .gallery__thumb:hover,
  .option:hover,
  .tab:hover {
    transform: none;
  }
}

@media (prefers-contrast: more) {
  .gallery__frame,
  .gallery__thumb,
  .tabs__panel,
  .review,
  .review-summary,
  .bundle-item,
  .buybox__inner {
    border-width: var(--border-thick);
  }
}

/* Colour is gone here, so every state that is carried by a fill needs an
   outline instead — otherwise the selected swatch, the active tab and the
   chosen filter all look exactly like the unselected ones. */
@media (forced-colors: active) {
  .gallery__frame,
  .tabs__panel,
  .review,
  .review-summary,
  .bundle-item,
  .buybox__inner,
  .buybar {
    border: 1px solid CanvasText;
  }
  .gallery__thumb.is-active,
  .option.is-selected,
  .chip.is-active,
  .tab.is-active {
    border: var(--border-thick) solid Highlight;
  }
  .stock__fill,
  .review-bar__fill {
    background: Highlight;
  }
}

@media print {
  /* Nothing here survives paper: the bar and the viewer are both
     interaction, and a printed spec sheet wants every panel open. */
  .buybar,
  .lightbox,
  .gallery__thumbs,
  .tabs__list,
  .buybox__countdown {
    display: none !important;
  }
  .tabs__panel[hidden] {
    display: block !important;
  }
  .pdp {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
  .buybox__inner {
    position: static;
  }
}
