/* Stoke Tiles redesign: shared components.
   Everything drawn in stoke-tiles-handoff/design/styles.html that tokens.css
   does not already cover. Loaded after tokens.css and after the theme's
   style.css. No hex values: every colour comes from a token.

   All selectors are `st-` prefixed. The theme's style.css contains no `st-`
   selector, so nothing here can reach a page that has not opted in. */

/* ---------------------------------------------------------------- Layout */

/* font-weight is named because the theme sets `body { font-weight: 300 }`,
   which otherwise makes every unstyled run of Jost render light. */
.st-scope { font-family: var(--st-sans); font-weight: 400; color: var(--st-espresso); line-height: 1.6; }
.st-scope *, .st-scope *::before, .st-scope *::after { box-sizing: border-box; }

.st-wrap { width: 100%; max-width: 1440px; margin: 0 auto; padding: 0 var(--st-gutter-desktop); }
.st-section { padding: var(--st-section-desktop) 0; }
.st-stack { display: flex; flex-direction: column; }
.st-row { display: flex; align-items: center; }

/* ------------------------------------------------------------------ Type */

.st-display {
  font-family: var(--st-serif);
  font-weight: 500;
  font-size: var(--st-display);
  line-height: 0.95;
  text-transform: uppercase;
  margin: 0;
}
.st-h1 { font-family: var(--st-serif); font-weight: 500; font-size: var(--st-h1); line-height: 1.05; margin: 0; }
.st-h2 { font-family: var(--st-serif); font-weight: 500; font-size: var(--st-h2); line-height: 1.05; margin: 0; }
.st-h3 { font-family: var(--st-serif); font-weight: 500; font-size: var(--st-h3); line-height: 1.2; margin: 0; }
.st-body-l { font-size: var(--st-body-l); font-weight: 300; line-height: 1.6; }
.st-body { font-size: var(--st-body); line-height: 1.6; }
.st-small { font-size: var(--st-small); line-height: 1.5; color: var(--st-taupe); }
.st-label {
  font-size: var(--st-label);
  font-weight: 500;
  letter-spacing: var(--st-track-label);
  text-transform: uppercase;
}

/* A section heading with its eyebrow above it. */
.st-heading { display: flex; flex-direction: column; gap: 12px; }
.st-heading--center { align-items: center; text-align: center; }

/* Rules are gold, and only ever hairlines. */
.st-rule { height: 1px; background: var(--st-divider); border: 0; margin: 0; }
.st-rule--gold { background: var(--st-gold); }

/* Where a sideways scroller has got to: three 28x2 marks, the current one
   dark. Drawn only where the track actually scrolls, which is the phone
   layout - at desktop the cards are all on screen and the arrows page. */
.st-dots { display: none; gap: 6px; }
.st-dots span { width: 28px; height: 2px; background: var(--st-linen); }
.st-dots span.is-on { background: var(--st-espresso); }
@media (max-width: 1024px) {
  .st-dots { display: flex; }
}


/* --------------------------------------------------------------- Buttons */

/* Height: the design draws buttons at 52px; tokens.css sets the large 56px
   variant as the .st-btn default. --lg is the 56px call to action, and the
   base class matches the 52px used through the buy box and forms. */
.st-btn { min-height: var(--st-control-h); }
.st-btn--lg { min-height: var(--st-control-h-lg); }
.st-btn--block { display: flex; width: 100%; }
/* 44px, not 40: every other control on the page honours that minimum and
   the design draws this one at 44 too. */
.st-btn--sm { min-height: 44px; padding: 0 18px; gap: 6px; font-size: var(--st-eyebrow); letter-spacing: 0.14em; }
.st-btn--dark { background: var(--st-espresso); color: var(--st-ivory); }
.st-btn--dark:hover { background: var(--st-espresso); color: var(--st-white); }
.st-btn--secondary:hover { background: var(--st-espresso); color: var(--st-ivory); }
.st-btn--on-dark:hover { background: var(--st-white); color: var(--st-espresso); }
.st-btn--on-dark-outline:hover { background: var(--st-white); color: var(--st-espresso); }
.st-btn[disabled]:hover { background: var(--st-divider); color: var(--st-taupe); }
.st-btn svg { flex-shrink: 0; }

