/**
 * Port-owned PDP styling for the accordion (toggle) rows.
 *
 * WHY A PORT STYLESHEET AND NOT A THEME EDIT
 * `src/theme/**` is byte-identical to the published theme (guarded by
 * scripts/theme-drift.ts), so the accordion's look cannot be changed there.
 * This file is the port's own layer, injected at the end of `</head>`, and it
 * is the only place the storefront's accordion presentation is decided.
 *
 * THE REQUEST
 * The client, looking at the Book of John PDP next to histrips.com: the toggles
 * feel "amontonado" (cramped). HiStrips gives each toggle its own rounded grey
 * card with a gap between cards; ours is a flat list separated by 1px rules.
 * That is the change: one card per row, generous internal padding, an 8px gap,
 * and the body revealed inside the same card.
 *
 * WHAT IS *NOT* CHANGED (deliberately)
 * - The markup. `snippets/tab.liquid` emits `<details class="byble-acc">` with
 *   `<summary>` and `__title`/`__icon`/`__plus`/`__body` children; every selector
 *   below targets exactly those names, so no Liquid moves and the theme's own
 *   analytics (`posthog-tracking.liquid` listens on `.byble-acc__head`) keeps
 *   working untouched.
 * - The open/close mechanism. These stay native `<details>` elements: no JS, no
 *   aria bookkeeping, keyboard and find-in-page behave as the platform does.
 * - Type scale and colours. Only spacing, radius, surface and borders change —
 *   the typography stays the theme's own.
 *
 * SCOPING
 * `.byble-acc` is used by the PDP tab snippets only, so this cannot leak into
 * the collection filters (`collapsible-trigger`) or the mobile nav.
 */

/* ---- the card ------------------------------------------------------------ */

details.byble-acc {
  display: block;
  /* WHITE toggle on a GREY field — the HiStrips reference the client gave:
     the track is grey, each row is a white card floating on it. (The first
     attempt had it inverted: grey cards on white.) */
  border: 0;
  border-bottom: 0;
  border-radius: 12px;
  background: #fff;
  /* A gap between cards is what stops the "one long list" feel. The margin has
     to go on the WRAPPER, not on `details`: `custom.css` sets
     `.product-block--tab { margin: 0 !important }` per block, and the cards are
     each their own `.product-block--tab`, so a margin here would be collapsed
     between siblings anyway. See the wrapper rule below. */
  margin: 0;
  padding: 0 18px;
  transition: background-color 180ms ease;
}

/* The :first-of-type top rule from custom.css would draw a line above the first
   card; the card edge already does that job. */
.product-block--tab:first-of-type details.byble-acc {
  border-top: 0;
}

/* The gap between cards. The theme's own wrapper is the element that owns the
   block rhythm (`margin: 0 !important` at custom.css:4059), so the spacing is
   set there instead of fighting it with !important on the same property. */
/* The grey field the white cards sit on, wrapping only the accordion rows. */
.product-block--tab {
  margin-bottom: 8px !important;
}

details.byble-acc {
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}

.product-block--tab:last-child,
.product-block--tab:last-of-type {
  margin-bottom: 0 !important;
}

/* Native marker: never rendered, in any engine. */
details.byble-acc > summary {
  list-style: none;
}
details.byble-acc > summary::-webkit-details-marker {
  display: none;
}
details.byble-acc > summary::marker {
  display: none;
}

/* ---- the clickable row --------------------------------------------------- */

summary.byble-acc__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  /* 18px inside the 18px card padding reads as a 20px+ inset at any width;
     the vertical rhythm is what the client saw as cramped before (20px). */
  padding: 18px 0;
  margin: 0;
  cursor: pointer;
  outline: none;
  gap: 16px;
}

/* The theme dims the whole row to 60% on hover, which on a grey card reads as a
   disabled control. Keep the affordance, drop the fade. */
summary.byble-acc__head:hover {
  opacity: 1;
}

@media (hover: hover) and (pointer: fine) {
  details.byble-acc:hover {
    background: #fafafa;
  }
}

summary.byble-acc__head:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
  border-radius: 8px;
}

