/**
 * Product page — Shivshakti.
 *
 * A warm, paper-and-ember treatment: Cormorant Garamond for anything that is a
 * name, Manrope for everything that is information. Written mobile-first; the
 * two-column desktop layout is the enhancement, not the base.
 *
 * Three things this file is careful about:
 *
 *  - **It does not invent markup.** Every selector below matches HTML the
 *    plugin already emits, so nothing here depends on a template change and
 *    pdp.js keeps finding what it looks for.
 *  - **It re-points the shared tokens rather than restating them.** Mapping
 *    --gms-* onto the Shivshakti palette inside .gms-pdp means reviews.css,
 *    compare.css and the product card re-theme themselves. Anything that
 *    disagrees is overridden with a .gms-pdp prefix, because reviews.css loads
 *    after this file and would otherwise win.
 *  - **The palette is the mock's, corrected for contrast.** The mock's muted
 *    greys (#A49C90, #AAA39A) and its ember-on-cream text sit between 2.1:1 and
 *    2.9:1, and white on the saffron gradient is 2.2:1 at the light end. The
 *    hues are kept; the values are taken down until body text clears 4.5:1 and
 *    UI edges clear 3:1. The bright ember and amber survive as fills, strokes,
 *    rings and glows, which is where they were doing the work anyway.
 */

/* ============================================================== fonts === */

/* Self-hosted, subset to latin + latin-ext. Both faces are variable, so one
   file per subset covers every weight the page uses. latin-ext is not optional
   here: U+20B9 — the rupee sign, i.e. the first character of every price on
   the page — lives in that subset, not in latin. */