/* Text link with a trailing arrow. */
.st-link { display: inline-flex; align-items: center; gap: 10px; }
.st-link--plain { border-bottom: 0; }

/* Round icon button, 52px, 1.5px line icon inside. */
.st-icon-btn {
  width: var(--st-control-h);
  height: var(--st-control-h);
  border-radius: 50%;
  border: 1px solid var(--st-espresso);
  background: transparent;
  color: var(--st-espresso);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}
.st-icon-btn:hover { background: var(--st-espresso); color: var(--st-ivory); }
.st-icon-btn[disabled] { border-color: var(--st-linen); color: var(--st-linen); cursor: not-allowed; }
.st-icon-btn[disabled]:hover { background: transparent; color: var(--st-linen); }
.st-icon-btn--on-dark { border-color: var(--st-white); color: var(--st-white); }

/* Every interactive thing gets the same visible focus ring. */
.st-scope a:focus-visible,
.st-scope button:focus-visible,
.st-scope input:focus-visible,
.st-scope select:focus-visible,
.st-scope textarea:focus-visible,
.st-scope [tabindex]:focus-visible {
  outline: 3px solid var(--st-focus);
  outline-offset: 2px;
}

/* ----------------------------------------------------------------- Forms */

.st-fieldset { margin: 0; padding: 0; border: 0; display: flex; flex-direction: column; gap: 12px; }
.st-legend { font-size: var(--st-small); font-weight: 500; margin-bottom: 8px; padding: 0; }
.st-field-group { display: flex; flex-direction: column; gap: 8px; }
.st-field-hint { font-size: 13px; color: var(--st-taupe); }
.st-field--select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 44px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%231F1C19' stroke-width='1.5'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 20px 20px;
}
.st-field--textarea { height: auto; padding: 14px 16px; line-height: 1.6; resize: vertical; }

/* Quantity stepper */
.st-stepper {
  display: inline-flex;
  height: var(--st-control-h);
  border: 1px solid var(--st-linen);
  border-radius: var(--st-radius);
  background: var(--st-white);
}
.st-stepper__btn {
  width: var(--st-control-h);
  border: 0;
  background: transparent;
  color: var(--st-espresso);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}
.st-stepper__btn:hover:not([disabled]) { background: var(--st-ivory); }
.st-stepper__btn[disabled] { color: var(--st-linen); cursor: not-allowed; }
.st-stepper__input {
  width: 82px;
  border: 0;
  border-left: 1px solid var(--st-linen);
  border-right: 1px solid var(--st-linen);
  text-align: center;
  font-family: var(--st-sans);
  font-size: 18px;
  color: var(--st-espresso);
  background: transparent;
  -moz-appearance: textfield;
}
.st-stepper__input::-webkit-outer-spin-button,
.st-stepper__input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* Checkbox. A real input, visually hidden, with a drawn box beside it. */
.st-check { display: flex; align-items: center; gap: 12px; min-height: var(--st-tap-min); font-size: 15px; cursor: pointer; }
.st-check input[type="checkbox"] { position: absolute; opacity: 0; width: 22px; height: 22px; margin: 0; cursor: pointer; }
.st-check__box {
  width: 22px;
  height: 22px;
  border: 1px solid var(--st-linen);
  background: var(--st-white);
  border-radius: var(--st-radius);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--st-white);
  flex-shrink: 0;
}
.st-check__box svg { opacity: 0; }
.st-check input[type="checkbox"]:checked + .st-check__box { background: var(--st-sage); border-color: var(--st-sage); }
.st-check input[type="checkbox"]:checked + .st-check__box svg { opacity: 1; }
.st-check input[type="checkbox"]:focus-visible + .st-check__box { outline: 3px solid var(--st-focus); outline-offset: 2px; }
.st-check input[type="checkbox"][disabled] + .st-check__box { background: var(--st-divider); border-color: var(--st-divider); }