/* ---------------------------------------------------------------------------
   USP rows inside Key Features.

   `snippets/product-template.liquid` emits a bare `<li>text</li>` list. The design
   puts an icon in front of each row so these read like the trust card above the
   accordion instead of a plain bullet list. The icons are injected by
   `applyUspIcons` in src/lib/product-layout.ts; this only lays them out.
   --------------------------------------------------------------------------- */

/* The theme's `section-featured-product.css` sets `list-style: disc` plus
   `padding-left: 1.5rem` on this exact class. With an icon leading each row the
   disc is a second bullet next to it, so the marker and its indent go; the
   `.byble-acc__body` prefix carries the specificity that beats the theme. */
/* The theme paints its bullets with a PSEUDO-ELEMENT, not with `list-style`:
   `custom.css` has `.byble-acc__body.rte ul li::before` drawing a 5px positioned
   dot, and `.product-features-list li:before` a literal "•" with `!important`.
   `list-style: none` therefore removes nothing. The dot has to be switched off on
   the pseudo-element itself, on the lists where a port icon already leads the row. */
.byble-acc__body ul:has(.usp-icon) > li::before,
.byble-acc__body .key-features-list > li::before {
  content: none !important;
  display: none !important;
}

/* Any list whose rows carry a port icon loses its marker: an icon and a disc
   together is two bullets. `:has()` keeps this honest — a plain list in the same
   body (the theme's fallback copy) keeps the theme's own bullets. */
.byble-acc__body ul:has(.usp-icon),
.byble-acc__body .key-features-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.byble-acc__body ul:has(.usp-icon) > li,
.byble-acc__body .key-features-list > li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 15px;
  line-height: 1.35;
  margin: 0;
}

/* The icon sits in a soft circular well.
   The row label of every accordion toggle already carries its own line icon, so a
   plain glyph leading each USP sentence collided with the same visual weight twice
   in one card — the reference separates them by giving one a chip. The well is a
   tint, never a border: a ring at 28px would read as a control the row does not
   have. `flex: 0 0 28px` keeps the text edge aligned no matter the glyph width. */
.byble-acc__body .key-features-list .usp-icon {
  /* The chip is 28px and a text line is ~20px, so a negative top margin was used to
     centre it on the FIRST line. That polish cost 4px above the row: the animation
     wrapper is `display: grid; overflow: hidden`, so the first chip was clipped at
     the body's top edge. Top-aligned instead, which cannot be clipped. */
  margin-top: 0;
  flex: 0 0 28px;
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: #f2f2f2;
  color: #111;
}

.byble-acc__body .key-features-list .usp-icon svg,
.byble-acc__body ul:has(.usp-icon) .usp-icon svg {
  display: block;
  /* The theme styles `svg` broadly and its rules outrank the presentation
     attribute the generator writes, so the stroke has to be enforced here or the
     USP glyphs come out at 2 next to the trust card's 1.5. */
  stroke-width: 1.5;
}

@media only screen and (max-width: 768px) {
  .key-features-list { gap: 10px; }
  .byble-acc__body ul:has(.usp-icon) > li,
  .byble-acc__body .key-features-list > li { font-size: 14px; gap: 10px; }
  .byble-acc__body .key-features-list .usp-icon { flex: 0 0 26px; width: 26px; height: 26px; }
}

/* ---------------------------------------------------------------------------
   The animated body wrapper.

   `custom.css` animates open/close with `display: grid; grid-template-rows: 0fr`
   -> `1fr` and `overflow: hidden`. That trick relies on the body's own intrinsic
   height to size the single row, and the theme sets `min-height: 0` on the child,
   so the row is free to collapse. With the port's taller bodies (six icon rows in
   Care Instructions instead of a short paragraph) the grid row measured 24px — the
   body's own padding — while the list inside it laid out at 303px and was clipped
   away by `overflow: hidden`.

   `min-height: auto` restores the intrinsic contribution the animation assumes,
   and the explicit `grid-template-rows: auto` on the open state removes the
   `1fr` dependency for content that is taller than the row. The transition stays:
   the grid still animates from 0fr to the natural height.
   --------------------------------------------------------------------------- */

.byble-acc__body-wrap > .byble-acc__body {
  min-height: auto;
}

details.byble-acc[open] > .byble-acc__body-wrap {
  grid-template-rows: auto;
}

/* ---- the row label ------------------------------------------------------- */