@font-face {
  font-family: 'GMS Manrope';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url(fonts/manrope-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'GMS Manrope';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url(fonts/manrope-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'GMS Cormorant Garamond';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(fonts/cormorant-garamond-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'GMS Cormorant Garamond';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(fonts/cormorant-garamond-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ============================================================= tokens === */

.gms-pdp,
.gms-pdpbar {
  /* --- surfaces --- */
  --ss-paper:      #fcfbf7;
  --ss-sand:       #f7f2e8;
  --ss-shell:      #f4efe5;
  --ss-white:      #ffffff;
  --ss-night:      #151412;

  /* --- ink. Contrast against --ss-paper is given for each. --- */
  --ss-ink:        #151412;  /* 17.8:1 */
  --ss-ink-2:      #57524a;  /*  7.5:1  body copy               */
  --ss-ink-3:      #6f6a61;  /*  5.2:1  labels, meta, MRP       */
  --ss-hair:       #a49c90;  /*  2.6:1  DECORATION ONLY — rules and aria-hidden separators, never text */

  --ss-line:       #e8e1d4;
  --ss-line-2:     #ded8cd;

  /* --- accent. Two embers on purpose: the bright one is a fill and a stroke,
         the deep one is the only one allowed to be text or to sit under white
         text. Using the bright one for either is how the mock ends up at
         2.9:1. --- */
  --ss-ember:      #f46c04;  /* fills, rings, glows, focus marks   */
  --ss-ember-ink:  #b4470a;  /* 5.3:1 as text · 5.5:1 under white  */
  --ss-ember-soft: rgba(244, 108, 4, .08);
  --ss-cta-a:      #a83e05;  /* gradient start · white on it 6.3:1 */
  --ss-cta-b:      #b05f02;  /* gradient end   · white on it 4.7:1 */
  --ss-amber:      #fa9804;  /* decorative only                    */
  --ss-star:       #b8720a;  /* 3.6:1 — a graphic, so 3:1 is the bar */
  --ss-lemon:      #f8f87d;  /* pill ground; ink on it is 16:1     */
  --ss-indigo:     #2408df;  /* 9.3:1 links and focus              */
  --ss-green:      #178154;  /* 4.7:1 savings                      */
  --ss-green-deep: #146f49;  /* 5.4:1 on the 10% green wash below  */
  --ss-red:        #a52218;

  --ss-r:          14px;
  --ss-r-lg:       22px;
  --ss-r-xl:       28px;
  --ss-pill:       50px;

  --ss-lift:       0 2px 4px rgba(24, 19, 13, .03), 0 22px 55px rgba(24, 19, 13, .07);
  --ss-lift-sm:    0 1px 2px rgba(24, 19, 13, .04), 0 10px 26px rgba(24, 19, 13, .06);

  --ss-sans:       'GMS Manrope', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --ss-serif:      'GMS Cormorant Garamond', ui-serif, Georgia, 'Times New Roman', serif;

  /* --- The shared storefront tokens, re-pointed. Everything that reads
         --gms-* inside the product page — reviews.css, compare.css, the
         product card, the delivery checker — comes along without knowing
         this file exists. --- */
  --gms-ink:          var(--ss-ink);
  --gms-ink-2:        var(--ss-ink-2);
  --gms-ink-3:        var(--ss-ink-3);
  --gms-ink-soft:     var(--ss-ink-3);
  --gms-muted:        var(--ss-ink-3);
  --gms-muted-strong: var(--ss-ink-2);
  --gms-line:         var(--ss-line);
  --gms-line-2:       var(--ss-line);
  --gms-surface:      var(--ss-white);
  --gms-tint:         var(--ss-sand);
  --gms-sunken:       var(--ss-shell);
  --gms-accent:       var(--ss-ember-ink);
  --gms-accent-ink:   var(--ss-white);
  --gms-accent-soft:  var(--ss-ember-soft);
  --gms-good:         var(--ss-green);
  --gms-good-soft:    rgba(23, 129, 84, .09);
  --gms-warn:         #8a5008;
  --gms-bad:          var(--ss-red);
  --gms-r:            var(--ss-r);
  --gms-r-lg:         var(--ss-r-lg);
  --gms-radius:       var(--ss-r);
  --gms-r-pill:       var(--ss-pill);
  --gms-shadow:       var(--ss-lift-sm);
  --gms-shadow-lg:    var(--ss-lift);
}

/* The brand-colour rule in ProductGridModule::paletteCss() sets --gms-accent on
   .gms-delivery-check directly, which beats inheriting from .gms-pdp. Inside
   the product page the page's own accent wins. */
.gms-pdp .gms-delivery-check {
  --gms-accent:     var(--ss-ember-ink);
  --gms-accent-ink: var(--ss-white);
}

/* The theme is not guaranteed to set a border-box default, and without it the
   page padding is added to a full-width block and overflows the viewport. */
.gms-pdp,
.gms-pdp *,
.gms-pdpbar,
.gms-pdpbar * { box-sizing: border-box; }

/* ================================================================ base === */

.gms-pdp {
  --gms-pdp-gap: 28px;

  max-width: 1420px;
  margin: 0 auto;
  padding: 16px 16px calc(96px + var(--gms-bottom-chrome, 0px));
  background: var(--ss-paper);
  font-family: var(--gms-font, var(--ss-sans));
  color: var(--ss-ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* The page's default link colour — and only for links that have not been
   given a colour of their own.
   
   `.gms-pdp a` is (0,1,1) and `.gms-pdp a:hover` is (0,2,1), which is more
   specific than a single component class. Three separate controls have been
   made unreadable by it: the offer ribbon rendered black on black, and the
   membership "Join for ₹99" button turned ember text on an ember background
   the moment a pointer touched it. Each was fixed by out-specifying it, and
   the next component to paint its own link will hit exactly the same wall.
   
   :not() takes the specificity of its argument, so listing the components here
   costs nothing and stops the rule reaching into them at all. A component that
   paints its own text now simply wins. */
.gms-pdp a:not([class*="gms-card-p__"]):not([class*="__member"]):not([class*="__quote"]) {
  color: var(--ss-ink);
  text-decoration: none;
}

.gms-pdp a:not([class*="gms-card-p__"]):not([class*="__member"]):not([class*="__quote"]):hover {
  color: var(--ss-ember-ink);
}

/* One focus ring for the whole page, in the indigo that is already the link
   colour, so a keyboard visitor sees the same signal everywhere. */
.gms-pdp :focus-visible,
.gms-pdpbar :focus-visible {
  outline: 2px solid var(--ss-indigo);
  outline-offset: 3px;
  border-radius: 4px;
}

.gms-pdp ::selection { background: var(--ss-lemon); color: var(--ss-ink); }

/* The eyebrow: a small caps line over a heading, with the rotated square that
   runs through the design as its bullet. */
.gms-pdp__eyebrow {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
  font-family: var(--ss-sans);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .16em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--ss-ember-ink);
}

.gms-pdp__eyebrow a { color: inherit; }
.gms-pdp__eyebrow a:hover { text-decoration: underline; text-underline-offset: 4px; }

.gms-pdp__mark {
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  transform: rotate(45deg);
  border: 1px solid var(--ss-amber);
}

/* ========================================================= breadcrumb === */

.gms-pdp__crumbs {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 16px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: .04em;
  color: var(--ss-ink-3);
}

.gms-pdp__crumbs a { color: var(--ss-ink-3); }
.gms-pdp__crumbs a:hover { color: var(--ss-ember-ink); text-decoration: underline; text-underline-offset: 3px; }
.gms-pdp__crumbs [aria-hidden] { color: var(--ss-hair); }

.gms-pdp__crumbs-current {
  color: var(--ss-ink);
  font-weight: 600;
  /* Long product names must not push the crumb trail into two awkward lines. */
  max-width: 22ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ============================================================= layout === */

.gms-pdp__grid {
  display: grid;
  /* minmax(0, 1fr), not 1fr: a plain 1fr track takes its minimum from the
     widest unbreakable child, which pushes the column past the viewport. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--gms-pdp-gap);
  align-items: start;
}

/* ============================================================ gallery === */

/* Centred, because the height cap decides the width.

   max-height plus an aspect-ratio means the stage is often narrower than the
   column it sits in: at 30vh on a 812px-tall phone that is 244px of height,
   which at 4:3 comes out 325px wide inside a 343px column. A block element
   defaults to flush left, so the photograph sat 16px from the left edge and
   34px from the right — it read as the image having slipped sideways, and on a
   product page the photograph is the thing being looked at.

   margin-inline: auto costs nothing when the stage does fill the column. */
.gms-pdp__stage {
  position: relative;
  aspect-ratio: var(--gms-pdp-ratio-mobile, 4 / 3);
  max-height: var(--gms-pdp-image-cap, 30vh);
  margin-inline: auto;
  border-radius: var(--ss-r-lg);
  overflow: hidden;
  background: var(--ss-shell);
  box-shadow: var(--ss-lift-sm);
}

/* No photographs at all. Drawn rather than left blank, because an empty box
   with a border reads as a failed image, and the diagonal weave is the same
   texture the design uses behind every placeholder. */
/* See the note in frontend.css: hatching reads as a broken image, and at this
   size — the main product photograph — it reads as it loudest. */
.gms-pdp__stage--empty {
  background-color: var(--ss-shell, #f4f2ef);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='72' height='72' viewBox='0 0 24 24' fill='none' stroke='%23c3bbae' stroke-width='1.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='14' rx='2.5'/%3E%3Ccircle cx='8.5' cy='10' r='1.5'/%3E%3Cpath d='M21 16l-5-5-6 6-2-2-5 4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 72px auto;
}

.gms-pdp__stage img,
.gms-pdp__stage video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.gms-pdp__stage video { background: #000; }
.gms-pdp__stage [hidden] { display: none; }

/* ---- Flags ---- */

.gms-pdp__flags {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  /* The stack must not run under the wishlist button in the opposite corner. */
  max-width: calc(100% - 66px);
}

.gms-pdp__badge {
  padding: 7px 11px;
  border-radius: var(--ss-pill);
  background: var(--ss-ember-ink);
  color: var(--ss-white);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .07em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
}

.gms-pdp__badge--new { background: var(--ss-night); }
.gms-pdp__badge--out { background: var(--ss-red); }

/* ---- Wishlist ---- */

.gms-pdp__wish {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 2;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, .92);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  box-shadow: 0 8px 24px rgba(24, 19, 13, .12);
  color: var(--ss-ink);
  cursor: pointer;
  transition: color .2s ease;
}

.gms-pdp__wish svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.6; }
.gms-pdp__wish:hover { transform: none; }
.gms-pdp__wish.is-on { color: var(--ss-ember-ink); }
.gms-pdp__wish.is-on svg { fill: currentColor; stroke: currentColor; }

/* ---- Arrows, counter, dots ---- */

.gms-pdp__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 38px;
  height: 38px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .94);
  color: var(--ss-ink);
  font-family: var(--ss-sans);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(24, 19, 13, .16);
  /* Visible on a phone, where there is no hover to reveal them with. */
  opacity: .92;
  transition: opacity .15s ease, color .15s ease;
}

.gms-pdp__nav--prev { left: 10px; }
.gms-pdp__nav--next { right: 10px; }
.gms-pdp__nav:hover { color: var(--ss-ember-ink); }

.gms-pdp__counter {
  position: absolute;
  right: 12px;
  bottom: 12px;
  z-index: 2;
  padding: 7px 11px;
  border-radius: 100px;
  background: rgba(21, 20, 18, .82);
  color: var(--ss-white);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .08em;
}

.gms-pdp__dots {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  margin-top: 8px;
}

/* The button is 24px square and mostly transparent; the dot inside it is 7px.
   Drawn this way because a 7px button is a 7px tap target, and this is a
   control a thumb has to hit on a moving bus. */
.gms-pdp__dot {
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  background: none;
  display: grid;
  place-items: center;
  cursor: pointer;
}

.gms-pdp__dot::after {
  content: '';
  display: block;
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--ss-line-2);
  transition: width .18s ease, background .18s ease;
}

/* The current one is a stadium rather than a bigger circle: it reads as "you
   are here" without shifting its neighbours around. */
.gms-pdp__dot.is-on { width: 34px; }
.gms-pdp__dot.is-on::after { width: 22px; background: var(--ss-ember-ink); }
.gms-pdp__dot:hover::after { background: var(--ss-ink-3); }

/* ---- Thumbnails ---- */

.gms-pdp__thumbs {
  display: flex;
  gap: 10px;
  margin-top: 14px;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 2px;
}

.gms-pdp__thumbs::-webkit-scrollbar { display: none; }

.gms-pdp__thumb {
  position: relative;
  flex: 0 0 auto;
  width: 62px;
  height: 74px;
  padding: 0;
  border: 1px solid rgba(30, 25, 18, .07);
  border-radius: 12px;
  overflow: hidden;
  background: var(--ss-shell);
  cursor: pointer;
  transition: border-color .2s ease, box-shadow .2s ease;
}

.gms-pdp__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gms-pdp__thumb:hover { border-color: var(--ss-line-2); }

.gms-pdp__thumb.is-on {
  border-color: var(--ss-ember);
  box-shadow: 0 0 0 3px rgba(244, 108, 4, .12);
}

.gms-pdp__play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: rgba(21, 20, 18, .72);
}

/* The triangle, drawn rather than fetched. */
.gms-pdp__play::after {
  content: '';
  position: absolute;
  left: 10px;
  top: 8px;
  border-style: solid;
  border-width: 5px 0 5px 8px;
  border-color: transparent transparent transparent #fff;
}

/* ============================================================ summary === */

.gms-pdp__title {
  margin: 0 0 14px;
  font-family: var(--ss-serif);
  font-size: clamp(30px, 8vw, 38px);
  font-weight: 600;
  line-height: 1.02;
  letter-spacing: -.02em;
  color: var(--ss-ink);
  /* A 60-character name is three lines here, not one line and an ellipsis. */
  overflow-wrap: break-word;
  text-wrap: balance;
}

/* ---- Brand ---- */

/* A destination, drawn as one. It sits under the name rather than above it,
   because the eyebrow above is already the category and two small caps lines
   stacked over a heading is a stack of labels, not a hierarchy. */
.gms-pdp__brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 16px;
  padding: 8px 14px 8px 8px;
  border: 1px solid var(--ss-line);
  border-radius: var(--ss-pill);
  background: var(--ss-white);
  transition: border-color .2s ease;
}

.gms-pdp__brand:hover { border-color: var(--ss-ember); transform: none; }

.gms-pdp__brand img {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  object-fit: contain;
  background: var(--ss-shell);
  flex: 0 0 30px;
}

.gms-pdp__brand-name {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .01em;
  color: var(--ss-ink);
}

.gms-pdp__brand-count {
  font-size: 12px;
  font-weight: 500;
  color: var(--ss-ink-3);
}

.gms-pdp__brand-count::before { content: '· '; color: var(--ss-hair); }
.gms-pdp__brand-go { font-size: 13px; color: var(--ss-ember-ink); }

.gms-pdp__rating {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  margin-bottom: 16px;
  font-size: 13px;
}

.gms-pdp .gms-stars {
  /* The shared rule hard-codes #f5a623, which is 2.3:1 on this paper. A star
     row is a graphic conveying a value, so it is held to 3:1. */
  background: linear-gradient(90deg, var(--ss-star) var(--gms-fill, 0%), rgba(21, 20, 18, .22) var(--gms-fill, 0%));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* ★ is in neither webfont, so it renders from a system face either way —
     named explicitly so the metrics do not shift when Manrope swaps in. */
  font-family: ui-sans-serif, system-ui, sans-serif;
  letter-spacing: .14em;

  /* Shrink-wrapped, and this is load-bearing. The fill is a gradient colour
     stop in percent, and percentages resolve against the element box — but
     background-clip: text paints it onto glyphs that occupy only as much of
     that box as five characters need. Let the box stretch and the stop lands
     past the last star, so every rating paints as five solid stars: a 2-star
     review in a 221px-wide list item put its 40% stop at 88px when the glyphs
     ended at 74px. How wrong it looked depended on the container width, which
     is why some ratings happened to render correctly and most did not. */
  width: max-content;
  max-width: 100%;
}

.gms-pdp__rating-num { font-weight: 700; color: var(--ss-ink); }

.gms-pdp__rating-count {
  color: var(--ss-indigo);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.gms-pdp__rating-count:hover { color: var(--ss-indigo); }

/* ---- Seal ---- */

.gms-pdp__seal {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 16px;
  padding: 12px 14px;
  border-radius: var(--ss-r);
  background: var(--ss-sand);
}

.gms-pdp__seal img {
  display: block;
  width: 52px;
  height: 52px;
  flex: 0 0 52px;
  /* contain, not cover: a round seal cropped square stops being a seal. */
  object-fit: contain;
}

.gms-pdp__seal-text {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .12em;
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--ss-ink-3);
}

/* ---- Price ---- */

.gms-pdp__price {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}

.gms-pdp__price strong {
  font-size: clamp(30px, 8vw, 34px);
  font-weight: 700;
  letter-spacing: -.03em;
  line-height: 1;
  color: var(--ss-ink);
}

/* What the price is for — "/ 500 g". Quieter than the price it qualifies. */
.gms-pdp__unit {
  margin-left: -6px;
  font-size: 14px;
  font-weight: 500;
  color: var(--ss-ink-3);
}

.gms-pdp__price del {
  font-size: 15px;
  font-weight: 500;
  color: var(--ss-ink-3);
}

.gms-pdp__off {
  padding: 7px 11px;
  border-radius: var(--ss-pill);
  background: var(--ss-lemon);
  color: var(--ss-ink);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .04em;
  line-height: 1;
  text-transform: uppercase;
}

.gms-pdp__saving {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--ss-green);
}

.gms-pdp__tax {
  margin: 0 0 14px;
  font-size: 12px;
  color: var(--ss-ink-3);
}

/* ---- Sales proof ---- */

.gms-pdp__proof {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 18px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ss-ember-ink);
}

.gms-pdp__proof svg { width: 14px; height: 14px; flex: 0 0 auto; }

/* ---- Offer ---- */

.gms-pdp__offer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0 0 20px;
  padding: 15px 16px;
  border: 1px solid rgba(250, 152, 4, .3);
  border-radius: var(--ss-r);
  background: linear-gradient(120deg, rgba(248, 248, 125, .38), rgba(250, 152, 4, .1));
}

.gms-pdp__offer-tag {
  padding: 6px 11px;
  border-radius: 7px;
  background: var(--ss-night);
  color: var(--ss-white);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .06em;
  line-height: 1.3;
  text-transform: uppercase;
}

.gms-pdp__offer--member .gms-pdp__offer-tag { background: var(--ss-ember-ink); }

.gms-pdp__offer-note {
  font-size: 13px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--ss-ink-2);
}

