/* ══ SHOP ALL — page-specific styling ════════════════════════════════════
   The filter rail itself (.cx-layout, .cx-filters, .cx-fgroup, .cx-fopt,
   .cx-apill, .cx-fmob …) already lives in storefront.css and is used as-is.
   Everything here is either the grid override this page has always had, or
   the price slider, which storefront.css has no equivalent for.
   Tokens come from storefront.css :root.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Grid columns ─────────────────────────────────────────────────────────
   The rail is 232px wide and stays INLINE beside the grid down to 900px,
   where storefront.css stacks it. So between 901px and ~1040px, three
   columns share whatever is left of a ~800px page and each card falls to
   about 144px of content — narrower than the 4-column card on a 2560px
   monitor. Two columns through that band instead. */
#shopGrid{grid-template-columns:repeat(4,1fr);}
@media (max-width:1100px){#shopGrid{grid-template-columns:repeat(3,1fr);}}
@media (max-width:1040px) and (min-width:901px){#shopGrid{grid-template-columns:repeat(2,1fr);}}
@media (max-width:700px){#shopGrid{grid-template-columns:repeat(2,1fr);}}

/* Retail price sits beside the member price here, not struck through */
.retail-val{text-decoration:none;}

/* ── "Join to get this price" sized to "Add to bag" ───────────────────────
   The two are declared in ONE rule on purpose: they are a stacked pair of
   controls, and listing them together means a future change to the button's
   padding or radius can't leave the hint behind at a different size.

   THE HEIGHT IS SET BY line-height, NOT font-size. A <button> does not
   inherit the body's line-height (form controls compute `normal`), while the
   <a> does, so leaving it alone made the two boxes 46px and 43px. Pinning
   both to 20px keeps the pair exactly 46px tall even though the label runs
   at a smaller type size than the button.

   WHY THE LABEL IS SMALLER: the grid is 4 columns inside an 860px track, so
   a card is ~193px wide and its content box only 160px. "Join to get this
   price" measures 140px at 15px and wraps to two lines, which breaks the
   match outright. At 13px it measures 121px and sits on one line with room
   to spare — verified down to a 129px card. If the cards ever get wider
   (3 columns, or a wider .cx-layout) this can go back up to 15px and match
   the button's type as well as its box.

   Scoped to #shopGrid. The same .p-memberhint class renders on the homepage
   and category grids through cc_card(), where it reads "Members pay $28 →"
   and is still the small inline pill. Widening that one too is a separate
   call, so it is deliberately untouched here. */
#shopGrid .p-memberhint,
#shopGrid .btn-add{
  width:100%;
  padding:13px;
  line-height:20px;
  font-weight:700;
  border-radius:var(--radius-pill);
}
#shopGrid .btn-add{font-size:15px;}
#shopGrid .p-memberhint{
  display:flex;align-items:center;justify-content:center;gap:5px;
  align-self:stretch;
  margin:0 0 10px;
  font-size:13px;
  letter-spacing:.01em;
  text-align:center;
}

/* ── Quick search (top of the filter rail) ────────────────────────────────
   Instant, client-side, title+brand only — shop.js narrows whatever is
   already rendered as you type. Same icon+input pattern as #brandSearch
   below, but its own class since it isn't scoped to a single fieldset's
   list and sits above everything else in the rail rather than inside one
   group. Pill-radius to match the site's other search input (.cc-search-
   input in storefront.css) rather than the 6px brand-search box, since this
   one reads as a peer of that search, not a sub-filter. */
.shop-qsearch-wrap{position:relative;margin-bottom:20px;}
.shop-qsearch-wrap svg{position:absolute;left:12px;top:50%;transform:translateY(-50%);pointer-events:none;color:var(--soft-rose);}
#shopQuickSearch{
  width:100%;box-sizing:border-box;padding:10px 12px 10px 36px;
  border:1.5px solid var(--light-gray);border-radius:var(--radius-pill);font-size:14px;
  font-family:var(--body-font);background:var(--off-white);color:var(--charcoal);outline:none;
  transition:border-color .15s;
}
#shopQuickSearch:focus{border-color:var(--soft-rose);}
#shopQuickSearch::placeholder{color:#aaa;}
/* No native ✕ clear icon in Firefox/old WebKit, and Chrome's own one isn't
   themeable — the chip in #shopChips already gives a visible, clickable way
   to clear it, so nothing else is added here. */
#shopQuickSearch::-webkit-search-cancel-button{cursor:pointer;}