/* The theme sets `.byble-acc__title` at 13px / weight 500 / 0.1em tracking, which
   at this row height reads as a caption, not a heading. The reference sets the
   toggle labels in bold at body size, so they hold the row on their own and the
   plus stops being the only weight in it. `letter-spacing` drops to normal because
   0.1em at 15px bold opens gaps the reference does not have. */
.byble-acc .byble-acc__title {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0;
  color: #111;
}

/* ---- open state ---------------------------------------------------------- */

details.byble-acc[open] {
  background: #fff;
}

/* The body sits inside the card; the top padding is the gap under the title row
   and the bottom padding keeps the last paragraph off the card edge. */
details.byble-acc > .byble-acc__body {
  padding: 0 0 20px;
}

details.byble-acc > .byble-acc__body > :first-child {
  margin-top: 0;
}

details.byble-acc > .byble-acc__body > :last-child {
  margin-bottom: 0;
}

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

@media only screen and (max-width: 768px) {
  details.byble-acc {
    padding: 0 16px;
    border-radius: 10px;
    margin-bottom: 8px;
  }

  .byble-acc .byble-acc__title {
    font-size: 14px;
  }

  summary.byble-acc__head {
    /* 16px is still a comfortable tap target with 13px uppercase labels, and it
       keeps more of the page visible per screen than the desktop rhythm. */
    padding: 16px 0;
  }
}

/* ---------------------------------------------------------------------------
   Savings label on the collection cards and the PDP price row.

   History: the port once restyled this to quiet grey text with a "·" separator,
   then removed that override so it matched the live store's red. The client has
   since asked for one treatment across the storefront: a small green pill with a
   white tick, matching the savings badge on the Pairs cards. The separator stays
   gone; only the colour and shape change here.

   `--colorTextSavings` is what the theme paints this label with, so the colour
   below has to beat a custom property: it is declared later at the same
   specificity (one class), and pdp-accordion.css loads after theme.css.

   THE TICK IS A ::before
   These spans are server-rendered Liquid, so no markup can be added to them. The
   Lucide "check" path is therefore a data URI background: white stroke, no fill,
   stroke-width 2.5 because 1.5 disappears at 10px. No JS, no extra element.

   The client then asked for the pill on its OWN LINE under the price ("que no
   esté al lado sino debajo"), so this is a block-level flex box that hugs its own
   content. `display: flex` is what takes it out of the price's inline flow, and
   `width: fit-content` keeps the pill hugging the text instead of stretching to
   the card. The inline-only `margin-left` and `vertical-align` are gone with the
   inline layout they belonged to.

   Two classes, one rule: the grid card uses `.grid-product__price--savings` and
   the PDP price row uses `.product__price-savings`. Both render the same claim, so
   they cannot be styled differently.
   --------------------------------------------------------------------------- */
.grid-product__price--savings,
.product__price-savings {
  display: flex;
  align-items: center;
  width: fit-content;
  gap: 5px;
  margin: 6px 0 0;
  padding: 3px 10px;
  border-radius: 999px;
  background: rgb(0, 105, 60);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
}

/* PDP only: the pill must sit on its own row directly under the price.
   The wrapper is a wrapping flex row shared with the price, the shipping badge and
   the volume tier line, so without an explicit break the pill shares the price's
   line and the tier line lands between the price and its own saving.

   The break is a real zero-height element, NOT `.product__price-savings::before`:
   that pseudo-element is the pill's tick icon, and a full flex basis on it would
   replace the icon with an invisible spacer. A dedicated spacer keeps the tick,
   forces the row, and leaves the pill hugging its own text width. */
.product-price-break {
  flex: 0 0 100%;
  height: 0;
}


/* The listing card centres its title and price, so a left-hugging pill reads off
   centre. Auto side margins centre the fit-content pill under the price. The PDP
   row keeps the shared left margin above, because its price is left aligned. */
.grid-product__price--savings { margin: 4px auto 0; }

.grid-product__price--savings::before,
.product__price-savings::before {
  content: "";
  flex: 0 0 auto;
  width: 10px;
  height: 10px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}