/* Pushed to the end of the row so it reads as the action, not part of the
   description — and given its own line when the strip wraps. */
.gms-pdp__offer-link {
  margin-left: auto;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ss-ember-ink);
}

.gms-pdp__offer-link::after { content: ' →'; }
.gms-pdp__offer-link:hover { color: var(--ss-ember-ink); text-decoration: underline; text-underline-offset: 4px; }

/* ============================================================= options === */

.gms-pdp__opt { margin-bottom: 18px; }

.gms-pdp__opt-label {
  display: block;
  margin-bottom: 10px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ss-ink-3);
}

/* The chosen value, beside its label. Not uppercase: it is a value, and
   "Antique Brass" shouted in 10px caps is unreadable. */
.gms-pdp__opt-label em {
  font-style: normal;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ss-ink);
}

.gms-pdp__opt-label em::before { content: '· '; color: var(--ss-hair); }

.gms-pdp__opt-choices { display: flex; gap: 10px; flex-wrap: wrap; }

/* ---- Chips ---- */

.gms-pdp__chip {
  min-width: 74px;
  min-height: 52px;
  padding: 8px 16px;
  border: 1px solid var(--ss-line-2);
  border-radius: var(--ss-r);
  background: var(--ss-white);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--ss-ink);
  cursor: pointer;
  transition: border-color .2s ease, background .2s ease, box-shadow .2s ease;
}

.gms-pdp__chip:hover { border-color: var(--ss-ember); }

.gms-pdp__chip.is-on {
  border: 2px solid var(--ss-ember);
  background: rgba(248, 248, 125, .3);
  box-shadow: 0 0 0 3px rgba(244, 108, 4, .09);
}

/* A value that leads nowhere: visibly gone, not merely unselected. */
.gms-pdp__chip.is-out,
.gms-pdp__swatch.is-out {
  position: relative;
  opacity: .45;
  cursor: not-allowed;
}

.gms-pdp__chip.is-out {
  border-color: var(--ss-line);
  background: var(--ss-shell);
  text-decoration: line-through;
  box-shadow: none;
}

/* ---- Swatches ---- */

.gms-pdp__swatches { gap: 12px; }

.gms-pdp__swatch {
  position: relative;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--gms-swatch, #ddd);
  cursor: pointer;
  /* The ring is drawn outside the colour so a white swatch is still visible
     against a white card, and the selected state does not change its size. */
  box-shadow: 0 0 0 1px rgba(30, 25, 18, .18);
  transition: box-shadow .2s ease;
}

.gms-pdp__swatch:hover { box-shadow: 0 0 0 1px rgba(30, 25, 18, .35); }

.gms-pdp__swatch.is-on {
  box-shadow: 0 0 0 1px rgba(30, 25, 18, .18), 0 0 0 3px var(--ss-paper), 0 0 0 5px var(--ss-ember);
}

/* A tick in a colour chosen for contrast against the swatch itself. */
.gms-pdp__swatch.is-on::after {
  content: '';
  position: absolute;
  left: 13px;
  top: 9px;
  width: 6px;
  height: 11px;
  border: solid var(--gms-swatch-ink, #fff);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

/* A diagonal bar across a swatch, since a colour cannot be struck through. */
.gms-pdp__swatch.is-out::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  color: var(--ss-ink-3);
  background: linear-gradient(to top left, transparent 46%, currentColor 46%, currentColor 54%, transparent 54%);
}

/* A value with no colour set still has to be pickable. */
.gms-pdp__swatch.is-plain {
  width: auto;
  height: auto;
  min-height: 44px;
  padding: 10px 16px;
  border-radius: var(--ss-r);
  background: var(--ss-white);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--ss-ink);
  box-shadow: inset 0 0 0 1px var(--ss-line-2);
}

.gms-pdp__swatch.is-plain.is-on {
  background: rgba(248, 248, 125, .3);
  box-shadow: inset 0 0 0 2px var(--ss-ember), 0 0 0 3px rgba(244, 108, 4, .09);
}

.gms-pdp__swatch.is-plain.is-on::after { display: none; }

/* ---- Dropdown ---- */

.gms-pdp__select {
  width: 100%;
  max-width: 280px;
  padding: 14px 38px 14px 16px;
  border: 1px solid var(--ss-line-2);
  border-radius: var(--ss-r);
  background: var(--ss-white);
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  color: var(--ss-ink);
  cursor: pointer;
  appearance: none;
  /* A drawn caret rather than an image request for one arrow. */
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 20px) 53%, calc(100% - 15px) 53%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.gms-pdp__select:hover { border-color: var(--ss-ember); }

/* ---- Radios ---- */

.gms-pdp__radios { flex-direction: column; align-items: stretch; gap: 8px; }

.gms-pdp__radio {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 12px 15px;
  border: 1px solid var(--ss-line-2);
  border-radius: var(--ss-r);
  background: var(--ss-white);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: border-color .2s ease, background .2s ease;
}

.gms-pdp__radio input { accent-color: var(--ss-ember-ink); width: 17px; height: 17px; margin: 0; }
.gms-pdp__radio:has(input:checked) { border-color: var(--ss-ember); background: rgba(248, 248, 125, .3); }
.gms-pdp__radio input:disabled + span { opacity: .45; text-decoration: line-through; }
.gms-pdp__radio:has(input:disabled) { cursor: not-allowed; background: var(--ss-shell); }

/* ============================================================== stock === */

.gms-pdp__stock {
  margin: 0 0 16px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .02em;
}

.gms-pdp__stock.is-low { color: var(--gms-warn); }
.gms-pdp__stock.is-out { color: var(--ss-red); }

/* ================================================ free shipping, variant === */

/* Under the pickers, because it is a property of the choice above it.
   The two states are deliberately different weights: qualifying is good news
   and gets the green; not qualifying is a nudge and stays quiet, because a
   loud "you could have had free shipping" reads as a reprimand. */
.gms-pdp__freeship { margin: -4px 0 18px; }

.gms-pdp__freeship p {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 0;
  font-size: 13px;
  line-height: 1.45;
}

.gms-pdp__freeship p[hidden] { display: none; }
.gms-pdp__freeship svg { width: 17px; height: 17px; flex: 0 0 auto; margin-top: 1px; }

.gms-pdp__freeship-on {
  padding: 11px 13px;
  border-radius: 10px;
  background: rgba(23, 129, 84, .1);
  color: var(--ss-green-deep);
}

.gms-pdp__freeship-on strong { font-weight: 800; }
.gms-pdp__freeship-off { color: var(--ss-ink-3); }
.gms-pdp__freeship-off svg { color: var(--ss-ink-3); }

/* ======================================================== partial COD === */

/* Between the options and Add to cart. Quiet on purpose — it is a payment
   term, not a second price, and the mock's saffron offer treatment here would
   have two gradient panels shouting at each other either side of the buy
   button. So: the sand panel, one ember rule down the edge, and the split
   itself as the only bold thing in it. */
.gms-pdp__partial {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 0 0 18px;
  padding: 14px 16px;
  border-left: 3px solid var(--ss-ember);
  border-radius: 6px var(--ss-r) var(--ss-r) 6px;
  background: var(--ss-sand);
}

.gms-pdp__partial svg {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  margin-top: 1px;
  color: var(--ss-ember-ink);
}

.gms-pdp__partial-body { display: grid; gap: 6px; min-width: 0; }

.gms-pdp__partial-head {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ss-ember-ink);
}

.gms-pdp__partial-split {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -.01em;
  line-height: 1.35;
  color: var(--ss-ink);
}

/* The caveat is the honest half of this block, so it is small but not faint —
   --ss-ink-3 on sand is 4.8:1, which is the point. */
.gms-pdp__partial-note {
  font-size: 12px;
  font-weight: 500;
  line-height: 1.45;
  color: var(--ss-ink-3);
}

/* ================================================================ buy === */

/* Stepper and Add to cart share the top line; Buy now takes the full width
   beneath. Two rows rather than three, and the primary action is the widest
   thing in the block rather than competing with the basket for half of it. */
.gms-pdp__buy {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 10px;
  align-items: stretch;
  margin-bottom: 10px;
}

/* Prefixed with .gms-pdp throughout, and not by habit: frontend.css carries
   `.gms-qty button { width:27px; height:27px }` for the cart drawer's tiny
   stepper, and a class-plus-type selector outranks a plain class no matter
   which file loads last. Unprefixed, the buy row's stepper renders as a 27px
   drawer control inside a 60px box. */
.gms-pdp .gms-qty {
  grid-column: 1;
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  width: 128px;
  min-height: 56px;
  border: 1px solid var(--ss-line-2);
  border-radius: var(--ss-r);
  overflow: hidden;
  background: var(--ss-white);
}

.gms-pdp .gms-qty__btn {
  width: 42px;
  height: auto;
  padding: 0;
  border: 0;
  background: transparent;
  font-family: var(--ss-sans);
  font-size: 19px;
  line-height: 1;
  color: var(--ss-ink);
  cursor: pointer;
  transition: background .15s ease;
}

.gms-pdp .gms-qty__btn:hover { background: var(--ss-shell); }
.gms-pdp .gms-qty__btn:disabled { opacity: .3; cursor: not-allowed; background: transparent; }

.gms-pdp .gms-qty__input {
  width: 40px;
  border: 0;
  padding: 16px 0;
  text-align: center;
  font-family: inherit;
  font-size: 15px;
  font-weight: 600;
  background: transparent;
  color: var(--ss-ink);
  -moz-appearance: textfield;
  appearance: textfield;
}

.gms-pdp .gms-qty__input::-webkit-outer-spin-button,
.gms-pdp .gms-qty__input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.gms-pdp__add,
.gms-pdp__buynow {
  min-height: 56px;
  padding: 14px 24px;
  border: 0;
  border-radius: var(--ss-r);
  font-family: inherit;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .09em;
  text-transform: uppercase;
  cursor: pointer;
  transition: box-shadow .2s ease, background .2s ease;
}

.gms-pdp__add {
  /* The gradient of the mock, taken down until white clears 4.5:1 at both
     ends. The bright ember stays on as the glow underneath it. */
  background: linear-gradient(110deg, var(--ss-cta-a), var(--ss-cta-b));
  color: var(--ss-white);
  box-shadow: 0 12px 30px rgba(244, 108, 4, .22);
}

