/* MGP shop — ported verbatim from the approved prototype shop.html.
   Loaded only on /shop (after brand.css + content.css). v1 */
.wrap{max-width:1100px;margin:0 auto;padding:0 22px 220px;position:relative;z-index:1}
/* 2026 merch artwork as a dimmed page backdrop (black-on-black, fades out down the page) */
.shopbg{position:fixed;inset:0;z-index:0;pointer-events:none;
  background:url("/assets/images/shop-2026-bg.jpg") center top/cover no-repeat;
  opacity:.11;filter:brightness(.55) saturate(.85);
  -webkit-mask-image:linear-gradient(180deg,#000 0%,#000 34%,transparent 78%);
  mask-image:linear-gradient(180deg,#000 0%,#000 34%,transparent 78%)}
.pg-shop section{padding:46px 0;border-top:1px solid var(--line)}
.pg-shop section:first-of-type{border-top:0}


.modnote{font-family:var(--body);font-size:14px;opacity:.7;margin-top:6px}

/* image-first product grid — square cubes, 3 across desktop / 1 mobile, click for full detail */
.pgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
/* v1.13.1 — the card has PADDING so the white photo plate sits inside it as its own rounded
   tile. Before this the plate ran edge to edge and only its top corners were rounded, by the
   card clipping them; the bottom two met .pinfo dead square. Rounding "the card" was never the
   same thing as rounding the image. */
.pcube{background:rgba(0,28,16,.5);border:1px solid var(--line);border-radius:16px;overflow:hidden;padding:7px;cursor:pointer;display:flex;flex-direction:column;transition:transform .2s ease,border-color .2s ease,box-shadow .2s ease}
.pcube:hover{transform:translateY(-3px);border-color:var(--leaf);box-shadow:0 12px 24px -12px rgba(0,0,0,.6)}
/* 3/2, not 1/1 (v1.12.16). Measured across all 49 product photos: 45 are landscape, median
   ratio 1.82. In a square plate a typical 2.15-ratio shot rendered 300x140 inside 341x341 —
   ~200px of empty white and a card a third taller than it needed to be. */
/* overflow:hidden is the point — without it the <img> paints straight over the rounded corners,
   which is why a radius here did nothing once a photo was cropped to fill the plate. */
.pcube .pimg{width:100%;aspect-ratio:3/2;background:#fff;position:relative;border-radius:11px;overflow:hidden}
/* ══ v1.13.4 — ROUND THE PICTURE ITSELF, not the plate it sits on ══════════════════════════════
   THE THING THAT KEPT BEING MISSED: with object-fit:contain the <img> ELEMENT is the whole plate
   and the picture is letterboxed inside it. So a border-radius on the plate — or even on the img —
   lands on empty padding, and the PICTURE keeps its own square corners in the middle. Rounding the
   card, the plate, or the img box are three different things and only this one is the picture.
   Sizing the image to its own aspect (auto width/height inside max-*, centred via inset:0 +
   margin:auto) makes the element box EQUAL the picture — so the radius finally clips the picture.
   Applies on every surface a product photo appears: shop cube, modal, product page. */
.pcube .pimg img,.pmodal-img img,.gstack img{
  position:absolute;inset:0;margin:auto;
  width:auto;height:auto;max-width:88%;max-height:88%;   /* 88% = the old 6% padding each side */
  padding:0;border-radius:10px}
/* A CROPPED photo fills its plate instead, so the plate's own radius + overflow does the clipping.
   contain (not cover) is the base so zoom 1 = the WHOLE picture and zooming only ever goes IN —
   starting already-cropped felt janky and hid half the product. */
.pcube .pimg img.cropped,.pmodal-img img.cropped,.gstack img.cropped{
  width:100%;height:100%;max-width:none;max-height:none;
  padding:0;object-fit:contain;border-radius:11px}
.pcube .pimg .ic{display:none}
.pcube .pimg.noimg{display:flex;align-items:center;justify-content:center;background:var(--forest-2)}
.pcube .pimg.noimg img{display:none}
.pcube .pimg.noimg .ic{font-size:52px;color:var(--leaf);opacity:.5;display:flex}
.pcube .pimg.noimg .ic i{display:block}
.pcube .pimg.noimg .ic svg{width:52px;height:52px}
/* name bar = animated green/black gradient (same drift as the header bar);
   price = floating chip lifted off the plate, overlapping the photo edge */
/* sits under the photo tile as its own rounded bar, not flush against it — so the plate reads
   as a rounded IMAGE rather than the top half of a rounded box */
.pcube .pinfo{position:relative;margin-top:7px;border-radius:11px;padding:14px 12px 13px;min-height:58px;display:flex;align-items:center;
  background:linear-gradient(120deg,#000 0%,#11281B 48%,#289851 100%);background-size:220% 220%;animation:headerDrift 20s ease infinite}
.pcube .pname{font-family:var(--disp);font-weight:700;text-transform:uppercase;font-size:18px;color:var(--cream);line-height:1.1;padding-right:86px}
.pcube .pprice{position:absolute;right:12px;top:-17px;z-index:2;font-family:var(--data);font-weight:700;letter-spacing:.5px;font-size:17px;color:var(--orange);
  background:#000;padding:8px 15px;border-radius:12px;box-shadow:0 10px 22px rgba(0,0,0,.6)}
.pcube .pprice .was{color:#8a8a8a;text-decoration:line-through;font-size:12px;margin-right:6px}
.pcube .pprice.avail{color:var(--leaf);font-size:13px;text-transform:uppercase;letter-spacing:1px}
.pcube .pprice.soldout{color:#999}
.pcube .pimg{position:relative}
.salebadge{position:absolute;left:10px;top:10px;z-index:3;background:var(--orange);color:#04140a;font-family:var(--data);font-weight:700;font-size:11px;letter-spacing:.5px;padding:4px 8px;border-radius:6px;box-shadow:0 2px 6px rgba(0,0,0,.28);text-transform:uppercase}
.salebadge.inl{position:static;display:inline-block;margin-left:12px;vertical-align:middle;box-shadow:none}
.pcube.soldout .pimg{filter:grayscale(.4);opacity:.75}

/* category cube grid — the homepage quick-button treatment, slightly smaller */
.catgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:11px;margin-top:18px}
@media(max-width:520px){.catgrid{grid-template-columns:1fr 1fr}}
.catgrid[hidden],.catdetail[hidden]{display:none}
.catcube{position:relative;min-height:86px;border-radius:14px;cursor:pointer;overflow:hidden;
  background-color:#11281B;background-repeat:no-repeat;color:var(--cream);
  padding:14px 52px 14px 15px;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;
  animation:sglow 3.6s ease-in-out infinite;transition:transform .28s cubic-bezier(.2,.7,.3,1.2),opacity .3s ease}
.catcube:hover{transform:translateY(-5px)}
.catcube .artl{position:absolute;inset:0;background-repeat:no-repeat;opacity:0;pointer-events:none;
  filter:blur(2.5px) brightness(.75);transform:scale(1.04); /* soften the art so the text layer owns the focus */
  transition:opacity .9s ease,filter .35s ease}
.catcube .artl.on{opacity:.9}
.catcube:hover .artl{filter:blur(0) brightness(.95)} /* the tile you're on comes into focus */
.catcube::after{content:"";position:absolute;inset:0;background:radial-gradient(75% 60% at 82% 92%,rgba(0,0,0,.16),transparent 70%);pointer-events:none}
/* title strip: runs from the tile's left edge, past the text, then melts into the artwork */
.catcube .lbl{position:relative;z-index:1;font-family:var(--disp);font-weight:700;text-transform:uppercase;font-size:16px;line-height:1.1;letter-spacing:.3px;text-align:left;color:var(--cream);
  margin-left:-15px;padding:6px 26px 6px 15px;border-radius:0 11px 11px 0;
  background:linear-gradient(90deg,rgba(17,40,27,.92) 0%,rgba(17,40,27,.92) 70%,rgba(17,40,27,0) 100%)}
.catcube .cic{position:absolute;right:0;bottom:0;width:52px;height:48px;background:#000;border-radius:100% 0 0 0;
  display:flex;align-items:flex-end;justify-content:flex-end;padding:0 10px 7px 0;font-size:24px;line-height:1;color:var(--cream);opacity:.97;
  animation:sglow 3.6s ease-in-out infinite}
.catcube .cic i,.catcube .cic svg{animation:cbob 2.8s ease-in-out infinite}
.catcube .cic i{display:block}
.catcube .cic svg{display:block;width:26px;height:26px;fill:none;stroke:var(--cream);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.catcube.bye{transform:scale(.6);opacity:0;pointer-events:none}
.catcube.go{transform:scale(1.08);opacity:0;pointer-events:none}
@keyframes sglow{0%,100%{box-shadow:0 0 0 1px rgba(243,146,0,.55),0 0 18px rgba(243,146,0,.28)}50%{box-shadow:0 0 0 1px rgba(40,152,81,.6),0 0 20px rgba(40,152,81,.34)}}
@keyframes cbob{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
@media(prefers-reduced-motion:reduce){.catcube{animation:none}.catcube .cic{animation:none}}

/* category detail (grid animates away, contents shown full width) */
.catdetail{opacity:0;transform:translateY(16px);transition:opacity .35s ease,transform .35s ease}
.catdetail.in{opacity:1;transform:none}
.cathead{display:flex;align-items:center;gap:14px;margin:18px 0 16px}
.catback{appearance:none;-webkit-appearance:none;background:rgba(243,146,55,.14);border:1px solid rgba(243,146,55,.45);outline:none;box-shadow:none;cursor:pointer;
  width:40px;height:40px;flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  line-height:1;color:var(--orange);border-radius:50%;padding:0;transition:background .2s ease,border-color .2s ease}
.catback svg{flex:none}
.catback:hover{background:var(--orange);border-color:var(--orange);color:#04140a}

/* Product page: the same round .catback button as the category header, beside the crumb. */
.crumbrow{display:flex;align-items:center;gap:13px;margin:2px 0 18px}
.pg-product .crumbrow .crumb,.crumbrow .crumb{margin:0}
.crumbrow .catback{text-decoration:none}
/* Cart button beside it — same disc, with the item count sat on the corner. */
.catcart{position:relative}
.catcart .cnum{position:absolute;top:-2px;right:-2px;min-width:19px;height:19px;padding:0 5px;box-sizing:border-box;
  border-radius:999px;background:var(--orange);color:#04140a;font-family:var(--data);font-weight:700;font-size:11px;
  display:flex;align-items:center;justify-content:center;line-height:1}
.catcart:hover .cnum{background:#04140a;color:var(--orange)}
.cattitle{font-family:var(--disp);font-weight:700;text-transform:uppercase;font-size:clamp(22px,3.6vw,30px);color:var(--cream);line-height:1}

/* modal gallery crossfade */
.gstack{position:absolute;inset:0}
.gstack img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;padding:6%;box-sizing:border-box;opacity:1;transition:opacity .35s ease}
.gstack img.fadeout{opacity:0}

/* product detail modal (opened from a cube) */
.pmodal{position:fixed;inset:0;background:rgba(4,8,5,.9);z-index:500;display:flex;align-items:center;justify-content:center;padding:24px;opacity:0;pointer-events:none;transition:opacity .25s ease}
.pmodal.open{opacity:1;pointer-events:auto}
/* The quick-view is a panel over the page, not a full-screen takeover, so the floating
   dock (cart / search / account) must stay usable while it is open — reaching the cart
   from a product was otherwise impossible without closing the modal first.
   brand.css hides .mgp-minipill whenever body.mgp-overlay-open is set, which the modal
   also sets; that is right for the main menu but wrong here, so it is overridden ONLY
   under body.shop-modal-open. The transform reset undoes the slide-away of the hide
   animation, and the z-index lifts it clear of the modal's own 500. */
body.shop-modal-open.mgp-overlay-open .mgp-minipill,
body.shop-modal-open.mgp-overlay-open .mgp-socdock{
  opacity:1;visibility:visible;pointer-events:auto;transform:translateX(-50%);z-index:520}
/* vertical card: image on top, all detail beneath (works for mobile + desktop) */
.pmodal-card{background:var(--card);border:1px solid var(--line);border-radius:16px;max-width:460px;width:100%;max-height:92vh;overflow-y:auto;display:flex;flex-direction:column;position:relative}
/* radius on ALL FOUR corners (v1.13.4) - it was top-only, so the plate met .pmodal-body dead square */
.pmodal-img{background:#fff;height:min(340px,40vh);position:relative;cursor:zoom-in;border-radius:16px;overflow:hidden;flex:0 0 auto}
/* magnifier hint — tells the user the image zooms */
.zoomhint{position:absolute;right:12px;bottom:12px;width:34px;height:34px;border-radius:50%;background:rgba(4,8,5,.55);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
  display:flex;align-items:center;justify-content:center;z-index:3;transition:opacity .2s ease;
  /* 🔴 was pointer-events:none — a click could never TARGET the badge, yet
     shop-product.js tests e.target.closest('.zoomhint'). Looked live, did nothing. */
  pointer-events:auto;cursor:zoom-in}
.zoomhint svg{width:19px;height:19px;stroke:#fff}
.pmodal-img:hover .zoomhint{opacity:.85}
/* persistent "in your cart" badge on the image (uses the cart icon) */
.incart{position:absolute;left:12px;bottom:12px;z-index:4;display:inline-flex;align-items:center;gap:5px;
  pointer-events:auto;cursor:pointer;text-decoration:none;
  background:var(--orange);color:#04140a;border-radius:20px;padding:5px 11px 5px 9px;box-shadow:0 6px 16px rgba(0,0,0,.4)}
.incart[hidden]{display:none}
.incart svg{width:17px;height:17px;stroke:#04140a}
.incart b{font-family:var(--data);font-weight:700;font-size:14px}
/* full-image ADDED TO CART tick overlay */
.addedov{position:absolute;inset:0;z-index:5;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
  background:rgba(40,152,81,.94);color:#fff;opacity:0;pointer-events:none;transform:scale(.96);transition:opacity .28s ease,transform .28s ease}
.addedov.show{opacity:1;transform:scale(1)}
.addedov .tick{width:72px;height:72px;border-radius:50%;background:rgba(255,255,255,.16);display:flex;align-items:center;justify-content:center}
.addedov .tick svg{width:44px;height:44px;stroke:#fff}
.addedov .atxt{font-family:var(--disp);font-weight:700;text-transform:uppercase;letter-spacing:2px;font-size:22px}
/* news-style dots when a product has multiple colour photos */
.pdots{position:absolute;left:0;right:0;bottom:10px;display:flex;justify-content:center;gap:9px;z-index:2}
.pdot{width:9px;height:9px;border-radius:50%;border:0;background:rgba(0,0,0,.22);cursor:pointer;transition:background .2s ease,transform .2s ease}
.pdot.on{background:var(--leaf);transform:scale(1.25)}
.pmodal-img img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;padding:6%;box-sizing:border-box}
.pmodal-img.noimg{display:flex;align-items:center;justify-content:center;background:var(--forest-2)}
.pmodal-img.noimg .ic{font-size:80px;color:var(--leaf);opacity:.5}
.pmodal-img.noimg .ic svg{width:80px;height:80px}
.pmodal-body{padding:20px 24px 22px;flex:0 0 auto}
.pmodal-eyebrow{font-family:var(--data);letter-spacing:1.5px;text-transform:uppercase;font-size:11px;color:var(--leaf)}
.pmodal-body h3{font-family:var(--disp);font-weight:700;text-transform:uppercase;font-size:clamp(22px,3vw,30px);color:var(--cream);line-height:1;margin:5px 0 4px}
.pmodal-colour{font-family:var(--body);font-style:italic;font-size:13.5px;opacity:.75;margin-bottom:12px}
.pmodal-body ul{margin:12px 0;padding-left:18px}
.pmodal-body li{font-family:var(--body);font-size:14.5px;opacity:.95;line-height:1.55;margin-bottom:5px}
.pmodal-spec{margin:14px 0;font-family:var(--data);font-size:12px;letter-spacing:.5px;text-transform:uppercase;opacity:.8;line-height:1.7}
.pmodal-spec b{color:var(--leaf);opacity:1;margin-right:6px}
.pmodal-foot{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-top:18px;padding-top:16px;border-top:1px dashed rgba(40,152,81,.4)}
.pmodal-code{font-family:var(--data);font-weight:700;letter-spacing:1px;font-size:12px;color:var(--forest);background:var(--leaf);padding:5px 12px;border-radius:14px}
.pmodal-status{font-family:var(--data);font-weight:700;letter-spacing:1px;text-transform:uppercase;font-size:13px;color:var(--orange)}
.pmodal-status.avail{color:var(--cream);opacity:.7}
.pmodal-close{position:absolute;top:12px;right:12px;width:38px;height:38px;border-radius:50%;background:rgba(0,0,0,.5);border:1px solid rgba(255,255,255,.25);color:#fff;font-size:20px;cursor:pointer;display:flex;align-items:center;justify-content:center;z-index:2}

/* image lightbox (full-size zoom from the modal) */
.mgp-lightbox{position:fixed;inset:0;background:rgba(0,0,0,.95);z-index:600;display:flex;align-items:center;justify-content:center;padding:30px;opacity:0;pointer-events:none;transition:opacity .25s ease}
.mgp-lightbox.open{opacity:1;pointer-events:auto}
/* radius 16, not 8 (v1.12.16) — 8px on an image that opens ~1040px wide is 0.8% and read as square */
.mgp-lightbox img{max-width:100%;max-height:100%;object-fit:contain;background:#fff;border-radius:16px;box-shadow:0 20px 60px rgba(0,0,0,.6)}
.mgp-lightbox-close{position:absolute;top:20px;right:24px;width:44px;height:44px;border-radius:50%;background:rgba(255,255,255,.12);border:1px solid rgba(255,255,255,.3);color:#fff;font-size:22px;cursor:pointer;display:flex;align-items:center;justify-content:center}
.ntype{font-family:var(--data);letter-spacing:1px;text-transform:uppercase;font-size:11px;color:var(--leaf);opacity:.85}
.nnote{font-family:var(--body);font-style:italic;font-size:12.5px;opacity:.7}
.nlist-foot{font-family:var(--body);font-size:13px;opacity:.7;margin-top:12px;padding-top:12px;border-top:1px solid var(--line)}

.credit{text-align:center;margin-top:40px;font-family:var(--data);letter-spacing:1px;text-transform:uppercase;font-size:11px;color:var(--cream);opacity:.4}

/* filter dropdown (same custom control as the Photos page) */
/* title + subtitle on the left, the category-group filter pinned far right, vertically centred */
.shop-head{display:flex;align-items:center;gap:16px 20px;flex-wrap:wrap}
.shop-head-txt{min-width:0}
.shop-head .sel{margin:0 0 0 auto;flex:0 0 auto}
.sel{position:relative;margin:18px 0 4px;max-width:100%}
.shopfilter{display:flex;justify-content:flex-start}
.selbtn{appearance:none;-webkit-appearance:none;background:rgba(255,255,255,.1);border:0;outline:none;box-shadow:none;cursor:pointer;
  display:flex;align-items:center;gap:10px;font-family:var(--data);font-weight:700;text-transform:uppercase;letter-spacing:1px;font-size:14px;color:var(--cream);
  padding:9px 20px;border-radius:17px;transition:background .25s ease}
.selbtn:hover{background:rgba(40,152,81,.3)}
.selbtn svg{flex:0 0 auto;transition:transform .3s cubic-bezier(.2,.7,.3,1.2)}
.sel.open .selbtn svg{transform:rotate(180deg)}
.sellist{position:absolute;top:calc(100% + 8px);left:0;z-index:60;width:max-content;min-width:180px;max-width:88vw;
  background:rgba(0,0,0,.94);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border-radius:15px;padding:7px;box-shadow:0 14px 40px rgba(0,0,0,.7);
  opacity:0;pointer-events:none;transform:translateY(-8px);transition:opacity .25s ease,transform .25s cubic-bezier(.2,.7,.3,1)}
.sel.open .sellist{opacity:1;pointer-events:auto;transform:translateY(0)}
/* the shop filter is pinned to the RIGHT edge (margin-left:auto) — anchor its list to the button's
   RIGHT so it opens inward. left:0 made the (closed-but-rendered, opacity:0) max-content list hang
   off-screen right = permanent horizontal scroll on mobile (page could be finger-shifted left). */
.shop-head .sellist{left:auto;right:0}
.selopt{display:block;white-space:nowrap;cursor:pointer;font-family:var(--data);font-weight:700;text-transform:uppercase;letter-spacing:1px;font-size:14px;color:var(--cream);
  padding:11px 26px;border-radius:10px;transition:background .2s ease,color .2s ease}
.selopt:hover{background:rgba(40,152,81,.3)}
.selopt.on{color:var(--leaf)}

/* colour / design variant picker + size chips inside the modal */
.vbtns{display:flex;flex-wrap:wrap;gap:8px;margin:10px 0 4px}
.vbtn{font-family:var(--data);font-weight:700;letter-spacing:.5px;text-transform:uppercase;font-size:12.5px;color:var(--cream);
  background:rgba(255,255,255,.08);padding:7px 13px;border-radius:14px;cursor:pointer;transition:background .2s ease,color .2s ease}
.vbtn:hover{background:rgba(40,152,81,.3)}
.vbtn.on{background:var(--leaf);color:#04140a}
.sizes{display:flex;flex-wrap:wrap;gap:7px;margin:10px 0 2px}
.schip{font-family:var(--data);font-weight:700;letter-spacing:.5px;font-size:12.5px;color:var(--cream);opacity:.9;
  background:rgba(255,255,255,.08);padding:6px 11px;border-radius:12px}
/* schip becomes a selectable control when the shop is live */
.schip.pick{cursor:pointer;transition:background .2s ease,color .2s ease,opacity .2s ease}
.schip.pick:hover{background:rgba(40,152,81,.3);opacity:1}
.schip.pick.on{background:var(--leaf);color:#04140a;opacity:1}
.pmodal-price{font-family:var(--data);font-weight:700;letter-spacing:.5px;font-size:24px;color:var(--orange);margin-top:8px}
.pmodal-price .was{color:#8a8a8a;text-decoration:line-through;font-size:16px;margin-right:9px}
.pmodal-lbl{font-family:var(--data);letter-spacing:1.5px;text-transform:uppercase;font-size:11px;color:var(--leaf);margin-top:10px}

/* centred Material / Sizing header + spec */
.pmodal-material{text-align:center;margin:11px 0 4px}
.pmodal-material .mlabel{font-family:var(--data);letter-spacing:1.5px;text-transform:uppercase;font-size:11px;color:var(--leaf)}
.pmodal-material .mtext{font-family:var(--body);font-size:13.5px;opacity:.9;margin-top:3px;line-height:1.5}

/* size selection = custom dropdown (matches the photos-page dropdown) */
/* Sized to its own text, not a fixed 220px box — "Choose a size" is short and once a size is
   picked it is 1–2 characters, so the old width was mostly empty space (25 Jul 2026). The
   min-width stops it snapping narrow when the label changes, and keeps the option list readable. */
.ssel{position:relative;display:inline-block;width:auto;margin:8px 0 4px;min-width:158px;max-width:220px}
.sselbtn{appearance:none;-webkit-appearance:none;width:100%;cursor:pointer;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.16);border-radius:12px;
  display:flex;align-items:center;justify-content:space-between;gap:10px;padding:11px 15px;
  font-family:var(--data);font-weight:700;text-transform:uppercase;letter-spacing:.6px;font-size:13px;color:var(--cream);transition:border-color .2s ease}
.sselbtn:hover,.ssel.open .sselbtn{border-color:var(--leaf)}
.sselbtn svg{flex:0 0 auto;transition:transform .3s cubic-bezier(.2,.7,.3,1.2)}
.ssel.open .sselbtn svg{transform:rotate(180deg)}
/* in-flow accordion (NOT absolute) — 0 height when closed so it never adds modal scroll height */
.ssellist{max-height:0;overflow:hidden;margin-top:0;background:rgba(0,0,0,.4);border-radius:10px;
  transition:max-height .3s cubic-bezier(.4,0,.2,1),margin-top .3s ease}
.ssel.open .ssellist{max-height:240px;overflow-y:auto;margin-top:6px;padding:4px}
.sselopt{display:block;cursor:pointer;padding:10px 14px;border-radius:8px;font-family:var(--data);font-weight:700;text-transform:uppercase;letter-spacing:.6px;font-size:13px;color:var(--cream);transition:background .18s ease,color .18s ease}
.sselopt:hover{background:rgba(40,152,81,.3)}
.sselopt.on{color:var(--leaf)}

/* add-to-cart controls — quantity + button on ONE aligned line */
.qtyrow{display:flex;align-items:stretch;gap:12px;margin-top:14px}
.qty{display:flex;align-items:stretch;background:rgba(255,255,255,.08);border-radius:12px;overflow:hidden;flex:0 0 auto;height:48px}
.qty button{appearance:none;-webkit-appearance:none;border:0;background:transparent;color:var(--cream);font-size:19px;width:40px;cursor:pointer;transition:background .2s ease}
.qty button:hover{background:rgba(40,152,81,.3)}
.qty span{min-width:36px;display:flex;align-items:center;justify-content:center;font-family:var(--data);font-weight:700;font-size:16px;color:var(--cream)}
.addbtn{appearance:none;-webkit-appearance:none;border:0;cursor:pointer;flex:1 1 auto;min-width:0;height:48px;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--disp);font-weight:700;text-transform:uppercase;letter-spacing:.6px;font-size:15px;color:#04140a;
  background:var(--orange);padding:0 18px;border-radius:14px;transition:filter .2s ease,transform .12s ease}
.addbtn:hover{filter:brightness(1.08)}
.addbtn:active{transform:translateY(1px)}
.addbtn.disabled{background:rgba(255,255,255,.12);color:var(--cream);opacity:.55;cursor:not-allowed}
.addhint{font-family:var(--body);font-size:12.5px;opacity:.7;margin-top:8px;min-height:0}
.addhint.ok{color:var(--leaf);opacity:1}
.addhint.warn{color:var(--orange);opacity:1}


@media(max-width:780px){
  .pgrid{grid-template-columns:1fr}
}

/* ============================================================================
   PRODUCT PAGE (/shop/<slug>) — added 20 Jul 2026 with site/templates/product.php.
   Layout frame ONLY. Everything inside reuses the modal's components (.pmodal-img,
   .pmodal-body, .vbtn, .ssel, .qtyrow, .pdots, .incart, .addedov) so the product
   page and the /shop modal stay identical without a second set of styles.
   ============================================================================ */
.crumb{display:flex;align-items:center;gap:9px;margin:4px 0 18px;font-family:var(--data);font-weight:700;letter-spacing:1.2px;text-transform:uppercase;font-size:11.5px}
.crumb a{color:var(--leaf);text-decoration:none;transition:color .2s ease}
.crumb a:hover{color:var(--orange)}
.crumb span{color:var(--cream);opacity:.35}

.prodpage{display:grid;grid-template-columns:1.05fr 1fr;gap:30px;align-items:start}
/* the photo panel: same white plate as the modal, but full height and rounded all round.
   v1.12.16 — was a fixed height:min(520px,58vh), which on a 526px column gave a 418px plate
   holding a 214px-tall photo: 200px of white and the 16px radius sitting miles from the
   picture. Aspect-driven so the plate follows the column width and hugs the photo; the old
   fixed height becomes the cap for very wide viewports. */
.prodpage .pmodal-img{height:auto;aspect-ratio:3/2;max-height:min(520px,58vh);border-radius:18px;border:1px solid var(--line)}
.prodpage .prodinfo{min-width:0}
/* .pmodal-body carries modal padding — the page supplies its own spacing instead */
.prodpage .pmodal-body{padding:0}
.prodpage .pmodal-price{margin-top:0}
.prodpage .ssel{max-width:260px}

@media(max-width:900px){
  .prodpage{grid-template-columns:1fr;gap:22px}
  .prodpage .pmodal-img{max-height:min(420px,52vh)}
}

/* ---- shop search (in .shop-head, beside the category filter) — added 20 Jul 2026 ---- */
.shopsearch{display:flex;align-items:center;gap:9px;height:38px;padding:0 8px 0 15px;border-radius:19px;
  background:rgba(255,255,255,.1);transition:background .25s ease}
.shopsearch:focus-within{background:rgba(40,152,81,.28)}
.shopsearch svg{flex:0 0 auto}
.shopsearch input{appearance:none;-webkit-appearance:none;background:transparent;border:0;outline:none;
  font-family:var(--body);font-size:14px;color:var(--cream);width:200px;max-width:42vw;padding:0}
.shopsearch input::placeholder{color:var(--cream);opacity:.55}
.shopsearch input::-webkit-search-cancel-button{display:none}
.shopqclr{appearance:none;-webkit-appearance:none;border:0;background:transparent;cursor:pointer;
  width:26px;height:26px;flex:0 0 auto;border-radius:50%;color:var(--cream);opacity:.6;font-size:17px;line-height:1;
  display:flex;align-items:center;justify-content:center;transition:opacity .2s ease,background .2s ease}
.shopqclr:hover{opacity:1;background:rgba(255,255,255,.12)}
.shopqclr[hidden]{display:none}
/* search takes the free space so BOTH controls sit right; the filter then just tucks in beside it */
.shop-head .shopsearch{margin-left:auto}
.shop-head .sel{margin-left:12px}
@media(max-width:620px){
  .shop-head .shopsearch{margin-left:0;flex:1 1 auto}
  .shopsearch input{width:100%;max-width:none}
}

/* "View full details ›" — the modal's link through to the real product page */
.fullink{display:block;text-align:center;margin-top:16px;padding-top:14px;border-top:1px dashed rgba(40,152,81,.4);
  font-family:var(--data);font-weight:700;text-transform:uppercase;letter-spacing:1px;font-size:12.5px;
  color:var(--leaf);text-decoration:none;transition:color .2s ease}
.fullink:hover{color:var(--orange)}

/* ============================================================================
   PRODUCT PAGE TYPE SCALE — v1.5.1, 20 Jul 2026.
   The modal's labels are sized for a 460px card (11–13.5px). Reused as-is at full
   page width they read as tiny text, which breaks the site rule that no interface
   text goes below 14px. These overrides are scoped to .pg-product ONLY — the /shop
   modal is untouched.
   ============================================================================ */
.pg-product .crumb{font-size:15px;letter-spacing:1px;margin:2px 0 20px}
.pg-product .crumb a{color:var(--leaf)}
.pg-product .crumb span{opacity:.45}

.pg-product .pmodal-lbl{font-size:14px;letter-spacing:1.2px;margin-top:18px}
.pg-product .pmodal-colour{font-size:16px;opacity:.85;margin-bottom:4px}
.pg-product .pmodal-body li{font-size:16px;line-height:1.6;margin-bottom:8px}
.pg-product .pmodal-body ul{margin:16px 0}
.pg-product .vbtn{font-size:14px;padding:9px 15px}
.pg-product .sselbtn,.pg-product .sselopt{font-size:15px}
.pg-product .addhint{font-size:14px;margin-top:10px}
.pg-product .salebadge.inl{font-size:13px;padding:5px 10px}
.pg-product .credit{font-size:14px;opacity:.5;letter-spacing:.8px}
.pg-product .shoppolicy-link{font-family:var(--data);font-size:14px;letter-spacing:.8px;text-transform:uppercase;color:var(--leaf);text-decoration:none}
.pg-product .shoppolicy-link:hover{color:var(--orange)}

/* Material / Sizing guide: the modal centres these because the card is narrow. In a
   left-aligned page column that reads as a mistake — left-align and size them up. */
.pg-product .pmodal-material{text-align:left;margin:20px 0 4px}
.pg-product .pmodal-material .mlabel{font-size:14px;letter-spacing:1.2px}
.pg-product .pmodal-material .mtext{font-size:16px;opacity:.9;margin-top:5px}

/* The page's primary action stays ORANGE at all times (site button law). The modal greys
   it out until a size is picked; on a full page that reads as a broken control, so the
   prompt goes in the hint line instead. .busy only dims it during the request. */
.pg-product .addbtn{font-size:16px;height:52px}
.pg-product .addbtn.busy{opacity:.6;pointer-events:none}
.pg-product .qty{height:52px}
.pg-product .qty span{font-size:17px}
.pg-product .qty button{font-size:21px;width:44px}
.pg-product .pmodal-price{font-size:30px}
.pg-product .pmodal-price .was{font-size:19px}

/* ============================================================================
   v1.5.3 — product cubes are real links, and the product page is no longer a
   dead end. The cube keeps its exact look; only link styling is reset.
   ============================================================================ */
.pcube{text-decoration:none;color:inherit;display:flex}
.pcube:hover .pname{color:var(--cream)}

/* "More in <category>" on the product page — reuses .pgrid/.pcube unchanged */
.morein{padding-top:38px}
.morein .cathead{display:flex;align-items:baseline;justify-content:space-between;gap:16px;flex-wrap:wrap;margin:0 0 16px}
.morein .cattitle{font-size:clamp(20px,2.6vw,26px)}
.moreall{font-family:var(--data);font-weight:700;text-transform:uppercase;letter-spacing:1px;font-size:14px;
  color:var(--leaf);text-decoration:none;white-space:nowrap;transition:color .2s ease}
.moreall:hover{color:var(--orange)}
@media(max-width:780px){
  /* the shop drops .pgrid to one column; two reads better for a "more like this" row */
  .morein .pgrid{grid-template-columns:1fr 1fr;gap:11px}
  .morein .pcube .pname{font-size:15px;padding-right:0}
  .morein .pcube .pprice{position:static;display:inline-block;margin-top:6px;font-size:15px;box-shadow:none;padding:5px 10px}
  .morein .pcube .pinfo{flex-direction:column;align-items:flex-start;gap:2px}
}

/* v1.12.14's `.pimg{border-radius:14px}` removed in v1.12.16 — it never showed anything.
   `.pimg` only ever appears inside `.pcube`, which already clips its top corners via
   overflow:hidden + border-radius:12px, so the rule was a no-op on the two corners you can
   see and the plate's bottom edge sits flush against .pinfo by design.
   ⚠ The lesson worth keeping: with object-fit:contain the <img> element box is the ENTIRE
   plate and the photo is letterboxed inside it, so a radius on the <img> lands on empty
   padding and is invisible. Round the PLATE, and size the plate to hug the photo. */

/* ── SIZE CHART ────────────────────────────────────────────────────────────────
   ONE LINE per size — "S  34/36"" — size in green, measurement after a gap, entries
   divided by a vertical rule. Stacking the measurement under the size doubled the
   height of the block and made the shop miserable on a phone (25 Jul 2026). */
.szchart{display:grid;grid-template-columns:repeat(4,auto);justify-content:start;
  gap:2px 0;margin-top:6px}
.szcell{display:flex;align-items:baseline;gap:7px;padding:1px 13px;
  border-left:1px solid rgba(228,228,216,.22);white-space:nowrap}
.szcell:nth-child(4n+1){border-left:0;padding-left:0}
.szsize{font-family:var(--data);font-weight:700;text-transform:uppercase;letter-spacing:.5px;
  font-size:12.5px;color:var(--leaf)}
.szmeas{font-size:14px;color:var(--cream);opacity:.88}
@media(max-width:520px){
  .szchart{grid-template-columns:repeat(3,auto)}
  .szcell{padding:1px 10px}
  .szcell:nth-child(4n+1){border-left:1px solid rgba(228,228,216,.22);padding-left:10px}
  .szcell:nth-child(3n+1){border-left:0;padding-left:0}
  .szmeas{font-size:13px}
}

/* Price, colour and size controls centred in the quick-view panel (25 Jul 2026) */
.pmodal-body .pmodal-price{text-align:center}
.pmodal-body .ssel{display:block;margin-left:auto;margin-right:auto}
.pmodal-body .szchart{justify-content:center}
/* the colour dropdown, and either control when there is only one choice to make */
.ssel.csel{margin-top:10px}
.ssel.one .sselbtn{cursor:default;opacity:.85;justify-content:center}
.ssel.one .sselbtn:hover{border-color:rgba(255,255,255,.16)}

/* Size-chart accordion — shut by default so it costs no height until it is wanted */
.szdet{border:0;padding:0}
.szdet > summary{cursor:pointer;list-style:none;display:inline-flex;align-items:center;gap:7px;
  user-select:none;-webkit-user-select:none}
.szdet > summary::-webkit-details-marker{display:none}
.szdet > summary::after{content:"";width:7px;height:7px;border-right:2px solid var(--leaf);
  border-bottom:2px solid var(--leaf);transform:rotate(45deg) translateY(-2px);
  transition:transform .25s ease}
.szdet[open] > summary::after{transform:rotate(-135deg) translateY(-2px)}
.szdet > summary:hover{opacity:.85}
.pmodal-body .szdet > summary{justify-content:center;width:100%}

/* The size-chart heading is the one thing a customer hunts for before choosing — make it read as
   a control, not a caption: larger and in the action colour (25 Jul 2026) */
.szdet > summary.mlabel{font-size:15px;letter-spacing:.8px;color:var(--orange)}
.szdet > summary.mlabel::after{border-right-color:var(--orange);border-bottom-color:var(--orange);
  width:8px;height:8px}

/* Category under the product name — smaller, green, its own line (25 Jul 2026) */
.pagetitle-sub{display:block;font-size:.42em;line-height:1.2;margin-top:.18em;
  color:var(--leaf);letter-spacing:1px;
  /* solid Gravesend Sans, NOT the outlined Inline face the title uses (25 Jul 2026) */
  font-family:"Gravesend Sans",sans-serif;font-weight:700}
.pmodal-body h3 .pagetitle-sub{font-size:.5em;margin-top:.2em}

/* PRICE — it was reading as smaller than the controls beneath it. Half again in size and set in
   a solid pill so it is the first thing the eye lands on. */
.pmodal-price{display:flex;align-items:center;justify-content:center;gap:9px;
  width:fit-content;margin:2px auto 12px;font-size:1.5em;line-height:1;
  background:var(--orange);color:#11281B;border-radius:999px;padding:13px 24px 12px;
  box-shadow:0 8px 20px -10px rgba(0,0,0,.75)}
.pmodal-price .was{color:rgba(17,40,27,.62);text-decoration:line-through;font-size:.62em;margin:0}
.pmodal-price .salebadge.inl{background:#11281B;color:var(--cream);margin:0;font-size:.42em}

/* Colour and size sit on ONE line — the button says "Size" rather than "Choose a size", which
   frees enough width for both and keeps the buying controls in a single glance (25 Jul 2026).
   They wrap to two lines by themselves on a narrow phone. */
.pmodal-body .ssel{display:inline-flex;vertical-align:top;margin:0 4px 8px;min-width:142px}
.pmodal-body .ssel .sselbtn{width:100%}
/* ⚠ the pills are kept in the page (hidden) because the gallery swap is driven off them — and
   [hidden]'s UA display:none LOSES to .vbtns{display:flex}, so they stayed visible. Same trap as
   the PayPal overlay. */
.vbtns[hidden]{display:none}

/* Colour + size on one row, centred, wrapping on a narrow phone. A wrapper rather than relying on
   inline-flex: the parent's display model differs between the page and the quick-view, and this
   behaves the same in both. */
.selrow{display:flex;flex-wrap:wrap;justify-content:center;align-items:flex-start;gap:8px;margin:4px 0 6px}
.selrow .ssel{margin:0;min-width:138px;max-width:200px;flex:0 1 auto}
.prodpage .selrow .ssel{max-width:220px}

/* PRICE lives in the buy row now — same box shape and height as the quantity stepper and Add to
   cart, in orange so it is the thing that pops (25 Jul 2026). */
.qtyrow .pmodal-price{margin:0;flex:0 0 auto;align-self:stretch;
  font-size:19px;padding:0 20px;border-radius:12px;box-shadow:none}
@media(max-width:520px){.qtyrow .pmodal-price{font-size:17px;padding:0 15px}}

/* 🔴 .ssel must NOT be a flex container: its children are the BUTTON and the OPTION LIST, which
   have to stack. Making it inline-flex (to get colour + size side by side) laid the list out
   BESIDE the button as a tall narrow scrolling column. The row is .selrow's job, not .ssel's. */
.pmodal-body .ssel,.selrow .ssel,.prodpage .ssel{display:inline-block}
.selrow .ssel .sselbtn{width:100%}

/* ── SIZE CHART FOLD ───────────────────────────────────────────────────────────
   Animates a GRID TRACK (0fr → 1fr), never the height of in-flow content — the same
   fold the staff consoles use, and the reason it is smooth rather than a snap.
   .szinner MUST keep overflow:hidden + min-height:0 or the track cannot collapse. */
.szacc{margin:11px 0 4px}
.szsum{display:inline-flex;align-items:center;gap:8px;cursor:pointer;background:none;border:0;padding:0;
  font-family:var(--data);letter-spacing:.8px;text-transform:uppercase;font-size:15px;color:var(--orange)}
.szsum:hover{opacity:.85}
.szchev{width:8px;height:8px;border-right:2px solid var(--orange);border-bottom:2px solid var(--orange);
  transform:rotate(45deg) translateY(-2px);transition:transform .3s cubic-bezier(.4,0,.2,1)}
.szacc.open .szchev{transform:rotate(-135deg) translateY(-2px)}
.szfold{display:grid;grid-template-rows:0fr;transition:grid-template-rows .34s cubic-bezier(.4,0,.2,1)}
.szacc.open .szfold{grid-template-rows:1fr}
.szinner{overflow:hidden;min-height:0}

/* ONE alignment on the product page: everything left, matching the bullets and the buy row.
   The narrow quick-view card stays centred — that is its own established look. */
.prodpage .selrow{justify-content:flex-start}
.prodpage .pmodal-material{text-align:left}
.prodpage .szchart{justify-content:start}
.prodpage .pmodal-price{margin-left:0;margin-right:0}

/* Quick-view title matches the product page exactly: Gravesend Inline (the outlined face), centred,
   category beneath in green — then room to breathe before the dropdowns start (25 Jul 2026). */
.pmodal-body h3{font-family:"Gravesend Inline",sans-serif;text-align:center;margin:6px 0 0}
.pmodal-body h3 .pagetitle-sub{margin-top:.3em;letter-spacing:1.5px}
.pmodal-body .selrow{margin-top:20px}
.prodpage .selrow{margin-top:6px}

/* Size-chart text was 12.5/14px — too small to read at a glance, and under the site's own
   14px floor. (25 Jul 2026) */
.szsize{font-size:15px}
.szmeas{font-size:16.5px;opacity:.95}
@media(max-width:520px){.szsize{font-size:14px}.szmeas{font-size:15px}}

/* The SIZE CHART heading is also a .mlabel, and `.pmodal-material .mlabel` (green, 11px) was
   outranking the plain .szsum rule — hence a green heading where an orange one was asked for. */
/* Titles GREEN, chevron ORANGE (25 Jul 2026) — the heading is a label, the arrow is the
   thing you act on, so only the arrow wears the action colour. */
.pmodal-material .szsum,.szacc .szsum{font-size:15px;color:var(--leaf)}
.pmodal-material .szsum .szchev{border-right-color:var(--orange);border-bottom-color:var(--orange)}

/* Quick-view opener stripes — the page's own motif at half length, above the product title.
   MODAL ONLY: the product page already has the full-size pair in its header. (25 Jul 2026) */
.pmodal-body .opener{display:flex;align-items:center;justify-content:center;gap:3px;margin:2px 0 10px}
.pmodal-body .opener i{display:block;width:7px;height:41px;background:var(--leaf);border-radius:1px}

/* ── DROPDOWN LISTS: OVERLAY, NOT PUSH ─────────────────────────────────────────
   Was max-height 0 → 240px. That animates LAYOUT: the list shoved everything below
   it down the page, and on the 2-item colour list it ran toward 240px regardless of
   content, which is what made it feel violent next to the longer size list.
   Now the list is taken out of flow and only opacity/transform animate — nothing
   below it moves, and both dropdowns behave identically. */
.ssel .ssellist{position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:60;
  max-height:min(260px,52vh);overflow-y:auto;margin-top:0;padding:4px;
  opacity:0;visibility:hidden;transform:translateY(-6px);pointer-events:none;
  transition:opacity .18s ease,transform .2s cubic-bezier(.4,0,.2,1),visibility 0s linear .2s}
.ssel.open .ssellist{opacity:1;visibility:visible;transform:none;pointer-events:auto;
  transition:opacity .18s ease,transform .2s cubic-bezier(.4,0,.2,1),visibility 0s}
.ssel{position:relative}
/* the open list must not be clipped by the card it sits in */
.pmodal-body,.prodinfo{overflow:visible}

/* The list may be WIDER than its button — "Heather Grey" doesn't fit the width "Black" gives.
   Because it is positioned out of flow, growing it moves nothing on the page. (25 Jul 2026) */
.ssel .ssellist{right:auto;min-width:100%;width:max-content;max-width:min(280px,84vw)}
.ssel .sselopt{white-space:nowrap}

/* ── DROPDOWNS: back IN FLOW, sized to their longest option ────────────────────
   Overlaying was the wrong call — reverted. The judder was never the opening
   itself: "Heather Grey" is wider than "Black", so the control RESIZED as the list
   appeared. Letting .ssel shrink-to-fit its own content means the option list —
   which holds the longest label — sets the width up front, so the button is
   already that wide and nothing changes when it opens. (25 Jul 2026) */
.ssel .ssellist{position:static;top:auto;left:auto;right:auto;z-index:auto;
  width:auto;min-width:0;max-width:none;
  opacity:1;visibility:visible;transform:none;pointer-events:auto;
  max-height:0;overflow:hidden;margin-top:0;padding:0;
  transition:max-height .26s cubic-bezier(.4,0,.2,1),margin-top .2s ease,padding .2s ease}
.ssel.open .ssellist{max-height:260px;overflow-y:auto;margin-top:6px;padding:4px}
.ssel{display:inline-block;width:auto;min-width:138px;max-width:260px}
.selrow .ssel{flex:0 0 auto}
.ssel .sselopt{white-space:nowrap}
.ssel .sselbtn{width:100%}

/* The last 8px of movement was the list's own left/right padding arriving on open. Hold the
   horizontal padding constant and animate only the vertical, so the width never changes at all. */
.ssel .ssellist{padding:0 4px}
.ssel.open .ssellist{padding:4px}
.ssel.open .ssellist{padding-left:4px;padding-right:4px}

/* 25 Jul 2026 — the phone buy row. Three controls would not fit one line: ADD TO CART was
   crushed to 99px and its label broke onto three lines ("ADD"/"TO"/"CART"). The row now
   wraps — price and quantity take half each on the first line, the button gets a full-width
   line of its own beneath them, so the three line up as one block.
   Must stay at the END of the file so it overrides the 520px block above. */
@media(max-width:430px){
  .qtyrow{flex-wrap:wrap}
  .qtyrow .addbtn{flex:1 0 100%}
  .qtyrow .pmodal-price{flex:1 1 0;min-width:0;box-sizing:border-box;display:flex;align-items:center;justify-content:center;padding:0}
  .qtyrow .qty{flex:1 1 0;min-width:0;justify-content:space-between}
}