/* ── Brand search ─────────────────────────────────────────────────────── */
.brand-search-wrap{position:relative;margin-bottom:10px;}
.brand-search-wrap svg{position:absolute;left:10px;top:50%;transform:translateY(-50%);pointer-events:none;color:var(--soft-rose);}
#brandSearch{
  width:100%;box-sizing:border-box;padding:7px 10px 7px 32px;
  border:1px solid var(--light-gray);border-radius:6px;font-size:13px;
  background:var(--off-white);color:var(--charcoal);outline:none;transition:border-color .15s;
}
#brandSearch:focus{border-color:var(--soft-rose);}
#brandSearch::placeholder{color:#aaa;}
.brand-no-results{font-size:12px;color:#999;padding:4px 0;display:none;}
#brandList{max-height:230px;overflow-y:auto;}

/* ── Price range: two overlapping native sliders ──────────────────────────
   Both inputs are transparent and pointer-events:none so the visible track
   below shows through; only the thumbs take pointer events, which is what
   lets the two handles be dragged past each other without one input
   swallowing the other's clicks. */
.pr-wrap{padding:2px 2px 0;}
.pr-slider{position:relative;height:30px;margin-bottom:6px;}
.pr-track{
  position:absolute;top:13px;left:0;right:0;height:4px;
  background:var(--light-gray);border-radius:4px;
}
.pr-fill{position:absolute;top:0;height:4px;background:var(--soft-rose);border-radius:4px;}
.pr-slider input[type=range]{
  position:absolute;top:0;left:0;width:100%;height:30px;margin:0;
  background:none;pointer-events:none;-webkit-appearance:none;appearance:none;
}
.pr-slider input[type=range]:focus{outline:none;}
.pr-slider input[type=range]:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 3px rgba(122,175,216,.45);}
.pr-slider input[type=range]:focus-visible::-moz-range-thumb{box-shadow:0 0 0 3px rgba(122,175,216,.45);}
.pr-slider input[type=range]::-webkit-slider-runnable-track{background:none;border:none;height:30px;}
.pr-slider input[type=range]::-moz-range-track{background:none;border:none;height:30px;}
.pr-slider input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none;appearance:none;pointer-events:auto;
  width:16px;height:16px;margin-top:7px;border-radius:50%;cursor:grab;
  background:#fff;border:2px solid var(--soft-rose);
  box-shadow:0 1px 4px rgba(44,44,44,.25);transition:border-color .15s,transform .1s;
}
.pr-slider input[type=range]::-moz-range-thumb{
  pointer-events:auto;width:16px;height:16px;border-radius:50%;cursor:grab;
  background:#fff;border:2px solid var(--soft-rose);
  box-shadow:0 1px 4px rgba(44,44,44,.25);transition:border-color .15s,transform .1s;
}
.pr-slider input[type=range]::-webkit-slider-thumb:hover{border-color:var(--coral);}
.pr-slider input[type=range]::-moz-range-thumb:hover{border-color:var(--coral);}
.pr-slider input[type=range]:active::-webkit-slider-thumb{cursor:grabbing;transform:scale(1.12);}
.pr-slider input[type=range]:active::-moz-range-thumb{cursor:grabbing;transform:scale(1.12);}

.pr-vals{
  display:flex;justify-content:space-between;align-items:center;
  font-size:13px;font-weight:700;color:var(--charcoal);font-family:var(--heading-font);
}
.pr-vals .sep{color:var(--gray);font-weight:400;}

/* ── Exhausted options ─────────────────────────────────────────────────────
   shop.js recounts every option against the current selection and marks the
   ones that would return an empty grid. Dimming beats hiding: an option that
   disappears makes the rail jump and leaves the shopper unsure whether the
   thing they wanted was ever there. A ticked option is never marked, so a
   filter can always be unticked from the rail it was set in. */
.cx-fopt.is-zero{opacity:.42;cursor:not-allowed;}
.cx-fopt.is-zero .cx-flabel{text-decoration:line-through;text-decoration-thickness:1px;}
.cx-fopt.is-zero .cx-fbox{background:var(--surface-soft);border-color:var(--line);}
.cx-fopt.is-zero:hover .cx-fbox{border-color:var(--line);}

/* ── Data-coverage notes ───────────────────────────────────────────────────
   A filter that is empty because nobody has tagged the products should say
   so, to the merchant, in place — not silently render nothing. */
.cx-note{
  font-size:11.5px;line-height:1.5;color:var(--gray);
  background:#f8fbff;border:1px solid var(--blush-pink);
  border-radius:8px;padding:8px 10px;margin-top:8px;
}
.cx-note b{color:var(--charcoal);font-weight:700;}
.cx-note a{color:var(--coral);font-weight:700;}
.cx-fgroup.is-empty legend{color:var(--light-gray);}

@media(prefers-reduced-motion:reduce){
  .pr-slider input[type=range]::-webkit-slider-thumb{transition:none;}
  .pr-slider input[type=range]::-moz-range-thumb{transition:none;}
}