.gms-pdp__add { grid-column: 2; }

/* Sold out, or cart-only with no stepper: the button is on its own, so it
   takes the whole row rather than leaving a gap where the stepper was. */
.gms-pdp__add:only-child { grid-column: 1 / -1; }

/* The gradient has to be restated, or the theme's flat background wins and
   Add to cart loses its gradient the moment a pointer touches it. */
.gms-pdp__add:hover,
.gms-pdp__add:focus-visible {
  background: linear-gradient(110deg, var(--ss-cta-a), var(--ss-cta-b));
  color: var(--ss-white);
  transform: none;
  box-shadow: 0 18px 40px rgba(244, 108, 4, .3);
}

.gms-pdp__buynow {
  grid-column: 1 / -1;
  position: relative;
  overflow: hidden;
  background: var(--ss-night);
  color: var(--ss-white);
}

/* Stays the colour it is.

   This swapped to --ss-indigo (#2408df) on hover — near-black to bright indigo,
   a hue change on the largest, most committed button on the page. A primary
   call to action should acknowledge the pointer, not change identity under it.

   Every property the theme's `body button:hover` sets is named here too, or it
   supplies its own background and the button changes colour anyway. */
.gms-pdp__buynow:hover,
.gms-pdp__buynow:focus-visible {
  background: var(--ss-night);
  border-color: var(--ss-night);
  color: var(--ss-white);
  opacity: .92;
}

/* ---- Buy now, animated -------------------------------------------------

   Which animation runs is a merchant setting, so each one is keyed off a
   data attribute rather than a class the template has to know about. All of
   them stop under prefers-reduced-motion, and "none" is a real option
   because a moving button on every product page is a tic, not a tactic. */

.gms-pdp__buynow-label { position: relative; display: inline-block; }

/* Shimmer: a light sweep across the label. */
.gms-pdp__buynow[data-gms-anim="shimmer"] .gms-pdp__buynow-label {
  background: none;
  color: var(--ss-white);
}

@keyframes gms-buynow-shimmer {
  0%, 65% { background-position: 130% 0; }
  100%    { background-position: -30% 0; }
}

/* Pulse: the whole button breathes, once in a while. */
.gms-pdp__buynow[data-gms-anim="pulse"] {
  animation: none;
}

@keyframes gms-buynow-pulse {
  0%, 88%, 100% { transform: scale(1); }
  94%           { transform: scale(1.014); }
}

/* Nudge: an arrow that leans forward, drawn rather than fetched. */
.gms-pdp__buynow[data-gms-anim="arrow"] .gms-pdp__buynow-label::after {
  content: '→';
  display: inline-block;
  margin-left: 10px;
  animation: none;
}

@keyframes gms-buynow-arrow {
  0%, 60%, 100% { transform: translateX(0); }
  75%           { transform: translateX(5px); }
}

/* Sheen: a band of light crossing the button itself. */
.gms-pdp__buynow[data-gms-anim="sheen"]::after {
  content: none;
  position: absolute;
  top: 0;
  bottom: 0;
  width: 40%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .16), transparent);
  animation: none;
  pointer-events: none;
}

@keyframes gms-buynow-sheen {
  0%, 55% { left: -45%; }
  100%    { left: 105%; }
}

/* Sold out. Flat and obviously inert — a disabled gradient still looks like a
   button somebody is meant to press. */
.gms-pdp__add:disabled {
  background: var(--ss-shell);
  color: var(--ss-ink-3);
  box-shadow: none;
  cursor: not-allowed;
  transform: none;
}

.gms-pdp__feedback {
  min-height: 20px;
  margin: 0 0 18px;
  font-size: 13px;
  font-weight: 700;
  color: var(--ss-green);
}

.gms-pdp__feedback.is-bad { color: var(--ss-red); }

/* ================================== hooked in after buy: pincode, share === */

/* The delivery checker and the share row arrive through gms_pdp_after_buy, so
   they are styled here rather than in their own modules — they only ever
   appear on this page. */

.gms-pdp .gms-delivery-check {
  margin: 0 0 20px;
  padding: 18px;
  border: 0;
  border-radius: var(--ss-r-lg);
  background: var(--ss-sand);

  /* frontend.css caps this at 420px, which is right where it sits in a page's
     flow at whatever width the content happens to be. In the product page's
     right-hand column it is wrong: the column is 634px on a 1600px screen, so
     the box stopped 214px short and left a band of empty sand beside it while
     Buy now above it spanned the full width. Nothing else in that column is
     narrower than the column. */
  max-width: none;
}

.gms-pdp .gms-delivery-check__label {
  display: block;
  margin-bottom: 12px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ss-ink-3);
}

.gms-pdp .gms-delivery-check__row { display: flex; gap: 10px; }

.gms-pdp .gms-delivery-check__input {
  flex: 1 1 auto;
  min-width: 0;
  height: 50px;
  padding: 0 16px;
  border: 1px solid var(--ss-line);
  border-radius: 12px;
  background: var(--ss-white);
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  color: var(--ss-ink);
}

.gms-pdp .gms-delivery-check__input:focus { outline: 2px solid var(--ss-indigo); outline-offset: 1px; }

.gms-pdp .gms-delivery-check__btn {
  flex: 0 0 auto;
  height: 50px;
  padding: 0 24px;
  border: 0;
  border-radius: 11px;
  background: var(--ss-night);
  color: var(--ss-white);
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .2s ease;
}

.gms-pdp .gms-delivery-check__btn:hover { background: var(--ss-indigo); }

.gms-pdp .gms-delivery-check__result:not(:empty) {
  margin-top: 12px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ss-ink-2);
}

/* Seven channels plus a label do not fit one line in a 293px column, and
   wrapping left a single orphaned icon on a row of its own. The label takes
   its own line and the icons stay together underneath it. */
.gms-pdp .gms-share {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 20px;
}

.gms-pdp .gms-share__label {
  flex: 1 0 100%;
  margin-bottom: 2px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ss-ink-3);
}

.gms-pdp .gms-share__btn {
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid var(--ss-line-2);
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--ss-white);
  color: var(--ss-ink-2);
  cursor: pointer;
  transition: border-color .2s ease, color .2s ease;
}

.gms-pdp .gms-share__btn svg { width: 17px; height: 17px; }
.gms-pdp .gms-share__btn:hover { border-color: var(--ss-ember); color: var(--ss-ember-ink); transform: none; }

/* ---- Short description ---- */

.gms-pdp__short {
  margin: 0 0 20px;
  font-size: 15px;
  line-height: 1.7;
  color: var(--ss-ink-2);
}

.gms-pdp__short p { margin: 0 0 10px; }
.gms-pdp__short p:last-child { margin-bottom: 0; }

/* ========================================================= assurances === */

/* On a phone these are cards in a two-up grid, as the design draws them; on a
   desktop they collapse to one quiet row under the buy block, because four
   boxes of reassurance above the fold outshout the price. */
/* One row, one column per assurance.

   This was a fixed two-up grid, and there are three assurances — so they broke
   as two on one line and a single orphan stretched across the next. The rule
   below was written to make that orphan look deliberate, which is treating the
   symptom: a row of trust marks is read at a glance or not at all, and a
   stretched "Secure payment" on its own line reads as an afterthought.

   Counted from the content rather than assumed, so a shop that adds a fourth
   still gets one row. minmax(0, 1fr) lets the columns shrink to whatever is
   available instead of forcing a wrap. */
.gms-pdp__assure {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 10px;
}

/* Below this the labels have no room to be readable three-up, and stacking is
   honest rather than cramped. */
@media (max-width: 420px) {
  .gms-pdp__assure {
    grid-auto-flow: row;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .gms-pdp__assure li:last-child:nth-child(odd) { grid-column: 1 / -1; }
}

.gms-pdp__assure li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 15px;
  border-radius: var(--ss-r);
  background: var(--ss-sand);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ss-ink);
}

.gms-pdp__assure svg {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  margin-top: 1px;
  color: var(--ss-ember-ink);
}

/* ============================================================= panels === */

/* Description and specifications, on the warm band the design uses to break
   the page between deciding and reading. */
.gms-pdp__panels {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 32px;
  margin-top: 40px;
  padding: 32px 20px;
  border-radius: var(--ss-r-xl);
  background: var(--ss-sand);
}

.gms-pdp__panel h2 {
  margin: 0 0 18px;
  font-family: var(--ss-serif);
  font-size: clamp(26px, 6vw, 32px);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -.02em;
  color: var(--ss-ink);
}

.gms-pdp__prose { font-size: 15px; line-height: 1.8; color: var(--ss-ink-2); }
.gms-pdp__prose p { margin: 0 0 14px; }
.gms-pdp__prose p:last-child { margin-bottom: 0; }
.gms-pdp__prose a { color: var(--ss-indigo); text-decoration: underline; text-underline-offset: 3px; }

/* The bullets. Read far more than the prose under them, so they get the
   room: full measure, real line height, and a mark that is not a bullet
   glyph the font may not have. */
.gms-pdp__highlights {
  list-style: none;
  margin: 0 0 22px;
  padding: 0;
  display: grid;
  gap: 10px;
}

.gms-pdp__highlights li {
  position: relative;
  padding-left: 20px;
  font-size: 15px;
  line-height: 1.65;
  color: var(--ss-ink-2);
}

.gms-pdp__highlights li::before {
  content: '';
  position: absolute;
  left: 2px;
  top: .62em;
  width: 6px;
  height: 6px;
  transform: rotate(45deg);
  border: 1px solid var(--ss-ember);
}

/* ---- Grouped specifications ---- */

.gms-pdp__group { border-bottom: 1px solid var(--ss-line); }
.gms-pdp__group:first-of-type { border-top: 1px solid var(--ss-line); }

.gms-pdp__group summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 0;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ss-ink);
  cursor: pointer;
  list-style: none;
}

.gms-pdp__group summary::-webkit-details-marker { display: none; }

/* A drawn chevron, so there is no icon font and no image request. */
.gms-pdp__group summary::after {
  content: '';
  width: 8px;
  height: 8px;
  flex: 0 0 auto;
  border-right: 1.5px solid var(--ss-ink-3);
  border-bottom: 1.5px solid var(--ss-ink-3);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .2s ease;
}