/* Radio card: a whole panel is the target, not just the dot. */
.st-radio-card {
  display: flex;
  gap: 14px;
  padding: 18px 20px;
  border: 1px solid var(--st-linen);
  background: var(--st-white);
  border-radius: var(--st-radius);
  cursor: pointer;
  position: relative;
}
.st-radio-card input[type="radio"] { position: absolute; opacity: 0; width: 20px; height: 20px; margin: 0; cursor: pointer; }
.st-radio-card__dot {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1.5px solid var(--st-taupe);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-top: 2px;
  box-sizing: border-box;
}
.st-radio-card__dot::after { content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--st-espresso); opacity: 0; }
.st-radio-card input[type="radio"]:checked ~ .st-radio-card__dot { border-color: var(--st-espresso); }
.st-radio-card input[type="radio"]:checked ~ .st-radio-card__dot::after { opacity: 1; }
.st-radio-card:has(input[type="radio"]:checked) { border: 1.5px solid var(--st-espresso); padding: 17.5px 19.5px; }
.st-radio-card input[type="radio"]:focus-visible ~ .st-radio-card__dot { outline: 3px solid var(--st-focus); outline-offset: 3px; }
.st-radio-card__text { display: flex; flex-direction: column; gap: 4px; flex-grow: 1; }
.st-radio-card__title { display: flex; justify-content: space-between; gap: 16px; font-size: 15px; font-weight: 500; }
.st-radio-card__note { font-size: 13px; color: var(--st-taupe); }

/* The unavailable state is not a radio at all: nothing to choose. */
.st-radio-card--off {
  border: 1px dashed var(--st-linen);
  background: var(--st-ivory);
  cursor: default;
}
.st-radio-card--off .st-radio-card__dot { border-color: var(--st-linen); }
.st-radio-card--off .st-radio-card__title,
.st-radio-card--off .st-radio-card__note { color: var(--st-taupe); }

/* -------------------------------------------------------- Product cards */

/* The design draws cards as image, then a text block on the page background.
   .st-card__body in tokens.css paints that block white for the boxed variant
   used on the homepage and category grid; --bare drops the box. */
.st-card { gap: 16px; }
.st-card--bare .st-card__body { background: transparent; padding: 0; }
.st-card__media { display: block; }
.st-card__media--pad { display: flex; align-items: center; justify-content: center; }
.st-card__name { color: var(--st-espresso); text-decoration: none; }
a.st-card__name:hover { color: var(--st-bronze); }
.st-card__tagline {
  font-size: var(--st-eyebrow);
  letter-spacing: var(--st-track-nav);
  text-transform: uppercase;
  color: var(--st-bronze);
}
.st-card__price { display: flex; align-items: baseline; gap: 8px; margin-top: 4px; }
.st-card__price-main { font-family: var(--st-serif); font-size: 26px; font-weight: 600; }
.st-card__price-unit { font-size: var(--st-small); color: var(--st-taupe); }
.st-card__meta { font-size: 13px; color: var(--st-taupe); }

/* Badge, top left of the image. */
.st-badge {
  position: absolute;
  left: 12px;
  top: 12px;
  height: 28px;
  padding: 0 10px;
  background: var(--st-espresso);
  color: var(--st-ivory);
  font-size: 11px;
  letter-spacing: var(--st-track-label);
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
}
.st-badge--sage { background: var(--st-sage); color: var(--st-white); }

/* Free sample button, bottom left of the image. */
.st-sample-btn {
  /* Anchored to the foot of the picture. `bottom` would measure from the
     card, whose height varies with the name; the media's height does not. */
  position: absolute;
  left: 12px;
  top: calc(332px - 56px);
  height: 44px;
  padding: 0 14px;
  background: color-mix(in srgb, var(--st-ivory) 94%, transparent);
  border: 0;
  border-radius: var(--st-radius);
  font-family: var(--st-sans);
  font-size: var(--st-eyebrow);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--st-espresso);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}
.st-sample-btn:hover { background: var(--st-ivory); }

/* Stand in for a pack shot the client has not supplied. */
.st-packshot {
  background: var(--st-linen);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: var(--st-eyebrow);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--st-taupe);
  padding: 12px;
}

