/* Hallmark · macrostructure: Editorial Catalogue · page: shop
   Pre-emit: P5 H4 E4 S5 R4 V4 — no axis below 3.
   Justification: a catalogue page should read as a shelf with a control
   rail above it, not as a dashboard of filters. */

/* ==========================================================================
   InihaoStudio — css/pages/shop.css
   Shop-only layout: sticky control rail plus the 1 / 2 / 3 / 4 grid from
   Section 11. Loaded after components.css on shop.html.
   ========================================================================== */

/* ---- Sticky control rail -------------------------------------------- */

/* The rail's parent is a .shell wrapper that only holds the rail, so a
   sticky child would have no travel. display:contents promotes the rail
   to be a child of <main>, which gives it the page as its scroll range.
   Browsers without :has() simply get a rail that scrolls away. */
main > .shell:has(> [data-shop-filters]) {
  display: contents;
}

.filter-bar {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-4);
  width: min(var(--shell), 100% - (var(--gutter) * 2));
  margin: var(--space-6) auto 0;
  padding-block: var(--space-3);
  border-block: 1px solid var(--line);
  background-color: var(--paper);
}

/* The header is sticky too; keep the rail clear of it. --header-h only
   applies while the header is actually pinned, which is always. */
@supports (position: sticky) {
  .filter-bar {
    top: var(--header-h);
  }
}

.filter-bar .pill-row {
  gap: var(--space-2);
}

.filter-bar .search {
  flex: 1 1 14rem;
  min-width: 0;
}

.filter-bar .select {
  min-height: 44px;
}

.filter-count {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-2);
  white-space: nowrap;
}

/* ---- Product grid --------------------------------------------------- */

/* Section 11: 1 col 320-599, 2 at 600-899, 3 at 900-1199, 4 at 1200+. */
[data-shop-grid] {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  align-items: stretch;
  gap: var(--space-7) var(--space-5);
  margin-top: var(--space-7);
}

/* Sort reorders the existing cards in the DOM rather than re-rendering
   them, so the grid needs no animation of its own — the browser moves
   boxes, and .product-card keeps its height:100% from components.css. */

/* ---- Empty state ---------------------------------------------------- */

[data-shop-empty] {
  margin-block: var(--space-8);
}

/* ---- Narrower viewports --------------------------------------------- */

@media (max-width: 1199px) {
  [data-shop-grid] {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 899px) {
  [data-shop-grid] {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-6) var(--space-4);
  }

  .filter-count {
    margin-left: 0;
  }
}

@media (max-width: 599px) {
  [data-shop-grid] {
    grid-template-columns: minmax(0, 1fr);
  }

  /* The rail stops being sticky on phones: five chip rows would eat the
     whole viewport. It scrolls with the page instead. */
  .filter-bar {
    position: static;
    margin-top: var(--space-5);
  }
}

/* ---- Shelf deck ------------------------------------------------------
   The sheets come from components.css. The shop's deck sits below the
   paper hero rather than rising out of it, so it keeps all four corners
   and a normal top margin instead of the homepage's negative pull. */

.stack--shop {
  margin-top: clamp(2rem, 5vw, 3.5rem);
  border-radius: clamp(1.75rem, 4vw, 3.75rem);
}

.stack--shop + .shell {
  margin-top: clamp(2rem, 5vw, 3.5rem);
}

/* The deck's sheet buttons jump here, so the rail has to clear the header
   when it scrolls into view. */
.filter-bar {
  scroll-margin-top: calc(var(--header-h) + 1rem);
}