.gms-pdp__group[open] summary::after { transform: rotate(-135deg) translate(-3px, -3px); }
.gms-pdp__group summary:hover { color: var(--ss-ember-ink); }
.gms-pdp__group > .gms-pdp__specs { padding-bottom: 8px; }

/* Inside a group the rows are already fenced by the group's own rule. */
.gms-pdp__group .gms-pdp__specs > div:first-child { border-top: 0; }
.gms-pdp__group .gms-pdp__specs > div:last-child { border-bottom: 0; }

.gms-pdp__specs { margin: 0; }

.gms-pdp__specs > div {
  display: grid;
  grid-template-columns: minmax(90px, 40%) minmax(0, 1fr);
  gap: 20px;
  padding: 15px 0;
  border-bottom: 1px solid var(--ss-line);
  font-size: 14px;
}

.gms-pdp__specs > div:first-child { border-top: 1px solid var(--ss-line); }
.gms-pdp__specs dt { margin: 0; font-weight: 500; color: var(--ss-ink-3); }
.gms-pdp__specs dd { margin: 0; font-weight: 500; color: var(--ss-ink); }

/* ====================================================== section heads === */

.gms-pdp__sechead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 22px;
}

.gms-pdp__sechead h2 {
  margin: 0;
  font-family: var(--ss-serif);
  font-size: clamp(26px, 6vw, 34px);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -.02em;
  color: var(--ss-ink);
}

.gms-pdp__seclink {
  flex: 0 0 auto;
  /* A standalone link, so it carries its own 24px hit box rather than relying
     on the inline-text exception. */
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ss-indigo);
}

.gms-pdp__seclink:hover { color: var(--ss-indigo); text-decoration: underline; text-underline-offset: 4px; }

/* ============================================================ related === */

.gms-pdp__related { margin-top: 48px; }

.gms-pdp__rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 62%;
  gap: 14px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  padding-bottom: 6px;
}

.gms-pdp__rail::-webkit-scrollbar { display: none; }
.gms-pdp__rail > * { scroll-snap-align: start; }

/* The card is the listing's card. Restyled only inside the product page, so
   the shop grid is untouched — this change is the product page and nothing
   else. */
.gms-pdp .gms-card-p {
  background: transparent;
  border: 0;
  box-shadow: none;
}

.gms-pdp .gms-card-p__media {
  border-radius: var(--ss-r-lg);
  overflow: hidden;
  background: var(--ss-shell);
}

/* A product with no photograph. The card's placeholder src is a 1×1 GIF as a
   data: URI, which esc_url() strips — so the <img> ends up with an empty src
   and the browser paints the alt text across the badges. The same weave the
   main stage uses goes behind it and the broken image is taken out of the
   picture; the link keeps its aria-label, so nothing is lost to a screen
   reader. (The empty src itself is ProductGridModule's, and shared with the
   shop grid, so it is not fixed from here.) */
.gms-pdp .gms-card-p__media--empty {
  background-image: none;
  background-color: var(--ss-shell, #f4f2ef);
}

.gms-pdp .gms-card-p__media--empty .gms-card-p__img { visibility: hidden; }

.gms-pdp .gms-card-p__body { padding: 14px 2px 0; }

.gms-pdp .gms-card-p__title {
  font-family: var(--ss-serif);
  font-size: 20px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0;
}

.gms-pdp .gms-card-p__title a { color: var(--ss-ink); }
.gms-pdp .gms-card-p__title a:hover { color: var(--ss-ember-ink); }
.gms-pdp .gms-card-p__now { font-size: 18px; font-weight: 700; letter-spacing: -.02em; }
.gms-pdp .gms-card-p__price del { color: var(--ss-ink-3); }

/* The listing paints a discount chip with --gms-bad, which is an alarm colour.
   On this page a discount is good news and matches the flag on the main
   photograph above it. */
.gms-pdp .gms-chip-b--sale { background: var(--ss-ember-ink); }
.gms-pdp .gms-chip-b--out { background: var(--ss-red); }

.gms-pdp .gms-card-p__off {
  /* The card body is a flex column, so a block pill stretches the full width
     unless it is told not to. */
  align-self: flex-start;
  margin-bottom: 10px;
  padding: 5px 9px;
  border-radius: var(--ss-pill);
  background: var(--ss-lemon);
  color: var(--ss-ink);
  font-size: 10px;
  font-weight: 700;
}

/* ============================================================ reviews === */

.gms-pdp__reviews { margin-top: 48px; }

.gms-rev {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 28px;
  align-items: start;
}

.gms-pdp .gms-rev__summary {
  display: block;
  padding: 22px;
  border: 0;
  border-radius: var(--ss-r-lg);
  background: var(--ss-sand);
}

.gms-pdp .gms-rev__score {
  display: block;
  text-align: left;
}

.gms-pdp .gms-rev__score strong {
  display: block;
  font-family: var(--ss-serif);
  font-size: 56px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ss-ink);
}

.gms-pdp .gms-rev__score .gms-stars { display: block; margin-top: 10px; font-size: 15px; }

.gms-pdp .gms-rev__score em {
  display: block;
  margin-top: 10px;
  font-style: normal;
  font-size: 13px;
  font-weight: 500;
  color: var(--ss-ink-3);
}

.gms-pdp .gms-rev__bars { display: grid; gap: 9px; margin-top: 20px; }

/* min-height, because a filter row is a link a thumb has to hit: five 21px
   rows stacked 9px apart is a column of near-misses. */
.gms-pdp a.gms-rev__bar {
  min-height: 24px;
  border-radius: 7px;
  padding: 4px 6px;
  margin: 0 -6px;
  text-decoration: none;
}

.gms-pdp a.gms-rev__bar:hover { background: rgba(244, 108, 4, .08); }
.gms-pdp a.gms-rev__bar.is-on { background: rgba(244, 108, 4, .12); }
.gms-pdp a.gms-rev__bar.is-on em { color: var(--ss-ember-ink); font-weight: 700; }

.gms-pdp .gms-rev__bar {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) 30px;
  align-items: center;
  gap: 10px;
  font-size: 11px;
  font-weight: 500;
  color: var(--ss-ink-3);
}

.gms-pdp .gms-rev__track {
  height: 5px;
  border-radius: 100px;
  background: #eee8dc;
  overflow: hidden;
}

.gms-pdp .gms-rev__track > span { display: block; height: 100%; border-radius: 100px; background: var(--ss-star); }
.gms-pdp .gms-rev__bar em { font-style: normal; text-align: right; }

.gms-pdp .gms-rev__none {
  margin: 0;
  padding: 22px;
  border-radius: var(--ss-r-lg);
  background: var(--ss-sand);
  font-size: 14px;
  line-height: 1.6;
  color: var(--ss-ink-2);
}

.gms-pdp .gms-rev__filter { margin: 0 0 18px; font-size: 13px; color: var(--ss-ink-3); }
.gms-pdp .gms-rev__filter a { margin-left: 8px; color: var(--ss-indigo); text-decoration: underline; text-underline-offset: 3px; }

.gms-pdp .gms-rev__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 14px;
}

.gms-pdp .gms-rev__item {
  padding: 22px;
  border: 1px solid var(--ss-line);
  border-radius: var(--ss-r-lg);
  background: var(--ss-white);
}

.gms-pdp .gms-rev__who strong { font-family: var(--ss-sans); font-size: 13px; font-weight: 700; color: var(--ss-ink); }
.gms-pdp .gms-rev__when { font-size: 11px; color: var(--ss-ink-3); }

.gms-pdp .gms-rev__verified {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 9px;
  border-radius: var(--ss-pill);
  background: rgba(23, 129, 84, .1);
  color: var(--ss-green-deep);
  font-style: normal;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
}

.gms-pdp .gms-rev__stars { display: block; margin-top: 12px; font-size: 13px; }
.gms-pdp .gms-rev__body { margin-top: 10px; font-size: 14px; line-height: 1.75; color: var(--ss-ink-2); }
.gms-pdp .gms-rev__body p { margin: 0 0 8px; }
.gms-pdp .gms-rev__body p:last-child { margin-bottom: 0; }

.gms-pdp .gms-rev__photos { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 16px; }

.gms-pdp .gms-rev__photos img {
  width: 76px;
  height: 76px;
  object-fit: cover;
  border-radius: 12px;
  display: block;
}

/* ---- Write a review ---- */

.gms-pdp .gms-rev__write {
  margin-top: 24px;
  padding: 24px;
  border: 1px solid var(--ss-line);
  border-radius: var(--ss-r-lg);
  background: var(--ss-white);
}

.gms-pdp .gms-rev__write h3 {
  margin: 0 0 18px;
  font-family: var(--ss-serif);
  font-size: 26px;
  font-weight: 600;
  line-height: 1.1;
  color: var(--ss-ink);
}

.gms-pdp .gms-rev__closed { margin: 0; font-size: 14px; line-height: 1.6; color: var(--ss-ink-3); }

.gms-pdp .gms-rev__signin {
  display: inline-block;
  margin-left: 4px;
  font-weight: 700;
  color: var(--ss-indigo);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* The unpicked stars are the affordance, not decoration — at --ss-line-2 they
   were 1.4:1 against the card and read as absent rather than empty. */
.gms-pdp .gms-rev__star { color: #8a8378; }
.gms-pdp .gms-rev__star.is-on,
.gms-pdp .gms-rev__star:hover { color: var(--ss-star); }

/* .gms-field and .gms-row live in auth.css, which a product page never loads —
   so until now the name, email and review boxes were unstyled browser
   controls sitting under a designed page. They are drawn here instead. */
.gms-pdp .gms-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 14px;
}

.gms-pdp .gms-field { display: block; min-width: 0; }

.gms-pdp .gms-field__label {
  display: block;
  margin-bottom: 8px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ss-ink-3);
}

.gms-pdp .gms-field__wrap { display: block; }

.gms-pdp .gms-field__input {
  display: block;
  width: 100%;
  padding: 14px 16px;
  border: 1px solid var(--ss-line-2);
  border-radius: 12px;
  background: var(--ss-white);
  font-family: inherit;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ss-ink);
  resize: vertical;
}

.gms-pdp .gms-field__input::placeholder { color: var(--ss-ink-3); }
.gms-pdp .gms-field__input:focus { outline: 2px solid var(--ss-indigo); outline-offset: 1px; border-color: var(--ss-indigo); }
.gms-pdp .gms-field.is-bad .gms-field__input { border-color: var(--ss-red); }

