/* ══ 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;
}

/* ── 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;}
}