/* -------------------------------------------------------------- Messages */

/* Plain panels. No coloured stripe down the side, no info icon: the brief
   and the design both call for the message to carry itself in words. */
.st-message {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 20px 24px;
  background: var(--st-white);
  border: 1px solid var(--st-linen);
}
.st-message__text { margin: 0; font-size: 15px; line-height: 1.5; }
.st-message__text strong { font-weight: 500; }
.st-message--alert .st-message__text { color: var(--st-alert); }
.st-message__actions { display: flex; gap: 20px; align-items: center; flex-wrap: wrap; }
.st-message__actions a {
  font-size: var(--st-label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--st-bronze);
  /* Underlined, as the design draws them: inside a panel of prose there is no
     other signal that these are links. The theme's stylesheet strips underlines
     globally, so it has to be put back explicitly. */
  text-decoration: underline;
  text-underline-offset: 3px;
}
.st-message__actions a:hover { color: var(--st-espresso); }
/* Phase 2 fix: a button among the actions keeps the button's own colours.
   The bronze link colour above was landing on the espresso fill (2.8:1). */
.st-message__actions a.st-btn { text-decoration: none; }
.st-message__actions a.st-btn--dark,
.st-message__actions a.st-btn--dark:hover { color: var(--st-ivory); }
.st-message__actions a.st-btn--secondary { color: var(--st-espresso); }
.st-message__actions a.st-btn--secondary:hover { color: var(--st-ivory); }

/* One chevron, mirrored, rather than a second icon. Shared, because it was
   stranded in st-home.css - which a product page does not load - so the
   gallery's previous arrow pointed right. */
.st-flip { display: flex; transform: scaleX(-1); }

/* Review card. Shared: the product page shows the site's reviews too, and
   this lived in st-home.css, which a product page does not load - so the cards
   rendered with no card at all. Fifth time a shared component has been left in
   a page sheet in this build.

   Measurements from the reviews section in product-tile.html: ivory rather
   than white, bordered, 28px, a fixed 320px so a short review and a long one
   line up, and the attribution stacked rather than spread. */
.st-review {
  margin: 0;
  height: 320px;
  box-sizing: border-box;
  background: var(--st-ivory);
  border: 1px solid var(--st-divider);
  padding: 28px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 16px;
}
.st-review__quote {
  margin: 0;
  font-family: var(--st-serif);
  font-size: 21px;
  line-height: 1.3;
  /* The card is a fixed height, as drawn. The design's sample reviews all fit
     it; real ones do not, and hiding the overflow cut a word in half.
     `-webkit-line-clamp` is not available here: this is a flex item, so
     `display: -webkit-box` is blockified away and the clamp never applies.
     A max-height of a whole number of lines cuts between lines instead. */
  max-height: calc(21px * 1.3 * 7);
  overflow: hidden;
}
.st-review__meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: var(--st-label);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.st-review__name { font-weight: 500; }
.st-review__date { color: var(--st-taupe); }

/* ---------------------------------------------------------------- Header */

/* Measurements come from the header drawn in home.html, category.html,
   category-nested.html, product-tile.html, product-porcelanosa.html and
   basket.html - all six agree. styles.html draws a leaner variant, which is
   what T2 was mistakenly built from; see DECISIONS.md D62. */

.st-topbar {
  height: 40px;
  background: var(--st-sage);
  color: var(--st-white);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 0 var(--st-gutter-desktop);
  font-size: var(--st-label);
  letter-spacing: 0.04em;
}
.st-topbar a { color: var(--st-white); text-decoration: none; }
.st-topbar a:hover { text-decoration: underline; }
.st-topbar__spacer { width: 280px; flex-shrink: 0; }
.st-topbar__message { text-align: center; }
.st-topbar__message strong { font-weight: 500; }
.st-topbar__links { width: 280px; display: flex; justify-content: flex-end; gap: 28px; flex-shrink: 0; }

.st-header__main {
  height: 88px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 0 var(--st-gutter-desktop);
}
.st-header__logo { width: 280px; flex-shrink: 0; }