@media (min-width: 561px) {
  .gms-pdp .gms-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.gms-pdp .gms-rev__hint { font-size: 12px; color: var(--ss-ink-3); }
.gms-pdp .gms-auth__error { color: var(--ss-red); font-size: 13px; font-weight: 600; }
.gms-pdp .gms-rev__done { color: var(--ss-green); font-size: 13px; font-weight: 600; }

.gms-pdp .gms-btn-solid {
  display: inline-block;
  padding: 15px 30px;
  border: 0;
  border-radius: var(--ss-r);
  background: linear-gradient(110deg, var(--ss-cta-a), var(--ss-cta-b));
  color: var(--ss-white);
  font-family: inherit;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .09em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  box-shadow: 0 12px 30px rgba(244, 108, 4, .2);
  transition: box-shadow .2s ease;
}

.gms-pdp .gms-btn-solid:hover { transform: none; box-shadow: 0 18px 40px rgba(244, 108, 4, .28); color: var(--ss-white); }

/* ========================================================= merchant rows === */

/* Whatever the merchant put on the product page — carousels, grids, category
   tiles. Drawn by the same engine as the home page, so the section styling
   comes with it; this only sets the rhythm between them and the page. */
.gms-pdp__rows { margin-top: 48px; }
.gms-pdp__rows > *:not(:last-child) { margin-bottom: 40px; }

@media (min-width: 861px) {
  .gms-pdp__rows { margin-top: 80px; }
  .gms-pdp__rows > *:not(:last-child) { margin-bottom: 64px; }
}

/* ======================================================= closing band === */

/* The way out for whoever is not buying this one, on the dark band the design
   closes with. */
.gms-pdp__more {
  margin-top: 48px;
  padding: 48px 24px;
  border-radius: var(--ss-r-xl);
  background: var(--ss-night);
  text-align: center;
}

.gms-pdp__more .gms-btn-solid { box-shadow: 0 12px 30px rgba(244, 108, 4, .3); }

/* ========================================================= sticky bar === */

.gms-pdpbar {
  position: fixed;
  left: 0;
  right: 0;
  /* Sits above the bottom navigation rather than under it. */
  bottom: var(--gms-bottom-chrome, 0px);
  z-index: 99985;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  padding-bottom: calc(12px + env(safe-area-inset-bottom));
  background: rgba(255, 255, 255, .97);
  -webkit-backdrop-filter: blur(15px);
  backdrop-filter: blur(15px);
  border-top: 1px solid var(--ss-line);
  font-family: var(--ss-sans);
  box-shadow: 0 -6px 22px rgba(24, 19, 13, .08);
  /* Must clear its own height *and* the offset it sits at, or "hidden" simply
     parks it on top of the bottom navigation. */
  transform: translateY(calc(100% + var(--gms-bottom-chrome, 0px)));
  transition: transform .22s ease;
}

.gms-pdpbar.is-on { transform: none; }
.gms-pdpbar__info { flex: 1 1 auto; min-width: 0; display: grid; gap: 4px; }

.gms-pdpbar__name {
  font-size: 12px;
  font-weight: 600;
  color: var(--ss-ink-3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gms-pdpbar__price { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.gms-pdpbar__price strong { font-size: 18px; font-weight: 700; letter-spacing: -.02em; color: var(--ss-ink); }
.gms-pdpbar__price del { font-size: 12px; color: var(--ss-ink-3); }
.gms-pdpbar__off { font-size: 11px; font-weight: 700; color: var(--ss-ember-ink); }

.gms-pdpbar__add {
  flex: 0 0 auto;
  min-width: 150px;
  padding: 15px 22px;
  border: 0;
  border-radius: var(--ss-r);
  background: linear-gradient(110deg, var(--ss-cta-a), var(--ss-cta-b));
  color: var(--ss-white);
  font-family: inherit;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 10px 26px rgba(244, 108, 4, .24);
}

/* The bar is a phone affordance; on a desktop the real button stays visible. */
@media (min-width: 861px) {
  .gms-pdpbar { display: none; }
}

/* ========================================================== ≥ 561px === */

@media (min-width: 561px) {
  .gms-pdp { padding-left: 24px; padding-right: 24px; }
  .gms-pdp__crumbs-current { max-width: 40ch; }
  .gms-pdp__thumb { width: 76px; height: 90px; }
  .gms-pdp__rail { grid-auto-columns: 40%; gap: 18px; }
  /* Left as auto-flow: this used to force four columns, and with three
     assurances the third matched li:last-child:nth-child(odd), spanned the
     whole row and dropped onto a second line. A wide screen made the wrapping
     worse rather than better. */
  .gms-pdp__assure { grid-template-columns: none; }
  .gms-pdp__panels { padding: 40px 32px; }
}

/* ========================================================== ≥ 861px === */

@media (min-width: 861px) {
  .gms-pdp {
    --gms-pdp-gap: 56px;

    padding: clamp(24px, 3vw, 40px) 40px 80px;
    border-radius: var(--ss-r-xl);
  }

  .gms-pdp__crumbs { margin-bottom: 28px; }

  .gms-pdp__grid {
    grid-template-columns: minmax(0, 50fr) minmax(0, 50fr);
  }

  /* The gallery stays put while the long right column scrolls. */
  .gms-pdp__media {
    position: sticky;

    /* Below whatever the theme has pinned to the top of the screen, measured
       at runtime — a fixed header over a hard-coded 24px offset is what cut
       the top off the photograph and then stuck it there. */
    top: calc(var(--gms-stuck-top, 0px) + 24px);

    /* Capped, and this is the important bit. The mock is drawn at 1420px wide
       with the photograph taking 56% of it — which renders at 710 × 888px on
       a 1440px screen, i.e. an image taller than the laptop it is being
       looked at on. On a 1280 × 800 machine the picture alone was the entire
       viewport and the price sat below the fold on a *desktop*.
       Three caps, smallest wins: never wider than the column, never wider
       than 470px, and never so tall that it eats the screen — 56vh of width
       is 70vh of height once the 4:5 ratio is applied. */
    max-width: min(100%, 470px, 56vh);

    /* width, not just max-width. An auto margin in the inline axis switches a
       grid item off stretch and onto fit-content, so the column was sizing to
       its widest child instead of its track: a narrow photograph made the
       gallery narrow, and a product with no photograph at all collapsed the
       column to zero and left half the page blank. Stating the width restores
       the track sizing and leaves the auto margins doing only the centring
       they were added for. */
    width: 100%;
    margin-inline: auto;
  }

  .gms-pdp__stage {
    aspect-ratio: var(--gms-pdp-ratio, 4 / 5);
    max-height: none;
    border-radius: var(--ss-r-xl);
    box-shadow: var(--ss-lift);
  }

  .gms-pdp__flags { top: 20px; left: 20px; gap: 9px; }
  .gms-pdp__badge { padding: 8px 13px; }
  .gms-pdp__wish { top: 20px; right: 20px; width: 46px; height: 46px; }
  .gms-pdp__counter { right: 20px; bottom: 20px; }
  .gms-pdp__thumbs { gap: 14px; margin-top: 18px; }
  .gms-pdp__thumb { width: 88px; height: 106px; border-radius: 14px; }

  .gms-pdp__info { padding-top: 4px; }
  .gms-pdp__eyebrow { margin-bottom: 18px; letter-spacing: .18em; }

  .gms-pdp__title { font-size: clamp(38px, 3.8vw, 54px); margin-bottom: 20px; }
  .gms-pdp__rating { gap: 12px; margin-bottom: 24px; font-size: 13px; }
  .gms-pdp__price { gap: 16px; margin-bottom: 10px; }
  .gms-pdp__price strong { font-size: clamp(34px, 3vw, 42px); }
  .gms-pdp__price del { font-size: 17px; }
  .gms-pdp__off { padding: 8px 12px; font-size: 12px; }
  .gms-pdp__tax { margin-bottom: 18px; }

  .gms-pdp__opt { margin-bottom: 24px; }
  .gms-pdp__chip { min-width: 96px; min-height: 62px; }

  .gms-pdp__buy { gap: 14px; margin-bottom: 12px; }
  .gms-pdp .gms-qty { width: 148px; min-height: 60px; }
  .gms-pdp .gms-qty__btn { width: 48px; }
  .gms-pdp__add,
  .gms-pdp__buynow { min-height: 60px; font-size: 14px; }

  /* One quiet row under the buy block rather than four cards: above the fold
     on a desktop, boxed reassurance competes with the price. */
  .gms-pdp__assure {
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 16px;
    margin: 26px 0 0;
    padding: 20px 0;
    border-top: 1px solid var(--ss-line);
    border-bottom: 1px solid var(--ss-line);
  }

  .gms-pdp__assure li { padding: 0; background: transparent; font-weight: 500; color: var(--ss-ink-2); }

  .gms-pdp__panels {
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: 64px;
    margin-top: 72px;
    padding: 64px 56px;
  }

  /* A product with a description but no specifications — or the reverse —
     would otherwise leave half the band empty. */
  .gms-pdp__panel:only-child { grid-column: 1 / -1; max-width: 70ch; }

  .gms-pdp__panel h2 { font-size: clamp(32px, 3vw, 42px); margin-bottom: 22px; }

  .gms-pdp__related,
  .gms-pdp__reviews { margin-top: 80px; }

  /* A fixed track, not minmax(0, …). The max in a minmax is a cap, not a
     floor, so with eight related products the grid shrank all eight to fit
     the container instead of overflowing it — four legible cards and a
     scrollbar became eight 82px slivers with "Add to cart" on three lines.

     Divided by 4.3 rather than 4, so a sliver of the fifth card shows. Four
     cards ending flush with the container edge reads as a grid that has been
     cut off — the peek is what says "this scrolls". */
  .gms-pdp__rail { grid-auto-columns: calc((100% - 3 * 24px) / 4.3); gap: 24px; }

  .gms-rev { grid-template-columns: 230px minmax(0, 1fr); gap: 36px; }
  .gms-pdp .gms-rev__rail { position: sticky; top: calc(var(--gms-stuck-top, 0px) + 24px); }
  .gms-pdp .gms-rev__list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
  .gms-pdp .gms-rev__score strong { font-size: 64px; }

  .gms-pdp__more { margin-top: 90px; padding: 84px 44px; }
}

/* ========================================================= ≥ 1200px === */

@media (min-width: 1200px) {
  .gms-pdp { padding-left: 44px; padding-right: 44px; }
  .gms-pdp__grid { gap: 64px; }

  /* No three-up row here, deliberately. Putting the stepper on the same line
     as both actions was measured at every width the layout reaches: the row
     takes its width from the info column, which is 44% of the content area,
     so a 1200px viewport gives 461px — 148px of stepper, two gaps and 131px
     per button, at which "ADD TO CART" wraps to two lines. It needs roughly a
     1330px viewport to fit, and one layout that holds everywhere beats a
     third arrangement that only appears on the widest monitors. */
  .gms-rev { grid-template-columns: 260px minmax(0, 1fr); gap: 56px; }
  .gms-pdp .gms-rev__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ================================================ reduced motion === */

@media (prefers-reduced-motion: reduce) {
  .gms-pdp *,
  .gms-pdpbar * {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
  }

  /* The Buy now animations stop outright rather than running at 0.01ms, which
     for the shimmer would leave the label mid-gradient and unreadable. */
  .gms-pdp__buynow,
  .gms-pdp__buynow-label,
  .gms-pdp__buynow-label::after,
  .gms-pdp__buynow::after { animation: none !important; }

  .gms-pdp__buynow[data-gms-anim="shimmer"] .gms-pdp__buynow-label {
    background: none;
    color: var(--ss-white);
  }

  .gms-pdp__buynow[data-gms-anim="sheen"]::after { display: none; }

  .gms-pdp__add:hover,
  .gms-pdp__buynow:hover,
  .gms-pdp .gms-btn-solid:hover,
  .gms-pdp .gms-share__btn:hover,
  .gms-pdp__wish:hover { transform: none; }
}

/* ================================================ backdrop and print === */

/* The merchant backdrop rules are emitted server-side by
   ProductPageModule::backdropCss() and land after this file, so a chosen
   colour or photograph still wins over the paper above. */

@media print {
  .gms-pdpbar,
  .gms-pdp__nav,
  .gms-pdp__dots,
  .gms-pdp__wish,
  .gms-pdp__buy,
  .gms-pdp .gms-rev__write,
  .gms-pdp__more { display: none; }

  .gms-pdp { background: #fff; box-shadow: none; }
}

/* ================================================ frequently bought === */

/* Above the description, because an offer under eight hundred words of prose
   is an offer nobody sees. */
.gms-fbt {
  margin-top: 40px;
  padding: 24px 20px;
  border: 1px solid var(--ss-line);
  border-radius: var(--ss-r-xl);
  background: var(--ss-white);
}

.gms-fbt__title {
  margin: 0 0 20px;
  font-family: var(--ss-serif);
  font-size: clamp(24px, 5vw, 30px);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -.02em;
  color: var(--ss-ink);
}

.gms-fbt__body { display: grid; gap: 24px; }

/* One row, the way this is read everywhere else: the pictures side by side
   with a plus between them, so the offer is legible at a glance. Stacked as
   full-width rows it took a whole screen to say "these three go together". */
.gms-fbt__items {
  display: flex;
  flex-wrap: wrap;
  /* Stretch, not flex-start: the entries are real cards now and cards size to
     their content, so a two-line title next to a one-line title left the row
     ragged and the buttons at different heights. */
  align-items: stretch;
  gap: 10px;
}

/* Between the pictures, level with them. */
.gms-fbt__plus {
  align-self: center;
  padding: 0 2px;
  font-size: 15px;
  font-weight: 300;
  line-height: 1;
  color: var(--ss-hair);
}

/* Each entry is a real product card with a tick above it.
   
   The panel used to draw its own smaller tile — its own title treatment, its
   own price line, no rating, no delivery estimate, no buttons — so the same
   product looked like two different products depending on where on the page a
   shopper met it. Everything the card knows how to do had to be reinvented
   here or go missing, and it went missing.
   
   So all that is left here is the sizing, the tick, and marking which one is
   the product being looked at. */
.gms-fbt__item {
  flex: 1 1 200px;
  min-width: 170px;
  max-width: 260px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Choosing what goes in the set is the only thing this panel adds to a card,
   so it sits above it rather than inside — nothing about a card changes just
   because it happens to be in this list. */
.gms-fbt__pick {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 6px 9px;
  border: 1px solid var(--ss-line);
  border-radius: var(--ss-r);
  background: var(--ss-paper);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--ss-ink-3);
  cursor: pointer;
  user-select: none;
}

.gms-fbt__pick input {
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: var(--ss-ember-ink);
  cursor: pointer;
}

.gms-fbt__pick:hover { border-color: var(--ss-ember); }

.gms-fbt__item:has(input:checked) .gms-fbt__pick {
  border-color: var(--ss-ember);
  background: rgba(248, 248, 125, .16);
  color: var(--ss-ink);
}

/* Unticked reads as excluded rather than merely unmarked — but only the card
   dims, never the tick, or there is no visible way back. */
.gms-fbt__item:has(input:not(:checked)) .gms-card-p { opacity: .5; }

/* The product being looked at. Said on the tick, where the label already is,
   rather than painted over its photograph. */
.gms-fbt__item.is-this .gms-fbt__pick { border-color: var(--ss-ink); color: var(--ss-ink); }

/* A card in here is a card. It should not carry the grid's own width cap,
   which is set for a four-across listing. */
.gms-fbt__item .gms-card-p { width: 100%; max-width: none; height: 100%; }

.gms-fbt__buy {
  display: grid;
  gap: 12px;
  /* align-content packed the contents at the top but left the panel itself
     stretched to the grid row — 351px of sand behind 130px of label, price
     and button. align-self is the one that sizes the box. */
  align-content: start;
  align-self: start;
  padding: 18px;
  border-radius: var(--ss-r-lg);
  background: var(--ss-sand);
}

.gms-fbt__total { display: grid; gap: 4px; margin: 0; }
.gms-fbt__total span { font-size: 11px; font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--ss-ink-3); }
.gms-fbt__total strong { font-size: 26px; font-weight: 700; letter-spacing: -.02em; color: var(--ss-ink); }

.gms-fbt__add {
  min-height: 52px;
  padding: 14px 22px;
  border: 0;
  border-radius: var(--ss-r);
  background: linear-gradient(110deg, var(--ss-cta-a), var(--ss-cta-b));
  color: var(--ss-white);
  font-family: inherit;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .09em;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 12px 30px rgba(244, 108, 4, .2);
}

.gms-fbt__add:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; }

/* Secondary to Add to cart, and outlined rather than filled: two solid CTAs
   of equal weight leave a customer choosing between them instead of buying. */
.gms-fbt__buynow {
  min-height: 48px;
  padding: 13px 22px;
  border: 1.5px solid var(--ss-ink);
  border-radius: var(--ss-r);
  background: transparent;
  color: var(--ss-ink);
  font-family: inherit;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .09em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .18s ease, color .18s ease;
}

.gms-fbt__buynow:hover { background: var(--ss-ink); color: var(--ss-paper); }
.gms-fbt__buynow:disabled { opacity: .4; cursor: not-allowed; }
.gms-fbt__buynow:disabled:hover { background: transparent; color: var(--ss-ink); }

/* An empty note is not a zero-height note: the margin reset below is scoped
   to :not(:empty), so with nothing to say the paragraph kept its default UA
   margin and held a grid row plus a gap open — about 40px of sand under the
   button that read as the panel being broken. */
.gms-fbt__note:empty { display: none; }

.gms-fbt__note:not(:empty) {
  margin: 0;
  font-size: 12px;
  font-weight: 600;
  color: var(--ss-green-deep);
}

@media (min-width: 861px) {
  .gms-fbt { margin-top: 72px; padding: 32px; }
  .gms-fbt__body { grid-template-columns: minmax(0, 1fr) 260px; gap: 32px; }
}

/* ==================================================== the trust strip === */

/* The promises, under the buy box.
   Wrapping, not a scrolling row. Amazon scrolls this strip, but it has the
   full page width to do it in; here the column is around 400px, so a forced
   single row put five cells behind a scrollbar with no visible affordance —
   promises the customer would simply never find. auto-fit wraps to a second
   line instead, which costs 40px and hides nothing. */
/* One row, always.

   auto-fit with a 76px minimum wrapped as soon as the labels were long — and
   "Free delivery above the threshold" is long — so the three guarantees broke
   onto two lines with a single orphan underneath. A zero minimum lets the
   tracks shrink to whatever is available and keeps them on one line, which is
   what a row of trust marks is for: read at a glance, not read at all. */
.gms-pdp .gms-trust {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px 6px;
  margin: 20px 0 0;
  padding: 14px 4px;
  border-block: 1px solid var(--ss-line);
  list-style: none;
}

.gms-pdp .gms-trust__cell {
  display: grid;
  justify-items: center;
  align-content: start;
  gap: 6px;
  padding: 2px 4px;
  text-align: center;
  text-decoration: none;
  color: inherit;
}

.gms-pdp .gms-trust__icon {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--ss-sand);
  color: var(--ss-ember-ink);
}

.gms-pdp .gms-trust__icon svg { width: 20px; height: 20px; }

.gms-pdp .gms-trust__label {
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ss-ink-2);
}

.gms-pdp .gms-trust__note {
  font-size: 10.5px;
  line-height: 1.3;
  color: var(--ss-ink-3);
}

a.gms-pdp .gms-trust__cell:hover .gms-trust__label,
.gms-pdp a.gms-trust__cell:hover .gms-trust__label { color: var(--ss-ember-ink); }
.gms-pdp a.gms-trust__cell:focus-visible { outline: 2px solid var(--ss-ember-ink); outline-offset: 3px; border-radius: 10px; }

/* ================================================== the brand panel === */

.gms-pdp .gms-brandp {
  display: grid;
  gap: 14px;
  margin-top: 20px;
  padding: 16px 18px;
  border: 1px solid var(--ss-line);
  border-radius: var(--ss-r-lg);
  background: var(--ss-white);
}

.gms-pdp .gms-brandp__id { display: flex; align-items: center; gap: 12px; }

.gms-pdp .gms-brandp__logo {
  width: 48px;
  height: 48px;
  border-radius: 10px;
  object-fit: contain;
  background: var(--ss-shell);
}

/* No logo uploaded: the initial, rather than a broken frame. */
.gms-pdp .gms-brandp__mark {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 10px;
  background: var(--ss-sand);
  font-family: var(--ss-serif);
  font-size: 22px;
  color: var(--ss-ember-ink);
}

.gms-pdp .gms-brandp__who { display: grid; gap: 3px; min-width: 0; }

.gms-pdp .gms-brandp__top {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  justify-self: start;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--ss-sand);
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ss-ember-ink);
}

