/* Shop page only: filter rail + product grid. Extracted from static shop.html. */
/* ============================================================
   SHOP PAGE ONLY — filter rail + full grid
   Shared header/buttons/footer/etc live in assets/site.css
   ============================================================ */
.shop{padding:clamp(2.5rem,6vw,4.5rem) 0 clamp(3rem,7vw,5rem)}
.shop-head{display:flex;align-items:flex-end;justify-content:space-between;gap:1.5rem;
  flex-wrap:wrap;margin-bottom:1.6rem}
.shop-head h1{font-family:var(--display);font-weight:800;line-height:.95;letter-spacing:-.03em;
  font-size:clamp(2rem,1.2rem + 3vw,3.6rem);text-transform:uppercase}
.shop-head .count{color:var(--slate);font-size:.85rem}
.shop-head .count b{color:var(--gold)}

/* --headH is measured from the real header on load/resize — it changes height
   on mobile when the search bar wraps to its own row */
.filters{position:sticky;top:var(--headH,74px);z-index:var(--z-sticky);background:rgba(5,15,20,.94);
  backdrop-filter:blur(14px);padding:.85rem 0;margin-bottom:1.6rem;
  box-shadow:inset 0 1px 0 rgba(228,237,240,.06);
  border-block:var(--line);display:flex;gap:.9rem;align-items:center;flex-wrap:wrap}
.chips{display:flex;gap:.5rem;overflow-x:auto;flex:1;scrollbar-width:thin;padding-bottom:2px}
.chip{flex:none;min-height:24px;background:rgba(140,188,199,.08);border:var(--line);color:var(--ice);
  border-radius:999px;padding:.5rem 1rem;font-size:.75rem;font-weight:600;white-space:nowrap;
  transition:background .3s,color .3s,border-color .3s,transform .12s var(--press)}
.chip:hover{border-color:var(--gold)}
.chip:active{transform:scale(.94);transition-duration:.08s}
.chip[aria-pressed="true"]{background:var(--chip,var(--gold));color:var(--ink-deep);border-color:transparent}
.chip .qty{opacity:.6;margin-left:.35rem;font-weight:500}
/* appearance:none + a hand-drawn chevron replaces the native browser arrow,
   so the select reads as part of this token system instead of default
   platform chrome dropped into a pill shape. */
.sortsel{flex:none;appearance:none;-webkit-appearance:none;
  background:rgba(140,188,199,.08) url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6 9l6 6 6-6" fill="none" stroke="%239DB4BD" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>') no-repeat right .7rem center/16px;
  border:var(--line);color:var(--ice);border-radius:999px;padding:.5rem 2.1rem .5rem .9rem;
  font-size:.75rem;font-weight:600;cursor:pointer;transition:border-color .3s}
.sortsel:hover,.sortsel:focus-visible{border-color:var(--gold)}
.sortsel option{background:var(--ink);color:var(--ice)}
/* The group select carries the longest labels in the bar ("Office Accessories
   (5)"), so it gets a ceiling the sort select doesn't need — everything else
   about it is .sortsel. It is removed entirely for a category with no groups
   ("More"), hence the explicit [hidden] rule rather than trusting the UA. */
.groupsel{max-width:min(14rem,100%)}
.filters [hidden]{display:none}

.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(215px,1fr));gap:clamp(.7rem,1.6vw,1.15rem)}
/* 2-up on phones rather than 1-up: dozens of items is a long scroll in a single column */
@media(max-width:560px){
  /* The bar now carries chips plus two selects. Chips keep a full row of
     their own and the selects split the next one, so at 375px everything
     wraps inside the bar and the page never scrolls sideways. */
  .filters{gap:.6rem}
  .chips{flex:1 0 100%}
  .sortsel{flex:1 1 0;min-width:0}
  .groupsel{max-width:none}
  .grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:.55rem}
  .pname{font-size:.86rem}
  .pprice .amt{font-size:1.02rem}
  .pmeta{padding:.6rem .6rem .75rem}
  .quickadd{padding:.55rem;font-size:.62rem;letter-spacing:.08em}
}

/* Hover-lift uses --ease (settle, no overshoot) — this is a passive hover
   state, not a gesture the user drove, so it doesn't earn the spring. */
