@charset "UTF-8";
/* ============================================================
   Buy Testosterone — theme.css
   Design system ported from the hims.com TRT landing page clone
   (see ~/projects/hims-clone). Same component/class names as the
   original MayoPills theme are kept so page markup didn't need to
   change — only the values (colors, type, shape) were replaced.
   ============================================================ */

/* ── Sofia Pro (self-hosted, matches hims.com) ────────────── */
@font-face{font-family:FontSofiaPro;src:url(../fonts/b8e48ac181eb5d44-s.p.woff2) format("woff2");font-display:swap;font-weight:400;font-style:normal}
@font-face{font-family:FontSofiaPro;src:url(../fonts/ac9e4cd5979b18c8-s.p.woff2) format("woff2");font-display:swap;font-weight:400;font-style:italic}
@font-face{font-family:FontSofiaPro;src:url(../fonts/6e157fee2afd6082-s.p.woff2) format("woff2");font-display:swap;font-weight:500;font-style:normal}
@font-face{font-family:FontSofiaPro;src:url(../fonts/6a3d0c7a81ca2e70-s.p.woff2) format("woff2");font-display:swap;font-weight:500;font-style:italic}
@font-face{font-family:FontSofiaPro;src:url(../fonts/01ff0e6b9f83af8b-s.p.woff2) format("woff2");font-display:swap;font-weight:600;font-style:normal}
@font-face{font-family:FontSofiaPro;src:url(../fonts/99a6e5efb8add4f5-s.p.woff2) format("woff2");font-display:swap;font-weight:600;font-style:italic}
@font-face{font-family:FontSofiaPro Fallback;src:local("Arial");ascent-override:97.75%;descent-override:26.98%;line-gap-override:24.85%;size-adjust:103.42%}

:root{
  /* Explicitly opt this site into a light-only color scheme. Without this,
     some mobile browsers (Android Chrome's "Dark theme for web contents",
     Samsung Internet's night mode, etc.) auto-invert/reinterpret pages that
     don't declare a scheme, which is why the site could look like it had a
     different color theme on mobile vs. desktop even though no CSS here is
     conditional on viewport - desktop browsers don't apply that heuristic. */
  color-scheme: light only;
  /* Primary (was sage green) → hims near-black */
  --sage:#141414;--sage-d:#000000;--sage-l:#3d3d3d;--sage-xl:#e8e8e6;
  /* Page background (was ivory) → hims warm off-white */
  --ivory:#faf8f4;--ivory-d:#f0eee8;
  /* Dark contrast (was forest green) → near-black */
  --forest:#121212;--forest-l:#1e1e1e;
  /* Accent (was gold) → hims warm cream/gold */
  --gold:#c9a24a;--gold-d:#a17f33;--gold-l:#e8d9a0;
  --text1:#1c1c1c;--text2:#424242;--text3:#8f8f8f;
  --border:rgba(0,0,0,.1);
  --r:20px;--r-lg:28px;--r-xl:36px;
  --shadow:0 1px 2px rgba(0,0,0,.02),0 12px 32px rgba(0,0,0,.05);
  --shadow-md:0 2px 4px rgba(0,0,0,.03),0 20px 48px rgba(0,0,0,.08);
  --shadow-sage:0 20px 48px rgba(0,0,0,.1);
  --shadow-gold:0 12px 32px rgba(201,162,74,.22);

  /* kept for markup compatibility; blur greatly reduced to match hims' flat look */
  --glass-bg:rgba(255,255,255,.9);
  --glass-border:rgba(0,0,0,.08);
  --glass-shadow:0 4px 24px rgba(0,0,0,.08);

  /* ── Vertical rhythm ──────────────────────────────────────
     ONE scale for every full-width band on the site, so a section
     never has to invent its own padding and no band is taller than
     its neighbour. Sections apply it symmetrically (see .bt-section
     below); anything that needs less space at one edge subtracts
     from the token rather than hard-coding a value.
       --sec-y       every content band, without exception
       --sec-y-sm    kept as an alias of --sec-y. There used to be
                     two scales — a full one and a compact one — and
                     which band got which was a judgement call that
                     drifted. They are now the same number, and the
                     alias is here so older markup and the rules that
                     still read it cannot fall out of step.
       --hero-y      NOT a section. The opening dark band on a page,
                     which is sized by its own content and has a
                     closing wave eating into its lower edge, so it
                     needs more room than a band between two others.
                     Only the four hero inners and the contact page's
                     overlap offset read this.
       --sec-head-gap  heading block → the content it introduces
     Mobile-first; the two overrides use the same 768/1024 break-
     points the rest of this file already uses. */
  --sec-y:28px;
  --sec-y-sm:var(--sec-y);
  --hero-y:30px;
  /* Always a little UNDER --sec-y. A band's heading has to feel attached to
     the content it introduces, so the gap inside the band must read as
     smaller than the gap separating the band from its neighbours. These are
     ~0.8 of --sec-y at each step, the same proportion the scale carried
     before --sec-y came down; left at the old 32/40/44 they were larger than
     the band padding at every breakpoint, which is what made the category
     band on the home page read as mis-spaced. */
  --sec-head-gap:22px;

  --font-base:FontSofiaPro,"FontSofiaPro Fallback",sans-serif;

  --fs-display:clamp(34px,5vw,54px);
  --fs-h1:clamp(28px,4vw,30px);
  --fs-h2:clamp(26px,4vw,26px);
  --fs-h3:clamp(20px,2vw,22px);
  --fs-h4:clamp(17px,1.2vw,19px);
  --fs-h5:16px;
  --fs-h6:13px;
  
  --fs-body:15px;          /* standard paragraph, site-wide */
  --fs-body-lg:clamp(15.5px,1.1vw,17px); /* hero / intro standfirst */
  --fs-ui:14px;            /* controls: buttons, fields, nav, table cells */
  --fs-small:13.5px;       /* supporting copy, captions, card text */
  --fs-xs:12px;            /* meta, fine print */
  --fs-label:11px;         /* eyebrows, uppercase labels, form labels */
  --fs-2xs:10px;           /* micro meta: date kickers, pills, badges */

  --lh-display:1.1;
  --lh-heading:1.15;       /* h1 / h2 */
  --lh-heading-sm:1.3;     /* h3 / h4 */
  --lh-heading-xs:1.4;     /* h5 / h6 */
  --lh-body:1.7;
  --lh-small:1.6;

  --fw-body:400;
  --fw-medium:500;
  --fw-semibold:600;
  --fw-heading:700;
  --fw-display:600;
  --fw-label:700;

  --ls-display:-.025em;
  --ls-heading:-.015em;
  --ls-heading-sm:-.01em;
  --ls-label:1.5px;

  --ink-heading:var(--forest);
  --ink-body:var(--text2);
  --ink-muted:var(--text3);

  /* Prose rhythm — used only inside .product-desc, so the
     global `*{margin:0}` reset still governs component headings and
     no existing layout gains a margin it did not have. */
  --prose-block-mb:1em;
  --prose-block-mt:1em;

  /* Editor tables (.product-desc table). Their own tokens, not --r/--r-lg:
     those are the 20-36px card radii, which on a data table read as a pill
     rather than a panel. Header is near-black rather than --forest so the
     table stays neutral against whichever band it lands in — product page,
     blog post or a page template's cream card. */
  --prose-table-radius:12px;
  --prose-table-bg:#fff;
  --prose-table-head-bg:#111;
  --prose-table-head-text:#fff;
  --prose-table-border:rgba(0,0,0,.12);

}
@media (min-width:768px){
  :root{--sec-y:36px;--hero-y:54px;--sec-head-gap:28px}
}
@media (min-width:1024px){
  :root{--sec-y:40px;--hero-y:56px;--sec-head-gap:32px}
}

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;font-family:var(--font-base)}
body{font-family:var(--font-base);font-size:var(--fs-body);font-weight:var(--fw-body);line-height:var(--lh-body);background:var(--ivory);color:var(--text1);min-height:100vh;overflow-x:hidden;-webkit-font-smoothing:antialiased}
img{max-width:100%;height:auto;display:block}

/* ═══════════════════════════════════════════════════════════════
   UNIVERSAL TYPOGRAPHY
   The single source of truth for text in this theme. tailwind.css
   loads BEFORE this file and its Preflight resets every heading to
   `font-size:inherit;font-weight:inherit`, which is why h1-h6 had no
   typography of their own and every section had to invent one. These
   rules restore the semantic elements, so from here on

       <h1>…</h1>  <h2>…</h2>  <h3>…</h3>  <p>…</p>

   are correctly styled with no class and no new CSS. A new section
   needs markup, not a font-size.

   Deliberately NOT set here: margins. The reset above zeroes every
   margin and dozens of components depend on that, so vertical spacing
   stays each block's own job (or the prose rules further down). Colour
   is set on headings only — paragraphs keep inheriting, because the
   theme paints body copy per surface (dark bands need white, cards
   need --text2) and forcing one ink would repaint half the site.
   ═══════════════════════════════════════════════════════════════ */
/* Weight splits at h3, which is how the theme already read before this
   block existed: page and section titles are bold (700 — .bt-section-title
   and every Woo `font-bold` page title), card and panel titles are
   semibold (600 — the drawer, promo, vision/mission and step titles). One
   rule instead of thirty, and the split is a token either way. */
h1,h2,h3,h4,h5,h6{
  font-family:var(--font-base);
  color:var(--ink-heading);
  line-height:var(--lh-heading-sm);
  letter-spacing:var(--ls-heading-sm);
  text-wrap:pretty;
}
h1,h2{font-weight:var(--fw-heading);line-height:var(--lh-heading);letter-spacing:var(--ls-heading)}
h3,h4,h5,h6{font-weight:var(--fw-semibold)}
h1{font-size:var(--fs-h1)}
h2{font-size:var(--fs-h2)}
h3{font-size:var(--fs-h3)}
h4{font-size:var(--fs-h4)}
h5{font-size:var(--fs-h5);line-height:var(--lh-heading-xs)}
h6{font-size:var(--fs-h6);line-height:var(--lh-heading-xs)}

/* Body text. font-size is inherited from <body> rather than re-declared
   so a context that legitimately shifts its measure (a compact card, the
   13.5px phone step in .product-desc) still governs the paragraphs
   inside it — one rule, no !important fights. */
p{line-height:var(--lh-body)}
/* Lists inherit the typography of whatever they sit in; these two lines
   only stop a list from picking up a different family or measure than
   the copy around it. Markers/indentation stay with the component. */
ul,ol{font-family:inherit;font-size:inherit}
li{line-height:var(--lh-body)}
small{font-size:var(--fs-small);line-height:var(--lh-small)}
strong,b{font-weight:var(--fw-heading)}
/* Form controls opt into the body face instead of the UA's own. */
input,select,textarea,button{font-family:inherit}

/* ─── Reusable type classes ───────────────────────────────────────
   For the cases semantic HTML cannot express: a <span> that must read
   as a heading, a heading that must sit a tier lower than its level
   (a card title that is legally an <h2>), or supporting copy that is
   not a paragraph. They carry the SAME tokens as the elements above,
   so using one can never introduce a size the scale does not have.
   Reach for these instead of writing a new font-size rule. */
/* The hero/display tier — the opening line of a page. Same modifier idea as
   .bt-section-title below: one type style, ink and layout vary. */
.typography-display{font-size:var(--fs-display);font-weight:var(--fw-display);line-height:var(--lh-display);letter-spacing:var(--ls-display);color:var(--ink-heading)}
.typography-display em{font-style:normal;color:var(--gold)}
.typography-display--invert{color:#fff}
.typography-display--invert em{color:var(--gold-l)}
.typography-h1{font-size:var(--fs-h1);font-weight:var(--fw-heading);line-height:var(--lh-heading);letter-spacing:var(--ls-heading);color:var(--ink-heading)}
/* .legal-title shares this rule rather than restating it: the clause
   headings on the legal pages (privacy, terms, returns, safe shopping) are
   real <h2>s — they are the page's sections — but at a clause size, not a
   page-section size. Sharing the selector means one size for all of them and
   nothing to keep in sync; the semantic name is there so an <h2> is never
   marked up with a class that reads "h3". */
.typography-h3,.legal-title{font-size:var(--fs-h3);font-weight:var(--fw-semibold);line-height:var(--lh-heading-sm);letter-spacing:var(--ls-heading-sm);color:var(--ink-heading)}
.typography-h4{font-size:var(--fs-h4);font-weight:var(--fw-semibold);line-height:var(--lh-heading-sm);letter-spacing:var(--ls-heading-sm);color:var(--ink-heading)}
.typography-h5{font-size:var(--fs-h5);font-weight:var(--fw-semibold);line-height:var(--lh-heading-xs);color:var(--ink-heading)}

.typography-body{font-size:var(--fs-body);font-weight:var(--fw-body);line-height:var(--lh-body)}
.typography-small{font-size:var(--fs-small);line-height:var(--lh-small)}
.typography-xs{font-size:var(--fs-xs);line-height:var(--lh-small)}
/* Uppercase label / eyebrow. .eyebrow (further down) is the same type
   with a flex row and an accent colour; this is the bare token set, for
   footer column heads, table heads and form labels. */
.typography-label{font-size:var(--fs-label);font-weight:var(--fw-label);letter-spacing:var(--ls-label);text-transform:uppercase;line-height:1.4}
.typography-muted{color:var(--ink-muted)}

::-webkit-scrollbar{width:4px;height:4px}
::-webkit-scrollbar-track{background:var(--ivory-d)}
::-webkit-scrollbar-thumb{background:var(--sage-l);border-radius:99px}
::selection{background:#d1cfca;color:var(--forest)}

/* ═══ GLASS (flattened to match hims' minimal surfaces) ═══ */
.glass{
  background:var(--glass-bg);
  backdrop-filter:blur(10px);
  -webkit-backdrop-filter:blur(10px);
  border:1px solid var(--glass-border);
  box-shadow:var(--glass-shadow);
}

/* Sheen / reflection (kept subtle) */
.sheen{position:relative;overflow:hidden}
.sheen::after{content:'';position:absolute;top:-50%;left:-60%;width:40%;height:200%;background:linear-gradient(105deg,transparent 40%,rgba(255,255,255,.12) 50%,transparent 60%);transform:skewX(-15deg);animation:sheen 5s ease-in-out infinite;pointer-events:none}
@keyframes sheen{0%,100%{left:-60%}50%{left:120%}}

/* ═══ BUTTONS (hims: flat pill, solid dark primary / bordered light secondary) ═══ */
.btn-sage{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:14px 28px;
  background:var(--sage);
  color:#fff;border:1px solid var(--sage);border-radius:9999px;
  font-size:var(--fs-ui);font-weight:var(--fw-semibold);cursor:pointer;
  font-family:inherit;text-decoration:none;line-height:1;white-space:nowrap;
  box-shadow:none;
  transition:all .2s ease-in-out;
  position:relative;overflow:hidden;
}
.btn-sage::after{content:none}
.btn-sage:hover{background:var(--sage-d);border-color:var(--sage-d);transform:translateY(-1px)}
.btn-sage:active{transform:translateY(0)}

.btn-gold{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:14px 28px;
  background:var(--gold);
  color:#1c1c1c;border:1px solid var(--gold);border-radius:9999px;
  font-size:var(--fs-ui);font-weight:var(--fw-semibold);cursor:pointer;
  font-family:inherit;text-decoration:none;line-height:1;white-space:nowrap;
  box-shadow:none;
  transition:all .2s ease-in-out;
  position:relative;overflow:hidden;
}
.btn-gold::after{content:none}
.btn-gold:hover{background:var(--gold-d);border-color:var(--gold-d);color:#fff;transform:translateY(-1px)}
.btn-gold:active{transform:translateY(0)}

.btn-outline{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:13px 26px;
  background:hsla(0,0%,100%,.4);
  color:var(--text1);border:1px solid rgba(0,0,0,.19);border-radius:9999px;
  font-size:var(--fs-ui);font-weight:var(--fw-semibold);cursor:pointer;
  font-family:inherit;text-decoration:none;line-height:1;white-space:nowrap;
  transition:all .2s ease-in-out;
  position:relative;overflow:hidden;
}
.btn-outline::after{content:none}
.btn-outline:hover{background:var(--sage);color:#fff;border-color:var(--sage);transform:translateY(-1px)}

/* ═══ SURFACES (borderless — replaces the old bordered-box "card") ═══ */
.card{
  background:#fff;border-radius:var(--r);
  border:none;box-shadow:var(--shadow);
  transition:transform .3s cubic-bezier(.22,.61,.36,1),box-shadow .3s ease;
}
.card-hover:hover{transform:translateY(-5px);box-shadow:var(--shadow-md)}

/* Product description card (woocommerce/single-product.php SECTION 4) now
   sits on a white band (bt-pdp-section--white), so the plain white .card
   would have no contrast; give it the theme's ivory surface instead.
   Scoped to the exact .product-desc.card combination so no other
   .product-desc use (blog posts, pages, FAQs) is affected. */
.product-desc.card{background:var(--ivory);border:1px solid var(--border)}

/* Eyebrow — the small uppercase kicker above a title. Type comes from the
   shared label tokens (identical to .typography-label); only the flex row
   and the accent ink are this component's own. */
.eyebrow{display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-label);font-weight:var(--fw-label);letter-spacing:var(--ls-label);text-transform:uppercase;line-height:1.4;color:var(--sage)}
/* .page-title is the hero/display tier, .section-title the h2 tier. Both
   predate the token scale and are now aliases of it, so anything still
   carrying them lands on the same sizes as .typography-display /
   the --fs-display / --fs-h2 tokens rather than on their own old values. */
.section-title{font-size:var(--fs-h2);font-weight:var(--fw-heading);line-height:var(--lh-heading);letter-spacing:var(--ls-heading);color:var(--ink-heading)}
.page-title{font-size:var(--fs-display);font-weight:var(--fw-display);line-height:var(--lh-display);letter-spacing:var(--ls-display);color:var(--ink-heading)}

/* ═══ FORM FIELDS ═══ */
.field{width:100%;padding:13px 16px;border:1px solid var(--border);border-radius:var(--r);font-family:inherit;font-size:var(--fs-ui);color:var(--text1);background:#fff;outline:none;transition:all .2s;-webkit-appearance:none}
.field:focus{border-color:var(--sage);box-shadow:0 0 0 3px rgba(0,0,0,.08)}
/* Form label — the label tier, with the field's own tighter tracking. */
.label{display:block;font-size:var(--fs-label);font-weight:var(--fw-semibold);color:var(--text2);margin-bottom:6px;letter-spacing:.6px;text-transform:uppercase}

/* ═══ BADGES ═══ */
.badge-sage{display:inline-flex;align-items:center;gap:5px;background:rgba(0,0,0,.05);color:var(--text1);border:1px solid rgba(0,0,0,.14);border-radius:50px;padding:4px 14px;font-size:var(--fs-label);font-weight:var(--fw-semibold);letter-spacing:.5px;text-transform:uppercase;line-height:1.4}
.badge-gold{display:inline-flex;align-items:center;gap:5px;background:rgba(201,162,74,.12);color:var(--gold-d);border:1px solid rgba(201,162,74,.3);border-radius:50px;padding:4px 14px;font-size:var(--fs-label);font-weight:var(--fw-semibold);line-height:1.4}

/* ═══ ANIMATIONS ═══ */
@keyframes fadeUp  {from{opacity:0;transform:translateY(30px)}to{opacity:1;transform:translateY(0)}}
@keyframes fadeIn  {from{opacity:0}to{opacity:1}}
@keyframes float   {0%,100%{transform:translateY(0) rotate(0deg)}33%{transform:translateY(-12px) rotate(1deg)}66%{transform:translateY(-6px) rotate(-1deg)}}
@keyframes blob    {0%,100%{border-radius:60% 40% 30% 70%/60% 30% 70% 40%}25%{border-radius:30% 60% 70% 40%/50% 60% 30% 60%}50%{border-radius:50% 50% 30% 70%/30% 50% 70% 50%}75%{border-radius:40% 60% 60% 40%/60% 40% 40% 60%}}
@keyframes shimmer {0%{background-position:200% center}100%{background-position:-200% center}}
@keyframes pulse-r {0%,100%{box-shadow:0 0 0 0 rgba(0,0,0,.16)}70%{box-shadow:0 0 0 10px rgba(0,0,0,0)}}
@keyframes spin    {from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
@keyframes morph   {0%,100%{border-radius:30% 70% 70% 30%/30% 30% 70% 70%}50%{border-radius:70% 30% 30% 70%/70% 70% 30% 30%}}
@keyframes count   {from{opacity:0;transform:scale(.8) translateY(10px)}to{opacity:1;transform:scale(1) translateY(0)}}
@keyframes glow    {0%,100%{filter:brightness(1)}50%{filter:brightness(1.1)}}

/* AOS scroll reveal */
[data-aos]{opacity:0;transform:translateY(28px);transition:opacity .7s cubic-bezier(.22,.61,.36,1),transform .7s cubic-bezier(.22,.61,.36,1)}
[data-aos].aos-in{opacity:1;transform:none}
[data-aos="zoom"]{transform:scale(.9)}
[data-aos="zoom"].aos-in{transform:scale(1)}
[data-aos="left"]{transform:translateX(-28px)}
[data-aos="left"].aos-in{transform:none}
[data-aos="right"]{transform:translateX(28px)}
[data-aos="right"].aos-in{transform:none}

/* Product card */
.product-card{transition:transform .3s cubic-bezier(.22,.61,.36,1),box-shadow .3s ease}
.product-card:hover{transform:translateY(-6px);box-shadow:var(--shadow-md)}

/* Round "Rx" disc on a product card, shown when any of the product's
   categories is flagged "Requires Prescription" (see Site_Core_Rx_Category).
   Deliberately the same gold disc as .pdp-gallery__rx on the single-product
   gallery, just smaller, so the badge reads as one thing across the site.

   It sits inside .product-thumb, which is position:relative in every card
   markup (woocommerce/content-product.php, the homepage Best Sellers strip in
   front-page.php and the plugin's [sc_product_shelf] cards), so this one rule
   positions it in all three. Top-RIGHT because the "Sale" badge already owns
   the top-left corner and the two can appear together.

   pointer-events:none keeps it from swallowing clicks on the card link. */
.product-card__rx{
  position:absolute;top:10px;right:10px;z-index:3;
  width:30px;height:30px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
  font-size:11px;font-weight:700;letter-spacing:.3px;line-height:1;
  background:rgba(201,162,74,.16);
  border:1px solid rgba(201,162,74,.38);
  color:var(--gold-d);
  pointer-events:none;
}
@media (min-width:640px){.product-card__rx{width:34px;height:34px;font-size:12px;top:12px;right:12px}}

/* Card details centred — category, name, price and the button — wherever a
   product card renders: the Shop and category archives, the homepage Best
   Sellers strip, the Product Collection / Hand-Picked Products blocks and the
   single-product related strips.

   Done here rather than in the templates because there are two card markups
   (woocommerce/content-product.php and the homepage strip in front-page.php)
   and this one rule covers both, so they cannot drift apart again.

   The selector is the text block that FOLLOWS the image box, which is what
   both cards have in common. It deliberately requires .product-thumb: the blog
   cards in home.php, category.php and front-page.php reuse the .product-card
   class purely for its hover lift and have no image box, so their left-aligned
   excerpts are untouched.

   justify-content on the child divs is for the price row, which is a flex row
   in both cards; on the non-flex children it simply does nothing. Nothing here
   sets a width, so no card changes size. */
.product-card .product-thumb ~ div{text-align:center}
.product-card .product-thumb ~ div > div{justify-content:center}

/* Product card thumbnail area.
   The image box is a fixed-height flex wrapper, NOT a ratio box. A ratio box
   (aspect-ratio:1/1 on a width:100% image) grows with the grid column - at 4
   columns that is a ~300px square, which made the image section dominate the
   card. A fixed height keeps the section compact and identical across every
   card in the grid, independent of column width, so nothing overflows as the
   column narrows. The height steps down on small screens where cards are
   narrower. */
/* flex-shrink:0 because several of these cards are flex columns (homepage
   Best Sellers, single-product related/upsell strips) - without it the box
   would compress whenever the text block below it runs tall. */
.product-thumb{
  position:relative;flex-shrink:0;
  display:flex;align-items:center;justify-content:center;
  height:150px;padding:14px;
}
@media (min-width:640px){.product-thumb{height:190px;padding:18px}}
@media (min-width:1280px){.product-thumb{height:220px;padding:20px}}

/* The image is sized by its own proportions and simply bounded by the box:
   max-width/max-height cap it, width/height:auto keep the original aspect
   ratio, so it is never cropped and never stretched. object-fit:contain is a
   safety net for any image whose intrinsic ratio is overridden elsewhere. */
.product-thumb-img{
  display:block;margin:0 auto;
  width:auto;height:auto;max-width:82%;max-height:100%;
  object-fit:contain;object-position:center;
}

/* No product image: fills the same box so the grid stays aligned. */
.product-thumb-empty{
  display:flex;align-items:center;justify-content:center;
  width:100%;height:100%;border-radius:calc(var(--r) / 2);
  background:var(--ivory-d);color:var(--text3);
}

/* ── Catalogue card image box: full-bleed 1:1 ────────────────────────
   Scoped to the two shop-style card CONTAINERS rather than to
   .product-thumb globally, which is what keeps this to the catalogue:
     .shop-grid     - the Shop archive, every product-category archive,
                      the single-product "You May Also Like" / "Related
                      Products" rows of 4 cards or fewer, the Product
                      Collection / Hand-Picked Products blocks and the
                      out-of-stock dialog's suggestions.
     .product-shelf - those same related/upsell rows when there are more
                      than 4 cards and the row scrolls.
     .grid-products - the homepage "Best Selling Medicines" strip. It
                      renders the same content-product.php as the rest
                      (front-page.php), it just keeps its own 2-up/4-up
                      grid, so it needs naming here purely because the
                      container differs.
   That is every container on the site that prints a shop-style product
   card, which is the point: the scope is still the catalogue card rather
   than .product-thumb globally, but no surface is left behind on the old
   box the way the homepage was.

   For those containers this REPLACES that padded fixed-height box. It
   was a flex wrapper 150/190/220px tall with 14-20px of padding and an
   image capped at max-width:82%/max-height:100% - so in a 3-column grid
   the box was far wider than it was tall and the image sat small in the
   middle with ivory card ground down both sides. Now the box is a ratio
   box: full card width, square, no padding, image cropped to fill, so
   there is no margin on any side at any column width.

   The square comes from the card, not from the files - the catalogue's
   product shots run from 500x500 to 1962x802 - so object-fit:cover
   crops the overflowing axis on the wide ones.

   border-radius is the CARD's --r on the top two corners, not the old
   placeholder's calc(--r / 2): now that the box is flush with the card
   edge a smaller radius would leave a white sliver in each top corner,
   and any bottom radius would notch the image where it meets the text
   block. .product-card is already overflow:hidden, so this only makes
   that clip explicit.

   line-height:0 removes the inline descender gap under the image.
   position:relative and flex-shrink:0 still come from the global rule
   above - the Rx disc stays absolutely positioned in the top-right
   corner over the image, and the box still refuses to compress inside
   the cards that are flex columns. */
.shop-grid .product-thumb,
.product-shelf .product-thumb,
.grid-products .product-thumb{
  display:block;line-height:0;
  width:100%;height:auto;aspect-ratio:1 / 1;
  padding:0;overflow:hidden;
  border-radius:var(--r) var(--r) 0 0;
}

/* These two selectors are 0,2,0, so they beat the global
   .product-thumb-img rule above (0,1,0), its max-width:82% /
   max-height:100% / width:auto included, as well as the
   img{max-width:100%;height:auto;display:block} reset at the top of
   this file. Nothing here needs !important.

   width/height:100% is what fills the box; the aspect-ratio after it is
   a fallback only - it applies solely if height:100% fails to resolve
   against the ratio box, in which case the image still comes out square
   rather than at its own proportions. */
.shop-grid .product-thumb-img,
.product-shelf .product-thumb-img,
.grid-products .product-thumb-img{
  display:block;
  width:100%;height:100%;aspect-ratio:1 / 1;
  max-width:none;max-height:none;min-width:0;
  margin:0;padding:0;
  object-fit:cover;object-position:center;
}

/* Products with no image: same ivory box and pill glyph as before, now
   the same square as a real thumbnail, so a card with a picture and a
   card without one are exactly the same height in the same row.
   border-radius:inherit so the placeholder follows the two top corners
   above instead of rounding all four, and line-height:1 restores normal
   line box height for the glyph inside the line-height:0 wrapper. */
.shop-grid .product-thumb-empty,
.product-shelf .product-thumb-empty,
.grid-products .product-thumb-empty{
  aspect-ratio:1 / 1;
  border-radius:inherit;
  line-height:1;
}

/* Product card title (woocommerce/content-product.php). Names wrap onto up
   to 2 lines with an end ellipsis rather than scrolling as a marquee - see
   the note this replaced in woocommerce/archive-product.php history: a
   translating marquee left names looking truncated at the START on load /
   in screenshots, since it was mid-scroll at almost any given moment.
   Global (not scoped to the shop template) so the Shop archive, homepage
   product strips AND any Product Collection / Hand-Picked Products block
   (rendered through this same content-product.php - see functions.php)
   all render product names identically. */
.marquee-wrap{overflow:hidden;width:100%;min-width:0}
.marquee-inner{display:block;width:100%;min-width:0}
/* ONE line, always, with a trailing ellipsis on anything longer. This used to
   be a 2-line -webkit-box clamp, which meant a card's height depended on how
   long its product name happened to be and the price/button rows below it sat
   at different heights across a row. white-space:nowrap + text-overflow rather
   than -webkit-line-clamp:1 because it is the plain, fully supported way to do
   a single line — no vendor box model involved — and it gives the same "…".
   min-width:0 so the name still truncates instead of forcing the card wider
   when the card is a flex item (the homepage strips and related rows). */
.marquee-text{
  font-family:var(--font-base);font-size:var(--fs-ui);font-weight:var(--fw-semibold);
  color:var(--forest);line-height:1.3;
  display:block;min-width:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}

/* The Shop archive's product grid - also reused wherever else this theme
   renders a plain (non-scrolling) row of shop-style product cards. */
.shop-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}
@media (min-width:640px){.shop-grid{grid-template-columns:repeat(3,1fr)}}
@media (min-width:1280px){.shop-grid{grid-template-columns:repeat(4,1fr)}}

/* ═══ SHOP SORT ═══
   The "Sort by: Featured" control above the product grid
   (woocommerce/archive-product.php + assets/js/shop-sort.js).

   A native <select>'s OPEN dropdown is drawn by the operating system, not the
   page: its font, row height, padding and highlight colour are completely
   outside CSS's reach, which is why the open list read as a stray system menu.
   So the closed control is styled here and the open list is a real listbox that
   shop-sort.js builds — same colours, same radius, same type scale as the rest
   of the shop.

   Two states, and they never overlap:
     .sh-sort               JS has not run (or is off) — WooCommerce's own
                            select, lightly dressed, native arrow intact.
     .sh-sort.is-enhanced   the listbox is live; the native form is hidden but
                            still in the DOM and still what gets submitted.

   Colours are existing theme tokens only — --sage (near-black) for ink and the
   selected row, --ivory / --ivory-d / --sage-xl for fills, --border, --text2/3
   — so this matches the category chips it sits beside. */

/* ── Fallback: no JS ── */
/* z-index on the WRAPPER, not only on the panel. The product cards below are
   `position:relative` (Tailwind `relative`) and several of them take a
   transform on hover, so they sit in the same paint pass as this control; a
   z-index on the panel alone left the open list underneath them, where its
   options could not be clicked and so the menu could never close. Raising the
   wrapper lifts the whole control — panel included — clear of the grid. The
   open value stays well under the header search (210), the drawer (2200+) and
   the toast (9999) so nothing that should cover this stops doing so. */
.sh-sort{position:relative;display:inline-block;z-index:1}
.sh-sort.is-open{z-index:120}
.sh-sort .woocommerce-ordering{display:flex;align-items:center;gap:8px;margin:0}
.sh-sort .woocommerce-ordering label{
  font-family:var(--font-base);font-size:var(--fs-ui);font-weight:var(--fw-medium);
  color:var(--text2);margin:0;white-space:nowrap;
}
.sh-sort .woocommerce-ordering label::after{content:":"}
.sh-sort select.orderby{
  font-family:var(--font-base);font-size:var(--fs-ui);font-weight:var(--fw-semibold);
  color:var(--sage);padding:11px 16px;
  background:var(--ivory);border:1px solid var(--border);border-radius:999px;
  cursor:pointer;
}
/* WooCommerce's no-JS submit button: the select self-submits, so it is noise. */
.sh-sort .woocommerce-ordering button[type="submit"],
.sh-sort .woocommerce-ordering input[type="submit"]{display:none}

/* ── Enhanced: trigger ── */
.sh-sort.is-enhanced .woocommerce-ordering{display:none}

.sh-sort__btn{
  display:inline-flex;align-items:center;gap:8px;
  height:48px;padding:0 18px;
  background:var(--ivory);border:1px solid var(--border);border-radius:999px;
  font-family:var(--font-base);font-size:var(--fs-ui);
  color:var(--sage);line-height:1;cursor:pointer;
  -webkit-user-select:none;user-select:none;
  transition:background .2s ease,border-color .2s ease,box-shadow .2s ease;
}
.sh-sort__btn:hover{background:#fff;border-color:rgba(0,0,0,.22)}
.sh-sort__btn:focus-visible{
  outline:0;background:#fff;border-color:var(--sage);
  box-shadow:0 0 0 3px rgba(20,20,20,.1);
}
.sh-sort.is-open .sh-sort__btn{
  background:#fff;border-color:var(--sage);box-shadow:0 0 0 3px rgba(20,20,20,.1);
}
.sh-sort__label{font-weight:var(--fw-medium);color:var(--text2);white-space:nowrap}
.sh-sort__value{font-weight:var(--fw-semibold);color:var(--sage);white-space:nowrap}
.sh-sort__chev{
  margin-left:4px;font-size:12px;color:var(--text3);line-height:1;
  transition:transform .2s ease,color .2s ease;
}
.sh-sort__btn:hover .sh-sort__chev{color:var(--sage)}
.sh-sort.is-open .sh-sort__chev{transform:rotate(180deg);color:var(--sage)}

/* ── Enhanced: the list ──
   visibility (not just opacity) so the collapsed list is out of the tab order
   and out of the accessibility tree, the same way the FAQ panels handle it.
   Right-aligned because the control sits at the right end of its row; min-width
   matches the trigger so it never looks narrower than what opened it. */
.sh-sort__menu{
  position:absolute;z-index:1;top:calc(100% + 8px);right:0;
  min-width:100%;max-width:min(280px,90vw);
  margin:0;padding:6px;list-style:none;
  background:#fff;border:1px solid var(--border);border-radius:18px;
  box-shadow:var(--shadow-md);
  opacity:0;visibility:hidden;transform:translateY(-6px);
  transition:opacity .18s ease,transform .18s ease,visibility .18s;
}
.sh-sort__menu:focus{outline:0}
.sh-sort.is-open .sh-sort__menu{opacity:1;visibility:visible;transform:none}

.sh-sort__opt{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:11px 14px;border-radius:12px;
  font-family:var(--font-base);font-size:var(--fs-ui);font-weight:var(--fw-medium);
  color:var(--text2);white-space:nowrap;cursor:pointer;
  transition:background .15s ease,color .15s ease;
}
/* .is-active is the keyboard/pointer cursor, aria-selected is the applied sort;
   they are different things and can sit on different rows. */
.sh-sort__opt.is-active{background:var(--ivory-d);color:var(--sage)}
.sh-sort__opt[aria-selected="true"]{
  background:var(--sage-xl);color:var(--sage);font-weight:var(--fw-semibold);
}
.sh-sort__tick{font-size:13px;opacity:0;flex-shrink:0}
.sh-sort__opt[aria-selected="true"] .sh-sort__tick{opacity:1}

/* Submitting: the page is about to navigate, so freeze the control rather than
   let a second click queue another request. The dimming is on the TRIGGER only
   — putting it on the wrapper faded the panel too, which is what made the open
   list look see-through over the products while the request was in flight. */
.sh-sort.is-busy{pointer-events:none}
.sh-sort.is-busy .sh-sort__btn{opacity:.6}

@media (prefers-reduced-motion:reduce){
  .sh-sort__menu,.sh-sort__chev,.sh-sort__opt,.sh-sort__btn{transition:none}
}

/* ═══ Product shelf (horizontally scrolling row of shop-style product
   cards, with prev/next arrows) ═══
   Used by the Product Collection / Hand-Picked Products Gutenberg block
   (see functions.php) whenever it holds more than 4 products - rather than
   let a 5th+ card wrap onto a second row (or squeeze the grid columns
   narrower than the Shop page ever does), it scrolls sideways instead, one
   "page" of cards at a time. The cards themselves are the exact same
   .product-card markup as the Shop grid; only the container turns from
   CSS grid into a horizontally scrolling flex row, with matching flex-basis
   breakpoints (2/3/4 per view) so a card is never a different size here
   than it is on the Shop page. */
.product-shelf-wrap{position:relative;width:100%;max-width:100%;min-width:0;box-sizing:border-box}
.product-shelf{
  display:flex;gap:14px;overflow-x:auto;overflow-y:hidden;
  padding:4px 4px 10px;margin:0;list-style:none;
  scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch;
  scrollbar-width:none;-ms-overflow-style:none;
}
.product-shelf::-webkit-scrollbar{display:none}
.product-shelf .product-card{flex:0 0 calc(50% - 7px);min-width:0;scroll-snap-align:start}
@media (min-width:640px){.product-shelf .product-card{flex:0 0 calc(33.333% - 10px)}}
@media (min-width:1280px){.product-shelf .product-card{flex:0 0 calc(25% - 10.5px)}}

.product-shelf-arrow{
  position:absolute;top:calc(50% - 6px);transform:translateY(-50%);
  width:38px;height:38px;border-radius:50%;
  border:1px solid rgba(0,0,0,.1);background:#fff;box-shadow:var(--shadow-md);
  display:flex;align-items:center;justify-content:center;cursor:pointer;
  font-size:17px;line-height:1;color:var(--gold-d);z-index:2;padding:0;
  transition:box-shadow .15s,transform .15s;
}
.product-shelf-arrow:hover{box-shadow:0 6px 18px rgba(0,0,0,.2);transform:translateY(-50%) scale(1.06)}
.product-shelf-arrow[hidden]{display:none}
.product-shelf-arrow-prev{left:-6px}
.product-shelf-arrow-next{right:-6px}
@media (max-width:600px){.product-shelf-arrow{display:none}}

/* ═══ PRODUCT COLLECTION BLOCK — COMPACT CARDS ═══
   The "Products by Category" / "Hand-picked Products" rows an editor drops
   into a description. In WooCommerce 10.x both are the SAME block —
   wp:woocommerce/product-collection with a `collection` preset of
   by-category / hand-picked — and functions.php replaces its output
   wholesale with this theme's own .product-card markup, so none of the
   wc-block-grid classes exist on this site. The container is .product-shelf
   (>4 products, scrolls) or .shop-grid (<=4, static), both shared with the
   Shop archive, so .bt-pcshelf from that filter is what keeps everything
   below off the Shop page, the homepage strips and the related rows.

   Those shared cards are sized for a full-width archive. Inside a prose
   column they came out at 4 per row with a ~420px square image. Everything
   here is sizing only: card chrome, colours, radius, shadow, the Rx badge,
   the Sale flash and the arrow design all still come from the shared rules
   above and from content-product.php.

   No !important anywhere. The card's own typography is Tailwind utilities
   (.text-[9px], .text-xs, .p-3, .w-full) at (0,1,0) and these selectors are
   all (0,2,0) or deeper, so they win on specificity; theme.css also loads
   after bt-tailwind (it declares it as a dependency). The only inline style
   on the card is the button's background, which is left alone.

   Breakpoints follow the brief (480/768/992/1200) rather than the theme's
   own 640/1280 pair: the five requested steps do not map onto two. */
.bt-pcshelf{--pcshelf-img:160px}
@media (min-width:768px){.bt-pcshelf{--pcshelf-img:180px}}
@media (min-width:992px){.bt-pcshelf{--pcshelf-img:220px}}

/* ── per view / columns + 16px gap ──
   The slider has no JS "slidesPerView" to configure — it is a native
   overflow-x scroller with scroll-snap, so flex-basis IS the per-view
   count. The .shop-grid branch is given the same counts so a block that
   happens to return 4 or fewer products matches one that returns more. */
.bt-pcshelf .product-shelf{gap:16px}
.bt-pcshelf .product-shelf .product-card{flex:0 0 calc(66.667% - 10.667px)}
.bt-pcshelf .shop-grid{gap:16px;grid-template-columns:repeat(2,minmax(0,260px));justify-content:center}
@media (min-width:480px){
  .bt-pcshelf .product-shelf .product-card{flex:0 0 calc(50% - 8px)}
}
@media (min-width:768px){
  .bt-pcshelf .product-shelf{gap:20px}
  .bt-pcshelf .product-shelf .product-card{flex:0 0 calc(33.333% - 13.333px)}
  .bt-pcshelf .shop-grid{gap:20px;grid-template-columns:repeat(3,minmax(0,260px))}
}
@media (min-width:992px){
  .bt-pcshelf .product-shelf{gap:24px}
  .bt-pcshelf .product-shelf .product-card{flex:0 0 calc(25% - 18px)}
  .bt-pcshelf .shop-grid{gap:24px;grid-template-columns:repeat(4,minmax(0,260px))}
}
/* No 5-up step at 1200. The row stays at 4 from 992 up: a fifth card in a
   1094px column is ~204px, which is what forced the product name onto two
   lines and squeezed the price range. The grid branch is pinned to 4 for
   the same reason - auto-fit here used to produce 5 as well. */
@media (min-width:1200px){
  .bt-pcshelf .shop-grid{grid-template-columns:repeat(4,minmax(0,260px))}
}

/* ── card ──
   max-width caps the card once the track is wide enough that 20% would
   exceed it; flex-basis still drives the count below that. display:flex
   turns the <a> (Tailwind .block) into a column so the button can be pushed
   to the bottom and every card in a row ends up the same height — flex
   items stretch to the tallest by default. */
.bt-pcshelf .product-card{
  display:flex;flex-direction:column;max-width:260px;
}
.bt-pcshelf .product-card>.p-3{padding:12px;display:flex;flex-direction:column;flex:1 1 auto;min-width:0}

/* ── image ──
   object-fit:cover, so the image fills the box edge to edge with no empty
   band. This replaced contain: every image in the catalogue is landscape
   (measured 1.33-1.50) while this box is 1.0-1.155, so contain was leaving
   30-68px of dead space under each one — visible as a grey strip inside
   the card, which is what this is fixing.

   The cost of cover is the left/right edges of a wide pack shot: a 1.50
   image in a 1.155 box loses about 23% of its width. That is inherent to
   filling a box whose ratio does not match the source. If it ever crops
   something important, the fix is to match the BOX ratio to the artwork
   (3/2 here) rather than to go back to contain.

   The background stays: it is what a product with no featured image shows
   behind .product-thumb-empty, and what covers the box while the image
   loads. */
/* Written through .product-card to reach (0,3,0): the catalogue rules these
   replace (`.shop-grid .product-thumb` / `.product-shelf .product-thumb-img`)
   are (0,2,0), so a two-class selector here would tie with them and win only
   on source order — which a later reshuffle of this file would silently
   flip. */
.bt-pcshelf .product-card .product-thumb{
  width:100%;max-height:var(--pcshelf-img);aspect-ratio:1 / 1;
  padding:0;background:var(--ivory-d);
}
.bt-pcshelf .product-card .product-thumb-img{
  width:100%;height:100%;margin:0;padding:0;
  object-fit:cover;object-position:center;
}
.bt-pcshelf .product-card .product-thumb-empty{max-height:var(--pcshelf-img)}

/* ── text ── */
.bt-pcshelf .product-card .text-\[9px\]{font-size:11px;margin-top:10px;margin-bottom:4px}
/* ONE line with an ellipsis, the same treatment body.single-post gives
   these cards. At 4 per view the card is ~255px, which fits every name the
   catalogue currently has; anything longer is cut with an ellipsis and the
   full name stays reachable as the title="" tooltip that the block filter
   in functions.php puts on this span. No min-height: the card is image +
   one line + price + button, and nothing should reserve a second line. */
.bt-pcshelf .marquee-wrap{margin-bottom:4px}
.bt-pcshelf .marquee-text{
  font-size:15px;line-height:1.3;
  display:block;max-width:100%;min-height:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  -webkit-line-clamp:none;line-clamp:none;
}
.bt-pcshelf .product-card .font-display{font-size:15px}
.bt-pcshelf .product-card .flex.items-center.gap-2{margin-bottom:0}

/* ── button ──
   margin-top:auto is what pins it to the bottom of the (now flex) text
   block, which is the other half of equal card heights. */
.bt-pcshelf .product-card .w-full{
  margin-top:auto;padding:0;height:40px;font-size:14px;
  display:flex;align-items:center;justify-content:center;gap:6px;
}

/* ── arrows ──
   36px, and moved out of the cards on desktop: the wrapper takes 44px of
   side padding and the arrows sit in it, so the track simply gets narrower
   instead of the arrows hanging outside the prose column — which is what
   would put a horizontal scrollbar on the page. Vertically centred on the
   image band rather than the whole card (the card is much taller than the
   image now, so a 50% arrow sat down in the button area): 4px is the
   track's own top padding. */
.bt-pcshelf .product-shelf-arrow{
  width:36px;height:36px;font-size:16px;
  top:calc(4px + var(--pcshelf-img) / 2);
}
@media (min-width:1200px){
  .bt-pcshelf .product-shelf-wrap{padding-inline:44px}
  .bt-pcshelf .product-shelf-arrow-prev{left:0}
  .bt-pcshelf .product-shelf-arrow-next{right:0}
}

/* ═══ PRODUCT COLLECTION BLOCK — BLOG POSTS ═══
   Same blocks, same .bt-pcshelf markup, but a blog post is not a product
   page: single.php wraps the content in .max-w-3xl (768px) while the
   .bt-pcshelf breakpoints above measure the VIEWPORT. At 1440px the rules
   above therefore put 5 cards into a 768px column — roughly 140px each,
   which is where the two-line category label, the wrapped price range and
   the clipped titles came from. Nothing is wrong with those rules on a
   product page, where the prose column really is wide; they just cannot
   see the column they are in.

   body.single-post is the whole scope: product pages, shop and category
   archives, related rows and the homepage keep everything above untouched.
   Everything here is layout and type scale — the card chrome, the Rx badge,
   the black CTA (--sage is #141414, already the shop card's button colour,
   so nothing needs recolouring) and the arrow design all still come from
   the shared rules.

   No !important. These selectors carry one class more than the rules they
   override, and the card's only inline style is that button background,
   which is left alone. */
body.single-post .bt-pcshelf{margin-top:32px;margin-bottom:32px}

/* ── 3 / 2 / 1.15 per view, 20px gap (16px on phones) ──
   The slider is not Swiper or Slick — it is a native overflow-x scroller
   with scroll-snap plus the arrow script in functions.php, so "slidesPerView"
   is flex-basis and "slidesPerGroup: 1" is scroll-snap doing its job. The
   arrow step is measured from the live card width, so it follows these
   counts without any config to change. Loop is off because a scroll
   container has no loop, and the arrows already self-hide at each end
   (prev.hidden / next.hidden in that script). */
body.single-post .bt-pcshelf .product-shelf{gap:16px}
body.single-post .bt-pcshelf .product-shelf .product-card{flex:0 0 calc(86.957% - 13.913px)}
@media (min-width:768px){
  body.single-post .bt-pcshelf .product-shelf{gap:20px}
  body.single-post .bt-pcshelf .product-shelf .product-card{flex:0 0 calc(50% - 10px)}
}
@media (min-width:992px){
  body.single-post .bt-pcshelf .product-shelf .product-card{flex:0 0 calc(33.333% - 13.333px)}
}
/* A block that returns few enough products renders a plain .shop-grid
   instead of the shelf — no arrows, which is the "3 or fewer: normal row"
   case. Capped at 3 columns here so it matches the slider rather than
   inheriting the 4-up/5-up grid meant for a full-width page. */
body.single-post .bt-pcshelf .shop-grid{gap:16px;grid-template-columns:repeat(1,minmax(0,1fr))}
@media (min-width:768px){
  body.single-post .bt-pcshelf .shop-grid{gap:20px;grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (min-width:992px){
  body.single-post .bt-pcshelf .shop-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
}

/* ── card ──
   max-width is dropped: the 260px cap above is right for a wide page, but
   in a 768px column it would leave 3 cards short of the track and break the
   alignment the brief asks for. */
body.single-post .bt-pcshelf .product-card{max-width:none}

/* ── image ──
   White, not the --ivory-d used on product pages. object-fit:contain
   letterboxes anything that is not square, and against a cream box that
   letterboxing read as "some products are small landscape strips on grey" —
   on white it reads as the product sitting in the card. Still contain, so
   nothing is cropped and every box is the same size.

   A fixed HEIGHT, not the catalogue's 1/1 ratio box. The square made the
   image area as tall as the card was wide — ~340px at 2-up — so every card
   read as a long column. This is the same shape the global .product-thumb
   already uses (flex-centred box, fixed height, padding); the catalogue
   rules replaced it with the ratio box for full-width grids, and the blog
   simply goes back to it with its own heights. aspect-ratio has to be
   explicitly unset on both the box and the <img>, or it keeps winning over
   height. */
body.single-post .bt-pcshelf .product-card .product-thumb{
  display:flex;align-items:center;justify-content:center;
  width:100%;height:170px;aspect-ratio:auto;
  padding:12px;background:#fff;overflow:hidden;
  max-height:none;
}
@media (min-width:768px){
  body.single-post .bt-pcshelf .product-card .product-thumb{height:180px}
}
@media (min-width:992px){
  body.single-post .bt-pcshelf .product-card .product-thumb{height:200px}
}
/* height:100% + contain is what makes a square, a landscape strip and a
   small file all render at the same visual size inside the padded box.
   background:transparent so nothing of the old cream box can show through
   the letterboxed area — that beige band was the box's own background
   reading as part of the picture. */
body.single-post .bt-pcshelf .product-card .product-thumb-img{
  width:100%;height:100%;max-height:100%;aspect-ratio:auto;
  object-fit:contain;object-position:center;
  margin:0;background:transparent;
}
body.single-post .bt-pcshelf .product-card .product-thumb-empty{
  width:100%;height:100%;aspect-ratio:auto;max-height:none;background:transparent;
}

/* ── text ──
   12px between the image and the category label comes from the text
   block's own padding-top, not a margin on the label: the card's 14px
   padding is the floor, so a 12px gap can only be the top padding being
   smaller than the sides. The label's margin-top from the product-page
   rules is zeroed for the same reason — it would stack on top of this. */
body.single-post .bt-pcshelf .product-card>.p-3{padding:12px 14px 14px}
body.single-post .bt-pcshelf .product-card .text-\[9px\]{
  font-size:11px;margin-top:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
/* ONE line with an ellipsis. The product-page rules clamp this to two
   lines with -webkit-box, so BOTH halves of that have to be undone — the
   display and the line-clamp — or the box model keeps wrapping. The
   two-line min-height goes with it: the card's height is now image + text
   + button and nothing reserves space it does not use. Equal heights
   survive because every title is now exactly one line.

   The full name is still reachable: the block filter in functions.php puts
   it on this span as a title="" tooltip. */
body.single-post .bt-pcshelf .marquee-text{
  font-size:16px;text-align:center;
  display:block;max-width:100%;min-height:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  -webkit-line-clamp:none;line-clamp:none;
}
/* Price on one line. The brief's "shrink to 15px rather than wrap" cannot
   be conditional in CSS — nothing can measure the text — so the step is
   tied to the breakpoint where the card is narrowest instead: 16px once
   there is room for it, 15px below that. nowrap at both sizes is what
   actually guarantees the single line. */
body.single-post .bt-pcshelf .product-card .flex.items-center.gap-2{justify-content:center}
body.single-post .bt-pcshelf .product-card .font-display{font-size:15px;white-space:nowrap}
@media (min-width:992px){
  body.single-post .bt-pcshelf .product-card .font-display{font-size:16px}
}

/* ── button: icon and label on one line ──
   .w-full is a div, so it was a block box: the <i> and the text were two
   inline runs that wrapped independently once the card got narrow. inline-flex
   puts them on one line and keeps them there. */
body.single-post .bt-pcshelf .product-card .w-full{
  height:44px;display:inline-flex;gap:8px;white-space:nowrap;
}

/* ── arrows ──
   40px, and genuinely outside the cards on desktop. The ≥1200px rule above
   insets the track by 44px to make room, which is the safe choice on a
   full-width page but would cost this 768px column a quarter of its width,
   so the blog puts them in the page margin instead: at 992px the column is
   centred with ~112px to spare on each side, so a 40px circle at -48px
   still clears the viewport edge and cannot push the page sideways.
   Below 992px that margin disappears, so they move back inside the track. */
/* --pcshelf-img is what the shared rule centres the arrow on
   (top: 4px + var/2), and it has to track whatever the image box actually
   is. On a product page that is the ratio box's max-height; here it is the
   fixed thumb height above, so the two are kept on the same three numbers.
   Get this wrong and the arrow drifts — it sat 87px below the image centre
   while the box was still a full-width square. */
body.single-post .bt-pcshelf{--pcshelf-img:170px}
@media (min-width:768px){ body.single-post .bt-pcshelf{--pcshelf-img:180px} }
@media (min-width:992px){ body.single-post .bt-pcshelf{--pcshelf-img:200px} }
body.single-post .bt-pcshelf .product-shelf-arrow{width:40px;height:40px;font-size:17px}
body.single-post .bt-pcshelf .product-shelf-arrow-prev{left:-6px}
body.single-post .bt-pcshelf .product-shelf-arrow-next{right:-6px}
@media (min-width:992px){
  body.single-post .bt-pcshelf .product-shelf-wrap{padding-inline:0}
  body.single-post .bt-pcshelf .product-shelf-arrow-prev{left:-48px}
  body.single-post .bt-pcshelf .product-shelf-arrow-next{right:-48px}
}

/* WhatsApp float — kept WhatsApp's own brand green (not part of site theme) */
.wa-float{position:fixed;bottom:24px;left:16px;z-index:400;width:48px;height:48px;background:linear-gradient(135deg,#25d366,#128c4a);border-radius:50%;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 20px rgba(37,211,102,.45),0 1px 0 rgba(255,255,255,.3) inset;transition:all .3s cubic-bezier(.34,1.4,.64,1);text-decoration:none}
.wa-float:hover{transform:scale(1.1) rotate(4deg);box-shadow:0 8px 32px rgba(37,211,102,.55)}

/* Nav link */
.nav-link{padding:8px 14px;border-radius:50px;font-size:var(--fs-ui);font-weight:var(--fw-medium);color:var(--text2);text-decoration:none;transition:all .2s;position:relative}
.nav-link::after{content:'';position:absolute;bottom:4px;left:50%;transform:translateX(-50%) scaleX(0);width:16px;height:2px;background:var(--sage);border-radius:99px;transition:transform .2s}
.nav-link:hover,.nav-link.active{color:var(--sage)}
.nav-link:hover::after,.nav-link.active::after{transform:translateX(-50%) scaleX(1)}

/* Hero background — the banner image now runs edge-to-edge with no gradient
   ground showing around it, so this is plain white rather than the old
   cream→blue-gray radial. */
.hero-grad{background:#fff}

.wave-b{position:absolute;bottom:-1px;left:0;right:0;line-height:0;pointer-events:none}
/* Fallback wave geometry for any band that sets no --wave-h of its own.
   The two bands that exist both override it: .bt-darkband derives --wave-h
   from its own width and sizes the SVG to 100%, and the homepage hero does
   the same from .bt-hero--banner. */
.wave-b svg{display:block;width:100%;height:var(--wave-h,64px)}

/* ═══ DARK BAND ═══
   Shared opening-band treatment for the About and Contact heroes, so the two
   pages read as one design rather than each declaring its own dark surface.
   Nothing here is page-specific: the gradient is the theme's own dark ramp
   (--forest → --forest-l → --sage-l, the same three tokens the old About hero
   and the .bt-promise panel use), and the closing curve is the theme's
   existing .wave-b component, not a second wave implementation.

   The band reserves the wave's height in --wave-h; each hero adds that to its
   own bottom padding so the copy never sits under the curve. The wave's SVG
   is filled to match the section BELOW it — both pages follow this band with
   a white one — which is what makes the seam invisible.

   Width matches the homepage hero banner exactly: that banner is the content
   box of a .max-w-7xl.mx-auto.px-4 container, i.e. min(100vw, 80rem) minus
   the 1rem gutter a side, so the same arithmetic here puts every dark hero
   on the same left/right edges as the homepage banner and as every section
   below it, at any width and any zoom level.

   The section itself stays FULL width and paints white; the dark gradient
   is a second background layer sized to --band-w and centred in it. Two
   layers on one element because there is nothing else to paint with: there
   is no wrapper element, and ::before/::after are already spoken for by
   each hero's own decorative washes. Painting the white here, rather than
   letting the page show through, is what keeps the strip either side of
   the panel white instead of the body's ivory.

   --wave-h is derived from --band-w rather than the old 44/54/64px steps,
   so the reserve that keeps hero copy clear of the curve tracks the wave's
   real height (the 1440/100 ratio below makes it 6.94% of the panel's
   width). Being width-relative it also scales with browser zoom, which
   fixed px heights did not: they left the wave reading as a thin flat line
   on a wide or zoomed-out viewport. */
.bt-darkband{
  --band-w:min(calc(100% - 2rem), calc(80rem - 2rem));
  --wave-h:calc(var(--band-w) * 0.0694);
  position:relative;overflow:hidden;isolation:isolate;
  background:
    linear-gradient(155deg,var(--forest) 0%,var(--forest-l) 52%,var(--sage-l) 100%)
      no-repeat center top / var(--band-w) 100%,
    #fff;
  color:#fff;
}
/* Same width-proportional wave as the homepage hero, centred on the same
   --band-w. The extra 2px is an overlap, not a miscalculation: the gradient
   layer is centred by the background painter and the wave by a transform,
   and the two round to different sub-pixels, which left a 1px vertical
   sliver of gradient showing past the wave's white at each edge. Covering
   1px beyond the panel on each side absorbs that; the overhang is white on
   white, so it cannot show. The 1440/100 box is taller than these SVGs' own
   1440/64 viewBox on purpose — every dark-band wave carries
   preserveAspectRatio="none", so the existing curve simply stretches into
   it and gains the depth it was missing. */
.bt-darkband .wave-b{
  left:50%;right:auto;transform:translateX(-50%);
  width:calc(var(--band-w) + 2px);aspect-ratio:1440/100;height:auto;
}
.bt-darkband .wave-b svg{height:100%}
/* The gold pill is tuned for ivory; on the dark ramp it needs the lighter
   accent token and a slightly stronger fill to hold its edge. */
.bt-darkband .badge-gold{background:rgba(201,162,74,.18);color:var(--gold-l);border-color:rgba(232,217,160,.34)}

/* ═══ REVIEWS / COMMENTS ═══ */
#reviews{margin-top:20px}
#reviews .woocommerce-Reviews-title{font-family:var(--font-base);font-size:var(--fs-h3);font-weight:var(--fw-semibold);color:var(--forest);margin-bottom:20px}
.commentlist{list-style:none;padding:0;margin:0 0 30px}
.commentlist .comment{display:flex;gap:14px;padding:18px 0;border-bottom:1px solid var(--border)}
.commentlist .avatar{width:44px;height:44px;border-radius:50%;flex-shrink:0}
.comment-text{flex:1}
.comment-text .star-rating{margin-bottom:6px}
.woocommerce-review__author{font-weight:var(--fw-heading);color:var(--forest);font-size:var(--fs-ui)}
.woocommerce-review__dash{color:var(--text3);margin:0 6px}
.woocommerce-review__published-date{color:var(--text3);font-size:var(--fs-xs)}
.description p{color:var(--ink-body);font-size:var(--fs-ui);line-height:var(--lh-small);margin-top:6px}
.star-rating{overflow:hidden;position:relative;height:1em;line-height:1;width:5.4em;font-family:inherit}
.star-rating::before{content:'\2605\2605\2605\2605\2605';color:var(--border);float:left;top:0;left:0;position:absolute}
.star-rating span{overflow:hidden;float:left;top:0;left:0;position:absolute;padding-top:1.5em}
.star-rating span::before{content:'\2605\2605\2605\2605\2605';top:0;position:absolute;left:0;color:var(--gold)}
#review_form_wrapper{background:#fff;border:1.5px solid var(--border);border-radius:var(--r);padding:24px;margin-top:10px}
#review_form_wrapper .comment-reply-title{font-family:var(--font-base);font-size:var(--fs-h3);font-weight:var(--fw-semibold);color:var(--forest);display:block;margin-bottom:16px}
.comment-notes,.comment-form-rating label,.comment-form-comment label,.comment-form-author label,.comment-form-email label{font-size:var(--fs-xs);font-weight:var(--fw-label);color:var(--text2);text-transform:uppercase;letter-spacing:.5px;display:block;margin-bottom:6px}
.comment-notes{text-transform:none;font-weight:var(--fw-body);letter-spacing:0;margin-bottom:14px}
.comment-form-rating{margin-bottom:16px}
.comment-form-rating .stars{display:flex;gap:4px}
.comment-form-rating .stars a{color:var(--gold);font-size:18px;text-decoration:none}
#review_form_wrapper input[type="text"],#review_form_wrapper input[type="email"],#review_form_wrapper textarea{
  width:100%;padding:12px 16px;border:1.5px solid var(--border);border-radius:10px;font-family:inherit;font-size:var(--fs-ui);margin-bottom:14px;outline:none;
}
#review_form_wrapper input:focus,#review_form_wrapper textarea:focus{border-color:var(--sage)}
.form-submit input[type="submit"]{
  display:inline-flex;align-items:center;justify-content:center;padding:12px 26px;
  background:linear-gradient(135deg,var(--sage),var(--sage-d));color:#fff;border:none;border-radius:50px;
  font-size:var(--fs-ui);font-weight:700;cursor:pointer;
}

/* ═══ PROSE — WYSIWYG / GUTENBERG CONTENT ═══
   .product-desc is this theme's one prose context: product descriptions,
   blog posts (single.php), plain pages (page.php), the homepage content
   and FAQ bands, and the contact/about FAQ wrappers all render editor
   output through it. So this block is where Gutenberg compatibility
   lives.

   Headings here take the GLOBAL h1-h6 sizes — no em-based parallel scale
   any more. An h2 an editor types into a product description is now the
   same h2 as one a template writes, which is the whole point of the
   system. This block only adds what prose needs on top: vertical rhythm
   (the global reset zeroes margins) and link/list/table treatment. */
.product-desc{font-size:var(--fs-body);line-height:var(--lh-body)}

/* One rhythm for every block an editor can produce, not just <p>.
   --prose-block-mt/mb used to sit on .product-desc p alone, so a paragraph
   got breathing room while a list, table or heading typed right after it
   carried whatever margin its own rule happened to set (lists: bottom only;
   tables: a hardcoded 1.25em; headings: nothing, because the global reset
   zeroes them). The gaps between blocks therefore changed depending on what
   the editor typed, which is the opposite of a rhythm.

   Listed by element rather than as `.product-desc>*` on purpose: prose
   reaches this wrapper nested as well as flat — Gutenberg wraps a table in
   <figure> and an embed in a div — so a direct-child selector would leave
   exactly those blocks unspaced. (The FAQ accordions are not a reason: their
   `.bt-faq .bt-faq__a-inner>*` rule is (0,2,0) and keeps its own 12px
   rhythm either way.) The trade-off is that a block Gutenberg wraps gets a margin on
   the wrapper AND the element inside; adjacent vertical margins collapse, so
   the gap stays one --prose-block-mb rather than doubling, and the
   figure>table reset below covers the one case that cannot collapse (a
   figure with its own padding or border). */
.product-desc p,
.product-desc ul,.product-desc ol,
.product-desc table,.product-desc figure,
.product-desc h1,.product-desc h2,.product-desc h3,
.product-desc h4,.product-desc h5,.product-desc h6,
.product-desc blockquote,.product-desc pre,.product-desc hr{
  margin-top:var(--prose-block-mt);margin-bottom:var(--prose-block-mb);
}
/* No leading gap above the first block or trailing gap below the last one —
   the wrapper's own padding owns those edges. Second level too, so a content
   area that opens with a Gutenberg-wrapped table does not inherit a gap from
   the <table> inside the <figure>. */
.product-desc>:first-child,.product-desc>:first-child>:first-child{margin-top:0}
.product-desc>:last-child,.product-desc>:last-child>:last-child{margin-bottom:0}
.product-desc figure>table{margin-top:0;margin-bottom:0}
/* A list nested inside a list item keeps the tighter inter-item rhythm
   instead of a full block gap, which would detach it from its parent item. */
.product-desc li>ul,.product-desc li>ol{margin-top:.4em;margin-bottom:.4em}
.product-desc a{color:var(--sage);text-decoration:underline}
.product-desc strong,.product-desc b{font-weight:var(--fw-heading)}
.product-desc ul,.product-desc ol{padding-left:1.4em;list-style-position:outside}
.product-desc ul{list-style-type:disc}
.product-desc ol{list-style-type:decimal}
.product-desc li{margin-bottom:.4em;line-height:1.65;color:var(--ink-body);display:list-item}
.product-desc p{line-height:1.75;color:var(--ink-body)}
/* EDITOR TABLES — one treatment wherever prose renders: product pages, blog
   posts and page templates all wrap the_content() in .product-desc, so a
   table pasted or built with the Gutenberg table block looks identical in
   all three. White panel, near-black header row, ruled cells, rounded
   corners. Tokens are at the top of the file (--prose-table-*).

   border-collapse:separate (was collapse) is what makes the radius possible:
   in the collapse model cell borders merge into the table's own border box
   and browsers drop border-radius on the table entirely, so the corners of
   the black header row stayed square. Separate + border-spacing:0 keeps the
   single-line ruling look while leaving the table a real border box to
   round. The ruling then has to come off the cells' shared edges, hence the
   right/bottom borders below and the :last-child resets that stop a double
   line against the table's own border.

   The table is not an overflow container, so the radius here rounds its
   border box only and does not clip the cells inside it — the corner cells
   carry their own radius further down to cover that. */
.product-desc table{
  width:100%;border-collapse:separate;border-spacing:0;font-size:var(--fs-small);
  background:var(--prose-table-bg);
  border:1px solid var(--prose-table-border);
  border-radius:var(--prose-table-radius);
}
.product-desc table th,.product-desc table td{
  padding:.6em 1em;text-align:left;
  border-right:1px solid var(--prose-table-border);
  border-bottom:1px solid var(--prose-table-border);
}
.product-desc table th{
  background:var(--prose-table-head-bg);color:var(--prose-table-head-text);
  font-weight:var(--fw-heading);
  border-right-color:rgba(255,255,255,.18);
  border-bottom-color:var(--prose-table-head-bg);
}
/* Last column and last row carry no rule of their own — the table's border
   is already there, and a second line next to it reads as a thick edge. */
.product-desc table tr>th:last-child,.product-desc table tr>td:last-child{border-right:0}
/* Bottom rule off the final row only. Scoped through `tbody:last-child`
   rather than a bare `tr:last-child`, which also matches the single row
   inside a <thead> and would strip the line under the header. */
.product-desc table tbody:last-child>tr:last-child>th,
.product-desc table tbody:last-child>tr:last-child>td{border-bottom:0}

/* The radius above rounds the table's border box but does NOT clip the cells
   inside it — a table cannot be an overflow container — so the black header
   row would square off the top two corners it sits in. The corner cells
   carry their own radius instead, one border-width smaller so the dark fill
   follows the inside of the border rather than bleeding over it.

   Each corner is matched twice so a Gutenberg table (header in <thead>) and
   a pasted one (no <thead>, header as the first <tbody> row, sometimes as
   <td>) round identically — and scoped to the first/last SECTION, never a
   bare tr:first-child/:last-child: those match per section, so the header
   row, being the only row in its <thead>, would also round its bottom
   corners and show two white nicks in the middle of the black band. */
.product-desc table>thead>tr:first-child>th:first-child,
.product-desc table>thead>tr:first-child>td:first-child,
.product-desc table>tbody:first-child>tr:first-child>th:first-child,
.product-desc table>tbody:first-child>tr:first-child>td:first-child{border-top-left-radius:calc(var(--prose-table-radius) - 1px)}
.product-desc table>thead>tr:first-child>th:last-child,
.product-desc table>thead>tr:first-child>td:last-child,
.product-desc table>tbody:first-child>tr:first-child>th:last-child,
.product-desc table>tbody:first-child>tr:first-child>td:last-child{border-top-right-radius:calc(var(--prose-table-radius) - 1px)}
.product-desc table>tbody:last-child>tr:last-child>th:first-child,
.product-desc table>tbody:last-child>tr:last-child>td:first-child{border-bottom-left-radius:calc(var(--prose-table-radius) - 1px)}
.product-desc table>tbody:last-child>tr:last-child>th:last-child,
.product-desc table>tbody:last-child>tr:last-child>td:last-child{border-bottom-right-radius:calc(var(--prose-table-radius) - 1px)}

/* Beat core's block-library CSS, which ships its own table treatment the
   moment a table block is on the page:
     .wp-block-table table{border-collapse:collapse;width:100%}
     .wp-block-table td,.wp-block-table th{border:1px solid;padding:.5em}
   Both are (0,1,1) — the same weight as the rules above — so which one wins
   comes down to stylesheet order, and that is not something a theme should
   bet its table design on. Re-declaring through the wrapper makes these
   (0,2,1) and settles it. `border:1px solid` with no colour also resolves to
   currentColor, which on a td means near-black gridlines, so the cell rule
   has to be restated and not just the collapse mode. */
.product-desc .wp-block-table table{border-collapse:separate;border-spacing:0}
.product-desc .wp-block-table th,.product-desc .wp-block-table td{
  padding:.6em 1em;border:0;
  border-right:1px solid var(--prose-table-border);
  border-bottom:1px solid var(--prose-table-border);
}
.product-desc .wp-block-table th{
  border-right-color:rgba(255,255,255,.18);
  border-bottom-color:var(--prose-table-head-bg);
}
.product-desc .wp-block-table tr>th:last-child,
.product-desc .wp-block-table tr>td:last-child{border-right:0}
.product-desc .wp-block-table tbody:last-child>tr:last-child>th,
.product-desc .wp-block-table tbody:last-child>tr:last-child>td{border-bottom:0}
/* The figure is core's own scroll container (.wp-block-table{overflow-x:auto}),
   so the inner table must not also be one — the mobile rule further down is
   skipped here and the radius clips against the figure instead. */
.product-desc .wp-block-table{border-radius:var(--prose-table-radius)}
/* Core also draws `.wp-block-table thead{border-bottom:3px solid}` with no
   colour, so it resolves to currentColor and lands a 3px near-black bar
   under the header — on top of our own 1px ruling, and wider than every
   other line in the table. Measured at 1280/768/375 before this rule:
   border-bottom-width 3px, rgb(28,28,28). The matching tfoot rule goes with
   it. */
.product-desc .wp-block-table thead,
.product-desc .wp-block-table tfoot{border:0}

/* ── "Stripes" block style ──
   One click away in the same block's sidebar, and core's variant actively
   dismantles this design: `border-collapse:inherit`, `border-color:
   transparent` on every cell, and a #f0f0f0 odd-row fill that belongs to no
   palette on this site. Restated here so picking Stripes changes only what
   it says on the tin — the row banding — and keeps the panel, the header and
   the ruling. The band is the theme's own ivory instead of #f0f0f0. */
.product-desc .wp-block-table.is-style-stripes{
  border:0;background:transparent;
}
.product-desc .wp-block-table.is-style-stripes table{
  border:1px solid var(--prose-table-border);
  border-radius:var(--prose-table-radius);
  background:var(--prose-table-bg);
}
.product-desc .wp-block-table.is-style-stripes tbody tr:nth-child(odd){background:var(--ivory-d)}
.product-desc .wp-block-table.is-style-stripes th,
.product-desc .wp-block-table.is-style-stripes td{border-color:var(--prose-table-border)}
.product-desc .wp-block-table.is-style-stripes th{
  border-right-color:rgba(255,255,255,.18);
  border-bottom-color:var(--prose-table-head-bg);
}

/* ── Table block: width follows content, position from the toolbar ──
   KEEP IN SYNC with assets/css/editor-tables.css, which repeats these rules
   for the editor canvas (where there is no .product-desc wrapper).

   Default was full-bleed because `.product-desc table` sets width:100% for
   every prose table — that rule is the one being overridden here, and only
   for figure.wp-block-table. A bare <table> (classic editor, pasted HTML)
   deliberately keeps width:100%: it has no figure to scroll inside, and the
   note above `.product-desc table{max-width:100%}` explains why it must
   fill rather than shrink.

   width:fit-content on a BLOCK box, not the brief's display:table. Same
   shrink-to-fit result, but display:table would silently drop the
   overflow-x:auto that core puts on this figure — overflow has no defined
   effect on a table wrapper box — and that scroll container is what keeps a
   wide table off the page's own scrollbar and what clips the rounded
   corners. One declaration here replaces both the default rule and the
   mobile-only rule the brief asked for, because a block figure can be
   shrink-to-fit and scrollable at the same time at every width. */
.product-desc figure.wp-block-table{
  display:block;width:fit-content;max-width:100%;
  overflow-x:auto;-webkit-overflow-scrolling:touch;
}
.product-desc figure.wp-block-table>table{width:auto;max-width:100%;table-layout:auto}
/* Cells wrap rather than forcing the table wider; min-width stops a
   two-word table collapsing to a sliver. Dropped below the theme's phone
   breakpoint: 120px x 3 columns plus padding already exceeds a 375px
   screen, so keeping it there would send tables that could simply wrap into
   a horizontal scroll instead. */
.product-desc figure.wp-block-table th,
.product-desc figure.wp-block-table td{
  white-space:normal;word-break:break-word;min-width:120px;
}
@media (max-width:767px){
  .product-desc figure.wp-block-table th,
  .product-desc figure.wp-block-table td{min-width:0}
}

/* Toolbar alignment. These are (0,3,0) and core's
   `.wp-block-table.alignleft,.aligncenter,.alignright{display:table;width:auto}`
   is (0,2,0), so they win without !important — the display:table there is
   the same overflow-killing problem as above.

   float:none is defensive only: the classic `.alignleft{float:left}` pair
   lives in a theme stylesheet, and this theme has none (grepped) — but it
   is one of the first things a future edit would add, and a floated table
   would wrap body copy around it, which the brief rules out. */
.product-desc .wp-block-table.alignleft{display:block;float:none;margin-left:0;margin-right:auto}
.product-desc .wp-block-table.aligncenter{display:block;float:none;margin-left:auto;margin-right:auto}
.product-desc .wp-block-table.alignright{display:block;float:none;margin-left:auto;margin-right:0}
.product-desc .wp-block-table.alignwide,
.product-desc .wp-block-table.alignfull{display:block;float:none;width:100%;max-width:100%;margin-left:0;margin-right:0}
.product-desc .wp-block-table.alignwide>table,
.product-desc .wp-block-table.alignfull>table{width:100%}

/* "Fixed width table cells" in the block sidebar. Core puts has-fixed-layout
   on the TABLE, and `.product-desc figure.wp-block-table>table{width:auto}`
   above would otherwise cancel the width:100% half of it. The :has() on the
   figure is what makes the toggle mean anything: a 100%-wide table inside a
   fit-content figure resolves back to its own content width, so the figure
   has to be told to fill too. */
.product-desc figure.wp-block-table>table.has-fixed-layout{table-layout:fixed;width:100%}
.product-desc figure.wp-block-table:has(>table.has-fixed-layout){width:100%}

/* Per-cell alignment from the block toolbar. `.product-desc table th,td`
   sets text-align:left at (0,1,1) and core's .has-text-align-* is (0,1,0),
   so without these the admin's per-column choice silently did nothing. */
.product-desc .wp-block-table th.has-text-align-left,
.product-desc .wp-block-table td.has-text-align-left{text-align:left}
.product-desc .wp-block-table th.has-text-align-center,
.product-desc .wp-block-table td.has-text-align-center{text-align:center}
.product-desc .wp-block-table th.has-text-align-right,
.product-desc .wp-block-table td.has-text-align-right{text-align:right}

/* Caption follows the table instead of core's unconditional centring
   (core uses :where(figcaption), specificity 0, so this needs nothing
   special to win). */
.product-desc .wp-block-table>figcaption{text-align:left;font-size:var(--fs-xs);color:var(--ink-muted)}
.product-desc .wp-block-table.aligncenter>figcaption{text-align:center}
.product-desc .wp-block-table.alignright>figcaption{text-align:right}
/* ── Table block: admin-chosen width ──
   KEEP IN SYNC with assets/css/editor-tables.css, which repeats these rules
   (plus the resize wrapper and readout) for the editor canvas.

   bt-has-custom-width is added at render time by bt_table_width_render()
   in includes/blocks/table-width/init.php, alongside an inline
   `width:<n><unit>;max-width:100%` on the same <figure>. The width itself is
   therefore NOT set here — an inline declaration already outranks every
   selector in this file — and these rules only have to make the figure behave
   like a box that has been given a width.

   Scoped loosely (no .product-desc) on purpose, unlike the rest of this
   section: the class is unique to tables this feature has touched, so it
   cannot reach a WooCommerce or classic-editor table, and keeping it
   unscoped means the width still applies to a table dropped into a template
   that has no .product-desc wrapper. `figure.wp-block-table.bt-has-custom-width`
   is (0,2,1) and `figure...>table` is (0,2,2), which is what beats
   `.product-desc figure.wp-block-table>table{width:auto}` above without
   reaching for !important. */
figure.wp-block-table.bt-has-custom-width{
  display:block;float:none;
}
/* The table fills the figure instead of shrinking back to its own content
   width, which is what makes the chosen figure width visible at all. With
   "Fixed width table cells" ON the has-fixed-layout rule above adds
   table-layout:fixed on top of this and the columns come out equal; with it
   OFF the layout stays auto and the columns size to their content inside the
   chosen width. */
figure.wp-block-table.bt-has-custom-width>table{width:100%;max-width:100%}
/* The 120px cell floor from the default rules is what stops a two-word table
   collapsing to a sliver — but once an admin has picked a width, that floor
   is the thing fighting the choice: six columns x 120px exceeds a 50% figure
   and the table starts scrolling inside it instead of honouring the width.
   The admin's number wins; the figure's overflow-x:auto is still there as the
   last resort if the content genuinely cannot wrap any narrower. */
figure.wp-block-table.bt-has-custom-width th,
figure.wp-block-table.bt-has-custom-width td{min-width:0}

/* Phones. A percentage that reads well on a desktop column is a few words per
   line at 375px, so below the theme's phone breakpoint the custom width is
   dropped and the table goes back to filling the content area. !important is
   unavoidable and deliberate: the width being overridden is an inline style,
   and nothing else outranks one. Tables already set to 100% are unaffected —
   this only ever widens. */
@media (max-width:767px){
  figure.wp-block-table.bt-has-custom-width{width:100%!important}
}


.comment-form-rating p.stars{display:flex;gap:4px;margin:4px 0 16px;list-style:none;padding:0}
.comment-form-rating p.stars a{position:relative;text-indent:-9999px;overflow:hidden;display:inline-block;width:22px;height:22px;text-decoration:none}
.comment-form-rating p.stars a::before{content:'\2605';text-indent:0;position:absolute;left:0;top:0;font-size:20px;line-height:1;color:var(--border)}
.comment-form-rating p.stars a:hover::before,.comment-form-rating p.stars a.active::before{color:var(--gold)}

/* ═══ WOOCOMMERCE NOTICES ═══ */
.woocommerce-error,.woocommerce-message,.woocommerce-info{
  border-radius:14px;padding:14px 20px;font-size:var(--fs-ui);font-weight:var(--fw-medium);list-style:none;margin:0 0 24px;
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;box-shadow:0 4px 16px rgba(0,0,0,.06);
}
.woocommerce-error::before,.woocommerce-message::before,.woocommerce-info::before{
  font-family:'bootstrap-icons';font-size:18px;flex-shrink:0;
}
.woocommerce-error{background:#fef2f2;border:1px solid rgba(220,38,38,.2);color:#991b1b}
.woocommerce-error::before{content:"\f622";color:#dc2626}
.woocommerce-message{background:var(--ivory-d);border:1px solid rgba(0,0,0,.12);color:var(--forest)}
.woocommerce-message::before{content:"\f26b";color:var(--gold-d)}
/* Info notices — "Have a coupon?", the empty-cart hint, and anything else
   WooCommerce files under .woocommerce-info. Core ships them in a blue that is
   the one palette this site does not use anywhere, and on checkout the notice
   sits directly above the cream cards, where it read as a piece of another
   site. It now carries the same treatment as a card head — beige ground, gold
   accent bar on the left, forest text — so it belongs to the page it opens.
   The error notice deliberately keeps its red: that one is meant to look
   different. */
.woocommerce-info{background:var(--ivory-d);border:1px solid rgba(0,0,0,.08);
  border-left:4px solid #C49A5A;color:var(--forest)}
.woocommerce-info::before{content:"\f430";color:var(--gold-d)}
/* The link inside it ("Click here to enter your code") was the other blue.
   :not(.button) so a notice that carries a real button — the empty-cart
   "Return to shop" — keeps its button styling instead of becoming a gold
   underlined link. */
.woocommerce-info a:not(.button){color:var(--gold-d);font-weight:var(--fw-heading);text-decoration:underline}
.woocommerce-info a:not(.button):hover{color:var(--forest)}
/* Black-pill CTA — the same treatment as the Orders table's "View" button —
   for any notice button: core's "Return to shop" (.woocommerce-message /
   .woocommerce-error) and the My Account > Orders empty-state buttons
   ("Browse products", "Confirm email address"), which are .woocommerce-info
   since WooCommerce's own notices/notice.php always renders that class. */
.woocommerce-message a.button.wc-forward,
.woocommerce-error a.button.wc-forward,
.woocommerce-info a.button{
  margin-left:auto;background:var(--sage);color:#fff!important;padding:7px 18px;border-radius:50px;
  font-size:var(--fs-xs);font-weight:var(--fw-heading);text-decoration:none!important;white-space:nowrap;
}
.woocommerce-message a.button.wc-forward:hover,
.woocommerce-info a.button:hover{background:var(--sage-d)}
/* Stack text above a full-width button instead of the button clipping or
   squeezing the text at phone widths, where flex-wrap alone leaves it
   right-aligned and cramped. */
@media (max-width:767px){
  .woocommerce-info{flex-direction:column;align-items:flex-start}
  .woocommerce-info a.button{margin-left:0;width:100%;text-align:center}
}

/* Pagination */
.woocommerce-pagination ul.page-numbers,.pagination .page-numbers{list-style:none;display:flex;align-items:center;justify-content:center;gap:8px;padding:0;margin:0;flex-wrap:wrap}
.woocommerce-pagination ul.page-numbers li{display:flex}
.woocommerce-pagination .page-numbers a,.woocommerce-pagination .page-numbers span,.pagination .page-numbers a,.pagination .page-numbers span{
  display:flex;align-items:center;justify-content:center;min-width:40px;height:40px;padding:0 8px;
  border-radius:10px;border:1.5px solid rgba(0,0,0,.1);color:var(--forest);font-weight:var(--fw-heading);font-size:var(--fs-small);
  text-decoration:none;background:#fff;transition:all .15s;
}
.woocommerce-pagination .page-numbers a:hover,.pagination .page-numbers a:hover{background:rgba(0,0,0,.04);border-color:var(--sage)}
.woocommerce-pagination .page-numbers span.current,.pagination .page-numbers span.current{background:var(--sage);border-color:var(--sage);color:#fff}
.woocommerce-pagination .page-numbers .dots,.pagination .page-numbers .dots{border:none;background:none}

/* OTP login */
.site-core-otp-login{max-width:380px;margin:0 auto;padding:8px 4px;text-align:center}
.site-core-otp-icon{width:56px;height:56px;border-radius:50%;background:rgba(0,0,0,.06);display:flex;align-items:center;justify-content:center;margin:0 auto 16px;font-size:24px;color:var(--sage)}
.site-core-otp-title{font-family:var(--font-base);font-weight:var(--fw-semibold);font-size:var(--fs-h3);color:var(--forest);margin-bottom:6px}
.site-core-otp-sub{font-size:var(--fs-small);color:var(--text3);margin-bottom:22px}
.site-core-otp-row{margin-bottom:14px;text-align:left}
.site-core-otp-label{display:block;font-size:var(--fs-label);font-weight:var(--fw-label);color:var(--text2);margin-bottom:6px;letter-spacing:.6px;text-transform:uppercase}
.site-core-otp-input{width:100%;padding:12px 16px;border:1.5px solid var(--border);border-radius:10px;font-size:var(--fs-ui);color:var(--text1);background:#fff;outline:none;transition:all .2s;box-sizing:border-box}
.site-core-otp-input:focus{border-color:var(--sage);box-shadow:0 0 0 4px rgba(0,0,0,.06)}
.site-core-otp-code-input{text-align:center;letter-spacing:6px;font-weight:700;font-size:18px}
.site-core-otp-btn{width:100%;padding:12px 26px;background:var(--sage);color:#fff;border:none;border-radius:50px;font-size:var(--fs-ui);font-weight:700;cursor:pointer}
.site-core-otp-btn:hover{background:var(--sage-d);transform:translateY(-2px)}
.site-core-otp-btn:disabled{opacity:.6;cursor:default;transform:none}
.site-core-otp-btn-primary{background:var(--gold);box-shadow:0 4px 16px rgba(201,162,74,.3)}
.site-core-otp-btn-primary:hover{background:var(--gold-d)}
.site-core-otp-msg{font-size:var(--fs-small);font-weight:var(--fw-semibold);margin-top:6px;min-height:18px}

/* ═══ WOOCOMMERCE FORM / TABLE RESKIN ═══ */
.woocommerce-checkout .form-row{margin-bottom:16px}
.woocommerce-checkout label{display:block;font-size:var(--fs-label);font-weight:var(--fw-label);color:var(--text2);margin-bottom:6px;letter-spacing:.6px;text-transform:uppercase}
.woocommerce-checkout .input-text,
.woocommerce-checkout select,
.woocommerce-checkout textarea,
.woocommerce-checkout .select2-selection{
  width:100%;padding:12px 16px;border:1.5px solid var(--border);border-radius:10px;
  font-family:inherit;font-size:var(--fs-ui);color:var(--text1);background:#fff;outline:none;transition:all .2s;
}
.woocommerce-checkout .input-text:focus,
.woocommerce-checkout select:focus,
.woocommerce-checkout textarea:focus{border-color:var(--sage);box-shadow:0 0 0 4px rgba(0,0,0,.06)}

.woocommerce-checkout .select2-container{width:100%!important}
.woocommerce-checkout .select2-container--default .select2-selection--single{
  height:48px;border:1.5px solid var(--border);border-radius:10px;background:#fff;
  display:flex;align-items:center;padding:0;
}
.woocommerce-checkout .select2-selection__rendered{padding:0 16px!important;line-height:46px!important;color:var(--text1)!important;font-size:var(--fs-ui)}
.woocommerce-checkout .select2-selection__placeholder{color:#9ca3af!important}
.woocommerce-checkout .select2-selection__arrow{height:46px!important;right:10px!important}
.woocommerce-checkout .select2-container--focus .select2-selection--single,
.woocommerce-checkout .select2-container--open .select2-selection--single{border-color:var(--sage)}
.select2-dropdown{border:1.5px solid var(--border)!important;border-radius:10px!important;overflow:hidden}
.select2-results__option{padding:10px 16px!important;font-size:var(--fs-ui)}
.select2-results__option--highlighted[aria-selected]{background:var(--sage)!important}
.select2-search--dropdown .select2-search__field{border:1.5px solid var(--border)!important;border-radius:8px!important;padding:8px 10px!important}

.woocommerce-checkout-review-order-table{width:100%;font-size:var(--fs-ui);border-collapse:collapse}
.woocommerce-checkout-review-order-table th,
.woocommerce-checkout-review-order-table td{padding:10px 0;border-bottom:1px solid rgba(0,0,0,.08);color:var(--text2)}
.woocommerce-checkout-review-order-table .product-name{font-weight:var(--fw-semibold);color:var(--text1)}
.woocommerce-checkout-review-order-table .order-total td,
.woocommerce-checkout-review-order-table .order-total th{font-weight:800;color:var(--forest);font-size:var(--fs-h5);border-top:2px solid rgba(0,0,0,.12);border-bottom:none}

.wc_payment_methods{list-style:none;padding:0;margin:16px 0 0}
.wc_payment_method{border:1.5px solid var(--border);border-radius:12px;padding:14px;margin-bottom:10px}
.wc_payment_method label{display:inline;font-size:var(--fs-ui);font-weight:var(--fw-heading);color:var(--forest);text-transform:none;letter-spacing:0;margin-left:6px}
.wc_payment_method .payment_box{margin-top:12px;font-size:var(--fs-small);color:var(--ink-body)}

#place_order,
.woocommerce-checkout #payment #place_order,
.checkout-button,
input[name="apply_coupon"],
input[name="update_cart"]{
  width:100%;padding:16px;background:linear-gradient(135deg,var(--sage),var(--sage-d));color:#fff;border:none;border-radius:50px;
  font-size:var(--fs-body);font-weight:var(--fw-heading);cursor:pointer;box-shadow:0 4px 16px rgba(0,0,0,.16);transition:all .2s;
}
#place_order:hover{transform:translateY(-2px)}

.quantity .qty{width:70px;padding:8px 10px;border:1.5px solid var(--border);border-radius:8px;text-align:center;font-weight:700}

/* ═══ CART PAGE (woocommerce/cart/cart.php, cart-totals.php, cart-empty.php) ═══
   No new palette here: the CTAs are the theme's own .btn-sage / .btn-outline
   pills (same buttons the rest of the site uses), and the accents below are
   existing tokens. .bt-btn-block only stretches a .btn-sage to fill its card. */
.bt-btn-block{width:100%;padding:16px}

/* Proceed to Checkout: no hover lift.
   This button carries both .checkout-button and .btn-sage, and .btn-sage:hover
   raises it by 1px. On an inline-size button that is harmless, but this one is
   full-width and the pointer commonly rests near its lower edge: the button
   slides up out from under the cursor, :hover drops, it slides back, :hover
   fires again - a visible shimmer for as long as the pointer is held there.
   The hover feedback moves to colour + shadow, which never changes the box the
   cursor is testing against. :active keeps a press cue via the shadow alone. */
.wc-proceed-to-checkout .checkout-button{transition:background-color .2s ease-in-out,box-shadow .2s ease-in-out}
.wc-proceed-to-checkout .checkout-button:hover,
.wc-proceed-to-checkout .checkout-button:active,
.wc-proceed-to-checkout .checkout-button:focus-visible{transform:none}
.wc-proceed-to-checkout .checkout-button:hover{box-shadow:0 6px 20px rgba(0,0,0,.22)}
.wc-proceed-to-checkout .checkout-button:active{box-shadow:0 2px 8px rgba(0,0,0,.18)}

/* Reference's card treatment: white ground, hairline border, soft radius. The
   site-wide .card is borderless, so the border is added here only, on these
   cart surfaces, rather than by changing .card for every page that uses it.
   The coupon box is excluded on purpose - it sits flat on the white band
   (.bt-cart-lower), where a card surface would be invisible anyway. */
.bt-cart-table-card,.bt-cart-totals{border:1px solid var(--border)}

.bt-cart-table-card{padding:0;overflow:hidden;margin-bottom:20px}
.bt-cart-table{width:100%;border-collapse:collapse;font-size:var(--fs-ui)}
/* Dark header band, as in the reference. The card already clips to
   border-radius with overflow:hidden, so the dark fill rounds off at the top
   corners without needing its own radius. */
.bt-cart-table thead th{
  background:var(--forest);color:#fff;font-weight:var(--fw-semibold);
  text-align:left;padding:14px 16px;border-bottom:none;white-space:nowrap;
  font-size:var(--fs-label);text-transform:uppercase;letter-spacing:var(--ls-label);
}
.bt-cart-table tbody td{padding:9px 12px;border-bottom:1px solid var(--border);vertical-align:middle;color:var(--text2)}
.bt-cart-table tbody tr:last-of-type td{border-bottom:none}
/* The name column soaks up all free width so the narrow columns actually keep
   the widths set below — table-layout:auto otherwise spreads slack evenly. */
.bt-cart-table .product-name{width:100%}
.bt-cart-table .product-remove{width:54px;text-align:center}
.bt-cart-table .product-remove a.remove{
  display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;
  border-radius:50%;background:transparent;color:#dc2626;text-decoration:none;
  font-size:20px;line-height:1;transition:all .15s;
}
.bt-cart-table .product-remove a.remove:hover{background:#dc2626;color:#fff}
.bt-cart-table .product-thumbnail{width:104px;min-width:104px}
/* min-width + max-width:none are load-bearing: the global `img{max-width:100%}`
   (see RESET) resolves against a column the name cell's width:100% has already
   squeezed to min-content, which collapses the thumbnail to its border. */
.bt-cart-table .product-thumbnail img{
  width:72px;min-width:72px;max-width:none;height:72px;object-fit:cover;background:var(--ivory-d);
}
.bt-cart-table .product-name a{color:var(--text1);font-weight:var(--fw-semibold);text-decoration:none}
.bt-cart-table .product-name a:hover{color:var(--sage)}
.bt-cart-table .product-name dl.variation{margin:6px 0 0;font-size:var(--fs-xs);color:var(--ink-muted);display:flex;flex-wrap:wrap;gap:0 4px}
.bt-cart-table .product-name dl.variation dt{font-weight:var(--fw-semibold);color:var(--text2)}
.bt-cart-table .product-name dl.variation dd{margin:0}
.bt-cart-table .product-name dl.variation dd p{margin:0}
/* Body cells only. Unscoped, this also matched th.product-price /
   th.product-subtotal in the head, and at (0,2,0) it outranked
   `.bt-cart-table thead th` (0,1,2) - which painted those two header labels
   near-black on the dark header band while Product and Quantity, having no
   such rule, stayed white. */
.bt-cart-table tbody .product-price,.bt-cart-table tbody .product-subtotal{font-weight:var(--fw-semibold);color:var(--text1);white-space:nowrap}
/* Header and cell alignment stay paired per column so numbers line up. */
.bt-cart-table .product-price,.bt-cart-table th.product-price,
.bt-cart-table .product-quantity,.bt-cart-table th.product-quantity{text-align:center}
.bt-cart-table .product-subtotal,.bt-cart-table th.product-subtotal{text-align:right}
.bt-cart-table .product-quantity .quantity{display:inline-flex;justify-content:center}

.bt-cart-table td.actions{padding:16px;border-bottom:none;background:var(--ivory-d)}
.bt-cart-actions{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap}
.bt-cart-actions__continue,.bt-cart-actions__update{padding:12px 24px}
/* Muted + non-interactive while there are no unsaved quantity changes. The real
   `disabled` attribute drives this, so assistive tech gets the state too. */
.bt-cart-actions__update:disabled{background:var(--sage-xl);border-color:var(--sage-xl);color:var(--ink-muted);cursor:not-allowed}
.bt-cart-actions__update:disabled:hover{background:var(--sage-xl);border-color:var(--sage-xl);color:var(--ink-muted);transform:none}
.bt-cart-actions__update i,.bt-cart-actions__continue i{font-size:15px;line-height:1}

/* Layout only. The band's vertical rhythm is .bt-section's and its white
   ground is the shared band-grounds rule (.bt-cart-lower-section), both on the
   markup - this element no longer carries padding, margins or a background of
   its own, so the cart follows the same section system as every other page. */
.bt-cart-lower{display:grid;grid-template-columns:1fr 1fr;gap:40px;align-items:start}

/* The items card's own bottom margin would stack on top of the band padding. */
.bt-cart-section .bt-cart-table-card{margin-bottom:0}
/* The coupon box carries .card, whose white ground and shadow would be
   invisible on the white band, so its surface is stripped back off and it
   reads as the section's own content. Order Summary deliberately keeps its
   card (white ground, hairline border, shadow) as the one boxed element.
   The coupon box's vertical padding matches the card's so the two section
   headings sit on the same line - without it the card's 24px inset drops
   "Order Summary" 24px below "Discount Codes". Horizontal padding stays 0 so
   the flat column still starts on the page grid, flush with the card above. */
.bt-cart-lower__coupon{
  padding:24px 0;background:transparent;box-shadow:none;
  /* Transparent top/bottom border only, mirroring the card's 1px hairline, so
     both headings land on the exact same line. Left/right stay borderless so
     the column keeps starting flush on the page grid. */
  border:none;border-top:1px solid transparent;border-bottom:1px solid transparent;
}
.bt-cart-lower__totals .bt-cart-totals{padding:24px}
.bt-cart-lower__coupon h2,.bt-cart-totals h2{margin-bottom:10px}
.bt-cart-lower__coupon-hint{font-size:var(--fs-small);color:var(--ink-muted);margin-bottom:14px}
.bt-coupon-form__row{display:flex;flex-wrap:wrap;gap:10px}
/* Reference coupon field: cream ground, dashed gold rule, tag glyph.
   The glyph is a background-image rather than an added element so the input
   keeps its exact markup (name/id/placeholder) - WC_Form_Handler reads the
   same `coupon_code` field it always has. */
.bt-coupon-form__field{
  flex:1 1 200px;min-width:0;padding:14px 16px 14px 42px;
  border:1.5px dashed var(--gold);border-radius:12px;
  font-family:inherit;font-size:var(--fs-ui);color:var(--text1);
  background-color:#fdf8ec;outline:none;transition:border-color .2s,box-shadow .2s;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23a17f33'%3E%3Cpath d='M2 1a1 1 0 0 0-1 1v4.586a1 1 0 0 0 .293.707l7 7a1 1 0 0 0 1.414 0l4.586-4.586a1 1 0 0 0 0-1.414l-7-7A1 1 0 0 0 6.586 1H2zm2.5 4a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:16px center;background-size:16px 16px;
}
.bt-coupon-form__field::placeholder{color:var(--text3)}
.bt-coupon-form__field:focus{border-style:solid;border-color:var(--gold-d);box-shadow:0 0 0 3px rgba(201,162,74,.18)}
.bt-coupon-form__apply{flex:0 0 auto}

/* "Try:" hint row under the coupon field. Pure presentation — the chips are
   type="button", so they are inert apart from the one-line fill handler in
   assets/js/script.js. */
.bt-coupon-try{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin:14px 0 0}
.bt-coupon-try__label{font-size:var(--fs-xs);color:var(--text3)}
.bt-coupon-chip{
  display:inline-flex;align-items:center;padding:6px 14px;border-radius:9999px;
  border:1px solid var(--border);background:var(--ivory-d);color:var(--text1);
  font-family:inherit;font-size:var(--fs-xs);font-weight:var(--fw-semibold);
  letter-spacing:.3px;cursor:pointer;transition:background-color .2s,border-color .2s,color .2s;
}
.bt-coupon-chip:hover{background:var(--gold);border-color:var(--gold);color:#1c1c1c}
.bt-coupon-chip:focus-visible{outline:2px solid var(--gold-d);outline-offset:2px}

.bt-cart-totals__table{width:100%;border-collapse:collapse;font-size:var(--fs-ui);margin-bottom:18px}
.bt-cart-totals__table th,.bt-cart-totals__table td{padding:12px 0;text-align:left;border-bottom:1px solid var(--border);color:var(--text2);font-weight:var(--fw-medium);vertical-align:top}
.bt-cart-totals__table td{text-align:right}
.bt-cart-totals__table .woocommerce-shipping-methods{list-style:none;margin:0;padding:0}
.bt-cart-totals__table .woocommerce-shipping-methods label{cursor:pointer}
.bt-cart-totals__table tr:last-child th,.bt-cart-totals__table tr:last-child td{border-bottom:none}
.bt-cart-totals__table .order-total th,.bt-cart-totals__table .order-total td{
  font-weight:var(--fw-heading);color:var(--text1);border-top:2px solid var(--border);border-bottom:none;padding-top:18px;vertical-align:middle;
}
.bt-cart-totals__table .order-total th{font-size:var(--fs-h5)}
/* The grand total is the one figure the reference sets apart from the rest. */
.bt-cart-totals__table .order-total td{font-size:var(--fs-h3);line-height:1.1}
.bt-cart-totals__table .woocommerce-shipping-destination{display:block;margin-top:4px;font-size:var(--fs-xs);color:var(--ink-muted)}
.bt-cart-totals__table .shipping-calculator-button{color:var(--sage);font-weight:var(--fw-semibold);text-decoration:underline;font-size:var(--fs-xs)}

.bt-cart-trust-list{list-style:none;margin:14px 0 0;padding:0;display:flex;flex-direction:column;gap:8px}
.bt-cart-trust-list li{display:flex;align-items:center;gap:8px;font-size:var(--fs-xs);color:var(--ink-muted)}
.bt-cart-trust-list i{color:var(--gold-d);font-size:14px}

.bt-cart-empty{text-align:center;padding:56px 16px}
.bt-cart-empty__icon{font-size:48px;color:var(--border);display:block;margin-bottom:16px}
.bt-cart-empty .woocommerce-info{justify-content:center;display:inline-flex;margin:0 0 20px}
.bt-cart-empty__cta{display:inline-flex;padding:12px 28px}

/* Cart-page success notice ("Cart updated successfully."). Scoped to
   body.woocommerce-cart and to .woocommerce-message alone, so the shared
   notice style above still covers every other notice and every other page.
   This only re-skins where WooCommerce already prints the notice - it is not
   a second notice system. */
.woocommerce-cart .woocommerce-message{
  background:#fff;border:1px solid var(--border);border-left:4px solid var(--gold);
  border-radius:14px;padding:16px 20px;color:var(--text1);
  box-shadow:0 1px 2px rgba(0,0,0,.02),0 8px 24px rgba(0,0,0,.04);
}
.woocommerce-cart .woocommerce-message::before{color:var(--gold-d)}

/* ── Cart table: tablet + mobile card layout (<=1023px) ──────────────────
   The table becomes one card per line item. Breakpoint is 1023px, not 767px,
   so tablets get the cards too; everything else on the page (the two-column
   lower grid, the coupon field, the actions row) keeps its own 767px
   crossover in the block below and is untouched here.

   The quantity and subtotal cells are deliberately flush - column-gap is 0 and
   the horizontal spacing is padding inside each cell instead. That is what
   lets those two separate <td>s read as one continuous grey bar: they share a
   background and each rounds off only its outer corners. Merging them for real
   would need a wrapper element, which would mean changing the template. */
@media (max-width:1023px){
  .bt-cart-table,
  .bt-cart-table thead,
  .bt-cart-table tbody,
  .bt-cart-table tr,
  .bt-cart-table th,
  .bt-cart-table td{display:block;width:100%}

  /* Dark header band keeps only the two labels the design shows. The band
     colour moves to the row so the space between the two labels is dark too. */
  .bt-cart-table thead tr{
    display:flex;align-items:center;justify-content:space-between;
    background:var(--forest);padding:14px 16px;
  }
  .bt-cart-table thead th{display:none;background:transparent;padding:0;border:none}
  .bt-cart-table thead th.product-name,
  .bt-cart-table thead th.product-subtotal{display:block;width:auto}
  .bt-cart-table thead th.product-subtotal{text-align:right}

  /* One card per item:
       thumb | name     | remove
       thumb | price    | remove
       qty bar (spans)  | subtotal                                        */
  .bt-cart-table tbody tr.woocommerce-cart-form__cart-item{
    display:grid;
    grid-template-columns:72px 1fr auto;
    grid-template-areas:
      "thumb name  remove"
      "thumb price remove"
      "qty   qty   sub";
    row-gap:2px;column-gap:0;
    align-items:start;
    padding:16px;border-bottom:1px solid var(--border);
  }
  .bt-cart-table tbody td{padding:0;border:none;width:auto}

  .bt-cart-table tbody .product-thumbnail{grid-area:thumb;width:72px;min-width:72px}
  .bt-cart-table tbody .product-thumbnail img{
    width:72px;height:72px;object-fit:contain;background:#fff;
    border:1px solid var(--border);border-radius:12px;padding:4px;
  }

  .bt-cart-table tbody .product-name{
    grid-area:name;padding-left:14px;text-align:left;
    font-size:var(--fs-body);line-height:1.35;
  }
  .bt-cart-table tbody .product-name a{font-weight:var(--fw-semibold);color:var(--text1)}

  /* "$285.00 each" — the unit price reads as a caption under the name, so the
     table's bold dark treatment is dropped here. */
  .bt-cart-table tbody .product-price{
    grid-area:price;padding-left:14px;text-align:left;
    font-size:var(--fs-small);font-weight:var(--fw-body);color:var(--text3);
  }
  .bt-cart-table tbody .product-price::after{content:" each"}

  .bt-cart-table tbody .product-remove{grid-area:remove;width:auto;padding-left:10px;text-align:right}
  .bt-cart-table tbody .product-remove a.remove{
    width:30px;height:30px;background:#fdecea;font-size:18px;
  }

  /* Left half of the grey bar: the QTY caption and the stepper. */
  /* align-self overrides the row's `align-items:start` for these two cells
     only: start sizes each to its own content, and the stepper makes this half
     ~15px taller than the subtotal half, which stepped the "single bar" and
     left a square corner under the price. Stretching both to the row height is
     what keeps the two backgrounds reading as one continuous bar. */
  .bt-cart-table tbody .product-quantity{
    grid-area:qty;margin-top:12px;align-self:stretch;
    display:flex;align-items:center;justify-content:space-between;gap:12px;
    background:var(--ivory-d);border-radius:12px 0 0 12px;
    padding:10px 14px 10px 16px;text-align:left;
  }
  /* Literal text, not attr(data-title): the cell's title is "Quantity" and the
     design calls for "QTY". It is a visual caption only - the input keeps its
     own label for assistive tech. */
  .bt-cart-table tbody .product-quantity::before{
    content:"QTY";flex-shrink:0;
    font-size:var(--fs-label);font-weight:var(--fw-label);
    letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--text3);
  }

  /* Right half of the same bar. */
  .bt-cart-table tbody .product-subtotal{
    grid-area:sub;margin-top:12px;align-self:stretch;
    display:flex;align-items:center;justify-content:flex-end;
    background:var(--ivory-d);border-radius:0 12px 12px 0;
    padding:10px 16px 10px 0;
    font-size:var(--fs-h5);font-weight:var(--fw-heading);color:var(--text1);
    text-align:right;white-space:nowrap;
  }

  /* The actions row stays a plain block, not a card. */
  .bt-cart-table tr.bt-cart-actions-row td.actions{padding:16px;width:100%}
}

@media (max-width:767px){
  .bt-cart-lower{grid-template-columns:1fr;gap:32px}

  .bt-cart-actions{justify-content:stretch}
  .bt-cart-actions__continue,.bt-cart-actions__update{flex:1 1 auto;text-align:center;margin-left:0}

  .bt-coupon-form__field,.bt-coupon-form__apply{flex:1 1 100%;width:100%}
  .bt-cart-totals__table .order-total td{font-size:var(--fs-h4)}
}

/* My Account */
.woocommerce-MyAccount-navigation ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:4px}
.woocommerce-MyAccount-navigation li a{display:flex;align-items:center;gap:8px;padding:10px 16px;border-radius:10px;font-size:var(--fs-ui);font-weight:var(--fw-semibold);color:var(--text2);text-decoration:none}
.woocommerce-MyAccount-navigation li.is-active a{background:var(--sage);color:#fff}
.woocommerce-MyAccount-navigation li:not(.is-active) a:hover{background:var(--ivory-d)}

/* The page content area (behind the sidebar + content cards) is white here,
   not the sitewide --ivory cream — scoped to the body class WooCommerce adds
   on this page only, so the header, footer and every other page are
   untouched. The cards are already #fff with just a shadow (see .card), which
   reads fine on cream but disappears on white, so they get a visible border
   back on this page specifically. */
body.woocommerce-account{background:#fff}
body.woocommerce-account .card{border:1px solid #eee}

/* Dashboard tab intro — "Hello NAME (not NAME? Log out)" + the recent-orders /
   addresses / account-details paragraph (myaccount/dashboard.php). Plain body
   copy; only its inline links get the accent treatment, matching the one
   .woocommerce-info already uses for "Click here to enter your code". */
.bt-account-dashboard p{color:var(--ink-body);font-size:var(--fs-ui);line-height:var(--lh-body);margin-bottom:16px}
.bt-account-dashboard strong{color:var(--ink-heading)}
.bt-account-dashboard a{color:var(--gold-d);font-weight:var(--fw-heading);text-decoration:underline}
.bt-account-dashboard a:hover{color:var(--forest)}

.woocommerce-MyAccount-content table{width:100%;border-collapse:collapse;font-size:var(--fs-ui)}
.woocommerce-MyAccount-content table th,.woocommerce-MyAccount-content table td{padding:12px;border-bottom:1px solid rgba(0,0,0,.08);text-align:center;vertical-align:middle}
.woocommerce-MyAccount-content table thead th{background:var(--sage);color:#fff;font-size:var(--fs-label);font-weight:var(--fw-label);text-transform:uppercase;letter-spacing:.6px;border-bottom:none;padding:14px 12px}
.woocommerce-MyAccount-content table thead th:first-child{border-top-left-radius:var(--r)}
.woocommerce-MyAccount-content table thead th:last-child{border-top-right-radius:var(--r)}
.woocommerce-orders-table__cell-order-actions{text-align:center}
.woocommerce-orders-table__cell-order-status{font-weight:700;color:var(--gold-d)}
.woocommerce-MyAccount-content p{color:var(--ink-body);font-size:var(--fs-ui);margin-bottom:16px}
.woocommerce-Addresses.col2-set{display:grid;grid-template-columns:1fr;gap:16px;list-style:none;padding:0}
@media(min-width:640px){.woocommerce-Addresses.col2-set{grid-template-columns:1fr 1fr}}
.woocommerce-Address{border:1.5px solid var(--border);border-radius:var(--r);padding:18px}
.woocommerce-Address-title{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}
.woocommerce-Address-title h2{font-family:var(--font-base);font-size:var(--fs-h5);font-weight:var(--fw-semibold);color:var(--forest)}
.woocommerce-Address-title .edit{font-size:var(--fs-xs);font-weight:var(--fw-heading);color:var(--sage);text-decoration:none}
.woocommerce-Address address{font-style:normal;font-size:var(--fs-small);line-height:1.8;color:var(--ink-body)}
.woocommerce-MyAccount-content .woocommerce-form-row{margin-bottom:16px}
.woocommerce-MyAccount-content .woocommerce-form-row label{display:block;font-size:var(--fs-label);font-weight:var(--fw-label);color:var(--text2);margin-bottom:6px;letter-spacing:.6px;text-transform:uppercase}
.woocommerce-MyAccount-content .input-text{width:100%;padding:12px 16px;border:1.5px solid var(--border);border-radius:10px;font-family:inherit;font-size:var(--fs-ui);color:var(--text1);background:#fff;outline:none;transition:all .2s}
.woocommerce-MyAccount-content .input-text:focus{border-color:var(--sage);box-shadow:0 0 0 4px rgba(0,0,0,.06)}
.woocommerce-MyAccount-content fieldset{border:none;padding:0;margin:20px 0 0;background:none}
.woocommerce-MyAccount-content fieldset legend{font-family:var(--font-base);font-size:var(--fs-h5);font-weight:var(--fw-semibold);color:var(--forest);margin-bottom:14px;background:none;background-color:transparent;padding:0;border:none;width:auto}
.woocommerce-MyAccount-content #account_display_name_description{display:block;font-style:normal;font-size:var(--fs-xs);color:var(--text2);margin-top:4px}
.woocommerce-MyAccount-content button[type="submit"],.woocommerce-MyAccount-content input[type="submit"]{padding:12px 28px;background:var(--sage);color:#fff;border:none;border-radius:50px;font-size:var(--fs-ui);font-weight:700;cursor:pointer}
.clear{clear:both}

/* ═══ MISSING TAILWIND UTILITIES (this build is a purged/curated subset —
   these grid-span/column classes are used on pages but were never included
   when the CSS was generated, silently collapsing multi-column layouts to
   1 column) ═══ */
.col-span-3{grid-column:span 3/span 3}
@media (min-width:1024px){
  .lg\:col-span-1{grid-column:span 1/span 1}
  .lg\:col-span-2{grid-column:span 2/span 2}
  .lg\:col-span-3{grid-column:span 3/span 3}
  .lg\:col-span-4{grid-column:span 4/span 4}
  .lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}
}

/* ═══ MINI CART POPOVER ═══
   .bt-cart-trigger wraps the header cart button + the popover itself, so
   mouseenter/mouseleave on the single root covers both and the pointer can
   travel from icon to panel without it closing (hover-open is wired in
   header.php). The popover content is WooCommerce's own mini-cart template
   inside .widget_shopping_cart_content, kept in sync by wc-cart-fragments.js
   / the theme's own applyFragments() after every AJAX cart change. */
.bt-cart-trigger{position:relative}
.bt-mini-cart{
  position:absolute;top:calc(100% + 10px);right:0;z-index:120;
  width:360px;max-width:min(360px,calc(100vw - 24px));
  background:#fff;border:1px solid rgba(0,0,0,.08);border-radius:14px;
  box-shadow:0 20px 48px rgba(0,0,0,.16);padding:14px 16px 16px;
  opacity:0;visibility:hidden;transform:translateY(-6px);pointer-events:none;
  transition:opacity .16s ease,transform .16s ease,visibility .16s;
}
.bt-mini-cart.is-open{opacity:1;visibility:visible;transform:translateY(0);pointer-events:auto}
.bt-mini-cart .widget_shopping_cart_content{display:flex;flex-direction:column;max-height:420px}
.bt-cart-trigger--mobile .bt-mini-cart{right:-4px}

.woocommerce-mini-cart.cart_list{list-style:none;padding:0;margin:0;flex:1;overflow-y:auto;min-height:0}
.woocommerce-mini-cart .mini_cart_item{display:flex;align-items:flex-start;gap:12px;padding:16px 30px 16px 0;border-bottom:1px solid rgba(0,0,0,.07);position:relative}
.woocommerce-mini-cart .mini_cart_item img{width:56px;height:56px;object-fit:cover;border-radius:10px;flex-shrink:0}
.woocommerce-mini-cart .mini_cart_item a:not(.remove){display:flex;align-items:flex-start;gap:12px;text-decoration:none;color:var(--text1);font-size:var(--fs-small);font-weight:var(--fw-semibold);flex:1;min-width:0}
.woocommerce-mini-cart .mini_cart_item a:not(.remove) > *{min-width:0}
.woocommerce-mini-cart .mini_cart_item .quantity{display:block;font-size:var(--fs-xs);color:var(--ink-muted);font-weight:var(--fw-medium);margin-top:4px;white-space:normal;word-break:break-word}
.woocommerce-mini-cart .mini_cart_item .remove{position:absolute;top:16px;right:0;width:22px;height:22px;border-radius:50%;background:rgba(0,0,0,.06);display:flex;align-items:center;justify-content:center;color:var(--text2);text-decoration:none;font-size:16px;line-height:1;flex-shrink:0}
.woocommerce-mini-cart .mini_cart_item .remove:hover{background:rgba(220,38,38,.1);color:#dc2626}
.woocommerce-mini-cart__empty-message{text-align:center;color:var(--ink-muted);font-size:var(--fs-ui);padding:40px 0 16px}
.bt-mini-cart__continue{display:flex;margin:0 auto 4px}
.woocommerce-mini-cart__total{display:flex;justify-content:space-between;font-size:var(--fs-body);font-weight:var(--fw-heading);color:var(--text1);padding-top:14px;margin-top:4px;border-top:1px solid rgba(0,0,0,.07);flex-shrink:0}
.woocommerce-mini-cart__total strong{font-weight:var(--fw-heading)}
.woocommerce-mini-cart__buttons{display:flex;flex-direction:row;gap:10px;margin-top:14px;flex-shrink:0}
.woocommerce-mini-cart__buttons .button{display:flex;align-items:center;justify-content:center;flex:1;width:auto;padding:12px 10px;border-radius:9999px;font-size:var(--fs-ui);font-weight:var(--fw-semibold);text-decoration:none;cursor:pointer;transition:all .2s}
.woocommerce-mini-cart__buttons .wc-forward:not(.checkout){background:transparent;color:var(--text1);border:1px solid rgba(0,0,0,.19)}
.woocommerce-mini-cart__buttons .wc-forward:not(.checkout):hover{background:var(--sage);color:#fff;border-color:var(--sage)}
.woocommerce-mini-cart__buttons .checkout{background:var(--sage);color:#fff;border:1px solid var(--sage);order:-1}
.woocommerce-mini-cart__buttons .checkout:hover{background:var(--sage-d);border-color:var(--sage-d)}

@media (max-width:480px){
  .bt-mini-cart{width:min(340px,calc(100vw - 16px))}
}

#btCheckoutBody .max-w-6xl,#btCheckoutBody .max-w-2xl{max-width:100%}
#btCheckoutBody .woocommerce-NoticeGroup-checkout{margin-bottom:16px}
#btCheckoutBody .grid{display:flex !important;flex-direction:column !important}
#btCheckoutBody .grid > div{width:100% !important}
#btCheckoutBody [id="order_review"]{position:static !important}

/* Wide editor tables scroll sideways instead of squeezing their columns —
   but only where the screen actually forces it. `display:block` turns the
   <table> into a plain block box with an anonymous, shrink-to-fit table
   inside it, so a table narrower than the text column no longer fills the
   box: the ruled cells stop short of the bordered, rounded edge added in the
   EDITOR TABLES block and leave a bare white strip down the right. At
   desktop widths the table therefore stays a real table, where width:100%
   makes the cells and the border edge agree. Below this breakpoint a table
   wide enough to need scrolling is wider than the box, so the content runs
   under a correctly-placed border and the mismatch cannot show. */
/* Editor tables stay real tables at every width.
   `display:block;overflow-x:auto` used to live here to let a wide table
   scroll sideways on a phone, and it has to go: display:block turns the
   <table> into a block box with an anonymous, SHRINK-TO-FIT table inside,
   so the box still spans 100% while the cells stop wherever their content
   ends. Measured in the harness at 768px: box right edge 735px, last cell
   right edge 140px — 595px of empty white panel with a border and a rounded
   corner around nothing. At 375px, 234px of it. Invisible before the EDITOR
   TABLES block, because a collapsed table with no border or background had
   nothing to reveal the gap.

   Nothing is lost on the case this is actually for. A Gutenberg table sits
   in core's own `.wp-block-table{overflow-x:auto}` <figure>, so it still
   scrolls on a phone — the figure scrolls, the table inside it fills. Only
   a bare table (classic editor, or HTML pasted into a Code block) gives up
   scrolling, and it wraps instead: .product-desc already sets
   word-break:break-word, which cells inherit, so the table's min-content
   width collapses and it fits a 375px screen rather than pushing the page
   sideways. Verified doc scrollWidth == viewport at 1280/768/375. */
.product-desc table{max-width:100%}

/* product description: tighter, readable layout on small screens */
.product-desc{overflow-wrap:break-word;word-break:break-word}
/* Phone: spacing only. The prose used to drop to 13.5px here and flatten
   every heading to one 1.25em size — both are gone: body copy stays at the
   one global --fs-body so it reads the same on every device, and the
   heading sizes are already the clamp() minima at this width, so the
   hierarchy survives instead of collapsing. */
@media(max-width:480px){
  .product-desc table th,.product-desc table td{padding:.5em .7em}
  .product-desc ul,.product-desc ol{padding-left:1.1em}
}

/* ═══ MY ACCOUNT — ORDERS TABLE ═══
   WooCommerce's default orders table (Order / Date / Status / Total / Actions)
   has too many columns to fit a phone screen; without an explicit scroll
   container the columns squeeze and wrap, breaking the row layout. Give it
   the same horizontal-scroll treatment already used for other wide tables
   in this theme (.product-desc table) instead of letting it collapse. */
.woocommerce-MyAccount-content table{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch;white-space:nowrap}
.woocommerce-MyAccount-content table thead,.woocommerce-MyAccount-content table tbody,.woocommerce-MyAccount-content table tr{display:table;width:100%;table-layout:fixed}
.woocommerce-orders-table__cell-order-actions{white-space:nowrap}
.woocommerce-orders-table__cell-order-actions .button{display:inline-flex;align-items:center;justify-content:center;padding:6px 14px;border-radius:50px;background:var(--sage);color:#fff;font-size:var(--fs-label);font-weight:var(--fw-heading);text-decoration:none;margin:2px}

/* ═══ BLOG — CATEGORY BADGE ON POST CARDS / SINGLE POST ═══ */
.bt-post-cats{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}
.bt-post-cat-badge{display:inline-flex;align-items:center;font-size:var(--fs-2xs);font-weight:var(--fw-label);letter-spacing:.5px;text-transform:uppercase;color:var(--sage);background:rgba(0,0,0,.05);border-radius:50px;padding:3px 10px;text-decoration:none}
.bt-post-cat-badge:hover{background:var(--sage);color:#fff}

/* ═══ BLOG — SINGLE POST META ROW (single.php) ═══
   "Posted on <date> by <author>" on the left, "Category: <name>" on the
   right, one inline row above the title — replaces the old standalone
   category-badge block + separate posted-on line. Date links to the
   homepage, author name links to the author page, category links to its
   archive — all plain-text labels stay un-linked, only the values. */
.bt-post-meta{
  display:flex;align-items:center;justify-content:left;flex-wrap:wrap;
  gap:8px 200px;margin-bottom:16px;font-size:var(--fs-small);color:var(--text3);
}
.bt-post-meta__posted a{color:var(--text1);font-weight:var(--fw-semibold);text-decoration:underline}
.bt-post-meta__posted a:hover{color:var(--gold-d)}
.bt-post-meta__cat a{color:var(--sage);font-weight:var(--fw-semibold);text-decoration:underline}
.bt-post-meta__cat a:hover{color:var(--gold-d)}
@media (max-width:480px){
  .bt-post-meta{flex-direction:column;align-items:flex-start;gap:6px}
}

/* ═══ HOMEPAGE CATEGORY RAIL — edge fade + breathing room ═══
   The horizontally-scrolling category rail had no visual cue that it
   continues past the viewport edge (no fade/gap), so it read as an
   arbitrarily-cropped row rather than a deliberate scrollable rail. */
#catTrackWrap{position:relative}
/* Edge fades span the full rail now that its vertical padding is symmetric
   (the old bottom:32px matched the rail's old 32px bottom-only padding). */
#catTrackWrap::before,#catTrackWrap::after{content:'';position:absolute;top:0;bottom:0;width:48px;z-index:2;pointer-events:none}
#catTrackWrap::before{left:0;background:linear-gradient(to right,#fff,transparent)}
#catTrackWrap::after{right:0;background:linear-gradient(to left,#fff,transparent)}

/* ═══ HEADER SEARCH — live suggestions dropdown ═══ */
.bt-search-wrap{position:relative}
.bt-search-suggest{position:absolute;top:calc(100% + 8px);left:0;right:0;background:#fff;border:1px solid rgba(0,0,0,.08);border-radius:14px;box-shadow:0 16px 40px rgba(30,58,30,.14);overflow:hidden;z-index:210;display:none;max-height:360px;overflow-y:auto}
.bt-search-suggest.is-open{display:block}
.bt-search-suggest a{display:flex;align-items:center;gap:10px;padding:10px 14px;text-decoration:none;color:var(--text1);font-size:var(--fs-small);border-bottom:1px solid rgba(0,0,0,.05)}
.bt-search-suggest a:last-child{border-bottom:none}
.bt-search-suggest a:hover,.bt-search-suggest a.is-active{background:rgba(0,0,0,.04)}
.bt-search-suggest img{width:32px;height:32px;object-fit:cover;border-radius:6px;flex-shrink:0;background:var(--ivory-d)}
.bt-search-suggest .bt-ss-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bt-search-suggest .bt-ss-price{font-weight:var(--fw-heading);color:var(--sage);flex-shrink:0;font-size:var(--fs-xs)}
.bt-search-suggest .bt-ss-empty{padding:14px;font-size:var(--fs-small);color:var(--ink-muted);text-align:center}

/* ═══ HOMEPAGE BENEFITS / TRUST BAR ═══
   A white band of its own - deliberately NOT the hero's cream. The hero's
   closing wave is filled white to match (see front-page.php), so the seam
   above is clean, and a hairline at the bottom keeps this band distinct from
   the white categories section that follows. No card: all the weight sits in
   the four items - a raised circular icon medallion, the label, and a short
   gold accent rule - separated by hairlines that fade out at both ends rather
   than solid borders. Mobile-first: 2x2 until 1024px, then one row of four. */
/* Padding comes from the shared --sec-y-sm token (see :root) so the
   band matches the other compact bands and is symmetric top/bottom. */
/* No bottom hairline any more: the band is white between two ivory bands
   (the hero above, Best Sellers below), so the colour change is the
   separator and a rule on top of it was a second, redundant one. */
.bt-benefits{background:#fff;padding:var(--sec-y-sm) 0}
.bt-benefits-row{display:grid;grid-template-columns:repeat(2,1fr);row-gap:34px}
.bt-benefit{
  position:relative;display:flex;flex-direction:column;align-items:center;
  text-align:center;gap:12px;padding:4px 12px;
  animation:fadeUp .7s cubic-bezier(.22,.61,.36,1) both;
}
.bt-benefit:nth-child(1){animation-delay:.04s}
.bt-benefit:nth-child(2){animation-delay:.12s}
.bt-benefit:nth-child(3){animation-delay:.20s}
.bt-benefit:nth-child(4){animation-delay:.28s}
/* Separator: a hairline that fades to transparent top and bottom. Only items
   with a preceding sibling get one, so the 2n+1 rule clears the first item of
   each row on mobile; at 1024px it is re-enabled for the 4-up row. */
.bt-benefit+.bt-benefit::before{
  content:'';position:absolute;left:0;top:50%;transform:translateY(-50%);
  width:1px;height:78%;
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.13),transparent);
}
.bt-benefit:nth-child(2n+1)::before{display:none}
.bt-benefit-ico{
  width:64px;height:64px;flex-shrink:0;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--ivory-d);
  border:1px solid rgba(0,0,0,.06);
  box-shadow:0 10px 22px -14px rgba(0,0,0,.45),inset 0 1px 0 #fff;
  transition:transform .35s cubic-bezier(.22,.61,.36,1),box-shadow .35s ease,
             background .35s ease,border-color .35s ease;
}
.bt-benefit-ico i{font-size:26px;line-height:1;color:var(--sage);transition:color .35s ease}
.bt-benefit-title{
  font-family:var(--font-base);
  font-size:var(--fs-ui);font-weight:var(--fw-semibold);color:var(--forest);line-height:1.4;letter-spacing:.2px;
}
.bt-benefit-rule{
  display:block;width:22px;height:2px;margin-top:-2px;border-radius:99px;
  background:rgba(201,162,74,.45);transition:width .35s ease,background .35s ease;
}
/* Hover: the medallion lifts and inverts, the gold rule widens. */
.bt-benefit:hover .bt-benefit-ico{
  background:var(--sage);border-color:var(--sage);
  transform:translateY(-4px);box-shadow:0 16px 28px -16px rgba(0,0,0,.6);
}
.bt-benefit:hover .bt-benefit-ico i{color:#fff}
.bt-benefit:hover .bt-benefit-rule{width:34px;background:var(--gold)}

@media (min-width:768px){
  .bt-benefit{padding:4px 18px}
  .bt-benefit-title{font-size:var(--fs-body)}
}
/* Desktop: one row of four, hairlines between all of them. */
@media (min-width:1024px){
  .bt-benefits-row{grid-template-columns:repeat(4,1fr);row-gap:0}
  .bt-benefit{padding:4px 24px}
  .bt-benefit:nth-child(2n+1)::before{display:block}
  .bt-benefit:first-child::before{display:none}
  .bt-benefit-ico{width:68px;height:68px}
  .bt-benefit-ico i{font-size:27px}
  .bt-benefit-title{white-space:nowrap}
}

/* ═══ HOMEPAGE SECTION RHYTHM ═══════════════════════════════
   Every band on the front page gets its vertical space from the
   --sec-* tokens instead of a per-section inline padding, so the
   top and bottom of a section always match and every section
   scales at the same two breakpoints. Where a child already
   contributes space at one edge (the category rail's own padding,
   the hero's closing wave) the section subtracts that amount so
   the *visible* gap stays symmetric — that is the fix for the
   "small top / large bottom" bands, rather than nudging the
   individual elements inside them. */
/* One band rhythm for the whole site. The old .bt-section-sm alias was
   removed in the Oct 2026 cleanup — no markup carried it, and there is no
   longer a "compact band" tier. Use .bt-section on new markup. */
.bt-section{padding-top:var(--sec-y);padding-bottom:var(--sec-y)}

/* ─── Band grounds ───
   Every full-width band on the site stands on one of exactly two surfaces:
   white, or --ivory. That was sixteen separate one-line rules scattered
   through this file — one per band, each re-declaring the same colour — so a
   palette change meant finding all sixteen. They are two rules now, and a new
   band joins by adding its class to one of them rather than writing a
   seventeenth background.

   Nothing else moves: these set a background and nothing more, so padding,
   width and type stay .bt-section's and each component's own job.

   ORDER MATTERS. .ab-points--cream is a modifier of .ab-points, and both are
   one class deep — so the cream rule must stay BELOW the white one for it to
   win. Keep them in this order. It exists because the About page alternates
   cream / white from "Supporting Buyers" down to its CTA, and that second band
   is a second .ab-points. */
.bt-news,.bt-cta,.ab-points,.ab-cat,.ab-faq,
.sh-products,.bt-helpcta,.bl-cats,.privacy-overview,.policy-note,
.rc-strip,.ss-assure,.bt-cart-lower-section{background:#fff}

.bt-trust,.ab-points--cream,.ab-values,.ab-vm,
.sh-faq,.policy-content,.pp-faq{background:var(--ivory)}
/* Heading + subtitle block that introduces a section's content. */
.bt-section-head{margin-bottom:var(--sec-head-gap)}
.bt-section-title{
  font-size:var(--fs-h2);
  font-weight:var(--fw-heading);
  line-height:var(--lh-heading);
  letter-spacing:var(--ls-heading);
  color:var(--ink-heading);
  margin:0;
  text-wrap:balance;
}
/* The site's one title accent: a gold phrase inside the heading. Was
   declared four times (.ab-hero__title em, .bt-why__title em,
   .bt-privacy__title em, .bt-promise__title em) with three colours. */
.bt-section-title em{font-style:normal;color:var(--gold)}

/* Dark-band variant — .bt-promise and any other inverted panel. */
.bt-section-title--invert{color:#fff}
.bt-section-title--invert em{color:var(--gold-l)}
/* There is deliberately no max-width/measure modifier. The five different
   ch caps the About headings each carried (15ch/17ch/18ch/20ch/24ch) were
   pre-`text-wrap:balance` workarounds for orphaned last words; the base
   rule above sets balance once, which does the same job without forcing a
   one-line title onto two lines. The container (max-w-6xl / max-w-7xl) is
   what bounds the measure. */
/* Sits under an eyebrow / badge pill. Replaces four different top gaps
   (10px, 12px, 14px, 18px). */

/* Accent phrase drops to its own line (.bt-privacy's two-line heading). */
.bt-section-title--stack em{display:block}
/* Title with copy directly beneath it in the same column, rather than a
   .bt-section-head block below it (.bt-why, .bt-serve). */
.bt-section-title--lead{margin-bottom:18px}
.bt-section-sub{margin:10px auto 0;max-width:560px;font-size:var(--fs-body);line-height:var(--lh-body);color:var(--ink-muted)}
/* A link/button that belongs to the heading block rather than to the
   section's content — sits under the title in the same centred column.
   .bt-blog-cta is the same control below a grid instead of below a title,
   so the two share everything except how far they sit from what precedes
   them. flex+center rather than text-align so the pill keeps its intrinsic
   width and can still shrink inside the 16px gutter on a narrow phone. */
.bt-head-cta,.bt-blog-cta{display:flex;justify-content:center}
.bt-head-cta .btn-sage,.bt-blog-cta .btn-sage{max-width:100%}
.bt-head-cta{margin-top:18px}
.bt-blog-cta{margin-top:32px}
/*blog single page date-time text color*/
.date-time{
  color: black; font-weight: 600;
}

/* HERO — centred content in a tall band. The closing wave is 64px
   of the section's own height and sits over the bottom edge, so
   without reserving it the centred block reads as sitting low.
   The reserve keeps the optical centre true; the inner padding is
   what defines the gap on a short viewport where min-height is
   not in play. */
.bt-hero{position:relative;overflow:hidden;display:flex;align-items:center;padding-bottom:64px}
/* The two-column hero's headline and standfirst (.bt-hero-title /
   .bt-hero-sub) are gone with the markup that used them: the homepage hero
   is now a banner image only. */
@media (min-width:1024px){
  .bt-hero{min-height:92vh}
}

/* HERO BANNER — the homepage hero is a Featured image and nothing else, so
   the band is sized by the image rather than by a text column. That is why
   this variant drops the 92vh min-height and the flex centring the
   two-column hero needed: display:block, with the image's own width now
   set by its .max-w-7xl.mx-auto.px-4 wrapper (the same container class
   every other homepage section uses — see front-page.php) rather than by
   the section. That is what keeps the banner's left/right edges lined up
   with Best Sellers, the benefits bar, the blog grid, etc. at every
   viewport width AND at every browser zoom level: they are all reading the
   same max-width + padding box, instead of the banner tracking 100vw while
   the rest of the page tracks a px-based max-width (the two drift apart
   under zoom because vw and px do not scale identically).
   min-height:0 is load-bearing, not tidying: .bt-hero carries a 92vh
   min-height above 1024px for the old two-column hero, and a banner-only
   band must not inherit it. Without this the section stays 92vh tall while
   the image inside it is capped at the container's max-width, which on a
   large monitor — or any zoomed-out viewport, where 92vh is a far bigger
   box than the banner — leaves hundreds of pixels of empty white between
   the wave and the benefits bar. */
.bt-hero--banner{display:block;padding-bottom:0;min-height:0;height:auto}
/* overflow:hidden clips the wave's bottom:-1px overhang. That 1px is there
   to guarantee no sub-pixel seam between wave and image at fractional zoom
   levels; clipping it here is what stops the same 1px reading as a stray
   hairline under the banner. */
.bt-hero-banner-media{position:relative;overflow:hidden;line-height:0}
/* The wave overlays the bottom of the banner artwork rather than sitting in
   reserved space below it, so z-index:2 is needed to lift it above the
   image, which is otherwise the later-painted element since it comes first
   in the DOM but is the taller box.
   aspect-ratio, not vw or clamp(), is what sizes it: a vw unit tracks the
   viewport, which is no longer the same box as the banner now that the
   banner's width is capped by max-w-7xl, and neither vw nor clamp() moves
   at all when the page is zoomed, the way a dimension relative to the
   banner's own (zoom-scaled) width does. 1440/100 matches the SVG's own
   viewBox, so the wave is always ~7% of the banner's width tall, on a 320px
   phone, a 2560px monitor or that monitor zoomed to 50%/200%, with no
   separate breakpoint logic needed. The taller ratio below 768px is the
   one deliberate exception, purely for legibility at small sizes. */
.bt-hero--banner .wave-b{
  z-index:2;aspect-ratio:1440/100;width:100%;height:auto;
}
.bt-hero--banner .wave-b svg{display:block;width:100%;height:100%}
@media (max-width:767px){
  .bt-hero--banner .wave-b{aspect-ratio:1440/160}
}
/* Balances the white gap the wave's removal of the hero's own bottom
   padding leaves above the benefits bar. This is ordinary section rhythm,
   not something that needs to track the banner's width or zoom level like
   the wave above, so a clamp() here is fine. */
.bt-hero--banner + .bt-benefits{padding-top:clamp(30px,6vw,70px)}
/* height:auto, not a fixed aspect-ratio + object-fit:cover: this is one
   baked-in image with its text and coupon code inside the artwork, so
   cropping it — to a fixed ratio, or via a viewport-height cap — would risk
   cutting that content off on some width/zoom combination. Scaling by
   width alone keeps the whole image visible and in proportion everywhere;
   the image's own intrinsic ratio reserves its box before load, so there
   is no layout shift. */
/* The whole banner is a link to the Shop page (front-page.php).
   display:block so the <a> is exactly the image's box and adds no inline
   descender strip of its own, and so the clickable area is the artwork
   rather than a text-sized line inside it. No hover or focus styling of
   its own: the site-wide a:focus-visible ring already covers the keyboard
   state, and a banner that changed colour on hover would fight the
   artwork. */
.bt-hero-banner-link{display:block}

/* The wave is decoration (its <svg> is aria-hidden) but it is painted at
   z-index:2 OVER the bottom of the banner, so without this it would
   swallow every click that lands on the bottom strip of the link.
   Scoped to this banner: the same .wave-b sits in the shop and About
   heroes, where there is no link underneath and nothing to let through. */
.bt-hero-banner-media .wave-b{pointer-events:none}

.bt-hero-banner-img{
  display:block;width:100%;height:auto;
}

/* CATEGORY RAIL — the rail carries its own vertical padding so the
   hover lift and its drop shadow are not clipped by the scroll
   container. That padding is symmetric here (it used to be 10px
   top / 32px bottom) and the section subtracts it from both its
   own bottom padding and the heading gap, so the band still reads
   as one --sec-y of space above and below. */
/* Horizontal padding matches the 16px page gutter on phones, where 40px a
   side ate a fifth of the viewport, and opens up to 40px from 640px where
   there is room for the hover lift's shadow to clear the scroll box. */
.bt-cat-track{
  display:flex;gap:60px;overflow-x:auto;
  padding:var(--cat-rail-y,24px) 16px;scroll-padding-left:16px;
  justify-content:safe center;
}
@media (min-width:640px){
  .bt-cat-track{padding-left:40px;padding-right:40px;scroll-padding-left:40px}
}
/* The rail scrolls but hides its scrollbar — the edge fade masks on
   #catTrackWrap are the affordance. These two rules lived in front-page.php's
   inline <style>, split from the .bt-cat-track rules they belong to. */
.bt-cat-track{-ms-overflow-style:none;scrollbar-width:none}
.bt-cat-track::-webkit-scrollbar{display:none}
/* The rail carries its own symmetric --cat-rail-y padding, so the band
   subtracts that amount again at both edges and the VISIBLE gap still comes
   out as one --sec-y above and one --sec-head-gap below the heading.

   max(0px, …) because the subtraction is only safe while the tokens are
   larger than the rail padding. They are not any more at the phone step
   (--sec-head-gap is 22px against a 24px rail), and a bare calc() would hand
   margin-bottom a negative value there and pull the icons up into the
   subtitle. Clamped, the worst case is simply no extra gap on top of the
   rail's own — never an overlap. */
.bt-cats{padding-bottom:max(0px,calc(var(--sec-y) - var(--cat-rail-y,24px)))}
.bt-cats .bt-section-head{margin-bottom:max(0px,calc(var(--sec-head-gap) - var(--cat-rail-y,24px)))}

/* ═══ ANNOUNCEMENT BAR ═══
   Three columns: phone (left) / shipping message (centered) / currency
   switcher (right). The grid's 1fr auto 1fr keeps the middle cell centered on
   the container regardless of how wide the two side cells are, which a plain
   flex row with justify-content:space-between could not do. */
.bt-announce{
  background:linear-gradient(90deg,var(--sage) 0%,var(--forest-l) 50%,var(--sage) 100%);
  background-size:200% 100%;animation:shimmer 8s linear infinite;
}
.bt-announce__inner{
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  gap:12px;padding-top:8px;padding-bottom:8px;
}
.bt-announce__phone{
  justify-self:start;display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
  font-size:var(--fs-xs);font-weight:var(--fw-semibold);color:rgba(255,255,255,.85);text-decoration:none;
  transition:color .2s;
}
.bt-announce__phone:hover{color:#fff}
.bt-announce__phone i{color:var(--gold-l);font-size:var(--fs-xs)}
.bt-announce__msg{
  grid-column:2;justify-self:center;display:inline-flex;align-items:center;gap:6px;
  font-size:var(--fs-xs);font-weight:var(--fw-semibold);color:rgba(255,255,255,.9);text-align:center;
  min-width:0;max-width:100%;
}
.bt-announce__msg i{color:var(--gold-l);flex-shrink:0}
/* The icon stays fixed-size; only the text truncates with an ellipsis if the
   row ever gets too tight to fit (very narrow phones, long converted prices) —
   without this the raw text just overflowed its grid column and visually
   overlapped the currency switcher next to it. */
.bt-announce__msg-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
/* grid-column is pinned explicitly (rather than relying on source order)
   because .bt-announce__phone is display:none below 1024px — an implicit grid
   would collapse msg/currency into columns 1/2 instead of the intended 2/3
   once the phone item stops taking a slot, throwing currency into the middle.
   This wrapper is intentionally NOT the mu-plugin's data-mam-dock target
   (see the comment in header.php) — it's a plain positioning/visibility box
   so hiding it below 1024px (see the @media block further down) can never be
   fought by the plugin's own inline styles. */
.bt-announce__currency{grid-column:3;justify-self:end;min-width:0}
/* This inner element IS the dock target. space-between (rather than
   flex-end) matches what the mu-plugin's dock script would otherwise force
   onto it; the docked child's own margin-left:auto is what right-aligns it.
   Pre-declaring display:flex + justify-content here means dockInto()'s own
   "is it already flex?" / "is justify-content already space-between?" checks
   both pass, so it never needs to add its own inline styles at all. */
.bt-announce__currency-dock{display:flex;align-items:center;justify-content:space-between;min-width:0}

/* The mu-plugin's docked styles use border:1px solid currentColor and set an
   inline color picked by reading the dock target's *background-color*. This bar
   paints its dark background with a gradient, so that read returns transparent,
   the script walks up to the light <body> and picks near-black — producing black
   text and a black border on a dark bar. Pin both to the theme palette here;
   !important is needed only to beat that inline color. */
.bt-announce .mam-currency-switcher{
  font:inherit;font-size:var(--fs-xs);gap:6px;color:rgba(255,255,255,.9) !important;
}
.bt-announce .mam-currency-switcher label{color:rgba(255,255,255,.6);opacity:1;font-weight:600}
.bt-announce .mam-currency-switcher select{
  -webkit-appearance:none;appearance:none;
  background-color:rgba(255,255,255,.08);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%23e8d9a0' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M1.5 2 6 6.5 10.5 2'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 8px center;background-size:9px 6px;
  border:1px solid rgba(255,255,255,.18);border-radius:50px;
  padding:3px 22px 3px 10px;font-family:inherit;font-size:var(--fs-xs);font-weight:var(--fw-heading);
  color:#fff;opacity:1;cursor:pointer;line-height:1.5;
}
.bt-announce .mam-currency-switcher select:hover{background-color:rgba(255,255,255,.14);border-color:rgba(255,255,255,.3)}
.bt-announce .mam-currency-switcher select option{color:var(--text1);background:#fff}
.bt-announce .mam-currency-switcher__note{color:rgba(255,255,255,.55);opacity:1;font-size:var(--fs-label)}

@media(max-width:1023px){
  .bt-announce .mam-currency-switcher__note{display:none}
}
@media(max-width:1023px){
  .bt-announce__inner{gap:8px}
  .bt-announce__msg{font-size:var(--fs-label)}
  /* Phone and currency both move into the mobile drawer footer
     (header.php, #btMobileDrawer) below 1024px — matching the
     hamburger/drawer's own crossover point (.bt-mobile-bar further down),
     not the old 768px — the announcement bar keeps only the shipping
     message, which — with both side items gone — sits centered in its own
     grid column (see .bt-announce__msg's base grid-column:2;justify-self:center
     rule above). */
  .bt-announce__phone,.bt-announce__currency{display:none}
}
@media(max-width:639px){
  .bt-announce__msg{font-size:10.5px}
}

/* ═══ ACCESSIBILITY — visible keyboard focus ═══
   Interactive elements had no explicit focus style, relying on each
   browser's own default outline (inconsistent, and invisible on the glass
   navbar / dark footer). Give every focusable control a consistent,
   high-contrast focus ring for keyboard users. */
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,.btn-sage:focus-visible,.btn-gold:focus-visible,.btn-outline:focus-visible{
  outline:2.5px solid var(--gold-d);outline-offset:2px;border-radius:4px;
}
footer a:focus-visible{outline-color:var(--gold-l)}

/* ═══ SCREEN-READER TEXT ═══
   .screen-reader-text is the class WordPress core and WooCommerce both emit
   for text meant only for assistive tech, and a theme is expected to supply
   the rule. This one never did, so every one of those strings was rendering
   as ordinary visible copy — most visibly WooCommerce's "Price range: $100.00
   through $448.00" printed under the price on each variable product card, and
   the catalogue-ordering form's own label. Declaring it hides all of them at
   once, site-wide, and keeps them announced.

   :focus is the standard exception: a skip-link must become visible when it
   is tabbed to, which is the one time this text is meant to be seen. */
.screen-reader-text{
  position:absolute !important;
  width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;white-space:nowrap;border:0;
  clip:rect(0,0,0,0);clip-path:inset(50%);
}
.screen-reader-text:focus{
  position:static !important;
  width:auto;height:auto;margin:0;overflow:visible;white-space:normal;
  clip:auto;clip-path:none;
}

/* ═══ HOMEPAGE — LATEST FROM OUR BLOG ═══
   Mirrors the Best Sellers section: same container, same .bt-section
   rhythm, same .card surface and hover lift. The grid is its own class
   rather than .grid-products because posts need 3 columns (not 4) and a
   single column on phones — a 2-up phone layout would squeeze the
   excerpt to an unreadable width. The media box uses aspect-ratio so
   every card's image is identically tall whatever the upload's
   dimensions, and object-fit:cover prevents stretching. */
.bt-blog-grid{display:grid;grid-template-columns:1fr;gap:20px}
@media (min-width:640px){.bt-blog-grid{grid-template-columns:repeat(2,1fr)}}
@media (min-width:1024px){.bt-blog-grid{grid-template-columns:repeat(3,1fr);gap:24px}}

.bt-blog-card{overflow:hidden;display:flex;flex-direction:column;text-decoration:none;height:100%}
/* Solid --ivory-d behind the image rather than a two-stop gradient: it is
   the same fill the category medallions and benefit chips use, so every
   "empty surface" on the homepage is one colour. */
.bt-blog-media{position:relative;aspect-ratio:16/10;overflow:hidden;background:var(--ivory-d);flex-shrink:0}
.bt-blog-media img{width:100%;height:100%;object-fit:cover;object-position:center;display:block;transition:transform .5s ease}
.bt-blog-card:hover .bt-blog-media img{transform:scale(1.06)}
/* ── Listing pages: whole image, edge to edge ──
   Used by home.php (the posts page) and category.php.

   History, because this has moved twice. Those cards started with a
   hardcoded height:190px on a .prod-img-wrap class that carried no CSS at
   all, which made the slot ~1.95:1 on a 400px desktop card and sliced the
   top and bottom off every featured image — differently at every
   breakpoint, since the height was fixed while the card width was not.
   Moving them onto .bt-blog-media fixed the inconsistency but, with
   object-fit:contain, left ivory bars down the sides of anything that was
   not exactly 16/10.

   So the box stops dictating a height here. aspect-ratio:auto drops the
   16/10 slot and height:auto on the image lets it render at its own
   proportions at full card width: nothing is cropped and there are no bars,
   which is the "cover the full width and still show the whole image" the
   brief asks for — the two are only reconcilable by letting the image's own
   ratio win. object-fit has nothing left to do once the box fits the image,
   but it is reset anyway so it cannot be inherited from the rule above.

   The cost, and it is the real one: cards in the same row no longer have
   identical image heights, so their titles can sit a few pixels apart when
   two uploads have different ratios. With the current posts (1.50 and 1.56)
   that is about 10px. A portrait upload would make one card markedly
   taller — if that ever happens, the fix is to crop the upload, not to put
   a fixed ratio back.

   Same specificity as the .bt-blog-media rules these override (0,1,1), so
   they must stay below them — keep them adjacent.

   No hover zoom here on purpose: these cards are .card.product-card, not
   .bt-blog-card, so that rule never reached them. */
.bt-blog-media--fit{aspect-ratio:auto;height:auto}
.bt-blog-media--fit img{width:100%;height:auto;object-fit:fill}

/* Fallback when a post has no featured image: the theme's own journal
   glyph on the card's own tint, never a stand-in photo. */
.bt-blog-media-fallback{width:100%;height:100%;display:flex;align-items:center;justify-content:center}
.bt-blog-media-fallback i{font-size:46px;color:rgba(0,0,0,.14)}

.bt-blog-body{padding:18px;display:flex;flex-direction:column;flex:1}
.bt-blog-date{font-size:var(--fs-2xs);font-weight:var(--fw-label);color:var(--sage);text-transform:uppercase;letter-spacing:.7px;margin-bottom:8px;display:inline-flex;align-items:center;gap:6px}
/* Card title = the h4 tier; the class contributes the 2-line clamp and the
   gap below it, not a size of its own. */
.bt-blog-title{font-size:var(--fs-h4);font-weight:var(--fw-semibold);color:var(--forest);line-height:var(--lh-heading-sm);margin-bottom:10px;
  display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.bt-blog-excerpt{font-size:var(--fs-small);color:var(--ink-muted);line-height:var(--lh-small);margin:0;
  display:-webkit-box;-webkit-line-clamp:3;line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}

/* The single CTA under this grid is .bt-blog-cta, defined with .bt-head-cta
   in the section-rhythm block above — the two are the same control. */

/* ═══ ACCESSIBILITY — respect reduced-motion preference ═══
   Sheen sweeps, AOS scroll-reveals, floating/blob/pulse loops and marquee
   scrolling all previously ran unconditionally, which can trigger
   discomfort for users with vestibular disorders and ignores their explicit
   OS-level preference. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important;scroll-behavior:auto !important}
  [data-aos]{opacity:1 !important;transform:none !important}
  .sheen::after{display:none}
}

/* ═══════════════════════════════════════════════════════════
   MOBILE HEADER — hamburger bar + slide-out drawer (<1024px)
   Local aliases onto the existing palette (no new colors invented):
     --mh-ink     near-black text/icons          → --forest
     --mh-cream   header/drawer background        → --ivory
     --mh-surface pills / active-row background   → --ivory-d
     --mh-line    hairline borders                → --border
     --mh-gold    accents / cart badge             → --gold
     --mh-muted   secondary text                   → --text3
   ═══════════════════════════════════════════════════════════ */
:root{
  --mh-ink:var(--forest);
  --mh-cream:var(--ivory);
  --mh-surface:var(--ivory-d);
  --mh-line:var(--border);
  --mh-gold:var(--gold);
  --mh-muted:var(--text3);
}

/* Desktop/tablet row — same box the flex/gap inline style used to carry;
   moved to a class purely so it can be `display:none` below 1024px without
   an !important fight against an inline style.
   Crossover is 1024px (not 768px) because the nav *inside* this row
   (header.php) is Tailwind's `hidden lg:flex`, and Tailwind's `lg` breakpoint
   compiles to min-width:1024px (confirmed against the compiled
   assets/css/tailwind.css - it only contains the utility classes actually
   used in the templates, so this can't be adjusted via an arbitrary
   Tailwind variant without a rebuild). The row itself used to switch at
   768px while the nav inside it only appeared at 1024px, leaving 768-1023px
   with the full row visible but its nav invisible, and the hamburger bar
   below also not shown yet - the nav (and, effectively, the whole row)
   disappeared for that entire range. Moving this row's own crossover to
   1024px keeps one single source of truth: below 1024px the mobile bar
   (hamburger + drawer) is the nav; at/above it, the desktop row is. */
.bt-header-desktop-row{height:66px;display:flex;align-items:center;gap:20px}

/* Mobile bar — hidden by default (desktop-first), shown only below 1024px
   (see the crossover note on .bt-header-desktop-row above). */
.bt-mobile-bar{
  display:none;position:relative;height:60px;padding:0 14px;
  align-items:center;gap:8px;background:var(--mh-cream);
}
@media(max-width:1023px){
  .bt-header-desktop-row{display:none}
  .bt-mobile-bar{display:flex}
}
/* flex-shrink:0 (not the old flex:1 1 0) so the icon groups never give up
   space to fit a narrow viewport — they can still grow to help center the
   brand when there's room, but all the squeezing on a very narrow phone
   lands on .bt-mobile-brand below instead of shrinking icons out of tap-size
   or letting the brand's text overflow on top of them. */
.bt-mobile-bar__side{display:flex;align-items:center;flex:1 0 auto;flex-shrink:0;min-width:0;gap:6px}
.bt-mobile-bar__side--end{justify-content:flex-end}

.bt-hamburger{
  width:34px;height:34px;padding:5px;margin:-5px;border:none;background:none;cursor:pointer;
  display:flex;flex-direction:column;justify-content:center;align-items:center;gap:5px;
  border-radius:10px;flex-shrink:0;
}
.bt-hamburger:hover{background:rgba(0,0,0,.05)}
.bt-hamburger span{display:block;width:20px;height:2px;background:var(--mh-ink);border-radius:2px;transition:transform .2s ease,opacity .2s ease}
.bt-hamburger[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.bt-hamburger[aria-expanded="true"] span:nth-child(2){opacity:0}
.bt-hamburger[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

.bt-icon-btn{
  position:relative;width:34px;height:34px;border-radius:50%;border:none;background:none;cursor:pointer;
  display:flex;align-items:center;justify-content:center;color:var(--mh-ink);font-size:18px;text-decoration:none;flex-shrink:0;
}
.bt-icon-btn:hover{background:rgba(0,0,0,.05)}

.bt-mobile-brand{
  display:flex;align-items:center;gap:8px;justify-content:center;text-decoration:none;white-space:nowrap;
  flex:1 1 auto;min-width:0;overflow:hidden;
}

/* Brand logo (assets/logobyt.webp, 936x200 => 4.68:1). One image carries the
   whole lockup, so it is sized by height and lets width follow, at each of the
   three places the header renders it. max-width:100% matters on the mobile bar:
   .bt-mobile-brand is the flex item that absorbs the squeeze on a narrow phone
   and it clips with overflow:hidden, so without this the wordmark would be cut
   off mid-letter rather than scaling down. */
.bt-brand-logo{display:block;height:40px;width:auto;max-width:100%;object-fit:contain}
.bt-mobile-brand .bt-brand-logo{height:28px}
.bt-drawer__header .bt-brand-logo{height:32px}
.bt-cart-badge{
  position:absolute;top:-2px;right:-2px;min-width:17px;height:17px;padding:0 3px;
  border-radius:50%;border:2px solid var(--mh-cream);
  background:linear-gradient(135deg,var(--gold-l),var(--gold));color:#fff;
  font-size:9.5px;font-weight:800;line-height:1;
  display:flex;align-items:center;justify-content:center;
}
.bt-cart-badge.is-empty{display:none}

/* ── Search overlay ─────────────────────────────────────── */
.bt-search-overlay{display:none}
.bt-mobile-bar.is-search-open{visibility:hidden;height:0;overflow:hidden}
.bt-search-overlay.is-open{
  display:block;position:relative;background:var(--mh-cream);
  border-bottom:1px solid var(--mh-line);
}
.bt-search-overlay__row{display:flex;align-items:center;gap:10px;height:60px;padding:0 14px}
.bt-search-overlay__form{
  flex:1;min-width:0;position:relative;display:flex;align-items:center;
  background:#fff;border:1.5px solid var(--mh-line);border-radius:50px;padding:0 14px;height:42px;
}
.bt-search-overlay__form i{color:var(--mh-muted);font-size:var(--fs-ui);margin-right:8px;flex-shrink:0}
.bt-search-overlay__form input{flex:1;min-width:0;border:none;outline:none;background:none;font-family:inherit;font-size:var(--fs-ui);color:var(--text1)}
.bt-search-overlay__cancel{
  flex-shrink:0;border:none;background:none;cursor:pointer;font-family:inherit;
  font-size:var(--fs-ui);font-weight:var(--fw-heading);color:var(--mh-gold);padding:8px 2px;
}
.bt-search-overlay__panel{padding:4px 18px 22px}
.bt-search-overlay__section + .bt-search-overlay__section{margin-top:20px}
.bt-search-overlay__heading{font-size:var(--fs-label);font-weight:var(--fw-label);letter-spacing:1px;text-transform:uppercase;color:var(--mh-muted);margin-bottom:10px}
.bt-search-overlay__chips{display:flex;flex-wrap:wrap;gap:8px}
.bt-search-chip{
  display:inline-flex;align-items:center;border-radius:50px;padding:7px 14px;
  background:var(--mh-surface);color:var(--text1);font-size:var(--fs-xs);font-weight:var(--fw-semibold);
  text-decoration:none;white-space:nowrap;
}
.bt-search-chip:hover{background:rgba(201,162,74,.14);color:var(--gold-d)}

/* ── Drawer ─────────────────────────────────────────────── */
.bt-drawer-scrim{
  position:fixed;inset:0;background:rgba(21,18,12,.5);z-index:2200;
  opacity:0;visibility:hidden;transition:opacity .22s ease;
}
.bt-drawer-scrim.is-open{opacity:1;visibility:visible}

.bt-drawer{
  position:fixed;top:0;bottom:0;left:0;width:calc(100% - 62px);max-width:400px;
  background:var(--mh-cream);z-index:2201;
  display:flex;flex-direction:column;
  transform:translateX(-100%);
  transition:transform .24s cubic-bezier(.22,.61,.36,1);
}
/* The shadow belongs to the OPEN state only. The drawer is rendered at
   every viewport width and merely translated off-screen, so a shadow on
   the base rule is painted permanently: offset 20px with a 60px blur puts
   roughly 50px of soft grey down the left edge of every page, full height,
   even though the drawer itself is nowhere in sight. */
.bt-drawer.is-open,.bt-drawer.is-open-instant{box-shadow:20px 0 60px rgba(0,0,0,.18)}
.bt-drawer.is-open{transform:translateX(0)}
.bt-drawer.is-open-instant{transform:translateX(0);transition:none}

.bt-drawer__header{
  display:flex;align-items:center;justify-content:space-between;flex-shrink:0;
  padding:16px 14px;border-bottom:1px solid var(--mh-line);
}
.bt-drawer__header .bt-mobile-brand{justify-content:flex-start}

.bt-drawer__search{padding:14px}
.bt-drawer__search-field{
  display:flex;align-items:center;gap:10px;height:44px;padding:0 16px;
  background:#fff;border:1px solid var(--mh-line);border-radius:50px;
}
.bt-drawer__search-field i{color:var(--mh-muted);font-size:var(--fs-ui)}
.bt-drawer__search-field input{flex:1;min-width:0;border:none;outline:none;background:none;font-family:inherit;font-size:var(--fs-ui);color:var(--text1)}

.bt-drawer__nav{flex:1;overflow-y:auto;padding:4px 10px}
.bt-drawer-list{list-style:none}
.bt-drawer-item{position:relative}
.bt-drawer-link{
  display:flex;align-items:center;min-height:49px;padding:0 12px;border-radius:12px;
  font-size:var(--fs-h5);font-weight:var(--fw-medium);color:var(--text1);text-decoration:none;
}
.bt-drawer-link.is-active{background:var(--mh-surface);font-weight:var(--fw-semibold);color:var(--mh-ink)}
.bt-drawer-chevron{position:absolute;right:14px;top:50%;transform:translateY(-50%);color:var(--mh-muted);font-size:13px;pointer-events:none}
.bt-drawer-toggle{
  position:absolute;right:4px;top:50%;transform:translateY(-50%);
  width:36px;height:36px;border:none;background:none;cursor:pointer;
  display:flex;align-items:center;justify-content:center;color:var(--mh-muted);
}
.bt-drawer-toggle i{transition:transform .2s ease}
.bt-drawer-toggle[aria-expanded="true"] i{transform:rotate(180deg)}
.bt-drawer-sub{list-style:none;max-height:0;overflow:hidden;transition:max-height .22s ease}
.bt-drawer-sub--open{max-height:600px}
.bt-drawer-item--sub .bt-drawer-link{padding-left:28px;min-height:42px;font-size:var(--fs-ui)}

.bt-drawer__footer{
  flex-shrink:0;border-top:1px solid var(--mh-line);
  padding-bottom:env(safe-area-inset-bottom,0px);
}
/* Account and phone rows share this one class so they render as identical,
   evenly-spaced rows in the same box instead of two differently-padded
   elements (the account link used to be a standalone 49px pill above the
   footer; the phone number sat in a smaller, differently-padded row). */
.bt-drawer__footer-row{
  display:flex;align-items:center;gap:10px;padding:14px 18px;
  font-size:var(--fs-ui);font-weight:var(--fw-semibold);color:var(--mh-ink);text-decoration:none;
}
.bt-drawer__footer-row + .bt-drawer__footer-row{border-top:1px solid var(--mh-line)}
.bt-drawer__footer-row i{font-size:17px;color:var(--mh-gold);flex-shrink:0}
/* display:flex pre-declared here (matching .bt-announce__currency-dock's own
   reasoning) so the mu-plugin's dockInto() never needs to add its own inline
   style — it only does that when the target's computed display isn't
   already flex, and skipping that path avoids any flash of unstyled/inline
   content before JS runs. */
.bt-drawer__footer-currency{display:flex;align-items:center;flex:1;min-width:0}
/* The mu-plugin sets its own inline `color` on .mam-currency-switcher by
   reading the dock target's computed background (pickTextColor(), in
   mam-auto-currency.php) — the same auto-detection that previously produced
   an unreadable black-on-black/near-invisible result in this drawer. Rather
   than depend on that heuristic guessing right against the cream drawer
   background, pin it to the theme's own ink/gold/line tokens directly;
   !important is needed only to beat that inline style, exactly like the
   announcement bar's currency override above does for the same reason. */
.bt-drawer__footer-currency .mam-currency-switcher{
  font-size:var(--fs-small);gap:6px;color:var(--mh-ink) !important;
  /* Overrides the mu-plugin's own .mam-currency-switcher--docked{margin-left:auto}
     (there to right-align it in the announcement bar's own layout) — in this
     row it just shoved the switcher to the far edge, leaving a large empty
     gap between the globe icon and "Currency:". Sit right after the icon instead. */
  margin-left:0;
}
.bt-drawer__footer-currency .mam-currency-switcher label{color:var(--mh-muted) !important;opacity:1;font-weight:600}
.bt-drawer__footer-currency .mam-currency-switcher select{
  -webkit-appearance:none;appearance:none;
  background-color:var(--mh-surface) !important;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%23857c6c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M1.5 2 6 6.5 10.5 2'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 8px center;background-size:9px 6px;
  border:1px solid var(--mh-line) !important;border-radius:50px;
  padding:3px 22px 3px 10px;font-family:inherit;font-weight:700;
  color:var(--mh-ink) !important;opacity:1;cursor:pointer;line-height:1.5;
}
.bt-drawer__footer-currency .mam-currency-switcher select option{color:var(--text1);background:#fff}

/* ═══ HOMEPAGE — EDITOR CONTENT BAND ═══
   Renders whatever an editor types into the front page's own WP editor,
   directly below "Latest from Our Blog". It is a band like every other
   homepage section (same .bt-section rhythm, same container), but the
   copy inside is free-form WYSIWYG, so it reuses .product-desc for its
   typography instead of inventing a second prose stylesheet — headings,
   lists, links and tables then look identical to the ones on product and
   blog pages. Deliberately flat: no card, no border, no radius, no
   shadow. Its white background is what separates it from the ivory blog
   band above and the ivory FAQ band below, so the two bands never touch
   without a colour change between them.

   These wrappers used to pin font-size:15px themselves, because the old
   .product-desc heading scale was em-based and needed a known root. Both
   are gone: the prose size is --fs-body on <body> / .product-desc and the
   headings are the global h1-h6, so the wrappers are pure layout now. */
/* .ct-faq-inner is the contact page's FAQ wrapper. It was declared in
   page-contact.php's inline <style> as a byte-identical copy of these six
   rules, so it is simply named alongside them here. */
.bt-home-content-inner,.bt-home-faq-inner,.ct-faq-inner{width:100%;max-width:none;margin:0}
/* Media and embeds pasted into the editor must never widen the column. */
.bt-home-content-inner img,.bt-home-faq-inner img,.ct-faq-inner img{max-width:100%;height:auto}
.bt-home-content-inner iframe,.bt-home-content-inner video,
.bt-home-faq-inner iframe,.bt-home-faq-inner video,
.ct-faq-inner iframe,.ct-faq-inner video{max-width:100%}
.bt-home-content-inner > :first-child,.bt-home-faq-inner > :first-child,.ct-faq-inner > :first-child{margin-top:0}
.bt-home-content-inner > :last-child,.bt-home-faq-inner > :last-child,.ct-faq-inner > :last-child{margin-bottom:0}

/* FAQ MEASURE — the 860px cap, restored for the FAQ bands only.
   The rule above leaves these wrappers uncapped so they fill their
   container, which is right for the homepage's CONTENT band (long-form
   editor prose that wants the full column) but leaves a question row
   running the whole width of max-w-7xl in an FAQ, where each row is one
   short line of text and a +/x mark 1200px away from it.

   Scoped to the five FAQ BANDS — blog, About, Contact, shop and the
   homepage — so every FAQ on the site keeps one measure, and the
   homepage content band above is untouched. Two classes deep, so it
   outranks the uncapped rule wherever the two meet. */
.bl-faq .ct-faq-inner,
.ab-faq .ct-faq-inner,
.ct-faq .ct-faq-inner,
.sh-faq .ct-faq-inner,
.pp-faq .ct-faq-inner,
.bt-home-faq .bt-home-faq-inner{
  max-width:860px;margin-left:auto;margin-right:auto;
}
.bt-home-content-inner blockquote{
  margin:1.25em 0;padding-left:18px;color:var(--text2);font-style:italic;
}

/* ═══ HOMEPAGE — FAQ BAND ═══
   There is deliberately NO FAQ styling here. Rank Math FAQ blocks already
   have one site-wide design: the click-to-expand accordion printed by
   site-core.php on wp_footer (the "+" affordance, the hairline row rule
   and the collapsed .rank-math-answer). That hook runs on is_singular()
   with has_block( 'rank-math/faq-block' ), and the front page is a
   singular page whose content holds the block — so it already applies
   here, unprompted, exactly as it does on products, posts and pages.

   Any question/answer rules added in this file would be a second,
   competing FAQ design that only the homepage got, and would drift from
   the rest of the site the moment site-core.php changed. The band
   therefore contributes layout only (container, measure and 15px base,
   shared with the content band above), and .product-desc supplies the
   heading scale — the same pair a product description gets. */

/* ═══ HOMEPAGE — FLAT SURFACES (scoped to body.home) ═══════════
   The homepage's own sections are already solid --ivory / #fff. What is
   left with a gradient is shared header chrome, which every other
   template renders too, so these overrides are scoped to body.home on
   purpose: the homepage reads completely flat while shop, product, cart
   and blog pages keep the header exactly as it is today.

   The trade-off is deliberate and worth stating — the top bar and the
   cart badge look slightly different on the homepage than elsewhere.
   Lifting these three rules out of the body.home block is all it takes
   to make the treatment site-wide later.

   Not included, because they were explicitly kept: the .sheen sweep and
   the .wa-float WhatsApp button (its green is a brand colour). Also left
   alone everywhere are the two fade-to-transparent gradients that are
   functional rather than decorative — the category rail's edge masks
   (#catTrackWrap::before/after) and the benefit-bar dividers — since a
   solid fill would turn a soft fade into a hard line. */
body.home .bt-announce{
  background:var(--sage);
  background-size:auto;animation:none;
}
body.home .bt-cart-badge{background:var(--gold)}

/* ═══ TRUST / BENEFITS BAND ═══
   The four-up strip that used to open the footer, now a page band above the
   newsletter (markup at the top of footer.php). The grid steps 1 → 2 → 4
   columns exactly as the footer version did; the palette is the light one the
   rest of the page uses, with the same --gold icon chip it always had. */
.bt-trust__grid{
  display:grid;grid-template-columns:1fr;gap:14px;
}
@media (min-width:640px){.bt-trust__grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}}
@media (min-width:1024px){.bt-trust__grid{grid-template-columns:repeat(4,minmax(0,1fr))}}
.bt-trust__item{
  display:flex;align-items:flex-start;gap:12px;min-width:0;
  padding:16px;border-radius:var(--r);
  background:#fff;border:1px solid var(--border);
  transition:border-color .2s ease,box-shadow .2s ease;
}
/* .ct-info-card (contact page) is the same white/hairline card with the same
   gold hover, so the two share one rule instead of declaring it twice. */
.bt-trust__item:hover,.ct-info-card:hover{border-color:rgba(201,162,74,.4);box-shadow:var(--shadow)}
.bt-trust__ico{
  flex:0 0 auto;width:40px;height:40px;border-radius:10px;
  display:flex;align-items:center;justify-content:center;
  background:rgba(201,162,74,.15);color:var(--gold-d);font-size:16px;
}
.bt-trust__text{min-width:0}
.bt-trust__title{font-size:var(--fs-h6);font-weight:var(--fw-semibold);color:var(--forest);margin-bottom:2px}
.bt-trust__copy{font-size:var(--fs-xs);line-height:1.55;color:var(--ink-muted);overflow-wrap:anywhere}

/* ═══ NEWSLETTER BAND ═══
   Markup is at the top of footer.php, above the <footer> element, so it
   renders site-wide immediately above the footer. Still a separate component:
   none of the footer's own styles apply to it and it owns all of its own
   styling here.

   Plain white band, centred column: it reads as the page's closing section
   and the black footer below supplies the contrast, so the band itself needs
   no fill of its own. Accents are the theme's primary (--sage) with --gold
   only on the small eyebrow/privacy marks, as elsewhere on the site.
   Vertical rhythm comes from the shared .bt-section token, not from its own
   hard-coded padding. */

/* The measure is what keeps the copy readable — full-width text at this
   font size would run past 100 characters a line on a desktop container. */
.bt-news__inner{max-width:620px;margin:0 auto;text-align:center}

/* Section-title tier (it is an <h2>), so size/weight/rhythm come from the
   global h2 and only the margin is local. */
.bt-news__title{margin:0 0 10px}
.bt-news__sub{
  font-size:var(--fs-ui);line-height:var(--lh-small);color:var(--ink-body);
  margin:0 auto 24px;max-width:46ch;
}

/* Centred row that wraps to a stacked, full-width field + button on phones. */
.bt-news__form{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;align-items:center}
.bt-news__input{
  flex:1 1 260px;min-width:0;max-width:100%;
  padding:14px 20px;
  border:1px solid var(--border);border-radius:9999px;
  background:#fff;
  font-family:inherit;font-size:var(--fs-ui);color:var(--text1);
  text-align:center;
  outline:none;transition:all .2s ease-in-out;-webkit-appearance:none;
}
.bt-news__input::placeholder{color:var(--text3)}
.bt-news__input:focus{
  border-color:var(--sage);
  box-shadow:0 0 0 3px rgba(0,0,0,.08);
}
/* Same pill geometry as .btn-sage, so the CTA matches every other primary
   button on the site. */
.bt-news__btn{
  flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:14px 28px;
  background:var(--sage);color:#fff;
  border:1px solid var(--sage);border-radius:9999px;
  font-family:inherit;font-size:var(--fs-ui);font-weight:600;line-height:1;
  white-space:nowrap;cursor:pointer;transition:all .2s ease-in-out;
}
.bt-news__btn:hover{background:var(--sage-d);border-color:var(--sage-d);transform:translateY(-1px)}
.bt-news__btn:active{transform:translateY(0)}
.bt-news__btn:disabled{opacity:.6;cursor:default;transform:none}
.bt-news__btn.is-busy i{animation:spin .8s linear infinite}
@media (max-width:519px){
  /* Side by side would leave the field ~90px wide on a small phone. */
  .bt-news__input,.bt-news__btn{flex:1 1 100%;width:100%}
}

.bt-news__msg{
  flex:1 1 100%;margin:0;font-size:var(--fs-xs);line-height:1.5;
  display:none;
}
.bt-news__msg.is-visible{display:block}
.bt-news__msg.is-ok{color:#2f7d43}
.bt-news__msg.is-err{color:#c0392b}

/* ═══ HOMEPAGE — PRODUCT GRID ═══
   The 2-up → 4-up card grid under "Best Selling Medicines". Moved here from
   front-page.php's inline <style>; the Shop archive has its own .shop-grid,
   so this stays the homepage's grid rather than being merged into it. */
.grid-products{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}
@media (min-width:1024px){.grid-products{grid-template-columns:repeat(4,1fr);gap:20px}}

/* ═══ HOMEPAGE — PROMO BANNER ═══
   Moved here from front-page.php's inline <style>, unchanged.

   A centred column, not a split row. The previous layout was a
   space-between flex row inside the max-w-7xl container, which pushed the
   copy hard left and the button hard right and left ~600px of dead space
   between them on desktop. Centring the stack and capping it with
   .promo-inner max-width keeps the content optically balanced at any
   container width, so the band stays compact instead of stretching.
   No fixed heights anywhere — the band is sized by its padding and content.

   Solid --forest rather than a #141414→#3d3d3d gradient: the card stays the
   dark CTA it always was, but the page no longer mixes gradient and flat
   surfaces. The band behind it is white, so the contrast still carries. */
.promo-banner{position:relative;border-radius:24px;overflow:hidden;background:var(--forest)}
.promo-inner{
  position:relative;z-index:1;
  display:flex;flex-direction:column;align-items:center;text-align:center;
  max-width:560px;margin:0 auto;padding:30px 20px;
}
.promo-badge{
  display:inline-flex;align-items:center;gap:6px;
  background:rgba(201,168,76,.2);color:#e8d9a0;border:1px solid rgba(201,168,76,.3);
  border-radius:50px;padding:4px 14px;font-size:var(--fs-2xs);font-weight:var(--fw-label);letter-spacing:.5px;
}
/* Panel-title tier. White ink is the only thing this needs beyond the
   shared h3 tokens, because the banner is the theme's one dark card. */
.promo-title{
  font-size:var(--fs-h3);font-weight:var(--fw-semibold);color:#fff;
  line-height:var(--lh-heading-sm);margin:12px 0 0;
}
.promo-copy{color:rgba(255,255,255,.6);font-size:var(--fs-small);line-height:1.5;margin:8px 0 0}
.promo-code{color:#e8d9a0;font-weight:800;background:rgba(201,168,76,.15);padding:2px 10px;border-radius:8px;white-space:nowrap}
/* max-width:100% so a long label can never push the band wider than the
   viewport on a narrow phone. */
.promo-cta{margin-top:20px;max-width:100%;font-size:var(--fs-ui);padding:12px 26px}
@media (min-width:640px){
  .promo-inner{max-width:620px;padding:38px 32px}
  .promo-badge{font-size:var(--fs-label)}
  .promo-copy{font-size:var(--fs-ui)}
  .promo-cta{margin-top:24px;font-size:var(--fs-body);padding:13px 30px}
}

/* ═══════════════════════════════════════════════════════════════
   CONTACT PAGE
   Moved here from page-contact.php's inline <style>. Every selector is
   prefixed .ct- / .bt-promise / .bt-cta and none of them appears in another
   template, so the block loads site-wide but only ever paints on the contact
   page — the same arrangement the homepage bands above already use. Vertical
   rhythm is the shared --sec-* scale via .bt-section on the markup; nothing
   here invents its own band padding.
   ═══════════════════════════════════════════════════════════════ */

/* ─── CONTACT HERO — centred stack: intro above, form card below ───
   Reuses the theme's .card / .field / .label / .btn-sage. The dark surface,
   the gradient and the closing curve are the shared .bt-darkband component
   (see "DARK BAND" above), the same one the About hero uses — only the
   accent wash, the intro type and the card's overhang are declared here. The
   form card stays a white .card, which is what gives it its lift.

   From 768px the card hangs past the band's bottom edge and straddles the
   wave, so the section must not clip: overflow is visible here (overriding
   .bt-darkband) and the accent circles live in .ct-hero-bg, which clips them
   instead. The overhang is a negative margin on the card, which also pulls
   the band's bottom edge up by the same amount — so the band needs no bottom
   padding at those widths, and .ct-info below adds the overhang to its own
   top padding so the info cards still start clear of the card. Below 768px
   there is no overhang (it would leave the card covering the wave across the
   full width), so the band keeps its normal padding. */
.ct-hero{position:relative;overflow:visible;padding-bottom:0}
/* Constrained to --band-w, not inset:0, so its overflow:hidden still clips
   the two washes below to the dark panel's edge. The section around it is
   full-width white now, so an inset:0 box would let the gold wash bleed out
   over that white instead of being cut off at the panel. */
.ct-hero-bg{position:absolute;top:0;bottom:0;left:50%;transform:translateX(-50%);width:var(--band-w);z-index:0;overflow:hidden;pointer-events:none}
.ct-hero-bg::before,.ct-hero-bg::after{content:'';position:absolute;border-radius:50%}
.ct-hero-bg::before{width:460px;height:460px;left:-190px;top:-160px;background:radial-gradient(circle,rgba(201,162,74,.20),transparent 70%)}
.ct-hero-bg::after{width:300px;height:300px;left:-80px;bottom:-170px;background:rgba(255,255,255,.035)}
.ct-hero-inner{position:relative;z-index:1}

/* One centred column, 48px between the intro and the card. The two blocks
   stay stretch-sized and centre themselves with auto inline margins — NOT
   with justify-items:center, which would size them to fit-content and let
   their max-widths (720px / 880px) overflow a narrow viewport. */
.ct-hero-grid{display:grid;grid-template-columns:1fr;gap:48px}
.ct-hero-intro{text-align:center;max-width:720px;margin-inline:auto}
/* Targets the h2, not the h1: the page name ("Gen In Touch") is the h1 here,
   the same way About's hero works, so the big hero line below it is an h2.
   This rule is the hero line's type — pointing it at h1 gave the small gold
   badge pill a 46px face and left the headline unstyled. The .ct-hero-card's
   own h2 is outside .ct-hero-intro, so it is untouched. */
/* Type is .typography-display --invert on the markup, the same pair the
   About hero uses — this rule is only the gap around it. */
.ct-hero-title{margin:20px 0 16px}
.ct-hero-intro p{color:rgba(255,255,255,.7);font-size:var(--fs-body-lg);line-height:1.8;max-width:620px;margin:0 auto}

/* Card padding is the form's own component spacing, not band rhythm — it
   steps with the breakpoints so the fields keep a comfortable inset. The
   z-index lifts it over .wave-b, which is a later sibling in the markup.

   Phones get their own sizing rather than inheriting the desktop card: a
   560px cap with a 92% width keeps real side margins inside the page
   gutter, and the overhang is proportional to the card's height there (it
   is ~640px tall with the fields stacked), so the form sits across the
   band's edge the way it does on desktop instead of filling the hero and
   leaving dead dark space below itself. */
.ct-hero-card{
  position:relative;z-index:2;width:100%;
  max-width:min(560px,92%);margin-inline:auto;
  padding:20px;margin-bottom:-240px;
}
/* Card heading: .typography-h3 on the markup, centring and gap here. */
.ct-hero-card__title{margin-bottom:18px;text-align:center}
.ct-hero-row{display:grid;grid-template-columns:1fr;gap:16px}
@media (min-width:768px){
  .ct-hero-row{grid-template-columns:repeat(2,1fr)}
  /* 92% rather than the full column from tablet up, so the dark band always
     shows on both sides of the card and it reads as centred in the hero
     instead of filling it. The 880px cap still governs on desktop. */
  /* The negative margin is roughly half the card's rendered height, so the
     band's bottom edge crosses the card near its middle — the card reads as
     centred ON the boundary, not as hanging off it. It is a fixed value
     because a percentage margin resolves against the container's WIDTH, not
     its height; if the form gains or loses a field, retune these two numbers
     (and the matching .ct-info padding-top above) together. */
  .ct-hero-card{padding:28px;margin-bottom:-200px;max-width:min(880px,92%)}
}
@media (min-width:1024px){
  .ct-hero-card{padding:32px;margin-bottom:-240px}
}

/* ─── CONTACT INFO BAND ───
   Four compact cards on a white band. The card/icon treatment is the theme's
   existing trust-band language (.bt-trust__item / .bt-trust__ico): white
   surface, hairline --border, --gold icon chip, and the hover is literally
   the same rule, declared with .bt-trust__item:hover above. Grid steps
   1 → 2 → 4 columns on the theme's 640/1024 breakpoints. */
/* Three cards, so the grid goes straight from one column to three at 768px
   rather than stepping 1 → 2 → 4: a 2-column step would leave a single
   orphaned card on its own row at tablet widths. */
/* Top padding = the band's own rhythm plus however far the hero's form card
   hangs into this band, so the three cards always start clear of it. The two
   values are the negative margins on .ct-hero-card above; change them
   together. */
.ct-info{padding-top:calc(var(--hero-y) + 240px)}
@media (min-width:768px){.ct-info{padding-top:calc(var(--hero-y) + 200px)}}
@media (min-width:1024px){.ct-info{padding-top:calc(var(--hero-y) + 240px)}}
.ct-info-grid{display:grid;grid-template-columns:1fr;gap:16px;align-items:stretch}
@media (min-width:768px){.ct-info-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
.ct-info-card{
  display:flex;flex-direction:column;align-items:center;text-align:center;gap:9px;
  min-width:0;padding:24px 18px;background:#fff;
  border:1px solid var(--border);border-radius:var(--r);
  transition:border-color .2s ease,box-shadow .2s ease;
}
.ct-info-ico{
  flex:0 0 auto;width:44px;height:44px;border-radius:12px;
  display:flex;align-items:center;justify-content:center;
  background:rgba(201,162,74,.15);color:var(--gold-d);font-size:17px;
}
.ct-info-title{font-size:var(--fs-label);font-weight:var(--fw-label);letter-spacing:.8px;text-transform:uppercase;color:var(--ink-muted)}
.ct-info-val{font-size:var(--fs-h6);font-weight:var(--fw-heading);line-height:1.5;color:var(--forest);text-decoration:none;overflow-wrap:anywhere}
a.ct-info-val:hover{color:var(--sage);text-decoration:underline}
.ct-info-sub{font-size:var(--fs-xs);line-height:1.55;color:var(--ink-muted)}
/* Working Hours shows two day/time pairs. The card's own 9px gap is tuned for
   single lines, so the pairs get a slightly wider gap between them to keep
   each day and its time reading as one unit. */
.ct-info-hours{display:flex;flex-direction:column;gap:10px}

/* ─── CONTACT FAQ BAND ───
   Layout only. The question/answer design (the "+" affordance, hairline row
   rule, collapsed answer) is the site-wide Rank Math accordion printed by
   site-core.php, and .product-desc supplies the prose scale — no second FAQ
   design is defined here. The wrapper's own rules are shared with the
   homepage bands; see .bt-home-faq-inner above. */

/* ─── CONTACT PROMISE BAND ───
   Dark inset panel between the FAQ and the closing CTA — deliberately a
   different treatment from the light .bt-trust band footer.php renders
   site-wide.

   Colours are the theme's own tokens, not new hexes: --sage is the panel
   fill (#141414), --gold-l the accent line/ring, --gold the filled first
   node, --r the radius. Muted copy is white at 66%, since the palette has no
   muted tone meant for a dark surface (--text3 is tuned for ivory). Type
   inherits the site font.

   The panel's vertical padding IS this band's rhythm (the section around it
   carries none, so the dark surface runs edge to edge), which is why it uses
   the shared --sec-y token rather than the three hard-coded values it used to
   have — those were 56/44/36px, and this was the one band on either page that
   did not scale with the rest. Horizontally it now adds nothing: the
   max-w-7xl mx-auto px-4 container inside it supplies the gutter, the same
   one every other band uses. Previously the panel's own 16px was the only
   gutter, so on a wide screen the five columns spread the full viewport width
   and the first item was clipped at the left edge. */
/* Centred on the same box as the dark hero panels, so the sage band starts
   and ends on the homepage banner's edges instead of running full-bleed.
   This one needs no layered-background trick: unlike .bt-darkband it has a
   real wrapper (.bt-promise-sec), so the wrapper paints the white and the
   panel is simply a narrower block inside it. Its own overflow:hidden then
   goes on clipping the two corner washes below to the panel edge exactly
   as it did when the panel was the full width of the page. */
.bt-promise-sec{background:#fff}
.bt-promise{
  width:calc(100% - 2rem);
  max-width:calc(80rem - 2rem);
  margin-inline:auto;
  position:relative;overflow:hidden;isolation:isolate;
  background:var(--sage);color:#fff;
  padding:var(--sec-y) 0;
}
.bt-promise::before{content:"";position:absolute;right:-140px;top:-180px;width:460px;height:460px;border-radius:50%;border:1px solid rgba(232,217,160,.14);z-index:-1}
.bt-promise::after{content:"";position:absolute;right:-60px;top:-100px;width:300px;height:300px;border-radius:50%;background:radial-gradient(circle,rgba(201,162,74,.20),transparent 70%);z-index:-1}

/* Heading is .bt-section-title --invert on the markup — same scale, same
   weight, white ink. This class now only supplies the panel's own centring
   and the --sec-head-gap that keeps its title-to-content gap identical to
   every light band. */
.bt-promise__title{text-align:center;margin:0 auto var(--sec-head-gap)}

.bt-promise__rail{position:relative;list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(5,minmax(0,1fr))}
/* Dotted connector, threaded through the node centres (node is 56px tall, so
   its centre sits at 28px). The nodes paint over it via z-index + a 6px ring
   in the panel colour, which is what breaks the line at each circle. */
.bt-promise__rail::before{content:"";position:absolute;left:28px;right:28px;top:27px;height:1px;background:repeating-linear-gradient(90deg,rgba(232,217,160,.55) 0 6px,transparent 6px 12px)}
.bt-promise__item{position:relative;min-width:0;padding:0 28px 0 0}
.bt-promise__item + .bt-promise__item{padding-left:28px;border-left:1px solid rgba(255,255,255,.08)}

.bt-promise__node{
  position:relative;z-index:1;width:56px;height:56px;border-radius:50%;
  display:grid;place-items:center;background:var(--sage);
  border:1px solid rgba(232,217,160,.55);color:var(--gold-l);
  box-shadow:0 0 0 6px var(--sage);
}
/* The row uses the theme's Bootstrap Icons webfont, so the node sizes a
   glyph rather than an SVG. */
.bt-promise__node i{font-size:22px;line-height:1}
.bt-promise__item:first-child .bt-promise__node{background:var(--gold);border-color:var(--gold);color:var(--sage)}

/* Ghost numeral — an ornament sized to the layout, not a type tier. */
.bt-promise__num{position:absolute;right:18px;top:-8px;font-size:64px;font-weight:var(--fw-heading);line-height:1;color:transparent;-webkit-text-stroke:1px rgba(255,255,255,.13);pointer-events:none;user-select:none}

.bt-promise__item h3{margin:26px 0 0;font-size:var(--fs-h4);color:#fff}
.bt-promise__item p{margin:6px 0 0;font-size:var(--fs-ui);line-height:1.55;color:rgba(255,255,255,.66)}

@media (max-width:1024px){
  .bt-promise__item,.bt-promise__item + .bt-promise__item{padding-left:16px;padding-right:12px}
  .bt-promise__item:first-child{padding-left:0}
  .bt-promise__num{font-size:48px}
}

@media (max-width:760px){
  /* Kept from the original design: the panel reads as a rounded slab against
     the body ivory on phones. Only its padding moved to the container. */
  .bt-promise{border-radius:var(--r)}
  .bt-promise__rail{grid-template-columns:1fr}
  /* Connector turns vertical and runs down through the node centres. */
  .bt-promise__rail::before{left:27px;right:auto;top:28px;bottom:28px;width:1px;height:auto;background:repeating-linear-gradient(180deg,rgba(232,217,160,.55) 0 6px,transparent 6px 12px)}
  .bt-promise__item,.bt-promise__item + .bt-promise__item{
    display:grid;grid-template-columns:56px minmax(0,1fr);column-gap:18px;align-items:center;
    padding:14px 44px 14px 0;border-left:0;
  }
  .bt-promise__node{grid-row:span 2}
  .bt-promise__item h3{margin:0}
  .bt-promise__item p{margin:2px 0 0}
  .bt-promise__num{font-size:40px;right:0;top:50%;transform:translateY(-50%)}
}

/* ─── CONTACT CLOSING CTA ───
   White band directly below the dark promise panel, so it reads as that
   section's quiet resolution rather than a second feature block. Everything
   is a theme token: #fff surface like the contact-info band, --forest for
   the heading, --text2 for the copy, --gold-d for the eyebrow, the theme's
   own .btn-sage pill for the action — the same primary button the form above
   uses, so the page closes on one button style, and no ornament of its own.
   Band rhythm is .bt-section on the markup, like every other band. */
.bt-cta__inner{max-width:680px;margin:0 auto;text-align:center}
/* Type comes from the shared .bt-section-title on the markup, so this heading
   reads exactly like every other h2 on the site — sentence case at the same
   scale. It used to declare its own smaller, uppercased scale here; only the
   bits specific to a centred closing heading are left. */
.bt-cta__title{margin:0 0 14px;text-wrap:balance;overflow-wrap:break-word}
.bt-cta__text{margin:0 auto;max-width:520px;font-size:var(--fs-body);line-height:1.75;color:var(--ink-body)}
/* The button carries its own gap from the copy, so the block needs no rule
   or divider between them. */
.bt-cta__btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  margin-top:26px;font-size:var(--fs-body);padding:13px 28px;max-width:100%;
}
@media (max-width:760px){
  .bt-cta__inner{max-width:100%}
  .bt-cta__btn{margin-top:22px;padding:12px 24px;font-size:var(--fs-ui)}
}

/* ═══════════════════════════════════════════════════════════════
   ABOUT PAGE HERO
   Defined here rather than in page-about.php's inline <style>, the same
   way the contact-page block above is: every selector is prefixed
   .ab-hero and appears in no other template, so it loads site-wide but
   only ever paints on the About page.

   Centred, three elements only — badge, headline, copy. The surface, the
   gradient and the closing curve are all the shared .bt-darkband component
   (see above), which the Contact hero uses too; this block only positions
   the accent wash and sets the type for a dark ground. Colours stay on the
   theme tokens — --gold / --gold-l accents, white copy at 70%, exactly as
   .bt-promise handles muted text on a dark panel. Rhythm is --sec-y plus
   the band's own --wave-h.
   ═══════════════════════════════════════════════════════════════ */
.ab-hero::before,.ab-hero::after{content:'';position:absolute;border-radius:50%;pointer-events:none;z-index:0}
.ab-hero::before{width:520px;height:520px;left:50%;top:-330px;margin-left:-260px;background:radial-gradient(circle,rgba(201,162,74,.20),transparent 70%)}
.ab-hero::after{width:320px;height:320px;right:-120px;bottom:-190px;background:rgba(255,255,255,.035)}

/* Shared with .sh-hero__inner (Shop root + product category heroes) — same
   band, same rhythm, so the rule is declared once here rather than twice. */
.ab-hero__inner,.sh-hero__inner{
  position:relative;z-index:1;text-align:center;
  padding-top:var(--hero-y);
  padding-bottom:calc(var(--hero-y) + var(--wave-h));
}

/* The theme's .badge-gold pill restated for the dark ground — same geometry
   and accent, lighter token so it keeps contrast — with a small live dot in
   place of an icon. Shared with .sh-hero__badge, which restates this exact
   pill on the Shop/category heroes rather than declaring a second one. */
/* This pill is the page's <h1>; the label tokens are what make it read as a
   kicker rather than a heading, which is why it declares them explicitly
   instead of inheriting the h1 tier. */
.ab-hero__badge,.sh-hero__badge{
  display:inline-flex;align-items:center;gap:8px;
  background:rgba(201,162,74,.18);border:1px solid rgba(232,217,160,.34);
  color:var(--gold-l);border-radius:9999px;padding:5px 15px;
  font-size:var(--fs-label);font-weight:var(--fw-label);letter-spacing:1.1px;text-transform:uppercase;
  line-height:1.4;
}
/* Shared with .sh-hero__dot — same live-dot treatment on both heroes. */
.ab-hero__dot,.sh-hero__dot{
  width:7px;height:7px;border-radius:50%;flex:0 0 auto;background:var(--gold);
  animation:abHeroPulse 2.6s ease-in-out infinite;
}
@keyframes abHeroPulse{
  0%,100%{box-shadow:0 0 0 3px rgba(201,162,74,.22)}
  50%{box-shadow:0 0 0 7px rgba(201,162,74,.06)}
}
@media (prefers-reduced-motion:reduce){.ab-hero__dot,.sh-hero__dot{animation:none}}

/* Type is .typography-display --invert on the markup — identical to the
   Contact hero. Only the measure and the gap are this hero's own. */
.ab-hero__title{margin:18px auto 0;max-width:17ch;text-wrap:balance}
/* Shared with .sh-hero__text — identical standfirst treatment on both
   heroes, so it is declared once rather than restated per hero. */
.ab-hero__text,.sh-hero__text{
  margin:16px auto 0;max-width:600px;
  font-size:var(--fs-body-lg);line-height:1.8;color:rgba(255,255,255,.7);
}

@media (max-width:760px){
  .ab-hero__title{max-width:20ch}
}

/* ═══════════════════════════════════════════════════════════════
   ABOUT PAGE — INFORMED CHOICES
   The six-point band directly under the hero. Everything structural is
   already in the design system and stays on the markup: .bt-section for
   band rhythm, .bt-section-head / .bt-section-title for the heading
   block, .badge-gold for the eyebrow, --r / --border / --shadow for the
   card surface. Only the point layout itself is declared here.

   One box holding a plain bullet list — no per-point cards, no numbered
   chips, no icons. The box itself is the contact page's .ct-info-card
   surface (white, hairline --border, --r radius), so a reader moving
   between About and Contact still sees one card language; the list inside
   it is spacing and type only.
   ═══════════════════════════════════════════════════════════════ */
/* The heading is a plain .bt-section-title on the markup (with the shared
   --kicker / --measure modifiers). .ab-points__title used to live here. */

/* The single container. Capped and centred so the lines keep a readable
   measure on a wide screen instead of running the full 6xl container. */
.ab-points__box{
  max-width:990px;margin-inline:auto;padding:32px;
  background:#fff;border:1px solid var(--border);border-radius:var(--r);
}

.ab-points__list{list-style:none;margin:0;padding:0}
/* Bullet is a ::before dot rather than a list marker, so wrapped lines hang
   in line with the first one instead of running back under the bullet. */
.ab-points__item{
  position:relative;padding-left:24px;min-width:0;
  font-size:var(--fs-body);line-height:var(--lh-body);
  color:var(--ink-body);overflow-wrap:break-word;
}
.ab-points__item::before{
  content:'';position:absolute;left:0;top:9px;
  width:7px;height:7px;border-radius:50%;background:var(--gold);
}
.ab-points__item + .ab-points__item{margin-top:18px}

@media (max-width:760px){
  .ab-points__box{padding:22px 18px}
  .ab-points__item{padding-left:20px}
  .ab-points__item + .ab-points__item{margin-top:16px}
}

/* ═══════════════════════════════════════════════════════════════
   ABOUT PAGE — VALUES ("What We Stand For") — REMOVED
   The band's markup is gone from page-about.php, so all of its
   .ab-values__* rules (grid, intro, rule, text, cards, card, icon,
   card-title, card-text) were removed in the Oct 2026 cleanup. The
   parent .ab-values is still listed in the --ivory band-ground rule
   above; it is inert and can go whenever that rule is next touched.
   ═══════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════
   ABOUT PAGE — VISION & MISSION
   Same convention as the three blocks above: .ab-vm prefix, used in no
   other template. Structural work stays on the markup — .bt-section for
   band rhythm, .bt-section-head / .bt-section-title for the heading,
   .card / .card-hover for the two tiles, and the shared .eyebrow for the
   OUR VISION / OUR MISSION labels (only its colour is retinted here, to
   --gold-d, so it reads as an accent rather than another line of body
   copy). Only this section's layout is declared below.

   Ground is --ivory, which alternates against the white .ab-points band
   above it and lifts the white .card tiles without needing a border. The
   note keeps --ivory-d so it still reads a step back from the tiles on
   this lighter ground.

   Equal card heights come from the grid stretching its items plus the
   card being a column flex container, so the two tiles match on desktop
   whatever the copy length, with no fixed height to cut text off. No
   gradients anywhere — the icon tile and note are flat tints of existing
   tokens.
   ═══════════════════════════════════════════════════════════════ */

/* Stacked by default; two-up from 768px, the theme's existing tablet
   breakpoint, since there is room for it by then. */
.ab-vm__grid{display:grid;grid-template-columns:minmax(0,1fr);gap:20px;align-items:stretch}
@media (min-width:768px){
  .ab-vm__grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:24px}
}

/* height:100% makes the tile fill the stretched grid row; the column flex
   keeps its contents top-aligned inside that height instead of spreading. */
.ab-vm__card{
  display:flex;flex-direction:column;align-items:flex-start;
  height:100%;padding:34px 30px;min-width:0;
}

/* Flat tint of --gold, matching the .ab-vm icon tile idiom used across the About
   sections share one icon language. */
.ab-vm__icon{
  display:flex;align-items:center;justify-content:center;
  width:54px;height:54px;flex:0 0 auto;border-radius:16px;
  background:rgba(201,162,74,.12);border:1px solid rgba(201,162,74,.26);
  color:var(--gold-d);font-size:24px;line-height:1;
}

.ab-vm__label{margin-top:24px;color:var(--gold-d)}
.ab-vm__card-title{
  margin:10px 0 0;max-width:24ch;
  font-size:var(--fs-h3);font-weight:var(--fw-semibold);line-height:var(--lh-heading-sm);
  letter-spacing:var(--ls-heading-sm);color:var(--forest);text-wrap:balance;
}
.ab-vm__card-text{
  margin:12px 0 0;font-size:var(--fs-body);line-height:1.75;
  color:var(--ink-body);overflow-wrap:break-word;
}

/* Full-width callout under the tiles. The accent is an inset ::before bar
   rather than a border-left, so the 3px rule stays crisp instead of being
   bent around the --r corner. */
.ab-vm__note{
  position:relative;overflow:hidden;margin-top:24px;min-width:0;
  padding:26px 30px 26px 34px;
  background:var(--ivory-d);border-radius:var(--r);
}
.ab-vm__note::before{
  content:'';position:absolute;top:0;bottom:0;left:0;
  width:3px;background:var(--gold);
}
.ab-vm__note-text{
  margin:0;font-size:var(--fs-body);line-height:1.8;
  color:var(--ink-body);overflow-wrap:break-word;
}

/* ═══════════════════════════════════════════════════════════════
   ABOUT PAGE — CATALOGUE (dynamic product categories)
   Same convention as the About blocks above: .ab-cat prefix, used in no
   other template. The heading block, button and card surface are all
   shared theme classes on the markup — .bt-section, .bt-section-head /
   .bt-section-title / .bt-section-sub, .eyebrow, .card, .btn-sage. Only
   the grid, the card's internal stack and the link treatment are here.

   White ground, so it alternates against the --ivory .ab-vm band above
   and the --ivory .bt-trust band that opens the footer below.

   The track count is fixed per breakpoint instead of left to auto-fit:
   the four categories have to hold one desktop row, so no single card
   ever drops to a line of its own. 1 column on mobile, 2 from 768px,
   4 from 1024px. Plain 1fr tracks rather than minmax(240px,1fr) are
   what let the four share a narrow desktop row without wrapping;
   min-width:0 on the card keeps a long word from widening its track.
   ═══════════════════════════════════════════════════════════════ */
.ab-cat__grid{display:grid;grid-template-columns:1fr;gap:20px;align-items:stretch}
@media (min-width:768px){
  .ab-cat__grid{grid-template-columns:repeat(2,1fr)}
}
@media (min-width:1024px){
  .ab-cat__grid{grid-template-columns:repeat(4,1fr)}
}

/* .card is borderless by design; on this white band the tile needs a
   hairline to read as a card, so --border is added back here only. The
   column flex plus height:100% is what keeps every card in a row equal. */
.ab-cat__card{
  display:flex;flex-direction:column;align-items:flex-start;
  height:100%;padding:26px 24px;min-width:0;
  border:1px solid var(--border);
}
.ab-cat__name{
  margin:0;font-size:var(--fs-h4);font-weight:var(--fw-semibold);line-height:var(--lh-heading-sm);
  letter-spacing:var(--ls-heading-sm);color:var(--forest);overflow-wrap:break-word;
}
/* Clamped rather than trimmed in PHP: the full description stays in the
   markup and the card keeps its height, so nothing is rewritten. */
.ab-cat__desc{
  margin:10px 0 0;font-size:var(--fs-ui);line-height:var(--lh-body);color:var(--ink-body);
  overflow-wrap:break-word;
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4;line-clamp:4;overflow:hidden;
}
/* margin-top:auto pins the link to the card's bottom edge whatever the
   description length, which is what keeps the links aligned across a row.
   padding-top supplies the gap above it; the rule sits under the text
   only, because align-self stops the anchor filling the column. */
.ab-cat__link{
  align-self:flex-start;margin-top:auto;padding-top:20px;
  display:inline-flex;align-items:center;gap:7px;
  font-size:var(--fs-small);font-weight:var(--fw-heading);letter-spacing:.2px;
  color:var(--forest);text-decoration:none;
  border-bottom:2px solid var(--gold);padding-bottom:3px;
  transition:color .2s ease;
}
.ab-cat__link i{transition:transform .2s ease}
.ab-cat__link:hover{color:var(--gold-d)}
.ab-cat__link:hover i{transform:translateX(3px)}
@media (prefers-reduced-motion:reduce){
  .ab-cat__link i{transition:none}
}

.ab-cat__cta{display:flex;justify-content:center;margin-top:38px}

@media (max-width:760px){
  .ab-cat__grid{gap:16px}
  .ab-cat__card{padding:22px 20px}
  .ab-cat__cta{margin-top:30px}
}

/* ═══════════════════════════════════════════════════════════════
   ABOUT PAGE — WHY CHOOSE US
   The editorial band between the white .ab-cat catalogue and the
   --ivory .bt-trust strip footer.php renders site-wide. Same
   convention as the .ab-* blocks above — every selector is prefixed
   .bt-why and appears in no other template — and everything already
   in the design system stays on the markup: the max-w-7xl mx-auto
   px-4 container, .font-display for the headings, the Bootstrap
   Icons webfont for the glyphs, and the --gold / --forest / --text2
   / --text3 tokens for every colour.

   Deliberately NOT a card grid. The right column is a real <ol>
   whose rows are separated by one warm hairline each; there is no
   surface, radius or shadow anywhere in the section, which is what
   keeps it reading as a list of reasons rather than five more tiles
   after the four .ab-cat cards directly above it.

   Ground is --ivory, the one cream this page alternates with #fff
   (.ab-vm, .ab-values and .bt-trust all stand on it), so the band
   is not a shade of its own. The white .ab-points band follows it,
   and the gold hairline on top separates it from the white
   .ab-cat band above. --bt-why-line is local to this block, not a
   new site token: it is the one warm rule colour this section
   needs.

   Vertical rhythm is the shared --sec-y token, so this band scales
   with every other one instead of carrying its own numbers; the
   horizontal gutter is the container's, as everywhere else.
   ═══════════════════════════════════════════════════════════════ */
.bt-why{
  --bt-why-line:#e9e3d6;
  position:relative;overflow:hidden;isolation:isolate;
  background:var(--ivory);
  border-top:1px solid rgba(201,162,74,.18);
  padding:var(--sec-y) 0;
}


/* Mobile-first: one column. The 5fr/7fr split is the desktop case below. */
.bt-why__grid{display:grid;grid-template-columns:minmax(0,1fr);gap:48px}

/* ─── Left column ─── */
/* The heading is .bt-section-title --lead on the markup. It used to be
   .bt-why__title: its own 31/38/44px steps AND font-weight:500, which is
   why this band's title read lighter than every other one on the site. */
.bt-why__text{font-size:var(--fs-body-lg);line-height:var(--lh-body);color:var(--ink-body)}

/* ─── Right column: the list ─── */
.bt-why__list{counter-reset:btwhy;list-style:none;margin:0;padding:0}
.bt-why__item{
  counter-increment:btwhy;
  display:grid;
  grid-template-columns:44px minmax(0,1fr);
  grid-template-areas:"icon num" "icon title" "icon text";
  column-gap:16px;row-gap:4px;align-items:start;
  padding:22px 0;
  border-bottom:1px solid var(--bt-why-line);
}
.bt-why__item:first-child{padding-top:0}
.bt-why__item:last-child{border-bottom:none}

.bt-why__num{
  grid-area:num;
  font-size:var(--fs-xs);font-weight:var(--fw-medium);letter-spacing:.12em;line-height:1.2;color:var(--gold);
}
.bt-why__num::before{content:counter(btwhy,decimal-leading-zero)}

.bt-why__ico{
  grid-area:icon;
  width:44px;height:44px;border-radius:50%;flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;
  background:rgba(201,162,74,.12);border:none;box-shadow:none;
  color:var(--gold);font-size:20px;line-height:1;
}
.bt-why__title-sm{grid-area:title;font-size:var(--fs-h4);font-weight:var(--fw-semibold);line-height:var(--lh-heading-sm);color:var(--forest)}
.bt-why__copy{grid-area:text;font-size:var(--fs-body);line-height:var(--lh-small);color:var(--ink-muted)}

/* Tablet: still one column, but the rows go back to the four-column
   editorial layout and the type steps up. */
/* Tablet: layout only now — the type steps with its own clamp(). */
@media (min-width:576px){
  .bt-why__intro{max-width:620px}
  .bt-why__item{
    grid-template-columns:44px 48px minmax(0,1fr) minmax(0,1.2fr);
    grid-template-areas:"num icon title text";
    column-gap:18px;row-gap:0;align-items:center;
    padding:30px 0;
  }
  .bt-why__ico{width:48px;height:48px}
}

/* Desktop: the 5/7 split. The intro is centred against the list rather than
   pinned to its top — the list is the taller column, so aligning the two at
   the top left the intro sitting high with a long empty run of ground under
   it. align-self on the intro alone, so the list still starts at the band's
   top edge. */
@media (min-width:992px){
  .bt-why__grid{grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:88px;align-items:start}
  .bt-why__intro{align-self:center;max-width:none}
  .bt-why__text{max-width:440px}
  .bt-why__item{grid-template-columns:52px 48px minmax(0,1fr) minmax(0,1.1fr);column-gap:22px}
}

/* ═══════════════════════════════════════════════════════════════
   ABOUT PAGE — STATISTICS
   The closing white band, under the cream .bt-why one. Same
   convention as the blocks above: .bt-stats prefix, used in no
   other template, and everything structural stays on the markup —
   .bt-section for the band rhythm, .bt-section-head /
   .bt-section-title for the heading, the max-w-7xl mx-auto px-4
   container, --gold for the figures and --text3 for the labels.

   No tiles: the four .ab-cat cards and the .bt-why list already
   give this page its structure, so the only separator here is the
   fading vertical hairline the home page's .bt-benefit row uses —
   the same rule, restated for this grid rather than a new idiom.
   The count-up script is at the foot of page-about.php.
   ═══════════════════════════════════════════════════════════════ */
/* White: this band sits between two cream ones in the page's cream / white
   run, and its figures need no ground of their own.

   It carries no heading, so the figures alone are its content and the shared
   --sec-y left them sitting tight against both edges. The extra 24px is
   added to the token rather than replacing it, so the band still scales with
   the rest of the page's rhythm. */
.bt-stats{
  background:#fff;
}
.bt-stats__grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));row-gap:40px}
.bt-stats__item{position:relative;text-align:center;padding:4px 10px;min-width:0}
/* Hairline between neighbours only, so the first item of each row is clear of
   one. The 2n+1 rule does that on the two-up mobile grid; at 1024px, where the
   four sit in a single row, it is switched back on for all but the first. */
.bt-stats__item+.bt-stats__item::before{
  content:'';position:absolute;left:0;top:50%;transform:translateY(-50%);
  width:1px;height:70%;
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.13),transparent);
}
.bt-stats__item:nth-child(2n+1)::before{display:none}

/* tabular-nums keeps the figure from jittering as the counter runs: every
   digit occupies the same width, so "1.4K+" and "2.8K+" are the same size. */
/* Figures, not headings: a counter is display-scale ornament, so it keeps
   its own clamp rather than borrowing a heading tier. */
.bt-stats__num{
  display:block;
  font-size:clamp(34px,5vw,48px);font-weight:var(--fw-display);line-height:1;
  letter-spacing:var(--ls-heading);color:var(--gold);font-variant-numeric:tabular-nums;
}
.bt-stats__label{
  display:block;margin-top:12px;
  font-size:var(--fs-xs);font-weight:var(--fw-semibold);letter-spacing:.08em;text-transform:uppercase;
  line-height:1.5;color:var(--ink-muted);
}

/* Four across already at the theme's tablet breakpoint — there is room for
   them once the horizontal padding comes down, and the longest label
   ("Licensed Pharmacists Brand") still sets on two lines. */
@media (min-width:768px){
  .bt-stats__grid{grid-template-columns:repeat(4,minmax(0,1fr));row-gap:0}
  .bt-stats__item{padding:4px 14px}
  .bt-stats__item:nth-child(2n+1)::before{display:block}
  .bt-stats__item:first-child::before{display:none}
}
@media (min-width:1024px){
  .bt-stats__item{padding:4px 24px}
}

/* ═══════════════════════════════════════════════════════════════
   ABOUT PAGE — PRIVACY & SECURITY
   White band under the cream .bt-stats one. Same convention as the
   blocks above: .bt-privacy prefix, used in no other template, and
   the band rhythm (.bt-section) and container (max-w-7xl mx-auto
   px-4) stay on the markup so it lines up with every other section
   on the page.

   The three colours are declared as tokens on the section itself
   rather than in :root — they are this block's palette, not the
   site's, and scoping them here keeps the rule count down without
   adding anything global. --bt-pv-gold is the theme's own --gold;
   the ink and body tones are this section's, a touch off --forest
   and --text3.

   Two structural pieces only: the statement column and the dark
   panel, the same inset-panel idiom the contact page's .bt-promise
   uses on a light band. Every decorative mark — the eyebrow rule,
   the check marks — is a pseudo-element, so the markup carries
   nothing but content and one lock glyph.
   ═══════════════════════════════════════════════════════════════ */
.bt-privacy{
  --bt-pv-gold:var(--gold);
  --bt-pv-ink:#1a1a1a;
  --bt-pv-text:#6b6b6b;
  --bt-pv-line:#ece9e2;
  background:var(--ivory);
}
/* Mobile first: one column. The split is the wide-screen case below. */
.bt-privacy__grid{display:grid;grid-template-columns:minmax(0,1fr);gap:32px;align-items:center}
.bt-privacy__intro{min-width:0}
/* 
   weight-500 copy of the section scale, and the third separate rule for
   the gold accent phrase. Both now come from the shared class.  */
.bt-privacy__text{
  margin-top:22px;max-width:500px;
  font-size:var(--fs-body);line-height:1.75;color:var(--bt-pv-text);
}

/* ─── Trust badges ─── */
/* Two equal pills per row on a phone, so four labels of very different
   lengths still read as one tidy block; they become content-width pills that
   wrap naturally once there is room for it. */
.bt-privacy__badges{
  list-style:none;margin:32px 0 0;padding:0;
  display:grid;grid-template-columns:minmax(0,1fr);gap:10px;
}
.bt-privacy__badge{
  display:flex;align-items:center;justify-content:center;gap:10px;
  min-width:0;padding:10px 14px;
  background:#fff;border:1px solid var(--bt-pv-line);border-radius:999px;
  font-size:var(--fs-ui);font-weight:var(--fw-semibold);line-height:1.35;color:var(--bt-pv-ink);
  text-align:center;overflow-wrap:break-word;
  transition:border-color .2s ease;
}
.bt-privacy__badge:hover{border-color:var(--bt-pv-gold)}
.bt-privacy__lock{flex:0 0 auto;color:var(--bt-pv-gold)}

/* ─── Dark promise panel ─── */
.bt-privacy__panel{
  min-width:0;
  background:var(--bt-pv-ink);border-radius:16px;padding:30px 22px;
}
.bt-privacy__panel-title{
  margin:0 0 22px;padding-bottom:22px;
  border-bottom:1px solid rgba(255,255,255,.12);
  font-size:var(--fs-h3);
  font-weight:var(--fw-semibold);line-height:var(--lh-heading-sm);color:#fff;
}
.bt-privacy__panel-title em{font-style:normal;color:var(--bt-pv-gold)}

.bt-privacy__list{list-style:none;margin:28px 0 0;padding:0}
.bt-privacy__point{
  position:relative;padding-left:34px;min-width:0;
  font-size:var(--fs-body);line-height:1.65;color:rgba(255,255,255,.82);
  overflow-wrap:break-word;
}
.bt-privacy__point + .bt-privacy__point{margin-top:16px}
/* Check mark drawn in two pseudo-elements — the tinted disc and the tick
   itself, an L rotated 45°. Decorative, so it stays out of the markup. */
.bt-privacy__point::before{
  content:'';position:absolute;left:0;top:2px;
  width:24px;height:24px;border-radius:50%;
  background:rgba(201,162,74,.16);
}
.bt-privacy__point::after{
  content:'';position:absolute;left:9px;top:8px;
  width:5px;height:9px;
  border:solid var(--bt-pv-gold);border-width:0 1.8px 1.8px 0;
  transform:rotate(45deg);
}

/* Two pills per row once there is width for them. */
@media (min-width:361px){
  .bt-privacy__badges{grid-template-columns:repeat(2,minmax(0,1fr))}
}
/* Small tablet: still stacked, but the pills go back to content width and
   the panel to its full padding. */
@media (min-width:601px){
  .bt-privacy__grid{gap:40px}
  .bt-privacy__text{max-width:620px;line-height:1.8}
  .bt-privacy__badges{display:flex;flex-wrap:wrap;gap:12px}
  .bt-privacy__badge{justify-content:flex-start;padding:12px 22px;font-size:var(--fs-body);text-align:left}
  .bt-privacy__panel{padding:48px 44px;border-radius:20px}
  .bt-privacy__point{padding-left:38px}
  .bt-privacy__point + .bt-privacy__point{margin-top:20px}
}
/* Tablet: the split opens, weighted towards the panel so it never turns
   into a narrow column of two-word lines. */
@media (min-width:861px){
  .bt-privacy__grid{grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);gap:40px}
  .bt-privacy__panel{padding:40px 32px}
}
/* Desktop: equal columns. */
@media (min-width:1025px){
  .bt-privacy__grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:72px}
  .bt-privacy__text{max-width:500px}
  .bt-privacy__panel{padding:48px 44px}
}

/* ═══════════════════════════════════════════════════════════════
   ABOUT PAGE — HOW TO ORDER
   The closing band, under the white .bt-privacy one. Same
   convention as the blocks above: .bt-ez prefix, used in no other
   template, the max-w-7xl mx-auto px-4 container on the markup,
   and the three colours as tokens on the section rather than in
   :root, since they are this block's palette and not the site's.

   White band, cream tiles: this is the white step in the page's
   cream / white run, so the tiles take the warm tone. (They were
   the other way round while the band itself carried the colour.)
   ═══════════════════════════════════════════════════════════════ */
.bt-ez{
  --bt-ez-gold:var(--gold);
  --bt-ez-ink:#1a1a1a;
  --bt-ez-text:#6b6b6b;
  --bt-ez-card:#faf8f4;
  --bt-ez-line:#efebe2;
  background:#fff;
}

.bt-ez__head{text-align:center;margin-bottom:48px}

/* Heading is a plain .bt-section-title on the markup; .bt-ez__title was a
   verbatim copy of it. */

.bt-ez__steps{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:24px;
}
.bt-ez__step{
  min-width:0;text-align:center;
  padding:36px 32px 34px;
  background:var(--bt-ez-card);
  border:1px solid var(--bt-ez-line);border-radius:14px;
  transition:border-color .2s ease,background-color .2s ease;
}
.bt-ez__step:hover{border-color:var(--bt-ez-gold)}

.bt-ez__num{
  display:inline-flex;align-items:center;justify-content:center;
  width:44px;height:44px;margin-bottom:20px;
  border-radius:50%;background:var(--bt-ez-gold);
  box-shadow:0 0 0 6px rgba(201,162,74,.14);
  color:#fff;font-size:var(--fs-h4);font-weight:var(--fw-semibold);line-height:1;
}
/* The last step closes the sequence, so its badge takes the ink tone. */
.bt-ez__step:last-child .bt-ez__num{
  background:var(--bt-ez-ink);box-shadow:0 0 0 6px rgba(26,26,26,.08);
}

.bt-ez__step-title{
  margin:0 0 10px;
  font-size:var(--fs-h4);font-weight:var(--fw-semibold);line-height:var(--lh-heading-sm);color:var(--bt-ez-ink);
}
.bt-ez__step-desc{
  margin:0 auto;max-width:300px;
  font-size:var(--fs-body);line-height:1.65;color:var(--bt-ez-text);
}

@media (max-width:1024px){
  .bt-ez{padding:72px 0}
  .bt-ez__steps{grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}
  .bt-ez__step{padding:32px 26px 30px}
}
/* Phone: the tile turns into a compact row — badge in its own column, the
   text left-aligned beside it, so six steps stay scannable in one column. */
@media (max-width:600px){
  .bt-ez{padding:56px 0}
  .bt-ez__head{margin-bottom:32px}
  .bt-ez__steps{grid-template-columns:minmax(0,1fr);gap:14px}
  .bt-ez__step{
    display:grid;grid-template-columns:40px minmax(0,1fr);
    grid-template-areas:"num title" "num text";
    column-gap:16px;align-items:start;
    padding:20px 18px;border-radius:12px;text-align:left;
  }
  .bt-ez__num{
    grid-area:num;align-self:start;
    width:40px;height:40px;margin-bottom:0;
    box-shadow:0 0 0 5px rgba(201,162,74,.14);
  }
  .bt-ez__step:last-child .bt-ez__num{box-shadow:0 0 0 5px rgba(26,26,26,.08)}
  .bt-ez__step-title{grid-area:title;margin-bottom:6px}
  .bt-ez__step-desc{grid-area:text;max-width:none;margin:0}
}

/* ═══════════════════════════════════════════════════════════════
   ABOUT PAGE — SUPPORT CTA
   The dark band closing the page, under .bt-ez. Prefixed
   .bt-support rather than .bt-cta: the contact page already owns
   .bt-cta (a white, centred band, see "CONTACT PAGE" above), so
   this block would have repainted that section.

   The buttons restate the theme's pill geometry — inline-flex,
   9999px radius, icon then label — rather than reusing .btn-gold,
   whose hover lifts the button and lands on --gold-d; this panel
   wants the flatter hover the brief asks for. Everything else is
   local: the panel is the only surface, the icons are inline SVGs
   inheriting currentColor, and there is no JavaScript.
   ═══════════════════════════════════════════════════════════════ */
/* ═══════════════════════════════════════════════════════════════
   ABOUT PAGE — WHO WE SERVE
   Cream band directly above the CTA. Same convention as the blocks
   above: .bt-serve prefix, used in no other template, colours as
   tokens on the section rather than in :root.

   The band is white; the content sits in a contained box washed
   with the faintest gold tint, so the section reads as one warm
   panel on white rather than another full-width colour band. The
   box caps at 1000px rather than using the page container, since
   this is one paragraph and wants the shorter measure.

   Inside it, one row — badge, hairline, statement — and nothing
   else: no second surface, no shadow.
   ═══════════════════════════════════════════════════════════════ */
.bt-serve{
  --bt-sv-gold:var(--gold);
  --bt-sv-ink:#1a1a1a;
  --bt-sv-text:#5a5a5a;
  --bt-sv-line:#e6dfcf;
  --bt-sv-tint:rgba(201,162,74,.07);
  background:#fff;
}
.bt-serve__inner{
  max-width:1000px;margin-inline:auto;
  display:flex;align-items:center;gap:40px;
  padding:40px 48px;
  background:var(--bt-sv-tint);
  border:1px solid rgba(201,162,74,.18);border-radius:var(--r);
}

.bt-serve__icon{
  flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;
  width:96px;height:96px;border-radius:50%;
  background:#fff;border:1px solid rgba(201,162,74,.35);
  box-shadow:0 0 0 10px rgba(201,162,74,.08);
  color:var(--bt-sv-gold);
}
.bt-serve__icon svg{width:40px;height:40px}

/* The divider is the body's own left border, so it is exactly as tall as
   the text beside it rather than a separate element to keep in sync. */
.bt-serve__body{
  min-width:0;
  border-left:1px solid var(--bt-sv-line);padding-left:40px;
}
/* Heading is .bt-section-title --lead on the markup (was .bt-serve__title,
   another weight-500 copy of the same scale). */
.bt-serve__text{
  margin:0;max-width:640px;
  font-size:var(--fs-body-lg);line-height:1.75;color:var(--bt-sv-text);
}

@media (max-width:1024px){
  .bt-serve{padding:64px 24px 32px}
  .bt-serve__inner{padding:36px 32px}
}
/* Phone: the row becomes a centred stack and the divider goes with it —
   a vertical rule makes no sense once the icon sits above the text. */
@media (max-width:700px){
  .bt-serve{padding:48px 16px 28px}
  .bt-serve__inner{
    flex-direction:column;align-items:center;text-align:center;
    gap:22px;padding:28px 20px;
  }
  .bt-serve__icon{width:72px;height:72px;box-shadow:0 0 0 8px rgba(201,162,74,.08)}
  .bt-serve__icon svg{width:32px;height:32px}
  .bt-serve__body{border-left:0;padding-left:0}
}

/* Same cream as .bt-serve above it — the two bands share one ground, so the
   top padding is cut to 40px to meet .bt-serve's 40px bottom and the join
   reads as one block. Bottom padding stays the band rhythm .bt-section sets.
   The card, its content and both buttons are unchanged. */
.bt-support{background:var(--ivory);}

/* ABOUT PAGE — FAQ
   White band closing the page, under the cream CTA. No design of its own:
   the heading block, the .ct-faq-inner wrapper and .product-desc are the
   ones the home and contact FAQ bands already use, and the accordion is
   site-core.php's site-wide Rank Math one. Only the ground is declared. */
/* These two have to sit after the rule above, not up in .bt-serve's own
   media queries: same specificity, so source order decides, and there they
   were being overridden straight back to 40px. Each one matches the bottom
   padding .bt-serve takes at the same breakpoint. */
@media (max-width:1024px){.bt-support{padding-top:32px}}
@media (max-width:700px){.bt-support{padding-top:28px}}

/* The one geometric difference from the home page: there the card runs the
   full max-w-7xl container; here it is capped so it reads as a contained
   banner with white showing either side. Below that width it is fluid, so
   the page gutter is the only thing between it and the screen edge. */
.bt-support__banner{max-width:880px;margin-inline:auto}

/* Two buttons instead of the home page's one, centred under the copy. The
   row carries the top margin .promo-cta would otherwise contribute, so the
   two buttons stay level with each other. */
.bt-support__actions{
  display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:12px;
  margin-top:20px;
}
.bt-support .promo-cta{margin-top:0}

/* Secondary button for a dark surface: the same pill geometry as .btn-gold /
   .promo-cta, drawn as an outline so it reads as the quieter of the two.
   Promoted to the shared name .btn-ghost when the shop hero needed the same
   control — .bt-support__ghost is kept as an alias so the About CTA's markup
   did not have to change, rather than the rule being declared twice. */
.btn-ghost,.bt-support__ghost{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  max-width:100%;padding:12px 26px;
  border:1px solid rgba(255,255,255,.35);border-radius:9999px;
  background:transparent;color:#fff;
  font-family:inherit;font-size:var(--fs-ui);font-weight:var(--fw-semibold);line-height:1;
  text-decoration:none;white-space:nowrap;
  transition:border-color .2s ease,color .2s ease;
}
.btn-ghost:hover,.bt-support__ghost:hover{border-color:var(--gold);color:var(--gold-l)}
.btn-ghost:focus-visible,.bt-support__ghost:focus-visible{outline:2px solid var(--gold);outline-offset:3px}

/* Matches the step .promo-cta takes at the same breakpoint. */
@media (min-width:640px){
  .btn-ghost,.bt-support__ghost{font-size:var(--fs-body);padding:13px 30px}
  .bt-support__actions{margin-top:24px;gap:14px}
}
/* Narrow phones: the two pills stack full width rather than sitting on one
   cramped line. */
@media (max-width:479px){
  .bt-support__actions{flex-direction:column;width:100%}
  .bt-support__actions>a{width:100%}
}

@media (max-width:760px){
  .ab-vm__card{padding:26px 22px}
  .ab-vm__icon{width:48px;height:48px;border-radius:14px;font-size:21px}
  .ab-vm__label{margin-top:20px}
  .ab-vm__card-title{max-width:none}
  .ab-vm__note{margin-top:20px;padding:22px 20px 22px 24px}
}

/* ═══════════════════════════════════════════════════════════════
   SHOP PAGE HERO
   The dark opening band on the Shop archive and every product
   category archive (woocommerce/archive-product.php). Same
   convention as the .ab-* / .ct-* blocks: every selector is
   prefixed .sh-hero and appears in no other template, so it loads
   site-wide but only ever paints on the shop.

   It is NOT a third dark-hero design. The surface, the gradient and
   the closing curve are the shared .bt-darkband component the About
   and Contact heroes already use; the type is the shared display
   tier (--fs-display / --fw-display / --lh-display / --ls-display);
   the badge restates .ab-hero__badge; the accent is --gold. Only the
   breadcrumb, the search row and the trust strip are declared here,
   because no other hero has them.

   Vertical rhythm is --sec-y plus the band's own --wave-h, exactly
   as .ab-hero__inner does — the hero is sized by its content, not by
   a fixed height, so a long category name can never clip.
   ═══════════════════════════════════════════════════════════════ */
/* Accent washes. Same idiom and same two tokens as .ab-hero::before /
   ::after, with a slow drift added: a transform loop on a blurred
   radial, so it costs one composited layer and never reflows. */
.sh-hero::before,.sh-hero::after{
  content:'';position:absolute;border-radius:50%;pointer-events:none;z-index:0;
  will-change:transform;
}
/* Anchored to the dark panel's left edge rather than the section's. The
   section is full-width white now, and this is the one gold wash low
   enough in opacity to vanish on the dark ground but still read as a warm
   smudge if it spills onto that white — its white counterparts below do
   not have the problem. */
.sh-hero::before{
  width:520px;height:520px;left:calc(50% - var(--band-w) / 2);bottom:-260px;
  background:radial-gradient(circle,rgba(201,162,74,.20),transparent 70%);
  animation:shHeroDrift 12s ease-in-out infinite;
}
.sh-hero::after{
  width:420px;height:420px;right:-150px;top:-220px;
  background:radial-gradient(circle,rgba(255,255,255,.05),transparent 70%);
  animation:shHeroDrift 12s ease-in-out infinite reverse;
}
@keyframes shHeroDrift{
  0%,100%{transform:translate3d(0,0,0)}
  50%{transform:translate3d(18px,-14px,0)}
}

/* .sh-hero__inner lives with .ab-hero__inner above — same rule, one
   declaration, shared by both heroes. */

/* Children fade up in sequence. The keyframes and the easing are the
   theme's own (.bt-benefit uses the same pair); only the delays are
   local. `both` holds the from-state before the delay elapses, which is
   what stops a flash of finished content on load.
   The global prefers-reduced-motion rule near the top of this file
   already collapses these to a single instant frame. */
.sh-hero__badge,
.sh-hero__title,
.sh-hero__text,
.sh-hero__actions{
  animation:fadeUp .6s cubic-bezier(.22,.61,.36,1) both;
}
.sh-hero__badge  {animation-delay:0s}
.sh-hero__title  {animation-delay:.08s}
.sh-hero__text   {animation-delay:.16s}
.sh-hero__actions{animation-delay:.24s}

/* ─── Badge ─── */
/* .sh-hero__badge and .sh-hero__dot live with .ab-hero__badge / .ab-hero__dot
   above — same pill, same live dot, one declaration shared by both heroes. */

/* ─── Heading + standfirst ─── */
/* Type is .typography-display --invert on the markup; only the measure is
   here, matching .ab-hero__title. .sh-hero__text lives with .ab-hero__text
   above — identical standfirst treatment, declared once. */
.sh-hero__title{margin:18px auto 0;max-width:19ch;text-wrap:balance}

/* ─── Actions ─── */
/* The same centred pair the About page's dark CTA uses — .btn-gold as the
   primary, the shared .btn-ghost as the quieter second — so the two dark
   bands on the site close on one button language. Only the gap above is
   declared here; the buttons carry their own geometry. */
.sh-hero__actions{
  display:flex;flex-wrap:wrap;justify-content:center;align-items:center;
  gap:12px;margin-top:28px;
}

/* Landing point for the hero's "Browse Products" anchor. The header is
   `sticky top-0`, so without this the jump would park the first product
   row underneath it. */
.sh-scroll-target{scroll-margin-top:96px}

/* ── Shop bands ──
   Two surfaces, in this order: the products on white, the FAQ on the cream
   body ground. The hero's closing wave is filled #fff in the template to meet
   the first one, so there is no seam under the curve.

   These set a background and nothing else — no padding, no width, no type —
   so the spacing inside them is still the wrapper's and .bt-section's job and
   the product grid is untouched. */
/* No width of its own. The FAQ column is the shared .ct-faq-inner wrapper the
   blog, About, home and contact bands all use, and its 860px measure is set
   once for all five bands in the "FAQ MEASURE" rule above — so every FAQ on
   the site stays the same width and no band caps itself. */

/* ═══ SUPPORT CTA (.bt-helpcta) ═══
   Compact horizontal support banner: icon, text, button on one row.

   Separate from .bt-support (page-about.php), which is the homepage's dark
   centred .promo-banner reused — a different component with a different job.
   Restyling that one would have repainted the About page and the homepage.

   The band is pure white and carries only .bt-section's rhythm; every bit of
   the visual treatment is on the inner box, which is what the white ground is
   there to set off.

   The box is the theme's dark card, not a light one: --forest is the same
   fill .promo-banner uses on the home and About pages, with .promo-title's
   white ink and .promo-copy's rgba(255,255,255,.6) for the second line, so
   this reads as the same surface rather than a third dark treatment. The gold
   pill and the button follow from that — on a dark ground the theme pairs
   --gold-l ink with a .btn-gold action (the shop hero and the About CTA both
   do), so there is still no new button here to keep in step with the others.

   Type comes from .typography-h4 / .typography-small on the markup; the rules
   below set only colour, margins and layout, so this component owns no font
   sizes of its own. */

.bt-helpcta__box{
  display:flex;align-items:center;gap:22px;
  padding:26px 36px;
  background:var(--forest);
  border:1px solid rgba(255,255,255,.08);
  border-radius:var(--r);
  color:#fff;
}

/* Same pill treatment .bt-darkband gives .badge-gold: the tint that works on
   ivory is too weak to hold its edge on the dark ramp, so the fill comes up
   and the ink moves to the lighter gold. */
.bt-helpcta__icon{
  flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;
  width:52px;height:52px;border-radius:50%;
  background:rgba(201,162,74,.18);color:var(--gold-l);
  border:1px solid rgba(232,217,160,.28);
  font-size:21px;line-height:1;
}

/* min-width:0 so a long heading wraps inside the row instead of pushing the
   button off the end — the usual flex-item overflow trap. */
.bt-helpcta__text{flex:1 1 auto;min-width:0}
.bt-helpcta__title{margin:0;color:#fff}
.bt-helpcta__copy{margin:6px 0 0;color:rgba(255,255,255,.6)}
.bt-helpcta__btn{flex:0 0 auto}
/* Holds the banner's actions when there is more than one (the blog page pairs
   Contact Support with View Products). It takes the single button's place as
   the row's third part, so the box is still icon | text | actions and every
   rule below keeps working; with one button inside it behaves identically to
   the button on its own. */
.bt-helpcta__actions{flex:0 0 auto;display:flex;flex-wrap:wrap;align-items:center;gap:10px}

/* Breakpoints are Bootstrap's own (the site already carries Bootstrap Icons,
   and these are the widths the brief referred to), expressed as max-width with
   the .02 gap so each range ends exactly where the next begins and no width
   falls through both or neither:
     ≥768px   md and up   — the full row
     576-767  sm          — still a row, just tightened
     <576px   xs          — the only range that stacks

   So the banner stays icon | text | button on landscape phones and tablets,
   and only becomes a centred column on portrait phones, where a three-part row
   would leave the text about 120px wide. */
@media (max-width:1024px){
  .bt-helpcta__box{gap:18px;padding:24px 26px}
}

/* sm — row kept. Gaps and padding give first, then the icon, then the button's
   padding; the text absorbs the rest by wrapping, which its min-width:0 is what
   allows. .btn-gold is white-space:nowrap, so its label never breaks in two. */
@media (max-width:767.98px){
  .bt-helpcta__box{gap:14px;padding:18px 18px}
  .bt-helpcta__icon{width:44px;height:44px;font-size:18px}
  .bt-helpcta__btn{padding:12px 20px}
}

/* xs — icon, heading, copy, button, stacked and centred on one axis. The
   button goes full width because at this size a centred pill floating in the
   middle reads as unfinished next to the centred text above it. */
@media (max-width:575.98px){
  .bt-helpcta__box{
    flex-direction:column;align-items:center;text-align:center;
    gap:14px;padding:22px 18px;
  }
  .bt-helpcta__text{width:100%}
  .bt-helpcta__icon{width:46px;height:46px;font-size:19px}
  .bt-helpcta__btn{width:100%;padding:12px 20px}
  /* Stacked too, so a pair of actions reads as two full-width rows rather
     than two half pills — the same step .sh-hero__actions takes here. */
  .bt-helpcta__actions{width:100%;flex-direction:column}
}

@media (max-width:600px){
  .sh-hero__title{max-width:20ch}
  .sh-scroll-target{scroll-margin-top:76px}
}
/* Narrow phones: the two pills stack full width rather than sitting on one
   cramped line — the same step .bt-support__actions takes. */
@media (max-width:479px){
  .sh-hero__actions{flex-direction:column;width:100%}
  .sh-hero__actions>a{width:100%}
}

/* ═══════════════════════════════════════════════════════════════
   UNIVERSAL FAQ
   The one FAQ design for the whole site — pages, posts, products,
   product categories, and anything an admin adds later. It is the
   only FAQ styling that exists: the per-page inline <style> that
   site-core.php used to print on singular views, and the inline CSS
   the mam-faq mu-plugin injected on product pages, are both gone.

   Two things feed it:
     assets/js/faq.js  normalises Rank Math / Yoast / hand-written FAQ
                       markup into the .bt-faq__* contract below and
                       adds the button + aria wiring. Enqueued
                       site-wide in functions.php.
     .mam-faq          the product-description accordion builds its own
                       buttons and binds its own toggle, so the script
                       skips it and it is mapped onto the same visuals
                       here instead (see the aliases at the end).

   Admins keep adding FAQs exactly as they do now — a Rank Math FAQ
   block, or the [mam_faq] shortcode. No class, no styling, no extra
   step: the design applies on its own.

   Colours are local tokens so the whole component retints from one
   place — every colour below is set once here and nowhere else, which
   is why a palette change never needs a single override rule.

   The bar is a light warm cream-gold with near-black text and a
   near-black +/x mark, inside a box with a near-black hairline. Nothing
   in the component paints the icon or the text per state, so both stay
   black in the default, hover, open and focus states by construction
   rather than by a stack of !important overrides.

   Scoped strictly to .bt-faq / .mam-faq / .wp-block-details, so no
   other accordion, tab or section on the site is affected.
   ═══════════════════════════════════════════════════════════════ */
.bt-faq,.mam-faq,details.wp-block-details{
  /* Question bar. A soft cream-gold, deliberately well short of a
     saturated yellow; the two variants are one and two steps deeper in
     the same family, so an open or hovered bar never leaves it. */
  --bt-faq-q-bg:#f6eedb;
  --bt-faq-q-bg-open:#f2e8d0;
  --bt-faq-q-bg-hover:#eee2c2;
  --bt-faq-q-ink:#111;
  --bt-faq-icon-ink:#111;
  /* Outer box hairline. */
  --bt-faq-border:#1a1a1a;
  --bt-faq-text:#4a4a4a;
  --bt-faq-bg:#fff;
  --bt-faq-line:#ece9e2;
  /* Content-container cap. 1152px is the theme's max-w-6xl; the box is
     width:100% underneath it, so in a narrower column (a product
     description) the column still wins and this only caps a wide one. */
  --bt-faq-max:1152px;
  --bt-faq-radius:16px;
  --bt-faq-item-radius:10px;
  --bt-faq-gap:14px;
  --bt-faq-box-pad:24px;
  --bt-faq-q-pad:14px 18px;
  --bt-faq-a-pad:20px 26px 22px;
  --bt-faq-q-size:17px;
  --bt-faq-a-size:16px;
  /* 18px, not 20: the mark is a UI affordance beside the question, not a
     second heading. flex-shrink is already handled by the flex:0 0 auto on the
     icon rule below, and the bars stay 2px, which is what reads as the weight. */
  --bt-faq-icon:18px;
}

/* ─── Outer box ─── */
/* max-width is a token rather than a fixed number so the measure can be
   retuned once; 1152px is the theme's max-w-6xl container. width:100%
   means it never exceeds a narrower column (a product description,
   say) — it only ever caps a wide one. */
.bt-faq,.mam-faq{
  width:100%;
  margin-top:32px;
  padding:var(--bt-faq-box-pad);
  background:var(--bt-faq-bg);
  border:1.5px solid var(--bt-faq-border);
  border-radius:var(--bt-faq-radius);
  /* The theme's prose contexts (.product-desc) give lists a marker and an
     indent; an FAQ is not that kind of list. */
  list-style:none;
}
/* Rank Math wraps its items in one more div. It is a pass-through: the
   gap between items is the box's job, not a wrapper's. */
.bt-faq .rank-math-list,
.bt-faq .schema-faq{
  display:flex;flex-direction:column;gap:var(--bt-faq-gap);
  margin:0;padding:0;border:0;background:none;list-style:none;
}
/* When the items are direct children (Yoast, hand-written, and Rank Math
   once its inner .rank-math-list is the flex parent above). */
.bt-faq{display:flex;flex-direction:column;gap:var(--bt-faq-gap)}
.bt-faq>.rank-math-list{gap:var(--bt-faq-gap)}

/* ─── Item ─── */
.bt-faq__item,.mam-faq-item{
  margin:0;border:0;background:none;min-width:0;
}

/* ─── Question bar ─── */
/* The heading element the plugin emitted (h3 for Rank Math) stays in the
   document and keeps its level; it is reduced to a transparent wrapper so
   the <button> inside it is the whole bar. Resetting the theme's global
   h1-h6 type here is deliberate — an FAQ question is UI, not a section
   heading, and it must not inherit the h3 tier. */
/* Two classes deep so this reset reliably beats the theme's own global
   h1-h6 type rule regardless of where in the cascade an FAQ block renders.
   The same reasoning applies to the answer rules further down. */
.bt-faq .bt-faq__q-head{
  margin:0;padding:0;border:0;background:none;
  font:inherit;letter-spacing:normal;color:inherit;
}
.bt-faq__q,.mam-faq-q{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  width:100%;margin:0;padding:var(--bt-faq-q-pad);
  background:var(--bt-faq-q-bg);color:var(--bt-faq-q-ink);
  border:0;border-radius:var(--bt-faq-item-radius);
  font-family:inherit;font-size:var(--bt-faq-q-size);font-weight:600;line-height:1.45;
  text-align:left;cursor:pointer;
  transition:background-color .2s ease,border-radius .25s ease;
}
/* Open and hover are one and two steps deeper in the same cream family.
   Hover is declared after open so a hovered open bar reads as hovered. */
.bt-faq__item.is-open>.bt-faq__q-head>.bt-faq__q,
.mam-faq-item.is-open>.mam-faq-q{background:var(--bt-faq-q-bg-open)}
.bt-faq__q:hover,.mam-faq-q:hover{background:var(--bt-faq-q-bg-hover)}
/* The focus ring is the border ink, not the accent: gold on this cream
   sits at roughly 1.6:1 and would be effectively invisible, which is the
   one control on the page a keyboard user cannot do without. */
.bt-faq__q:focus-visible,.mam-faq-q:focus-visible{
  outline:2px solid var(--bt-faq-border);outline-offset:3px;
}
/* Square the bottom corners when open so the bar joins its answer. */
.bt-faq__item.is-open>.bt-faq__q-head>.bt-faq__q,
.mam-faq-item.is-open>.mam-faq-q{
  border-bottom-left-radius:0;border-bottom-right-radius:0;
}
/* The question text itself. <strong> is what Rank Math and Yoast wrap the
   question in; it must not add a second weight on top of the bar's 600. */
.bt-faq__q-text{flex:1;min-width:0;overflow-wrap:break-word}
.bt-faq .bt-faq__q-text strong,.bt-faq .bt-faq__q-text b,.bt-faq .bt-faq__q-text p{
  font:inherit;font-weight:inherit;color:inherit;margin:0;display:inline;
}

/* ─── Icon ─── */
/* Drawn with two bars rather than a glyph, so it is identical in every
   font and rotates cleanly. aria-hidden in the markup, transparent
   background, no disc behind it.

   The ink is declared once, here. No hover, open or focus rule anywhere
   in this component touches it, and the theme's dequeued mam-faq CSS was
   the only other thing that ever coloured it — so the mark is black in
   every state without a single override. */
.bt-faq__icon,.mam-faq-icon{
  position:relative;flex:0 0 auto;
  width:var(--bt-faq-icon);height:var(--bt-faq-icon);
  background:none;
  transition:transform .25s ease;
}
.bt-faq__icon::before,.bt-faq__icon::after,
.mam-faq-icon::before,.mam-faq-icon::after{
  content:'';position:absolute;top:50%;left:50%;
  background:var(--bt-faq-icon-ink);border-radius:2px;
  transform:translate(-50%,-50%);
}
.bt-faq__icon::before,.mam-faq-icon::before{width:75%;height:2px}
.bt-faq__icon::after,.mam-faq-icon::after{width:2px;height:80%}
/* + becomes x. */
.bt-faq__item.is-open .bt-faq__icon,
.mam-faq-item.is-open .mam-faq-icon{transform:rotate(45deg)}

/* ─── Answer panel ─── */
/* grid-template-rows 0fr -> 1fr animates to the answer's real height, so a
   long answer is never clipped the way a guessed max-height clips it. The
   inner wrapper (added by faq.js) is what collapses. */
/* visibility (not opacity alone) is what takes a closed answer out of the
   tab order and the accessibility tree — at opacity:0 the text is still
   focusable and still read aloud, so a "closed" panel would not be closed
   to a screen reader. It transitions discretely: instant on open, held
   until the collapse finishes on close. */
.bt-faq__a{
  display:grid;grid-template-rows:0fr;
  transition:grid-template-rows .25s ease,opacity .25s ease,visibility .25s;
  opacity:0;visibility:hidden;margin:0;padding:0;border:0;background:none;
}
.bt-faq__item.is-open>.bt-faq__a{grid-template-rows:1fr;opacity:1;visibility:visible}
.bt-faq__a-inner{
  min-height:0;overflow:hidden;
  background:var(--bt-faq-bg);
  border:1px solid var(--bt-faq-line);border-top:0;
  border-radius:0 0 var(--bt-faq-item-radius) var(--bt-faq-item-radius);
}
/* Padding sits on a child of the collapsing box: on the box itself it would
   still occupy height at 0fr and leave a visible sliver when closed. */
.bt-faq__item.is-open>.bt-faq__a>.bt-faq__a-inner{padding:var(--bt-faq-a-pad)}

/* Answer copy. Prefixed with .bt-faq / .mam-faq for the same reason as the
   question head: .product-desc p is (0,1,1) and would otherwise repaint the
   answers in --ink-body at a 1em margin. */
.bt-faq .bt-faq__a-inner,.mam-faq .mam-faq-a{
  color:var(--bt-faq-text);
  font-size:var(--bt-faq-a-size);line-height:1.75;
}
.bt-faq .bt-faq__a-inner>*,.mam-faq .mam-faq-a>*{margin:0 0 12px;color:inherit;font-size:inherit;line-height:inherit}
.bt-faq .bt-faq__a-inner>:last-child,.mam-faq .mam-faq-a>:last-child{margin-bottom:0}
.bt-faq .bt-faq__a-inner a,.mam-faq .mam-faq-a a{color:var(--gold-d);text-decoration:underline}
.bt-faq .bt-faq__a-inner ul,.bt-faq .bt-faq__a-inner ol{padding-left:1.3em;margin-bottom:12px;list-style-position:outside}
.bt-faq .bt-faq__a-inner li{margin-bottom:.35em;color:inherit}

/* ─── mam-faq aliases ─── */
/* The mu-plugin's accordion keeps its own JS (it sets an inline max-height
   and toggles .is-open), so only the box needs restating in this design's
   terms. Its old hairline-row look is fully overridden. */
.mam-faq{border-top:1.5px solid var(--bt-faq-border)}
.mam-faq-item{border-bottom:0}
.mam-faq-item+.mam-faq-item{margin-top:var(--bt-faq-gap)}
.mam-faq-a{
  background:var(--bt-faq-bg);
  border:1px solid var(--bt-faq-line);border-top:0;
  border-radius:0 0 var(--bt-faq-item-radius) var(--bt-faq-item-radius);
  padding:0 26px;
}
.mam-faq-item.is-open>.mam-faq-a{padding:var(--bt-faq-a-pad)}

/* ─── Gutenberg Details block ─── */
/* Native disclosure, so it needs no script — only the same clothes. */
details.wp-block-details{
  width:100%;max-width:var(--bt-faq-max,1152px);margin:32px auto;
  padding:var(--bt-faq-box-pad);
  background:var(--bt-faq-bg);
  border:1.5px solid var(--bt-faq-border);border-radius:var(--bt-faq-radius);
}
details.wp-block-details>summary{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:var(--bt-faq-q-pad);
  background:var(--bt-faq-q-bg);color:var(--bt-faq-q-ink);
  border-radius:var(--bt-faq-item-radius);
  font-size:var(--bt-faq-q-size);font-weight:600;line-height:1.45;
  cursor:pointer;list-style:none;
  transition:background-color .2s ease;
}
details.wp-block-details>summary::-webkit-details-marker{display:none}
details.wp-block-details>summary::after{
  content:'';flex:0 0 auto;
  width:var(--bt-faq-icon);height:var(--bt-faq-icon);
  background:
    linear-gradient(var(--bt-faq-icon-ink),var(--bt-faq-icon-ink)) center/100% 2px no-repeat,
    linear-gradient(var(--bt-faq-icon-ink),var(--bt-faq-icon-ink)) center/2px 100% no-repeat;
  transition:transform .25s ease;
}
details.wp-block-details[open]>summary::after{transform:rotate(45deg)}
details.wp-block-details[open]>summary{background:var(--bt-faq-q-bg-open)}
details.wp-block-details>summary:hover{background:var(--bt-faq-q-bg-hover)}
details.wp-block-details>summary:focus-visible{outline:2px solid var(--bt-faq-border);outline-offset:3px}
details.wp-block-details[open]>summary{border-bottom-left-radius:0;border-bottom-right-radius:0}
details.wp-block-details>:not(summary){
  padding:var(--bt-faq-a-pad);
  border:1px solid var(--bt-faq-line);border-top:0;
  border-radius:0 0 var(--bt-faq-item-radius) var(--bt-faq-item-radius);
  color:var(--bt-faq-text);font-size:var(--bt-faq-a-size);line-height:1.75;
}

/* ─── Responsive ─── */
@media (max-width:1024px){
  .bt-faq,.mam-faq,details.wp-block-details{--bt-faq-box-pad:20px}
}
@media (max-width:600px){
  .bt-faq,.mam-faq,details.wp-block-details{
    --bt-faq-box-pad:14px;
    --bt-faq-radius:12px;
    --bt-faq-item-radius:8px;
    --bt-faq-gap:10px;
    --bt-faq-q-pad:16px 18px;
    --bt-faq-a-pad:16px 18px 18px;
    --bt-faq-q-size:15.5px;
    --bt-faq-a-size:15px;
    margin:24px auto;
  }
  .mam-faq-a{padding-left:18px;padding-right:18px}
}

@media (prefers-reduced-motion:reduce){
  .bt-faq__a,.bt-faq__icon,.mam-faq-icon,.bt-faq__q,.mam-faq-q,
  details.wp-block-details>summary::after{transition:none}
}

/* ═══════════════════════════════════════════════════════════════
   FAQ — Shop + category archives (spacing/alignment only)
   Scoped to body.tax-product_cat / body.post-type-archive-product so no
   other FAQ on the site (blog, About, Contact, product pages) is
   affected. Nothing here touches colour, font or the accordion's
   behaviour — the global h2 scale (the same one the content H2s above use)
   supplies the heading's type, and the box keeps every "UNIVERSAL FAQ"
   token (--bt-faq-q-bg, --bt-faq-border, the icon, the open/hover states)
   exactly as declared above; only a few spacing custom properties are
   redeclared on top of it. The shared "FAQ MEASURE" 860px cap (above)
   is left as-is — this section keeps that same max-width, it does not
   go full width. The box's own margin (.bt-faq,.mam-faq{margin:32px auto}
   above, including its margin-top:32px) is left untouched on both
   templates — nothing here overrides it.

   The "Frequently Asked Questions" heading is template markup on the
   Shop root only (archive-product.php, a .bt-section-title h2) — on the category
   template it now comes from the category's own content (ACF
   "category_content" WYSIWYG) instead, so no heading rule is scoped to
   body.tax-product_cat here. */

body.tax-product_cat .sh-faq .bt-faq,
body.post-type-archive-product .sh-faq .bt-faq{
  --bt-faq-gap:12px;
  --bt-faq-q-pad:18px 20px;
  --bt-faq-a-pad:0 20px 18px;
  --bt-faq-text:var(--text1);
}
body.tax-product_cat .sh-faq .bt-faq .bt-faq__q,
body.post-type-archive-product .sh-faq .bt-faq .bt-faq__q{
  gap:16px;min-height:56px;
}
body.tax-product_cat .sh-faq .bt-faq .bt-faq__a-inner,
body.post-type-archive-product .sh-faq .bt-faq .bt-faq__a-inner{
  line-height:1.7;
}

@media (max-width:767px){
  body.tax-product_cat .sh-faq .bt-faq,
  body.post-type-archive-product .sh-faq .bt-faq{
    --bt-faq-gap:10px;
    --bt-faq-q-pad:16px;
    --bt-faq-a-pad:0 16px 16px;
  }
}

/* BACK TO TOP
   Fixed circular button, bottom-right, on every page. Hidden (faded +
   dropped + unclickable) near the top of the page, fades/slides in once the
   visitor has scrolled past a threshold. Toggled by the .is-visible class in
   footer.php's scroll listener. */
.bt-to-top{
  position:fixed;right:20px;bottom:24px;z-index:60;
  width:44px;height:44px;border-radius:9999px;border:1px solid var(--gold);
  background:var(--gold);color:#1c1c1c;
  display:flex;align-items:center;justify-content:center;font-size:18px;
  box-shadow:0 6px 20px rgba(0,0,0,.18);
  cursor:pointer;
  opacity:0;visibility:hidden;transform:translateY(12px);
  transition:opacity .25s ease,transform .25s ease,visibility .25s,background-color .2s;
}
.bt-to-top.is-visible{opacity:1;visibility:visible;transform:translateY(0)}
.bt-to-top:hover{background:var(--gold-d);border-color:var(--gold-d);color:#fff}
.bt-to-top:focus-visible{outline:2.5px solid var(--gold-d);outline-offset:2px}
@media(max-width:640px){.bt-to-top{right:14px;bottom:16px;width:40px;height:40px;font-size:16px}}

/* ═══════════════════════════════════════════════════════════════
   BLOG PAGE HERO
   The dark opening band on the posts page (home.php). Same
   convention as the .ab-* / .ct-* / .sh-* blocks: every selector is
   prefixed .bl-hero and appears in no other template, so it loads
   site-wide but only ever paints on the blog.

   It is NOT a fourth dark-hero design. The surface, the gradient and
   the closing curve are the shared .bt-darkband component the About,
   Contact and Shop heroes already use; the type is the shared display
   tier (.typography-display --invert on the markup); the badge is the
   same pill as .ab-hero__badge / .sh-hero__badge, with the theme's
   bi-book icon in place of the live dot; the accent is --gold. Only
   the search row is declared here, because no other hero has one.

   Rhythm is --sec-y plus the band's own --wave-h, exactly as
   .ab-hero__inner and .sh-hero__inner do, so the copy never sits
   under the curve and the hero is sized by its content.

   The closing wave is filled --ivory, not #fff: the blog's article
   grid sits straight on the body ground rather than in a white band,
   and the wave always takes the colour of whatever it curves into. */
/* Accent washes — same idiom and the same two tokens as
   .ab-hero::before / ::after, with the shop hero's slow drift. */
.bl-hero::before,.bl-hero::after{
  content:'';position:absolute;border-radius:50%;pointer-events:none;z-index:0;
  will-change:transform;
}
.bl-hero::before{
  width:520px;height:520px;left:50%;top:-330px;margin-left:-260px;
  background:radial-gradient(circle,rgba(201,162,74,.20),transparent 70%);
  animation:shHeroDrift 12s ease-in-out infinite;
}
.bl-hero::after{
  width:380px;height:380px;right:-140px;bottom:-210px;
  background:radial-gradient(circle,rgba(255,255,255,.05),transparent 70%);
  animation:shHeroDrift 12s ease-in-out infinite reverse;
}

.bl-hero__inner{
  position:relative;z-index:1;text-align:center;
  padding-top:var(--hero-y);
  padding-bottom:calc(var(--hero-y) + var(--wave-h));
}

/* Same staggered entrance the shop hero uses — the theme's own fadeUp
   keyframes and easing, local delays only. `both` holds the from-state
   so there is no flash of finished content on load. The global
   prefers-reduced-motion rule near the top of this file collapses
   these to a single instant frame. */
.bl-hero__badge,
.bl-hero__title,
.bl-hero__text,
.bl-hero__search{
  animation:fadeUp .6s cubic-bezier(.22,.61,.36,1) both;
}
.bl-hero__badge {animation-delay:0s}
.bl-hero__title {animation-delay:.08s}
.bl-hero__text  {animation-delay:.16s}
.bl-hero__search{animation-delay:.24s}

/* ─── Badge ─── */
.bl-hero__badge{
  display:inline-flex;align-items:center;gap:8px;
  background:rgba(201,162,74,.18);border:1px solid rgba(232,217,160,.34);
  color:var(--gold-l);border-radius:9999px;padding:5px 15px;
  font-size:var(--fs-label);font-weight:var(--fw-label);letter-spacing:1.1px;
  text-transform:uppercase;line-height:1.4;
}

/* ─── Heading + standfirst ─── */
/* Measures and gaps match .ab-hero__title / .sh-hero__title exactly. */
.bl-hero__title{margin:18px auto 0;max-width:17ch;text-wrap:balance}
.bl-hero__text{
  margin:16px auto 0;max-width:600px;
  font-size:var(--fs-body-lg);line-height:1.8;color:rgba(255,255,255,.7);
}

/* ─── Search ─── */
/* The header's .bt-drawer__search-field pattern — icon, then a
   borderless input that fills the row — restated for the dark ground:
   a glass fill over the band's gradient instead of a white field, with
   the theme's rounded-full pill geometry. No new colour: the border and
   the fill are white at low alpha, the ink is white, the placeholder and
   the icon are the same rgba(255,255,255,.7) / .55 muted steps the band
   already uses for secondary copy. */
.bl-hero__search{margin:28px auto 0;max-width:520px}
.bl-hero__field{
  display:flex;align-items:center;gap:10px;
  padding:11px 20px;border-radius:9999px;
  background:rgba(255,255,255,.08);
  border:1px solid rgba(255,255,255,.18);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  transition:border-color .2s ease,background-color .2s ease;
}
.bl-hero__field:focus-within{
  background:rgba(255,255,255,.12);
  border-color:rgba(232,217,160,.5);
}
.bl-hero__field i{color:rgba(255,255,255,.55);font-size:var(--fs-ui);flex-shrink:0}
.bl-hero__field input{
  flex:1;min-width:0;border:none;outline:none;background:none;
  font-family:inherit;font-size:var(--fs-ui);color:#fff;
}
.bl-hero__field input::placeholder{color:rgba(255,255,255,.55)}
/* The submit is the icon-free affordance for keyboards and screen
   readers; visually the field itself is the control, so the button
   only needs to be reachable, not decorated. */
.bl-hero__submit{
  flex-shrink:0;border:none;background:none;padding:0;cursor:pointer;
  color:var(--gold-l);font-size:var(--fs-label);font-weight:var(--fw-semibold);
  letter-spacing:.4px;text-transform:uppercase;
}
.bl-hero__submit:hover{color:#fff}
.bl-hero__submit:focus-visible{outline:2px solid rgba(232,217,160,.6);outline-offset:3px;border-radius:4px}

/* The wave takes the colour of the band it curves into — the white
   .bl-cats band directly below the hero — which is the same #fff the About
   and Shop waves use, for the same reason. */
.bl-hero .wave-b path{fill:#fff}

/* The content band under the hero — the category row AND the article grid
   together, so the blog reads as one white section rather than a strip on
   the cream ground. A background and nothing else, exactly like
   .sh-products on the shop: the width, the padding and the type inside it
   stay the wrapper's and the shared classes' job. */

@media (max-width:600px){
  .bl-hero__title{max-width:20ch}
  .bl-hero__field{padding:10px 16px}
}

/* ═══════════════════════════════════════════════════════════════
   PRIVACY POLICY — QUICK OVERVIEW
   The summary bar under the hero on page-policy.php: one ivory panel
   on a white band, four points across with a hairline between each.
   Every rule is scoped under .privacy-overview, so nothing here can
   reach the .bt-trust strip or any other band — and it must not read
   as that strip, which is four separate white cards on ivory with
   gold-tinted squares. This is the inverse: one ivory panel on white,
   dark charcoal circles, hairline dividers.

   Colours are all tokens: --ivory panel, --forest circles, --gold
   glyphs, --border hairlines, --ink-heading / --ink-muted text.
   ═══════════════════════════════════════════════════════════════ */
/* Band rhythm is the shared .bt-section on the markup, like every other
   band on the site, so only the ground is declared here. */
.privacy-overview__panel{
  padding:24px;border-radius:var(--r);
  background:var(--ivory);border:1px solid var(--border);
}

@media (min-width:1024px){
  .privacy-overview__panel{padding:28px 32px}
}

/* minmax(0,1fr) rather than 1fr on every step: a 1fr track takes the
   width of its widest item, so one long unbroken word would push the
   row past the panel and put a phone into horizontal scroll. */
/* Two layouts only, not three: a 2x2 grid on phones and one row of four
   everywhere else. The single-column stack the bar used to start on is gone —
   four points down a phone screen pushed the clauses a long way below the
   fold for no gain, and the labels are short enough to sit two across. */
.privacy-overview .privacy-badges{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px 16px;
}

/* One row from the tablet breakpoint up, so the bar reads as a single strip on
   every screen a phone is not. */
@media (min-width:768px){
  .privacy-overview .privacy-badges{
    grid-template-columns:repeat(4,minmax(0,1fr));gap:0;
  }
}

.privacy-overview .privacy-badge{display:flex;align-items:center;gap:12px;min-width:0}

@media (min-width:768px){
  /* Only a point with one before it draws a divider, so the row opens
     and closes flush with the panel padding instead of on a stray rule.
     Dividers exist only in this block, which keeps them off the 2x2
     layout without a rule to undo them.

     A row of four at 768px leaves about 170px per point, so the gutter, the
     icon and the icon gap all come down to buy the label its line — at the
     desktop metrics the second line broke to "&" on its own. All three go
     back up at 1024px, where the room is there. */
  .privacy-overview .privacy-badge{padding:2px 10px;gap:10px}
  .privacy-overview .privacy-badge:first-child{padding-left:0}
  .privacy-overview .privacy-badge:last-child{padding-right:0}
  .privacy-overview .privacy-badge+.privacy-badge{border-left:1px solid var(--border)}
  .privacy-overview .privacy-badge__ico{width:38px;height:38px}
}

@media (min-width:1024px){
  .privacy-overview .privacy-badge{padding:2px 24px;gap:12px}
  .privacy-overview .privacy-badge:first-child{padding-left:0}
  .privacy-overview .privacy-badge:last-child{padding-right:0}
  .privacy-overview .privacy-badge__ico{width:44px;height:44px}
}

/* Dark charcoal, gold glyph: what ties this bar to the .bt-darkband
   hero above, and what most separates it from the gold-tinted tiles in
   the trust strip below. */
.privacy-overview .privacy-badge__ico{
  flex:0 0 auto;width:44px;height:44px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--forest);color:var(--gold);
}

.privacy-overview .privacy-badge__body{min-width:0}
.privacy-overview .privacy-badge__title{
  margin:0 0 2px;
  font-size:var(--fs-body);font-weight:var(--fw-semibold);
  line-height:var(--lh-heading-xs);color:var(--ink-heading);
}
.privacy-overview .privacy-badge__desc{
  margin:0;
  font-size:var(--fs-small);line-height:1.5;color:var(--ink-muted);
}

@media (max-width:420px){
  .privacy-overview__panel{padding:20px}
  .privacy-overview .privacy-badge__ico{width:40px;height:40px}
}

/* ═══════════════════════════════════════════════════════════════
   PRIVACY POLICY — POLICY CONTENT
   The ten clauses under the Quick Overview bar on page-policy.php.
   Plain prose on a cream band — no cards, no boxes. Band rhythm is
   the shared .bt-section on the markup; every rule is scoped under
   .policy-content, and the headings carry .legal-title so they size
   with the other legal pages.
   ═══════════════════════════════════════════════════════════════ */

/* Reading measure, centred in the container. The text inside stays
   left-aligned — centring a bulleted clause list would cost far more
   in legibility than it gains. */
.policy-content__inner{max-width:820px;margin-left:auto;margin-right:auto}

.policy-content .policy-block+.policy-block{margin-top:44px}

/* Targets .legal-title, not a tag: the clause headings are <h3> while the
   band's own heading above them is an <h2>, and only the clauses carry a
   numeral. flex, so that numeral sits beside the heading rather than in its
   text flow — a wrapped heading then aligns as one block instead of running
   back under the number. */
.policy-content .legal-title{
  display:flex;align-items:center;gap:14px;
  margin:0;
}
.policy-content .policy-num{
  flex:0 0 auto;
  font-size:14px;font-weight:700;letter-spacing:1px;line-height:1;
  color:var(--gold);font-variant-numeric:tabular-nums;
}

.policy-content .policy-intro{
  margin:12px 0 0;
  font-size:16px;line-height:1.7;color:var(--ink-body);
}

/* The standfirst above clause 01, used by page-return-cancellation-policy.php.
   Same measure and colour as a clause paragraph, a step larger, and separated
   from the first clause by the same 44px the clauses keep between themselves —
   so it reads as the band's opening line rather than as part of clause 01. */
.policy-content .policy-lead{
  margin:0 0 44px;
  font-size:17px;line-height:1.7;color:var(--ink-body);
}

/* A sub-heading INSIDE a clause ("How to Cancel Your Order", "Required
   Proof"), also page-return-cancellation-policy.php's. It has to read as
   subordinate to the gold-numbered .legal-title above it, so it takes no
   numeral and sits a clear step down in size — and its top margin is wider
   than its bottom, which is what groups it with the paragraph or list it
   introduces rather than with the text it follows. */
.policy-content .policy-sub{
  margin:22px 0 0;
  font-size:var(--fs-h4);font-weight:var(--fw-semibold);
  line-height:var(--lh-heading-sm);color:var(--ink-heading);
}
/* The part that follows a sub-heading closes up against it: .policy-intro and
   .policy-list both carry their own top margin, which would otherwise stack on
   top of the 22px above and break the pairing. */
.policy-content .policy-sub + .policy-intro,
.policy-content .policy-sub + .policy-list{margin-top:8px}

/* Links in clause copy — the two support mailtos. Gold, underlined on hover
   only, the same treatment body links take elsewhere on the site. */
.policy-content .policy-intro a,
.policy-content .policy-list a{
  color:var(--gold-d);text-decoration:none;overflow-wrap:anywhere;
}
.policy-content .policy-intro a:hover,
.policy-content .policy-list a:hover{text-decoration:underline}

/* Default markers are dropped on both lists and redrawn as ::before, so
   the bullet and the number are both gold and both sit in the same
   12px indent. */
.policy-content .policy-list{
  list-style:none;margin:16px 0 0;padding:0;
}
.policy-content .policy-list li{
  position:relative;padding-left:12px;
  font-size:16px;line-height:1.7;color:var(--ink-body);
}
.policy-content .policy-list li+li{margin-top:6px}

/* 6px gold dot, centred on the first line whatever the line-height. */
.policy-content .policy-list--ul li::before{
  content:'';position:absolute;left:0;top:calc(.85em - 3px);
  width:6px;height:6px;border-radius:50%;background:var(--gold);
}

/* The ordered list keeps its own counter so the numerals can be gold. */
.policy-content .policy-list--ol{counter-reset:policy}
.policy-content .policy-list--ol li{counter-increment:policy;padding-left:26px}
.policy-content .policy-list--ol li::before{
  content:counter(policy) '.';position:absolute;left:0;top:0;
  font-weight:var(--fw-semibold);color:var(--gold);
  font-variant-numeric:tabular-nums;
}

/* ═══════════════════════════════════════════════════════════════
   PRIVACY POLICY — IMPORTANT NOTE
   The legal disclaimer between the clauses and the FAQ, on page-policy.php.

   Same shape as the .bt-helpcta banner below it — one rounded box on a plain
   band, icon left, copy right — but deliberately the LIGHT version of it: a
   gold wash with a gold hairline instead of the dark --forest fill. A notice
   is something to read in passing, not an action to take, so it must not
   compete with the dark CTA that closes the page.

   Ground is white (declared with the other band grounds above). Colours are
   the theme's existing gold-tint idiom — the same rgba pair .badge-gold and
   .bt-trust__item:hover already use — so nothing new is introduced.
   ═══════════════════════════════════════════════════════════════ */
/* Capped at the 860px the FAQ measure uses directly below it, and centred, so
   the notice sits in the same column as the rest of the page. Left to the full
   max-w-7xl container it ran one ~1800px line of text — far past a readable
   measure, and visibly wider than every other block on the page.

   align-items:center, not flex-start: the copy is one or two lines, so the
   disc belongs on the optical centre of the text rather than pinned to its
   first line, which left the box looking top-heavy. */
.policy-note__box{
  display:flex;align-items:center;gap:18px;
  max-width:860px;margin-left:auto;margin-right:auto;
  padding:22px 26px;border-radius:var(--r);
  background:rgba(201,162,74,.10);
  border:1px solid rgba(201,162,74,.3);
}

/* White disc on the tinted ground, so the glyph reads at a glance without a
   second, deeper tint. */
.policy-note__ico{
  flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;
  width:44px;height:44px;border-radius:50%;
  background:#fff;color:var(--gold-d);
}

/* A flex row of label | copy, so the copy wraps inside its own column and
   every line after the first starts where the first line's text starts
   instead of running back under "Important:".

   align-items:baseline, not center: the label is a size up from the copy, so
   the two line up on the copy's first baseline rather than on their box
   centres. */
.policy-note__text{
  display:flex;align-items:baseline;gap:8px;
  min-width:0;margin:0;
  font-size:var(--fs-small);line-height:1.7;color:var(--ink-body);
}

/* The label is its own tier, a step above the copy it introduces — inheriting
   the copy's size and sitting hard against it made the two read as one
   run-on sentence. */
.policy-note__label{
  flex:0 0 auto;
  font-size:var(--fs-body);font-weight:var(--fw-semibold);
  color:var(--ink-heading);
}

/* min-width:0 so a long word cannot push this column past the box. */
.policy-note__copy{min-width:0}

@media (max-width:600px){
  .policy-note__box{padding:18px;gap:14px}
  .policy-note__ico{width:38px;height:38px}
  /* Two columns leave the copy about 120px wide at 320px, so on a phone the
     label goes back into the text flow. The hanging indent is a desktop
     refinement, not something worth a 15-character line for. */
  .policy-note__text{display:block}
  .policy-note__label{margin-right:8px}
}

/* ═══════════════════════════════════════════════════════════════
   RETURN & CANCELLATION — POLICY STRIP
   The six-tile strip under the hero on page-return-cancellation-policy.php:
   icon over title over one line of copy, six across on desktop.

   It exists as its own block because of that six. Every card grid already
   on the site tops out at four tracks (.bt-trust__grid) or three
   (.ct-info-grid), so six items in either would have broken 4+2 or 3+3 and
   stopped reading as a strip. Nothing else here is new: the tile surface,
   radius, hairline and gold icon chip are the same tokens and the same
   treatment as .bt-trust__item — centred and stacked rather than a row.

   Every rule is scoped under .rc-strip, so nothing here can reach the trust
   strip, the contact cards or any other band. Colours are all tokens:
   white tiles, --border hairlines, --gold-d glyphs on the gold tint the
   icon chips use site-wide, --forest titles, --ink-muted copy.
   ═══════════════════════════════════════════════════════════════ */
/* Band rhythm is the shared .bt-section on the markup, like every other band
   on the site, and the white ground is declared up with the other band
   grounds — so neither is repeated here.

   White tiles on a white band, which is why the hairline and the radius are
   doing the work of separating them: the same arrangement .ct-info-card uses
   on the contact page. */
/* minmax(0,1fr) rather than 1fr on every step: a 1fr track takes the width of
   its widest item, so one long unbroken word would push the row past the
   container and put a phone into horizontal scroll. */
.rc-strip__grid{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;
}
/* 2 → 3 → 6. The 3-track step is what keeps the tablet range even — six items
   across two rows — instead of the 4+2 a four-track step would leave. */
@media (min-width:640px){
  .rc-strip__grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
}
@media (min-width:1024px){
  .rc-strip__grid{grid-template-columns:repeat(6,minmax(0,1fr));gap:16px}
}

/* FOUR-UP VARIANT  (.rc-strip__grid--4)
   /drug-policy/ carries four tiles, not six, so the two steps that assume six
   are the only ones overridden: the 3-track tablet step, which would leave a
   3+1 row, and the 6-track desktop step. Everything else about the tile — the
   surface, the hairline, the radius, the centred stack, the gold icon chip and
   the gold hover — is .rc-strip__item untouched, so the four-up strip and the
   six-up strip stay one component.

   2 → 2 → 4: two across from the smallest width through tablet (an even 2+2),
   then all four across at 1024px. */
@media (min-width:640px){
  .rc-strip__grid--4{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (min-width:1024px){
  .rc-strip__grid--4{grid-template-columns:repeat(4,minmax(0,1fr))}
}
/* The padding trim at 1024–1279px below exists because six tracks leave a tile
   ~170px wide. Four tracks leave it ~270px, so the trim is reverted here. */
@media (min-width:1024px) and (max-width:1279px){
  .rc-strip__grid--4 .rc-strip__item{padding:24px 16px}
}

.rc-strip__item{
  min-width:0;text-align:center;
  display:flex;flex-direction:column;align-items:center;gap:10px;
  padding:24px 16px;
  background:#fff;border:1px solid var(--border);border-radius:var(--r);
  transition:border-color .2s ease,box-shadow .2s ease;
}
/* Same gold hover as .bt-trust__item and .ct-info-card, so a tile answers to
   the pointer the way every other card on the site does. */
.rc-strip__item:hover{border-color:rgba(201,162,74,.4);box-shadow:var(--shadow)}

/* Six tracks at 1024px leave roughly 170px a tile, so the horizontal padding
   comes down to buy the copy its lines; it goes back up at 1280px. */
@media (min-width:1024px) and (max-width:1279px){
  .rc-strip__item{padding:22px 12px}
}

.rc-strip__ico{
  flex:0 0 auto;width:44px;height:44px;border-radius:12px;
  display:flex;align-items:center;justify-content:center;
  background:rgba(201,162,74,.15);color:var(--gold-d);font-size:19px;
}

.rc-strip__title{
  margin:0;
  font-size:var(--fs-h6);font-weight:var(--fw-semibold);
  line-height:var(--lh-heading-xs);color:var(--forest);
}
.rc-strip__copy{
  margin:0;
  font-size:var(--fs-xs);line-height:1.6;color:var(--ink-muted);
}

@media (max-width:420px){
  .rc-strip__item{padding:20px 12px;gap:8px}
  .rc-strip__ico{width:40px;height:40px;font-size:17px}
}

/* ═══════════════════════════════════════════════════════════════
   SAFE SHOPPING — ASSURANCE CARDS  (.ss-assure)
   ───────────────────────────────────────────────────────────────
   The four-up assurance row on /safe-shopping/. It is the trust band's card
   (.bt-trust__grid / __item / __ico / __text / __title / __copy) reused as
   it stands — icon chip left, title and copy stacked beside it, 1 → 2 → 4
   tracks — so none of the layout, the white surface, the hairline, the
   radius or the gold hover is restated here.

   Two things are this band's own, and they are the only rules below:
   the white ground (declared up with the other band grounds, not here), and
   a ROUND icon chip instead of the trust band's squircle. Both are scoped
   under .ss-assure, so the trust strip footer.php renders site-wide keeps
   its own 10px chip untouched.
   ═══════════════════════════════════════════════════════════════ */
/* 44px and fully round, matching the circular chips in the reference. Only
   the three properties that differ are declared — the tint, the glyph colour,
   the centring and the flex basis all stay .bt-trust__ico's. */
.ss-assure .bt-trust__ico{width:44px;height:44px;border-radius:999px}

/* The card's padding goes up a little because this band stands alone rather
   than closing a page, and the copy here runs to three lines at 1024px. */
.ss-assure .bt-trust__item{padding:18px}

@media (max-width:420px){
  .ss-assure .bt-trust__ico{width:40px;height:40px}
}

/* ═══════════════════════════════════════════════════════════════
   OUT-OF-STOCK POPUP
   Raised by the add-to-cart section of assets/js/script.js when a customer
   submits an add-to-cart form for a product or variation that is out of
   stock. Scoped entirely under .bt-oos- so nothing here can reach the cart
   drawer, the checkout drawer or the quiz modal.
   Every colour, radius, shadow and type size below is an existing theme
   token from this file - no new palette is introduced. The surfaces match
   .card, the button matches .btn-outline and the overlay matches the quiz
   modal. The product cards are not styled here at all - they are the Shop
   archive's own .product-card markup, rendered server-side.
   ═══════════════════════════════════════════════════════════════ */

.bt-oos,
.bt-oos *,
.bt-oos *::before,
.bt-oos *::after {
  box-sizing: border-box;
}

.bt-oos {
  position: fixed;
  inset: 0;
  z-index: 2200;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(18, 18, 18, .55);
  backdrop-filter: blur(6px);
  font-family: var(--font-base);
}

.bt-oos.is-open {
  display: flex;
}

.bt-oos__dialog {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 560px;
  max-height: calc(100vh - 32px);
  max-height: calc(100dvh - 32px);
  overflow: hidden;
  background: #fff;
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
  animation: fadeUp .4s cubic-bezier(.22, .61, .36, 1) both;
}

.bt-oos__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-shrink: 0;
  padding: 20px 24px;
  border-bottom: 1px solid var(--border);
}

.bt-oos__title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-size: var(--fs-h5);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-heading-xs);
  color: var(--ink-heading);
}

.bt-oos__title i {
  font-size: 18px;
  line-height: 1;
  color: var(--gold);
}

.bt-oos__close {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  padding: 0;
  font-size: 14px;
  color: var(--text2);
  cursor: pointer;
  background: rgba(0, 0, 0, .05);
  border: none;
  border-radius: 50%;
  transition: background .2s ease-in-out, color .2s ease-in-out;
}

.bt-oos__close:hover {
  background: var(--sage);
  color: #fff;
}

/* Same focus ring the theme gives .field, rather than a default outline box. */
.bt-oos__close:focus-visible,
.bt-oos__btn:focus-visible,
.bt-oos__grid .product-card:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(0, 0, 0, .12);
}

.bt-oos__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 22px 24px;
}

.bt-oos__lead {
  margin: 0 0 6px;
  font-size: var(--fs-ui);
  font-weight: var(--fw-semibold);
  line-height: 1.45;
  color: var(--text1);
}

.bt-oos__sub {
  margin: 0 0 20px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text3);
}

/* The cards inside are the Shop archive's own .product-card markup, rendered
   server-side through woocommerce/content-product.php, so their image box,
   category, title, price and button all come from this file untouched. Only
   the column count is pinned here: .shop-grid goes to 3 and then 4 columns on
   wider screens, which the dialog does not have room for. */
.bt-oos__grid .shop-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.bt-oos__grid--1 .shop-grid {
  grid-template-columns: minmax(0, 260px);
  justify-content: center;
}

/* Cards sit on white here rather than the page's ivory, so the shadow alone is
   not enough separation. */
.bt-oos__grid .product-card {
  border: 1px solid var(--border);
}

.bt-oos__empty {
  margin: 0;
  padding: 20px;
  font-size: 13px;
  line-height: 1.6;
  text-align: center;
  color: var(--text2);
  background: var(--ivory-d);
  border-radius: var(--r);
}

.bt-oos__footer {
  flex-shrink: 0;
  padding: 18px 24px;
  text-align: center;
  border-top: 1px solid var(--border);
}

.bt-oos__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-width: 220px;
  padding: 13px 26px;
  font-size: var(--fs-ui);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  line-height: 1;
  white-space: nowrap;
  color: var(--text1);
  background: hsla(0, 0%, 100%, .4);
  border: 1px solid rgba(0, 0, 0, .19);
  border-radius: 9999px;
  transition: all .2s ease-in-out;
}

.bt-oos__btn:hover,
.bt-oos__btn:focus {
  color: #fff;
  background: var(--sage);
  border-color: var(--sage);
  transform: translateY(-1px);
}

@media (max-width: 600px) {
  .bt-oos {
    padding: 10px;
  }

  .bt-oos__dialog {
    max-height: calc(100vh - 20px);
    max-height: calc(100dvh - 20px);
    border-radius: var(--r);
  }

  .bt-oos__header,
  .bt-oos__body,
  .bt-oos__footer {
    padding-left: 16px;
    padding-right: 16px;
  }

  /* Two across, exactly as the Shop archive looks on a phone. */
  .bt-oos__grid .shop-grid {
    gap: 10px;
  }

  .bt-oos__btn {
    display: flex;
    width: 100%;
    min-width: 0;
    min-height: 46px;
  }
}

/* ═══════════════════════════════════════════════════════════════
   PDP GALLERY + MAGNIFIER
   Single-product image stage, thumbnail strip and the circular
   magnifier lens. Surface comes from .card and the --gold /
   --border tokens; no new colours.
   ═══════════════════════════════════════════════════════════════ */

.pdp-gallery {
  margin-bottom: 14px;
}

.pdp-gallery__empty {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: var(--text3);
  text-align: center;
}

.pdp-gallery__empty .bi {
  font-size: 72px;
  color: rgba(0, 0, 0, .12);
}

/* Round "Rx / Required" badge over the product image, shown only when the
   product is flagged prescription-only. Single-product page only - this is that
   page's one Rx marker, since the .badge-gold pill that used to sit next to the
   category links was removed in favour of it.

   Same cream-and-gold disc as .product-card__rx on the product cards, just large
   enough to carry the wording: the "Rx" sign on top, a hairline rule, then
   "REQUIRED" under it. The cards keep the small glyph-only disc - their image
   box has no room for the text - so this rule is deliberately scoped here.

   Everything scales off --rx-size, so the three breakpoints below only restate
   that one value and the glyph, rule, label and padding all follow. The
   breakpoints are the ones the rest of the PDP gallery already uses (1024px for
   tablet, 768px for phone) rather than new ones.

   The gold tint sits on an opaque #fff base rather than being used on its own:
   the disc is on top of the product photo, and a translucent background would
   let a dark image bleed through and kill the text contrast.

   pointer-events:none keeps it out of the magnifier's way. */
.pdp-gallery__rx {
  --rx-size: 62px;
  position: absolute;
  top: 14px;
  left: 14px;
  z-index: 5;
  box-sizing: border-box;
  width: var(--rx-size);
  height: var(--rx-size);
  border-radius: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: calc(var(--rx-size) * .05);
  padding: calc(var(--rx-size) * .1);
  background: linear-gradient(rgba(201, 162, 74, .16), rgba(201, 162, 74, .16)), #fff;
  border: 1px solid rgba(201, 162, 74, .34);
  color: var(--gold-d);
  text-align: center;
  pointer-events: none;
}

/* Classic prescription sign: serif cap R with a smaller x dropped towards the
   descender, which is how the Rx symbol is drawn. */
.pdp-gallery__rx-sym {
  font-family: Georgia, 'Times New Roman', serif;
  font-weight: 700;
  font-size: calc(var(--rx-size) * .32);
  line-height: 1;
}

.pdp-gallery__rx-x {
  font-size: .7em;
  position: relative;
  top: .14em;
}

.pdp-gallery__rx-rule {
  display: block;
  width: 56%;
  height: 1px;
  background: rgba(201, 162, 74, .42);
}

/* The label is small by design, so it gets a hard floor: below ~6px the letters
   stop resolving on a standard display. text-indent cancels the trailing
   letter-spacing on the last character, which would otherwise push the word
   visibly off-centre inside the circle. */
.pdp-gallery__rx-label {
  font-size: max(6px, calc(var(--rx-size) * .105));
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: .13em;
  text-indent: .13em;
  line-height: 1;
}

/* Thumbnail strip — centred under the stage, and horizontally scrollable on
   the rare product with more images than fit. "safe center" keeps the first
   thumbnail reachable when it does overflow. */
.pdp-thumbs {
  display: flex;
  gap: 10px;
  justify-content: center;
  justify-content: safe center;
  margin-top: 12px;
  min-width: 0;
  overflow-x: auto;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  padding: 2px;
}

.pdp-thumbs::-webkit-scrollbar {
  display: none;
}

.pdp-thumb {
  flex: 0 0 84px;
  width: 84px;
  aspect-ratio: 1;
  padding: 6px;
  border: 1.5px solid var(--border);
  border-radius: 14px;
  background: #fff;
  cursor: pointer;
  overflow: hidden;
  transition: border-color .2s ease, box-shadow .2s ease;
}

.pdp-thumb img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.pdp-thumb:hover {
  border-color: rgba(0, 0, 0, .26);
}

.pdp-thumb.is-active {
  border-color: var(--gold);
  box-shadow: 0 0 0 1px var(--gold);
}

@media (max-width: 1024px) {
  .pdp-thumb {
    flex-basis: 74px;
    width: 74px;
  }

  .pdp-gallery__rx {
    --rx-size: 56px;
  }
}

@media (max-width: 768px) {
  .pdp-thumb {
    flex-basis: 64px;
    width: 64px;
    border-radius: 12px;
    padding: 5px;
  }

  .pdp-gallery__rx {
    --rx-size: 50px;
    top: 10px;
    left: 10px;
  }
}

.pdp-image-zoom {
  position: relative;
}

.pdp-image-zoom.pdp-mag-active .pdp-zoom-img {
  cursor: none;
}

/* box-sizing + background-origin/clip on the BORDER box, all three, so the
   width the JS sets is the lens's full outer size and the magnified picture
   is laid out over that same box. Left on the defaults the 6px ring would
   sit outside the measured size: the lens would overhang the image's edge by
   6px on each side, and its background would be centred on a box 12px
   smaller than the one the maths in script.js clamps against. */
.pdp-mag-lens {
  position: absolute;
  left: 0;
  top: 0;
  box-sizing: border-box;
  width: 260px;
  height: 260px;
  border-radius: 50%;
  border: 6px solid #fff;
  box-shadow: 0 10px 28px rgba(0, 0, 0, .2), 0 0 0 1px rgba(0, 0, 0, .12);
  background-repeat: no-repeat;
  background-origin: border-box;
  background-clip: border-box;
  background-color: #fff;
  pointer-events: none;
  opacity: 0;
  z-index: 30;
  transition: opacity .15s ease;
  will-change: transform, opacity;
}

.pdp-mag-lens.is-active {
  opacity: 1;
}

@media (max-width: 991px) {
  .pdp-mag-lens {
    width: 180px;
    height: 180px;
    border-width: 5px;
  }
}

@media (hover: none), (pointer: coarse) {
  .pdp-mag-lens {
    display: none !important;
  }
}

/* ═══ AUTHOR ARCHIVE (.au-*) ═══
   Scoped to author.php only. Reuses .card for the surface, .btn-outline for
   the website link, .badge-sage for the optional designation and the site's
   existing --sage/--gold/--forest tokens throughout — no new colours. */
.au-hero{
  display:flex;align-items:center;gap:40px;
  padding:40px;
}
.au-hero__avatar{flex-shrink:0}
.au-avatar-img{
  width:160px;height:160px;border-radius:50%;
  object-fit:cover;display:block;
  box-shadow:0 0 0 6px var(--ivory-d);
}
.au-name{
  font-size:var(--fs-h1);font-weight:var(--fw-heading);
  line-height:var(--lh-heading);letter-spacing:var(--ls-heading);
  color:var(--forest);margin-bottom:10px;
}
.au-designation{margin-bottom:14px}
.au-bio{
  color:var(--ink-body);font-size:var(--fs-body);line-height:var(--lh-body);
  max-width:640px;
}
.au-bio p{margin-bottom:1em}
.au-bio p:last-child{margin-bottom:0}
.au-social{display:flex;gap:10px;flex-wrap:wrap;margin-top:16px}
.au-readmore{
  margin-top:auto;font-weight:var(--fw-heading);color:var(--sage);
  display:inline-flex;align-items:center;gap:5px;
}
@media (max-width:767px){
  .au-hero{flex-direction:column;text-align:center;padding:28px 20px;gap:20px}
  .au-avatar-img{width:120px;height:120px}
  .au-bio{max-width:none}
  .au-social{justify-content:center}
}

/* ── Static author header (.au-static-*) — BT_STATIC_AUTHOR_SLUG only.
   Deliberately NOT a .card: flat, no background/border/shadow, sits
   directly on the page as a simple intro block. ──────────────────── */
.au-static-hero{display:flex;align-items:center;gap:48px}
.au-static-hero__photo{
  flex-shrink:0;width:280px;height:280px;border-radius:50%;
  object-fit:cover;display:block;border:6px solid #F1EADF;
}
.au-static-hero__info{display:flex;flex-direction:column;justify-content:center}
.au-static-name{
  font-family:var(--font-base);font-size:clamp(32px,3.4vw,48px);
  font-weight:var(--fw-heading);line-height:var(--lh-heading);
  letter-spacing:var(--ls-heading);color:#111;margin:0 0 16px;
}
.au-static-bio{font-size:16.5px;line-height:1.7;color:#444;max-width:820px;margin:0}
.au-static-bio a{color:var(--gold);text-decoration:underline}
@media (max-width:767px){
  .au-static-hero{flex-direction:column;text-align:center;gap:20px;padding:0 16px 8px}
  .au-static-hero__photo{width:180px;height:180px}
  .au-static-hero__info{align-items:center}
  .au-static-bio{max-width:none}
}

/* ── Single product page: full-width alternating cream/white bands, one
   per section (hero, steps, description, reviews, you-may-also-like,
   related products). The band paints edge-to-edge; each section's own
   inner div keeps the existing max-w-7xl/px-4 content width. ────────── */
.bt-pdp-section{width:100%}
.bt-pdp-section--cream{background:var(--ivory)}
.bt-pdp-section--white{background:#FFFFFF}

/* ── "Easy Steps to Order" (single-product.php, between the hero and the
   Description/Reviews block). A self-contained beige card — every rule is
   scoped under .bt-steps so the surrounding theme (ol/li resets, borders,
   backgrounds) can't leak in. ─────────────────────────────────────────── */
.bt-steps{
  --g:#C49A5A;--gd:#A87C3C;--ring:#ECDCC3;--bg:#F7F1E7;--ln:#E3D6C1;--ink:#151515;--mut:#5D6470;
  font-family:var(--font-base);
  background:var(--bg) !important;border:1px solid #EADFCB;border-radius:16px;box-shadow:none;padding:36px;
  display:grid;grid-template-columns:280px 1fr;gap:32px;align-items:center;box-sizing:border-box;
}
.bt-steps *{box-sizing:border-box}
.bt-steps__intro{border-right:1px solid var(--ln);padding-right:28px}
.bt-steps__title{font-size:26px;font-weight:600;line-height:1.2;margin:10px 0;color:var(--ink)}
.bt-steps__text{font-size:14px;line-height:1.55;color:var(--mut);margin:0}
.bt-steps__list{list-style:none;margin:0;padding:0;
  display:flex;justify-content:space-between;align-items:flex-start}
.bt-steps__item{flex:1;text-align:center;position:relative;padding:0 6px;margin:0;
  list-style:none;background:none;border:0}
.bt-steps__item::before{content:none}
.bt-steps__item:not(:last-child)::after{content:"";position:absolute;top:24px;
  left:calc(50% + 34px);right:calc(-50% + 34px);border-top:1.5px dashed #CDB48B}
.bt-steps__icon{width:48px;height:48px;border-radius:50%;background:var(--g);margin:0 auto;
  display:grid;place-items:center;box-shadow:0 0 0 6px var(--ring);position:relative;z-index:1}
.bt-steps__icon svg{width:21px;height:21px;stroke:#fff;fill:none;stroke-width:1.8}
.bt-steps__num{color:var(--gd);font-size:12px;font-weight:600;letter-spacing:.06em;margin:14px 0 4px}
.bt-steps__name{font-size:15px;font-weight:600;color:var(--ink);margin:0}
.bt-steps__desc{font-size:12.5px;line-height:1.45;color:var(--mut);margin:6px 0 0}

/* Tablet (≤1024px): stacked header, 3-then-2 centered grid, no connectors. */
@media (max-width:1024px){
  .bt-steps{grid-template-columns:1fr;padding:32px 28px;gap:28px}
  .bt-steps__intro{border-right:0;border-bottom:1px solid var(--ln);padding:0 0 24px;text-align:center}
  .bt-steps__text{max-width:460px;margin:0 auto}
  .bt-steps__list{flex-wrap:wrap;justify-content:center;row-gap:30px}
  .bt-steps__item{flex:0 0 33.333%}
  .bt-steps__item:not(:last-child)::after{display:none}
}

/* Mobile (≤600px): left-aligned header, vertical dashed timeline centered
   under each icon circle. */
@media (max-width:600px){
  .bt-steps{padding:26px 20px;border-radius:14px;margin:32px 0}
  .bt-steps__intro{text-align:left;padding-bottom:20px}
  .bt-steps__title{font-size:23px}
  .bt-steps__list{flex-direction:column;row-gap:0;padding-top:6px}
  .bt-steps__item{flex:none;width:100%;display:grid;grid-template-columns:48px 1fr;
    column-gap:16px;text-align:left;padding:0 0 22px 6px}
  .bt-steps__item:last-child{padding-bottom:0}
  .bt-steps__icon{grid-row:1 / 4;margin:0}
  .bt-steps__item:not(:last-child)::after{display:block;top:56px;bottom:4px;
    left:29px;right:auto;border-top:0;border-left:1.5px dashed #CDB48B}
  .bt-steps__num{margin:2px 0}
  .bt-steps__desc{margin-top:3px}
}

/* AUTHOR BAR — "Written by" strip on single product pages, in its own cream
   band (SECTION 3) above Description, per bt_render_author_bar() in
   woocommerce/single-product.php. White card with a gold left edge: author
   photo/initials + name + role on the left, "Published"/"Updated" beige
   chips on the right. Scoped to .bt-author so the theme's own card/box
   styles never leak in. No outer margin — the section's own .bt-section
   padding-top/bottom already gives it vertical rhythm. */
.bt-author{
  background:#fff!important;border:1px solid #EADFCB;border-left:4px solid #C49A5A;
  border-radius:12px;padding:18px 22px;margin:0;box-shadow:none;
  display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;
  box-sizing:border-box;font-family:inherit;
}
.bt-author *{box-sizing:border-box}
.bt-author__who{display:flex;align-items:center;gap:14px;min-width:0}
.bt-author__avatar{
  width:52px;height:52px;border-radius:50%;object-fit:cover;flex:none;margin:0;
  box-shadow:0 0 0 3px #ECDCC3;
}
.bt-author__avatar--initials{
  display:flex;align-items:center;justify-content:center;
  background:#ECDCC3;color:#A87C3C;font-size:16px;font-weight:700;letter-spacing:.3px;
}
.bt-author__info{display:flex;flex-direction:column;min-width:0}
.bt-author__label{
  font-size:11px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;
  color:#A87C3C;line-height:1.3;
}
.bt-author__name{
  font-size:16px;font-weight:600;color:#151515!important;
  text-decoration:none!important;line-height:1.3;
}
.bt-author__name:hover{color:#A87C3C!important}
.bt-author__role{font-size:13px;color:#5D6470;line-height:1.4}
.bt-author__meta{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.bt-author__chip{
  display:inline-flex;align-items:center;gap:8px;background:#F7F1E7;border-radius:30px;
  padding:9px 16px;font-size:13px;color:#5D6470;white-space:nowrap;
}
.bt-author__chip time{color:#151515;font-weight:600}
.bt-author__chip svg{width:16px;height:16px;flex:none;stroke:#A87C3C;fill:none;stroke-width:1.8}

@media (max-width:1024px){
  .bt-author{padding:16px 18px}
}
@media (max-width:600px){
  .bt-author{flex-direction:column;align-items:stretch;padding:16px;gap:14px;margin:0}
  .bt-author__meta{display:grid;grid-template-columns:1fr 1fr;gap:8px;width:100%}
  .bt-author__chip{flex-direction:column;align-items:flex-start;gap:2px;border-radius:12px;padding:10px 14px}
  .bt-author__chip:only-child{grid-column:1 / -1}
  .bt-author__chip svg{display:none}
}
@media (max-width:340px){
  .bt-author__meta{grid-template-columns:1fr}
}

/* ==========================================================================
   CART COUPON BOX
   Shown on the cart page only (is_cart(), see includes/class-bt-cart-coupon.php),
   merged in here from the former assets/css/cart-coupon.css so cart-page
   styling no longer needs its own stylesheet/enqueue.

   Scoped entirely under .bt-coupon. Nothing here is a global rule and no
   existing selector is redefined, so the rest of the cart - and every other
   page - is unaffected.

   The palette is declared as local custom properties rather than reaching for
   the global tokens, because the brief specified exact hexes that sit slightly
   off the site-wide values (#D4A23A vs --gold #c9a24a, and so on). Keeping
   them local means the box matches the brief without shifting any other
   component that reads --gold.
   ========================================================================== */
.bt-coupon{
  --cpn-ink:#111111;
  --cpn-cream:#F7F3EA;
  --cpn-gold:#D4A23A;
  --cpn-gold-dark:#B8862A;
  --cpn-gold-bg:#FBF3E0;
  --cpn-green:#2F7D4F;
  --cpn-red:#C0392B;
  --cpn-muted:#8f8f8f;
}

/* ── Field + Apply row ──────────────────────────────────────────────────── */

/* Disabled (a coupon is on the cart, ONE_COUPON_ONLY on). The dashed gold
   rule goes flat grey so "locked" reads at a glance rather than only from the
   cursor. */
.bt-coupon.is-locked .bt-coupon-form__field,
.bt-coupon .bt-coupon-form__field:disabled{
  background-color:#f4f4f2;border-color:rgba(0,0,0,.16);border-style:solid;
  color:var(--cpn-muted);cursor:not-allowed;opacity:1;
}
.bt-coupon .bt-coupon-form__apply:disabled{
  background:#d9d9d6;border-color:#d9d9d6;color:#7a7a7a;cursor:not-allowed;
  transform:none;box-shadow:none;
}
.bt-coupon .bt-coupon-form__apply:disabled:hover{
  background:#d9d9d6;border-color:#d9d9d6;transform:none;
}

/* Invalid code: red rule on the field, matching the inline message. */
.bt-coupon .bt-coupon-form__field.has-error{
  border-style:solid;border-color:var(--cpn-red);
  box-shadow:0 0 0 3px rgba(192,57,43,.12);
}

/* ── Applying… spinner ──────────────────────────────────────────────────── */

/* The label is swapped by CSS, not by JS rewriting the button text, so the
   button's accessible name and its name="apply_coupon" value are never
   touched - WooCommerce still receives exactly the control it expects on a
   no-JS submit. */
.bt-coupon.is-busy .bt-coupon-form__apply{
  color:transparent;position:relative;pointer-events:none;
}
.bt-coupon.is-busy .bt-coupon-form__apply::before{
  content:attr(data-applying-label);
  position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);
  color:#7a7a7a;font-size:var(--fs-ui);font-weight:var(--fw-semibold);
  padding-left:14px;
}
.bt-coupon.is-busy .bt-coupon-form__apply::after{
  content:"";position:absolute;top:50%;right:16px;width:14px;height:14px;
  margin-top:-7px;border-radius:50%;
  border:2px solid rgba(0,0,0,.18);border-top-color:var(--cpn-gold-dark);
  animation:bt-coupon-spin .7s linear infinite;
}
@keyframes bt-coupon-spin{to{transform:rotate(360deg)}}

@media (prefers-reduced-motion:reduce){
  .bt-coupon.is-busy .bt-coupon-form__apply::after{animation-duration:2.4s}
}

/* ── Inline message (aria-live region) ──────────────────────────────────── */
.bt-coupon-msg{
  margin:10px 0 0;font-size:var(--fs-small);line-height:1.5;
  display:flex;align-items:flex-start;gap:7px;
}
.bt-coupon-msg[hidden]{display:none}
.bt-coupon-msg::before{
  font-family:'bootstrap-icons';font-size:14px;line-height:1.35;flex-shrink:0;
}
.bt-coupon-msg--error{color:var(--cpn-red)}
.bt-coupon-msg--error::before{content:"\f622"}
.bt-coupon-msg--success{color:var(--cpn-green)}
.bt-coupon-msg--success::before{content:"\f26b"}
.bt-coupon-msg--info{color:var(--cpn-muted)}
.bt-coupon-msg--info::before{content:"\f431"}

/* ── Applied-coupon chip ────────────────────────────────────────────────── */
.bt-coupon-applied{margin:14px 0 0;display:flex;flex-direction:column;gap:10px}
.bt-coupon-applied[hidden]{display:none}

.bt-coupon-applied__chip{
  display:flex;align-items:center;flex-wrap:wrap;gap:4px 10px;
  padding:12px 14px;border-radius:12px;
  background:var(--cpn-gold-bg);border:1px solid var(--cpn-gold);
  font-size:var(--fs-small);color:var(--cpn-ink);
}
.bt-coupon-applied__tick{color:var(--cpn-green);font-size:16px;line-height:1;flex-shrink:0}
/* min-width:0 lets a long code wrap instead of forcing the chip wider than
   its card on a narrow screen. */
.bt-coupon-applied__text{flex:1 1 auto;min-width:0;overflow-wrap:anywhere}
.bt-coupon-applied__text strong{font-weight:var(--fw-heading);letter-spacing:.3px}

.bt-coupon-applied__remove{
  display:inline-flex;align-items:center;gap:3px;flex-shrink:0;
  margin-left:auto;padding:5px 12px;border-radius:9999px;
  background:#fff;border:1px solid rgba(0,0,0,.16);
  color:var(--cpn-ink);text-decoration:none;cursor:pointer;
  font-size:var(--fs-xs);font-weight:var(--fw-semibold);
  transition:background-color .2s,border-color .2s,color .2s;
}
.bt-coupon-applied__remove:hover{
  background:var(--cpn-red);border-color:var(--cpn-red);color:#fff;
}
.bt-coupon-applied__remove:focus-visible{
  outline:2px solid var(--cpn-gold-dark);outline-offset:2px;
}
.bt-coupon-applied__remove.is-loading{
  pointer-events:none;opacity:.6;
}
.bt-coupon-applied__remove.is-loading i::before{
  content:"\f130";display:inline-block;
  animation:bt-coupon-spin .7s linear infinite;
}

/* The remove link WooCommerce prints inside Cart totals - same loading cue so
   both removal paths feel identical. Core owns its behaviour. */
.cart_totals a.woocommerce-remove-coupon.is-loading{opacity:.5;pointer-events:none}

/* ── Mobile ─────────────────────────────────────────────────────────────── */
@media (max-width:767px){
  /* The field/button stacking is already handled by the cart block in
     theme.css; this only keeps the chip readable once it wraps. */
  .bt-coupon-applied__chip{align-items:flex-start}
  .bt-coupon-applied__remove{margin-left:0}
}

/* ═══════════════════════════════════════════════════════════════
   CATEGORY SIDEBAR
   Catalog layout (sidebar + product grid) shared by the Shop root
   (woocommerce/archive-product.php) and product category archives
   (woocommerce/taxonomy-product_cat.php). "All Products" is the active
   sidebar/pill entry on the Shop root, since that template has no term
   of its own.

   No new colours: every value below is one of the theme's existing
   tokens (--forest #121212 for the dark/active surface, --gold, --ivory
   / --ivory-d for the off-white ground and hover tint, --border,
   --text1/2/3, the --fs- / --fw- type scale). The product card itself is
   untouched — only .shop-grid's column count is re-scoped here, because
   it now sits beside a sidebar instead of running the full container
   width.
   ═══════════════════════════════════════════════════════════════ */

/* ─── Catalog layout: sidebar + main ─── */
.bt-cat-layout{display:grid;grid-template-columns:260px 1fr;gap:36px;align-items:start}

.bt-cat-sidebar{position:sticky;top:100px}

.bt-cat-sidebar__card{
  background:#fff;border:1px solid var(--border);border-radius:18px;padding:20px;
}

.bt-cat-sidebar__heading{
  display:block;font-size:var(--fs-label);font-weight:var(--fw-label);
  letter-spacing:2px;text-transform:uppercase;color:var(--text3);margin-bottom:12px;
}

.bt-cat-sidebar__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}

/* Row order is name, count, arrow. The count belongs to the name, so the
   two sit together at the start (gap:0 + the count's own small offset)
   and only the arrow is pushed to the far end, by margin-left:auto —
   space-between used to strand the count in the middle of the row. */
.bt-cat-sidebar__link{
  display:flex;align-items:center;justify-content:flex-start;gap:0;
  padding:12px 14px;border-radius:12px;min-height:44px;
  font-weight:var(--fw-heading);font-size:var(--fs-ui);color:var(--text1);
  text-decoration:none;transition:background-color .15s ease,color .15s ease;
}
.bt-cat-sidebar__link:hover{background:var(--ivory-d)}
.bt-cat-sidebar__link.is-active{background:var(--forest);color:#fff}
.bt-cat-sidebar__link.is-active:hover{background:var(--forest)}
.bt-cat-sidebar__link-name{overflow-wrap:anywhere}
.bt-cat-sidebar__arrow{flex:0 0 auto;opacity:.6;margin-left:auto;padding-left:10px}
.bt-cat-sidebar__link.is-active .bt-cat-sidebar__arrow{opacity:1}
/* Brackets are drawn here, not written into the templates, so the three
   places that print a count (both sidebars and the child list) can never
   drift apart. */
.bt-cat-sidebar__count{font-weight:var(--fw-medium);font-size:var(--fs-xs);color:var(--text3);flex:0 0 auto;margin-left:6px}
.bt-cat-sidebar__count::before{content:"("}
.bt-cat-sidebar__count::after{content:")"}
.bt-cat-sidebar__link.is-active .bt-cat-sidebar__count{color:rgba(255,255,255,.65)}

.bt-cat-sidebar__children{
  list-style:none;margin:4px 0 8px;padding:0 0 0 14px;
  display:flex;flex-direction:column;gap:2px;
  border-left:2px solid var(--border);
}
.bt-cat-sidebar__child-link{
  display:flex;align-items:center;justify-content:flex-start;gap:0;
  padding:10px 14px;border-radius:10px;min-height:44px;
  font-weight:var(--fw-medium);font-size:var(--fs-small);color:var(--text2);
  text-decoration:none;transition:background-color .15s ease,color .15s ease;
}
.bt-cat-sidebar__child-link:hover{background:var(--ivory-d)}
.bt-cat-sidebar__child-link[aria-current="page"]{background:var(--ivory-d);color:var(--text1);font-weight:var(--fw-semibold)}

/* ─── Mobile/tablet category pills (shown <1024px instead of the sidebar) ─── */
.bt-cat-pills{
  display:none;
  gap:10px;overflow-x:auto;padding:4px 2px 12px;margin-bottom:16px;
  scroll-snap-type:x proximity;
  scrollbar-width:none;-ms-overflow-style:none;
}
.bt-cat-pills::-webkit-scrollbar{display:none}
.bt-cat-pills__link{
  flex:0 0 auto;scroll-snap-align:start;
  display:inline-flex;align-items:center;gap:6px;
  padding:10px 16px;border-radius:9999px;min-height:44px;
  font-weight:var(--fw-heading);font-size:var(--fs-small);color:var(--text1);
  background:#fff;border:1px solid var(--border);white-space:nowrap;text-decoration:none;
}
.bt-cat-pills__link.is-active{background:var(--forest);color:#fff;border-color:var(--forest)}

/* ─── Toolbar ─── */
.bt-cat-toolbar{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  margin-bottom:20px;flex-wrap:wrap;
}
.bt-cat-toolbar__count{color:var(--text3);font-size:var(--fs-small);margin:0}

/* ─── Product grid (card markup/styles untouched — only the column
   count changes here, since the grid now runs in the main column next
   to the sidebar rather than the full container width).

   Three across from tablet up, two on a phone. Three is the count all
   the way down to 768px, not just on desktop: below 1024px the sidebar
   is gone and .bt-cat-main has the whole container, so the same three
   columns are WIDER on a tablet than they are next to the sidebar at
   1024px — dropping to two there made the cards larger still, which is
   what this now avoids. ─── */
.bt-cat-main .shop-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:20px}

/* ─── 1024–1279px: narrower fixed sidebar, grid stays 3-up ─── */
@media (min-width:1024px) and (max-width:1279px){
  .bt-cat-layout{grid-template-columns:220px 1fr;gap:28px}
}

/* ─── <1024px: sidebar gives way to the pill row, grid drops to 2-up ─── */
@media (max-width:1023px){
  .bt-cat-layout{grid-template-columns:1fr;gap:0}
  .bt-cat-sidebar{display:none}
  .bt-cat-pills{display:flex}
  /* The grid deliberately does NOT change count here — it stays at the
     three columns the base rule sets, right down to 768px. The phone
     block below is where it becomes two. */
}

/* ─── <768px: toolbar stacks, grid gap tightens ─── */
@media (max-width:767px){
  .bt-cat-toolbar{flex-direction:column;align-items:stretch}
  .bt-cat-toolbar .sh-sort{width:100%}
  .bt-cat-toolbar .sh-sort .sh-sort__btn{width:100%;justify-content:space-between}
  .bt-cat-main .shop-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
}

/* Two across holds all the way down: at 360px that is a 158px card, the
   same width the homepage strip (.grid-products) already renders at that
   viewport, so there is no width at which the catalogue falls to a single
   column. The <380px single-column rule that used to live here is gone
   with it — it was what made a 360/375px phone show one card per row
   while a 390px one showed two. */

/* ═══════════════════════════════════════════════════════════════
   MOBILE/TABLET CATEGORY DROPDOWN + PRODUCT LIST VIEW
   Shop root (archive-product.php) + product category archives
   (taxonomy-product_cat.php) ONLY. Every selector below is scoped to
   body.post-type-archive-product / body.tax-product_cat so it can
   never reach any other template, and every rule that actually
   changes the catalog's look sits inside a <1024px media query — so
   ≥1024px (DESKTOP) falls through completely untouched: same
   .bt-cat-sidebar, same .shop-grid cards, same everything above.

   No new colours: #111 (ink), #c9a24a (the theme's --gold), #faf8f4
   (the theme's --ivory) and #ece7dc (a hairline close to the theme's
   --border) are the only values used here.

   Markup is unchanged below <1024px — the .mcat dropdown and the
   .bt-cat-toolbar__catname span are new, but the product grid/card
   markup (.shop-grid, .product-card, .product-thumb, .marquee-*) is
   purely restyled here, exactly as it renders at ≥1024px. ═══ */

/* The number in "N products" is bold ONLY inside the <1024px block
   below — this baseline keeps it at the surrounding text's own
   weight everywhere else, so desktop prints the same plain string it
   always has. */
body.post-type-archive-product .bt-cat-toolbar__count strong,
body.tax-product_cat .bt-cat-toolbar__count strong{font-weight:inherit}

/* ── Category dropdown — hidden by default, shown below 1024px. ── */
.mcat{display:none}

body.post-type-archive-product .mcat summary,
body.tax-product_cat .mcat summary{
  list-style:none;cursor:pointer;
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  background:#fff;border:1px solid #ece7dc;border-radius:16px;padding:12px 14px;
}
body.post-type-archive-product .mcat summary::-webkit-details-marker,
body.tax-product_cat .mcat summary::-webkit-details-marker{display:none}
body.post-type-archive-product .mcat summary > span,
body.tax-product_cat .mcat summary > span{display:flex;flex-direction:column;gap:3px;min-width:0}
body.post-type-archive-product .mcat summary small,
body.tax-product_cat .mcat summary small{
  font-size:11px;letter-spacing:1.5px;color:#888;font-weight:700;text-transform:uppercase;
}
body.post-type-archive-product .mcat summary b,
body.tax-product_cat .mcat summary b{
  font-size:17px;font-weight:800;color:#111;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
body.post-type-archive-product .mcat-btn,
body.tax-product_cat .mcat-btn{
  flex:0 0 40px;width:40px;height:40px;border-radius:10px;
  background:#111;color:#fff;font-style:normal;font-size:15px;line-height:1;
  display:flex;align-items:center;justify-content:center;
  transition:transform .2s ease;
}
body.post-type-archive-product .mcat[open] .mcat-btn,
body.tax-product_cat .mcat[open] .mcat-btn{transform:rotate(180deg)}

body.post-type-archive-product .mcat nav,
body.tax-product_cat .mcat nav{
  display:flex;flex-direction:column;
  background:#fff;border:1px solid #ece7dc;border-radius:14px;
  margin-top:8px;overflow:hidden;
}
body.post-type-archive-product .mcat nav a,
body.tax-product_cat .mcat nav a{
  display:flex;align-items:center;justify-content:flex-start;gap:6px;
  min-height:48px;padding:12px 14px;
  font-size:15px;font-weight:600;color:#111;text-decoration:none;
  border-bottom:1px solid #ece7dc;
}
body.post-type-archive-product .mcat nav a:last-child,
body.tax-product_cat .mcat nav a:last-child{border-bottom:0}
body.post-type-archive-product .mcat nav a em,
body.tax-product_cat .mcat nav a em{font-style:normal;font-weight:600;font-size:13px;color:#888;margin-left:6px}
body.post-type-archive-product .mcat nav a em::before,
body.tax-product_cat .mcat nav a em::before{content:"("}
body.post-type-archive-product .mcat nav a em::after,
body.tax-product_cat .mcat nav a em::after{content:")"}
body.post-type-archive-product .mcat nav a[aria-current="page"],
body.tax-product_cat .mcat nav a[aria-current="page"]{background:#111;color:#fff}
body.post-type-archive-product .mcat nav a[aria-current="page"] em,
body.tax-product_cat .mcat nav a[aria-current="page"] em{color:#c9a24a}

/* ── <1024px: dropdown replaces the pill row, count+sort row restyles,
   product grid becomes a list ── */
@media (max-width:1023px){
  body.post-type-archive-product .mcat,
  body.tax-product_cat .mcat{display:block;margin:16px}

  body.post-type-archive-product .bt-cat-pills,
  body.tax-product_cat .bt-cat-pills{display:none}

  /* Toolbar: one row, space-between — overrides the <768px stacked rule
     above, which this redesign replaces. */
  body.post-type-archive-product .bt-cat-toolbar,
  body.tax-product_cat .bt-cat-toolbar{
    flex-direction:row;align-items:center;flex-wrap:nowrap;
    padding:14px 16px;margin:0;
  }
  body.post-type-archive-product .bt-cat-toolbar__count,
  body.tax-product_cat .bt-cat-toolbar__count{margin:0}
  body.post-type-archive-product .bt-cat-toolbar__count strong,
  body.tax-product_cat .bt-cat-toolbar__count strong{font-weight:800;color:#111}
  body.post-type-archive-product .bt-cat-toolbar__catname,
  body.tax-product_cat .bt-cat-toolbar__catname{display:none}

  /* Sort: plain text, no pill/border — the real <select> underneath
     still submits exactly as it did before. */
  body.post-type-archive-product .bt-cat-toolbar .sh-sort,
  body.tax-product_cat .bt-cat-toolbar .sh-sort{width:auto}
  body.post-type-archive-product .bt-cat-toolbar .sh-sort__btn,
  body.tax-product_cat .bt-cat-toolbar .sh-sort__btn{
    width:auto;justify-content:flex-start;
    height:auto;min-height:44px;padding:0;
    background:transparent;border:none;box-shadow:none;
    font-size:13px;
  }
  body.post-type-archive-product .bt-cat-toolbar .sh-sort__btn:hover,
  body.tax-product_cat .bt-cat-toolbar .sh-sort__btn:hover,
  body.post-type-archive-product .bt-cat-toolbar .sh-sort.is-open .sh-sort__btn,
  body.tax-product_cat .bt-cat-toolbar .sh-sort.is-open .sh-sort__btn{
    background:transparent;border:none;box-shadow:none;
  }
  body.post-type-archive-product .bt-cat-toolbar .sh-sort__value,
  body.tax-product_cat .bt-cat-toolbar .sh-sort__value{font-weight:800}
  body.post-type-archive-product .bt-cat-toolbar select.orderby,
  body.tax-product_cat .bt-cat-toolbar select.orderby{
    background:transparent;border:none;padding:0;min-height:44px;font-size:13px;
  }

  /* Product cards are intentionally left alone here — .shop-grid and
     .product-card keep the theme's original grid design (the existing
     <1024px rules above this block already size the grid down to 2
     columns, and 1 column under 380px). Only the dropdown and the
     toolbar above the grid change on mobile/tablet. */
}

/* ── Footer column heads ──────────────────────────────────────────────
   The four .typography-label heads inside the dark footer ("Quick Links",
   "Categories", "Important Links", "Contact Us") read too small and too
   light against the black band, so they get their own size/weight here.
   Scoped to <footer> on purpose: .typography-label is the shared label
   token used by table heads, form labels and eyebrows elsewhere, and
   those are all on light backgrounds and must not change. */
footer .typography-label{font-size:15px;font-weight:900}

/* ═══════════════════════════════════════════════════════════════
   PDP TOP GRID (.bt-product-grid)
   Everything on a single-product page between the header and the
   "Easy Steps to Order" band: category pill, title + rating, specs
   table, image card, thumb rail, short description, coupon box,
   pack-size table, small pack image and the categories card.

   ONE set of markup (woocommerce/single-product.php), placed three
   ways by grid-area name, on the THEME'S OWN breakpoints rather than
   any of this block's own — <=767px (single column), 768-1023px (two
   columns, categories full width on top) and >=1024px (the 30/50/20
   three-column layout).

   768/767 and 1024/1023 are the two crossovers the rest of the theme
   already turns on: 1024 is where header.php swaps the hamburger bar
   for the full desktop nav (.bt-header-desktop-row / .bt-mobile-bar)
   and where the category archive brings back its sidebar
   (.bt-cat-layout), and 768/767 is the theme's long-standing phone
   crossover. This grid used to cross over at 1200px, a value nothing
   else in the theme used, which left 1024-1199px showing the desktop
   header above a tablet body. Nothing here is product-specific
   and every block is a direct child of the grid, so a block that a
   product has no data for simply isn't printed and its row
   collapses.

   Surfaces, type, colour and buttons are the site's existing
   tokens and components (.card, .btn-sage, .btn-outline,
   .badge-sage, .bt-cat-sidebar__*, --gold/--forest/--border) —
   this block adds layout, not a second visual language. Scoped to
   body.single-product throughout so none of the shared components
   it re-tints change anywhere else.
   ═══════════════════════════════════════════════════════════════ */

/* The gallery div exists only as the wrapper assets/js/script.js reads (its
   data-variation-images map, and its querySelector('.pdp-thumbs')). It must
   not be a grid item itself, or the image card and the thumb rail could not
   sit in two different grid areas — display:contents keeps the DOM the JS
   expects while promoting its two children to real grid items. */
body.single-product .pdp-gallery{display:contents}

/* ── Breadcrumb — above the grid, full content width ─────────────── */
body.single-product .bt-pdp-crumbs{
  display:flex;align-items:center;flex-wrap:wrap;gap:8px;
  font-size:var(--fs-xs);color:var(--text3);margin-bottom:18px;
}
body.single-product .bt-pdp-crumbs__link{color:inherit;text-decoration:none}
body.single-product .bt-pdp-crumbs__link:hover{color:var(--text1)}
body.single-product .bt-pdp-crumbs__sep{font-size:10px;opacity:.7}
body.single-product .bt-pdp-crumbs__current{font-weight:var(--fw-semibold);color:var(--text1)}

/* ── The grid — mobile first ──────────────────────────────────────
   cats leads: below 1024px it is a CLOSED dropdown (one 44px button
   tall until tapped), so at the top it costs a single row of height
   and puts the category navigation where a phone visitor looks for
   it, instead of burying it under the whole page.

   packimg is absent from this template on purpose: on a phone it would
   be a second copy of the main image two blocks up, so it is not shown
   (see its own display:none below). */
body.single-product .bt-product-grid{
  display:grid;
  grid-template-columns:minmax(0,1fr);
  grid-template-areas:
    "cats"
    "pill"
    "title"
    "img"
    "thumbs"
    "specs"
    "desc"
    "coupon"
    "pack";
  column-gap:24px;
  row-gap:20px;
  align-items:start;
}

body.single-product .bt-pdp-pill{grid-area:pill;display:flex;flex-wrap:wrap;gap:8px;min-width:0}
body.single-product .bt-pdp-pill__link{text-decoration:none}
body.single-product .bt-pdp-head{grid-area:title;min-width:0}
body.single-product .bt-pdp-specs{grid-area:specs;min-width:0}
body.single-product .bt-pdp-imgcard{grid-area:img;min-width:0}
body.single-product .bt-pdp-thumbs{grid-area:thumbs;min-width:0}
body.single-product .bt-pdp-desc{grid-area:desc;min-width:0}
body.single-product .bt-pdp-coupon{grid-area:coupon;min-width:0}
body.single-product .bt-pdp-pack,
body.single-product .bt-pdp-buy{grid-area:pack;min-width:0}
body.single-product .bt-pdp-packimg{grid-area:packimg}
body.single-product .bt-pdp-cats{grid-area:cats;min-width:0}

/* ── title ───────────────────────────────────────────────────────── */
body.single-product .bt-pdp-title{
  font-size:var(--fs-h1);font-weight:var(--fw-heading);
  line-height:var(--lh-heading);letter-spacing:var(--ls-heading);
  color:var(--ink-heading);margin:0;overflow-wrap:anywhere;
}
body.single-product .bt-pdp-rating{
  display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-top:10px;
}
body.single-product .bt-pdp-rating__stars{display:inline-flex;gap:2px;font-size:var(--fs-small);color:var(--gold)}
body.single-product .bt-pdp-rating__stars .is-empty{color:#e5e7eb}
body.single-product .bt-pdp-rating__score{font-size:var(--fs-small);font-weight:var(--fw-heading);color:var(--text1)}
body.single-product .bt-pdp-rating__count{font-size:var(--fs-xs);color:var(--text3)}

/* ── specs ───────────────────────────────────────────────────────── */
body.single-product .bt-pdp-specs{overflow:hidden}
body.single-product .bt-pdp-specs__table{width:100%;table-layout:fixed;border-collapse:collapse;margin:0}
body.single-product .bt-pdp-specs__row{border-bottom:1px solid var(--border)}
body.single-product .bt-pdp-specs__row:last-child{border-bottom:0}
body.single-product .bt-pdp-specs__label{
  width:40%;padding:11px 16px;text-align:left;vertical-align:top;
  font-size:var(--fs-label);font-weight:var(--fw-label);
  letter-spacing:.06em;text-transform:uppercase;color:var(--text3);
  overflow-wrap:anywhere;
}
body.single-product .bt-pdp-specs__value{
  width:60%;padding:11px 16px;vertical-align:top;
  font-size:var(--fs-small);font-weight:var(--fw-semibold);color:var(--text1);
  overflow-wrap:anywhere;
}

/* ── img ─────────────────────────────────────────────────────────
   A SQUARE white card, every breakpoint, with the picture contained inside
   it at its own aspect ratio.

   The stage carries no background of its own. Product photography here is
   mixed-ratio — some shots are near-square, some are 2.4:1 banners — so
   object-fit:contain always leaves some unused band above and below the
   picture. Painted grey, that band read as a rectangle the image was
   floating inside; left white, it is the card, and the picture (whose own
   source background is white) simply sits on it with nothing to see. The
   alternative, object-fit:cover, would crop a third to a half off the wide
   shots, which is not acceptable on a product page.

   The card does NOT stretch to the rows beside it. A card stretched to the
   title + specs rows is as tall as that text, not as wide as it is tall, so
   it stopped being square and left visible dead space under the picture.
   Squareness won over the row alignment here.

   The <img> is absolutely positioned so it contributes nothing to the
   card's min-content height — the aspect-ratio alone decides that.

   The Rx disc is positioned against the card, not the stage, so it sits in
   the card's top-left corner without taking part in the flex column and
   cannot push the image down. */
body.single-product .bt-pdp-imgcard{
  position:relative;
  display:flex;
  flex-direction:column;
  padding:clamp(10px,2vw,16px);
  overflow:hidden;
  aspect-ratio:1;
  max-width:360px;
  width:100%;
  margin-inline:auto;
}
body.single-product .bt-pdp-imgcard__stage{
  position:relative;
  flex:1 1 auto;
  min-height:0;
  overflow:hidden;
}
/* Fills the stage exactly — inset:0 with an explicit 100%/100%, and NO
   padding of its own. Two reasons it has to be written this way:

   - height:auto on an absolutely positioned REPLACED element resolves to the
     image's intrinsic height and `bottom` is then ignored, so the picture
     anchors to the top of the card with all the slack underneath instead of
     sitting in the middle. An explicit height is what centres it.
   - padding would make the <img>'s border box larger than the content box
     object-fit measures against, and the magnifier (assets/js/script.js)
     derives the visible picture from getBoundingClientRect() plus the
     natural ratio — it already accounts for letterboxing, but not for
     padding, and the lens would track a point the cursor isn't on. The
     card's own padding provides the breathing room instead. */
body.single-product .bt-pdp-imgcard__stage .pdp-zoom-img{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:contain;
  display:block;
}
body.single-product .bt-pdp-imgcard .pdp-gallery__empty{position:absolute;inset:0}
body.single-product .bt-pdp-imgcard__fallback{
  font-size:var(--fs-small);font-weight:var(--fw-semibold);
  color:var(--text3);margin:8px 16px 0;
}

/* ── thumbs ───────────────────────────────────────────────────────
   Three squares in a row, as a grid rather than the archive rail's
   scrolling flex row: this area must never scroll sideways. A product
   with two images shows two; one with more than three wraps onto a
   second row instead of overflowing.

   The tracks are a FIXED size, not minmax(0,1fr). With 1fr each thumb
   stretched to a third of the whole column — about 113px on a 1440px
   desktop and the full content width on a phone — which made the three
   variant pictures read as a second product row under the main image
   rather than as a thumbnail strip. The size here is the same
   84/74/64px the rail already uses everywhere else on the site
   (.pdp-thumb in the PDP GALLERY block above), so this stops the grid
   from overriding it rather than inventing a new measurement.

   One variable drives the track width and nothing else needs to know
   the number; the two media queries below only re-point it. */
body.single-product .bt-pdp-thumbs{
  --pdp-thumb-size:84px;
  display:grid;
  grid-template-columns:repeat(3,var(--pdp-thumb-size));
  justify-content:start;
  gap:10px;
  margin-top:0;
  padding:0;
  overflow:visible;
}
/* width:auto, so each thumb fills its fixed track exactly (a grid item
   stretches to its track by default). flex:none because .pdp-thumb's
   base rule is written for the flex rail and its flex:0 0 84px would
   otherwise be dead weight here. */
body.single-product .bt-pdp-thumbs .pdp-thumb{flex:none;width:auto}

/* ── desc ────────────────────────────────────────────────────────── */
body.single-product .bt-pdp-desc{padding:18px 20px}
body.single-product .bt-pdp-desc__title{
  font-size:var(--fs-label);font-weight:var(--fw-label);
  letter-spacing:var(--ls-label);text-transform:uppercase;
  color:var(--text3);margin:0 0 8px;
}
body.single-product .bt-pdp-desc__body{
  font-size:var(--fs-body);line-height:var(--lh-body);color:var(--ink-body);
}
body.single-product .bt-pdp-desc__body p{margin:0 0 .7em}
body.single-product .bt-pdp-desc__body > :last-child{margin-bottom:0}

/* ── coupon ──────────────────────────────────────────────────────── */
body.single-product .bt-pdp-coupon{
  display:flex;align-items:center;gap:10px;
  padding:14px 16px;border-radius:var(--r);
  background:rgba(201,162,74,.08);
  border:1px solid rgba(201,162,74,.22);
}
body.single-product .bt-pdp-coupon__icon{color:var(--gold);flex:0 0 auto}
body.single-product .bt-pdp-coupon__text{font-size:var(--fs-small);color:var(--text2)}
body.single-product .bt-pdp-coupon__code{color:var(--gold-d);font-weight:var(--fw-heading)}

/* ── pack ─────────────────────────────────────────────────────────
   Four columns on >=768px, with no min-width and so no horizontal
   scroller; the phone rules further down turn each row into a card. */
body.single-product .bt-pdp-pack{overflow:hidden}
body.single-product .bt-pdp-pack__table{width:100%;border-collapse:collapse;margin:0}
body.single-product .bt-pdp-pack__head tr{background:var(--forest)}
body.single-product .bt-pdp-pack__th{
  padding:12px 14px;text-align:left;color:#fff;
  font-size:var(--fs-label);font-weight:var(--fw-label);
  letter-spacing:var(--ls-label);text-transform:uppercase;white-space:nowrap;
}
body.single-product .bt-pdp-pack__th--center{text-align:center}
body.single-product .bt-pdp-pack__row{border-bottom:1px solid var(--border)}
body.single-product .bt-pdp-pack__row:last-child{border-bottom:0}
body.single-product .bt-pdp-pack__row.is-first{background:rgba(0,0,0,.03)}
body.single-product .bt-pdp-pack__cell{padding:11px 14px;vertical-align:middle}
body.single-product .bt-pdp-pack__name{
  font-size:var(--fs-ui);font-weight:var(--fw-heading);
  color:var(--forest);overflow-wrap:anywhere;
}
body.single-product .bt-pdp-pack__namelink{color:inherit;text-decoration:none}
body.single-product .bt-pdp-pack__namelink:hover{color:var(--gold-d)}
body.single-product .bt-pdp-pack__amount{
  font-size:17px;font-weight:var(--fw-heading);color:var(--sage);white-space:nowrap;
}
body.single-product .bt-pdp-pack__qty,
body.single-product .bt-pdp-pack__add{text-align:center}
body.single-product .bt-pdp-pack__form{display:inline-flex;margin:0}
/* Smaller than the site's default .btn-sage/.btn-outline padding because it
   sits in a table cell; the pill shape, colours and hover stay theirs. */
body.single-product .bt-pdp-pack__btn{
  padding:10px 16px;font-size:var(--fs-xs);min-height:40px;
}
body.single-product .bt-pdp-pack__oos{
  font-size:var(--fs-xs);font-weight:var(--fw-heading);color:var(--text3);
}
body.single-product .bt-pdp-qty{
  width:60px;min-height:40px;padding:8px 6px;text-align:center;
  border:1px solid var(--border);border-radius:12px;background:#fff;
  font-family:inherit;font-size:var(--fs-ui);color:var(--text1);outline:none;
}
body.single-product .bt-pdp-qty:focus{border-color:var(--sage);box-shadow:0 0 0 3px rgba(0,0,0,.08)}

/* ── pack, simple-product form (no variations and no upsell packs) ── */
body.single-product .bt-pdp-buy{
  display:flex;align-items:center;flex-wrap:wrap;gap:16px;padding:18px 20px;
}
body.single-product .bt-pdp-buy__price{
  font-size:var(--fs-h2);font-weight:var(--fw-heading);color:var(--sage);
}
body.single-product .bt-pdp-buy__form{display:flex;gap:12px;flex:1 1 220px;margin:0}
body.single-product .bt-pdp-buy__btn{flex:1 1 auto;min-height:48px}

/* ── packimg ─────────────────────────────────────────────────────── */
body.single-product .bt-pdp-packimg{
  width:180px;max-width:100%;aspect-ratio:1;
  display:flex;align-items:center;justify-content:center;overflow:hidden;
}
body.single-product .bt-pdp-packimg__img{width:100%;height:100%;object-fit:contain;display:block}

/* ── cats ────────────────────────────────────────────────────────
   One copy of the links serves all three breakpoints. Written closed-
   first, which is the <1024px dropdown; the >=1024px block opens it
   permanently, hides the button and shows the static heading instead.

   The card surface is the desktop one at every width — same white fill,
   same 1px --border, same 18px radius, same 16px padding — so only the
   header row and the panel's height change between ranges, never the
   card's design.

   Rows are the category archive's own .bt-cat-sidebar__* component;
   only the active row is re-tinted here, from that sidebar's black to
   the light-gold/gold pair .badge-gold already uses. */
body.single-product .bt-pdp-cats__box{
  background:#fff;border:1px solid var(--border);border-radius:18px;padding:4px 16px;
}

/* The static title. Hidden in the dropdown ranges, where the button
   carries its own copy of it; shown from 1024px up, where there is no
   control to label. */
body.single-product .bt-pdp-cats__heading{display:none;margin:0}

/* The control. A real <button>, so Enter/Space, focus and the
   aria-expanded state all come for free - assets/js/pdp-categories.js
   only flips that attribute and .is-open. */
body.single-product .bt-pdp-cats__toggle{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  width:100%;min-height:44px;padding:0;margin:0;
  background:none;border:0;cursor:pointer;text-align:left;
  font-family:inherit;color:inherit;
}
body.single-product .bt-pdp-cats__toggle .bt-cat-sidebar__heading{margin:0}

/* "+" that becomes "−" when open, in the 30px light-gold disc from the
   design. The glyph is CSS content on an aria-hidden span rather than
   text in the markup, so the button's accessible name stays the word
   "Categories" and never reads as "Categories plus". U+2212 MINUS, not
   a hyphen, so the two states are the same optical width. */
body.single-product .bt-pdp-cats__icon{
  flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;
  width:30px;height:30px;border-radius:50%;
  background:#F6EEDC;color:#9A7433;
  font-size:17px;font-weight:var(--fw-heading);line-height:1;
}
body.single-product .bt-pdp-cats__icon::before{content:"+"; margin-top: -5px;}
body.single-product .bt-pdp-cats__toggle[aria-expanded="true"] .bt-pdp-cats__icon::before{content:"\2212"}

/* Closed by default. max-height rather than height:auto because auto is
   not animatable; the 520px cap is well clear of the real list (the
   store's top-level categories at 44px a row) and is only ever a
   ceiling for the transition, never a crop - overflow returns to
   visible the moment the panel is open, so a longer list than that
   still shows in full, it just finishes opening sooner.

   padding-top only applies when open, or the closed state would keep
   8px of dead space under the button. */
body.single-product .bt-pdp-cats__panel{
  max-height:0;overflow:hidden;
  transition:max-height .3s ease;
}
body.single-product .bt-pdp-cats__box.is-open .bt-pdp-cats__panel{
  max-height:520px;overflow:visible;padding-top:8px;
}
@media (prefers-reduced-motion:reduce){
  body.single-product .bt-pdp-cats__panel{transition:none}
}
body.single-product .bt-pdp-cats .bt-cat-sidebar__link.is-active,
body.single-product .bt-pdp-cats .bt-cat-sidebar__link.is-active:hover{
  background:rgba(201,162,74,.12);color:var(--gold-d);
}
body.single-product .bt-pdp-cats .bt-cat-sidebar__link.is-active .bt-cat-sidebar__count{
  color:var(--gold-d);opacity:.8;
}

/* ════════ >=768px — two columns (the half tablet and desktop share) ════════
   The area map and the two-column behaviour the two upper ranges have
   in common. Desktop overrides the map again at 1024px. */
@media (min-width:768px){
  body.single-product .bt-product-grid{
    grid-template-columns:minmax(0,2fr) minmax(0,3fr);
    grid-template-areas:
      "cats    cats"
      ".       pill"
      "img     title"
      "img     specs"
      "thumbs  desc"
      "thumbs  coupon"
      "packimg pack";
    column-gap:20px;
    row-gap:16px;
  }

  /* Stretched across the title and specs rows, so the card's bottom edge
     lines up with the bottom of the specs table rather than floating above
     it, and free to use the full column width.

     aspect-ratio:1 STAYS, and is doing something different from the height
     it sets on a phone: on a stretched grid item the row decides the used
     height, but the ratio is still what the item contributes to sizing that
     row, so it acts as the floor. The square is the minimum and the specs
     table can only ever push past it. Dropping the ratio here collapsed the
     card to the height of the two rows beside it — 55px on a product with
     no specs table at all — which is the bug this comment exists to stop
     coming back.

     Above the square the picture keeps object-fit:contain and is simply
     centred in the taller rectangle. Contain, not cover, because these shots
     run to 2.4:1 and cropping a third off a product label on the product's
     own page is not acceptable. */
  body.single-product .bt-pdp-imgcard{
    align-self:stretch;
    max-width:none;
    margin-inline:0;
  }

  body.single-product .bt-pdp-packimg{
    align-self:center;
    justify-self:center;
    width:150px;
  }
}

/* ════════ 768-1023px — tablet ════════
   Ends at 1023px, not at 1199px: 1024px is where header.php swaps the
   hamburger bar for the full desktop nav, so this is exactly the range
   that gets the tablet header. */
@media (min-width:768px) and (max-width:1023px){
  /* Full width at the TOP of the grid, a dropdown rather than the always-
     open desktop card, and not sticky — it sits above the content here,
     so there is nothing for it to stick alongside. */
  body.single-product .bt-pdp-cats{position:static}

  /* Two columns inside the panel: the card runs the full page width in
     this range, so a single file of rows would make the open dropdown
     needlessly tall. Same rows, same component, two tracks. */
  body.single-product .bt-pdp-cats__list{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:4px 12px;
  }

  body.single-product .bt-pdp-title{font-size:28px}

  /* Same step down the rail already takes at this width. */
  body.single-product .bt-pdp-thumbs{--pdp-thumb-size:74px}

  /* The same four-column table as desktop, a little tighter so its head
     row still fits the 3fr column without wrapping. */
  body.single-product .bt-pdp-pack__th,
  body.single-product .bt-pdp-pack__cell{padding-left:10px;padding-right:10px}
  body.single-product .bt-pdp-pack__name{font-size:var(--fs-small)}
  body.single-product .bt-pdp-pack__amount{font-size:15px}
}

/* ════════ >=1024px — desktop, 30 / 50 / 20 ════════
   1024px, not the 1200px this block used to carry: 1024 is the theme's
   own desktop crossover (.bt-header-desktop-row, .bt-cat-layout's
   sidebar, the catalogue grid going 3-up). Starting the three-column
   layout here is what stops 1024–1199px from showing the full desktop
   header above a tablet body. */
@media (min-width:1024px){
  body.single-product .bt-product-grid{
    grid-template-columns:minmax(0,3fr) minmax(0,5fr) minmax(0,2fr);
    grid-template-areas:
      ".       pill   cats"
      "img     title  cats"
      "img     specs  cats"
      "thumbs  desc   cats"
      "thumbs  coupon cats"
      "packimg pack   cats";
    column-gap:24px;
    row-gap:20px;
  }

  body.single-product .bt-pdp-packimg{width:180px}

  /* Same offset the category archive's sidebar uses: the sticky header's
     height plus 20px of breathing room. */
  body.single-product .bt-pdp-cats{align-self:start;position:sticky;top:100px}

  /* No dropdown up here: the list is always open, the button and its disc
     are gone and the static heading takes over as the card's title, so
     nothing focusable is left that would not do anything. transition:none
     so a viewport dragged across 1024px does not animate the panel open. */
  /* 10px of lead-in above the title, desktop only. The base rule keeps
     margin:0 so the dropdown ranges are unaffected - and they hide this
     element anyway; the button below carries its own copy of the word
     there. */
  body.single-product .bt-pdp-cats__heading{display:block;margin-top:10px}
  body.single-product .bt-pdp-cats__toggle{display:none}
  body.single-product .bt-pdp-cats__panel{
    max-height:none;overflow:visible;padding-top:0;transition:none;
  }
}

/* 1024–1279px — the narrowest desktop. The 2fr cats column lands near
   200px here and the 5fr column near 500px, so the pack table keeps the
   tighter side padding the tablet range uses in order to hold its four
   columns. The category list is back to one row per line: the 768–1023
   two-column rule deliberately does not reach this range. */
@media (min-width:1024px) and (max-width:1279px){
  body.single-product .bt-pdp-pack__th,
  body.single-product .bt-pdp-pack__cell{padding-left:10px;padding-right:10px}
}

/* ════════ <=767px — phone ════════
   One column, in the order set on the base rule at the top of this
   block (cats first). The 16px of side padding is the container's own
   .px-4, not a rule here. */
@media (max-width:767px){
  body.single-product .bt-product-grid{row-gap:14px}

  body.single-product .bt-pdp-title{font-size:26px}

  /* A duplicate of the main image on one column. */
  body.single-product .bt-pdp-packimg{display:none}

  /* Square again (the >=768px stretch does not apply here) and capped, so
     the picture never eats the whole first screen on a tall phone and the
     pack table stays within reach. max-width:360px from the base rule
     already holds it in on a 390px viewport; the cap is what governs on
     anything wider than 340px of content. */
  body.single-product .bt-pdp-imgcard{
    aspect-ratio:1;
    max-height:340px;
  }

  /* 64px is the rail's own phone size. Centred rather than start-
     aligned because the image card above is max-width:360px with
     margin-inline:auto, so on anything wider than 360px of content the
     card is centred and a left-aligned strip would sit off its edge. */
  body.single-product .bt-pdp-thumbs{
    --pdp-thumb-size:64px;
    justify-content:center;
  }

  /* 42/58 rather than the desktop 40/60: the labels are the fixed, known
     strings and the values are what varies, so the extra 2% goes to the
     column that has to hold a long one without wrapping to three lines. */
  body.single-product .bt-pdp-specs__label{width:42%;padding:9px 12px;font-size:11px}
  body.single-product .bt-pdp-specs__value{width:58%;padding:9px 12px;font-size:var(--fs-xs)}

  body.single-product .bt-pdp-desc{padding:16px}

  /* Pack table — the SAME four-column table as desktop, black head row
     included, not a stack of cards. It used to collapse into one card per
     row here; the brief asks for the table itself, so this instead shrinks
     it until four columns fit a 360px viewport (328px of content inside
     the container's 16px gutters) with no sideways scroll:

     - table-layout:fixed + the three widths below - the name column takes
       whatever is left and wraps, instead of the browser handing the
       widest cell its content width and overflowing the row.
     - 6px side padding on head and body cells.
     - 14px type in the cells, --fs-xs uppercase in the head.
     - A 44px qty box and a 44px-tall Add button, which is the floor for a
       touch target and so is what the other two columns are sized around.

     Everything visual is still the desktop table's: --forest head, white
     uppercase head type, 1px --border row rules, the .is-first tint, the
     pill button. Only the measurements change. */
  body.single-product .bt-pdp-pack__table{table-layout:fixed}
  body.single-product .bt-pdp-pack__th,
  body.single-product .bt-pdp-pack__cell{padding-left:6px;padding-right:6px}
  body.single-product .bt-pdp-pack__th{padding-top:10px;padding-bottom:10px;font-size:9.5px;letter-spacing:.04em}
  body.single-product .bt-pdp-pack__cell{padding-top:10px;padding-bottom:10px}
  body.single-product .bt-pdp-pack__th:first-child,
  body.single-product .bt-pdp-pack__cell:first-child{padding-left:10px}
  body.single-product .bt-pdp-pack__th:last-child,
  body.single-product .bt-pdp-pack__cell:last-child{padding-right:10px}

  /* The three fixed columns; name gets the remainder. Set on the head
     cells because table-layout:fixed takes every column width from the
     first row, and the <th> row is it — the <td>s already carry
     __price/__qty/__add classes but those would be ignored here. */
  body.single-product .bt-pdp-pack__head th:nth-child(2){width:72px}
  body.single-product .bt-pdp-pack__head th:nth-child(3){width:56px}
  body.single-product .bt-pdp-pack__head th:nth-child(4){width:104px}

  body.single-product .bt-pdp-pack__name{font-size:14px;overflow-wrap:anywhere}
  body.single-product .bt-pdp-pack__amount{font-size:14px;white-space:normal}
  body.single-product .bt-pdp-pack__oos{font-size:10px}

  body.single-product .bt-pdp-qty{width:44px;min-height:44px;padding:8px 2px;font-size:14px}
  body.single-product .bt-pdp-pack__form{display:flex;width:100%}
  body.single-product .bt-pdp-pack__btn{
    width:100%;min-height:44px;padding:8px 6px;font-size:11px;
  }

  body.single-product .bt-pdp-buy{padding:16px}
  body.single-product .bt-pdp-buy__form{flex:1 1 100%}
}

/* ════════ <=420px — extra small ════════
   An existing theme breakpoint, and type/padding only: no block moves
   and no column count changes, the four pack columns simply give up
   their last few px so a 360px phone still has no sideways scroll. */
@media (max-width:420px){
  body.single-product .bt-pdp-title{font-size:23px}
  body.single-product .bt-pdp-desc{padding:14px}
  body.single-product .bt-pdp-cats__box{padding:14px}
  body.single-product .bt-pdp-pack__head th:nth-child(2){width:64px}
  body.single-product .bt-pdp-pack__head th:nth-child(4){width:92px}
  body.single-product .bt-pdp-pack__btn{padding:8px 4px;font-size:10.5px}
}
