/* Collection pages: the title block, the product grid with its toolbar, and the pager.
 *
 * Every number here was measured on aeke.com's `/collections/s1-pro` at a 1440 viewport and is
 * recorded in the rule that uses it, so the next reader can check the port against the original
 * rather than against a screenshot.
 *
 * Colour comes from `tokens.css` only — `tests/test_tokens.py` fails the build on a literal.
 */

/* --------------------------------------------------------------------- header */
/* Measured: `.template-header` 95 tall = `padding: 15px 0 30px` plus a 50px line box.
 *
 * The heading is `h1.template-header--title.h2` upstream — an `h1` wearing the `h2` type step,
 * 42px/50px at desktop. It is the page's only `h1`, which is why the template renders it as one
 * and takes its size from the token rather than from the element. */
.collection-header {
  padding: 15px 0 30px;
}

/* Upstream names the inner box `.template-header--content--content-width-standard` and measures
 * it at 1325 inside a 1540px row. That is `.container-page` already, so the modifier is kept as
 * the hook a wide variant would hang off rather than duplicating geometry that is already right. */

.collection-header__title {
  margin: 0;
  font-size: var(--type-h2);
  line-height: var(--type-h2-lh);
  font-weight: var(--font-body-bold-weight);
  color: var(--color-heading);
}

/* ---------------------------------------------------------------- the section */
/* Measured: the grid's wrapper is `.collection-container.section-spacing-bottom`, 70px of space
 * below it at desktop and 50px at narrow widths — the shared rhythm tokens, not a new value. */
.collection-grid-section {
  padding-bottom: var(--section-spacing-mobile);
}

/* -------------------------------------------------------------- toolbar */
/* Measured on both live collections: `.facets--bar-right` 199x43 on the S1 Pro accessories and
 * 184x43 on the K1 accessories, `display: flex; align-items: center`, holding the sort control and
 * the count **25px apart** — and, in both cases, sitting at the *right* edge of the page: the
 * wrapper's right edge is x=1375, which is the container's right edge, while its left edge moves
 * with the width of the sort label (x=1175 for "Most relevant", x=1191 for "Best selling").
 *
 * So the bar is right-aligned, not left. Ours was left-aligned on both collection pages until the
 * second collection was measured and showed the same 1375 right edge at a different left one —
 * which is what a right-aligned row looks like and a left-aligned row does not. */
.collection-grid__bar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 25px;
}

/* Upstream's sort control is a `<custom-select>`: a `<button>` that opens a list of `<button>`s.
 * Ours is a native `<select>`, so it will be wider than 106px — a select is as wide as its widest
 * option, and "Alphabetical, Z-A" is longer than "Most relevant". The trade is deliberate: a
 * native select is operable by keyboard and announced by a screen reader with no script at all,
 * and it still collapses to the same transparent 43px control with an 8x6 arrow. */
.collection-grid__sort {
  position: relative;
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}

/* Measured: 13px text with `padding: 15px 0` and `line-height: 13px` gives exactly 43. */
.collection-grid__select {
  appearance: none;
  -webkit-appearance: none;
  margin: 0;
  padding: 15px 18px 15px 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--color-body);
  font-family: inherit;
  font-size: var(--type-caption);
  line-height: var(--type-caption);
  cursor: pointer;
}

.collection-grid__select-arrow {
  position: absolute;
  right: 0;
  top: 50%;
  width: 8px;
  height: 6px;
  margin-top: -3px;
  color: var(--color-body);
  /* The arrow is decoration over the select's own hit area; without this it would swallow the
     click and the control would only open from the text. */
  pointer-events: none;
}

.collection-grid__select-arrow svg {
  width: 8px;
  height: 6px;
}

/* Measured: 13px on the 1.6 body leading, which is what makes the count 21 tall. */
.collection-grid__count {
  margin: 0;
  font-size: var(--type-caption);
  line-height: 1.6;
  color: var(--color-body);
}

/* Only ever seen when scripting is off, where it is the difference between a working filter and
   a dead one. */
.collection-grid__sort-submit {
  padding: 0 0 0 8px;
  border: 0;
  background: transparent;
  color: var(--color-accent);
  font-family: inherit;
  font-size: var(--type-caption);
  line-height: var(--type-caption);
  cursor: pointer;
  text-decoration: underline;
}

.collection-grid__empty {
  margin: 40px 0 0;
  color: var(--color-body);
}

/* ------------------------------------------------------------------ the grid */
/* Measured: `ul#product-grid` is 1325x1606 with `display: flex; margin: 0 -10px`, and each
 * `li.column` is 336 wide with `padding: 0 10px; flex: 0 0 25%`. The negative margin and the
 * matching padding are how the gutters end up on the outside of the row as well as between the
 * cards. Upstream's classes are `small-up-2.medium-up-4`: two across on a phone, four from 48em. */
.collection-grid__list {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -10px;
  padding: 0;
  list-style: none;
}

.collection-grid__column {
  flex: 0 0 50%;
  max-width: 50%;
  padding: 0 10px;
  list-style: none;
}

/* ------------------------------------------------------------------ the card */
/* `height: 100%` so cards in a row stay the same height when one title wraps to two lines: the
 * flex row stretches the columns, and the card has to fill the column it was given. */
.product-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  margin: 0 0 20px;
  border-radius: var(--block-border-radius);
  background: var(--color-product-card-bg);
  overflow: hidden;
  text-align: center;
}

.product-card__media {
  position: relative;
  margin: 0;
  aspect-ratio: 1 / 1;
}

.product-card__media-link {
  display: block;
  width: 100%;
  height: 100%;
}

.product-card__image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.product-card__image--secondary {
  opacity: 0;
  transition: opacity 240ms ease-out;
}