.gms-pdp .gms-brandp__top svg { width: 12px; height: 12px; }

.gms-pdp .gms-brandp__name {
  font-family: var(--ss-serif);
  font-size: 19px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--ss-ink);
  text-decoration: none;
}

.gms-pdp .gms-brandp__name:hover { color: var(--ss-ember-ink); }

.gms-pdp .gms-brandp__stats {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 10px;
  margin: 0;
  padding-block-start: 12px;
  border-block-start: 1px solid var(--ss-line);
}

.gms-pdp .gms-brandp__stats dt {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ss-ink-3);
}

.gms-pdp .gms-brandp__stats dd {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 4px 0 0;
  font-size: 15px;
  color: var(--ss-ink);
}

.gms-pdp .gms-brandp__stats dd strong { font-weight: 700; }
.gms-pdp .gms-brandp__stats .gms-stars { font-size: 12px; }

.gms-pdp .gms-brandp__all {
  justify-self: start;
  font-size: 13px;
  font-weight: 700;
  color: var(--ss-ember-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* A list on a phone, one product per line.

   Two to a row was tried first and is wrong here. The panel's question is
   "which of these do I also want", and answering it means reading a name and
   a price for each — at two-up on a 375px screen the title wraps to three
   lines, the price lands under the fold of the card, and the tick ends up
   somewhere different on every row. A list gives each product one line of
   its own: picture, name, price, tick, always in the same place.

   The cards stay cards — the same component as everywhere else in the shop,
   just laid on their side — so nothing about a product's appearance depends
   on which panel it turned up in.
   --------------------------------------------------------------------------- */
@media (max-width: 700px) {
  .gms-fbt__items {
    display: block;
    border: 1px solid var(--ss-hair);
    border-radius: 14px;
    overflow: hidden;
  }

  /* Siblings of the items, so they would sit between the rows as stray
     characters once the row is a list. */
  .gms-fbt__plus { display: none; }

  .gms-fbt__item {
    flex: none;
    min-width: 0;
    max-width: none;
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--ss-hair);
  }

  .gms-fbt__item:last-child { border-bottom: 0; }

  /* The anchor product, tinted rather than labelled — the row is too narrow
     to spend a line on saying "this item" and still show a price. */
  .gms-fbt__item.is-this { background: var(--ss-paper-2, rgba(0, 0, 0, .03)); }

  /* The tick moves to the end of the row and loses its wording: with one
     product per line the checkbox is unambiguous, and "Include" repeated
     down the column is noise. */
  .gms-fbt__item .gms-fbt__pick {
    order: 2;
    border: 0;
    padding: 0;
    background: none;
  }

  .gms-fbt__item .gms-fbt__pick span { display: none; }

  /* The card, on its side. */
  .gms-fbt__item .gms-card-p {
    order: 1;
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr);
    align-items: center;
    gap: 12px;
    border: 0;
    background: none;
    box-shadow: none;
    border-radius: 0;
  }

  .gms-fbt__item .gms-card-p:hover { transform: none; box-shadow: none; }

  .gms-fbt__item .gms-card-p__media {
    aspect-ratio: 1;
    border-radius: 8px;
    overflow: hidden;
  }

  .gms-fbt__item .gms-card-p__body { padding: 0; }

  .gms-fbt__item .gms-card-p__title {
    font-size: .8125rem;
    line-height: 1.3;
    /* Two lines, then stop. A four-line name pushes the price out of the row
       and the rows stop lining up with each other. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  /* Hover furniture has no meaning on a touch screen and, at this size, no
     room either. */
  .gms-fbt__item .gms-wish,
  .gms-fbt__item .gms-cmp,
  .gms-fbt__item .gms-card-p__shots,
  .gms-fbt__item .gms-card-p__meta,
  .gms-fbt__item .gms-card-p__delivery { display: none; }
}

@media (max-width: 520px) {
  .gms-pdp .gms-brandp__stats { grid-auto-flow: row; grid-auto-columns: auto; gap: 8px; }
  .gms-pdp .gms-brandp__stats div { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
  .gms-pdp .gms-brandp__stats dd { margin: 0; }
}

/* ====================================================== pack variants === */

.gms-pdp__variants { margin: 18px 0 4px; }

.gms-pdp__variants-label {
  display: block;
  margin-bottom: 8px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ss-ink-3);
}

.gms-pdp__variant-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 8px;
}