/* Account links: icon above a small capital label, with the basket count
   sitting on the corner of its bag. */
.st-header__utils {
  width: 280px;
  flex-shrink: 0;
  display: flex;
  justify-content: flex-end;
  gap: 28px;
}
.st-header__util {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: inherit;
  text-decoration: none;
  font-size: 11px;
  letter-spacing: var(--st-track-nav);
  text-transform: uppercase;
}
.st-header__util svg { flex-shrink: 0; }
.st-header__badge {
  position: absolute;
  top: -6px;
  right: -2px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  box-sizing: border-box;
  border-radius: 9px;
  background: var(--st-espresso);
  color: var(--st-ivory);
  font-size: 11px;
  letter-spacing: 0;
  line-height: 18px;
  text-align: center;
}

.st-search {
  width: 480px;
  height: 46px;
  border: 1px solid var(--st-linen);
  background: var(--st-white);
  border-radius: var(--st-radius-pill);
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 6px 0 22px;
  box-sizing: border-box;
  font-size: 15px;
  color: var(--st-taupe);
  flex-shrink: 0;
}
.st-search input {
  border: 0;
  background: transparent;
  flex-grow: 1;
  height: 100%;
  font-family: var(--st-sans);
  font-size: 15px;
  color: var(--st-espresso);
  min-width: 0;
}
.st-search button {
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--st-espresso);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}

/* The design draws six nav items with a 36px gap. The live menu has eight,
   two of them long enough that at 36px the row needs 1296px of a 1280px
   gutter - so items wrapped to a second line inside a 56px bar. The gap gives
   way before the row does, and the row never wraps.

   This must NOT be given `overflow: auto` as a safety valve. It was, and a
   56px tall scroll container clips its own dropdowns to 56px - every menu
   panel on the site was cut off at the height of the bar. If the menu ever
   outgrows the row, let it overflow visibly rather than hide the panels. */
.st-nav {
  height: 56px;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: clamp(16px, 2.2vw, 36px);
  padding: 0 var(--st-gutter-desktop);
  font-size: var(--st-label);
  letter-spacing: var(--st-track-nav);
  text-transform: uppercase;
}
/* `color: inherit` belongs to the nav's own links, not to the pill: as
   `.st-nav a` it scored one step above `.st-nav__pill` and repainted the
   pill's white text espresso on sage. */
.st-nav a { text-decoration: none; white-space: nowrap; }
.st-nav__item a { color: inherit; }
.st-nav__item { flex-shrink: 0; }
.st-nav__chevron { display: flex; }
.st-nav__pill {
  margin-left: auto;
  flex-shrink: 0;
  background: var(--st-sage);
  color: var(--st-white);
  padding: 10px 16px;
}

/* Over an image: chrome goes transparent, everything turns white. */
.st-header--overlay { color: var(--st-white); }
.st-header--overlay .st-header__main { border-bottom: 1px solid color-mix(in srgb, var(--st-white) 20%, transparent); }
.st-header--overlay .st-search {
  border-color: color-mix(in srgb, var(--st-white) 50%, transparent);
  background: color-mix(in srgb, var(--st-white) 12%, transparent);
  color: color-mix(in srgb, var(--st-white) 85%, transparent);
}
.st-header--overlay .st-search input { color: var(--st-white); }
.st-header--overlay .st-search input::placeholder { color: color-mix(in srgb, var(--st-white) 85%, transparent); }
.st-header--overlay .st-search button { color: var(--st-white); }
.st-header--overlay .st-header__badge { background: var(--st-ivory); color: var(--st-espresso); }
.st-header--overlay .st-nav__pill {
  background: transparent;
  color: var(--st-white);
  border: 1px solid color-mix(in srgb, var(--st-white) 65%, transparent);
}

/* Solid: the default everywhere else, and what the overlay becomes on scroll. */
.st-header--solid { background: var(--st-ivory); color: var(--st-espresso); }
.st-header--solid .st-header__main { border-bottom: 1px solid var(--st-linen); }
.st-header--solid .st-nav { border-bottom: 1px solid var(--st-linen); }