/* ---------------------------------------------------------------------------
   THE ACCORDION FIELD  (histrips.com, which the client pointed at)

   One grey container, a white benefits card, then every toggle as its own white
   card separated by a gap.

   WHY A WRAPPER ELEMENT
   The theme emits the rows as consecutive `.product-block--tab` siblings with no
   container. Painting each row grey and rounding `:first-of-type` /
   `:last-of-type` produced no field at all: each tab is a `<div>` among many
   sibling `<div>`s (header, price, stories), so no row is the first or last of its
   type and every one took the square-cornered middle branch — the chopped strips
   the client saw around the white cards. `src/lib/product-layout.ts` now wraps the
   run in `<div class="byble-acc-field">`, which is the element that owns the grey,
   the outer radius and the 12px inset. No positional selectors are involved.

   `.waitlist-form` is a `.product-block` too (the port inserts it into this
   column), so every selector stays scoped to the field or to `.byble-acc`.
   --------------------------------------------------------------------------- */

.byble-acc-field {
  background: #f2f2f2;
  border-radius: 16px;
  padding: 12px;
  /* The theme gives each tab block its own vertical margin; inside the field the
     gap between cards is owned here instead, so the rhythm is 8px everywhere. */
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.byble-acc-field > .product-block--tab {
  margin: 0 !important;
  padding: 0 !important;
  background: none !important;
  border-radius: 0 !important;
}

/* The benefits card: the theme's own sales points, lifted out of the first toggle
   and given the card the reference shows above the toggles. */
.byble-acc-card {
  background: #fff;
  border: 1px solid #e4e4e4;
  border-radius: 12px;
  padding: 16px 20px;
  /* ABOVE the grey field, in its own space: the reference separates the trust
     card from the accordion container instead of stacking them flush. */
  margin: 0 0 10px;
}

/* The trust card is a stack of statements, one per line: shipping, then the
   missionary note. A two-column grid (the earlier attempt) split an unrelated
   sentence across columns and read as a table of unrelated claims. */
.byble-acc-card--benefits .sales-points {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.byble-acc-card--benefits .sales-point {
  margin: 0;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0.01em;
}

.byble-acc-card--benefits .icon-and-text {
  display: flex;
  align-items: center;
  gap: 14px;
}

.byble-acc-card--benefits .icon {
  flex: 0 0 20px;
  width: 20px;
  height: 20px;
}

/* The white card itself. */
details.byble-acc {
  background: #fff;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
  border-radius: 12px;
  padding: 0 18px;
  margin: 0;
}

@media only screen and (max-width: 768px) {
  .byble-acc-field { padding: 10px; gap: 8px; border-radius: 14px; }
  .byble-acc-card { padding: 16px; }
  .byble-acc-card { padding: 14px 16px; }
}

/* ---------------------------------------------------------------------------
   John PDP blocks: Pairs Well With / Read our reviews / UGC rail.
   Rendered by src/lib/john-blocks.ts, not by the theme.
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   Pairs Well With — the HiStrips cross-sell rail the client pointed at.

   Anatomy, top to bottom: a dark title-case heading, then one light container
   holding a white card per recommendation. Each card is image / name / price /
   pill on one row, with the pill pinned right. The earlier version dropped the
   container (a full-bleed grey band), shrank the image to 72px and set the price
   as plain body text, so the block read as a footnote list rather than a
   merchandising surface.
   --------------------------------------------------------------------------- */

.john-block { padding: 40px 0; }
.john-block--pairs { background: #fff; }

.john-block__heading {
  margin: 0 0 18px;
  font-size: 30px;
  line-height: 1.15;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: #111;
  /* The theme uppercases headings through
     `[data-type_header_capitalize="true"] h2`, an attribute plus a type selector.
     A single class cannot outrank that, so this block carries the wrapper class the
     theme's own element lives inside and wins on equal specificity, later in the
     cascade. The reference and the authored copy are both title case. */
}

.john-block .john-block__heading {
  text-transform: none;
}

/* The light container the cards sit in. It is the visual grouping the reference
   has: one tinted panel, not a full-width band. */
.john-block__pairs {
  list-style: none;
  margin: 0;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  background: #f7f7f7;
  border-radius: 18px;
}

.john-block__pair {
  display: flex;
  align-items: center;
  gap: 20px;
  background: #fff;
  border-radius: 14px;
  padding: 16px 20px;
  /* A hairline plus a soft shadow gives the lift the reference cards have
     without a heavy card treatment. */
  border: 1px solid #ededed;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}

.john-block__pair-media { flex: 0 0 116px; }
.john-block__pair-media img {
  width: 116px;
  height: 116px;
  object-fit: cover;
  border-radius: 10px;
  display: block;
  background: #f2f2f2;
}

.john-block__pair-body { flex: 1 1 auto; min-width: 0; }

.john-block__pair-title {
  display: block;
  font-size: 19px;
  line-height: 1.2;
  font-weight: 700;
  color: #111;
  text-decoration: none;
  letter-spacing: -0.01em;
}
.john-block__pair-title:hover { text-decoration: underline; }

.john-block__pair-price {
  margin-top: 6px;
  font-size: 21px;
  line-height: 1.15;
  font-weight: 700;
  color: #111;
  display: flex;
  align-items: baseline;
  gap: 10px;
}
/* Compare-at: struck through and quiet, never competing with the real price. */
.john-block__pair-price s {
  margin: 0;
  font-size: 17px;
  font-weight: 500;
  color: #9a9a9a;
}

/* The bundle note, matched to the same note everywhere else on the store
   (`/collections/essentials`, the cart upsell): 11px, weight 600, the shop's own
   deep green. A different size or a softer hue made the same sentence look like a
   different claim depending on the page.

   The row holds two claims: the promise as plain text, then the savings as a
   filled badge with a tick, which is what the client's reference shows. `nowrap`
   keeps both on one line at every width; the card gives this row its own line, so
   there is nothing to wrap into. */
.john-block__pair-note {
  margin: 4px 0 0;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.3;
  color: rgb(0, 105, 60);
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.john-block__pair-promise { color: inherit; }

/* The savings badge. The green is the SAME token as the note text above, so the
   badge can never drift into a second brand green, and the tick inherits the
   badge's white through `currentColor`. */
.john-block__save-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: 999px;
  background: rgb(0, 105, 60);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.3;
  vertical-align: middle;
  white-space: nowrap;
}
.john-block__save-pill svg { display: block; flex: 0 0 auto; }

.john-block__pill {
  flex: 0 0 auto;
  border: 0;
  border-radius: 999px;
  background: #111;
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.01em;
  padding: 16px 32px;
  min-width: 148px;
  cursor: pointer;
  transition: background-color 160ms ease;
}
.john-block__pill:hover { background: #000; }
.john-block__pill:disabled { opacity: 0.55; cursor: default; }

/* --- Colour swatches and size pills on the Pairs cards ---------------------
   Same anatomy as the theme's product swatches: a round dot inside a round
   button whose selected and hover states are a ring, never a colour change, so
   a pale swatch cannot lose its selected state. Sizes follow the theme's
   variant-input-wrap labels: a thin box border that fills dark when chosen.

   Both rows are empty until the injected script finds a real option with more
   than one available value, so `:empty` removes them from every card that has
   nothing to pick. */
.john-block__pair-swatches {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
}
.john-block__pair-swatches:empty { display: none; }

.john-block__pair-sizes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
}
.john-block__pair-sizes:empty { display: none; }

.john-block__size {
  padding: 6px 14px;
  border: 1px solid #d0d0d0;
  border-radius: 999px;
  background: #fff;
  color: #111;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.2;
  cursor: pointer;
  transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease;
}
.john-block__size:hover { border-color: #111; }
.john-block__size:focus-visible { outline: 2px solid #111; outline-offset: 2px; }
.john-block__size.is-selected,
.john-block__size[aria-pressed="true"] {
  background: #111;
  border-color: #111;
  color: #fff;
}

.john-block__swatch {
  width: 22px;
  height: 22px;
  padding: 0;
  margin: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  box-shadow: 0 0 0 1px transparent;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: box-shadow 160ms ease, transform 160ms ease;
}
.john-block__swatch:hover { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.45); }
.john-block__swatch:focus-visible { outline: 2px solid #111; outline-offset: 2px; }
.john-block__swatch.is-selected,
.john-block__swatch[aria-pressed="true"] { box-shadow: 0 0 0 2px #111; }

.john-block__swatch-dot {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: block;
  border: 1px solid rgba(0, 0, 0, 0.12);
}

/* Clear is acrylic, not a colour: the theme draws it as a lit gradient so it is
   not mistaken for White. Mirrored here without the product-handle scoping. */
.john-block__swatch--clear .john-block__swatch-dot {
  background-color: #f2f4f6;
  background-image:
    radial-gradient(circle at 28% 22%, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0) 38%),
    linear-gradient(135deg, #eef3f6 0%, #f7f9fa 40%, #e3ebf0 72%, #f2f4f6 100%);
  border-color: #b8c2cc;
}

@media only screen and (max-width: 768px) {
  .john-block { padding: 28px 0; }
  .john-block__heading { font-size: 24px; margin-bottom: 14px; }
  .john-block__pairs { padding: 8px; gap: 10px; border-radius: 14px; }
  /* On a narrow card the title column is only ~110px once the 84px image and the
     pill take theirs, which breaks seven swatches into three ragged rows. The card
     becomes a grid here so the swatch row can span its full width on one line
     under the note, and the pill keeps its place beside the price. Anatomy is
     unchanged: image left, name / price / note centre, pill right, swatches last. */
  .john-block__pair {
    display: grid;
    grid-template-columns: 84px minmax(0, 1fr) auto;
    column-gap: 14px;
    row-gap: 6px;
    align-items: center;
    padding: 12px 14px;
    border-radius: 12px;
  }
  .john-block__pair-media { grid-column: 1; grid-row: 1 / span 2; flex: none; }
  .john-block__pair-media img { width: 84px; height: 84px; border-radius: 8px; }
  .john-block__pair-body { display: contents; }
  .john-block__pair-title { grid-column: 2; grid-row: 1; align-self: end; font-size: 16px; }
  .john-block__pair-price { grid-column: 2; grid-row: 2; font-size: 17px; gap: 8px; }
  .john-block__pair-price s { font-size: 14px; }
  /* The note is a single unbreakable line (promise + savings badge). In the 110px
     centre column it overflowed its box, so it takes a full width row of its own. */
  .john-block__pair-note { grid-column: 1 / -1; grid-row: 3; margin-top: 2px; }
  .john-block__pill { grid-column: 3; grid-row: 1 / span 2; min-width: 0; padding: 12px 20px; font-size: 13px; }
  .john-block__pair-swatches { grid-column: 1 / -1; grid-row: 4; margin-top: 4px; gap: 8px; }
  .john-block__pair-sizes { grid-column: 1 / -1; grid-row: 5; margin-top: 0; gap: 8px; }
  .john-block__swatch { width: 24px; height: 24px; }
  .john-block__swatch-dot { width: 20px; height: 20px; }
  .john-block__size { padding: 7px 16px; }
}

/* --- Read our reviews ----------------------------------------------------- */

.john-block__reviews {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(260px, 1fr);
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}
.john-block--reviews { background: #f7f7f7; }

.john-block__review {
  scroll-snap-align: start;
  background: #fff;
  border-radius: 12px;
  padding: 16px;
}

.john-block__review-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 12px;
}

.john-block__stars { display: inline-flex; gap: 2px; color: #1f9d3f; }
.john-block__star { display: block; }

.john-block__verified {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  color: #3a7bd5;
}

.john-block__review-body { margin: 0 0 14px; font-size: 15px; line-height: 1.45; }
.john-block__review-author { margin: 0; font-size: 12px; font-weight: 600; letter-spacing: 0.06em; }

.john-block__progress {
  margin-top: 14px;
  height: 4px;
  border-radius: 2px;
  background: #e2e2e2;
  overflow: hidden;
}
.john-block__progress > span {
  display: block;
  height: 100%;
  background: #111;
  border-radius: 2px;
}

/* --- UGC rail ------------------------------------------------------------- */

.john-block--ugc { display: none; }
.john-block__ugc {
  list-style: none; margin: 0; padding: 0;
  display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory;
}
.john-block__ugc-card { flex: 0 0 200px; scroll-snap-align: start; }
.john-block__ugc-card video { width: 100%; border-radius: 12px; display: block; background: #000; }

@media only screen and (max-width: 768px) {
  .john-block { padding: 28px 0; }
  .john-block__pair { gap: 12px; padding: 12px; }
  .john-block__pill { padding: 10px 16px; font-size: 12px; }
}