.gms-pdp__variant {
  display: grid;
  gap: 3px;
  padding: 11px 13px;
  border: 1.5px solid var(--ss-line);
  border-radius: var(--ss-r);
  background: var(--ss-white);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color .18s ease, background .18s ease;
}

.gms-pdp__variant:hover:not(:disabled) { border-color: var(--ss-hair); }

.gms-pdp__variant.is-on {
  border-color: var(--ss-ember);
  background: var(--ss-sand);
}

/* Sold out stays readable rather than dimmed into illegibility — a shopper
   needs to know which pack is gone, not merely that something is. */
.gms-pdp__variant:disabled {
  cursor: not-allowed;
  background: var(--ss-shell);
  border-style: dashed;
}

.gms-pdp__variant:disabled .gms-pdp__variant-price { text-decoration: line-through; }

.gms-pdp__variant:focus-visible {
  outline: 2px solid var(--ss-ember-ink);
  outline-offset: 2px;
}

.gms-pdp__variant-name {
  font-size: 14px;
  font-weight: 650;
  line-height: 1.25;
  color: var(--ss-ink);
}

.gms-pdp__variant-price { font-size: 14px; font-weight: 700; color: var(--ss-ink); }

.gms-pdp__variant-badge {
  justify-self: start;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--ss-ember);
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: #fff;
}

.gms-pdp__variant-out {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ss-ink-3);
}

/* ---- What's in the box ----------------------------------------------------
   For a gift set the contents are the product: "Diwali Hamper" tells a
   customer nothing, and the decision is entirely about what is inside. */

.gms-inbox {
  margin: 0 0 28px;
  padding: 22px;
  border: 1px solid var(--ss-line);
  border-radius: var(--ss-r-lg);
  background: var(--ss-paper);
}

.gms-inbox__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 16px;
}

.gms-inbox__title {
  margin: 0;
  font-size: 21px;
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -.02em;
  color: var(--ss-ink);
}

.gms-inbox__save {
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  color: var(--ss-ok, #15803d);
}

.gms-inbox__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
  gap: 14px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.gms-inbox__item { display: grid; gap: 5px; align-content: start; }

.gms-inbox__shot {
  position: relative;
  display: block;
  aspect-ratio: 1;
  border-radius: 10px;
  overflow: hidden;
  background: var(--ss-shell);
}

.gms-inbox__shot img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* How many of this one are in the box. Only drawn when it is more than one —
   "×1" on every tile is noise. */
.gms-inbox__qty {
  position: absolute;
  right: 5px;
  bottom: 5px;
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(17, 17, 17, .82);
  color: #fff;
  font-size: 11px;
  font-style: normal;
  font-weight: 700;
  line-height: 1.5;
}

.gms-inbox__name {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.35;
  text-decoration: none;
  color: var(--ss-ink);
}

.gms-inbox__name:hover { text-decoration: underline; }

.gms-inbox__price { font-size: 12px; font-weight: 700; color: var(--ss-ink-3); }

.gms-inbox__out {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--ss-warn, #b45309);
}

/* The three trust marks share the row, so their labels have to survive being
   narrow. Balanced wrapping keeps "Free delivery above the threshold" as two
   even lines rather than four words and an orphan. */
.gms-pdp .gms-trust__label,
.gms-pdp .gms-trust__note {
  text-wrap: balance;
  overflow-wrap: break-word;
  hyphens: auto;
}

@media (max-width: 420px) {
  .gms-pdp .gms-trust__label { font-size: 10.5px; }
  .gms-pdp .gms-trust__note  { font-size: 9.5px; }
}

/* Arrows and "View all", together at the end of the section heading.

   The related rail hides its scrollbar, which on a touchscreen is right and on
   a desktop left no way at all to reach the cards past the first screenful.
   The arrows come from the shared rail script; this only places them. */
.gms-pdp__sectools {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-shrink: 0;
}

/* Hidden where they would be redundant: a touchscreen swipes. */
@media (hover: none) {
  .gms-pdp__sectools .gms-rail__nav { display: none; }
}

/* ---- The member price ----------------------------------------------------
   Under the price, above the buying row: the last thing read before deciding.
   Quiet enough not to compete with the price itself — it is an alternative
   price, not the price, and a shopper who is not going to join must not be
   left unsure what they are actually paying. */

.gms-pdp__member {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 10px;
  margin: 10px 0 0;
  padding: 9px 12px;
  border: 1px dashed var(--ss-line, rgba(87, 82, 74, .28));
  border-radius: var(--ss-r, 14px);
  font-size: 13px;
  line-height: 1.45;
  color: var(--ss-ink-2, #57524a);
}

.gms-pdp__member svg {
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
  color: var(--ss-ember-ink, #a83e05);
}

.gms-pdp__member > span { flex: 1 1 auto; min-width: 0; }

.gms-pdp__member-join {
  flex: 0 0 auto;
  padding: 5px 12px;
  border: 1px solid currentColor;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  text-decoration: none;
  color: var(--ss-ember-ink, #a83e05);
  white-space: nowrap;
}

.gms-pdp__member-join:hover {
  background: var(--ss-ember-ink, #a83e05);
  border-color: var(--ss-ember-ink, #a83e05);
  color: #fff;
}

/* Already a member: a confirmation, not a pitch. Solid, and in the good
   colour, because there is nothing left to sell. */
.gms-pdp__member.is-member {
  border-style: solid;
  border-color: rgba(6, 118, 71, .3);
  background: rgba(6, 118, 71, .05);
  color: #065f46;
}

.gms-pdp__member.is-member svg { color: #067647; }