.pcard{position:relative;background:var(--ink-card);border:var(--line);border-radius:5px;
  overflow:hidden;display:flex;flex-direction:column;
  transition:transform .45s var(--ease),border-color .45s,box-shadow .45s}
.pcard:hover{transform:translateY(-6px);border-color:color-mix(in srgb,var(--tint,var(--gold)) 65%,transparent);
  box-shadow:0 26px 46px -24px rgba(0,0,0,.85),0 0 0 1px color-mix(in srgb,var(--tint,var(--gold)) 22%,transparent)}
.pcard:active{transform:translateY(-6px) scale(.98);transition-duration:.1s}
.pcard .shot{position:relative;aspect-ratio:1;overflow:hidden;
  background:repeating-linear-gradient(96deg,rgba(11,31,39,.05) 0 2px,transparent 2px 9px),
             linear-gradient(155deg,var(--wood-1),var(--wood-2) 65%,var(--wood-3))}
.pcard .shot>svg,.pcard .shot>img{position:absolute;inset:15%;width:70%;height:70%;color:var(--wood-ink);
  transition:transform .6s var(--ease)}
.pcard .shot>img{object-fit:contain;inset:8%;width:84%;height:84%}
.pcard:hover .shot>svg,.pcard:hover .shot>img{transform:scale(1.09) rotate(-2deg)}
.pcard .shot::after{content:"";position:absolute;inset:0;opacity:0;transition:opacity .5s;
  background:linear-gradient(118deg,transparent 32%,rgba(255,248,228,.55) 50%,transparent 68%)}
.pcard:hover .shot::after{opacity:1}

.tags{position:absolute;top:.55rem;left:.55rem;z-index:2;display:flex;flex-direction:column;gap:.3rem;align-items:flex-start}
.tag{font-size:.58rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  padding:.28rem .5rem;border-radius:3px;background:var(--ink-deep);color:var(--gold-lite)}
.tag.hot{background:var(--hot);color:var(--ink-deep)}
/* Wishlist heart — opposite corner from the tags, always visible (not
   hover-gated) since it's a primary action, not a hover-only nicety. */
.pwish{position:absolute;top:.5rem;right:.5rem;z-index:2;width:30px;height:30px;
  border-radius:999px;background:rgba(5,15,20,.55);backdrop-filter:blur(3px);
  color:var(--ice);display:grid;place-items:center;
  transition:background .25s var(--ease),color .25s var(--ease),transform .12s var(--press)}
.pwish svg{width:15px;height:15px}
.pwish:hover{background:rgba(200,155,74,.35)}
.pwish:active{transform:scale(.88)}
.pwish[aria-pressed="true"]{color:var(--gold-lite)}
.tag.new{background:var(--e-emerald);color:var(--on-accent-light)}
.tag.eng{background:var(--e-violet);color:var(--on-accent-light)}

/* Rises on hover/focus-within — same passive-state reasoning as .pcard
   above, so this uses --ease too, not the momentum spring. */
.quickadd{position:absolute;left:.55rem;right:.55rem;bottom:.55rem;z-index:2;min-height:24px;
  background:var(--gold);color:var(--ink-deep);border:none;border-radius:4px;padding:.7rem;
  font-size:.7rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  transform:translateY(130%);opacity:0;transition:transform .3s var(--ease),opacity .3s,background .25s}
.pcard:hover .quickadd,.pcard:focus-within .quickadd{transform:none;opacity:1}
.quickadd:hover{background:var(--gold-lite)}
/* Hover-reveal is dead weight on touch — there's no sustained hover state
   to reveal it with, so it's permanently invisible-but-present there.
   Devices with no real hover always show it. */
@media(hover:none){
  .quickadd{transform:none;opacity:1}
}
/* higher specificity than the ".pcard:hover .quickadd{transform:none}" rule above,
   so a press mid-hover still visibly depresses instead of being overridden to none */
.pcard:hover .quickadd:active,.pcard:focus-within .quickadd:active{transform:scale(.95);transition-duration:.08s}
.quickadd.done{background:var(--e-emerald);color:var(--on-accent-light)}

