/* ============================================================================
   PLATFORM CONSISTENCY FIXES
   ----------------------------------------------------------------------------
   Loaded LAST on every public page, after style.css and the Elementor bundles,
   so it can correct them without editing the vendored theme.

   Fixes, in order:
     1. One scrollbar, not two
     2. The fixed header / 120px logo overlapping page content
     3. One type system across public site and consoles
     4. Consistent buttons
   ========================================================================== */


/* ---------------------------------------------------------------------------
   1. ONE SCROLLBAR
   ---------------------------------------------------------------------------
   #wrapper is `float:left; min-height:100%` inside a full-height body, which
   gives it its own scrollbar on top of the document's — two bars, side by side.

   Sixteen blades each carried a private <style> block hiding it, and every page
   added since did not, so the site was inconsistent page to page. The rule now
   lives here once and applies everywhere.
   ------------------------------------------------------------------------ */
#wrapper,
#wrapper.hasbg.transparent {
    -ms-overflow-style: none;   /* IE / old Edge */
    scrollbar-width: none;      /* Firefox */
}

#wrapper::-webkit-scrollbar,
#wrapper.hasbg.transparent::-webkit-scrollbar {
    display: none;              /* Chrome, Safari, Opera */
}

/* Nothing may push the page sideways — a stray wide element reads to the user as
   a second (horizontal) scrollbar.
 *
 * ONLY on <html>, never on <body>. Per CSS overflow, a box with `overflow-x:hidden`
 * and a visible `overflow-y` has its overflow-y computed to `auto` — so putting
 * this on body turns body into its own scroll container and it grows a second
 * vertical scrollbar beside the viewport's. That is a regression I introduced
 * here; <html> is already the viewport scroller, so it is the correct and only
 * place for this.
 */
html {
    overflow-x: hidden;
}


/* ---------------------------------------------------------------------------
   2. HEADER OVERLAP
   ---------------------------------------------------------------------------
   .main-menu-wrapper is `position:fixed; top:0`, and the logo inside it is a
   120x120 absolutely-positioned image, so the header occupies roughly 130px of
   the viewport while taking up no space in the flow. `#wrapper.hasbg.transparent`
   then forces `padding-top:0`.

   Theme pages get away with it because each one opens with a full-bleed hero
   whose own top padding clears the logo. Pages that open straight into content
   had the logo sitting on top of their first heading.
   ------------------------------------------------------------------------ */
/* Measured from the theme's own rules in custom-css.min.css, not estimated:
 *
 *   desktop   .elementor-element-6f23744 { top: 20px }  img { width: 130px }  -> 150px
 *   <=1024px  { top: 10px }                img { width: 100px }  -> 110px
 *   <=767px                                img { width:  68px }  ->  78px
 *
 * Plus breathing room, so a heading never sits tight under the logo.
 */
:root {
    --ac-header-h: 168px;
}

/* These pages DO each open with a dark hero band, but the hero's own top padding
   (64-96px) is less than the logo's reach, so the logo sat on the eyebrow and
   heading inside it.

   The padding goes on the hero, NOT on the page root: padding the root would
   push the hero itself down and leave a strip of background above it. */
.cat-wrap .cat-hero,
.ac-sf .ac-co__hero,
.ac-auth .ac-auth__hero {
    padding-top: calc(var(--ac-header-h) + 16px);
}

/* All 15 .ac-sf pages (checkout, claims, finder, reviews, trade) open with
   .ac-co__hero, so the hero rule above covers every one of them. No root-level
   fallback is needed — and adding one would double the offset. */

/* The banner on the supplier directory and supplier profile (both use Elementor
   section 1ef6e22). Its content is vertically centred in a min-height box that
   starts at y=0, so the top of the heading sat under the logo.

   Deliberately scoped to that one section id rather than to
   .elementor-section-height-min-height: the homepage alone has 22 of those, and
   padding them all would shift the entire page.

   The padding is now SYMMETRIC. The background paints the whole section, padding
   included, but the content is centred only within the container below the padding —
   so with top padding alone the eyebrow and title sat in the bottom third of the
   banner and read as bottom-aligned. Equal padding on both sides puts the optical
   centre of the band and the centre of the text in the same place, and the container
   min-height comes down to keep the overall height roughly where it was. */
.elementor-element-1ef6e22 {
    padding-top: var(--ac-header-h);
    padding-bottom: var(--ac-header-h);
}

/* The column inside carried a 40px top margin of its own, which re-broke the
   balance the symmetric padding just established. */
.custom-css-style .elementor-element.elementor-element-6fc77c4 > .elementor-element-populated {
    margin: 0;
}

/* Same breakpoints the theme itself uses for the logo, so the offset changes at
   exactly the moment the logo does. */
@media (max-width: 1024px) {
    :root { --ac-header-h: 128px; }
}

@media (max-width: 767px) {
    :root { --ac-header-h: 96px; }
}


/* ---------------------------------------------------------------------------
   3. TYPE — DELIBERATELY NOT TOUCHED
   ---------------------------------------------------------------------------
   This file previously overrode the public site's body and heading fonts to
   Inter/Fraunces. That was wrong and it changed how the live brochure pages look.

   The Craft theme already ships a complete, self-consistent type system and the
   last `body` rule in style.css wins the cascade:

       body                      var(--ci-font-body)  ->  Montserrat
       h1, h2                    bebas_neuebold        (public/assets/fonts)
       h3, .elementor-heading    arkipelagoregular     (public/assets/fonts)

   Verified against https://testlink.addcoffee.co.uk — the local site now computes
   exactly the same faces. Nothing here may set font-family on body, h1-h3 or any
   Elementor class. Marketplace-only components keep whatever they declare for
   themselves inside their own stylesheets.
   ------------------------------------------------------------------------ */


/* ---------------------------------------------------------------------------
   4. CONSISTENT BUTTONS
   ---------------------------------------------------------------------------
   Each section was styled in isolation, so the same "primary action" appeared as
   a terracotta pill on one page, a dark square on another and a bordered ghost on
   a third. These align the shared primitives on one shape, weight and palette
   without touching the theme's own .button class used by the brochure pages.
   ------------------------------------------------------------------------ */
.ac-btn,
.pg-btn,
.sp-btn,
.rp-btn,
.cv-vvisit,
.cv-visit-btn,
.cv-cta-btn,
.pv-btn {
    font-weight: 600;
    letter-spacing: .01em;
    text-decoration: none;
    transition: background-color .22s ease, color .22s ease,
                border-color .22s ease, transform .22s ease;
}

.ac-btn:hover,
.pg-btn:hover,
.sp-btn:hover,
.rp-btn:hover,
.cv-vvisit:hover,
.cv-visit-btn:hover,
.cv-cta-btn:hover,
.pv-btn:hover {
    text-decoration: none;
}

/* A disabled action must look disabled and refuse the pointer — several screens
   disable a submit until the form is valid and explain why underneath. */
.ac-btn[disabled],
.pg-btn[disabled],
.sp-btn[disabled],
.mv-btn[disabled] {
    opacity: .5;
    cursor: not-allowed;
    transform: none !important;
}

/* Focus is visible on every control, not just the ones a designer remembered. */
.ac-btn:focus-visible,
.pg-btn:focus-visible,
.sp-btn:focus-visible,
.rp-btn:focus-visible,
.cv-vvisit:focus-visible,
.cv-visit-btn:focus-visible,
.cv-cta-btn:focus-visible,
.pv-btn:focus-visible,
.sb-badge:focus-visible {
    outline: 2px solid #C18B57;
    outline-offset: 2px;
}


/* ---------------------------------------------------------------------------
   5. TABLES AND WIDE CONTENT
   ---------------------------------------------------------------------------
   Wide content scrolls inside its own box rather than widening the page, which
   is what produced a horizontal bar at the document level.
   ------------------------------------------------------------------------ */
.ac-sf table,
.cat-wrap table {
    max-width: 100%;
}

.ac-table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}


/* ---------------------------------------------------------------------------
   6. "ORGANIZATIONS AND TRUSTED VENDORS" CAROUSEL
   ---------------------------------------------------------------------------
   Three separate problems in this section:

     a) .cv-root had padding declared ONLY inside a max-width media query, so at
        desktop the section had none at all. "View All Suppliers" (margin-top:42px)
        ran straight into the section below it.

     b) The arrows were 52px translucent white circles with a backdrop blur,
        floating over the card faces at left:-6px / right:10px. They read as a
        default component rather than part of the design.

     c) The card meta row is small and low-contrast for what is the section's
        actual payload — who the supplier is and what they carry.
   ------------------------------------------------------------------------ */

/* (a) Real vertical rhythm, and room under the CTA. */
.cv-root {
    padding: 88px 20px 96px;
    position: relative;
}

.cv-cta-wrap {
    margin-top: 52px;
    padding-bottom: 4px;
}

/* (b) Arrows: solid ink discs sitting just outside the stage, gold on hover.
   Matches the sidebar/topbar language used across the marketplace rather than
   the frosted-glass default. */
.cv-arrow {
    width: 46px;
    height: 46px;
    border: 1px solid rgba(28, 26, 23, .14);
    background: #FFFDFA;
    backdrop-filter: none;
    color: #1C1A17;
    font-size: 13px;
    box-shadow: 0 6px 18px -8px rgba(28, 26, 23, .28);
}

.cv-arrow:hover {
    background: #1C1A17;
    border-color: #1C1A17;
    color: #D8A24A;
    box-shadow: 0 12px 26px -10px rgba(28, 26, 23, .45);
}

.cv-arrow:focus-visible {
    outline: 2px solid #C18B57;
    outline-offset: 3px;
}

/* Clear of the cards entirely on wide screens; tucked in only when there is no
   room, rather than always overlapping the artwork. */
@media (min-width: 1280px) {
    .cv-arrow-prev { left: -30px; }
    .cv-arrow-next { right: -30px; }
}

@media (min-width: 760px) and (max-width: 1279px) {
    .cv-arrow-prev { left: 4px; }
    .cv-arrow-next { right: 4px; }
}

/* (c) Meta row: the product count is the useful number here, so give it weight.
   It read "0 products" for every supplier until seller_profiles.product_count
   was actually maintained — see Product::syncSellerCount(). */
.cv-meta-row {
    padding-top: 14px;
    margin-top: 2px;
    border-top: 1px solid rgba(28, 26, 23, .08);
}

.cv-therapists {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 10px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: #1C1A17;
}

.cv-org-tag {
    font-size: 9.5px;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: #A8723F;
}

/* Dots: a touch larger so they are a usable target. */
.cv-dots { margin-top: 30px; }
.cv-dot { width: 10px; height: 10px; }
.cv-dot.cv-dot-active { width: 28px; }

@media (max-width: 767px) {
    .cv-root { padding: 56px 14px 72px; }
    .cv-cta-wrap { margin-top: 36px; }
}


/* ---------------------------------------------------------------------------
   7. SIGN-IN / SIGN-UP DROPDOWN
   ---------------------------------------------------------------------------
   The menu items are built as:

       <span>Sign up as a Buyer<small>Retailer, roaster or cafe</small></span>

   but nothing ever styled that <small>. Inline by default, it ran straight on
   from the label — "Sign up as a BuyerRetailer, roaster or cafe" — and because
   .dr-link is `align-items:center` the icon then sat against a two-line block it
   was not aligned to.
   ------------------------------------------------------------------------ */
.dr-link > span {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    line-height: 1.35;
}

.dr-link > span > small {
    display: block;
    font-size: 11px;
    font-weight: 400;
    line-height: 1.45;
    color: #7a7167;
    letter-spacing: .01em;
}

/* Icon aligns to the label, not to the middle of a two-line block. */
.dr-link {
    align-items: flex-start;
    padding-top: 8px;
    padding-bottom: 8px;
}

.dr-link i {
    margin-top: 2px;
    flex: 0 0 15px;
}

/* Description stays readable on hover, rather than turning terracotta with the
   label and losing the visual hierarchy between the two. */
.dr-link:hover > span > small {
    color: #a08a76;
}

/* Give the panel room now that each row is two lines. */
.dr-panel {
    min-width: 268px;
}


/* ---------------------------------------------------------------------------
   8. SUPPLIER PROFILE — REVIEWS
   ---------------------------------------------------------------------------
   .pv-reviews-head is `justify-content: space-between`, which pushed the heading
   hard left and the score block hard right with a gulf between them. With the
   certifications and contact sections removed the reviews block is the last thing
   on the page, so the imbalance was the first thing you saw.

   Centred as a single column, and the grid centres its own row when there are
   fewer cards than columns rather than leaving a hole on the right.
   ------------------------------------------------------------------------ */
.pv-reviews-head {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 22px;
}

.pv-reviews-head > div { text-align: center; }

.pv-reviews-summary {
    justify-content: center;
    padding: 16px 26px;
    border: 1px solid rgba(241, 234, 224, .14);
    border-radius: 10px;
}

.pv-review-grid {
    justify-content: center;
    /* Auto-fit so one or two reviews sit centred instead of stranded left. */
    grid-template-columns: repeat(auto-fit, minmax(280px, 340px));
}

.pv-section#pvReviews .pv-section-inner { display: flex; flex-direction: column; align-items: center; }
.pv-section#pvReviews .pv-review-grid,
.pv-section#pvReviews .pv-reviews-head { width: 100%; }

/* ============================================================================
   9. SUPPLIER PROFILE — SECTION WIDTH AND BANNER HEIGHT
   ----------------------------------------------------------------------------
   The marketplace sections (.pv-section) are dropped straight inside Elementor's
   .elementor-container, which is display:flex. A flex item shrinks to its content,
   so the reviews band measured 404px of the available 1170px and its centred inner
   column was centred inside *that* — which is why the section 8 centring rules above
   looked like they were doing nothing. The products band only looked right because
   its content happened to be wide enough to fill the row.

   Make every pv-section fill its flex row, and the centring works as written.
   ========================================================================== */
.elementor-container > .pv-section,
.elementor-container > .pv-hero {
    flex: 1 1 100%;
    width: 100%;
    min-width: 0;      /* flex items default to min-width:auto and refuse to shrink */
}

/* --- Banner ---------------------------------------------------------------
   Was 818px: 168px header offset plus a 650px min-height container, then a
   further 150px spacer section under it — roughly a screen and a half before any
   content. The header offset has to stay (it is what stops the logo overlapping),
   so the reducible part is the container.
   ------------------------------------------------------------------------ */
.custom-css-style .elementor-element.elementor-element-1ef6e22 > .elementor-container {
    min-height: 150px;
}

@media (max-width: 900px) {
    .custom-css-style .elementor-element.elementor-element-1ef6e22 > .elementor-container {
        min-height: 90px;
    }
}

/* The spacer section directly beneath the banner added another 150px of nothing. */
.custom-css-style .elementor-element.elementor-element-26e4125 > .elementor-container {
    min-height: 0;
}
.custom-css-style .elementor-element.elementor-element-26e4125 {
    padding-top: 0;
    padding-bottom: 0;
}