/* The dark scrim that keeps white chrome legible over a photograph. */
.st-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(24, 21, 18, 0.72) 0%, rgba(24, 21, 18, 0.35) 100%);
}

/* ----------------------------------------------------------------- Mobile */

@media (max-width: 1024px) {
  .st-wrap { padding: 0 var(--st-gutter-mobile); }
  .st-section { padding: var(--st-section-mobile) 0; }
  .st-topbar, .st-header__main, .st-nav { padding: 0 var(--st-gutter-mobile); }
  /* Below the desktop canvas the nav wraps rather than forcing the page wide.
     T2 replaces it outright with the 64px bar and drawer on phones. */
  .st-nav { height: auto; flex-wrap: wrap; gap: 20px 24px; padding-top: 12px; padding-bottom: 12px; }
  .st-nav__pill { margin-left: 0; }
  .st-header__main { height: auto; flex-wrap: wrap; gap: 16px; padding-top: 12px; padding-bottom: 12px; }
  .st-header__logo,
  .st-header__utils,
  .st-topbar__spacer,
  .st-topbar__links { width: auto; }
  .st-search { width: 100%; }
}

/* Touch targets.

   Two components are drawn smaller than 44px in the design: the free sample
   button on a product card (36px) and the plain text links inside a message
   panel (21px). Rather than redraw them and lose the design, each gets a
   transparent 44px tall hit area from a pseudo element, which changes nothing
   about layout or appearance. Applied only on coarse pointers, so a mouse
   still gets exactly the box it can see. */
@media (pointer: coarse) {
  .st-sample-btn::after,
  .st-message__actions a::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    height: var(--st-tap-min);
  }
  .st-message__actions a { position: relative; }
}

@media (max-width: 640px) {
  .st-card__price-main { font-size: 22px; }
  .st-message { padding: 16px 18px; }
  .st-radio-card { padding: 16px; }
  .st-radio-card:has(input[type="radio"]:checked) { padding: 15.5px; }
  .st-search { width: 100%; }
  /* Tap targets stay at 44px however tight the layout gets. */
  /* Not .st-btn: its own tokens are 52px and 56px, both already above the
     44px minimum, so including it here only shrank every CTA below what the
     design draws. The icon and stepper buttons genuinely can be smaller. */
  .st-icon-btn, .st-stepper__btn { min-height: var(--st-tap-min); }
}

/* =====================================================================
   The product card and its grid.

   Lives here rather than in st-catalog.css because the same card appears on
   category pages, in related products on a product page, and in cross sells
   in the basket. Keeping it with the catalogue meant related products
   rendered unstyled the moment they appeared outside an archive.
   ===================================================================== */

/* ------------------------------------------------------------ Product grid */

.st-pgrid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: 24px;
  row-gap: 48px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.st-pgrid > li { list-style: none; }

.st-pcard { position: relative; display: flex; flex-direction: column; height: 100%; }
.st-pcard__media {
  position: relative;
  height: 332px;
  overflow: hidden;
  background: var(--st-stone);
}
/* The card's own link fills the media box. Named explicitly, because as
   `.st-pcard__media > a` this also caught the free-sample button sitting in
   the same box and flattened it over the photograph. */
.st-pcard__media > a.st-pcard__link { display: block; width: 100%; height: 100%; }
.st-pcard .st-pcard__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 600ms ease;
}
.st-pcard:hover .st-pcard__media img { transform: scale(1.04); }
.st-pcard__empty { width: 100%; height: 100%; }

.st-pcard__body {
  background: var(--st-white);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex-grow: 1;
}
.st-pcard__tagline {
  font-size: var(--st-eyebrow);
  letter-spacing: var(--st-track-nav);
  text-transform: uppercase;
  color: var(--st-bronze);
}
.st-pcard__name {
  font-family: var(--st-serif);
  font-size: 24px;
  line-height: 1.2;
  font-weight: 500;
  color: var(--st-espresso);
  text-decoration: none;
  /* The design reserves three lines so the price lines up across a row. */
  min-height: 87px;
}
.st-pcard__name:hover { color: var(--st-bronze); }
.st-pcard__price { display: flex; align-items: baseline; gap: 8px; }
.st-pcard__price-main { font-family: var(--st-serif); font-size: 26px; font-weight: 600; line-height: normal; }
.st-pcard__price-unit { font-size: var(--st-small); color: var(--st-taupe); }
.st-pcard__meta { font-size: 13px; line-height: normal; color: var(--st-taupe); }