/* Guarded on `hover: hover` so a touch device never leaves a card showing a picture it cannot
   get back to. `:focus-within` gives the same reveal to a keyboard, which upstream does not. */
@media (hover: hover) and (pointer: fine) {
  .product-card:hover .product-card__image--secondary,
  .product-card:focus-within .product-card__image--secondary {
    opacity: 1;
  }
}

/* Measured: `padding: 20px`, which is also the button's inset. */
.product-card__info {
  display: flex;
  flex-direction: column;
  padding: 20px;
}

/* Measured: 11px on an 11px leading, uppercase, letter-spaced 1.1px. */
.product-card__vendor {
  margin: 0 0 8px;
  font-size: 11px;
  line-height: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-body);
}

/* Measured: 16px/500 on a 20.16px leading, `letter-spacing: normal`, and `rgb(229,231,235)` —
   the *body* colour, not heading white. The leading is under 1.3 because the title is allowed to
   run to two lines and upstream keeps those two lines tight. The tracking is reset explicitly:
   the global heading rule tracks −0.02em for display headings, and the live card title is not
   tracked at all. */
.product-card__title {
  margin: 0 0 5px;
  font-size: 16px;
  line-height: 20.16px;
  font-weight: 500;
  letter-spacing: normal;
  color: var(--color-body);
}

.product-card__title-link {
  color: inherit;
}

.product-card__title-link:hover {
  color: var(--color-accent);
}

/* Measured: 15px/15px, white, `margin: 0`.
 *
 * `.price` and its children are the *buy block's* component: `product-main.css` sizes the amount
 * at 24px/700 for the product page and leaves 11px of right margin for the badges beside it.
 * Inside a card the same markup is a centred 15px line, so the shared numbers are reset here
 * rather than the template growing a second class name for the same thing. */
.product-card .price {
  display: block;
  margin: 0;
  font-size: var(--type-small);
  line-height: var(--type-small);
  color: var(--color-price);
}

.product-card .price ins,
.product-card .price del {
  display: inline;
  font-size: inherit;
}

.product-card .price ins .amount,
.product-card .price del .amount {
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
}

/* Measured: white, `text-decoration: none`, and *not* the sale colour. `product-main.css` paints
 * the buy block's `ins` in `--color-price-discounted` because there the struck-through compare-at
 * is what needs to stand out; in a card the price is simply the price, and upstream renders all
 * twelve of them white with no `del` at all. */
.product-card .price ins {
  color: var(--color-price);
  text-decoration: none;
}

/* `.price` normally sits in a row with its compare-at; here it is a centred line of its own.

   Muted rather than red. Upstream paints the struck-through figure in `--color-price-discounted`,
   which measures **4.12:1** on the card surface — below the 4.5:1 AA needs for text this size, and
   axe says so on every page that shows a card. Grey is also the more honest signal: a struck-through
   price is *previous* information, not a warning, and the sale colour belongs on the live price in
   the buy block where it means "this is what you pay". */
.product-card .price del {
  margin-left: 6px;
  color: var(--color-secondary-menu-text);
}

/* Measured: the button is 276 wide inside the 316 card — the info block's 20px padding — and
   44 tall with `margin: 15px 0`, `padding: 7px 30px`, 13px/500, radius 2px, and *no* tracking or
   case transform: the live label is written in capitals in the markup and the control keeps
   `letter-spacing: normal`.
 *
 * The 44 is a `min-height` rather than a height so the label can wrap on a narrow card without
 * being clipped; it also happens to be the touch-target floor, so the control is 44 tall on a
 * phone as well. */
.product-card__form {
  margin: 0;
}

.product-card__button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 44px;
  margin: 15px 0 0;
  padding: 7px 30px;
  border: 0;
  border-radius: 2px;
  background: var(--color-accent);
  color: var(--color-badge-text);
  font-family: inherit;
  font-size: var(--type-caption);
  line-height: var(--type-caption);
  font-weight: 500;
  letter-spacing: normal;
  cursor: pointer;
  transition: background-color 200ms ease-out;
}

.product-card__button:hover {
  background: var(--color-accent-hover);
}

/* ------------------------------------------------------------------- pager */
/* Measured: 1325x42, `margin: 10px 0 0` — the 10px gap is the whole space between the last row of
 * cards and the pager, on top of the cards' own 20px bottom margin. */
.pagination {
  margin: 10px 0 0;
}

.pagination__list {
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Upstream's page numbers are 13px with `padding: 0 2px` — a 17x13 hit area. These keep the
 * glyph the same size and the same 2px breathing room, and extend the *target* to 24x42 so the
 * control meets the WCAG 2.1 target-size minimum and is comfortable on a phone. The current page
 * is the accent colour, as upstream has it. */
.pagination__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  min-height: 42px;
  padding: 0 2px;
  color: var(--color-body);
  font-size: var(--type-caption);
  line-height: var(--type-caption);
}

.pagination__link:hover {
  color: var(--color-accent);
}

.pagination__link--current {
  color: var(--color-accent);
}

.pagination__link--disabled {
  color: var(--color-secondary-menu-text);
  opacity: 0.5;
}

.pagination__link svg {
  width: 7px;
  height: 12px;
}

.pagination__item--gap {
  padding: 0 2px;
  color: var(--color-secondary-menu-text);
  font-size: var(--type-caption);
  line-height: var(--type-caption);
}

/* ---------------------------------------------------------------- breakpoints */
@media (min-width: 48em) {
  /* `medium-up-4`. */
  .collection-grid__column {
    flex: 0 0 25%;
    max-width: 25%;
  }
}

@media (min-width: 1068px) {
  .collection-grid-section {
    padding-bottom: var(--section-spacing-desktop);
  }
}