.pmeta{padding:.8rem .85rem 1rem;display:flex;flex-direction:column;gap:.3rem;flex:1}
.pcat{font-size:.6rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--tint-text,var(--gold-lite))}
.pname{font-family:var(--display);font-weight:700;font-size:.98rem;line-height:1.15;letter-spacing:-.02em}
.qv-trigger{display:block;width:100%;text-align:left;background:none;border:none;padding:0;
  font:inherit;color:inherit;border-bottom:1px solid transparent;
  transition:color .25s var(--ease),border-color .25s var(--ease)}
.qv-trigger:hover{color:var(--gold-lite);border-color:var(--gold-lite)}
.pprice{margin-top:auto;padding-top:.55rem;display:flex;align-items:baseline;gap:.5rem}
.pprice .amt{font-family:var(--display);font-weight:800;font-size:1.18rem;color:var(--paper);
  letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.pprice .was{font-size:.78rem;color:var(--slate);text-decoration:line-through;font-variant-numeric:tabular-nums}

/* ============ PRODUCT GROUP HEADINGS ============
   Square sells this catalog in item-GROUPS ("Handbag", "Serving Trays") and
   gives each one its own page. A group is not a child of a category — 8 of
   the 19 span two categories — so its heading spans the whole grid row
   (grid-column:1/-1) rather than nesting under the category chips. */
.ghead{grid-column:1/-1;display:flex;align-items:baseline;flex-wrap:wrap;gap:.35rem .8rem;
  margin:1.5rem 0 .15rem;padding-bottom:.5rem;border-bottom:var(--line)}
.grid>.ghead:first-child{margin-top:.2rem}
.ghead h2{font-size:clamp(1rem,.9rem + .5vw,1.4rem);text-transform:uppercase;color:var(--ice)}
.ghead .gcount{font-family:var(--ui);font-size:.62rem;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;color:var(--slate);font-variant-numeric:tabular-nums;margin:0}
.ghead h2 .gcount{margin-left:.55rem}
/* The heading of a real group is a real button — it filters to that group,
   same as a chip does. Styled off .qv-trigger so the two read as one idiom. */
.ghead-btn{display:inline-flex;align-items:baseline;min-height:24px;background:none;border:none;
  padding:0;font:inherit;color:inherit;text-align:left;border-bottom:1px solid transparent;
  transition:color .25s var(--ease),border-color .25s var(--ease)}
.ghead-btn:hover{color:var(--gold-lite);border-color:var(--gold-lite)}
.ghead-btn:active{opacity:.72;transition-duration:.08s}
/* Ungrouped pieces get a heading too, but a quiet, inert one — there is no
   group to filter to, so it must not look clickable. */
.ghead-plain h2{color:var(--slate)}
/* The single-group view: title, "N results", and the way back out. */
.ghead-on{padding-bottom:.7rem}
.ghead-on h2{color:var(--gold-lite)}
.ghead-clear{margin-left:auto;display:inline-flex;align-items:center;min-height:24px;
  border:var(--line);border-radius:999px;padding:.42rem .95rem;color:var(--gold);white-space:nowrap;
  font-size:.64rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  transition:border-color .25s var(--ease),color .25s var(--ease)}
.ghead-clear:hover{border-color:var(--gold);color:var(--gold-lite)}
@media(max-width:560px){
  .ghead{margin:1.1rem 0 .1rem;gap:.3rem .6rem}
}

.empty{grid-column:1/-1;text-align:center;padding:4rem 1rem;color:var(--slate)}
.empty b{display:block;font-family:var(--display);font-size:1.4rem;color:var(--ice);margin-bottom:.5rem}
.empty #clearFilters{display:inline-block;margin-top:1.1rem;background:none;border:var(--line);
  color:var(--gold);padding:.6rem 1.2rem;border-radius:999px;font-size:.72rem;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;transition:border-color .25s var(--ease),color .25s var(--ease)}
.empty #clearFilters:hover{border-color:var(--gold);color:var(--gold-lite)}
#wishNote a{color:var(--gold);border-bottom:1px solid transparent;transition:border-color .25s var(--ease)}
#wishNote a:hover{border-color:var(--gold)}
