/* ============================================================
   CHEAPWEED shop layer — WDK (Porto) port.          wdk-shop.css
   ============================================================
   Ported 2026-08-16 from cw-src/theme/assets/cw.css (grid/card/
   sidebar/toolbar extracts only) and cw-shop.css (archive chrome,
   minus the Woodmart footer/header sections). Source line ranges
   are stamped on every block; NOTES-css.md holds the full map of
   kept vs dropped vs re-targeted.

   Order matters: on CW, cw-shop.css loads AFTER cw.css and wins on
   equal specificity. This file preserves that cascade — cw.css
   extracts first, cw-shop.css extracts second, then the Porto
   adaptation layer (new code, this port only) at the very end.

   Enqueued by functions.php -> wdk_shop_enqueue() as 'wdk-shop',
   ver WDK_VER, dep styles-child. Loads on every front-end page —
   cards can render inside any Elementor product loop.
   ============================================================ */

/* ============================================================
   FONTS + TOKENS                                 [cw.css 8-27]
   WDK RETHEME (2026-08-16, DESIGN-TOKENS.md): CW's display faces
   are replaced by ONE face — Archivo Black (WDK's own heading
   font) — and the colour token values are repointed to the WDK
   palette (jade/orange). Token NAMES stay for diffability.
   The CWNameplate faces (header wordmark) are NOT ported — the
   header stays Porto's. --cw-nameplate is kept in the token block
   for CW-parity diffing; nothing in this file uses it, and with no
   @font-face behind it it falls through to the display face.
   URLs stay relative: this file lives in assets/ beside the fonts,
   same as CW, so they already resolve to porto-child/assets/.
   ============================================================ */
@font-face{font-family:'Archivo Black';font-style:normal;font-weight:400;font-display:swap;
  src:url('archivo-black.woff2') format('woff2')}
/* Figtree 600 — the card size-picker face (owner, 2026-08-18: "let's stick
   with figtree"). Latin subset, self-hosted like the others; the 800 cut in
   wdk-chrome.css is a separate face of the same family, so both coexist.
   Bulk lb fractions (¼ ½) are outside this subset and fall through to the
   system stack — visible only on the rare lb rows. */
@font-face{font-family:'Figtree';font-style:normal;font-weight:600;font-display:swap;
  src:url('figtree-600.woff2') format('woff2')}

:root{
  --cw-paper:#f1f1ee; --cw-card:#fff; --cw-ink:#111110; --cw-mut:#77776f; --cw-line:#e3e3de;
  /* WDK palette: accent = footer jade, deep = derived dark jade (hovers),
     soft = light jade tint, hi = bright jade (toast, on dark ink). */
  --cw-accent:#3EB785; --cw-accent-ink:#fff; --cw-soft:#e8f6f0; --cw-deep:#1F8A5F; --cw-hi:#4fd9a4;
  /* SAVE badges / deal chips: WDK orange, white text (DESIGN-TOKENS.md). */
  --cw-badge:#FF9800; --cw-badge-ink:#fff;
  /* Hybrid strain chip joins the jade family (was CW green #0f8a3d);
     deep jade keeps ~4.5:1 on white at chip sizes. */
  --cw-indica:#7a4fd0; --cw-sativa:#c98514; --cw-hybrid:#1F8A5F;
  /* The one destructive colour. Dark enough for white text at 4.5:1. */
  --cw-warn:#a52016; --cw-warn-ink:#fff;
  --cw-display:'Archivo Black','Arial Black',Impact,sans-serif;
  --cw-nameplate:'CWNameplate','Archivo Black','Arial Black',sans-serif;
  --cw-ui:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
}

/* ============================================================
   PRODUCT CARD                                 [cw.css 29-148]
   Verbatim. (.cw-hscroll is CW's homepage scroller — no WDK
   markup emits it yet; kept in the selector for parity.)
   ============================================================ */
ul.products.cw-grid, ul.products.cw-hscroll{list-style:none;margin:0;padding:0}
.cw-card{background:var(--cw-card);border-radius:6px;position:relative;display:flex;flex-direction:column;
  box-shadow:0 1px 4px rgba(17,17,16,.07);margin:0!important;width:auto!important;float:none!important;font-family:var(--cw-ui)}