/* ============================================================================
   10. PASSWORD STRENGTH METER  (.pwm-*)
   ----------------------------------------------------------------------------
   Signup only told you the rule after you had already guessed wrong. This scores
   as you type and names the single most useful next change.
   ========================================================================== */
.pwm { margin-top: 10px; }
.pwm[hidden] { display: none; }

.pwm__bar {
    height: 4px;
    border-radius: 999px;
    background: #E7E0D6;
    overflow: hidden;
    margin-bottom: 7px;
}

.pwm__bar span {
    display: block;
    height: 100%;
    width: 0;
    border-radius: 999px;
    background: #B24B33;
    transition: width .25s ease, background .25s ease;
}

.pwm.is-bad   .pwm__bar span { background: #B24B33; }
.pwm.is-fair  .pwm__bar span { background: #D8A24A; }
.pwm.is-good  .pwm__bar span { background: #6E9A5C; }
.pwm.is-great .pwm__bar span { background: #4E7A52; }

.pwm__row {
    display: flex;
    align-items: baseline;
    gap: 9px;
    flex-wrap: wrap;
    font-size: 12px;
    margin-bottom: 8px;
}

.pwm__row strong { font-size: 12.5px; }
.pwm.is-bad   .pwm__row strong { color: #B24B33; }
.pwm.is-fair  .pwm__row strong { color: #A5713F; }
.pwm.is-good  .pwm__row strong,
.pwm.is-great .pwm__row strong { color: #4E7A52; }
.pwm__row span { color: #5C564D; }

.pwm__rules {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
}

.pwm__rules li {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11.5px;
    color: #8A8175;
    transition: color .2s ease;
}

.pwm__rules li i { font-size: 8px; }
.pwm__rules li.is-met { color: #4E7A52; }
.pwm__rules li.is-met i { font-size: 11px; }


/* ============================================================================
   11. QUOTE SCOPE CHOOSER  (.rfqto-*)
   ----------------------------------------------------------------------------
   Every request used to be open, because the form never sent seller_id. A buyer
   who asked one supplier about one lot had it broadcast to everyone. The choice
   is now explicit, and preselected to the supplier they were actually looking at.
   ========================================================================== */
.rfqto { margin: 0 0 22px; display: grid; gap: 10px; }

.rfqto__label {
    font-family: 'IBM Plex Mono', monospace;
    font-size: 9.5px;
    letter-spacing: .15em;
    text-transform: uppercase;
    color: #A8723F;
    margin-bottom: 2px;
}

.rfqto__opt { display: block; cursor: pointer; margin: 0; }
.rfqto__opt input { position: absolute; opacity: 0; pointer-events: none; }

.rfqto__box {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 15px 17px;
    border: 1px solid #E7E0D6;
    border-radius: 7px;
    background: #fff;
    transition: border-color .16s ease, box-shadow .16s ease;
}

.rfqto__opt:hover .rfqto__box { border-color: #C18B57; }

.rfqto__opt input:checked + .rfqto__box {
    border-color: #A5713F;
    box-shadow: 0 0 0 3px rgba(193, 139, 87, .16);
}

.rfqto__mark {
    width: 36px;
    height: 36px;
    flex: none;
    border-radius: 9px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #F1EAE0;
    color: #A5713F;
    font-size: 14px;
}

.rfqto__opt input:checked + .rfqto__box .rfqto__mark { background: #A5713F; color: #fff; }
.rfqto__text { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 0; }
.rfqto__text strong { font-size: 14px; color: #1C1A17; font-weight: 600; }
.rfqto__text small { font-size: 12.5px; line-height: 1.65; color: #5C564D; }

.rfqto__tick {
    width: 22px;
    height: 22px;
    flex: none;
    border-radius: 50%;
    border: 1px solid #D9D0C3;
    background: #fff;
    color: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    transition: all .16s ease;
}

.rfqto__opt input:checked + .rfqto__box .rfqto__tick { background: #A5713F; border-color: #A5713F; color: #fff; }

.rfqto--openonly {
    display: flex;
    align-items: flex-start;
    gap: 13px;
    padding: 15px 17px;
    border: 1px solid #E7E0D6;
    border-radius: 7px;
    background: #FBF8F4;
    font-size: 13px;
    line-height: 1.65;
    color: #5C564D;
}

.rfqto--openonly strong { color: #1C1A17; }


/* ============================================================================
   12. CHECKOUT — SAVE THIS ADDRESS
   ========================================================================== */
.ac-save {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    margin-top: 6px;
    padding: 13px 15px;
    border: 1px solid #E7E0D6;
    border-radius: 7px;
    background: #FBF8F4;
    cursor: pointer;
}

.ac-save[hidden] { display: none; }
.ac-save input { margin-top: 3px; flex: none; accent-color: #C18B57; }
.ac-save span { display: flex; flex-direction: column; gap: 3px; }
.ac-save strong { font-size: 13.5px; color: #1C1A17; }
.ac-save small { font-size: 12px; color: #5C564D; line-height: 1.55; }


/* ============================================================================
   13. TERMS MODAL  (.tcm-*)  and PRODUCT CARDS  (.pcard-*)
   ========================================================================== */
.tcm { position: fixed; inset: 0; z-index: 970; display: flex; align-items: center; justify-content: center; padding: 20px; }
.tcm[hidden] { display: none; }
.tcm__scrim { position: absolute; inset: 0; background: rgba(28, 26, 23, .58); }

.tcm__box {
    position: relative;
    width: min(680px, 100%);
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    background: #fff;
    border-radius: 8px;
    box-shadow: 0 22px 64px rgba(28, 26, 23, .34);
    overflow: hidden;
    font-family: 'Montserrat', sans-serif;
}

.tcm__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 22px 24px 16px; border-bottom: 1px solid #E7E0D6; }
.tcm__eyebrow { font-family: 'IBM Plex Mono', monospace; font-size: 9.5px; letter-spacing: .15em; text-transform: uppercase; color: #A8723F; }
.tcm__head h2 { font-size: 21px; margin: 6px 0 0; color: #1C1A17; text-transform: none; letter-spacing: normal; }
.tcm__x { width: 32px; height: 32px; border-radius: 50%; border: 0; cursor: pointer; background: #F1EAE0; color: #1C1A17; flex: none; }
.tcm__intro { padding: 16px 24px; background: #FBF8F4; border-bottom: 1px solid #E7E0D6; }
.tcm__intro p { margin: 0 0 12px; font-size: 13px; line-height: 1.65; color: #5C564D; }

.tcm__all {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 13px;
    font-weight: 600;
    color: #1C1A17;
    cursor: pointer;
}

.tcm__all input { accent-color: #A5713F; width: 17px; height: 17px; }
.tcm__body { overflow-y: auto; flex: 1; padding: 8px 24px 16px; }
.tcm__list { list-style: none; margin: 0; padding: 0; }
.tcm__list[hidden] { display: none; }
.tcm__item { border-bottom: 1px solid #F1EAE0; }
.tcm__item:last-child { border-bottom: 0; }
.tcm__item label { display: flex; align-items: flex-start; gap: 13px; padding: 15px 0; cursor: pointer; margin: 0; }
.tcm__item input { position: absolute; opacity: 0; pointer-events: none; }

.tcm__mark {
    width: 22px;
    height: 22px;
    flex: none;
    margin-top: 2px;
    border-radius: 5px;
    border: 1.5px solid #D9D0C3;
    background: #fff;
    color: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    transition: all .15s ease;
}

.tcm__item input:checked ~ .tcm__mark { background: #4E7A52; border-color: #4E7A52; color: #fff; }
.tcm__text { display: flex; flex-direction: column; gap: 5px; }
.tcm__text strong { font-size: 14px; color: #1C1A17; }
.tcm__text small { font-size: 12.5px; line-height: 1.7; color: #5C564D; }
.tcm__item input:checked ~ .tcm__text strong { color: #4E7A52; }
.tcm__foot { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 16px 24px; border-top: 1px solid #E7E0D6; background: #FBF8F4; flex-wrap: wrap; }
.tcm__count { font-family: 'IBM Plex Mono', monospace; font-size: 11.5px; color: #5C564D; }
.tcm__foot button[disabled] { opacity: .45; cursor: not-allowed; }

/* Accepting the clauses is the ONLY way to submit the signup form, so the confirm
   button must be reachable on a phone or registration is blocked outright.

   90vh is the wrong unit for that on mobile: vh is measured against the viewport
   with the URL bar retracted, so at rest the box is taller than what is actually on
   screen and the footer — with "Agree and continue" in it — sits below the fold with
   no way to scroll to it, because .tcm itself does not scroll. dvh tracks the real
   visible height; the vh line stays first as the fallback for older browsers. */
.tcm__box { max-height: 90vh; max-height: 88dvh; }

@media (max-width: 560px) {
    .tcm { padding: 12px; align-items: flex-end; }
    .tcm__box { border-radius: 8px 8px 0 0; }
    .tcm__head { padding: 18px 18px 14px; }
    .tcm__head h2 { font-size: 18px; }
    .tcm__intro,
    .tcm__body { padding-left: 18px; padding-right: 18px; }

    /* Stacked and full width: side-by-side these fell to ~140px each, under the
       comfortable tap size, on the one control the whole signup depends on. */
    .tcm__foot { flex-direction: column-reverse; align-items: stretch; gap: 10px; padding: 14px 18px; }
    .tcm__foot > div { display: flex; flex-direction: column-reverse; gap: 8px; }
    .tcm__foot .ac-btn { width: 100% !important; padding: 14px 18px !important; }
    .tcm__count { text-align: center; }
}

/* --- the agree row on the signup form --- */
.ac-terms { display: flex; align-items: flex-start; gap: 11px; margin: 6px 0 18px; font-size: 13px; color: #5C564D; }
.ac-terms input { margin-top: 2px; flex: none; accent-color: #A5713F; width: 16px; height: 16px; }
.ac-terms__link { background: none; border: 0; padding: 0; cursor: pointer; font: inherit; color: #A5713F; text-decoration: underline; }

/* --- catalogue cards --- */
.pcard {
    background: #fff;
    border: 1px solid #E7E0D6;
    border-radius: 8px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    transition: box-shadow .2s ease, transform .2s ease;
}

.pcard:hover { box-shadow: 0 8px 24px rgba(28, 26, 23, .12); transform: translateY(-3px); }
.pcard__media { position: relative; display: block; aspect-ratio: 4 / 3; background: #F1EAE0; }
.pcard__media img { width: 100%; height: 300px; object-fit: cover; display: block; }
.pcard__noimg { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 8px; color: #8A8175; font-size: 12px; }

.pcard__flag {
    position: absolute;
    left: 10px;
    top: 10px;
    padding: 4px 10px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .94);
    font-size: 10.5px;
    font-weight: 600;
    color: #1C1A17;
}

.pcard__flag--own { background: #1C1A17; color: #F1EAE0; }
.pcard__body { padding: 15px 16px 17px; display: flex; flex-direction: column; gap: 7px; flex: 1; }
.pcard__name { font-size: 15px; font-weight: 600; color: #1C1A17; text-decoration: none; line-height: 1.35; }
.pcard__name:hover { color: #A5713F; }
.pcard__desc { margin: 0; font-size: 12.5px; line-height: 1.6; color: #5C564D; }
.pcard__price { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; margin-top: auto; padding-top: 6px; }
.pcard__price strong { font-size: 19px; color: #A5713F; }
.pcard__price span { font-size: 12px; color: #8A8175; }
.pcard__moq { width: 100%; font-size: 11.5px; color: #8A8175; }
.pcard__acts { display: grid; gap: 8px; margin-top: 10px; }

.pcard__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 11px 14px;
    border-radius: 4px;
    border: 1px solid transparent;
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    transition: all .18s ease;
}

.pcard__btn--buy { background: #A5713F; color: #fff; }
.pcard__btn--buy:hover { background: #8C5C31; color: #fff; }
.pcard__btn--quote { background: #fff; border-color: #E7E0D6; color: #1C1A17; }
.pcard__btn--quote:hover { border-color: #C18B57; color: #A5713F; }

.pcard-empty {
    grid-column: 1 / -1;
    text-align: center;
    padding: 56px 24px;
    border: 1px dashed #D9D0C3;
    border-radius: 8px;
    background: #FBF8F4;
}

.pcard-empty i { font-size: 26px; color: #C18B57; opacity: .6; }
.pcard-empty h3 { font-size: 19px; color: #1C1A17; margin: 12px 0 6px; }
.pcard-empty p { font-size: 13px; color: #5C564D; max-width: 46ch; margin: 0 auto 16px; line-height: 1.7; }


/* --- catalogue grid ------------------------------------------------------
   The cards sit inside the Craft theme's .service-grid-content-wrapper, which
   lays its children out as full-bleed absolutely-positioned tiles. Our cards
   are ordinary blocks, so without this each one stretched to the full page
   width and the images rendered enormous.

   Scoped to a wrapper that actually contains a .pcard, so the theme's own
   service grids elsewhere on the site are untouched.
   ----------------------------------------------------------------------- */
.service-grid-content-wrapper:has(.pcard) {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 22px;
    padding: 0 24px 152px;
    max-width: 1280px;
    margin: 0 auto;
    height: auto !important;
}

.service-grid-content-wrapper:has(.pcard) > * { position: static !important; width: auto !important; }

/* Fallback for browsers without :has() — the cards carry their own max width. */
.pcard { max-width: 100%; }

@media (max-width: 640px) {
    .service-grid-content-wrapper:has(.pcard) { padding: 0 16px; gap: 16px; }
}


/* ============================================================================
   14. HOMEPAGE MARKETPLACE BANDS  (.mkt-*)
   ----------------------------------------------------------------------------
   Featured supplier products, featured suppliers, top rated products, top rated
   suppliers. Featured is a paid plan capability; top rated is earned on reviews.
   The two are separate bands with separate badges so a buyer can tell which is
   which — the previous single band mixed them and read as neither.
   ========================================================================== */
.mkt { padding: 72px 0; background: #fff; }
.mkt--cream { background: #FBF8F4; }
.mkt__inner { max-width: 1280px; margin: 0 auto; padding: 0 24px; }
.mkt__head { text-align: center; margin-bottom: 38px; }

.mkt__eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-family: 'IBM Plex Mono', monospace;
    font-size: 10px;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: #A8723F;
    margin-bottom: 12px;
}

.mkt__title { font-size: 36px; color: #1C1A17; margin: 0 0 12px; line-height: 1.15; }
.mkt__sub { max-width: 62ch; margin: 0 auto; font-size: 14.5px; line-height: 1.75; color: #5C564D; }
.mkt__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 22px; }
.mkt__grid--suppliers { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
.mkt__more { text-align: center; margin-top: 34px; }

.mkt-card {
    background: #fff;
    border: 1px solid #E7E0D6;
    border-radius: 8px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    transition: box-shadow .2s ease, transform .2s ease;
}

.mkt-card:hover { box-shadow: 0 10px 28px rgba(28, 26, 23, .12); transform: translateY(-3px); }
.mkt-card__media { position: relative; display: block; aspect-ratio: 4 / 3; background: #F1EAE0; }
.mkt-card__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mkt-card__noimg { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #8A8175; font-size: 22px; }

.mkt-badge {
    position: absolute;
    left: 10px;
    top: 10px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 11px;
    border-radius: 999px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .04em;
}

.mkt-badge--featured { background: #A5713F; color: #fff; }
.mkt-badge--rated { background: #1C1A17; color: #D8A24A; }
.mkt-card__body { padding: 15px 16px 17px; display: flex; flex-direction: column; gap: 7px; flex: 1; }
.mkt-card__name { font-size: 15px; font-weight: 600; color: #1C1A17; text-decoration: none; line-height: 1.35; }
.mkt-card__name:hover { color: #A5713F; }
.mkt-card__by { font-size: 12px; color: #8A8175; text-decoration: none; }
.mkt-card__by:hover { color: #A5713F; }
.mkt-card__by .fa-circle-check { color: #3E7BC4; font-size: 11px; }
.mkt-card__stars { display: flex; align-items: center; gap: 4px; font-size: 11px; color: #D8A24A; }
.mkt-card__stars small { color: #8A8175; margin-left: 4px; font-size: 11.5px; }
.mkt-card__price { margin-top: auto; padding-top: 6px; font-size: 18px; font-weight: 600; color: #A5713F; }
.mkt-card__price small { font-size: 11.5px; font-weight: 400; color: #8A8175; }
.mkt-card__acts { display: grid; grid-template-columns: 1fr auto; gap: 8px; margin-top: 10px; }

.mkt-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 11px 16px;
    border-radius: 4px;
    border: 1px solid transparent;
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    transition: all .18s ease;
}

.mkt-btn--buy { background: #A5713F; color: #fff; }
.mkt-btn--buy:hover { background: #8C5C31; color: #fff; }
.mkt-btn--line { background: #fff; border-color: #E7E0D6; color: #1C1A17; }
.mkt-btn--line:hover { border-color: #C18B57; color: #A5713F; }

.mkt-sup {
    position: relative;
    display: flex;
    align-items: start;
    gap: 15px;
    padding: 20px;
    background: #fff;
    border: 1px solid #E7E0D6;
    border-radius: 8px;
    text-decoration: none;
    transition: box-shadow .2s ease, border-color .2s ease;
}

.mkt-sup:hover { box-shadow: 0 8px 22px rgba(28, 26, 23, .1); border-color: #C18B57; }

.mkt-sup__logo {
    width: 58px;
    height: 58px;
    flex: none;
    border-radius: 12px;
    overflow: hidden;
    background: #F1EAE0;
    color: #A5713F;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    font-weight: 700;
}

.mkt-sup__logo img { width: 100%; height: 100%; object-fit: cover; }
.mkt-sup__body { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1; }
.mkt-sup__body strong { font-size: 15px; color: #1C1A17; }
.mkt-sup__tick { color: #3E7BC4; font-size: 12px; margin-left: 4px; }
.mkt-sup__where { font-size: 12px; color: #8A8175; }
.mkt-sup__where i { margin-right: 5px; }
.mkt-sup .mkt-badge { position: static; flex: none; }

@media (max-width: 640px) {
    .mkt { padding: 48px 0; }
    .mkt__inner { padding: 0 16px; }
    .mkt__title { font-size: 27px; }
    .mkt-card__acts { grid-template-columns: 1fr; }
}


/* ============================================================================
   15. NAV BASKET, BASKET PAGE (.crt-*) AND RECOMMENDATIONS (.rec-*)
   ----------------------------------------------------------------------------
   There was no basket page and no way to reach a basket from the navigation —
   the drawer only appeared after adding something, so a returning visitor had
   no route back to it.
   ========================================================================== */
.nav-basket { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; color: inherit; }
.nav-basket:hover { color: #D8A24A; }
.nav-basket i { font-size: 17px; }

.nav-basket__count {
    position: absolute;
    top: 2px;
    right: 0;
    min-width: 17px;
    height: 17px;
    padding: 0 5px;
    border-radius: 999px;
    background: #A5713F;
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 17px;
    text-align: center;
}

.crt { background: #FBF8F4; padding: 122px 0 72px; font-family: 'Plus Jakarta Sans', sans-serif; }
.crt__inner { max-width: 1240px; margin: 0 auto; padding: 0 24px; }
.crt__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; flex-wrap: wrap; margin-bottom: 26px; }
.crt__eyebrow { font-family: 'IBM Plex Mono', monospace; font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: #A8723F; }
.crt__title { font-size: 34px; font-weight: 600; color: #1C1A17; margin: 8px 0 6px; text-transform: none; letter-spacing: -.02em; }
.crt__sub { margin: 0; font-size: 14px; color: #5C564D; }
.crt__grid { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 24px; align-items: start; }
.crt-loading { padding: 40px; text-align: center; color: #8A8175; font-size: 13.5px; }

.crt-line {
    display: grid;
    grid-template-columns: 88px minmax(0, 1fr) auto auto auto;
    gap: 16px;
    align-items: center;
    background: #fff;
    border: 1px solid #E7E0D6;
    border-radius: 8px;
    padding: 16px;
    margin-bottom: 12px;
}

.crt-line__img { width: 88px; height: 88px; border-radius: 7px; overflow: hidden; background: #F1EAE0; display: flex; align-items: center; justify-content: center; color: #8A8175; }
.crt-line__img img { width: 100%; height: 100%; object-fit: cover; }
.crt-line__body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.crt-line__name { font-size: 15px; font-weight: 600; color: #1C1A17; text-decoration: none; }
.crt-line__name:hover { color: #A5713F; }
.crt-line__meta { font-size: 12px; color: #8A8175; }
.crt-line__bundle { font-size: 11.5px; color: #4E7A52; font-weight: 600; }
.crt-line__qty { display: flex; align-items: center; gap: 6px; }

.crt-line__qty button {
    width: 30px; height: 30px; border: 1px solid #E7E0D6; background: #fff;
    border-radius: 4px; cursor: pointer; font-size: 15px; color: #1C1A17;
}

.crt-line__qty button:hover { border-color: #C18B57; }
.crt-line__qty input { width: 54px; text-align: center; padding: 7px 4px; border: 1px solid #E7E0D6; border-radius: 4px; font-size: 14px; }
.crt-line__qty input::-webkit-outer-spin-button, .crt-line__qty input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.crt-line__unit { font-size: 12px; color: #8A8175; }
.crt-line__money { text-align: right; display: flex; flex-direction: column; gap: 3px; }
.crt-line__money strong { font-size: 17px; color: #1C1A17; }
.crt-line__money span { font-size: 11.5px; color: #8A8175; }
.crt-line__x { width: 32px; height: 32px; border: 0; background: none; cursor: pointer; color: #B24B33; opacity: .65; border-radius: 50%; }
.crt-line__x:hover { opacity: 1; background: rgba(178, 75, 51, .08); }

.crt-problem {
    display: flex; gap: 11px; padding: 14px 16px; margin-bottom: 12px;
    background: rgba(216, 162, 74, .1); border: 1px solid rgba(216, 162, 74, .35);
    border-radius: 7px; font-size: 13px; line-height: 1.6; color: #5C564D;
}

.crt-problem i { color: #A8723F; margin-top: 2px; }
.crt-empty { background: #fff; border: 1px dashed #D9D0C3; border-radius: 8px; padding: 60px 28px; text-align: center; }
.crt-empty i { font-size: 30px; color: #C18B57; opacity: .55; }
.crt-empty h2 { font-size: 22px; margin: 14px 0 8px; color: #1C1A17; text-transform: none; }
.crt-empty p { font-size: 14px; color: #5C564D; max-width: 48ch; margin: 0 auto 20px; line-height: 1.7; }
.crt-empty__acts { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

.crt-sum { background: #fff; border: 1px solid #E7E0D6; border-radius: 8px; padding: 24px; position: sticky; top: 122px; }
.crt-sum h2 { font-size: 18px; margin: 0 0 18px; color: #1C1A17; text-transform: none; }
.crt-sum__row { display: flex; justify-content: space-between; gap: 14px; padding: 9px 0; font-size: 14px; color: #5C564D; }
.crt-sum__row strong { color: #1C1A17; }
.crt-sum__row--save strong { color: #4E7A52; }
.crt-sum__row--total { border-top: 1px solid #E7E0D6; margin-top: 6px; padding-top: 15px; }
.crt-sum__row--total strong { font-size: 24px; }
.crt-sum__note { font-size: 12px; color: #8A8175; line-height: 1.6; margin: 10px 0 18px; }
.crt-sum__trust { list-style: none; margin: 18px 0 0; padding: 18px 0 0; border-top: 1px solid #E7E0D6; display: grid; gap: 10px; }
.crt-sum__trust li { display: flex; gap: 9px; font-size: 12px; color: #5C564D; line-height: 1.5; }
.crt-sum__trust i { color: #4E7A52; margin-top: 2px; }

.crt-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    padding: 12px 20px; border-radius: 4px; border: 1px solid transparent;
    font-size: 13px; font-weight: 600; cursor: pointer; text-decoration: none;
    transition: all .18s ease;
}

.crt-btn--buy { background: #A5713F; color: #fff; }
.crt-btn--buy:hover { background: #8C5C31; color: #fff; }
.crt-btn--line { background: #fff; border-color: #E7E0D6; color: #1C1A17; }
.crt-btn--line:hover { border-color: #C18B57; color: #A5713F; }
.crt-btn--full { width: 100%; }

/* --- recommendations --- */
.rec { margin-bottom: 46px; }
.rec__head { margin-bottom: 20px; }
.rec__head h2 { font-size: 23px; color: #1C1A17; margin: 0 0 6px; text-transform: none; }
.rec__head p { margin: 0; font-size: 13.5px; color: #5C564D; padding: 0px !important; }
.rec__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 18px; }
.rec-card { background: #fff; border: 1px solid #E7E0D6; border-radius: 8px; overflow: hidden; display: flex; flex-direction: column; transition: box-shadow .2s ease; }
.rec-card:hover { box-shadow: 0 6px 20px rgba(28, 26, 23, .1); }
/* The media box is a FIXED frame, never sized by the photograph inside it.
 *
 * .rec-card is a column flex container, so .rec-card__media was a flex item whose main
 * size (its height) resolved from its content. aspect-ratio cannot win that on its own:
 * the <img> asked for height:100% against an indefinite height, fell back to the image's
 * intrinsic height, and the frame took whatever height that photograph happened to be.
 * A row of "you may also like" cards therefore had a different image height in every
 * card and the names and prices below them never lined up.
 *
 * flex:none stops the item flexing, and an explicit aspect-ratio on a definite width
 * makes the height definite — so the img's height:100% has something real to resolve
 * against. The percentage padding is the fallback for anything without aspect-ratio. */
.rec-card__media {
    display: block;
    position: relative;
    flex: none;
    width: 100%;
    aspect-ratio: 4 / 3;
    background: #F1EAE0;
    overflow: hidden;
}

@supports not (aspect-ratio: 4 / 3) {
    .rec-card__media { height: 0; padding-bottom: 75%; }
}

.rec-card__media img {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.rec-card__noimg { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #8A8175; }
.rec-card__body { padding: 13px 14px 15px; display: flex; flex-direction: column; gap: 5px; flex: 1; }
.rec-card__name { font-size: 14px; font-weight: 600; color: #1C1A17; text-decoration: none; line-height: 1.35; }
.rec-card__name:hover { color: #A5713F; }
.rec-card__by { font-size: 11.5px; color: #8A8175; }
.rec-card__price { margin-top: auto; padding-top: 4px; font-size: 15px; font-weight: 600; color: #A5713F; }
.rec-card__price small { font-size: 11px; font-weight: 400; color: #8A8175; }

.rec-btn {
    margin-top: 9px; width: 100%; padding: 9px 12px; border: 1px solid #E7E0D6;
    background: #fff; border-radius: 4px; cursor: pointer;
    font-size: 12px; font-weight: 600; color: #1C1A17;
    display: inline-flex; align-items: center; justify-content: center; gap: 7px;
}

.rec-btn:hover { border-color: #C18B57; color: #A5713F; }

.rec-bundle {
    display: flex; flex-direction: column; gap: 5px;
    background: #fff; border: 1px solid #E7E0D6; border-left: 3px solid #4E7A52;
    border-radius: 8px; padding: 18px; text-decoration: none;
}

.rec-bundle strong { font-size: 15px; color: #1C1A17; }
.rec-bundle__save { align-self: flex-start; padding: 3px 9px; border-radius: 999px; background: rgba(78, 122, 82, .13); color: #4E7A52; font-size: 10.5px; font-weight: 700; }

@media (max-width: 900px) {
    .crt__grid { grid-template-columns: 1fr; }
    .crt-sum { position: static; }
}

@media (max-width: 680px) {
    .crt { padding: 96px 0 48px; }
    .crt-line { grid-template-columns: 64px minmax(0, 1fr) auto; row-gap: 12px; }
    .crt-line__img { width: 64px; height: 64px; }
    .crt-line__qty { grid-column: 2 / 3; }
    .crt-line__money { grid-column: 3 / 4; }
    .crt-line__x { grid-row: 1; grid-column: 3; justify-self: end; }
}


/* ============================================================================
   16. MARKETPLACE BANDS — PREMIUM REBUILD  (overrides section 14)
   ----------------------------------------------------------------------------
   The first pass used 250px cards in an auto-fill grid, which on a wide screen
   produced five or six cramped tiles per row — small photography, tight type,
   and nothing that read as a premium export marketplace.

   This rebuild: fewer, larger cards, a taller image, real typographic hierarchy,
   generous spacing, and a hairline-and-shadow treatment rather than a plain box.
   Section 14 is left in place as the base; everything below refines it.
   ========================================================================== */

.mkt { padding: 72px 0; }
.mkt__inner { max-width: 1340px; padding: 0 32px; }

/* --- heading block ------------------------------------------------------- */
.mkt__head { margin-bottom: 52px; }

.mkt__eyebrow {
    gap: 9px;
    font-size: 10.5px;
    letter-spacing: .24em;
    margin-bottom: 16px;
    padding: 7px 16px;
    border: 1px solid rgba(193, 139, 87, .34);
    border-radius: 999px;
    background: rgba(193, 139, 87, .07);
}

.mkt__title {
    font-size: clamp(30px, 3.4vw, 46px);
    letter-spacing: -.025em;
    font-weight: 600;
    margin-bottom: 16px;
}

.mkt__sub { font-size: 16px; line-height: 1.8; max-width: 58ch; padding: 0px !important; }

/* A hairline under the heading, centred, to separate head from grid. */
.mkt__head::after {
    content: '';
    display: block;
    width: 54px;
    height: 2px;
    margin: 26px auto 0;
    background: linear-gradient(90deg, transparent, #C18B57, transparent);
}

/* --- product cards ------------------------------------------------------- */
/* Four across at most, so each card has room to breathe. */
.mkt__grid {
    grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
    gap: 30px;
}



.mkt-card {
    border: 1px solid #EDE6DC;
    border-radius: 14px;
    box-shadow: 0 1px 2px rgba(28, 26, 23, .04);
    transition: box-shadow .28s cubic-bezier(.22, .61, .36, 1),
                transform .28s cubic-bezier(.22, .61, .36, 1),
                border-color .28s;
}

.mkt-card:hover {
    box-shadow: 0 18px 44px rgba(28, 26, 23, .14);
    transform: translateY(-6px);
    border-color: #DCCFBC;
}

/* Taller than 4:3 — product photography is the reason to stop scrolling. */
.mkt-card__media { aspect-ratio: 1 / 1; overflow: hidden; }
.mkt-card__media img { transition: transform .6s cubic-bezier(.22, .61, .36, 1); }
.mkt-card:hover .mkt-card__media img { transform: scale(1.06); }
.mkt-card__noimg { font-size: 30px; }

.mkt-badge {
    left: 14px;
    top: 14px;
    padding: 7px 14px;
    font-size: 10px;
    letter-spacing: .1em;
    text-transform: uppercase;
    backdrop-filter: blur(6px);
    box-shadow: 0 2px 10px rgba(28, 26, 23, .2);
}

.mkt-badge--featured { background: rgba(165, 113, 63, .96); }
.mkt-badge--rated { background: rgba(28, 26, 23, .92); }

.mkt-card__body { padding: 24px 22px 26px; gap: 10px; justify-content: space-between; }

.mkt-card__name {
    font-size: 18px;
    line-height: 1.35;
    letter-spacing: -.01em;
    font-weight: 600;
}

.mkt-card__by { font-size: 12.5px; letter-spacing: .01em; }
.mkt-card__stars i { font-size: 12px; }
.mkt-card__stars small { font-size: 12px; }

.mkt-card__price {
    padding-top: 14px;
    margin-top: 14px;
    border-top: 1px solid #F1EAE0;
    font-size: 23px;
    letter-spacing: -.02em;
}

.mkt-card__price small { font-size: 12.5px; }
.mkt-card__acts { margin-top: 16px; gap: 10px; }

.mkt-btn {
    padding: 14px 20px;
    border-radius: 6px;
    font-size: 13px;
    letter-spacing: .01em;
}

.mkt-btn--buy { box-shadow: 0 2px 8px rgba(165, 113, 63, .28); }
.mkt-btn--buy:hover { box-shadow: 0 5px 16px rgba(165, 113, 63, .36); transform: translateY(-1px); }

/* --- supplier cards ------------------------------------------------------ */
.mkt-sup {
    padding: 30px;
    border-radius: 14px;
    border-color: #EDE6DC;
    gap: 8px;
    box-shadow: 0 1px 2px rgba(28, 26, 23, .04);
    transition: box-shadow .28s cubic-bezier(.22, .61, .36, 1),
                transform .28s cubic-bezier(.22, .61, .36, 1),
                border-color .28s;
}

.mkt-sup:hover { transform: translateY(-5px); box-shadow: 0 18px 44px rgba(28, 26, 23, .13); }

.mkt-sup__logo {
    width: 76px;
    height: 76px;
    border-radius: 16px;
    font-size: 28px;
    border: 1px solid #EDE6DC;
}

.mkt-sup__body { gap: 7px; }
.mkt-sup__body strong { font-size: 18px; letter-spacing: -.01em; }
.mkt-sup__where { font-size: 13px; }
.mkt-sup .mkt-badge { align-self: flex-start; }

/* --- footer link --------------------------------------------------------- */
.mkt__more { margin-top: 48px; }
.mkt__more .mkt-btn { padding: 15px 34px; font-size: 13.5px; }

/* --- narrow -------------------------------------------------------------- */
@media (max-width: 900px) {
    .mkt { padding: 64px 0; }
    .mkt__inner { padding: 0 20px; }
    .mkt__head { margin-bottom: 36px; }
    .mkt__grid { gap: 20px; }
    .mkt-card__body { padding: 20px 18px 22px; }
}

@media (max-width: 560px) {
    .mkt__grid { grid-template-columns: 1fr; }
    .mkt__grid--suppliers { grid-template-columns: 1fr; }
    .mkt-sup { padding: 22px; }
    .mkt-card__acts { grid-template-columns: 1fr; }
}


/* ============================================================================
   17. MARKETPLACE BANDS — FULL BLEED AND SENSIBLE CARD WIDTHS
   ----------------------------------------------------------------------------
   Two faults the first pass left:

   1. The bands sat inside the Craft theme's content column, capped at 1170px,
      while every other homepage section breaks out to the full viewport. That
      is why they read as a narrow strip down the middle of the page.

   2. The grid used repeat(4, 1fr), which divides the row by the COLUMN COUNT
      rather than sizing to the content — so a band holding one product still
      cut the row into quarters and rendered a 254px card.

   Now: full-bleed like the sections around them, and an auto-fill track with a
   real maximum so cards are ~340px whether there is one of them or eight, and
   a short row centres instead of stretching.
   ========================================================================== */
/*
 * NOT full-bleed.
 *
 * The 100vw + calc(50% - 50vw) trick only lands correctly when the parent is itself
 * centred in the viewport. The Craft content column is not — it starts at x=333 of
 * 1905 — so the band was shifted 439px left, hanging off the left edge and leaving a
 * bare strip down the right. Measured: band 1920px wide starting at -439.
 *
 * The band now sits in the content column like every other section on the page, which
 * is also more consistent than making these four the only full-width ones.
 */
.mkt { position: relative; }
.mkt__inner { max-width: 1440px; margin: 0 auto; padding: 0 40px; }

/* --- logo overhang ------------------------------------------------------
   The header is 94px tall and the logo is a 130px circle sitting at top 67,
   so it hung 103px below the bar and landed on the banner headline of every
   inner page. Smaller, and pulled up, so it still overlaps the bar as the
   design intends without reaching the banner text.
   --------------------------------------------------------------------- */
#elementor-header .elementor-widget-image img {
    max-width: 88px;
    height: auto;
    margin-top: -28px;
}

@media (max-width: 900px) {
    #elementor-header .elementor-widget-image img { max-width: 66px; margin-top: -20px; }
}

.mkt__grid {
    grid-template-columns: repeat(auto-fit, minmax(290px, 340px));
    justify-content: center;
    gap: 26px;
}

.mkt__grid--suppliers {
    grid-template-columns: repeat(auto-fit, minmax(320px, 420px));
    gap: 24px;
}

/* Headings follow the site's own display face, so they belong to the page
   rather than looking like a bolted-on widget. */
.mkt__title { font-family: inherit; }

@media (max-width: 900px) {
    .mkt__inner { padding: 0 20px; }
    .mkt__grid { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
    .mkt__grid--suppliers { grid-template-columns: 1fr; }
}


/* ============================================================================
   18. NAV BASKET — VISIBILITY AND ALIGNMENT
   ----------------------------------------------------------------------------
   Two faults in the first attempt:

   1. color:inherit resolved to black, so on the transparent header over a dark
      hero the basket was invisible. The header's own links are cream there and
      dark once .page-account gives it a solid background, so the icon has to
      follow the same two states rather than inherit.

   2. The extra widget pushed the header row to 102px and dropped the search and
      sign-in controls onto a second line. It needs to sit in the same flex row
      as its neighbours rather than as a full-height block.
   ========================================================================== */
.nav-basket {
    width: 34px;
    height: 34px;
    color: #F1EAE0;
    flex: none;
    align-self: center;
}

.nav-basket i { font-size: 16px; }
.nav-basket:hover { color: #D8A24A; }

/* Solid-header pages (the buyer account) put dark text on a light bar. */
.page-account .nav-basket { color: #F1EAE0; }

/* Keep the widget inline with the search and sign-in controls. */
.nav-basket__widget { display: flex; align-items: center; }
.nav-basket__widget .elementor-widget-container { display: flex; align-items: center; }


/* ============================================================================
   19. SOLID HEADER ON APPLICATION PAGES
   ----------------------------------------------------------------------------
   This rule previously lived in buyer-account.css and used --ts-ink, a token
   that file declares on .bac. Neither is present on /cart, so the header stayed
   transparent over a light page and the navigation was unreadable.

   Moved here (loaded on every page) with literal colours, so any page passing
   bodyClass="page-account" gets a legible header.
   ========================================================================== */
.page-account #elementor-header {
    background: #1C1A17;
    box-shadow: 0 1px 0 rgba(255, 255, 255, .07);
}

.page-account #elementor-header > * a:not(.dr-panel a):not(.sub-menu a),
.page-account #elementor-header .elementor-heading-title,
.page-account #elementor-header .navigation > li > a { color: #F1EAE0; }
.page-account #elementor-header a:hover,
.page-account #elementor-header .navigation > li > a:hover { color: #D8A24A; }


/* ============================================================================
   20. CART PAGE OVERFLOW, BASKET PLACEMENT, DROPDOWN COLOUR
   ----------------------------------------------------------------------------
   Three faults found by measuring the live page:

   1. The theme uses box-sizing: content-box. "width:100%" on .crt-btn--full
      therefore meant 100% PLUS 40px padding plus 2px border, so Proceed to
      checkout overhung its card by 17px. Every component I added needs
      border-box explicitly — it cannot be assumed here.

   2. The basket was inserted before the search widget, which put it in the
      social-icon row rather than on the Sign in line.

   3. ".page-account #elementor-header a { color:#F1EAE0 }" was colouring every
      anchor in the header, including the items inside the Sign in dropdown
      panel, which has its own background. The rule now excludes that panel.
   ========================================================================== */
.crt *,
.crt *::before,
.crt *::after,
.rec *,
.mkt *,
.pcard * { box-sizing: border-box; }

.crt-btn, .rec-btn, .mkt-btn, .pcard__btn { box-sizing: border-box; }
.crt-btn--full { width: 100%; }

/* Basket, on the Sign in line. */
.dr-wrap { display: inline-flex; align-items: center; }

.nav-basket {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    margin-right: 10px;
    flex: none;
    color: #F1EAE0;
    box-sizing: border-box;
}

.nav-basket i { font-size: 16px; }
.nav-basket:hover { color: #D8A24A; }

/* The dropdown panel supplies its own colours — the header rule must not reach in. */
.page-account #elementor-header .dr-panel a,
.page-account #elementor-header .dr-panel button,
.page-account #elementor-header .sub-menu a {
    color: inherit;
}


/* ============================================================================
   21. BUNDLE CARDS  (.bdl-*)
   ----------------------------------------------------------------------------
   The first version was a bare link with no member images, no contents list and
   no way to buy it. A bundle is a set of goods — it has to show what is in it.
   ========================================================================== */
.bdl {
    display: flex;
    flex-direction: column;
    background: #fff;
    border: 1px solid #E7E0D6;
    border-radius: 10px;
    overflow: hidden;
    box-sizing: border-box;
    transition: box-shadow .2s ease, border-color .2s ease;
}

.bdl:hover { box-shadow: 0 8px 24px rgba(28, 26, 23, .1); border-color: #DCCFBC; }
.bdl__imgs { display: grid; grid-template-columns: repeat(2, 1fr); gap: 2px; background: #F1EAE0; }
.bdl__imgs .bdl__img:only-child { grid-column: 1 / -1; aspect-ratio: 2 / 1; }

.bdl__img {
    position: relative;
    aspect-ratio: 1;
    background: #F1EAE0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #8A8175;
    overflow: hidden;
}

.bdl__img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bdl__img--more { background: #1C1A17; color: #F1EAE0; font-weight: 700; font-size: 15px; }
.bdl__body { padding: 18px 20px 20px; display: flex; flex-direction: column; gap: 9px; flex: 1; }

.bdl__save {
    align-self: flex-start;
    padding: 4px 11px;
    border-radius: 999px;
    background: rgba(78, 122, 82, .13);
    color: #4E7A52;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .04em;
}

.bdl__name { font-size: 16px; color: #1C1A17; line-height: 1.35; }
.bdl__list { list-style: none; margin: 2px 0 0; padding: 0; display: grid; gap: 5px; }

.bdl__list li {
    display: flex;
    gap: 8px;
    font-size: 12.5px;
    color: #5C564D;
    line-height: 1.5;
}

.bdl__list i { color: #4E7A52; font-size: 10px; margin-top: 4px; flex: none; }
.bdl__price { display: flex; align-items: baseline; gap: 10px; margin-top: auto; padding-top: 12px; border-top: 1px solid #F1EAE0; }
.bdl__price strong { font-size: 21px; color: #A5713F; font-weight: 600; }
.bdl__price small { font-size: 13px; color: #8A8175; text-decoration: line-through; }

.bdl__btn {
    margin-top: 12px;
    width: 100%;
    box-sizing: border-box;
    padding: 12px 16px;
    border: 0;
    border-radius: 5px;
    background: #A5713F;
    color: #fff;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    transition: background .18s ease;
}

.bdl__btn:hover { background: #8C5C31; }


/* ============================================================================
   22. BASKET + SIGN IN ON ONE LINE
   ----------------------------------------------------------------------------
   The basket and the Sign in dropdown are siblings inside a single
   .elementor-widget-container that is display:block and 112px wide. They
   therefore stacked, and "SIGN IN" broke onto two lines.

   Make just that container a nowrap flex row and let it size to its content.
   :has() targets it without needing a class on Elementor's generated markup.
   ========================================================================== */
.elementor-widget-container:has(> .nav-basket) {
    display: flex;
    align-items: center;
    gap: 14px;
    width: max-content;
    white-space: nowrap;
}

/* The widget itself must not clamp the row it now contains. */

.dr-trigger { white-space: nowrap; }
.nav-basket { margin-right: 0; }


/* width:max-content collapsed the widget, so the search / basket / sign-in group
   rode up to the top of the header row instead of sitting on its centre line.
   Centre the group within the column it lives in. */
.elementor-widget-wrap:has(.nav-basket) {
    align-items: center;
    align-content: center;
}

.elementor-element:has(> .elementor-widget-container > .nav-basket) { align-self: center; }


/* The search icon sits in its own widget and rode high of the basket / sign-in /
   phone line (centre 13 against 45). One rule brings the whole right-hand group
   onto a single centre line. */
.craftcoffee-search-icon {
    display: flex;
    align-items: center;
    min-height: 40px;
}

.elementor-widget-craftcoffee-search { align-self: center; }
.elementor-widget-craftcoffee-search > .elementor-widget-container { display: flex; align-items: center; min-height: 40px; }


/* ============================================================================
   23. HEADER — CENTRED LOGO, PROMINENT SEARCH AND BASKET
   ----------------------------------------------------------------------------
   The three header columns are flex: 0 1 auto, i.e. sized to their content. The
   logo was therefore only ever centred by coincidence: with a 596px nav on the
   left and a 373px group on the right, it sat exactly 112px — half the 223px
   imbalance — left of centre.

   Giving the outer two columns equal flex and letting the logo size to itself
   centres it by construction, at any viewport and whatever the nav contains.
   The phone column, which sat outside this row and skewed it further, is gone.
   ========================================================================== */
#maxwidthheader > .elementor-row { align-items: center; }

/*
 * ONLY the outer two columns are touched. Giving them equal flex makes them split
 * the leftover space evenly, which centres whatever sits between them.
 *
 * The logo column is deliberately left alone: setting width:auto on it collapsed it
 * to 0px and the logo vanished, because the image has no intrinsic width without the
 * column's own sizing.
 */
#maxwidthheader > .elementor-row > .elementor-column:first-child,
#maxwidthheader > .elementor-row > .elementor-column:last-child {
    flex: 1 1 0;
    min-width: 0;
}

/* Right-hand group hugs the right edge. */
#maxwidthheader > .elementor-row > .elementor-column:last-child > .elementor-column-wrap > .elementor-widget-wrap {
    justify-content: flex-end;
    align-items: center;
}

/* Ensure Facebook, Instagram, Language, and Currency share the same horizontal center line */
.elementor-social-icons-wrapper {
    display: flex !important;
    align-items: center !important;
}
.elementor-social-icons-wrapper .elementor-grid-item {
    display: inline-flex !important;
    align-items: center !important;
}
.elementor-social-icons-wrapper .elementor-icon {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
}

/* --- search, basket, language and currency, made prominent ---------------- */
.craftcoffee-search-icon a,
.nav-basket,
.tr-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: 1px solid rgba(241, 234, 224, .22);
    background: rgba(241, 234, 224, .06);
    color: #F1EAE0;
    transition: background .2s ease, border-color .2s ease, color .2s ease;
    box-sizing: border-box;
	position: relative;
    cursor: pointer;
    text-decoration: none;
}

.craftcoffee-search-icon a:hover,
.nav-basket:hover,
.tr-icon-btn:hover,
.tr-icon-btn.tr-active {
    background: #C18B57;
    border-color: #C18B57;
    color: #fff;
}

.craftcoffee-search-icon a i,
.nav-basket i,
.tr-icon-btn i { font-size: 17px; }
.craftcoffee-search-icon { min-height: 0; }

.nav-basket__count {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: 999px;
    background: #C18B57;
    border: 2px solid #1C1A17;
    color: #fff;
    font-size: 10.5px;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
}

.nav-basket { position: relative; }


/* ============================================================================
   24. FOOTER SITTING BESIDE THE CONTENT INSTEAD OF BELOW IT
   ----------------------------------------------------------------------------
   PRE-EXISTING THEME BUG, not introduced here — verified by disabling this
   stylesheet entirely and re-measuring: the footer stayed at x=1196 either way,
   and it does the same on pages that were never restructured.

   The theme floats the page-content wrapper left. The footer wrapper is also
   floated and never clears, so at the theme's design width (~1350px) it happens
   to fall below, but on a wider viewport (1905px) there is room beside the
   1170px content column and the footer slots into the gap — 864px wide, jammed
   against the right edge, looking like it has vanished.

   Clearing the float puts it back underneath, at full width, at any size.
   ========================================================================== */
/*
 * THE ACTUAL CAUSE: the theme's style.css sets `body { display: flex }`.
 *
 * Body being a flex ROW makes #perspective (the page content) and #footer-wrapper
 * siblings in the same row. At the theme's design width they fill it and it looks
 * fine; on a 1905px viewport there is 864px spare beside the 1350px content, so the
 * footer slots into the gap on the right and appears to have vanished.
 *
 * Verified with this stylesheet fully disabled: body was still flex and the footer
 * was still at x=1196, so this is the theme's, not ours. Chasing it as a float
 * problem was wrong — flex items ignore float and width:100% behaves differently.
 *
 * Stacking the row fixes the footer and every "section thrown to the left" symptom
 * that came from the same row.
 */
body {
    flex-direction: column;
    align-items: stretch;
}

#footer-wrapper { width: 100%; max-width: none; }




/* ============================================================================
   25. MOBILE
   ----------------------------------------------------------------------------
   Measured at a 390px viewport, not guessed:

     - #elementor-header rendered 1560px wide and #maxwidthheader 1404px, which
       is the entire cause of the horizontal scroll. The nav-links column
       collapsed correctly (0px) but the social / search / basket column stayed
       at 842px, so the row could not shrink.
     - The card grids used a 350px fixed track, giving one card per row. A B2B
       catalogue should show two.
     - Supplier cards kept their desktop side-by-side layout and the details
       ran into the badge.
   ========================================================================== */
@media (max-width: 900px) {

    /* --- header: nothing may exceed the viewport ------------------------- */
    #elementor-header,
    #navnoborder,
    #maxwidthheader,
    #maxwidthheader > .elementor-row {
        max-width: 100%;
        width: 100%;
        box-sizing: border-box;
    }

    #maxwidthheader > .elementor-row {
        flex-wrap: nowrap;
        justify-content: space-between;
        gap: 8px;
        padding: 0 12px;
    }

    #maxwidthheader > .elementor-row > .elementor-column {
        min-width: 0;
        max-width: 100%;
    }

    /* The logo column keeps its size; the outer two must be free to shrink. */
    #maxwidthheader > .elementor-row > .elementor-column:first-child,
    #maxwidthheader > .elementor-row > .elementor-column:last-child {
        flex: 1 1 0;
        min-width: 0;
    }

    /* Social icons and the language switcher are desktop-only furniture â€” they
       are what kept the right column at 842px. Search, basket and sign-in stay. */
    #maxwidthheader .elementor-widget-social-icons,
    #maxwidthheader [class*="translate"],
    #maxwidthheader .gtranslate_wrapper,
    #maxwidthheader .elementor-social-icons-wrapper {
        display: none !important;
    }

    #maxwidthheader .elementor-widget-wrap {
        flex-wrap: nowrap;
        justify-content: flex-end;
        gap: 6px;
    }

    .nav-basket,
    .craftcoffee-search-icon a { width: 36px; height: 36px; }
    .nav-basket i, .craftcoffee-search-icon a i { font-size: 15px; }
    .dr-trigger { padding: 6px 10px; font-size: 11px; }

    /* --- two cards per row ---------------------------------------------- */
    .mkt__grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 12px;
    }

    .service-grid-content-wrapper:has(.pcard) {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 12px;
        padding: 0 12px;
    }

    .rec__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }

    /* Cards get smaller type so the details still fit at half width. */
    .mkt-card__body, .pcard__body { padding: 12px 12px 14px; gap: 6px; }
    .mkt-card__name, .pcard__name { font-size: 13.5px; line-height: 1.3; }
    .mkt-card__by, .pcard__desc { font-size: 11px; }
    .mkt-card__price, .pcard__price strong { font-size: 15px; }
    .mkt-card__price { padding-top: 8px; margin-top: 8px; }
    .mkt-card__stars i { font-size: 10px; }
    .mkt-card__stars small { font-size: 10px; }

    /* Stack the two actions and keep the labels readable. */
    .mkt-card__acts, .pcard__acts { grid-template-columns: 1fr; gap: 6px; }
    .mkt-btn, .pcard__btn { padding: 10px 8px; font-size: 11.5px; gap: 5px; }

    .mkt-badge { left: 8px; top: 8px; padding: 4px 8px; font-size: 9px; }

    /* --- supplier cards -------------------------------------------------- */
    .mkt__grid--suppliers { grid-template-columns: 1fr; gap: 12px; }

    .mkt-sup {
        display: grid;
        grid-template-columns: 52px minmax(0, 1fr);
        grid-template-areas: "logo body" "badge badge";
        gap: 12px;
        padding: 16px;
        align-items: center;
    }

    .mkt-sup__logo { grid-area: logo; width: 52px; height: 52px; font-size: 19px; }
    .mkt-sup__body { grid-area: body; min-width: 0; gap: 3px; }
    .mkt-sup__body strong { font-size: 14.5px; }
    .mkt-sup__where { font-size: 11.5px; }
    .mkt-sup .mkt-badge { grid-area: badge; justify-self: start; }

    /* --- headings -------------------------------------------------------- */
    .mkt { padding: 44px 0; }
    .mkt__inner { padding: 0 12px; }
    .mkt__head { margin-bottom: 26px; }
    .mkt__title { font-size: 24px; }
    .mkt__sub { font-size: 13px; }

    /* --- "Help me choose" tab -------------------------------------------- */
    /* It is a fixed side tab sized for desktop; at 390px it covered the cards
       and its own text overflowed. Smaller, and out of the content's way. */
    [class*="help-me"], [id*="helpMe"], .cf-tab, .coffee-finder-tab {
        transform: scale(.72);
        transform-origin: right center;
        right: 0 !important;
    }

    /* --- basket page ----------------------------------------------------- */
    .crt__grid { grid-template-columns: 1fr; }
    .crt__inner { padding: 0 12px; }
}

/* ============================================================================
   26. SECTION OVERLAP ABOVE THE FOOTER
   ----------------------------------------------------------------------------
   Several theme sections are position:relative with negative margins so they
   tuck under the one above. With body no longer a flex row those overlaps
   resolve differently, and the last inner section rode over its neighbour.
   Giving the section wrap a stacking context of its own keeps each section in
   its own layer without changing any of the theme's intended offsets.
   ========================================================================== */
#perspective .elementor-section-wrap > .elementor-section { position: relative; }
#perspective .elementor-section-wrap > .elementor-section + .elementor-section { z-index: auto; }
#footer-wrapper { position: relative; z-index: 2; }



/* ============================================================================
   27. MOBILE — RESIDUAL SIDEWAYS PAN
   ----------------------------------------------------------------------------
   With the header fixed (section 25) the page still reported a 2006px scroll
   width at a 375px viewport. Nothing in normal flow was to blame — every
   offender was one of the theme's position:absolute decorations: the
   "Reliable Industrial Supply" marquee heading (1950px wide by design) and a
   pair of decorative images sitting at x=757.

   "html { overflow-x: hidden }" from section 1 hides the scrollbar but does NOT
   stop programmatic or touch panning, so on a phone the page could still be
   dragged sideways into empty space.

   Clipping at the section instead confines each decoration to the section it
   belongs to. Measured: document scrollWidth 2006px -> 375px, exactly the
   viewport. Safe for the fixed furniture (header, bottom nav, chat, cart, the
   "Help me choose" tab) because overflow-x:clip on a non-transformed ancestor
   does not become their containing block, and the page has no position:sticky
   elements at this breakpoint.
   ========================================================================== */
@media (max-width: 900px) {
    #perspective .elementor-section-wrap > .elementor-section { overflow-x: clip; }
}


/* ============================================================================
   28. MOBILE — CARD ACTION BUTTONS WRAPPING TO TWO LINES
   ----------------------------------------------------------------------------
   At a 375px viewport the card actions are one column 124px wide. "Request a
   quote" measured 90px of text + a 12px icon + the 5px gap = 107px against
   108px of content box, so it fits on one line by 1px — but the label was still
   allowed to break, so it wrapped and the button grew to 63px while "Add to
   basket" beside it stayed 40px, leaving the pair visibly uneven.

   nowrap on the label and flex:0 0 auto on the icon keeps it to one line:
   63px -> 43px, no clipped text, no change to document scroll width.

   Deliberately scoped to the card action rows. The wide standalone buttons
   (".mkt__more .mkt-btn", e.g. "See all supplier products") must stay free to
   wrap, since those labels are longer than any card is wide.
   ========================================================================== */
@media (max-width: 900px) {
    .mkt-card__acts .mkt-btn,
    .pcard__acts .pcard__btn {
        white-space: nowrap;
        justify-content: center;
    }

    .mkt-card__acts .mkt-btn i,
    .pcard__acts .pcard__btn i { flex: 0 0 auto; }
}

/* Same font leak as section 31, on the listing cards this time: "Add to basket"
   is a <button> and picks up the theme's bebas_neuebold, which has no lowercase
   glyphs, so it shouted "ADD TO BASKET" beside a Montserrat "Request a quote"
   in the very same card. Applies at every width, not just mobile. */
.pcard__acts .pcard__btn,
.mkt-card__acts .mkt-btn { font-family: inherit; }


/* ============================================================================
   29. INSTAGRAM SECTION COVERED BY THE BLACK BAND ABOVE THE FOOTER
   ----------------------------------------------------------------------------
   The last band on the home page ("For Wholesale Coffee Buyers", the black
   .elementor-element-8c297b2) rode up over the tail of the Instagram section,
   burying the "Follow Our Export Journey" CTA strip and its button.

   The culprit is not that band. Between the Instagram block and it sits an
   empty 1px spacer section, .elementor-element-26e4125, which the theme's
   custom-css.min.css gives "margin-top: -95px" so it tucks under whatever
   precedes it. That was authored for the Elementor section originally in that
   slot, which had 95px of bottom padding to absorb it. The hand-built
   <section class="IuSection"> now in that slot ends flush with its CTA card,
   so the -95px eats real content instead of empty padding.

   Measured at 1905px: CTA strip 26601-26744, black band starting at 26650 —
   94px of overlap. Cancelling the pull puts the band at 26745, one pixel clear.

   Scoped with the adjacent sibling combinator so it only ever affects a section
   that directly follows the Instagram block; the theme's -95px tuck is left
   intact everywhere else. #perspective is present purely for specificity: the
   theme's rule is (0,3,0) and carries no !important, so the id makes this
   (1,2,0) and it wins honestly.
   ========================================================================== */
#perspective .IuSection + .elementor-section { margin-top: 0; }

/* Below 900px the black band carries a second, separate pull of its own
   (margin-top: -39px on .elementor-element-8c297b2), so cancelling the spacer
   alone still left 38px of the CTA strip buried on a phone. Cancelling the
   band's pull as well: gap -38px -> +1px at a 375px viewport. This selector is
   a no-op on desktop, where that margin is already 0. */
#perspective .IuSection + .elementor-section + .elementor-section { margin-top: 0; }


/* ============================================================================
   30. MOBILE NAVIGATION DRAWER  (.mnav-*)
   ----------------------------------------------------------------------------
   The header's nav-links column carries the theme's "elementor-hidden-phone",
   so below the phone breakpoint the header exposed only the basket and the
   Sign in dropdown — Home / About / Products / Training / Contact were
   unreachable on a phone. The theme's own .mobile-menu-wrapper exists but
   nothing opens it: its trigger lives in the commented-out phone-number column.

   So: a hamburger in the header opens a right-hand drawer carrying the
   navigation AND the account links. Below 900px .dr-wrap is hidden from the
   header, because Sign in now lives in the drawer and must not be offered twice
   on one screen.

   Surface is white to match .dr-panel, so the reused .dr-link / .dr-eyebrow /
   .dr-divider markup (partials/account-links.blade.php, shared with the desktop
   dropdown) needs no recolouring — only spacing, since it is a full-width
   column here rather than a 200px popover.

   z-index 8800 sits above the Coffee Finder tab (8500) and the header, and
   below the cart drawer (.ac-cart, 9000) so the basket still opens over it.
   ========================================================================== */

/* --- trigger: mobile only ------------------------------------------------ */
.mnav-burger {
    display: none;
    width: 36px;
    height: 36px;
    align-items: center;
    justify-content: center;
    padding: 0;
    margin-left: 6px;
    background: #ffffff1c;
    border: 1px solid #ffffff;
    border-radius: 999px;
    color: #F1EAE0;
    cursor: pointer;
    box-sizing: border-box;
    transition: background .2s ease, border-color .2s ease;
}

.mnav-burger:hover,
.mnav-burger[aria-expanded="true"] { background: #C18B57; border-color: #C18B57; }

.mnav-burger__bars { display: block; width: 16px; }

.mnav-burger__bars span {
    display: block;
    height: 1.5px;
    background: currentColor;
    border-radius: 2px;
}

.mnav-burger__bars span + span { margin-top: 3.5px; }

/* --- scrim and drawer ---------------------------------------------------- */
.mnav-scrim {
    position: fixed;
    inset: 0;
    background: rgba(28, 26, 23, .55);
    opacity: 0;
    visibility: hidden;
    transition: opacity .3s ease, visibility .3s ease;
    z-index: 8790;
}

.mnav-scrim.is-open { opacity: 1; visibility: visible; }

.mnav {
    position: fixed;
    top: 0;
    right: 0;
    height: 100dvh;
    width: min(86vw, 340px);
    background: #fff;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    box-shadow: -18px 0 40px -12px rgba(20, 20, 20, .28);
    transform: translateX(102%);
    visibility: hidden;
    transition: transform .32s cubic-bezier(.22, .61, .36, 1), visibility .32s;
    z-index: 8800;
}

.mnav.is-open { transform: none; visibility: visible; }

/* Freeze the page behind the drawer so the drawer scrolls, not the document. */
body.mnav-lock { overflow: hidden; }

/* --- head ---------------------------------------------------------------- */
.mnav__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 18px;
    background: #F1EAE0;
    border-bottom: 1px solid #e6ddd1;
    position: sticky;
    top: 0;
    z-index: 1;
}

.mnav__eyebrow {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 10px;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: #5C564D;
}

.mnav__close {
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid #d9cec0;
    border-radius: 999px;
    color: #1C1A17;
    font-size: 14px;
    cursor: pointer;
    transition: background .2s ease, color .2s ease, border-color .2s ease;
}

.mnav__close:hover { background: #C18B57; border-color: #C18B57; color: #fff; }

/* --- navigation ---------------------------------------------------------- */
.mnav__nav { padding: 10px 12px 4px; }

.mnav__link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    padding: 12px 10px;
    border: 0;
    background: transparent;
    border-radius: 9px;
    font-family: 'Inter', sans-serif;
    font-size: 14.5px;
    font-weight: 500;
    color: #1a1a1a;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    /* The Products row is a <button> so it can drive aria-expanded. The theme's
       global button rule gives it text-transform:uppercase and letter-spacing:2px,
       so it rendered as "P R O D U C T S" among sentence-case links. Reset both
       here rather than on the button alone, so any future button in this list
       matches the anchors automatically. */
    text-transform: none;
    letter-spacing: normal;
    transition: background .18s ease, color .18s ease;
}

.mnav__link:hover,
.mnav__link:focus-visible { background: #F1EAE0; color: #1C1A17; }

.mnav__nav > .mnav__link + .mnav__link,
.mnav__group + .mnav__link,
.mnav__link + .mnav__group { border-top: 1px solid #f2efeb; }

.mnav__caret { font-size: 11px; color: #9b9b9b; transition: transform .22s ease; }
.mnav__toggle[aria-expanded="true"] .mnav__caret { transform: rotate(180deg); }

.mnav__sub { padding: 2px 0 8px 10px; margin-left: 8px; border-left: 1px solid #ececec; }

.mnav__sub a {
    display: block;
    padding: 9px 10px;
    border-radius: 7px;
    font-size: 13px;
    color: #5C564D;
    text-decoration: none;
    transition: background .18s ease, color .18s ease;
}

.mnav__sub a:hover { background: #F1EAE0; color: #1C1A17; }

.mnav__count {
    min-width: 19px;
    height: 19px;
    padding: 0 5px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: #C18B57;
    color: #fff;
    border-radius: 999px;
    font-size: 10.5px;
    font-weight: 600;
}

/* --- account block ------------------------------------------------------- */
/* Reuses .dr-* from style.css. Only the popover-specific geometry is undone. */
.mnav__account {
    margin-top: auto;
    padding: 12px;
    border-top: 1px solid #ececec;
    background: #fcfbfa;
}

.mnav__account .dr-link { padding: 10px; font-size: 14px; }
.mnav__account .dr-eyebrow { padding: 8px 10px 6px; }

/* .dr-link puts the label and its <small> caption in one flex row, which is
   right in a 200px popover but leaves the caption cramped at drawer width. */
.mnav__account .dr-link > span { display: flex; flex-direction: column; gap: 2px; }
.mnav__account .dr-link small { font-size: 11.5px; color: #9b9b9b; line-height: 1.35; }
.mnav__account .dr-link i { width: 18px; text-align: center; color: #C18B57; }

/* --- Mobile Drawer: Language Accordion --- */
.mnav__lang {
    padding: 10px 14px;
    border-top: 1px solid #f2efeb;
}

.mnav__lang-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 11px 13px;
    background: #fbf9f6;
    border: 1px solid #ece4d8;
    border-radius: 8px;
    font-family: 'Inter', sans-serif;
    font-size: 14px;
    font-weight: 500;
    color: #1c1a17;
    cursor: pointer;
    text-transform: none;
    letter-spacing: normal;
    transition: background 0.18s ease, border-color 0.18s ease;
}

.mnav__lang-toggle:hover {
    background: #F1EAE0;
    border-color: #dfd4c5;
}

.mnav__lang-toggle .fa-globe,
.mnav__lang-toggle .fa-coins {
    color: #A5713F;
    margin-right: 8px;
    font-size: 15px;
}

.mnav__lang-list {
    list-style: none;
    margin: 8px 0 0;
    padding: 6px 0;
    max-height: 220px;
    overflow-y: auto;
    border: 1px solid #ece4d8;
    border-radius: 8px;
    background: #fff;
}

.mnav__lang-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 14px;
    font-size: 13.5px;
    color: #333;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
    user-select: none;
}

.mnav__lang-item:hover,
.mnav__lang-item.is-selected {
    background: #F1EAE0;
    color: #1C1A17;
    font-weight: 600;
}

.mnav__lang-item.is-selected::after {
    content: "✓";
    margin-left: auto;
    color: #A5713F;
    font-weight: bold;
    font-size: 12px;
}

/* --- Mobile Drawer: Social Media Strip --- */
.mnav__social {
    padding: 16px 18px 22px;
    border-top: 1px solid #ececec;
    background: #fcfbfa;
}

.mnav__social-label {
    display: block;
    font-family: 'IBM Plex Mono', monospace;
    font-size: 10px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: #8A8175;
    margin-bottom: 10px;
}

.mnav__social-icons {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.mnav__social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: #F1EAE0;
    color: #1C1A17 !important;
    font-size: 15px;
    text-decoration: none !important;
    transition: background 0.2s ease, color 0.2s ease, transform 0.2s ease;
}

.mnav__social-link:hover {
    background: #A5713F;
    color: #fff !important;
    transform: translateY(-2px);
}

/* --- breakpoint ---------------------------------------------------------- */
@media (max-width: 900px) {
    .mnav-burger { display: inline-flex; }

    /* Sign in moved into the drawer — do not offer it twice. */
    #maxwidthheader .dr-wrap { display: none; }
}

/* Above the breakpoint the drawer must never be reachable, even mid-transition
   or if a stale .is-open survives a resize. */
@media (min-width: 901px) {
    .mnav,
    .mnav-scrim { display: none; }
}


/* ============================================================================
   31. PRODUCT DETAIL — THE THREE ACTION BUTTONS  (.pw-cta-row / .pw-btn-cart)
   ----------------------------------------------------------------------------
   style.css gives .pw-btn-cart a fixed "height:48px", "flex:1 1 0%" and NO
   padding. Three consequences, all visible at once:

     1. Two of the three are <a> and one is <button>. The <button> picked up the
        theme's global button rule — text-transform:uppercase and 36px of side
        padding — so it read "ADD TO BASKET" next to "Request a sample" and
        "Request a bulk quote". Three buttons, two different typographic styles.
     2. The <a> versions inherited padding:0, so their labels ran to the very
        edge of the pill.
     3. "flex:1 1 0%" divides the row by button COUNT, not by label length, so
        each got ~150px while "Request a bulk quote" needs ~150px of text alone.
        Every label wrapped to two lines inside a box locked to 48px, which is
        what pushed the text outside the button.

   Fix: one typographic treatment for all three regardless of tag, real padding,
   and min-height instead of height so a wrapped label grows the button rather
   than spilling out of it. The primary action takes its own full-width row
   (flex-basis:100%), which leaves the two secondary actions enough width to sit
   on one line on desktop. align-items:stretch keeps a pair equal height when
   one of them does wrap.
   ========================================================================== */
.pw-cta-row { align-items: stretch; }

.pw-cta-row .pw-btn-cart {
    flex: 1 1 170px;
    height: auto;
    min-height: 48px;
    padding: 11px 16px;
    line-height: 1.25;
    text-align: center;
    text-decoration: none;
    text-transform: none;
    letter-spacing: .01em;
    white-space: normal;
    box-sizing: border-box;
    /* The <button> resolved to the theme's display face, bebas_neuebold, which
       has NO LOWERCASE GLYPHS — so "Add to basket" rendered as "ADD TO BASKET"
       beside two Montserrat anchors even though text-transform computed to
       "none". Inheriting matches whatever the anchors inherit, so all three
       stay one face without hardcoding a font name that could drift. */
    font-family: inherit;
}

/* "Add to basket" is the primary action — its own row, full width. */
.pw-cta-row .pw-btn-cart[data-add-to-cart] { flex-basis: 100%; }

/* The MOQ hint rides inside the primary label; keep it quiet, not shouty. */
.pw-cta-row .pw-btn-cart small { text-transform: none; white-space: nowrap; }

.pw-cta-row .pw-btn-wish { flex: 0 0 48px; }

@media (max-width: 600px) {
    /* Two secondary actions side by side under the full-width primary. Narrower
       padding and a slightly smaller face buy back the room a 375px screen
       does not have. */
    .pw-cta-row { gap: 10px; }
    .pw-cta-row .pw-btn-cart { flex: 1 1 calc(50% - 34px); font-size: 13px; padding: 11px 10px; }
    .pw-cta-row .pw-btn-cart[data-add-to-cart] { flex-basis: 100%; font-size: 14px; }
}


/* ============================================================================
   32. BASKET LINE — QTY CONTROL SPILLING INTO THE PRICE  (mobile)
   ----------------------------------------------------------------------------
   Section 15 dropped .crt-line to three columns under 680px and put the qty
   stepper in column 2 (.crt-line__qty { grid-column: 2/3 }). Column 2 is
   minmax(0,1fr), which on a 375px screen resolves to about 121px — but the
   stepper is a flex row of button+input+button+unit needing roughly 140px.
   Flex rows do not wrap by default, so the trailing unit label ("kg") overflowed
   its own column and rendered at x=335, on top of the price in column 3.
   Measured: .crt-line__qty spanned 109-230 while its own .crt-line__unit child
   sat at 335-349, i.e. 105px outside its parent.

   Widening column 2 is not possible at this width without squeezing the price,
   so the stepper gets a row of its own instead: named areas put name and remove
   on the first row, stepper and price on the second. The stepper then spans
   columns 1-2 (~235px) and the price keeps the right edge it needs to align to.
   flex-wrap is a belt-and-braces guard so an unusually long unit label wraps
   under the stepper rather than escaping it again.
   ========================================================================== */
/* The stepper's own buttons were 77px wide, not the 30px section 15 declares.
   The theme's global button rule pads them "9px 37.5px", and with box-sizing:
   border-box a 75px horizontal padding cannot fit inside a 30px width, so the
   box grew to its padding. That alone made the stepper ~240px — wider than any
   column it was ever placed in, and the real reason it could not fit. Resetting
   the padding restores the intended 30px square at every breakpoint. */
/* font-family: the stepper glyphs also resolved to bebas_neuebold, whose "+"
   renders as a small raised dot — the button read as "·" rather than "+".
   Inheriting gives both glyphs the body face, and centring them with flex
   removes the reliance on a line-height that was tuned for a different font. */
.crt-line__qty button {
    padding: 0;
    min-width: 0;
    font-family: inherit;
    font-size: 16px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

@media (max-width: 680px) {
    .crt-line {
        grid-template-columns: 64px minmax(0, 1fr) auto;
        grid-template-areas:
            "img body x"
            "qty qty money";
        row-gap: 12px;
        align-items: center;
    }

    .crt-line__img   { grid-area: img; align-self: start; }
    .crt-line__body  { grid-area: body; }
    .crt-line__qty   { grid-area: qty; flex-wrap: wrap; min-width: 0; }
    .crt-line__money { grid-area: money; text-align: right; }
    .crt-line__x     { grid-area: x; justify-self: end; align-self: start; }
}


/* ============================================================================
   33. ALL PRODUCTS — UNIFORM CARD HEIGHT  (.pcard)
   ----------------------------------------------------------------------------
   Checked first: the card IMAGE is already a fixed height at both breakpoints.
   .pcard__media carries aspect-ratio 4/3 with object-fit:cover, so every tile
   measured exactly 217px on desktop and 111px at 375px — including the three
   lots with no photo, whose placeholder matches. Cards within a row were also
   already equal height, with price and buttons at identical offsets.

   What actually varied was row against row: 539px vs 579px. The cause is
   unclamped text — product names run to one or two lines and descriptions
   measured 50px, 70px or 90px — so each grid row sized to its own tallest card
   and the shelf edge moved as you scrolled.

   Reserving a fixed two lines for the name and three for the description makes
   every card in the listing the same height, so the images, prices and buttons
   line up down the whole page rather than only across a row. min-height (not
   just line-clamp) is what holds the space open for a short name.
   ========================================================================== */
/* IMPLEMENTATION NOTE — why this is a fixed height and not a line clamp.

   The obvious tool is "display:-webkit-box + -webkit-line-clamp", and both
   CSS.supports() checks return true, so it looks available. It does not work
   here: on Chrome 150 the element's display resolves to "flow-root" even when
   -webkit-box is set inline, and without the box display the clamp is inert —
   measured 84px before and 84px after. The standard "line-clamp" property is
   not supported either (CSS.supports('line-clamp','3') === false).

   A fixed height with overflow:hidden does work — the same paragraph measured
   84px -> 54px — and it is what actually guarantees identical card heights,
   which a clamp only approximates. The -webkit-* declarations are kept as a
   progressive enhancement: where the box model is honoured they add the
   trailing ellipsis, and where it is not they change nothing. */
.pcard__name {
    height: 2.6em;
    overflow: hidden;
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

.pcard__desc {
	    padding: 0 !important;
    /* height: 4.35em; */
    overflow: hidden;
    line-height: 1.45;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
}


/* ============================================================================
   34. HEADER SEARCH — CLOSE CONTROL AND RESULTS PANEL  (.nsr-*)
   ----------------------------------------------------------------------------
   The overlay had no exit. craftcoffee-elementor.js adds .active to the search
   wrapper and puts "elementor-no-overflow" on <body>, and nothing anywhere
   removes either — the theme's close control was WordPress markup that did not
   survive the static export. Opening search covered the page and locked
   scrolling until a reload. .nsr-close is that missing control; Escape and a
   backdrop click do the same job (see layouts/navbar.blade.php).

   The results box was an inline-styled div: "width:40%; left:30%; top:58%" with
   a translucent grey wash and a 10px radius, positioned against the form rather
   than the field. Each row was the product name and price as plain text, no
   image, no description — and its click handler navigated to /products/{id}
   while the route binds on slug, so every result 404'd.

   This is the panel rebuilt on the site's own palette: anchored under the
   field, thumbnail + name + short description on the left, price on the right.
   ========================================================================== */

/* --- close control -------------------------------------------------------- */
.craftcoffee-search-wrapper .nsr-close {
    position: absolute;
    top: 28px;
    right: 28px;
    width: 46px;
    height: 46px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: rgba(255, 255, 255, .08);
    border: 1px solid rgba(241, 234, 224, .35);
    border-radius: 50%;
    color: #F1EAE0;
    font-size: 17px;
    line-height: 1;
    cursor: pointer;
    z-index: 10;
    transition: background .2s ease, border-color .2s ease, color .2s ease;
}

.craftcoffee-search-wrapper .nsr-close:hover {
    background: #C18B57;
    border-color: #C18B57;
    color: #fff;
}

/* --- results panel -------------------------------------------------------- */

/* The panel is absolute, and the form it sits in is position:static, so without
   this it resolved against a distant ancestor and landed at y=918 — 400px below
   the field, off the bottom of the viewport. Making the form the containing
   block puts "top:100%" exactly under the input where it belongs. */
.craftcoffee-search-wrapper .tg_search_form { position: relative; }

.nsr {
    display: none;
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    top: calc(100% + 14px);
    width: min(680px, calc(100vw - 40px));
    max-height: min(60vh, 460px);
    overflow-y: auto;
    background: #fff;
    border: 1px solid #E7E0D6;
    border-radius: 8px;
    box-shadow: 0 26px 64px rgba(28, 26, 23, .28);
    text-align: left;
    z-index: 20;
}

.nsr.is-open { display: block; }

.nsr__item {
    display: grid;
    grid-template-columns: 54px minmax(0, 1fr) auto;
    gap: 14px;
    align-items: center;
    padding: 12px 16px;
    text-decoration: none;
    color: #1C1A17;
    border-bottom: 1px solid #F2EFEB;
    transition: background .16s ease;
}

.nsr__item:last-child { border-bottom: 0; }
.nsr__item:hover { background: #F1EAE0; text-decoration: none; color: #1C1A17; }

.nsr__thumb {
    width: 54px;
    height: 54px;
    border-radius: 5px;
    overflow: hidden;
    background: #F1EAE0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #8A8175;
    font-size: 15px;
}

.nsr__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

.nsr__body { min-width: 0; display: flex; flex-direction: column; gap: 3px; }

.nsr__name {
    font-family: inherit;
    font-size: 14.5px;
    font-weight: 600;
    line-height: 1.3;
    color: #1C1A17;
    /* One line — a long lot name must not push the price out of the row. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nsr__desc {
    font-size: 12px;
    line-height: 1.5;
    color: #5C564D;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nsr__price {
    font-size: 15px;
    font-weight: 700;
    color: #A5713F;
    white-space: nowrap;
    text-align: right;
}

.nsr__price small { font-size: 10.5px; font-weight: 500; color: #8A8175; margin-left: 3px; }

.nsr__empty {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 26px 20px;
    font-size: 13.5px;
    color: #5C564D;
}

.nsr__empty i { color: #C18B57; font-size: 15px; }

@media (max-width: 900px) {
    .craftcoffee-search-wrapper .nsr-close { top: 14px; right: 14px; width: 40px; height: 40px; font-size: 15px; }
    .nsr { width: calc(100vw - 24px); max-height: 56vh; top: calc(100% + 10px); }
    .nsr__item { grid-template-columns: 44px minmax(0, 1fr) auto; gap: 10px; padding: 10px 12px; }
    .nsr__thumb { width: 44px; height: 44px; }
    .nsr__name { font-size: 13.5px; }
    .nsr__desc { font-size: 11.5px; }
    .nsr__price { font-size: 13.5px; }
}


/* ============================================================================
   35. MOBILE DRAWER — SEARCH  (.mnav__search + .nsr--inline)
   ----------------------------------------------------------------------------
   The header magnifier lives in a widget the theme marks #hiddenonmob, so below
   the phone breakpoint there was no way to search the catalogue at all. The
   drawer now carries the entry point.

   The results reuse the .nsr item styling from section 34 unchanged — same
   thumbnail, name, description and price — so the two surfaces cannot drift.
   Only the container differs: in the header it is a popover anchored under the
   field, here it is inline, because the drawer is already a panel and a popover
   inside a scrolling panel would clip against it.
   ========================================================================== */
.mnav__search { padding: 12px 12px 4px; }

.mnav__search-field {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 9px 14px;
    background: #FBF8F4;
    border: 1px solid #e6ddd1;
    border-radius: 999px;
    transition: border-color .18s ease, box-shadow .18s ease;
}

.mnav__search-field:focus-within {
    border-color: #C18B57;
    box-shadow: 0 0 0 3px rgba(193, 139, 87, .15);
}

.mnav__search-field i { flex: 0 0 auto; font-size: 13px; color: #8A8175; }

.mnav__search-field input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 0;
    border: 0;
    outline: 0;
    background: transparent;
    font-family: inherit;
    font-size: 14px;
    color: #1a1a1a;
    box-sizing: border-box;
}

/* Safari draws its own clear affordance on type=search; the drawer has its own
   close and the field clears itself on close. */
.mnav__search-field input::-webkit-search-cancel-button { -webkit-appearance: none; }

/* Inline variant: flows in the drawer instead of floating over it. */
.nsr--inline {
    position: static;
    transform: none;
    left: auto;
    top: auto;
    width: 100%;
    max-height: none;
    overflow: visible;
    margin-top: 10px;
    border-radius: 6px;
    box-shadow: none;
}

/* The drawer is ~300px wide. Keeping the desktop three-column row left the
   name about 170px once the price column took its share, so "Ethiopian Green
   Coffee" truncated to "Ethiopian Green Cof…". Dropping the price onto its own
   line under the text gives the name the full ~240px and stops the useful part
   of every result being the part that gets cut. */
.nsr--inline .nsr__item {
    padding: 10px 12px;
    grid-template-columns: 44px minmax(0, 1fr);
    grid-template-areas:
        "thumb body"
        "thumb price";
    row-gap: 3px;
    align-items: start;
}

.nsr--inline .nsr__thumb { grid-area: thumb; width: 44px; height: 44px; }
.nsr--inline .nsr__body  { grid-area: body; }

.nsr--inline .nsr__price {
    grid-area: price;
    text-align: left;
    font-size: 13.5px;
}


/* ============================================================================
   36. ACCOUNT PAGES — INVISIBLE "PRODUCTS" DROPDOWN
   ----------------------------------------------------------------------------
   The Products dropdown was unreadable on buyer account pages only: black text
   on the dark header. Everywhere else it was fine.

   Three things combined to cause it.

   1. Every theme rule that styles this dropdown is keyed on "#menu-wrapper"
      (e.g. "#menu-wrapper div .nav li ul li a { color:#fff }" in style.css).
      There is no #menu-wrapper in this markup — the header is
      "#elementor-header.main-menu-wrapper". So NONE of the theme's dropdown
      styling has ever applied: no white links, and no panel background either.
      The dropdown has always shown whatever is behind it.

   2. On brochure pages that did not matter. The links fell back to the dark
      body colour and the header is transparent over a light page, so they read
      fine by accident.

   3. Account pages set .page-account, which makes the header solid --ts-ink.
      Section 20 above then set ".page-account #elementor-header .sub-menu a
      { color: inherit }" — correct for .dr-panel, which carries its own
      background, but wrong for .sub-menu, which carries none. The links
      inherited the dark body colour and landed on the now-dark header.

   Fixed by giving the dropdown its own surface rather than by leaving it
   dependent on whatever sits behind it. Scoped to .page-account so the
   brochure pages keep the appearance they already have.
   ========================================================================== */
.page-account #elementor-header .sub-menu {
    background: #14120F;
    border: 1px solid rgba(241, 234, 224, .10);
    border-radius: 7px;
    overflow: hidden;
}

/* Overrides the `color: inherit` from section 20 — same specificity, later in
   the file. .dr-panel keeps inheriting; only .sub-menu is corrected. */
.page-account #elementor-header .sub-menu a {
    color: #F1EAE0;
    display: block;
    padding: 9px 16px;
}

.page-account #elementor-header .sub-menu a:hover {
    color: #D8A24A;
    background: rgba(241, 234, 224, .06);
}

/* The bolded catalogue entries must not read as a different colour. */
.page-account #elementor-header .sub-menu a strong { color: inherit; font-weight: 600; }


/* ============================================================================
   SUPPLIER PROFILE — IDENTITY ROW OVERLAP
   ----------------------------------------------------------------------------
   .pv-info-top is a two-item flex row: the identity block (eyebrow, name,
   verified tick, bio, plan badges) on the left and the "All listings" button on
   the right. The button is flex-shrink:0, but the identity block was a bare
   <div> with no min-width, and a flex item's min-width defaults to `auto` — it
   refuses to shrink below its content. So on a long company name or once the
   VERIFIED / PREMIUM badges wrapped, the identity block overflowed its track and
   the badges ran underneath the button.

   min-width:0 lets it shrink and wrap properly; allowing the row itself to wrap
   drops the button onto its own line when there genuinely is not room.
   ========================================================================== */
.pv-info-top {
    flex-wrap: wrap;
    align-items: flex-start;
}

.pv-info-top > *:first-child {
    flex: 1 1 320px;
    min-width: 0;
}

.pv-title {
    flex-wrap: wrap;
    max-width: 100%;
    overflow-wrap: anywhere;
}

.pv-info-top .sb-badges {
    max-width: 100%;
}

/* Keeps the button clear of the badges at every width rather than relying on the
   row never running out of space. */
.pv-follow-toggle {
    margin-left: auto;
}

@media (max-width: 720px) {
    .pv-follow-toggle {
        margin-left: 0;
        width: 100%;
        justify-content: center;
    }
}


/* A seller viewing their own listing gets a note where the buy actions would be. */
.pw-own-note {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    flex: 1 1 260px;
    padding: 11px 15px;
    border-left: 2px solid var(--ts-terracotta, #C18B57);
    background: rgba(193, 139, 87, .10);
    color: #5C564D;
    font-size: 12.5px;
    line-height: 1.65;
}
.pw-own-note i { color: var(--ts-terracotta, #C18B57); margin-top: 2px; }

/* Featured badge on a supplier's own storefront grid. */
.pv-product-img { position: relative; }
.pv-product-featured {
    position: absolute;
    top: 10px;
    left: 10px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px;
    border-radius: 999px;
    background: #1C1A17;
    color: #D8A24A;
    font-family: 'IBM Plex Mono', monospace;
    font-size: 9px;
    letter-spacing: .14em;
    text-transform: uppercase;
    line-height: 1;
    box-shadow: 0 3px 10px rgba(28, 26, 23, .28);
}
.pv-product-featured i { font-size: 9px; }


/* ============================================================================
   BASKET OVERLAP DIALOG  (.ac-dupe)
   ----------------------------------------------------------------------------
   Shown by cart.js when a product would end up in the basket twice — once loose
   and once inside a bundle. Purpose-built rather than window.confirm because the
   choice is not yes/no: it is "fold them together" versus "keep both", and each
   needs explaining.
   ========================================================================== */
.ac-dupe {
    position: fixed;
    inset: 0;
    z-index: 3000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}

.ac-dupe__scrim {
    position: absolute;
    inset: 0;
    background: rgba(28, 26, 23, .55);
    animation: acDupeFade .2s ease;
}

.ac-dupe__panel {
    position: relative;
    width: min(460px, 100%);
    background: #fff;
    border-radius: 8px;
    padding: 28px 28px 24px;
    box-shadow: 0 24px 60px rgba(28, 26, 23, .34);
    animation: acDupeIn .26s cubic-bezier(.22, .61, .36, 1);
}

.ac-dupe__title {
    margin: 0 0 10px;
    font-family: 'Fraunces', Georgia, serif;
    font-size: 21px;
    font-weight: 500;
    color: #1C1A17;
    text-transform: none;
    line-height: 1.3;
}

.ac-dupe__body {
    margin: 0 0 20px;
    font-size: 13.5px;
    line-height: 1.7;
    color: #5C564D;
}

.ac-dupe__acts { display: flex; flex-wrap: wrap; gap: 10px; }

.ac-dupe__btn {
    flex: 1 1 auto;
    padding: 12px 18px;
    border: 1px solid #E7E0D6;
    border-radius: 4px;
    background: #fff;
    color: #1C1A17;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: border-color .18s, background .18s, color .18s;
}
.ac-dupe__btn:hover { border-color: #C18B57; color: #A5713F; }

.ac-dupe__btn--primary { background: #1C1A17; border-color: #1C1A17; color: #F1EAE0; }
.ac-dupe__btn--primary:hover { background: #322E28; border-color: #322E28; color: #F1EAE0; }

.ac-dupe__x {
    position: absolute;
    top: 12px;
    right: 14px;
    border: 0;
    background: none;
    font-size: 22px;
    line-height: 1;
    color: #8A8175;
    cursor: pointer;
}
.ac-dupe__x:hover { color: #1C1A17; }

@keyframes acDupeFade { from { opacity: 0 } to { opacity: 1 } }
@keyframes acDupeIn { from { opacity: 0; transform: translateY(12px) } to { opacity: 1; transform: translateY(0) } }

@media (prefers-reduced-motion: reduce) {
    .ac-dupe__scrim, .ac-dupe__panel { animation: none; }
}


/* ============================================================================
   RICH PRODUCT DESCRIPTIONS  (.pw-rich)
   ----------------------------------------------------------------------------
   The description is written in Summernote now, so it arrives as real HTML
   rather than a block of text run through nl2br. The theme styles almost none
   of these elements inside a product accordion, so a seller's heading, list or
   table would have rendered unstyled — which looks worse than the plain text it
   replaced.

   Deliberately restrained: this is a supplier's copy inside our page, so it gets
   readable rhythm and our type scale, not a second visual voice.
   ========================================================================== */
.pw-rich > *:first-child { margin-top: 0; }
.pw-rich > *:last-child { margin-bottom: 0; }

.pw-rich p { margin: 0 0 14px; line-height: 1.8; }

.pw-rich h2,
.pw-rich h3,
.pw-rich h4,
.pw-rich h5,
.pw-rich h6 {
    margin: 22px 0 10px;
    font-family: 'Fraunces', Georgia, serif;
    font-weight: 500;
    color: #1C1A17;
    line-height: 1.3;
    text-transform: none;
    letter-spacing: -.01em;
}
.pw-rich h2 { font-size: 20px; }
.pw-rich h3 { font-size: 18px; }
.pw-rich h4,
.pw-rich h5,
.pw-rich h6 { font-size: 16px; }

.pw-rich ul,
.pw-rich ol { margin: 0 0 14px; padding-left: 22px; }
.pw-rich li { margin-bottom: 6px; line-height: 1.75; }
.pw-rich ul { list-style: disc; }
.pw-rich ol { list-style: decimal; }

.pw-rich strong, .pw-rich b { font-weight: 600; color: #1C1A17; }
.pw-rich em, .pw-rich i { font-style: italic; }

.pw-rich blockquote {
    margin: 18px 0;
    padding: 12px 18px;
    border-left: 2px solid #C18B57;
    background: rgba(193, 139, 87, .07);
    font-style: italic;
}

.pw-rich a { color: #A5713F; text-decoration: underline; }
.pw-rich hr { margin: 20px 0; border: 0; border-top: 1px solid #E7DECF; }

/* A pasted table must not push the page sideways. */
.pw-rich table {
    width: 100%;
    margin: 16px 0;
    border-collapse: collapse;
    font-size: 13.5px;
}
.pw-rich th,
.pw-rich td {
    padding: 9px 12px;
    border: 1px solid #E7DECF;
    text-align: left;
    vertical-align: top;
}
.pw-rich th { background: #F1EAE0; font-weight: 600; color: #1C1A17; }

/* ==========================================================================
   §31 — Mobile header controls (currency / language / basket)

   The theme's right-hand header cluster — basket, currency, language, search
   and Sign in — all sit inside a container carrying "elementor-hidden-phone",
   so below the phone breakpoint every one of them vanished and the header was
   left with nothing but the burger. Currency and language were then reachable
   only by opening the drawer and scrolling to the accordions; the basket was
   not reachable from the header at all.

   This strip restores the three a buyer needs at a glance. It is display:none
   by default and appears only below 768px, which is where
   .elementor-hidden-phone actually takes effect — deliberately NOT the 900px
   used by .mnav-burger in §30, so these controls and the still-visible
   originals are never on screen together.

   z-index 8600 puts the open dropdowns above the Coffee Finder tab (8500) and
   below the cart drawer (.ac-cart, 9000), matching the ordering in §30.
   ========================================================================== */

.mhead-ctl { display: none; align-items: center; gap: 6px; }

.mhead-ctl__item { position: relative; }

.mhead-ctl__btn,
.mhead-ctl__cart {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    height: 36px;
    padding: 0 9px;
    background: #ffffff1c;
    border: 1px solid #ffffff;
    border-radius: 999px;
    color: #F1EAE0;
    font-family: var(--mv-font-mono, 'IBM Plex Mono', monospace);
    font-size: 11px;
    letter-spacing: .04em;
    line-height: 1;
    cursor: pointer;
    box-sizing: border-box;
    text-decoration: none;
    transition: background .2s ease, border-color .2s ease;
}

.mhead-ctl__cart { width: 36px; padding: 0; position: relative; }

/* The strip sits in a narrow Elementor column, and as flex items these buttons
   were shrinkable: the icon-only ones held their size but the currency button,
   whose width comes from its "GBP" text, was squeezed to a 16px sliver. Pin all
   three and stop the label wrapping. */
.mhead-ctl__btn,
.mhead-ctl__cart { flex: 0 0 auto; }

/* nowrap alone was not enough: as a flex child of the button the label still had
   the default flex-shrink:1 and collapsed to 0 width inside a 31px pill, so the
   pill showed the coins icon and no code. Pin it too. */
.mhead-ctl__code { white-space: nowrap; flex: 0 0 auto; }

.mhead-ctl__item { flex: 0 0 auto; }

.mhead-ctl__btn:hover,
.mhead-ctl__cart:hover,
.mhead-ctl__btn[aria-expanded="true"] {
    background: #C18B57;
    border-color: #C18B57;
    color: #fff;
}

.mhead-ctl__code { font-weight: 600; }

/* The button's font-size is for the "GBP" label; without this the <i> inherits
   11px and the globe/basket render at a size that reads as a missing icon. */
.mhead-ctl__btn > i,
.mhead-ctl__cart > i { font-size: 15px; line-height: 1; }

.mhead-ctl__btn > i.mhead-ctl__caret { font-size: 8px; opacity: .75; }
.mhead-ctl__flag { font-size: 15px; line-height: 1; }

/* Unread-style badge, same idiom as .nav-basket__count. */
.mhead-ctl__count {
    position: absolute;
    top: -3px;
    right: -3px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    background: #C18B57;
    border-radius: 999px;
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
    box-sizing: border-box;
}

.mhead-ctl__count[hidden] { display: none; }

/* --- dropdowns ----------------------------------------------------------- */
.mhead-ctl__menu {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 8600;
    min-width: 208px;
    max-height: 60vh;
    margin: 0;
    padding: 6px;
    overflow-y: auto;
    list-style: none;
    background: #1F1C17;
    border: 1px solid rgba(241, 234, 224, .12);
    border-radius: 7px;
    box-shadow: 0 18px 40px rgba(0, 0, 0, .45);
    -webkit-overflow-scrolling: touch;
}

.mhead-ctl__menu[hidden] { display: none; }

.mhead-ctl__opt {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 10px 10px;
    border-radius: 4px;
    color: #F1EAE0;
    font-size: 13px;
    line-height: 1.2;
    cursor: pointer;
}

.mhead-ctl__opt:hover { background: rgba(193, 139, 87, .22); }

.mhead-ctl__opt.is-selected {
    background: rgba(193, 139, 87, .30);
    font-weight: 600;
}

/* --- breakpoint ----------------------------------------------------------
   767px, NOT the 900px used by .mnav-burger in §30.

   Most of the originals this strip stands in for are hidden by Elementor's
   .elementor-hidden-phone, which frontend.min.css defines at max-width:767px.
   Showing this at 900px put the strip and the still-visible originals on screen
   together between 768 and 900px.

   The basket is the exception and needs hiding by hand — see the rule below. */
@media (max-width: 767px) {
    .mhead-ctl { display: inline-flex; }

    /* The strip carries the basket below 768px, so the original must go or the
       header shows two of them.

       It is not enough to rely on .elementor-hidden-phone: the basket sits in a
       different Elementor column from the currency/language/search/sign-in group,
       and style.css force-shows that column on phones with

           @media (max-width:767px) { #navbartrnas { display: flex } }

       an ID selector (1,0,0) that outranks .elementor .elementor-hidden-phone
       (0,2,0). The other originals are genuinely hidden; this one is not, which is
       why only the basket appeared twice. #maxwidthheader .nav-basket is 1,1,0 and
       nothing sets this !important, so it wins cleanly. */
    #maxwidthheader .nav-basket { display: none; }
}

/* Narrow phones: the strip plus the burger has to clear the logo on one line.
   The caret is the first thing to go (the pill is obviously a menu without it),
   then the padding and gaps tighten. Measured at 320px this leaves the burger
   inside the viewport with room to spare. */
@media (max-width: 420px) {
    .mhead-ctl { gap: 3px; }
    .mhead-ctl__btn { padding: 0 6px; gap: 3px; }
    .mhead-ctl__btn > i.mhead-ctl__caret { display: none; }
    .mhead-ctl__cart { width: 32px; }
    .mnav-burger { margin-left: 3px; }
}



/* ============================================================================
   37. HEADER DISAPPEARED ONCE THE PAGE WAS SCROLLED  (all devices; worst on iPhone)
   ----------------------------------------------------------------------------
   style.css makes the header invisible until script says otherwise:

       #elementor-header.main-menu-wrapper          { opacity: 0 }
       #elementor-header.main-menu-wrapper.visible  { opacity: 1 }

   and craftcoffee-custom.js removes .visible as soon as the page is scrolled
   100px, handing over to a separate #elementor-sticky-header. This site never
   had that second header, so past 100px the logo, menu, currency, language,
   basket and burger all went to opacity 0 — still there, still fixed and still
   clickable, just invisible.

   On an iPhone it looked like the header never appeared at all: Safari restores
   the previous scroll position on reload and on Back, and its collapsing toolbar
   fires scroll events, so the page is past 100px almost immediately.

   The header now always shows. Once scrolled (the theme adds .scroll at the same
   100px) it takes the solid ink band the account pages already use (section 19),
   because the transparent version was drawn to sit over a dark hero, and over
   ordinary page content its cream logo and icons would be unreadable.
   The theme's own files are left untouched.
   ========================================================================== */
#elementor-header.main-menu-wrapper {
    opacity: 1;
    transition: background-color .25s cubic-bezier(.22, .61, .36, 1),
                box-shadow .25s cubic-bezier(.22, .61, .36, 1);

    /* iPhone (every iOS browser is WebKit): the hero covered the header on load,
       and sections slid OVER it while scrolling, then it reappeared. Android
       Chrome was fine. WebKit paints GPU-composited layers — the hero slider,
       parallax and animated sections, all translate3d — above a fixed element
       that is not composited itself, whatever their z-index says, and during
       iOS momentum scrolling that is exactly when it shows.

       translate3d gives the header a layer of its own so it is ordered with
       them, and z-index 50 clears all page content (highest is 20) while
       staying under modals and drawers (100 and up).

       Safe for the full-screen search overlay inside the header: a transform
       makes it position against the header instead of the screen, but the
       header is pinned at 0,0 and the overlay is sized 100vw x 100vh, so it
       still covers exactly the screen. */
    z-index: 50;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
}

#elementor-header.main-menu-wrapper.scroll {
    background-color: #1C1A17;
    box-shadow: 0 1px 0 rgba(241, 234, 224, .10);
}



/* ============================================================================
   38. HEADER MISSING ON iPHONE — ITS PARENT CLIPPED AND BURIED IT
   ----------------------------------------------------------------------------
   Diagnosed on a real iPhone (iOS Safari), not guessed: the header reported
   itself present, opaque, z-index 50 and correctly placed — yet the element
   actually drawn at the logo's position was the home hero's container.

   The header's parent is #wrapper, and #wrapper holds NOTHING else: every page
   section lives in #page-content-wrapper, a sibling. The theme gives #wrapper
   `overflow-x:hidden`, which computes overflow-y to `auto` and so makes it a
   scroll container — 0px tall, since its only child is fixed.

   Desktop browsers and Android Chrome let a position:fixed child escape its
   parent's clipping and stacking. iOS WebKit composites a scroll container as
   its own layer and keeps the fixed child inside it: the header was clipped to
   a 0px box and ordered as part of #wrapper — which had no z-index, so the
   hero (a GPU layer: will-change:transform) painted over it. The header's own
   z-index never got a say.

   Fix on #wrapper itself:
     - overflow:visible   no longer a scroll container, nothing to clip to.
                          Sideways scroll stays prevented by html{overflow-x:hidden}
                          (section 1), which is where that belongs.
     - z-index:50         the header's group now outranks page content (max 20)
                          and stays under modals and drawers (100+). The box is
                          0px tall, so it cannot cover or block anything.
   ========================================================================== */
#wrapper,
#wrapper.hasbg.transparent {
    position: relative;
    z-index: 50;
    overflow: visible;
}



/* ============================================================================
   39. "EMPTY SPACE ON THE RIGHT" ON TABLETS, iPADS AND DEVTOOLS DEVICE MODE
   ----------------------------------------------------------------------------
   Measured across 18 widths (320-1920): from 1024px up, decorative theme pieces
   are positioned to bleed past the edge on purpose — coffee-sack/pot
   illustrations, giant background words ("FARM", "LOGISTICS") and the 6400px
   "OUR COMMITMENT" marquee. Up to 8000px of overflow on the home page.

   html{overflow-x:hidden} (section 1) hides that on a desktop browser, but iOS,
   iPadOS and Chrome's device mode do not reliably honour it on the root, so the
   page could be panned sideways onto blank cream.

   Clip at the content wrapper instead. `clip`, NOT `hidden`: hidden would turn
   the wrapper into a scroll container — the exact trap that buried the iPhone
   header (section 38) — and would break position:sticky (the cart summary).
   clip does neither. Nothing changes visually; the bleed is simply cut at the
   edge as designed. Browsers without `clip` (Safari < 16) ignore it: no change.

   Clipped at #perspective (full viewport width), NOT #page-content-wrapper: on
   desktop that wrapper carries a 45px side margin, and the home hero is an
   Elementor stretched section that deliberately reaches past it to both edges —
   clipping there trimmed 45px off each side of the hero image.
   ========================================================================== */
#perspective {
    overflow-x: clip;
}



/* ============================================================================
   40. HOME "ADD COFFEE PRODUCTS": TWO PER ROW ON PHONES (client request, Oct 2026)
   ----------------------------------------------------------------------------
   style.css drops the card grid to one column under 560px, so six products were
   six full screens of scrolling. Two per row on phones; tablet (2) and desktop
   (3) are untouched. Cards are ~170px wide here (~140px on a 320px phone), so the
   inside is compacted: smaller type, description clamped to two lines, MOQ moved
   under the price, and button labels allowed to wrap so "View & request a quote"
   never overflows. Scoped to .rp-section so no other grid is affected.
   ========================================================================== */
@media (max-width: 560px) {
    .rp-section .pg-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
    .rp-section .pg-card { border-radius: 10px; }
    .rp-section .pg-source { top: 8px; left: 8px; padding: 4px 7px; font-size: 7.5px; letter-spacing: .08em; gap: 4px; }
    .rp-section .pg-stock { top: 8px; right: 8px; padding: 3px 7px; font-size: 7.5px; }
    .rp-section .pg-body { padding: 11px 10px 12px; }
    .rp-section .pg-cat { font-size: 8.5px; letter-spacing: .1em; margin-bottom: 5px; }
    .rp-section .pg-name { font-size: 14.5px; line-height: 1.25; margin-bottom: 5px; overflow-wrap: anywhere; }
    .rp-section .pg-origin { font-size: 11px; margin-bottom: 6px; }
    /* flex:0 + max-height: the theme gives .pg-desc flex:1, which stretches the box
       and lets the clamped lines show through below the ellipsis. */
    .rp-section .pg-desc {
        font-size: 11.5px; line-height: 1.5; margin-bottom: 8px; flex: 0 0 auto; max-height: 3em;
        display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
    }
    .rp-section .pg-body > .pg-foot { margin-top: auto; }
    .rp-section .pg-rating { margin-bottom: 8px; }
    .rp-section .pg-rating i { font-size: 9.5px; }
    .rp-section .pg-rating span { font-size: 10px; }
    .rp-section .pg-foot { margin-bottom: 10px; }
    .rp-section .pg-price { font-size: 16px; gap: 2px 6px; line-height: 1.2; }
    .rp-section .pg-price small { font-size: 10px; }
    .rp-section .pg-moq { margin-left: 0; width: 100%; font-size: 8.5px; }
    .rp-section .pg-actions { gap: 6px; }
    .rp-section .pg-btn { padding: 9px 7px; font-size: 11.5px; line-height: 1.25; border-radius: 8px; text-align: center; white-space: normal; }
    .rp-section .pg-btn--ghost { width: 34px; padding: 9px 0; }
}