/* The card's sample button is a link, so it needs the button's look. */
a.st-sample-btn { text-decoration: none; }

@media (max-width: 1024px) {
  .st-pgrid { column-gap: 12px; row-gap: 28px; }
  .st-pcard__media { height: 200px; }
  /* Still a white panel at this width, as the design draws it - dropping
     the background left the text sitting straight on the page. */
  .st-pcard__body { padding: 12px; gap: 4px; }
  /* Below the card, not over the photograph: at this size the pill covered
     a third of a 200px image. Bronze on white, left aligned, as drawn. */
  .st-sample-btn {
    position: static;
    top: auto;
    height: 48px;
    padding: 0 12px 6px;
    background: transparent;
    color: var(--st-bronze);
    justify-content: flex-start;
    gap: 6px;
  }
  .st-sample-btn:hover { background: transparent; color: var(--st-espresso); }
  .st-pcard__name { font-size: 19px; min-height: 68px; display: flex; align-items: flex-start; }
  .st-pcard__price-main { font-size: 22px; }
}

/* =====================================================================
   Shared furniture that more than one page needs.

   These started life in the stylesheet of the page that first used them, and
   that was wrong: the breadcrumb rendered as a numbered list on the product
   page, because .st-crumbs and its `list-style: none` only loaded on category
   pages. Anything used by two templates belongs here.
   ===================================================================== */

.st-crumbs {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  font-size: var(--st-label);
  letter-spacing: 0.04em;
}
.st-crumbs a { color: var(--st-on-dark-cream); text-decoration: none; }
.st-crumbs a:hover { color: var(--st-white); text-decoration: underline; }
.st-crumbs li[aria-hidden] { color: var(--st-on-dark-muted); }
.st-crumbs [aria-current] { color: var(--st-white); }

.st-accordion { border-top: 1px solid var(--st-linen); }
.st-accordion__item { border-bottom: 1px solid var(--st-linen); }
.st-accordion h3 { margin: 0; font-size: inherit; font-family: inherit; }
.st-accordion__toggle {
  width: 100%;
  min-height: 74px;
  padding: 24px 0;
  border: 0;
  background: transparent;
  color: var(--st-espresso);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  font-family: var(--st-sans);
  font-size: var(--st-body-l);
  line-height: 1.45;
  text-align: left;
  cursor: pointer;
}
.st-accordion__toggle svg { flex-shrink: 0; }
/* Plus when closed, minus when open, as the designs draw it - a chevron reads
   as "go somewhere", and this opens in place. */
.st-accordion__pm { display: flex; flex-shrink: 0; }
.st-accordion__pm svg:last-child { display: none; }
.st-accordion__toggle[aria-expanded="true"] .st-accordion__pm svg:first-child { display: none; }
.st-accordion__toggle[aria-expanded="true"] .st-accordion__pm svg:last-child { display: block; }
.st-accordion__body { padding: 0 64px 28px 0; }
.st-accordion__body[hidden] { display: none; }
.st-accordion__body p { margin: 0 0 1em; font-size: var(--st-body); line-height: 1.65; color: var(--st-taupe); }
.st-accordion__body p:last-child { margin-bottom: 0; }

.st-section__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 32px;
  margin-bottom: 48px;
}

/* =====================================================================
   "Complete the job": adhesive and grout beside a tile.

   Shared by the product page and the basket, so it lives here. It was in
   st-product.css, which the basket does not load, and the row rendered as
   four full width unstyled cards.
   ===================================================================== */

/* ------------------------------------------------------- Complete the job */

.st-job { background: var(--st-white); padding: 88px 0; }
.st-job__head { display: flex; justify-content: space-between; align-items: flex-end; gap: 32px; margin-bottom: 36px; }
.st-job__note { margin: 0; max-width: 420px; font-size: var(--st-small); line-height: 1.55; color: var(--st-taupe); text-align: right; }
.st-job__grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 24px; }