.cw-card:hover{box-shadow:0 4px 14px rgba(17,17,16,.12)}
.cw-imgw{position:relative;display:block;background:#f5f5f2;border-radius:6px 6px 0 0;overflow:hidden;aspect-ratio:.96}
.cw-imgw img{width:100%;height:100%;object-fit:cover;display:block}
/* Stamp badges. SOLD OUT is bigger and more angled than NEW so they
   never read as peers. Archivo Black runs ~15% wider than the CW
   faces: tracking drops to 0 and both stamps step down a size so
   SOLD OUT still clears the NEW stamp on narrow cards. */
.cw-badge-new,.cw-badge-oos{position:absolute;z-index:2;
  font-family:var(--cw-display)!important;font-weight:400!important;text-transform:uppercase;
  line-height:1;letter-spacing:0;border:2.5px solid currentColor;border-radius:3px;
  padding:5px 9px 6px;background:rgba(255,255,255,.82);-webkit-backdrop-filter:blur(1px);
  backdrop-filter:blur(1px)}
.cw-badge-new{top:12px;left:11px;color:var(--cw-deep);font-size:13px;transform:rotate(-6deg)}
/* Left side (owner, 2026-08-19). The stamp keeps its angle; rotate(-8deg)
   pivots about the centre so nothing pokes past the card edge at this size. */
.cw-badge-oos{top:15px;left:11px;color:var(--cw-warn);font-size:16px;transform:rotate(-8deg);
  box-shadow:inset 0 0 0 1px rgba(165,32,22,.25)}
/* A card can be BOTH new and sold out, and both stamps now claim the left
   corner — content-product.php prints NEW first, so when SOLD OUT follows it,
   NEW yields and takes the right side (the OOS stamp is the state that must
   not move). */
.cw-badge-new:has(+ .cw-badge-oos){left:auto;right:11px}
/* The rule through the words is what makes it a cancellation and not a label. */
.cw-badge-oos::after{content:"";position:absolute;left:8%;right:8%;top:50%;height:2.5px;
  background:currentColor;transform:translateY(-1px)}
.cw-body{padding:11px 12px 12px;display:flex;flex-direction:column;flex:1}
.cw-nm{font:800 13.5px/1.3 var(--cw-ui);letter-spacing:.05em;text-transform:uppercase;color:var(--cw-ink)!important;
  text-decoration:none;margin-bottom:3px;display:block}
.cw-price{font-family:var(--cw-display);font-size:22px;line-height:1.05;letter-spacing:-0.01em;color:var(--cw-ink);
  display:flex;align-items:baseline;gap:7px;flex-wrap:wrap}
.cw-price .unit{font:700 11.5px/1 var(--cw-ui);letter-spacing:.05em;color:var(--cw-mut)}
/* min-height reserves the sale row on undiscounted cards so grid rows align. */
.cw-salerow{display:flex;align-items:center;gap:2px;margin-top:8px;min-height:19px}
.cw-salerow .was{font:600 11.5px/1 var(--cw-ui);color:var(--cw-mut);text-decoration:line-through}
.cw-salerow .off{font:800 10.5px/1 var(--cw-ui);background:var(--cw-badge);color:var(--cw-badge-ink);
  letter-spacing:.05em;padding:4px 6.5px;border-radius:3px;font-variant-numeric:tabular-nums}
.cw-tag{display:flex;align-items:center;flex-wrap:wrap;gap:0 6px;
  font:800 10px/1.3 var(--cw-ui);letter-spacing:.06em;margin:3px 0 8px;color:var(--cw-mut);
  font-variant-numeric:tabular-nums}
.cw-tag.is-indica{color:var(--cw-indica)}.cw-tag.is-sativa{color:var(--cw-sativa)}.cw-tag.is-hybrid{color:var(--cw-hybrid)}
/* Potency reads as reference data: its own bordered chip in the muted ink. */
.cw-tag .sub{font:800 9.5px/1 var(--cw-ui);letter-spacing:.07em;color:var(--cw-mut);
  border:1px solid var(--cw-line);border-radius:3px;padding:3px 5px;white-space:nowrap}
.cw-acts{display:flex;gap:7px;margin-top:auto;padding-top:12px;position:relative}
.cw-szbtn{flex:1.25;display:flex;align-items:center;justify-content:center;gap:4px;min-width:0;
  border:1.5px solid var(--cw-ink);background:var(--cw-card);color:var(--cw-ink);border-radius:4px;padding:9px 5px;
  font:800 11px/1 var(--cw-ui);letter-spacing:.07em;cursor:pointer;white-space:nowrap}
.cw-szbtn .szlbl{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.cw-addbtn{flex:1;background:var(--cw-soft);color:var(--cw-deep);border:1.5px solid var(--cw-accent);border-radius:4px;
  padding:9px 5px;font:800 11px/1 var(--cw-ui);letter-spacing:.1em;cursor:pointer;transition:background .15s}
.cw-addbtn:active,.cw-addbtn.loading{background:var(--cw-accent);color:var(--cw-accent-ink)}
/* Sold out is grey, not a faded green — it drops out of the colour
   hierarchy to match the desaturated photo above it. */
.cw-addbtn[disabled]{background:#f2f2ef;color:#8a8a84;border-color:var(--cw-line);
  opacity:1;cursor:not-allowed}
.cw-addbtn[disabled]:hover{background:#f2f2ef;color:#8a8a84;border-color:var(--cw-line)}
.cw-addbtn-solo{flex:1 1 100%}
/* Mix & match containers and bundles are links to their own page, not adds. */
a.cw-addbtn{display:inline-flex;align-items:center;justify-content:center;text-align:center;
  text-decoration:none;box-sizing:border-box}
a.cw-addbtn:hover{background:var(--cw-accent);color:var(--cw-accent-ink)}
.cw-szbtn:focus-visible,.cw-addbtn:focus-visible,.cw-chip:focus-visible{outline:2.5px solid var(--cw-accent);outline-offset:2px}
.cw-card.open{z-index:30}

/* dropdown */
.cw-dd{position:absolute;left:0;right:0;top:calc(100% + 6px);background:var(--cw-card);border:1.5px solid var(--cw-ink);
  border-radius:6px;box-shadow:0 14px 34px rgba(17,17,16,.22);display:none;overflow:hidden;z-index:31;
  /* 27px header + 8 rows; past that are flavour lists, meant to scroll. */
  max-height:min(420px,72vh);overflow-y:auto}
.cw-card.open .cw-dd{display:block}
/* Sticky header needs its own stacking or later rows paint over it. */
.cw-dd-hdr{display:flex;justify-content:space-between;padding:9px 12px 7px;font:800 9.5px/1 var(--cw-ui);
  letter-spacing:.14em;color:var(--cw-mut);border-bottom:1px solid var(--cw-line);
  position:sticky;top:0;z-index:2;background:var(--cw-card)}
.cw-dd{isolation:isolate}
.cw-dd .cw-opt{position:relative;z-index:1}
.cw-opt{display:flex;justify-content:space-between;align-items:center;width:100%;background:none;border:none;
  border-bottom:1px solid var(--cw-line);padding:10px 12px;cursor:pointer;text-align:left;font-family:var(--cw-ui)}
.cw-opt:last-child{border-bottom:none}
.cw-opt:hover{background:var(--cw-soft)}
.cw-opt-l{flex:1;min-width:0;padding-right:10px}
.cw-opt .w{font:800 12.5px/1.25 var(--cw-ui);letter-spacing:.04em;display:block;color:var(--cw-ink)}
.cw-opt .pg{display:block;font:600 10px/1 var(--cw-ui);color:var(--cw-mut);margin-top:2px}
.cw-opt-p{text-align:right;font-variant-numeric:tabular-nums}
.cw-opt-p .now{font:800 13.5px/1 var(--cw-ui);color:var(--cw-ink)}
.cw-opt-p .reg{font:600 10.5px/1 var(--cw-ui);color:var(--cw-mut);text-decoration:line-through;margin-right:5px}
.cw-opt-p .sv{display:block;font:800 9.5px/1 var(--cw-ui);color:var(--cw-deep);letter-spacing:.04em;margin-top:2px}
.cw-opt.sel{background:var(--cw-soft);box-shadow:inset 3px 0 0 var(--cw-accent)}
.cw-opt.soldout{opacity:.45;cursor:not-allowed}
.cw-opt.soldout .now{text-decoration:line-through}

/* ============================================================
   SHOP ARCHIVE — 2-across mobile, sidebar desktop
                                               [cw.css 150-219]
   Verbatim. Phase B only in practice (.cw-shop wrapper comes from
   archive-product.php); harmless while Phase A ships without it.
   .cw-sapply has no WDK markup (CW dropped the button too) —
   kept for parity.
   ============================================================ */
.cw-shop{background:var(--cw-paper);font-family:var(--cw-ui)}
.cw-shoplayout{max-width:1610px;margin:0 auto}
.cw-crumb{display:flex;align-items:baseline;gap:12px;padding:18px 16px 0}
.cw-crumb h1,.cw-crumb h2{font-family:var(--cw-display);font-size:24px;letter-spacing:0;margin:0;color:var(--cw-ink)}
.cw-count{font:700 11.5px/1 var(--cw-ui);letter-spacing:.08em;color:var(--cw-mut)}
.cw-toolrow{display:flex;gap:8px;padding:12px 16px 4px;align-items:center}
.cw-filters{display:flex;gap:8px;overflow-x:auto;scrollbar-width:none;flex:1}
.cw-filters::-webkit-scrollbar{display:none}
.cw-chip{flex:0 0 auto;border:1.5px solid var(--cw-ink);background:transparent;color:var(--cw-ink)!important;border-radius:3px;
  padding:6px 12px;font:700 11.5px/1 var(--cw-ui);letter-spacing:.07em;cursor:pointer;text-decoration:none!important;white-space:nowrap}
.cw-chip.on{background:var(--cw-ink);color:#fff!important}
.cw-filterbtn{flex:0 0 auto;border:1.5px solid var(--cw-ink);background:var(--cw-card);border-radius:3px;padding:6px 12px;
  font:800 11.5px/1 var(--cw-ui);letter-spacing:.08em;cursor:pointer}
.cw-sortform .woocommerce-ordering{margin:0}
.cw-sortform select{border:1.5px solid var(--cw-ink);border-radius:3px;background:var(--cw-card);
  font:700 11px/1.2 var(--cw-ui);letter-spacing:.03em;padding:7px 8px;color:var(--cw-ink)}
.cw-grid{display:grid!important;grid-template-columns:repeat(2,1fr);gap:12px;padding:12px 16px 26px}
.cw-pagination{padding:0 16px 30px}
.cw-pagination ul{display:flex;gap:6px;list-style:none;margin:0;padding:0}
.cw-pagination li a,.cw-pagination li span{display:flex;align-items:center;justify-content:center;min-width:38px;height:38px;
  border:1.5px solid var(--cw-ink);border-radius:4px;font:800 13px/1 var(--cw-ui);color:var(--cw-ink);text-decoration:none;padding:0 8px}
.cw-pagination li span.current{background:var(--cw-ink);color:#fff}
.cw-empty{padding:40px 16px;color:var(--cw-mut)}

/* sidebar: drawer on mobile */
.cw-side{position:fixed;top:0;left:0;bottom:0;width:min(320px,88vw);background:var(--cw-card);z-index:1001;
  transform:translateX(-102%);transition:transform .25s;overflow-y:auto;box-shadow:12px 0 40px rgba(17,17,16,.25)}
body.cw-side-open .cw-side{transform:none}
.cw-scrim{position:fixed;inset:0;background:rgba(17,17,16,.45);z-index:1000;opacity:0;pointer-events:none;transition:opacity .2s}
body.cw-side-open .cw-scrim{opacity:1;pointer-events:auto}
.cw-side-head{display:flex;justify-content:space-between;align-items:center;padding:16px;border-bottom:1px solid var(--cw-line)}
.cw-side-head h2,.cw-side-head p{font-family:var(--cw-display);font-size:16px;letter-spacing:0;margin:0}
.cw-x{background:none;border:1.5px solid var(--cw-ink);border-radius:4px;width:34px;height:34px;font-weight:800;cursor:pointer}
.cw-sgrp{padding:14px 16px 4px}
.cw-sgrp .gt{font:800 10px/1 var(--cw-ui);letter-spacing:.18em;color:var(--cw-mut);margin-bottom:9px}
.cw-chips2{display:flex;flex-wrap:wrap;gap:7px}
.cw-togglerow{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-bottom:1px solid var(--cw-line);
  font:700 12.5px/1 var(--cw-ui);letter-spacing:.05em}
.cw-tog{width:42px;height:24px;border-radius:99px;background:var(--cw-line);position:relative;display:inline-block}
.cw-tog span{position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;background:#fff;transition:left .15s;
  box-shadow:0 1px 3px rgba(0,0,0,.25)}
.cw-tog.on{background:var(--cw-accent)}
.cw-tog.on span{left:21px}
.cw-sapply{display:block;margin:16px;background:var(--cw-accent);color:var(--cw-accent-ink)!important;border-radius:5px;
  padding:13px;font:800 13px/1 var(--cw-ui);letter-spacing:.08em;text-align:center;text-decoration:none!important}

/* desktop */
@media (min-width:768px){
  .cw-grid{grid-template-columns:repeat(3,1fr);gap:14px}
}
@media (min-width:1025px){
  .cw-shoplayout{display:grid;grid-template-columns:250px 1fr;column-gap:15px;
    align-items:start;padding:0 24px}
  /* No right border on the rail: the gap does the separating. */
  .cw-side{position:sticky;top:0;transform:none;box-shadow:none;width:auto;
    height:100vh;background:transparent;z-index:1}
  .cw-side-head .cw-x,.cw-filterbtn,.cw-sapply{display:none}
  .cw-grid{grid-template-columns:repeat(4,1fr)}
}
@media (min-width:1200px){
  .cw-grid{grid-template-columns:repeat(5,1fr)}
}

/* ============================================================
   TOAST                                       [cw.css 494-517]
   The reduced-motion rule is RE-TARGETED: CW's list also named
   .cw-mtrack (ticker), .cw-searchtoggle and the Woodmart header
   search form — none ported, trimmed from the selector list.
   ============================================================ */
.cw-toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%) translateY(20px);background:var(--cw-ink);color:#fff;
  padding:11px 18px;border-radius:6px;font:700 12.5px/1 var(--cw-ui);letter-spacing:.04em;opacity:0;pointer-events:none;
  transition:opacity .2s,transform .2s;z-index:100000;
  /* One narrow line; the NAME is what gives way, never the money. */
  width:max-content;max-width:min(calc(100vw - 32px),340px);
  white-space:nowrap;overflow:hidden}
.cw-toast .nm{display:inline-block;vertical-align:bottom;
  max-width:min(44vw,186px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cw-toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
.cw-toast b{color:var(--cw-hi)}

@media (prefers-reduced-motion: reduce){
  .cw-toast,.cw-side,.cw-scrim,.cw-addbtn{transition:none}
}

/* ============================================================
   OPTION ROWS ON PHONES                     [cw.css 2328-2334]
   Long flavour names stop competing for width: name on its own
   line, money underneath. (.is-size rows opt back out below.)
   ============================================================ */
@media (max-width:768px){
  .cw-opt{flex-wrap:wrap;gap:2px 0}
  .cw-opt-l{flex:1 1 100%;padding-right:0}
  .cw-opt-p{flex:1 1 100%;display:flex;align-items:baseline;gap:6px;text-align:left}
  .cw-opt-p .sv{margin-top:0}
  .cw-dd{max-height:60vh}
}

/* ============================================================
   SOLD-OUT TREATMENT                        [cw.css 2396-2408]
   ============================================================ */
.cw-card.outofstock .cw-imgw img{filter:grayscale(1) contrast(.95);opacity:.62;
  transition:filter .2s,opacity .2s}
.cw-card.outofstock:hover .cw-imgw img{opacity:.72}
/* The name stays black — it is still a product you might want back in. */
.cw-card.outofstock .cw-price,
.cw-card.outofstock .cw-tag{opacity:.62}

@media (max-width:768px){
  .cw-badge-new{top:9px;left:8px;font-size:11px;padding:4px 7px 5px;border-width:2px}
  .cw-badge-oos{top:11px;right:8px;font-size:13px;padding:4px 7px 5px;border-width:2px}
  .cw-badge-oos::after{height:2px}
}

/* ============================================================
   FILTER RAIL SCROLLBAR                     [cw.css 2512-2513]
   ============================================================ */
.cw-side{scrollbar-width:none;-ms-overflow-style:none}
.cw-side::-webkit-scrollbar{width:0;height:0;display:none}

/* ============================================================
   ADDED-TO-CART TICK + SR TEXT              [cw.css 2575-2586]
   The tick SVG and .cw-sr span come from wdk-shop.js flashAdded().
   ============================================================ */
.cw-addbtn.is-added{display:inline-flex;align-items:center;justify-content:center}
.cw-addbtn.is-added svg{display:block}
@media (prefers-reduced-motion:no-preference){
  .cw-addbtn.is-added svg path{stroke-dasharray:24;stroke-dashoffset:24;
    animation:cw-tick .3s cubic-bezier(.16,1,.3,1) forwards}
}
@keyframes cw-tick{to{stroke-dashoffset:0}}
/* Visually hidden, still announced — the SVG says nothing on its own. */
.cw-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
/* [cw.css 2310-2311] the state colour, stated at bang weight upstream. */
.cw-addbtn.is-added{background:var(--cw-accent)!important;color:var(--cw-accent-ink)!important}

/* ============================================================
   SIZE-DROPDOWN SCROLLBAR                   [cw.css 2849-2855]
   The two halves are mutually exclusive on purpose (see CW note).
   ============================================================ */
.cw-dd::-webkit-scrollbar{width:8px}
.cw-dd::-webkit-scrollbar-track{background:transparent}
.cw-dd::-webkit-scrollbar-thumb{background:#c9c9c4;border-radius:8px}
.cw-dd::-webkit-scrollbar-thumb:hover{background:#adada6}
@supports not selector(::-webkit-scrollbar){
  .cw-dd{scrollbar-width:thin;scrollbar-color:#c9c9c4 transparent}
}

/* ============================================================
   FILTER RAIL: BOTTOM FADE + SCROLL ARROW   [cw.css 2868-2898]
   .cw-side-more / .has-more come from wdk-shop.js initSideMore().
   ============================================================ */
.cw-side-more{position:sticky;bottom:0;height:0;z-index:6;pointer-events:none;
  opacity:0;transition:opacity .22s ease}
.cw-side.has-more .cw-side-more{opacity:1}
.cw-side-more::before{content:"";position:absolute;left:0;right:0;bottom:0;height:86px;
  background:linear-gradient(to top,var(--cw-side-fade,#fff) 26%,rgba(255,255,255,0) 100%)}
/* The drawer sits on card white; the desktop rail is transparent over
   the paper ground, so the fade has to match the page. */
.cw-side{--cw-side-fade:var(--cw-card,#fff)}
@media (min-width:1025px){
  .cw-side{--cw-side-fade:var(--cw-paper,#f1f1ee)}
  .cw-side-more::before{background:linear-gradient(to top,var(--cw-paper,#f1f1ee) 26%,rgba(241,241,238,0) 100%)}
}
.cw-side-morebtn{position:absolute;left:50%;bottom:10px;transform:translateX(-50%);
  pointer-events:auto;width:38px;height:38px;padding:0;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  background:none;border:0;box-shadow:none;color:var(--cw-ink,#111110);opacity:.55;
  transition:opacity .16s,color .16s;
  animation:cw-side-nudge 1.9s ease-in-out infinite}
.cw-side-morebtn:hover{opacity:1;color:var(--cw-accent,#3EB785)}
.cw-side-morebtn:focus-visible{outline:2.5px solid var(--cw-accent,#3EB785);outline-offset:2px}
@keyframes cw-side-nudge{0%,70%,100%{transform:translateX(-50%) translateY(0)}
  82%{transform:translateX(-50%) translateY(3px)}}
/* Reduced motion still needs the arrow — it just stops nudging. */
@media (prefers-reduced-motion:reduce){
  .cw-side-morebtn{animation:none}
  .cw-side-more{transition:none}
}

/* ============================================================
   NUMBERS ON THE MONEY FACE — GRID CARDS ONLY [cw.css 2919-2989]
   RE-TARGETED: CW applied its money face site-wide (header chip,
   mini cart, cart, checkout, PDP ladder — all Woodmart/unported
   surfaces). Only the grid-card money moved here; Porto's own
   money keeps Porto's face. CW's .woocommerce-Price-currencySymbol
   shrink is DROPPED for the same reason — this file loads on every
   page and that rule would restyle Porto's cart/checkout/PDP
   prices.
   WDK RETHEME: CW's condensed money face is gone; --cw-money now
   resolves to the same Archivo Black as --cw-display (single
   @font-face at the top of the file). Archivo Black is ~15% wider
   at equal size, so every money/size figure below steps down a
   notch from the CW values to keep prices on one line in a
   2-across mobile card.
   ============================================================ */
/* Figtree took over every money/variation figure sitewide (owner,
   2026-08-18: "all prices and variations text throughout the site figtree").
   The display face stays on headings and the money face is this token, so
   the next font change is one line. Faces: 600 here, 800 in wdk-chrome. */
:root{--cw-money:'Figtree',var(--cw-ui)}

/* --- grid cards --- */
.cw-price{font-family:var(--cw-money);font-size:26px}
/* Figures line up in a column or they are not a price list. */
.cw-price,.cw-opt-p .now{font-variant-numeric:tabular-nums}

/* ============================================================
   CARD SIZE DROPDOWN — FIGTREE, NOT THE MONEY FACE.
   DIVERGES FROM CW (cw.css 3008-3010 put these on Archivo
   Black): the owner picked Figtree 600 from a specimen sheet
   (2026-08-18) — the display face at data sizes read wide and
   heavy, and SELECT truncated on 2-across mobile cards. The big
   card price (.cw-price above) STAYS on the money face; only the
   picker button and its rows change. Sizes/spacing unchanged.
   ============================================================ */
.cw-opt-p .now{font-family:'Figtree',var(--cw-ui);font-weight:600;font-size:15px}
.cw-opt-l .w{font-family:'Figtree',var(--cw-ui);font-weight:600;font-size:13px;letter-spacing:0}
.cw-szbtn .szlbl{font-family:'Figtree',var(--cw-ui);font-weight:600;font-size:12.5px;letter-spacing:0}
.cw-opt-l .pg{font-family:'Figtree',var(--cw-ui);font-weight:600;font-size:11px;letter-spacing:0;
  font-variant-numeric:tabular-nums}
/* The $ steps further down in the picker rows (owner: "make the $ sign
   smaller") — the digits lead. font-weight restated because the no-faux-bold
   block below pins bare .cw-cur to 400 for the Archivo Black card price. */
.cw-opt-p .cw-cur{font-size:.6em;font-weight:600!important}

/* The currency mark on prices this theme prints itself (cw_money_html /
   moneyHtml). A size down so the figure leads.       [cw.css 3040] */
.cw-cur{font-size:.6em;font-weight:inherit;margin-right:.02em}

/* ============================================================
   NO FAUX BOLD ON THE MONEY FACE            [cw.css 3055-3072]
   Archivo Black registers as weight 400 (its blackness is the
   design, not the weight) — synthesized bold would smear it.
   RE-TARGETED: selector list trimmed to the grid-card elements
   this port actually sets in the money face; CW's list also named
   the deal tickets, header chip, mini cart and PDP ladder
   (unported).
   ============================================================ */
/* Selector list re-trimmed 2026-08-18: the picker roles (.cw-opt-l .w/.pg,
   .cw-opt-p .now, .cw-szbtn .szlbl) left the money face for Figtree 600 and
   must not be pinned to 400 here. Bare .cw-cur stays — the card price's $. */
/* Weight 600 since the money face became Figtree (2026-08-18); the block
   still exists to stop synthesis and keep every money figure on one weight. */
.cw-price,.cw-price .now,.cw-price .cw-cur,
.cw-cur{font-weight:600!important;font-synthesis:none;font-synthesis-weight:none}

/* Only the closed size button, which never holds anything but a size
   or the word SELECT.                                [cw.css 3085] */
.cw-szbtn .szlbl{white-space:nowrap}

/* ============================================================
   SIZE ROWS KEEP THEIR PRICE ON ONE LINE    [cw.css 3099-3104]
   .is-size is set server-side on rows whose label is a weight.
   ============================================================ */
@media (max-width:768px){
  .cw-opt.is-size{flex-wrap:nowrap;gap:0 10px}
  .cw-opt.is-size .cw-opt-l{flex:1 1 auto;padding-right:0;min-width:0}
  .cw-opt.is-size .cw-opt-p{flex:0 0 auto;display:flex;flex-wrap:wrap;
    justify-content:flex-end;align-items:baseline;text-align:right;gap:2px 7px}
}

/* ============================================================
   SALE ROWS IN THE DROPDOWN, PHONES         [cw.css 3118-3123]
   ============================================================ */
@media (max-width:768px){
  .cw-opt.is-size .cw-opt-p{max-width:64%}
  .cw-opt.is-size .cw-opt-p .sv{flex:0 0 100%;text-align:right;margin-top:2px}
  .cw-opt.is-size .cw-opt-l{flex:0 1 auto}
}

/* ============================================================
   THE $ IN A STRUCK PRICE KEEPS FULL SIZE   [cw.css 3136-3143]
   RE-TARGETED: CW's list also named .cw-vl-* (PDP ladder) and the
   sidebar deal tickets — unported, trimmed. The generic del/s +
   .woocommerce-Price-currencySymbol pairs are kept: .cw-cur only
   exists in our markup, and with the .68em shrink rule dropped the
   Woo-symbol halves are inert no-ops on Porto (harmless if a later
   phase restores the shrink).
   ============================================================ */
del .cw-cur, del .woocommerce-Price-currencySymbol,
s .cw-cur, s .woocommerce-Price-currencySymbol,
.cw-opt-p .reg .cw-cur, .cw-opt-p .reg .woocommerce-Price-currencySymbol,
.cw-salerow .was .cw-cur, .cw-salerow .was .woocommerce-Price-currencySymbol{font-size:inherit!important;
  vertical-align:baseline!important;margin-right:0!important}

/* ============================================================
   A SIZE NEVER BREAKS MID-WORD              [cw.css 3158-3164]
   ============================================================ */
.cw-opt.is-size .cw-opt-l .w{overflow-wrap:normal!important;word-break:normal!important;
  hyphens:none!important}
.cw-opt-p{gap:2px 4px}
@media (max-width:768px){
  .cw-opt.is-size .cw-opt-p{gap:2px 4px;max-width:72%}
  .cw-opt.is-size .cw-opt-l{flex:0 0 auto}
}

/* ============================================================
   SALE ROW: PRICE ON TOP (flex pass)        [cw.css 3178-3186]
   Superseded by the grid pass below, kept in source order so the
   computed styles match CW exactly.
   ============================================================ */
.cw-opt-p{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:flex-end;
  gap:1px 6px;text-align:right}
.cw-opt-p .now{order:1;flex:0 0 100%;text-align:right}
.cw-opt-p .reg{order:2}
.cw-opt-p .sv{order:3}
@media (max-width:768px){
  .cw-opt.is-size .cw-opt-p{max-width:none;gap:1px 6px}
  .cw-opt.is-size .cw-opt-p .sv{flex:0 0 auto;margin-top:0}
}

/* ============================================================
   SIZE-ROW PRICE CELL — FINAL LAYOUT        [cw.css 3220-3239]
   Two-column grid: price spans row 1, was + saving share row 2.
   ============================================================ */
.cw-opt-p{display:grid!important;grid-template-columns:auto auto;justify-content:end;
  align-items:baseline;gap:1px 6px;text-align:right;max-width:none!important;flex:0 0 auto!important}
.cw-opt-p .now{grid-column:1 / -1;justify-self:end;order:0}
.cw-opt-p .reg{grid-column:1;justify-self:end;order:0}
.cw-opt-p .sv{grid-column:2;justify-self:end;order:0;margin:0}

@media (max-width:768px){
  .cw-opt.is-size .cw-opt-p{max-width:none!important}
  /* The saving is the first thing that may go — never the price. */
  .cw-opt-p .sv{white-space:nowrap}
}

/* Explicit rows, independent of markup order. */
.cw-opt-p .now{grid-row:1;grid-column:1 / -1}
.cw-opt-p .reg{grid-row:2;grid-column:1}
.cw-opt-p .sv{grid-row:2;grid-column:2}

/* ============================================================
   NARROW CARDS: BUY BACK THE 11px           [cw.css 3251-3268]
   ============================================================ */
@media (max-width:768px){
  .cw-dd .cw-opt{padding-left:8px;padding-right:8px;gap:0 6px}
  .cw-dd .cw-opt-p{gap:1px 5px}
  .cw-dd .cw-opt-p .sv{font-size:8.5px;padding:3px 4px;letter-spacing:.03em}
  .cw-dd .cw-opt-p .reg{font-size:10px}
  .cw-dd-hdr{padding-left:8px;padding-right:8px}
}
@media (max-width:768px){
  .cw-dd .cw-opt-p{grid-template-columns:auto}
  .cw-dd .cw-opt-p .now{grid-row:1;grid-column:1}
  .cw-dd .cw-opt-p .reg{grid-row:2;grid-column:1}
  .cw-dd .cw-opt-p .sv{grid-row:3;grid-column:1;justify-self:end}
}

/* ============================================================
   DROPDOWN SALE ROW = LADDER LAYOUT         [cw.css 3288-3306]
   ============================================================ */
@media (max-width:768px){
  .cw-dd .cw-opt-p{grid-template-columns:auto auto;gap:1px 3px}
  .cw-dd .cw-opt-p .now{grid-row:1;grid-column:1 / -1;justify-self:end}
  .cw-dd .cw-opt-p .reg{grid-row:2;grid-column:1;justify-self:end;
    font:600 9.5px/1 var(--cw-ui)!important;margin-right:0!important}
  .cw-dd .cw-opt-p .sv{grid-row:2;grid-column:2;justify-self:end;
    font:800 8px/1 var(--cw-ui)!important;letter-spacing:.01em!important;
    margin:0!important;padding:0!important;background:none!important;white-space:nowrap}
}
/* The size sits on the price's line, not between the two price lines. */
.cw-dd .cw-opt{align-items:baseline}
.cw-dd .cw-opt-l{align-self:baseline}

/* ############################################################
   ##  cw-shop.css EXTRACTS BEGIN — loaded after cw.css on CW,
   ##  same order preserved here.
   ############################################################ */

/* ============================================================
   ARCHIVE TOOLBAR + FILTER CHIPS       [cw-shop.css 19-29]
   Controls share one shape and one hairline; the only filled
   element in the row is the tier you are standing on.
   ============================================================ */
.cw-shoplayout .cw-chip{
  height:26px;display:inline-flex;align-items:center;padding:0 12px;
  border:1px solid var(--cw-line);border-radius:3px;background:var(--cw-card);
  color:var(--cw-ink);font:800 10.5px/1 var(--cw-ui);letter-spacing:.12em;text-transform:uppercase;
  text-decoration:none;transition:border-color .18s,background-color .18s,color .18s}
.cw-shoplayout .cw-chip:hover{border-color:var(--cw-accent);background:var(--cw-soft)}
.cw-shoplayout .cw-chip:focus-visible{outline:2px solid var(--cw-accent);outline-offset:2px}
.cw-shoplayout .cw-chip.on,
.cw-shoplayout .cw-chip.on:hover{
  background:var(--cw-accent);border-color:var(--cw-accent);color:var(--cw-accent-ink)}

/* --- sort control (closed <select>, pre-JS) [cw-shop.css 39-55] --- */
.cw-toolrow .cw-sortform{margin:0 0 0 auto;display:flex;align-items:center}
/* Porto prints a bare "Sort by:" <label> ahead of the icon dropdown; the icon
   is the whole control (owner, 2026-08-18: label off). */
.cw-toolrow .cw-sortform > label{display:none}
.cw-toolrow select.orderby{
  height:26px;width:auto;min-width:0;padding:0 29px 0 11px;
  border:1px solid var(--cw-line);border-radius:3px;
  background-color:var(--cw-card);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2377776f' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 9px center;background-size:11px 11px;
  color:var(--cw-ink);font:800 10.5px/24px var(--cw-ui);letter-spacing:.12em;text-transform:uppercase;
  cursor:pointer;box-shadow:none;-webkit-appearance:none;appearance:none;
  transition:border-color .18s,box-shadow .18s}
.cw-toolrow select.orderby:hover{border-color:var(--cw-accent)}
.cw-toolrow select.orderby:focus-visible{
  outline:none;border-color:var(--cw-accent);box-shadow:0 0 0 3px rgba(62,183,133,.25)}
.cw-toolrow select.orderby option{
  font:400 13px/1.4 var(--cw-ui);letter-spacing:0;text-transform:none;color:var(--cw-ink)}

/* --- product card: size picker hairline    [cw-shop.css 65-74] --- */
.cw-card .cw-szbtn{
  border:1px solid var(--cw-line);
  background-color:var(--cw-card);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2377776f' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 11px center;background-size:11px 11px;
  padding-right:30px;transition:border-color .18s}
.cw-card .cw-szbtn:hover{border-color:var(--cw-accent)}
.cw-card .cw-szbtn:focus-visible{outline:none;border-color:var(--cw-accent);box-shadow:0 0 0 3px rgba(62,183,133,.25)}
.cw-card .cw-szbtn > span:not(.szlbl){display:none}
.cw-card .cw-dd{border:1px solid var(--cw-line);box-shadow:0 6px 20px rgba(17,17,16,.12)}

/* ============================================================
   MOBILE GRID — overflow blowout guard  [cw-shop.css 98-103]
   min-width:auto on the flex/grid chain refuses to shrink and
   drags fr tracks off-screen; min-width:0 lets it collapse.
   ============================================================ */
.cw-shop{flex:1 1 auto;min-width:0}
.cw-shoplayout,
.cw-smain{min-width:0}
.cw-shoplayout ul.products.cw-grid > li,
.cw-shoplayout .cw-card{min-width:0}
.cw-shoplayout .cw-card img{max-width:100%}
/* --- one gutter, shared with the rest of the page [cw-shop.css 112-117] --- */
.cw-shoplayout{padding-inline:16px}
.cw-shoplayout .cw-crumb,
.cw-shoplayout .cw-toolrow{padding-inline:0}
@media (min-width:768px){
  .cw-shoplayout{padding-inline:40px}
}

/* ============================================================
   TOOLBAR ON PHONES                    [cw-shop.css 409-418]
   Chips get their own full-width line underneath.
   ============================================================ */
@media (max-width:768px){
  .cw-toolrow{flex-wrap:wrap;row-gap:10px}
  .cw-toolrow .cw-filterbtn{order:1;flex:0 0 auto}
  .cw-toolrow .cw-sortform{order:2;margin-left:auto;flex:0 1 auto;min-width:0}
  .cw-toolrow .cw-sortform select.orderby{max-width:100%}
  .cw-toolrow .cw-filters{order:3;flex:1 0 100%;
    margin-inline:-16px;padding-inline:16px;
    scroll-padding-inline:16px;overscroll-behavior-x:contain}
}

/* ============================================================
   SORT AS A LISTBOX                    [cw-shop.css 427-465]
   The <select> stays underneath as the submitted value and the
   accessible one; wdk-shop.js draws .cw-sortpick over it.
   ============================================================ */
.cw-sortform select.orderby{position:absolute!important;width:1px;height:1px;
  padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.cw-sortpick{position:relative}
.cw-sortbtn{display:flex;align-items:center;justify-content:space-between;gap:10px;
  min-width:210px;background:var(--cw-card);border:1.5px solid var(--cw-line);
  border-radius:4px;padding:9px 12px;cursor:pointer;
  font:700 11.5px/1 var(--cw-ui);letter-spacing:.07em;text-transform:uppercase;
  color:var(--cw-ink);transition:border-color .15s}
.cw-sortbtn:hover{border-color:var(--cw-accent)}
.cw-sortbtn:focus-visible{outline:2.5px solid var(--cw-accent);outline-offset:2px}
.cw-sortbtn .chev{width:7px;height:7px;flex:none;
  border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;
  transform:translateY(-2px) rotate(45deg);transition:transform .18s ease-out}
.cw-sortpick.open .cw-sortbtn{border-color:var(--cw-ink)}
.cw-sortpick.open .cw-sortbtn .chev{transform:translateY(1px) rotate(-135deg)}

.cw-sortdd{position:absolute;right:0;top:calc(100% + 6px);min-width:100%;
  background:var(--cw-card);border:1.5px solid var(--cw-ink);border-radius:6px;
  box-shadow:0 14px 34px rgba(17,17,16,.22);overflow:hidden;display:none;z-index:60}
.cw-sortpick.open .cw-sortdd{display:block}
.cw-sortopt{display:block;width:100%;text-align:left;background:none;border:0;
  border-bottom:1px solid var(--cw-line);padding:11px 14px;cursor:pointer;
  font:600 12.5px/1.3 var(--cw-ui);color:var(--cw-ink);white-space:nowrap}
.cw-sortopt:last-child{border-bottom:0}
.cw-sortopt:hover{background:var(--cw-soft)}
.cw-sortopt.sel{background:var(--cw-soft);color:var(--cw-deep);font-weight:800}
.cw-sortopt:focus-visible{outline:2.5px solid var(--cw-accent);outline-offset:-3px}

@media (max-width:768px){
  .cw-toolrow .cw-sortform{flex:1 1 auto;min-width:0}
  .cw-sortpick{width:100%}
  .cw-sortbtn{min-width:0;width:100%}
  .cw-sortdd{left:0;right:0;width:auto;min-width:0}
  .cw-sortopt{white-space:normal}
}

/* ============================================================
   TOOLBAR ORDER + HAIRLINES            [cw-shop.css 473-497]
   ============================================================ */
.cw-toolrow{align-items:center}
.cw-toolrow .cw-filters{order:1;flex:1 1 auto;min-width:0}
.cw-toolrow .cw-sortform{order:2;margin-left:auto;flex:0 0 auto}
.cw-toolrow .cw-filterbtn{order:3;flex:0 0 auto}

/* Hairlines, not outlines. */
.cw-chip{border-color:var(--cw-line)!important}
.cw-chip:hover{border-color:var(--cw-ink)!important}
.cw-chip.on{border-color:var(--cw-ink)!important}
.cw-filterbtn{border-color:var(--cw-line)!important}
.cw-filterbtn:hover{border-color:var(--cw-ink)!important}
.cw-sortform select.orderby,
.cw-sortbtn{border-color:var(--cw-line)!important}
.cw-sortbtn:hover,
.cw-sortpick.open .cw-sortbtn{border-color:var(--cw-ink)!important}
.cw-sortdd{border-color:var(--cw-ink)!important}

@media (max-width:768px){
  .cw-toolrow .cw-sortform{order:1;margin-left:0;flex:1 1 auto;min-width:0}
  .cw-toolrow .cw-filterbtn{order:2;margin-left:auto}
  .cw-toolrow .cw-filters{order:3;flex:1 0 100%}
}

/* ============================================================
   SORTING: RIGHT, NARROWER, NO INK EDGE [cw-shop.css 506-536]
   ============================================================ */
.cw-toolrow .cw-filters{order:1;flex:1 1 auto;min-width:0}
.cw-toolrow .cw-filterbtn{order:2!important;margin-left:0!important}
.cw-toolrow .cw-sortform{order:3!important;margin-left:auto!important;flex:0 0 auto!important}

.cw-sortbtn{min-width:150px}

.cw-sortbtn{background:var(--cw-card)!important}
.cw-sortpick.open .cw-sortbtn{border-color:var(--cw-accent)!important;
  background:var(--cw-card)!important}
.cw-sortdd{border:1px solid var(--cw-line)!important;
  box-shadow:0 16px 36px rgba(17,17,16,.16)!important}
.cw-sortopt.sel{color:var(--cw-deep)}

@media (max-width:768px){
  .cw-toolrow .cw-filterbtn{order:1!important}
  .cw-toolrow .cw-sortform{order:2!important;flex:0 0 164px!important;width:164px!important;max-width:164px}
  .cw-toolrow .cw-filters{order:3;flex:1 0 100%}
  .cw-sortbtn{min-width:0;width:100%}
  .cw-sortdd{left:auto;right:0;width:max-content;min-width:100%;max-width:78vw}
  .cw-sortopt{white-space:nowrap}
}

/* ============================================================
   SORT AS AN ICON                      [cw-shop.css 544-569]
   Square icon button; the words live in the panel it opens.
   ============================================================ */
.cw-toolrow .cw-sortform{flex:0 0 auto!important;width:auto!important;max-width:none!important}
.cw-sortbtn.is-icon{min-width:0;width:40px;height:40px;padding:0;
  display:inline-flex;align-items:center;justify-content:center;gap:0;
  border:1.5px solid var(--cw-line);border-radius:4px;background:var(--cw-card);
  color:var(--cw-ink);cursor:pointer;transition:border-color .15s,color .15s}
.cw-sortbtn.is-icon svg{width:19px;height:19px;display:block}
.cw-sortbtn.is-icon .lbl,
.cw-sortbtn.is-icon .chev{position:absolute;width:1px;height:1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap}
.cw-sortbtn.is-icon:hover{border-color:var(--cw-ink)}
.cw-sortpick.open .cw-sortbtn.is-icon{border-color:var(--cw-accent);color:var(--cw-deep)}
/* An applied sort has to remain visible once the label is gone. */
.cw-sortpick.is-set .cw-sortbtn.is-icon{border-color:var(--cw-accent);color:var(--cw-deep)}
.cw-sortpick.is-set .cw-sortbtn.is-icon::after{content:"";position:absolute;top:-3px;right:-3px;
  width:8px;height:8px;border-radius:50%;background:var(--cw-accent);
  border:2px solid var(--cw-paper)}
.cw-sortpick{position:relative;display:inline-block}

.cw-sortdd{left:auto;right:0;min-width:210px;width:max-content;max-width:min(80vw,280px)}
.cw-sortopt{white-space:nowrap}

@media (max-width:768px){
  .cw-toolrow .cw-sortform{flex:0 0 auto!important;width:auto!important;max-width:none!important}
  .cw-sortbtn.is-icon{width:38px;height:38px}
}

/* ============================================================
   CARD HOVER PHOTO                     [cw-shop.css 614-628]
   .has-alt is set server-side; hover:hover only, so a tap never
   latches the second shot on a touch screen.
   ============================================================ */
.cw-imgw.has-alt img.cw-img-alt{position:absolute;inset:0;z-index:1;opacity:0;
  transition:opacity .35s ease}
@media (hover:hover){
  .cw-imgw.has-alt:hover img.cw-img-alt{opacity:1}
}
@media (prefers-reduced-motion:reduce){
  .cw-imgw.has-alt img.cw-img-alt{transition:none}
}
/* Sold-out cards pin every img to .62 opacity; restate the swap at
   that weight so the treatment and the hover coexist. */
.cw-card.outofstock .cw-imgw.has-alt img.cw-img-alt{opacity:0}
@media (hover:hover){
  .cw-card.outofstock .cw-imgw.has-alt:hover img.cw-img-alt{opacity:.72}
}

/* ============================================================
   MOBILE SHOP HEAD                     [cw-shop.css 646-689]
   One row: title left, FILTER + sort right, count as subtitle.

   ROW NUMBERING DIVERGES FROM CW — head rows are 1/2/3, not
   2/3/4. CW reserves row 1 for .cw-bc (its SEO breadcrumb);
   cw_seo_breadcrumb() is not ported here, so on WDK that row
   stayed EMPTY — and the auto-placed product grid slotted into
   the hole, rendering the whole head (title, FILTER, count,
   chips) BELOW the products (owner, 2026-08-18: "on mobile all
   the title and filters seem to appear at the bottom of the
   page"). With the head packed from row 1 the first free row is
   below it, which is where the grid and pagination auto-place.
   If the breadcrumb is ever ported, give it grid-row:1 and shift
   these back down.
   ============================================================ */
@media (max-width:768px){
  .cw-shop .cw-smain{
    display:grid;grid-template-columns:minmax(0,1fr) auto auto;
    column-gap:8px;align-items:center;
  }
  .cw-shop .cw-smain > *{grid-column:1/-1;min-width:0}
  .cw-shop .cw-smain > .cw-crumb,
  .cw-shop .cw-smain > .cw-toolrow{display:contents}

  /* row 1 — title and the two controls */
  .cw-shop .cw-smain .cw-crumb h1{
    grid-column:1;grid-row:1;justify-self:start;align-self:center;
    min-width:0;margin:14px 0 0;
    /* Stepped down from CW's clamp(19px,5.4vw,25px) for Archivo Black. */
    font-size:clamp(17px,5vw,23px);line-height:1.02;
    overflow-wrap:anywhere;
  }
  .cw-shop .cw-smain .cw-toolrow .cw-filterbtn{
    grid-column:2;grid-row:1;order:0!important;margin:14px 0 0!important;
    white-space:nowrap;padding:7px 11px!important;
  }
  .cw-shop .cw-smain .cw-toolrow .cw-sortform{
    grid-column:3;grid-row:1;order:0!important;margin:14px 0 0!important;
    flex:0 0 132px!important;width:132px!important;max-width:132px!important;
    min-width:0;
  }
  .cw-shop .cw-smain .cw-toolrow .cw-sortform .cw-sortbtn{
    width:100%;min-width:0;padding-inline:10px;
  }

  /* row 2 — the count, now the title's subtitle */
  .cw-shop .cw-smain .cw-crumb .cw-count{
    grid-column:1/-1;grid-row:2;justify-self:start;margin:5px 0 0;
  }

  /* row 3 — the chip scroller, unchanged in behaviour */
  .cw-shop .cw-smain .cw-toolrow .cw-filters{
    grid-column:1/-1;grid-row:3;margin-top:12px;flex:1 1 auto;
  }
}

/* ============================================================
   MOBILE CATEGORY HEAD — TIGHTEN       [cw-shop.css 715-728]
   Sort control back to its natural icon width; air between the
   chip scroller and the first card row. The !important on the
   grid margin was armour against a Woodmart archive rule — kept,
   harmless under Porto and future-proof against theme resets.
   ============================================================ */
@media (max-width:768px){
  .cw-shop .cw-smain .cw-toolrow .cw-sortform{
    flex:0 0 auto!important;width:auto!important;max-width:none!important;
  }
  .cw-shop .cw-smain .cw-toolrow .cw-sortform .cw-sortbtn,
  .cw-shop .cw-smain .cw-toolrow .cw-sortform .cw-sortbtn.is-icon{
    width:42px;min-width:0;height:42px;padding:0;
  }

  .cw-shop .cw-smain > ul.products.cw-grid{margin-top:18px!important}
}

/* ############################################################
   ##  PORTO ADAPTATION LAYER — NEW CODE, THIS PORT ONLY.
   ##  Nothing below exists in the CW source. wdk_ conventions
   ##  do not apply to CSS classes (we style Porto's/YITH's own
   ##  markup here), so blocks are labelled WDK-A* / WDK-B*.
   ############################################################ */

/* ============================================================
   WDK-A1 — PHASE A GRID TAKEOVER
   The Elementor Pro archive loop UL is
   'products elementor-grid products-container grid has-ccols
    has-ccols-spacing ccols-xl-4 ...'. Two grid systems compete on
   it (Elementor's .elementor-grid CSS grid and Porto's ccols
   flex/width classes) and we control neither stylesheet, so the
   UL's layout is taken over outright: our own CSS grid, CW's
   column rhythm (2 phone / 3 tablet / 4 desktop — Phase A stops
   at 4; CW's 5-at-1200 is keyed to .cw-grid and only returns
   with Phase B).
   :has() guards the takeover to ULs that actually hold our cards;
   a :has-less browser keeps Elementor's grid-4/3/2, which is an
   acceptable fallback since the li resets below still apply.
   ============================================================ */
ul.products.elementor-grid:has(> li.cw-card){
  display:grid!important;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:12px;margin:0;padding:0;list-style:none;width:100%}
@media (min-width:768px){
  ul.products.elementor-grid:has(> li.cw-card){
    grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}
}
@media (min-width:1025px){
  ul.products.elementor-grid:has(> li.cw-card){
    grid-template-columns:repeat(4,minmax(0,1fr))}
}

/* ============================================================
   WDK-A2 — LI NEUTRALIZATION
   The li carries 'product-col' (Porto's ccols system sizes off
   it: percentage widths + gutter padding) plus whatever Porto
   filters onto post_class. Under our grid the track sizes the
   item, so every Porto sizing/spacing/skin hook is flattened.
   Porto centres loop items and floats some skins — reset both.
   Unscoped li.cw-card so the same armour holds in Phase B.
   ============================================================ */
ul.products.elementor-grid > li.cw-card{
  width:auto!important;max-width:none!important;flex:none!important;
  padding:0!important;margin:0!important}
li.cw-card{min-width:0;text-align:start;float:none;position:relative}
li.cw-card::before,
li.cw-card::after{content:none!important}
.cw-card img{max-width:100%}

/* ============================================================
   WDK-A3 — THUMBNAIL-FILTER LEFTOVERS (YITH badges etc.)
   woocommerce_get_product_thumbnail() output arrives filtered:
   YITH Badge Management wraps the img in div.container-image-and-
   badge and injects its SVG badge INSIDE our .cw-imgw link. The
   CW grid carries no plugin badges by design (the NEW / SOLD OUT
   stamps are the card's own), so the badge is hidden and the
   wrapper is made a transparent full-bleed box so the img keeps
   filling the photo well. Wishlist/quickview cover the case of a
   plugin filtering markup into the thumbnail HTML — CW cards
   never show them.
   ============================================================ */
.cw-card .yith-wcbm-badge{display:none!important}
.cw-imgw .container-image-and-badge{display:block;width:100%;height:100%}
.cw-imgw .container-image-and-badge img{width:100%;height:100%;object-fit:cover}
.cw-card .yith-wcwl-add-to-wishlist,
.cw-card .add-to-wishlist,
.cw-card .quickview,
.cw-card .porto-quickview{display:none!important}

/* ============================================================
   WDK-B1 — PHASE B UNDER PORTO'S SHELL
   archive-product.php fires woocommerce_before/after_main_content
   so .cw-shop renders inside Porto's #main > .container > .row >
   .main-content. Two consequences:
   - .cw-shop is a child of a Bootstrap-style column; the CW rule
     .cw-shop{flex:1 1 auto;min-width:0} (kept above) already
     handles the flex-child case.
   - Porto's .container caps the page (~1170px by default), well
     under CW's 1610px shoplayout. v1 accepts the narrower grid;
     widening is a Porto theme-option/Elementor decision, not CSS
     forced full-bleed (see NOTES-css.md risks).
   The pieces below are the only genuinely needed shims.
   ============================================================ */
/* Porto wraps archive pages in its own padding; keep the cw body
   from double-guttering inside the drawn container. */
.main-content > .cw-shop{margin-inline:0}
/* Numbered paging replaces CW's endless grid (that JS is not
   ported). woocommerce_pagination() emits nav.woocommerce-
   pagination > ul.page-numbers inside div.cw-pagination — make
   sure a Porto nav skin doesn't re-margin it. */
.cw-pagination .woocommerce-pagination{margin:0;padding:0;text-align:left}
/* Porto styles .page-numbers globally; CW's own pagination rules
   (see SHOP ARCHIVE block) win on specificity for the boxes, this
   clears list-level leftovers. */
.cw-pagination ul.page-numbers{border:0;background:none}
/* The drawer + scrim must clear Porto's sticky header (Porto uses
   four-digit z-indexes on .sticky-header). CW's 1001/1000 pair is
   kept upstream for diffability; this lifts both above Porto —
   but ONLY at drawer widths: at >=1025px the rail is in-flow with
   a deliberate z-index:1, and an unscoped lift here would land
   after that media rule in the cascade and paint the rail over
   open card dropdowns (z-index 30/31) in the first column. */
@media (max-width:1024px){
  .cw-side{z-index:10001}
  .cw-scrim{z-index:10000}
}

/* ---- auto-loading archives (see the tail of wdk-shop.js) ----------------
   The pagination stays in the DOM for crawlers and no-JS visitors; it is only
   hidden once the observer is actually running. */
body.wdk-autoload .cw-pagination{display:none}
.wdk-autoload-sentinel{height:1px}
/* Owner, 2026-08-18: the old greys (#8a8a84 / #a8a8a2) sank into the paper
   ground. Loading reads in ink; the end cap in jade text (5:1 on paper). */
.wdk-autoload-status{min-height:22px;text-align:center;padding:14px 0 2px;
  font:800 11px/1 var(--cw-ui);letter-spacing:.14em;text-transform:uppercase;color:var(--cw-ink)}
.wdk-autoload-status.is-end{color:#177A52}

/* ============================================================
   PDP VARIATION LADDER (snippet 115 markup) — same Figtree voice
   and small $ as the cards (owner, 2026-08-18). The snippet's own
   CSS carries sizes/weights; family + symbol land here so all
   type decisions stay in the theme layer.
   ============================================================ */
.single-product .cw-vl-name,
.single-product .cw-vl-price,
.single-product .cw-vl-amt,.single-product .cw-vl-amt .amount,
.single-product .cw-vl-unit,
.single-product .cw-vl-total-retail,.single-product .cw-vl-total-retail .amount,
.single-product .cw-vl-total-amt,.single-product .cw-vl-total-amt .amount{
  font-family:'Figtree',var(--cw-ui)}
.single-product .cw-vl-amt,.single-product .cw-vl-amt .amount{font-weight:600}
.single-product .cw-vl-row .woocommerce-Price-currencySymbol,
.single-product .cw-vl-total-amt .woocommerce-Price-currencySymbol,
.single-product .cw-vl-total-retail .woocommerce-Price-currencySymbol{font-size:.6em}

/* ============================================================
   FULL-BLEED ARCHIVE GROUND (owner, 2026-08-19: "all the category
   pages have this thick white border on the top and sides and
   bottom").

   The paper ground (.cw-shop) sat inside Porto's column, so the
   page painted white for 16px either side, 20px above and 40px
   below it. The homepage sections bleed; these did not, and the
   mismatch is what reads as a border.

   Only the GROUND bleeds — .cw-shoplayout keeps its 1610px measure
   and its 16/40px inline padding, so the cards do not move. The
   vertical spacing is not deleted either, just moved INSIDE the
   ground: .main-content's 20/40 comes off and .cw-shop takes it,
   which keeps the rhythm identical and only changes what colour is
   behind it.

   The WDK-B1 block above deferred this as "a Porto theme-option
   decision" — the owner has now made it. Nothing here touches
   Porto's container: the bleed is the same
   `50% - var(--wdk-vw)/2` trick the homepage uses, and --wdk-vw
   (functions.php, inline in <head>) is the LAYOUT viewport, so it
   is exact with a scrollbar present and at fractional DPR.

   VERIFY BY PAINT, NOT BY RECT: getBoundingClientRect() reports a
   bleed as full-width even when an ancestor clips it away (that is
   what hid main.wdk-home's overflow-x:clip for hours on the
   homepage). Hit-test with elementFromPoint(1, y).
   ============================================================ */
body.archive .cw-shop,
body.post-type-archive-product .cw-shop,
body.woocommerce-shop .cw-shop,
body.search .cw-shop{
  /* +2px/-1px slack: --wdk-vw and the 50% both resolve fractionally at
     non-integer DPR, and the residue shows as a hairline of page background
     at one edge. The overhang is clipped by .page-wrapper. */
  width:calc(var(--wdk-vw,100vw) + 2px);
  margin-left:calc(50% - var(--wdk-vw,100vw) / 2 - 1px);
  padding-top:20px;
  padding-bottom:40px;
}
body.archive .main-content,
body.post-type-archive-product .main-content,
body.woocommerce-shop .main-content,
body.search .main-content{
  padding-top:0!important;
  padding-bottom:0!important;
}

/* ============================================================
   ROUND 25 (owner, 2026-08-19) — CARD FIXES
   ============================================================ */

/* --- 25a. the dropdown's price lines up to the LEFT on a sale row ----
   Owner: "the price doesnt line up to the left if there is a sale price;
   if there is only a reg price then it lines up to the left."

   Below 768px .cw-opt wraps and .cw-opt-l takes the whole first line, so
   .cw-opt-p drops to a line of its own. It is `flex:0 0 auto`, so that box
   SHRINK-WRAPS to its content — and its content is right-aligned inside it
   (justify-content:end + justify-self:end, the desktop price column). With
   only .now in it the box is exactly the price wide and the figure lands on
   the row's left edge; add .reg + .sv and the box grows to their width and
   the price slides right, ending up flush with nothing at all. Measured on
   the Cannalean card at 360px: label at x=38, "$40" at x=73.8.

   So: when the group is on its own line, align its content left like the
   reg-only rows already do. .is-size rows are excluded — they keep the
   nowrap "⅛ oz … $40" layout with the price against the right edge.
   Specificity: (0,4,0) beats the (0,3,0) .cw-dd rules above; desktop, where
   the group shares the row and belongs on the right, is untouched. */
@media (max-width:768px){
  .cw-dd .cw-opt:not(.is-size) .cw-opt-p{
    justify-content:start;justify-items:start;text-align:left;
  }
  .cw-dd .cw-opt:not(.is-size) .cw-opt-p .now,
  .cw-dd .cw-opt:not(.is-size) .cw-opt-p .reg,
  .cw-dd .cw-opt:not(.is-size) .cw-opt-p .sv{justify-self:start}
}

/* --- 25b. SOLD OUT stamp: one corner, not both -----------------------
   Owner: "sold out badge needs fixing on mobile."

   Round 21 moved the stamp to the card's left (`left:11px`) but the ≤768px
   block still carried the OLD `right:8px` and never cleared `left`. An
   absolutely positioned box with BOTH offsets and width:auto stretches from
   one to the other, so on a phone the stamp ran the full width of the photo
   — and rotate(-8deg) then pushed its corners past the card edge. Clear the
   offset the round-21 rule replaced. */
@media (max-width:768px){
  .cw-badge-oos{left:8px;right:auto}
}

/* ============================================================
   PER-PAGE "Show: 20" SELECT (owner, 2026-08-19: "remove this
   from category pages").

   Porto prints it from woocommerce/loop/pagination.php as
   form.woocommerce-viewing inside nav.woocommerce-pagination, on
   every shop/category archive. Hidden rather than unhooked: the
   form also carries the query-string passthrough inputs, and the
   template is the theme's, so a CSS rule survives a Porto update
   where a template override would not. Per-page stays at the
   theme default (20).
   ============================================================ */
.woocommerce-pagination form.woocommerce-viewing,
form.woocommerce-viewing{display:none!important}