.st-jobcard { display: flex; flex-direction: column; }
.st-jobcard__media {
  height: 150px;
  background: var(--st-stone);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.st-jobcard__media img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* Complete the job: the whole pack shot shows, at one height, on white (the
   pack shots are photographed on white), framed by the stone card. Shared by
   the product page and the basket (client round 2). */
.st-job .st-jobcard__media { height: 200px; padding: 16px; background: var(--st-white); border: 1px solid var(--st-panel); border-bottom: 0; box-sizing: border-box; }
.st-job .st-jobcard__media img { width: 100%; height: 100%; object-fit: contain; object-position: center; }
@media (max-width: 767px) {
  .st-job .st-jobcard__media { height: 160px; padding: 12px; }
}
/* Client round 2: product grid cards with a pack shot show it whole. */
.st-pcard--packshot .st-pcard__media { background: var(--st-white); }
.st-pcard.st-pcard--packshot .st-pcard__media img { object-fit: contain; padding: 16px; box-sizing: border-box; }
.st-jobcard__empty { width: 96px; height: 120px; font-size: 11px; }
.st-jobcard__body { background: var(--st-panel); padding: 20px; display: flex; flex-direction: column; gap: 6px; flex-grow: 1; }
.st-jobcard__text { display: flex; flex-direction: column; gap: 6px; min-height: 118px; }
.st-jobcard__tagline {
  font-size: var(--st-eyebrow);
  letter-spacing: var(--st-track-nav);
  text-transform: uppercase;
  color: var(--st-bronze);
}
.st-jobcard__name { font-family: var(--st-serif); font-size: 22px; line-height: 1.2; font-weight: 500; color: var(--st-espresso); text-decoration: none; }
.st-jobcard__name:hover { color: var(--st-bronze); }
.st-jobcard__foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.st-jobcard__price { display: flex; flex-direction: column; }
.st-jobcard__price-value { font-family: var(--st-serif); font-size: 24px; font-weight: 600; line-height: 1.1; }
.st-jobcard__price-unit { font-size: var(--st-eyebrow); color: var(--st-taupe); }

@media (max-width: 1200px) {
  .st-job__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 1024px) {
  .st-job { padding: 56px 0; }
  .st-job__head { flex-direction: column; align-items: flex-start; gap: 16px; }
  .st-job__note { text-align: left; }
}

/* On a phone this is a scroller, not a grid. Two across leaves 123px inside
   the card padding, and a price beside a 44px Add button wants about 160px -
   the button ended up outside the card and the name wrapped to six lines.
   The design runs 220px cards off the right edge instead, so the row reads as
   something to swipe. */
@media (max-width: 767px) {
  .st-job { padding: 56px 0 56px var(--st-gutter-mobile); }
  /* The row has to reach the screen edge, so the wrap gives up its padding
     and the head takes its own back. */
  .st-job > .st-wrap { padding: 0; max-width: none; }
  .st-job__head { padding-right: var(--st-gutter-mobile); }

  .st-job__grid {
    display: flex;
    grid-template-columns: none;
    gap: 12px;
    overflow-x: auto;
    padding-right: var(--st-gutter-mobile);
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .st-job__grid::-webkit-scrollbar { display: none; }

  .st-jobcard { width: 220px; flex-shrink: 0; scroll-snap-align: start; }
  .st-jobcard__media { height: 120px; }
  .st-jobcard__body { padding: 14px; gap: 4px; }
  .st-jobcard__text { min-height: 118px; gap: 4px; }
  .st-jobcard__tagline { font-size: 11px; }
  .st-jobcard__name { font-size: 20px; }
  .st-jobcard__price-value { font-size: 22px; }
  .st-jobcard__price-unit { font-size: 11px; }
  /* 14px, not the 18px the desktop button takes: inside 192px of card there
     is not room for both the price and a wider button. */
  .st-jobcard__foot .st-btn--sm { padding: 0 14px; font-size: 12px; }
}
