/* ==========================================================================
   Pack Leader — global design system
   Fonts, tokens, and custom component behaviors used by the Elementor build.
   Class convention: .pl-*  (applied via Elementor "CSS Classes" controls)
   ========================================================================== */

/* ---- Plus Jakarta Sans (self-hosted) ---- */
/* Campaign pages rebuilt from the old site (ACANA Podcast, ORIJEN K9 Unit, 2026-10-20) keep the old site's fonts,
   self-hosted like Plus Jakarta Sans (Google Fonts, latin; Raleway and Roboto are variable, one file each). A face
   is only downloaded where text uses it. Registered with Elementor as system fonts (packleader-core.php), so
   Elementor never loads them from Google. */
@font-face {
  font-family: 'Raleway';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/raleway-v37-latin-variable.woff2') format('woff2');
}
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/roboto-v51-latin-variable.woff2') format('woff2');
}
@font-face {
  font-family: 'Lato';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../fonts/lato-v25-latin-300.woff2') format('woff2');
}
@font-face {
  font-family: 'Lato';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/lato-v25-latin-700.woff2') format('woff2');
}
@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/plus-jakarta-sans-v12-latin-regular.woff2') format('woff2'),
       url('../fonts/plus-jakarta-sans-v12-latin-regular.woff') format('woff');
}
@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/plus-jakarta-sans-v12-latin-500.woff2') format('woff2'),
       url('../fonts/plus-jakarta-sans-v12-latin-500.woff') format('woff');
}
@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/plus-jakarta-sans-v12-latin-600.woff2') format('woff2'),
       url('../fonts/plus-jakarta-sans-v12-latin-600.woff') format('woff');
}
@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/plus-jakarta-sans-v12-latin-700.woff2') format('woff2'),
       url('../fonts/plus-jakarta-sans-v12-latin-700.woff') format('woff');
}
@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/plus-jakarta-sans-v12-latin-italic.woff2') format('woff2'),
       url('../fonts/plus-jakarta-sans-v12-latin-italic.woff') format('woff');
}

/* ---- Design tokens ---- */
:root {
  --pl-forest: #173434;
  --pl-forest-deep: #12332C;
  --pl-green-hover: #2E8B62;
  --pl-cream: #FFF9F0;
  --pl-card: #FFF7F2;
  --pl-body: rgba(23, 52, 52, 0.63);
  --pl-beige-panel: #EAE1D5;
  --pl-panel-soft: #F0EBE3;
  --pl-sage: #E2E1CF;
  --pl-offer-tan: #E3D4BA;
  --pl-gold: #E2CD96;
  --pl-card-hover: #E0DCD0;
  --pl-lime: #B5D44E;
  --pl-field: #F8F1EB;
  --pl-marquee-fg: #C7C1BD;
  --pl-marquee-bg: #1E1E1E;
  --pl-panel: #1C3E3E;
  --pl-btn: #1D8167;
  --pl-nav: #737170;
  --pl-radius-lg: 24px;
  --pl-radius-md: 16px;
  --pl-ease: cubic-bezier(0.33, 1, 0.68, 1);
}
/* Site Settings › Global Colours drive the palette: Elementor prints the --e-global-color-*
   variables on body.elementor-kit-7, so the mapping is declared on body (a var() on :root
   would resolve before the kit's variables exist). The :root values above are fallbacks.
   Kit ids: primary #173434, secondary #2E8B62, accent #B5D44E, plcream … (Site Settings). */
body {
  --pl-forest: var(--e-global-color-primary, #173434);
  --pl-green-hover: var(--e-global-color-secondary, #2E8B62);
  --pl-cream: var(--e-global-color-plcream, #FFF9F0);
  --pl-card: var(--e-global-color-plcard, #FFF7F2);
  --pl-beige-panel: var(--e-global-color-plbeige, #EAE1D5);
  --pl-panel-soft: var(--e-global-color-plsoft, #F0EBE3);
  --pl-sage: var(--e-global-color-plsage, #E2E1CF);
  --pl-offer-tan: var(--e-global-color-pltan, #E3D4BA);
  --pl-gold: var(--e-global-color-plgold, #E2CD96);
  --pl-card-hover: var(--e-global-color-plhovcard, #E0DCD0);
  --pl-lime: var(--e-global-color-accent, #B5D44E);
  --pl-field: var(--e-global-color-plfield, #F8F1EB);
  --pl-marquee-bg: var(--e-global-color-pldark, #1E1E1E);
  --pl-panel: var(--e-global-color-plpanel, #1C3E3E);
  --pl-btn: var(--e-global-color-plbtn, #1D8167);
  --pl-nav: var(--e-global-color-plnav, #737170);
}

body {
  background-color: var(--pl-cream);
}
body a {
  color: var(--pl-forest);
  text-decoration: none;
}
body a:hover {
  color: var(--pl-green-hover);
}
/* Boxed page sections carry 35px side margins — width must respect them.
   In the Elementor editor the document being edited wraps its top-level containers in
   .elementor-section-wrap; the :where() twins give the preview the same geometry as the
   front end at the same specificity (footer 62 / 404 626 when they are the edited document). */
[data-elementor-type="wp-page"] > .e-con,
[data-elementor-type="footer"] > .e-con,
[data-elementor-type="wp-page"] > :where(.elementor-section-wrap) > .e-con,
[data-elementor-type="footer"] > :where(.elementor-section-wrap) > .e-con {
  width: auto !important;
  max-width: none !important;
}
html, body { overflow-x: clip; }

/* ==========================================================================
   1. Offer cards — frosted glass panel slides up on hover (Home)
   ========================================================================== */
.pl-offer-card {
  position: relative;
  overflow: hidden;
  border-radius: 18px;
  border: 1px solid rgba(23, 52, 52, 0.15);
}
.pl-offer-card .pl-reveal {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 12px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.71);
  border: 1px solid #FDFDFD;
  -webkit-backdrop-filter: blur(23px);
  backdrop-filter: blur(23px);
  transform: translateY(115%);
  transition: transform 0.45s var(--pl-ease);
  will-change: transform;
  z-index: 2;
}
.pl-offer-card:hover .pl-reveal,
.pl-offer-card:focus-within .pl-reveal {
  transform: translateY(0);
}
/* Card artwork — absolutely positioned to Figma geometry (inline styles carry the numbers) */
.elementor .pl-card-art,
.pl-card-art {
  position: absolute !important;
  max-width: none !important;
  pointer-events: none;
  z-index: 0;
  display: block;
}
.pl-offer-card > *:not(.elementor-widget-html, .elementor-widget-pl_card_art):not(.pl-reveal),
.pl-cta-card > *:not(.elementor-widget-html, .elementor-widget-pl_card_art) {
  position: relative;
  z-index: 1;
}
.pl-offer-card .pl-reveal { position: absolute !important; }
.pl-offer-card .elementor-widget-html,
.pl-cta-card .elementor-widget-html,
.pl-offer-card .elementor-widget-pl_card_art,
.pl-cta-card .elementor-widget-pl_card_art { position: static; }
.pl-card-top { width: 100%; }
.pl-photo-arrow { text-align: center; margin-top: 10px; }
/* photo card: dark scrim at rest, deepens on hover (design: rgba(0,0,0,.2) -> rgba(23,52,52,.74)) */
.pl-cta-card--photo::before {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.2);
  transition: background-color 0.35s ease;
  z-index: 0;
  pointer-events: none;
}
.pl-cta-card--photo:hover::before { background: rgba(23, 52, 52, 0.74); }

/* ==========================================================================
   2. CTA cards — overlay tint + arrow-chip inversion (Home "Delivered nationwide")
   ========================================================================== */
.pl-cta-card {
  position: relative;
  overflow: hidden;
  border-radius: var(--pl-radius-md);
  transition: background-color 0.35s ease;
}
.pl-cta-card .pl-arrow-chip {
  transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease;
}
/* dark card: cream chip -> outlined cream. The arrow strokes with currentColor,
   so the colour has to be set on the CHIP -- `fill` never touched a stroked
   path, which is why the arrow used to vanish into the dark card on hover. */
.pl-cta-card--dark:hover .pl-arrow-chip {
  background-color: transparent !important;
  border: 1px solid var(--pl-cream) !important;
  color: var(--pl-cream) !important;
}
/* light card: white chip -> outlined forest, bg warms to gold */
.pl-cta-card--light:hover {
  background-color: var(--pl-gold) !important;
}
.pl-cta-card--light:hover .pl-arrow-chip {
  background-color: transparent !important;
  border: 1px solid var(--pl-forest) !important;
  color: var(--pl-forest) !important;
}
/* photo card: forest tint fades in (overlay handled by Elementor hover overlay) */

/* Arrow chip — rounded square icon button used on cards */
.pl-arrow-chip {
  color: var(--pl-forest);   /* drives the arrow stroke via currentColor */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 37px;
  height: 33px;
  border-radius: 8px;
  background: var(--pl-cream);
  border: 1px solid transparent;
  flex: 0 0 auto;
}
.pl-arrow-chip--white { background: #FFFFFF; }
.pl-arrow-chip--outline {
  background: transparent;
  border-color: rgba(23, 52, 52, 0.45);
}
.pl-arrow-chip svg { display: block; }
/* Home CTA-card chips are Icon widgets (uploaded SVG) carrying this class — the widget is the chip; the
   icon inside is a plain block that takes the chip's colour (and its hover inversion) through currentColor. */
.pl-arrow-chip .elementor-icon { display: block; color: inherit !important; transition: none; }  /* beats the Icon widget's default (Primary) colour */
/* Elementor's `.elementor-element:where(.elementor-widget) { align-items: var(--align-items) }` ties the
   chip's centring on specificity and loads later. */
.pl-arrow-chip.elementor-widget { align-items: center; justify-content: center; }

/* ==========================================================================
   3. Connect CTA bar — gradient sweep + arrow rotation (footer)
   ========================================================================== */
.pl-connect {
  position: relative;
  overflow: hidden;
  border-radius: 13px;
  background: linear-gradient(63.33deg, #E9E8D7 22.76%, #D1D0BB 108.16%);
}
.pl-connect::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(63.33deg, #FAF9F1 22.76%, #B7B6A3 108.16%);
  opacity: 0;
  transition: opacity 0.4s ease;
  pointer-events: none;
  border-radius: inherit;
}
.pl-connect::after { z-index: 0; }
/* Elements only (was `.pl-connect > *`): in the editor the container also holds Elementor's
   absolutely placed overlay, shape-divider and resize-handle nodes; forcing those relative made
   them flex items and pushed the band's copy ~750px right in the preview. */
.pl-connect > .e-con,
.pl-connect > .elementor-element {
  position: relative !important;
  z-index: 2 !important;
}
/* pl-connect-arrow is the footer's Icon widget; the SVG inside it turns about its own centre. */
.pl-connect .pl-connect-arrow svg {
  transform: rotate(-45deg); /* resting: ↗ (icon drawn as →) */
  transition: transform 0.3s var(--pl-ease);
}
.pl-connect:hover::after {
  opacity: 1;
}
/* Page Settings → Pack Leader → "Hide the Connect with us footer band"
   (packleader-core.php). The Contact board 29:8903 uses the footer without it. */
body.pl-hide-connect [data-elementor-type="footer"] .pl-connect { display: none; }
.pl-connect:hover .pl-connect-arrow svg {
  transform: rotate(0deg); /* hover: → */
}

/* ==========================================================================
   4. Logo marquee — two staggered infinite rows (Brands page)
   ========================================================================== */
.pl-marquee {
  overflow: hidden;
  background: var(--pl-marquee-bg);
  padding: 22px 0;
}
.pl-marquee__track {
  display: flex;
  width: max-content;
  gap: 64px;
  align-items: center;
  animation: pl-marquee 40s linear infinite;
}
.pl-marquee--reverse .pl-marquee__track {
  animation-direction: reverse;
}
.pl-marquee__track img {
  height: 32px;
  width: auto;
  flex: 0 0 auto;
  opacity: 0.9;
}
@keyframes pl-marquee {
  to { transform: translateX(-50%); }
}
/* Diagonal ribbon variant (crossing corners of the "near you" band) */
.pl-near-band { position: relative; }
.pl-near-band .elementor-widget-html {
  position: absolute !important;
  inset: 0;
  pointer-events: none;
  z-index: 0 !important;
  overflow: hidden;
  border-radius: inherit;
}
.pl-ribbon {
  position: absolute;
  width: 70%;
  pointer-events: none;
}
.pl-ribbon--tl { left: -25%; top: 6%; transform: rotate(-33deg); }
.pl-ribbon--tr { right: -25%; top: 6%; transform: rotate(33deg); }
.pl-ribbon .pl-marquee { padding: 16px 0; background: var(--pl-forest); }
.pl-ribbon .pl-marquee__track img.pl-marquee__strip { height: 38px; }

/* ==========================================================================
   5. Brand directory cards (Loop Item)
   ========================================================================== */
.pl-brand-card {
  background: var(--pl-card);
  border: 1px solid #EDE5D8;
  border-radius: var(--pl-radius-md);
  transition: background-color 0.3s ease;
}
.pl-brand-card:hover {
  background: var(--pl-card-hover);
}
.pl-brand-card .pl-arrow-chip {
  transition: background-color 0.3s ease, color 0.3s ease;
}
.pl-brand-card:hover .pl-arrow-chip {
  background-color: var(--pl-forest) !important;
  border-color: var(--pl-forest) !important;
}
/* Figma 29:9361 (the card's hover variant): the same arrow, only its stroke turns #F4ECDF. The arrow is an open
   stroked line — a `fill` here used to fill its head into a solid triangle (client, 2026-10-12). */
.pl-brand-card:hover .pl-arrow-chip svg,
.pl-brand-card:hover .pl-arrow-chip i {
  color: #F4ECDF;
}
.pl-tag-pill {
  display: inline-block;
  background: #FFFFFF;
  border: 1px solid rgba(23, 52, 52, 0.25);
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 13px;
  color: var(--pl-forest);
}

/* Filter bar pills */
.pl-filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 30px;
}
button.pl-filter-pill {
  -webkit-appearance: none;
  appearance: none;
  font-family: 'Plus Jakarta Sans', sans-serif !important;
  font-size: 14px !important;
  font-weight: 600 !important;
  border: 1px solid var(--pl-forest) !important;
  border-radius: 999px !important;
  padding: 11px 22px !important;
  color: var(--pl-forest) !important;
  background: transparent !important;
  cursor: pointer;
  transition: all 0.25s ease;
  box-shadow: none !important;
  outline: none !important;
}
button.pl-filter-pill.is-active,
button.pl-filter-pill:hover,
button.pl-filter-pill:focus,
button.pl-filter-pill.is-active:focus {
  background: var(--pl-forest) !important;
  color: var(--pl-cream) !important;
  border-color: var(--pl-forest) !important;
}
/* ---- mobile: horizontally-scrollable "slider" instead of wrapping -------
   A single species row (All/Dogs/Cats) wraps fine at any width. But this bar
   is also the key-ingredient row once a brand's products carry tags — the
   client's own vocabulary (Lamb/Poultry/Pork/Fish/Beef) is five chips, and a
   wrapped multi-row block of pills reads as clutter and pushes the grid down
   unpredictably depending on how many chips happen to exist. A horizontal
   swipeable strip keeps the row's height constant regardless of chip count,
   which is the more scalable choice as more tags get added later — this
   applies everywhere `.pl-filter-bar` is used (brand directory too), so the
   behaviour stays consistent across the site rather than being one-off. */
@media ( max-width: 767px ) {
  .pl-filter-bar {
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    /* `.pl-bp-products` (the parent) is `align-items: center` — every child
       is sized to its OWN content and centred, not stretched to the parent's
       width. That's correct for a heading or a card grid, but it means this
       bar was never being asked to fit inside the section at all: measured
       directly, its content sized it to 612px while the section itself was
       only 362px, and it just rendered at its full 612px (centred),
       overflowing there was nothing to clip against. `min-width:0` was tried
       first and does nothing here — the bug isn't a refusal to shrink below
       min-content, it's that the box was never constrained to the parent's
       width in the first place. `align-self: stretch` overrides the
       parent's `center` for this one child, and THEN `overflow-x:auto`
       has an actual boundary to clip and scroll against. */
    align-self: stretch;
    width: 100%;
    min-width: 0;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;               /* Firefox */
    /* Fade the edges so a partially-cut-off chip reads as "there's more —
       swipe", not as a rendering glitch. Kept narrow (20px) so it doesn't
       clip a keyboard focus ring sitting near the edge. */
    -webkit-mask-image: linear-gradient( to right, transparent, #000 20px, #000 calc( 100% - 20px ), transparent );
    mask-image: linear-gradient( to right, transparent, #000 20px, #000 calc( 100% - 20px ), transparent );
    padding: 3px 2px;                    /* room for the focus ring, not clipped by the mask */
  }
  .pl-filter-bar::-webkit-scrollbar { display: none; }  /* Chromium/Safari */
  button.pl-filter-pill {
    flex: 0 0 auto;
    white-space: nowrap;
    scroll-snap-align: start;
  }
}

/* Brand directory grid + card internals */
.pl-brand-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 22px;
}
.pl-brand-card {
  padding: 16px 16px 26px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  /* Anchor landings from the nav (/brands/#brand-<slug>): clear the fixed
     header instead of scrolling the card underneath it. */
  scroll-margin-top: 130px;
}
/* The landed-on card announces itself — an external-brand menu click now
   arrives HERE rather than leaving the site, so the user needs to see at a
   glance which block they were brought to. */
.pl-brand-card:target {
  box-shadow: 0 0 0 2px var(--pl-green-hover), 0 14px 34px rgba(23, 52, 52, 0.16);
}
.pl-brand-card.is-hidden { display: none; }
.pl-brand-card .pl-brand-card__img img,
.elementor .pl-brand-card .pl-brand-card__img img {
  width: 100%;
  height: 196px;
  object-fit: cover;
  border-radius: 12px;
  display: block;
}
.pl-brand-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.pl-brand-card__title {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 26px;
  font-weight: 600;
  color: var(--pl-forest);
  margin: 0;
}
.pl-brand-card .pl-tag-pill { align-self: flex-start; }
.pl-brand-card__desc {
  font-size: 14px;
  font-weight: 500;
  line-height: 1.5;
  color: var(--pl-body);
  margin: 0;
}
@media (max-width: 1024px) {
  .pl-brand-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 767px) {
  .pl-brand-grid { grid-template-columns: 1fr; }
}

/* ==========================================================================
   6. Section overlaps (card pulled up over hero)
   ========================================================================== */
/* The overlap amounts (e.g. Home -286 / -160 / -48, About & Team -60 / -32) are each panel's own
   Elementor Margin (tablet / mobile too) since build/be-spacing.php; the classes only lift the panel
   above the hero. */
.pl-overlap-sm,
.pl-overlap-md,
.pl-overlap-lg { position: relative; z-index: 5; }

/* ==========================================================================
   7. Grain / riso texture overlay
   ========================================================================== */
.pl-texture {
  position: relative;
}
.pl-texture::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url('../img/pl-grain.png');
  background-repeat: repeat;
  opacity: 0.35;
  mix-blend-mode: overlay;
  pointer-events: none;
  border-radius: inherit;
  z-index: 0;
}
.pl-texture > * { position: relative; z-index: 1; }
/* The grain belongs to the panel, not to what sits on it (client, 2026-10-08: the dots ran over the paws and the
   box on the Home cards, and over the footer logo). Two things beat the rule above:
   - card art (.pl-card-art) is absolutely placed at z-index 0, level with the grain and earlier in the page, so
     the grain painted over it — it goes to 1 (the card's title and arrow come after it, so they stay on top);
   - Elementor's `.e-con { z-index: var(--z-index) }` loads later and resets child containers to auto — its own
     variable is set instead, so a container's z-index set in Elementor still wins. */
.pl-texture .pl-card-art { z-index: 1; }
.pl-texture > .e-con,
.pl-texture > .e-con-inner > .e-con { --z-index: 1; }

/* Left scrim — solid brand green fading over a right-aligned photo */
.pl-scrim-left { position: relative; }
.pl-scrim-left::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--pl-forest) 42%, rgba(23, 52, 52, 0.35) 72%, rgba(23, 52, 52, 0) 100%);
  pointer-events: none;
  border-radius: inherit;
}
.pl-scrim-left > * { position: relative; z-index: 1; }

/* Figma scrim rectangles (About "What we do" / Team "Join our pack"):
   an opaque fill at the left edge fading to zero at 70.2% of the band. */
.pl-scrim-stone,
.pl-scrim-forest { position: relative; }
.pl-scrim-stone::after,
.pl-scrim-forest::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  z-index: 0;
}
.pl-scrim-stone::after {
  background: linear-gradient(90deg, rgb(136, 133, 128) 0%, rgba(136, 133, 128, 0) 70.2%);
}
.pl-scrim-forest::after {
  background: linear-gradient(90deg, rgb(23, 52, 52) 0%, rgba(23, 52, 52, 0) 70.2%);
}
.pl-scrim-stone > *,
.pl-scrim-forest > * { position: relative; z-index: 1; }

/* ==========================================================================
   8. Stats band
   ========================================================================== */
.pl-stat-blur {
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  background: rgba(23, 52, 52, 0.18);
  border-radius: 999px;
}
.pl-stats-band .elementor-heading-title {
  text-shadow: 0 2px 14px rgba(0, 0, 0, 0.35);
}

/* ==========================================================================
   9. Philosophy columns — vertical hairline dividers
   ========================================================================== */
.pl-divide-col {
  border-left: 1px solid rgba(23, 52, 52, 0.15);
}

/* ==========================================================================
   10. Why-partners rows — top hairline rules
   ========================================================================== */
.pl-why-row > * { flex-shrink: 0; }
.pl-why-row .elementor-widget-text-editor { flex-grow: 0; }
@media (max-width: 767px) {
  .pl-why-row { flex-direction: column; gap: 12px !important; }
  .pl-why-row > * { width: 100% !important; }
}
/* "Why partners choose us" paws and the footer "Connect" arrow are Icon widgets (uploaded SVG, Size and
   Colour in the widget). The icon box is the SVG's own box, as with the old inline SVG — Elementor's
   inline-block .elementor-icon would otherwise add a line-box descent under it. */
.pl-paw-icon .elementor-icon { display: block; }

/* ==========================================================================
   11. Buy online — dashed retailer grid
   ========================================================================== */
.pl-dash-grid {
  display: grid;
  grid-template-columns: repeat(20, 1fr);
}
.pl-dash-grid .pl-dash-cell { grid-column: span 5; }
.pl-dash-grid .pl-dash-cell:nth-child(n+9) { grid-column: span 4; }
.pl-dash-grid .pl-dash-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 34px 24px;
  outline: 1px dashed rgba(23, 52, 52, 0.35);
  outline-offset: -0.5px;
}
.pl-dash-grid .pl-dash-cell img {
  max-height: 110px;
  width: auto;
  max-width: 80%;
  object-fit: contain;
}

/* ==========================================================================
   11b. Agile Store Locator — brand reskin
   ========================================================================== */
.pl-locator .asl-cont,
.pl-locator .asl-cont * {
  font-family: 'Plus Jakarta Sans', sans-serif !important;
}
.pl-locator .asl-cont .asl-buttons a,
.pl-locator .asl-cont button.asl-btn,
.pl-locator .asl-cont .asl-btn {
  background: var(--pl-forest) !important;
  color: var(--pl-cream) !important;
  border-radius: 999px !important;
  border-color: var(--pl-forest) !important;
}
.pl-locator .asl-cont .asl-btn:hover {
  background: var(--pl-green-hover) !important;
}
.pl-locator .asl-cont input[type="text"],
.pl-locator .asl-cont select {
  background: var(--pl-field) !important;
  border: 1px solid rgba(23, 52, 52, 0.12) !important;
  border-radius: 8px !important;
  color: var(--pl-forest) !important;
}
.pl-locator .asl-cont .asl-panel,
.pl-locator .asl-cont .asl-list {
  background: transparent !important;
}
.pl-locator .asl-cont .asl-map {
  border-radius: 16px;
  overflow: hidden;
  min-height: 540px;
  background: var(--pl-forest);
}
.pl-locator .asl-cont .asl-store {
  border: 1px solid rgba(23, 52, 52, 0.14) !important;
  border-radius: 14px !important;
  background: #FFFFFF !important;
  margin-bottom: 12px !important;
}
.pl-locator .asl-cont .asl-store .asl-name,
.pl-locator .asl-cont .asl-store .asl-name a {
  color: var(--pl-forest) !important;
  font-weight: 600 !important;
}
/* ASL preset-0 accent overrides (red preset -> forest) */
.pl-locator .asl-cont.asl-bg-0 .asl-shops-count,
.pl-locator .asl-cont.asl-bg-0 .num-shops,
.pl-locator .asl-cont.asl-bg-0 .asl-count-hdr,
.pl-locator .asl-cont.asl-bg-0 .sl-addr-sec .btn,
.pl-locator .asl-cont.asl-bg-0 a.asl-directions,
.pl-locator .asl-cont.asl-bg-0 .asl-buttons .btn,
.pl-locator .asl-cont.asl-bg-0 .btn-danger,
.pl-locator .asl-cont.asl-bg-0 .input-group-text,
.pl-locator .asl-cont.asl-bg-0 .asl-search-event,
.pl-locator .asl-cont.asl-bg-0 .sl-head-title {
  background-color: var(--pl-forest) !important;
  border-color: var(--pl-forest) !important;
  color: var(--pl-cream) !important;
}
.pl-locator .asl-cont.asl-bg-0 .asl-cntrl-lbl,
.pl-locator .asl-cont.asl-bg-0 .asl-panel a:not(.btn) {
  color: var(--pl-forest) !important;
}
.pl-locator .asl-cont .asl-panel-inner {
  background: transparent !important;
}
.pl-locator .sl-head-title,
.pl-locator .top-title,
.pl-locator .Num_of_store { display: none !important; }
.pl-locator .asl-cont [class*="icon-"],
.pl-locator .asl-cont [class*="icon-"]::before {
  color: var(--pl-forest) !important;
}
.pl-locator .asl-cont .asl-map {
  background: transparent !important;
  height: auto !important;
}
.pl-locator .asl-cont.asl-bg-0 .asl-p-cont label,
.pl-locator .asl-cont.asl-bg-0 label {
  color: var(--pl-forest) !important;
}

/* ==========================================================================
   12. Floating pill navigation
   ========================================================================== */
.pl-nav {
  background: var(--pl-cream);
  border-radius: 999px;
}
/* The pill must be rounded AT REST, not only once sticky: Elementor's own
   container radius (`--border-radius: 0` via .e-con) was beating the rule
   above, which went unnoticed while every page was flat cream — on the
   2026-09 brand-tinted pages (ACANA, Taste of the Wild) it showed as a hard
   cream rectangle. 29:9033 is rounded-128 in its resting state. */
[data-elementor-type="header"] .e-con.pl-nav {
  border-radius: 128px;
}
/* 29:9033: "Partner Log In" ends 50px inside the pill's right edge (the nav
   links start 33px inside the left one) — the CTA zone's own 17px desktop
   Padding Right in the header template. */
.pl-nav .elementor-nav-menu a {
  transition: color 0.2s ease !important;
}
/* "Contact us" in the bar's right-hand zone (29:9033) is a plain link set
   exactly like the nav links on the left — a button widget stripped to its
   text so the client still edits it as a button in the header template. */
.pl-nav .pl-nav-textlink .elementor-button {
  min-height: 0;
  padding: 0 !important;
  border: 0;
  background: transparent !important;
  box-shadow: none;
  transition: color 0.2s ease !important;
}
/* dropdown panel as rounded pill */
.pl-nav .elementor-nav-menu--dropdown {
  border-radius: 24px;
  overflow: hidden;
  box-shadow: 0 12px 30px rgba(23, 52, 52, 0.14);
}
.pl-nav .elementor-nav-menu--dropdown a {
  transition: background-color 0.25s ease, color 0.25s ease;
}
.pl-nav .elementor-nav-menu--dropdown a:hover {
  background: var(--pl-forest);
  color: var(--pl-cream) !important;
}

/* ==========================================================================
   13. Forms (Elementor Pro Form widget skin)
   ========================================================================== */
.pl-form .elementor-field {
  background: var(--pl-field);
  border: 1px solid rgba(23, 52, 52, 0.12);
  border-radius: 8px;
  color: var(--pl-forest);
}
.pl-form .elementor-field::placeholder {
  color: var(--pl-body);
}
.pl-form .elementor-field:focus {
  border-color: var(--pl-forest);
  outline: none;
}
.pl-form a { text-decoration: underline; }
/* Hover colour likewise comes from the Form widget (Button → Hover). */

/* ==========================================================================
   14. Media helpers
   ========================================================================== */
.pl-media-rounded,
.elementor .pl-media-rounded img,
.elementor .pl-media-rounded video,
.elementor .pl-media-rounded iframe {
  border-radius: var(--pl-radius-md) !important;
  overflow: hidden;
  object-fit: cover;
}
/* Contact media block fills its column height */
.elementor .pl-media-fill,
.elementor .pl-media-fill .elementor-widget-container,
.elementor .pl-media-fill img {
  height: 100%;
}
.elementor .pl-media-fill img {
  object-fit: cover;
  border-radius: var(--pl-radius-md) !important;
}

/* ==========================================================================
   15. Touch / reduced motion fallbacks
   ========================================================================== */
@media (hover: none) {
  /* show offer-card reveal statically on touch devices */
  .pl-offer-card .pl-reveal {
    position: static;
    transform: none;
    margin: 12px;
  }
  .pl-connect .pl-connect-arrow svg { transform: rotate(0deg); }
}
@media (prefers-reduced-motion: reduce) {
  .pl-marquee__track { animation: none; }
  .pl-offer-card .pl-reveal,
  .pl-connect::before,
  .pl-connect .pl-connect-arrow svg { transition: none; }
}

/* ==========================================================================
   16. Responsive adjustments (breakpoints: 1024 tablet / 767 mobile)
   ========================================================================== */
@media (max-width: 1024px) {
  .pl-dash-grid { grid-template-columns: repeat(3, 1fr); }
  .pl-dash-grid .pl-dash-cell,
  .pl-dash-grid .pl-dash-cell:nth-child(n+9) { grid-column: auto; }
}
.pl-stat-sub { font-size: 0.4em; font-weight: 500; }
/* Heading sizes per breakpoint are set in each widget's Elementor typography controls
   (build/be-typography.php, 2026-09-30); the blanket h1/h2/h3 !important sizes that were
   here overrode the editor on every page. Go Natural's hero headings (page 45) carry
   their 28px phone size in their own typography too (build/fix-gonatural-be.php). */
@media (max-width: 767px) {
  .pl-dash-grid { grid-template-columns: repeat(2, 1fr); }
  .pl-dash-grid .pl-dash-cell,
  .pl-dash-grid .pl-dash-cell:nth-child(n+9) { grid-column: auto; }
  .pl-divide-col {
    border-left: 0;
    border-top: 1px solid rgba(23, 52, 52, 0.15);
  }
  .pl-marquee__track img { height: 24px; }
  .pl-marquee__track { gap: 40px; }
}

/* ==========================================================================
   17. About us / Our Team — Figma conformance (scoped to those sections only)
   Note: boxed Elementor containers wrap children in .e-con-inner, and the
   image widget renders <img> directly (no .elementor-widget-container).
   ========================================================================== */

/* -- 17a. Overlap cards (About "How it started", Team intro)
   Figma: 1px hairline + 27.2px soft shadow, equal columns, 10px photo radius. */
.pl-fcard {
  border: 1px solid rgba(23, 52, 52, 0.15);
  box-shadow: 0 0 27.2px 0 rgba(23, 52, 52, 0.06);
}
.pl-fcard > .e-con-inner > .e-con,
.pl-fcard > .e-con-inner > .elementor-widget {
  flex: 1 1 0 !important;
  min-width: 0;
}
.elementor .pl-fcard .elementor-widget-image img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 10px;
}
.pl-fcard--stretch > .e-con-inner > .elementor-widget-image {
  align-self: stretch;
  position: relative;
}
/* the stretched photo must not drive the card height — the copy column does */
.elementor .pl-fcard--stretch .elementor-widget-image img { position: absolute; inset: 0; }
/* single-paragraph copy blocks: no stray <p> margins (Figma spaces with flex gaps) */
.pl-tight-p .elementor-widget-text-editor p { margin: 0; }
/* Team intro photo is a fixed 306px band in the design */
.elementor .pl-team-intro .elementor-widget-image img { height: 306px; }

/* -- 17b. Paragraph rhythm inside the "How it started" copy (21px gap) */
.pl-p21 p { margin: 0 0 21px; }
.pl-p21 p:last-child { margin-bottom: 0; }

/* -- 17c. About "What we do" band — Figma photo framing + 20% darkening layer */
.pl-ww-band {
  background-size: 103.24% auto !important;
  background-position: 22% 17% !important;
  background-repeat: no-repeat !important;
}
.pl-ww-band::before {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.2);
  border-radius: inherit;
  pointer-events: none;
  z-index: 0;
}

/* -- 17d. About "Go Natural" banner */
.pl-gn-band { position: relative; }
.pl-gn-band > .e-con-inner > .e-con { position: relative; z-index: 2; }
/* logo: 425px-wide artwork clipped to the 386x95 box used in the design */
.pl-gn-logo {
  width: 425px;
  max-width: 100%;
  aspect-ratio: 425 / 95;
  overflow: hidden;
  position: relative;
}
.elementor .pl-gn-logo img {
  position: absolute;
  left: 0;
  top: -13.4%;
  width: 100%;
  max-width: none;
  height: auto;
  display: block;
}
/* ingredients collage: bleeds off the right edge of the banner. 2026-09 board
   29:8898 sits it flush with the band top at x650 (the band is now 349 tall). */
.pl-gn-ingredients {
  position: absolute !important;
  left: 47.448%;
  top: 0;
  width: 69.9%;
  z-index: 1;
  overflow: hidden;
  aspect-ratio: 957 / 344;
  border-radius: 60px 60px 0 60px;
  transform: scaleX(-1);
}
.elementor .pl-gn-ingredients img {
  position: absolute;
  left: 0;
  top: -59.16%;
  width: 120.83%;
  max-width: none;
  height: auto;
  display: block;
}

/* -- 17e. Team "It's personal" — 3 equal 335px photos, 13px radius, 12px gutters */
.pl-personal { border: 1px solid rgba(23, 52, 52, 0.15); }
.pl-img3 > .elementor-widget {
  flex: 1 1 0 !important;
  min-width: 0;
}
.elementor .pl-img3 .elementor-widget-image img {
  display: block;
  width: 100%;
  height: 335px;
  object-fit: cover;
  border-radius: 13px;
}

/* -- 17f. Team "Join our pack" — photo scaled/offset exactly as the Figma frame
   (2026-09 board 29:9214: 2029.5 wide at x -53.2 → 8.07%). */
.pl-join-band {
  background-size: 148.14% auto !important;
  background-position: 8.07% 36% !important;
}

/* -- 17g. Responsive */
@media (max-width: 1024px) {
  .pl-gn-band > .e-con-inner { flex-direction: column !important; }
  .pl-gn-band > .e-con-inner > .e-con,
  .pl-gn-band > .e-con-inner > .elementor-widget { width: 100% !important; align-self: stretch; }
  .pl-gn-ingredients {
    position: relative !important;
    left: auto;
    top: auto;
    width: 100%;
    transform: none;
    margin-top: 28px;
    aspect-ratio: auto;
    overflow: visible;
    border-radius: 0;
  }
  .elementor .pl-gn-ingredients img {
    position: static;
    width: 100%;
    height: auto;
    border-radius: 24px;
  }
  .elementor .pl-img3 .elementor-widget-image img { height: 240px; }
  .elementor .pl-team-intro .elementor-widget-image img { height: 260px; }
  /* keep the photo but darken the scrim so cream copy stays legible */
  .pl-scrim-forest::after {
    background: linear-gradient(90deg, rgb(23, 52, 52) 0%, rgba(23, 52, 52, 0.72) 100%);
  }
  .pl-scrim-stone::after {
    background: linear-gradient(90deg, rgb(136, 133, 128) 0%, rgba(136, 133, 128, 0.6) 100%);
  }
}
@media (max-width: 767px) {
  .pl-fcard > .e-con-inner > .e-con,
  .pl-fcard > .e-con-inner > .elementor-widget {
    flex: 0 0 auto !important;
    width: 100%;
  }
  .elementor .pl-fcard .elementor-widget-image img,
  .elementor .pl-team-intro .elementor-widget-image img { height: 230px; }
  .elementor .pl-img3 .elementor-widget-image img { height: 210px; }
  .pl-gn-logo { max-width: 240px; }
  .pl-gn-ingredients { margin-top: 22px; }
  .pl-join-band { background-image: none !important; }
  /* photo bands: flat overlay instead of a horizontal fade on a narrow screen */
  .pl-ww-band {
    background-size: cover !important;
    background-position: 62% center !important;
  }
  .pl-scrim-stone::after { background: rgba(74, 72, 68, 0.74); }
  .pl-scrim-forest::after { background: rgba(23, 52, 52, 0.8); }
}

/* ==========================================================================
   18. Brands / Stockists / Contact — strict Figma conformance
   Scoped to those pages' components so Home/About/Team are untouched.
   Sources: brands 1:402, stockists 1:471, contact 1:369,
            brand card 1:592, filter chip 1:623, retailer tile 1:2061.
   ========================================================================== */

/* ---- 18.1 Hero headings (brands 1:407, stockists 1:474) ---- */
.pl-hero-h1 .elementor-heading-title {
  max-width: 961px;
  margin-left: auto;
  margin-right: auto;
}
/* riso texture on photography: soft-light, per Figma 1:408 / 1:475 */
.pl-texture-soft { position: relative; }
.pl-texture-soft::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url('../img/pl-grain.png');
  background-repeat: repeat;
  opacity: 0.4;
  mix-blend-mode: soft-light;
  pointer-events: none;
  border-radius: inherit;
  z-index: 1;
}
.pl-texture-soft > * { position: relative; z-index: 2; }

/* ---- 18.2 Section overlaps measured from the Figma frames ---- */
/* amounts (-47 / -69, phone -32) are the panels' own Elementor Margin */
.pl-overlap-47,
.pl-overlap-69 { position: relative; z-index: 5; }

/* ---- 18.3 Brand directory (Figma 1:592 / 1:623 / 1:417) ---- */
.pl-brand-directory .pl-filter-bar {
  gap: 12px;
  margin-bottom: 29px;
  padding-bottom: 28px;
  border-bottom: 1px solid rgba(23, 52, 52, 0.15);
}
.pl-brand-directory button.pl-filter-pill {
  font-size: 16px !important;
  font-weight: 500 !important;
  padding: 12px 23px !important;
  border-radius: 44px !important;
  line-height: 1.19 !important;
}
.pl-brand-directory button.pl-filter-pill.is-active,
.pl-brand-directory button.pl-filter-pill:hover,
.pl-brand-directory button.pl-filter-pill:focus {
  background: var(--pl-forest) !important;
  color: var(--pl-cream) !important;
  border-color: var(--pl-forest) !important;
}

.pl-brand-directory .pl-brand-grid {
  grid-template-columns: repeat(3, 1fr);
  column-gap: 19px;
  row-gap: 28px;
}
.pl-brand-directory .pl-brand-card {
  background: transparent;
  border: 1px solid rgba(23, 52, 52, 0.13);
  border-radius: 24px;
  padding: 14px;
  gap: 23px;
  transition: background-color 0.3s ease;
}
.pl-brand-directory .pl-brand-card:hover { background: #F4ECDF; }
.elementor .pl-brand-directory .pl-brand-card .pl-brand-card__img img,
.pl-brand-directory .pl-brand-card .pl-brand-card__img img {
  height: 191px;
  border-radius: 16px;
  object-fit: cover;
  object-position: center;
}
.pl-brand-directory .pl-brand-card__body {
  display: flex;
  flex-direction: column;
  gap: 19px;
}
.pl-brand-directory .pl-brand-card__head {
  align-items: flex-start;
  gap: 16px;
}
.pl-brand-directory .pl-brand-card__titles {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  min-width: 0;
}
.pl-brand-directory .pl-brand-card__title {
  font-size: 28px;
  font-weight: 500;
  line-height: 1.26; /* Figma "normal" for Plus Jakarta Sans (35.3px at 28px) */
}
.pl-brand-directory .pl-brand-card .pl-tag-pill {
  background: #FFFFFF;
  border: 1px solid rgba(23, 52, 52, 0.14);
  border-radius: 54px;
  padding: 7px 10px;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.19;
  color: #000000;
}
.pl-brand-directory .pl-brand-card .pl-arrow-chip--outline {
  background: transparent;
  border: 1px solid var(--pl-forest);
  border-radius: 8px;
  width: 37px;
  height: 33px;
  color: var(--pl-forest);
}
.pl-brand-directory .pl-brand-card .pl-arrow-chip svg { width: 22px; height: 15px; }
.pl-brand-directory .pl-brand-card__desc {
  font-size: 16px;
  font-weight: 500;
  line-height: 1.25;
  color: rgba(23, 52, 52, 0.69);
}

/* ---- 18.4 "Find brands near you" ribbons (Figma 1:426 / 1:428) ---- */
.pl-near-band .pl-ribbon {
  width: 1500px;
  transform-origin: 50% 50%;
}
.pl-near-band .pl-ribbon--tl {
  left: 30%;
  right: auto;
  top: -74px;
  transform: translate(-50%, -50%) rotate(-30deg);
}
.pl-near-band .pl-ribbon--tr {
  left: 70%;
  right: auto;
  top: -101px;
  transform: translate(-50%, -50%) rotate(30deg);
}
.pl-near-band .pl-ribbon .pl-marquee {
  padding: 0;
  background: var(--pl-forest);
}
.pl-near-band .pl-ribbon .pl-marquee__track { gap: 0; }
.pl-near-band .pl-ribbon .pl-marquee__track img.pl-marquee__strip {
  height: 65px;
  opacity: 1;
}
@media (max-width: 767px) {
  .pl-near-band .pl-ribbon { width: 900px; }
  .pl-near-band .pl-ribbon--tl { top: -50px; }
  .pl-near-band .pl-ribbon--tr { top: -70px; }
  .pl-near-band .pl-ribbon .pl-marquee__track img.pl-marquee__strip { height: 44px; }
}

/* ---- 18.5 Buy online dashed grid (Figma 1:2061 / 1:552) ---- */
.pl-dash-grid .pl-dash-cell {
  padding: 17.76% 14.07%;
  outline: none;
  border: 1px dashed rgba(23, 52, 52, 0.5);
  margin: -0.5px;
  transition: background-color 0.3s ease;
}
.pl-dash-grid .pl-dash-cell:hover { background: #F3EADC; }
.pl-dash-grid .pl-dash-cell > a {
  display: block;
  width: 100%;
}
.elementor .pl-dash-grid .pl-dash-cell img,
.pl-dash-grid .pl-dash-cell img {
  width: 100%;
  max-width: 100%;
  max-height: none;
  aspect-ratio: 360 / 209;
  object-fit: contain;
  display: block;
}

/* ---- 18.6 Store locator — Agile Store Locator skin (Figma 1:481) ---- */
.pl-locator .asl-cont { --pl-asl-panel: 460px; }
.pl-locator .sl-container { max-width: none !important; padding: 0 !important; }
.pl-locator .sl-row { margin: 0 !important; }
/* search row lives inside the results panel, above the store cards */
.pl-locator .asl-panel-inner {
  border: 1px solid rgba(23, 52, 52, 0.14);
  border-radius: 14px;
  background: #FFFFFF;
  padding: 24px 25px;
  overflow: hidden;
}
.pl-locator .Filter_section {
  background: transparent !important;
  border: 0 !important;
  padding: 0 0 24px !important;
  margin: 0 !important;
  display: flex !important;
  flex-wrap: nowrap;
  gap: 6px;
  align-items: center;
}
.pl-locator .Filter_section .search_filter {
  flex: 1 1 auto;
  width: auto !important;
  max-width: none !important;
  padding: 0 !important;
}
.pl-locator .Filter_section .pol-lg-8 {
  flex: 0 0 auto;
  width: auto !important;
  max-width: none !important;
  padding: 0 !important;
}
.pl-locator .Filter_section label { display: none !important; }
.pl-locator .Filter_section .sl-search-group {
  border: 1px solid rgba(23, 52, 52, 0.14);
  border-radius: 10px;
  overflow: hidden;
  background: #FFFFFF;
  height: 42px;
}
.pl-locator .asl-cont input.asl-search-address {
  background: #FFFFFF !important;
  border: 0 !important;
  border-radius: 0 !important;
  height: 40px !important;
  font-size: 15px !important;
  box-shadow: none !important;
}
.pl-locator .asl-cont .input-group-append { padding: 4px; }
.pl-locator .asl-cont button.asl-search-event {
  background: var(--pl-forest) !important;
  border: 1px solid rgba(255, 255, 255, 0.15) !important;
  border-radius: 8px !important;
  color: #FFFFFF !important;
  min-width: 55px;
  height: 33px !important;
  font-size: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.pl-locator .asl-cont button.asl-search-event::after {
  /* Text = Settings › Pack Leader › "Search button" (inc/settings.php prints --pl-lbl-find). */
  content: var(--pl-lbl-find);
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: #FFFFFF;
}
.pl-locator .asl-cont button.asl-search-event i,
.pl-locator .asl-cont button.asl-search-event i::before { display: none !important; }
.pl-locator .asl-cont button.asl-search-event:hover { background: var(--pl-green-hover) !important; }
/* distance dropdown */
.pl-locator .asl-cont .asl-advance-filters,
.pl-locator .asl-cont .asl-advance-filters > .sl-row,
.pl-locator .asl-cont .range_filter,
.pl-locator .asl-cont .asl-filter-cntrl { width: auto !important; max-width: none !important; padding: 0 !important; margin: 0 !important; }
.pl-locator .asl-cont .Status_filter { display: none !important; }
.pl-locator .asl-cont .sl-dropdown-cont,
.pl-locator .asl-cont .sl-dropdown-cont .btn-group { width: 134px !important; height: 42px; }
.pl-locator .asl-cont .sl-dropdown-cont .btn-group > button,
.pl-locator .asl-cont .sl-dropdown-cont .dropdown-toggle {
  background: #FFFFFF !important;
  border: 1px solid rgba(23, 52, 52, 0.14) !important;
  border-radius: 10px !important;
  color: var(--pl-forest) !important;
  height: 42px !important;
  font-size: 15px !important;
  box-shadow: none !important;
  text-align: left;
}
/* results list + store card */
.pl-locator .asl-cont .sl-main-cont-box,
.pl-locator .asl-cont .sl-list-wrapper { background: transparent !important; }
.pl-locator .asl-cont ul.sl-list > li,
.pl-locator .asl-cont .asl-store {
  border: 1px solid rgba(23, 52, 52, 0.14) !important;
  border-radius: 14px !important;
  background: #FFFFFF !important;
  margin-bottom: 12px !important;
  padding: 16px 20px !important;
  list-style: none;
}
.pl-locator .asl-cont ul.sl-list { padding: 0 !important; margin: 0 !important; }
.pl-locator .asl-cont .sl-addr-list-title {
  color: var(--pl-forest) !important;
  font-size: 18px !important;
  font-weight: 600 !important;
  margin: 0 0 10px !important;
}
.pl-locator .asl-cont .sl-addr-sec ul {
  list-style: none;
  margin: 0 !important;
  padding: 0 !important;
}
.pl-locator .asl-cont .sl-addr-sec ul li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 14px;
  line-height: 1.6;
  color: rgba(23, 52, 52, 0.75);
  border: 0 !important;
  padding: 0 !important;
  margin: 0 0 4px !important;
  background: transparent !important;
}
.pl-locator .asl-cont .sl-addr-sec ul li a { color: rgba(23, 52, 52, 0.75) !important; }
.pl-locator .asl-cont .sl-act-btns {
  display: flex;
  gap: 6px;
  margin-top: 14px !important;
}
.pl-locator .asl-cont .sl-act-btns .btn-asl,
.pl-locator .asl-cont a.s-direction {
  background: var(--pl-forest) !important;
  border: 1px solid rgba(255, 255, 255, 0.15) !important;
  border-radius: 8px !important;
  color: #FFFFFF !important;
  font-size: 0 !important;
  padding: 10px 13px !important;
  line-height: 1 !important;
  display: inline-flex;
  align-items: center;
}
.pl-locator .asl-cont a.s-direction::after {
  /* No drawn copy: the button shows its own text, Store Locator label "Directions" (pl-locator.css). */
  content: none;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: #FFFFFF;
}
.pl-locator .asl-cont a.s-direction:hover { background: var(--pl-green-hover) !important; }
.pl-locator .asl-cont a.pl-call-now {
  border: 1px solid rgba(23, 52, 52, 0.22) !important;
  border-radius: 10px !important;
  background: transparent !important;
  color: var(--pl-forest) !important;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 14px;
  font-weight: 500;
  padding: 10px 13px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}
.pl-locator .asl-cont a.pl-call-now:hover { background: #FFFFFF !important; }
/* panel / map geometry per Figma: 460 | 10 | 725 */
.pl-locator .sl-main-row {
  display: flex !important;
  flex-wrap: nowrap !important;
  align-items: flex-start;
  gap: 10px;
  margin: 0 !important;
  width: 100% !important;
}
.pl-locator .sl-main-cont,
.pl-locator .pol-12 {
  width: 100% !important;
  max-width: none !important;
  margin: 0 !important;
  padding: 0 !important;
}
.pl-locator #asl-panel.asl-panel {
  flex: 0 0 38.49% !important;
  max-width: 38.49% !important;
  width: 38.49% !important;
  height: 625px !important;
  padding: 0 !important;
  overflow: visible !important;
}
.pl-locator .asl-panel-inner {
  position: relative !important;
  inset: auto !important;
  height: 100% !important;
  width: 100% !important;
  display: flex !important;
  flex-direction: column;
}
.pl-locator .sl-main-cont-box {
  height: auto !important;
  max-height: none !important;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto !important;
  overflow-x: hidden;
}
.pl-locator #asl-list,
.pl-locator ul.sl-list { height: auto !important; max-height: none !important; }
.pl-locator .asl-map {
  flex: 0 0 60.67% !important;
  max-width: 60.67% !important;
  width: 60.67% !important;
  padding: 0 !important;
  height: 625px !important;
}
.pl-locator .asl-map .map-image,
.pl-locator .asl-map #asl-map-canv {
  border-radius: 14px;
  overflow: hidden;
  height: 625px !important;
}
/* No Google Maps API key on this environment: suppress the injected
   "can't load Google Maps correctly" dialog. It disappears on its own
   once a key is installed. */
.pl-locator #asl-map-canv > div:not(:first-child) { display: none !important; }
.pl-locator .asl-cont .agile-modal-header h4 { color: var(--pl-forest) !important; }

/* ---- 18.7 Contact form + locations (Figma 1:373 / 1:393) ---- */
.pl-contact-card { position: relative; }
.pl-form .elementor-field-group { margin-bottom: 0; }
.elementor .pl-form .elementor-field,
.pl-form .elementor-field {
  background: rgba(238, 232, 224, 0.4) !important;
  border: 1.161px solid rgba(23, 52, 52, 0.14) !important;
  border-radius: 12.767px !important;
  color: var(--pl-forest) !important;
  padding: 12px 17px !important;   /* field text 16.25px / 400: the Form widget's Field typography */
  min-height: 48.75px;
}
.pl-form .elementor-field::placeholder { color: rgba(23, 52, 52, 0.58); opacity: 1; }
.elementor .pl-form textarea.elementor-field { min-height: 170px; height: 170px; }   /* 29:8918: 545x170 */
/* 29:8924 — "Or send us an email at info@packleader.co.za", 18px under the
   intro, underlined address. */
.elementor .pl-contact-email p { margin: 0; }
.elementor .pl-contact-email a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.elementor .pl-contact-email a:hover { color: var(--pl-btn); }
/* No background-color here: it comes from the Form widget's own Button colour
   setting (#1D8167 since the 2026-09 Contact board), so it stays editable in
   Elementor. It used to be forced forest with !important, which silently
   disabled that setting. */
.elementor .pl-form .elementor-field-type-submit button,
.pl-form .elementor-field-type-submit button {
  border: 1px solid rgba(255, 255, 255, 0.15) !important;
  border-radius: 8px !important;
  color: #FFFFFF !important;
  padding: 11px 15px !important;   /* 13 + 22 + 2 border = 37px, Figma 29:8926 (16 / 500 / 13px: the widget's Button typography) */
}
/* privacy note sits beside the Submit button (Figma 1:391) */
.pl-form .elementor-field-type-submit.pl-form-actions {
  display: flex !important;
  flex-direction: row;
  align-items: center;
  gap: 81px;
  flex-wrap: nowrap;
  width: 100%;
}
.pl-form .elementor-field-group.elementor-field-type-submit.pl-form-actions button.elementor-button {
  flex: 0 0 auto !important;
  width: auto !important;
}
.pl-form .elementor-field-group.elementor-field-type-submit.pl-form-actions .pl-form-legal {
  flex: 0 0 auto !important;
  width: auto !important;
  min-width: 0;
}
.pl-form .pl-form-actions .pl-form-legal p { margin: 0; white-space: nowrap; }
.elementor .pl-media-fill,
.elementor .pl-media-fill .elementor-widget-container,
.elementor .pl-media-fill img { height: 100%; }
.elementor .pl-contact-card > .elementor-widget-image.pl-contact-media {
  align-self: stretch !important;
  height: auto !important;
}
.elementor .pl-contact-media .elementor-widget-container { height: 100%; }
.elementor .pl-contact-media img {
  height: 100%;
  width: 100%;
  object-fit: cover;
  border-radius: 18px !important;
  display: block;
}

.pl-locations .pl-loc-col .elementor-heading-title { letter-spacing: 0 !important; }
.pl-locations .pl-loc-col p strong { font-weight: 500; }
/* 29:8933: the three columns are exactly their text (190px); the last line's
   paragraph margin added a 14px tail under every column. */
.elementor .pl-locations .pl-loc-col .elementor-widget-text-editor p:last-child { margin-bottom: 0; }
.pl-form .pl-form-legal a { font-weight: inherit; color: inherit; text-decoration: underline; }

/* ---- 18.8 Responsive for the three pages ---- */
@media (max-width: 1024px) {
  .pl-brand-directory .pl-brand-grid { grid-template-columns: repeat(2, 1fr); }
  .pl-locator .sl-main-row { flex-wrap: wrap !important; }
  .pl-locator #asl-panel.asl-panel,
  .pl-locator .asl-map {
    flex: 0 0 100% !important;
    max-width: 100% !important;
    width: 100% !important;
  }
  .pl-locator #asl-panel.asl-panel { height: auto !important; min-height: 360px; }
  .pl-locator .asl-map,
  .pl-locator .asl-map .map-image,
  .pl-locator .asl-map #asl-map-canv { height: 420px !important; }
  .pl-locator .asl-map { margin-top: 10px; }
  .elementor .pl-contact-card { min-height: 0 !important; }
  .elementor .pl-contact-card > .elementor-widget-image.pl-contact-media { align-self: auto !important; }
  .elementor .pl-contact-media img { height: 320px; }
}
@media (max-width: 767px) {
  .pl-brand-directory .pl-brand-grid { grid-template-columns: 1fr; }
  .pl-brand-directory .pl-brand-card__title { font-size: 24px; }
  .pl-form .elementor-field-group.elementor-field-type-submit.pl-form-actions .pl-form-legal {
    max-width: 100%;
    flex: 1 1 100% !important;
  }
  .pl-form .elementor-field-group.elementor-field-type-submit.pl-form-actions {
    flex-wrap: wrap !important;
    gap: 14px;
  }
  .pl-form .pl-form-actions .pl-form-legal p { white-space: normal; }
  .pl-locator .Filter_section { flex-wrap: wrap; }
  .pl-locator .Filter_section .search_filter,
  .pl-locator .Filter_section .pol-lg-8 { flex: 1 1 100%; }
  .pl-locator .asl-cont .sl-dropdown-cont,
  .pl-locator .asl-cont .sl-dropdown-cont .btn-group { width: 100% !important; }
  .elementor .pl-contact-media img { height: 240px; }
}

/* ===== §20 HOME QA ===== */
/* Home page only. Figma file hXeWeoSa5D7hmlCsvQmUWy, node 1:104. */

/* --- Hero (1:105 / 1:106) ---------------------------------------------- */
/* Figma places the 1376.545 x 774.307 still at (0.63, -110.88) inside the
   1370 x 715 frame. `cover` alone lands it at y = -27.8, ~83px too low.
   QA 2026-10-08 (A1): the size was "100.478% 108.294%" — width tied to the
   panel, height to the 715px band — so the photo was stretched everywhere but
   1440 (x0.88 at 1280, x1.35 at 1920, x1.82 at 2560). Now one scale for both
   axes: 100.478% of the panel, never below the 1440 size (1376.545px), height
   `auto`. The crop is the 1440 one: the image's top 14.32% stays above the
   band (calc = 14.32% - 715 x 14.32%, so the top cut is a share of the image
   whatever its height) and its right edge stays 7.18px past the panel, so
   narrower panels trim the left (the person) and keep the hand, toy and dog.
   1440 resolves to the same 1376.5 x 774.3 at (0.63, -110.88). The band is
   715px tall from 1025 up (Elementor min height). */
@media (min-width: 1025px) {
  .elementor .e-con.pl-home-hero {
    background-size: max(100.478%, 1376.545px) auto !important;
    background-position: calc(100% + 7.183px) calc(14.3203% - 102.39px) !important;
  }
}

/* --- What we offer (1:109 / 1:2 / 1:17) -------------------------------- */
.elementor .pl-offer-label .elementor-heading-title { text-transform: uppercase; }
/* The reveal is an Elementor container, so its width:100% beat the right
   offset and pushed the panel 11px past the card. Figma insets it ~11.4px. */
.elementor .pl-offer-card .pl-reveal {
  width: auto !important;
  left: 11px;
  right: 11px;
  bottom: 11px;
}
.pl-offer-card .pl-reveal .elementor-widget-text-editor p { margin-bottom: 0; }

/* Figma 1:109 panel shadow. */
.elementor .e-con.pl-offer-panel { box-shadow: 0 0 27.2px 0 rgba(23, 52, 52, 0.06); }

/* --- Stats band (1:194 - 1:207) ---------------------------------------- */
/* Figma 1:194: the still is w-full h-134.91% anchored top-left, not `cover`
   centred (which scaled it to 957px tall and cropped the dog's head off).
   QA 2026-10-08 (A1): "100% 134.91%" fixed the height to the 449px band while
   the width followed the panel, so the dog was squashed below 1440 (x0.87 at
   1280) and stretched above (x1.38 at 1920, x1.88 at 2560). `cover` is the
   panel's full width with the height in proportion (1273 x 605.3 at 1440 —
   Figma's 134.91% is the same within 0.5px), anchored at the top. Wider than
   1440 the photo grows taller than the band, so it slides up just enough to
   keep the top of the dog's head (7.36% down the image) 44.6px under the
   band's top edge as at 1440 — more of the dog shows, none of the head is cut
   (min(0px, …) = top-anchored at 1440 and below). */
@media (min-width: 1025px) {
  .elementor .e-con.pl-stats-band {
    background-size: cover !important;
    background-position: center min(0px, calc(7.36% + 11.5px)) !important;
  }
}
/* "9 provinces" is 80.367px + 36.12px, not one size with a 0.4em sub. */
/* line-height:0 keeps the mixed-size line box at the parent strut's 113px —
   otherwise the 36px span's half-leading grows the row to 135px. */
.pl-stats-band .pl-stat-9 { font-size: 0.893em; line-height: 0; }
.pl-stats-band .pl-stat-sub { font-size: 0.401em; font-weight: 600; line-height: 0; }

/* --- Delivered nationwide (1:114) -------------------------------------- */
.pl-delivered .elementor-widget-text-editor p { margin-bottom: 0; }
/* The photo card's arrow sat in static flow, so the z-index:0 scrim painted
   over it and it was invisible. Figma 1:76: 42.23 x 28.79, centred, and it
   slides 13.61px right on hover. */
/* Lift the arrow element itself, NOT its .elementor-widget-html wrapper — the
   card artwork lives in a sibling html widget and would lose its containing
   block (art collapsed to 0x0 when the wrapper was made position:relative). */
.pl-photo-arrow {
  position: relative;
  z-index: 1;
  margin-top: 16px;
  line-height: 0;
  transition: transform 0.35s var(--pl-ease, ease);
}
.pl-photo-arrow svg { display: inline-block; }
.pl-cta-card--photo:hover .pl-photo-arrow { transform: translateX(13.6px); }
.pl-cta-card--photo:hover .elementor-heading-title { color: #E8DCC8; }
.pl-cta-card--photo .elementor-heading-title { transition: color 0.35s ease; }
/* Chip glyph is 22 x 15 in Figma, not a 20 x 20 square. */
.pl-cta-card .pl-arrow-chip svg {
  /* The viewBox is square (0 0 24 24), so a 22x15 box made preserveAspectRatio
     letterbox the glyph down to 15px and the arrow rendered at roughly half
     size -- measured shaft 11px against the design's 19px. A square box maps
     1:1. 28px measured a 21px shaft against the design's 19px, so 25px. */
  width: 25px;
  height: 25px;
}
/* Photo-card scrim (Figma 1:74: rgba(0,0,0,0.2) -> rgba(23,52,52,0.74)).
   Elementor styles the container background overlay on the SAME ::before that
   §1 uses for the scrim: `.e-con::before { content: var(--background-overlay);
   transition: background 0.3s, border-radius 0.3s, opacity 0.3s; }`. It ties
   `.pl-cta-card--photo::before` on specificity (0,1,1) and wins on source
   order. --background-overlay is unset here, so `content` computed to `none`
   and the pseudo-element was never generated — the card had NO tint at rest
   and no hover darkening at all (getComputedStyle still reports colours for a
   pseudo that isn't rendered, which masked it). Re-declare at (0,3,1). */
.elementor .e-con.pl-cta-card--photo::before {
  content: "" !important;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  border-radius: inherit;
  pointer-events: none;
  background-color: rgba(0, 0, 0, 0.2);
  transition: background-color 0.35s ease !important;
}
.elementor .e-con.pl-cta-card--photo:hover::before {
  background-color: rgba(23, 52, 52, 0.74);
}
/* Scrim now sits at z-index 1, so lift the label and arrow above it. */
.elementor .e-con.pl-cta-card--photo > *:not(.elementor-widget-html, .elementor-widget-pl_card_art),
.elementor .e-con.pl-cta-card--photo .pl-photo-arrow { z-index: 2; }
/* The three CTA cards are <a> containers and fell back to the 1px UA outline
   (rgb(0,95,204)), barely visible on #1C3D3D and on the photo. */
.elementor .e-con.pl-cta-card:focus-visible {
  outline: 3px solid var(--pl-forest);
  outline-offset: 3px;
}

/* --- Why partners choose us (1:125) ------------------------------------ */
/* Rows 2-4 are fixed 90px bands in Figma; row 1 hugs its 3-line copy. */
.elementor .pl-why-row {
  min-height: 90px;
  box-sizing: border-box;
}
.pl-why-row .elementor-widget-text-editor p { margin-bottom: 0; }

/* --- Responsive ---------------------------------------------------------
   Section gutters (24px tablet / 16px phone), paddings and rhythm below 1025px
   are the containers' own Elementor Margin / Padding (tablet & mobile) since
   build/be-spacing.php. */
@media (max-width: 767px) {
  .elementor .pl-why-row { min-height: 0; }
  /* Touch: the offer reveal is shown statically, so undo the desktop offsets. */
  .elementor .pl-offer-card .pl-reveal { width: auto !important; }
}
@media (hover: none) {
  .elementor .pl-offer-card .pl-reveal {
    left: auto;
    right: auto;
    bottom: auto;
    width: auto !important;
  }
}

/* ===== §23 MOTION QA ===== */
/* Global motion / interaction-state fixes found in the animation audit.
   Scoped to header, footer, dropdown, focus states, touch and reduced motion.
   Every rule here overrides a measured defect — see the QA report. */

/* --- 23.1 Campaigns dropdown: dissolve + keyboard reach (Figma 1:2071) ----
   SmartMenus toggles `display`, which cannot transition, so the panel
   appeared instantly (measured transition: all / 0s). An animation on the
   sub-menu starts the moment `display` flips away from none, which gives the
   300ms dissolve the prototype specifies. */
@keyframes pl-dd-dissolve {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.pl-nav .elementor-nav-menu--main ul.sub-menu {
  animation: pl-dd-dissolve 300ms ease-out;
}
/* The submenu was unreachable by keyboard: `display:none` kept its links out
   of the tab order entirely, so /gonatural/ could not be reached without a
   mouse.

   ...and then it turned out not to open on HOVER either -- measured
   `display:none` at rest and still `display:none` while hovering the parent,
   so /gonatural/ was reachable ONLY by tabbing to it. The parent anchor is
   href="#" (WordPress's dropdown-parent convention), so clicking did nothing
   either, which left the page unreachable for every mouse user. Both states
   are now covered explicitly rather than relying on Elementor's own rule. */
.pl-nav .elementor-nav-menu--main li.menu-item-has-children:hover > ul.sub-menu,
.pl-nav .elementor-nav-menu--main li.menu-item-has-children:focus-within > ul.sub-menu {
  display: block !important;
}
/* §12 sets `transition: color .2s ease !important` on every nav anchor, which
   beat the dropdown rule and made the item background snap instantly. */
.pl-nav .elementor-nav-menu--dropdown a,
.pl-nav ul.sub-menu a.elementor-sub-item,
.pl-nav ul.sub-menu a {
  transition: background-color 0.25s ease, color 0.25s ease !important;
}

/* --- 23.2 Footer link colour dissolve ~200ms (prototype spec) -----------
   Elementor emits the hover colour on the text span with its own 0.3s. */
[data-elementor-type="footer"] .elementor-icon-list-item .elementor-icon-list-text {
  transition: color 0.2s ease !important;
}

/* --- 23.3 Contact form Submit hover -------------------------------------
   §18.7 `.elementor .pl-form .elementor-field-type-submit button` (0,3,1)
   set the background !important and tied §13's hover rule on specificity,
   winning on source order — so the button had no hover state at all.
   Prototype: #173434 -> #2E8B62 over 300ms. */
.elementor .pl-form .elementor-field-type-submit button,
.pl-form .elementor-field-type-submit button {
  transition: background-color 0.3s ease !important;
}
.elementor .pl-form .elementor-field-type-submit button:hover,
.elementor .pl-form .elementor-field-type-submit button:focus-visible,
.pl-form .elementor-field-type-submit button:hover {
  background-color: var(--pl-forest) !important;
}

/* --- 23.4 Visible focus indicators (WCAG 2.4.7) -------------------------
   `.pl-filter-pill` carried `outline: none !important` and the form fields
   `outline: none`, leaving keyboard users with no focus indicator. */
button.pl-filter-pill:focus-visible,
.pl-brand-directory button.pl-filter-pill:focus-visible {
  outline: 2px solid #173434 !important;
  outline-offset: 3px !important;
}
.elementor .pl-form .elementor-field:focus,
.elementor .pl-form .elementor-field:focus-visible,
.pl-form .elementor-field:focus {
  outline: 2px solid var(--pl-forest) !important;
  outline-offset: 2px !important;
  border-color: var(--pl-forest) !important;
}
.pl-nav .elementor-nav-menu a:focus-visible,
.pl-nav .elementor-button:focus-visible,
[data-elementor-type="footer"] a:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
  border-radius: 4px;
}

/* --- 23.5 Touch fallback for the offer-card reveal ----------------------
   §1 line "`.pl-offer-card .pl-reveal { position: absolute !important; }`"
   defeated the `@media (hover: none)` fallback, so on a 390px touch viewport
   the panel stayed absolutely positioned: measured 633px tall inside a 553px
   card, top offset -105px, its own copy clipped off the top of the card.
   Restoring static flow puts the hover-only copy in the document. */
@media (hover: none) {
  .elementor .pl-offer-card .pl-reveal,
  .pl-offer-card .pl-reveal {
    position: static !important;
    transform: none !important;
    margin: 11px;
    width: auto !important;
    height: auto !important;
  }
}

/* --- 23.6 prefers-reduced-motion ----------------------------------------
   §15 aimed at `.pl-connect::before`, but the gradient sweep is drawn on
   `::after` — measured 0.4s/opacity still running under reducedMotion.
   Non-essential motion is suppressed; hover *states* still apply instantly. */
@media (prefers-reduced-motion: reduce) {
  .pl-marquee__track { animation: none !important; }
  .pl-nav .elementor-nav-menu--main ul.sub-menu { animation: none !important; }
  .pl-connect::after,
  .pl-connect .pl-connect-arrow svg,
  .pl-cta-card,
  .pl-cta-card--photo::before,
  .pl-cta-card .pl-arrow-chip,
  .pl-photo-arrow,
  .pl-offer-card .pl-reveal,
  .pl-brand-card,
  .pl-brand-card .pl-arrow-chip,
  .pl-dash-grid .pl-dash-cell {
    transition: none !important;
  }
  .pl-cta-card--photo:hover .pl-photo-arrow { transform: none !important; }
}

/* --- 23.7 Footer geometry vs Figma 1:209 --------------------------------
   The brand paragraph is a 382px block in the design; the 40% column let it
   run to 503px and wrap "South / Africa." */
[data-elementor-type="footer"] .pl-footer-brand,
[data-elementor-type="footer"] .pl-footer-brand .elementor-widget-container,
[data-elementor-type="footer"] .pl-footer-brand p {
  max-width: 382px;
}

/* ===== §22 BSC QA ===== */
/* Round-3 QA of Brands (1:402), Stockists (1:471) and Contact (1:369).
   Scoped to those three pages' own wrapper classes so nothing here can
   leak into other agents' sections. */

/* -- 22.1 Brands: ribbons must run edge-to-edge across the band ----------
   The [pl_marquee] ribbons live in an .elementor-widget-html that is
   absolutely positioned against .e-con-inner (1302px @ x69), not against
   .pl-near-band (1344px @ x48), and it carried overflow:hidden. Measured:
   the ribbon stopped at x=72 and x=1371 — 21px short of the band on both
   sides, where Figma runs it right into the rounded corners. .pl-near-band
   itself is overflow:hidden + border-radius:24px, so it can do the clip. */
.pl-near-band .elementor-widget-html { overflow: visible !important; }
.pl-near-band .pl-ribbon .pl-marquee__track img.pl-marquee__strip {
  width: auto;
  max-width: none;
  flex: 0 0 auto;
}
/* The ribbon offsets were hard-coded px values that only resolve correctly at
   1440. Below that the band narrows but the offsets do not, so both ribbons
   slide up into the corners — at 390 they were 20px wedges. Derive them from
   the band width instead, calibrated so 1440 reproduces the verified
   1:426 / 1:428 geometry exactly (centre-line crosses the band's left edge at
   y=164 and its right edge at y=137; ribbon width = 1.1161 x band width). */
.pl-near-band { --pl-bw: calc(100vw - 96px); }
.pl-near-band .pl-ribbon { width: calc(var(--pl-bw) * 1.1161); }
.pl-near-band .pl-ribbon--tl { top: calc(12.20px - 5.96vw); }
.pl-near-band .pl-ribbon--tr { top: calc(7.11px - 7.48vw); }
.pl-near-band .pl-ribbon .pl-marquee__track img.pl-marquee__strip {
  height: calc(25.57px + 2.738vw);
}
@media (max-width: 1024px) {
  .pl-near-band { --pl-bw: calc(100vw - 48px); }
  .pl-near-band .pl-ribbon--tl { top: calc(9.34px - 5.96vw); }
  .pl-near-band .pl-ribbon--tr { top: calc(3.52px - 7.48vw); }
  .pl-near-band .pl-ribbon .pl-marquee__track img.pl-marquee__strip {
    height: calc(26.89px + 2.738vw);
  }
}
@media (max-width: 767px) {
  .pl-near-band { --pl-bw: calc(100vw - 32px); }
  .pl-near-band .pl-ribbon--tl { top: calc(8.39px - 5.96vw); }
  .pl-near-band .pl-ribbon--tr { top: calc(2.32px - 7.48vw); }
  .pl-near-band .pl-ribbon .pl-marquee__track img.pl-marquee__strip {
    height: calc(27.32px + 2.738vw);
  }
}

/* -- 22.2 Brands: filter pill gap (Figma 18px, was 12px) ---------------- */
.pl-brand-directory .pl-filter-bar { gap: 18px; }

/* -- 22.3 Buttons: the global Elementor "accent" typography adds 2px of
   letter-spacing. Figma has none: "Find a stockist" measures 122px in the
   design vs 154px live, "Submit" 84px vs 99px. Every button now sets its own
   Letter Spacing 0 in Elementor (build/be-typography.php), so no override. */

/* -- 22.4 Stockists: distance dropdown -----------------------------------
   The Agile Store Locator "multiselect" menu still shipped plugin defaults:
   the open panel rendered with an orange (#CB2800) active row and option
   labels were display:none, so the open menu showed no text at all. It also
   had no caret.
   Root causes: (a) --sl-primary is #cb2800 on #asl-storelocator and the
   active-row rule is ID-qualified + !important, so re-point the variable;
   (b) §18.6's ".pl-locator .Filter_section label { display:none }" (meant
   for the "Search Location"/"Distance" field labels) also matched the
   option labels inside the menu — they sit in the same .Filter_section. */
.pl-locator #asl-storelocator { --sl-primary: var(--pl-forest); }
.pl-locator .Filter_section .multiselect-container label.radio {
  display: flex !important;
}
/* Figma 1:485 sizes this control at 136px next to a 267px search group; the
   search row is a .sl-row, and the plugin's own `.sl-row{flex-wrap:wrap}`
   outranks §18.6's nowrap, so the row broke into two lines as soon as the
   control grew. Pin nowrap and let the search group shrink instead. */
.pl-locator .Filter_section.sl-row { flex-wrap: nowrap !important; }
.pl-locator .Filter_section .search_filter { flex: 1 1 0 !important; min-width: 0 !important; }
.pl-locator .Filter_section .sl-search-group { flex-wrap: nowrap !important; }
.pl-locator .asl-cont input.asl-search-address { min-width: 0 !important; width: 100% !important; }
.pl-locator .asl-cont .sl-dropdown-cont,
.pl-locator .asl-cont .sl-dropdown-cont .btn-group { width: 136px !important; }
.pl-locator .asl-cont .sl-dropdown-cont .btn-group > button.multiselect {
  position: relative;
  padding: 0 28px 0 12px !important;
  font-size: 13px !important;
}
.pl-locator .asl-cont .sl-dropdown-cont .btn-group > button.multiselect .multiselect-selected-text {
  font-size: 13px !important;
  color: var(--pl-forest) !important;
  white-space: nowrap;
}
.pl-locator .asl-cont .sl-dropdown-cont .btn-group > button.multiselect .multiselect-selected-text::after {
  /* " " + Store Locator label "Radius" (inc/settings.php prints --pl-lbl-radius); lower-cased by §31.10. */
  content: var(--pl-lbl-radius);
}
.pl-locator .asl-cont .sl-dropdown-cont .btn-group > button.multiselect b.caret {
  display: block !important;
  position: absolute;
  top: 50%;
  right: 11px;
  width: 9px;
  height: 9px;
  margin: -6px 0 0;
  border: 0;
  border-right: 1.6px solid var(--pl-forest);
  border-bottom: 1.6px solid var(--pl-forest);
  transform: rotate(45deg);
}
.pl-locator .asl-cont .sl-dropdown-cont .multiselect-container.adropdown-menu {
  min-width: 100%;
  margin: 6px 0 0;
  padding: 6px !important;
  list-style: none;
  background: #FFFFFF !important;
  border: 1px solid rgba(23, 52, 52, 0.14) !important;
  border-radius: 10px !important;
  box-shadow: 0 8px 24px rgba(23, 52, 52, 0.12) !important;
  z-index: 20;
}
.pl-locator .asl-cont .sl-dropdown-cont .multiselect-container.adropdown-menu li,
.pl-locator .asl-cont .sl-dropdown-cont .multiselect-container.adropdown-menu li a {
  background: transparent !important;
  border: 0 !important;
  display: block;
  text-decoration: none;
}
.pl-locator .asl-cont .sl-dropdown-cont .multiselect-container.adropdown-menu li a {
  padding: 8px 10px !important;
  border-radius: 7px !important;
}
.pl-locator .asl-cont .sl-dropdown-cont .multiselect-container.adropdown-menu li a label.radio {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 !important;
  padding: 0 !important;
  cursor: pointer;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: var(--pl-forest) !important;
}
.pl-locator .asl-cont .sl-dropdown-cont .multiselect-container.adropdown-menu li a:hover,
.pl-locator .asl-cont .sl-dropdown-cont .multiselect-container.adropdown-menu li.active a {
  background: #F3EEE7 !important;
}
/* the selected row keeps the plugin's ID-qualified !important fill, which
   --sl-primary now paints forest green — so its label has to go light. */
.pl-locator .asl-cont .sl-dropdown-cont .multiselect-container.adropdown-menu li.active a label.radio {
  font-weight: 600;
  color: var(--pl-card) !important;
}

/* -- 22.5 Stockists: remaining Agile Store Locator default chrome --------
   #CB2800 buttons ("GET DIRECTIONS", "USE LOCATION"), the cream-on-white
   clear (x) button and the orange store-count chip. */
.pl-locator .btn-submit,
.pl-locator .btn-block,
.pl-locator .btn-default:not(.multiselect),
.pl-locator .onoffswitch-inner,
.pl-locator .Num_of_store,
.pl-locator .agile-modal .btn {
  background-color: var(--pl-forest) !important;
  border-color: rgba(255, 255, 255, 0.15) !important;
  color: var(--pl-card) !important;
}
.pl-locator button.asl-search-clr,
.pl-locator button.asl-clear-btn {
  background: transparent !important;
  color: var(--pl-forest) !important;
}
.pl-locator button.asl-search-clr svg,
.pl-locator button.asl-clear-btn svg { fill: var(--pl-forest); }

/* -- 22.6 Stockists: result card row order (Figma 1:516 lists the email
   above the phone; the plugin emits phone first). ------------------------ */
.pl-locator .asl-cont .sl-addr-sec ul { display: flex; flex-direction: column; }
.pl-locator .asl-cont .sl-addr-sec ul li.sl-addr  { order: 1; }
.pl-locator .asl-cont .sl-addr-sec ul li.sl-email { order: 2; }
.pl-locator .asl-cont .sl-addr-sec ul li.sl-phone { order: 3; }

/* -- 22.7 Keyboard focus. Every interactive control on these three pages
   computed to outline-style:none, so there was no visible focus ring. ---- */
.pl-brand-directory button.pl-filter-pill:focus-visible,
.pl-brand-directory .pl-brand-card a:focus-visible,
.pl-locator button:focus-visible,
.pl-locator .asl-cont a:focus-visible,
.pl-form .elementor-field:focus-visible,
.pl-form .pl-form-legal a:focus-visible,
.pl-form button.elementor-button:focus-visible,
.pl-locations a:focus-visible {
  outline: 2px solid var(--pl-green-hover) !important;
  outline-offset: 2px !important;
}
.pl-form .elementor-field:focus {
  border-color: rgba(23, 52, 52, 0.45) !important;
}

/* -- 22.8 Contact: at 1024 the media was pinned to 320px and left a large
   dead area under it while the form column ran on to ~520px. Let it fill
   the card again (Figma 1:373 — media is full card height). ------------- */
@media (min-width: 768px) and (max-width: 1024px) {
  .elementor .pl-contact-card > .elementor-widget-image.pl-contact-media {
    align-self: stretch !important;
  }
  .elementor .pl-contact-media img { height: 100% !important; min-height: 420px; }
  /* the privacy note is nowrap at 1440; at 1024 the form column is only
     ~414px so it ran 143px past the column and over the media. */
  .pl-form .elementor-field-group.elementor-field-type-submit.pl-form-actions {
    gap: 18px;
    flex-wrap: wrap !important;
  }
  .pl-form .elementor-field-group.elementor-field-type-submit.pl-form-actions .pl-form-legal {
    flex: 1 1 190px !important;
  }
  .pl-form .pl-form-actions .pl-form-legal p { white-space: normal; }
}

/* -- 22.9 Narrow-viewport clean-up -------------------------------------- */
@media (max-width: 767px) {
  /* radius control filled only 86px of the row */
  .pl-locator .asl-cont .range_filter,
  .pl-locator .asl-cont .asl-filter-cntrl,
  .pl-locator .asl-cont .asl-ddl-filters { width: 100% !important; }
  /* 22.4's nowrap is a desktop-only fix — at 390 it squeezed the address
     input to 20px and overlapped it with the radius control. Stack again. */
  .pl-locator .Filter_section.sl-row { flex-wrap: wrap !important; }
  .pl-locator .Filter_section .search_filter,
  .pl-locator .Filter_section .pol-lg-8 { flex: 1 1 100% !important; }
  .pl-locator .asl-cont .sl-dropdown-cont,
  .pl-locator .asl-cont .sl-dropdown-cont .btn-group { width: 100% !important; }
  .pl-brand-directory .pl-filter-bar { gap: 10px; }
}

/* ===== §21 ABOUT+TEAM QA ===== */
/* Round-3 QA of /about-us/ (Figma 1:296) and /our-team/ (Figma 1:432).
   Everything here overrides §17; it must stay last so it wins on ties. */

/* 21.1 About "How it started" photo — Figma 1:307 sits at y=0 in its
   582.5x263 frame (bottom 71px cropped). cover was centring it instead. */
.elementor .pl-fcard--stretch .elementor-widget-image img {
  object-position: 50% 0%;
}

/* 21.2 That photo is absolutely positioned, so at mobile — where the card
   stacks — its widget collapsed to 0px high and the image was clipped to the
   card's 36px bottom padding (only ~32px of the cat was visible). Put the
   height on the wrapper. */
@media (max-width: 767px) {
  .pl-fcard--stretch > .e-con-inner > .elementor-widget-image {
    height: 230px;
    align-self: stretch;
  }
  .elementor .pl-fcard--stretch .elementor-widget-image img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100% !important;
  }
}

/* 21.3 About "What we do" scrim legibility.
   Two problems. (a) §17c's darkening layer never rendered at all: pl-global.css
   is enqueued BEFORE elementor/frontend.min.css, whose `.e-con::before {
   content: var(--background-overlay) }` won the tie and resolved to `none`, so
   Figma 1:318's rgba(0,0,0,.2) photo layer was missing. (b) With it missing,
   cream #FFF9F0 measured 3.3:1 at the left edge and 2.2:1 under the right half
   of the copy — the 21px paragraph needs 4.5:1 and the 40px heading 3:1, so
   both failed. Re-declare the layer at a specificity Elementor can't beat and
   ramp it across the text column; Figma's .2 is kept on the exposed photo. */
.e-con.pl-ww-band::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 0;
  background: linear-gradient(
    90deg,
    rgba(0, 0, 0, 0.58) 0%,
    rgba(0, 0, 0, 0.57) 40%,
    rgba(0, 0, 0, 0.44) 58%,
    rgba(0, 0, 0, 0.2) 72%,
    rgba(0, 0, 0, 0.2) 100%
  );
}
.pl-scrim-stone.pl-ww-band::after {
  background: linear-gradient(90deg, rgb(96, 94, 90) 0%, rgba(96, 94, 90, 0) 70.2%);
}
/* §17g's tablet/mobile scrims kept the light stone, so with the copy running
   the full width they measured 3.05:1 (1024) and 2.08:1 (390). Deepen both:
   the copy now sits at 5.5:1 (1024) and 5.6:1 (390) while the photo still
   reads through. */
@media (max-width: 1024px) {
  .e-con.pl-ww-band::before { background: rgba(0, 0, 0, 0.24); }
  .pl-scrim-stone.pl-ww-band::after {
    background: linear-gradient(90deg, rgb(88, 86, 82) 0%, rgba(88, 86, 82, 0.72) 100%);
  }
}
@media (max-width: 767px) {
  .e-con.pl-ww-band::before { background: rgba(0, 0, 0, 0.2); }
  .pl-scrim-stone.pl-ww-band::after { background: rgba(70, 68, 64, 0.7); }
}

/* 21.4 Go Natural wordmark.
   The PNG carries 5.86% transparent padding each side, so a box sitting on the
   65px content gutter pushed the glyphs to x=90 while Figma 1:361 renders them
   at x=70 (band-relative). Pull the box back by the difference. */
.pl-gn-logo {
  width: 425px;
  max-width: 100%;
  /* beats the per-element margin Elementor prints for this widget */
  margin-left: -20px !important;
}
@media (max-width: 767px) {
  /* Phones centre the card (mobile QA 2026-10-15), so the padding is even on both sides and no pull-back is needed:
     the -11px left the wordmark 5.5px left of the button and text below it. */
  .pl-gn-logo { width: 240px; max-width: 240px; margin-left: 0 !important; }
}

/* 21.5 Go Natural ingredient collage below 1024px.
   The source PNG is 1400x933 but the collage only occupies x 0-78.9%,
   y 28.3-69.9% of that canvas. §17g dropped the crop at tablet/mobile, so the
   widget laid out the whole transparent canvas: the banner ballooned to
   1048px tall at 1024 and the collage shrank to a 73px strip at 390.
   Re-crop to the artwork's own bounding box. */
@media (max-width: 1024px) {
  .pl-gn-ingredients {
    position: relative !important;
    left: auto;
    top: auto;
    width: 100%;
    transform: none;
    margin-top: 28px;
    aspect-ratio: 1104 / 388;
    overflow: hidden;
    border-radius: 18px;
  }
  .elementor .pl-gn-ingredients img {
    position: absolute;
    left: 0;
    top: -68.06%;
    width: 126.81%;
    max-width: none;
    height: auto;
    border-radius: 0;
  }
}

/* 21.6 Team intro photo — Figma 1:469 places a 689x406 crop inside the
   582.5x306 frame, i.e. 1.18x tighter than object-fit:cover and framed lower.
   cover was showing the empty deck below the group. Oversize the image box so
   cover still guards the aspect at every width. */
.elementor .pl-team-intro .elementor-widget-image {
  position: relative;
  overflow: hidden;
  border-radius: 10px;
  height: 306px;
}
.elementor .pl-team-intro .elementor-widget-image img {
  position: absolute;
  left: -9.19%;
  top: -24.84%;   /* 2026-09 board 29:9233: 29px more of the top of the photo */
  width: 118.28%;
  height: 151.52%;
  max-width: none;
  object-fit: cover;
  border-radius: 0;
}
@media (max-width: 1024px) {
  .elementor .pl-team-intro .elementor-widget-image { height: 260px; }
  .elementor .pl-team-intro .elementor-widget-image img { height: 151.52%; }
}
@media (max-width: 767px) {
  .elementor .pl-team-intro .elementor-widget-image { height: 230px; }
  .elementor .pl-team-intro .elementor-widget-image img { height: 151.52%; }
}

/* 21.7 Team "It's personal" trio — Figma 1:440 / 1:442 / 1:444 each frame
   their photo off-centre; plain cover cropped the shampoo bottle out of shot
   and lost the top of the cat's box. */
.elementor .pl-img3 > .elementor-widget:nth-child(1) img { object-position: 63% 0%; }
.elementor .pl-img3 > .elementor-widget:nth-child(2) img { object-position: 50% 24%; }
.elementor .pl-img3 > .elementor-widget:nth-child(3) img { object-position: 50% 42%; }

/* 21.8 Philosophy icon chips are a fixed 48x48 in Figma (1:333); the container
   width control emits no mobile value, so they stretched the full column. */
.pl-phil-chip {
  width: 48px !important;
  max-width: 48px;
  flex: 0 0 auto !important;
  align-self: flex-start;
}


/* ===== §24 FINAL A11Y ===== */
.pl-sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}
.pl-main { display: block; }
.pl-main:focus { outline: none; }

/* ===== §26 MOBILE HOME ===== */
/* Home page (Figma hXeWeoSa5D7hmlCsvQmUWy 1:104) has no mobile design. These
   rules take the desktop system (forest #173434, cream #FFF9F0, rounded
   panels) down to a phone. Everything is scoped to `.pl-home-hero`,
   `.pl-offer-*`, `.pl-stats-band`, `.pl-delivered`, `.pl-why` and gated at
   max-width: 767px so no other page or breakpoint is touched. */
@media (max-width: 767px) {

  /* --- 26.1 Hero ------------------------------------------------------ */
  /* The 2000 x 1125 poster `cover`-fits a 358 x 470 box at 835px wide, so only
     43% of the frame survives. Centre lands on the high-contrast patterned
     trousers, which read as noise behind white type at phone size; biasing
     right puts the softer grass under the H1 instead.
     The phone crop is now the hero container's own Mobile background position
     in Elementor (Center Right: the dog and its ball; mobile QA 2026-10-15),
     so it is no longer forced here. */

  /* --- 26.2 Offer cards: stacked, nothing overlapping ------------------
     The touch fallback (§15 `@media (hover:none)`) makes `.pl-reveal` static,
     but `.pl-card-art` stayed `position:absolute` to its Figma percentages
     (measured: card 2 art spanned x -45 -> 388 inside a 33 -> 357 card) so the
     paragraph painted straight over the food bags. At mobile the art joins the
     flow as a real block and the card reads heading -> image -> copy -> button. */
  .elementor .e-con.pl-offer-card {
    min-height: 0 !important;
    display: flex;
    flex-direction: column;
  }
  .elementor .pl-offer-card > .elementor-widget-heading { order: 1; }
  .elementor .pl-offer-card > .elementor-widget-html,
  .elementor .pl-offer-card > .elementor-widget-pl_card_art { order: 2; width: 100%; }
  .elementor .pl-offer-card > .pl-reveal                { order: 3; }
  .elementor .pl-offer-card .pl-card-art {
    position: static !important;
    left: auto !important;
    top: auto !important;
    right: auto !important;
    bottom: auto !important;
    width: 100% !important;
    height: 190px !important;
    max-width: 100% !important;
    object-fit: cover !important;
    /* Both sources carry transparent headroom above the product row; a centred
       crop left ~70px of empty tan at the top of the frame. */
    object-position: center 82% !important;
    border-radius: 12px;
  }
  /* Card 2's source is shot bottom-heavy; centre-crop loses the products. */
  .elementor .pl-offer-card + .pl-offer-card .pl-card-art {
    object-position: center 72% !important;
  }
  /* In flow the frosted panel is just a floating rectangle — drop the glass
     and let the copy sit on the card the way the heading does. §1 line
     "position: absolute !important" and §20's left/right/bottom insets both
     have to be unwound here. */
  .elementor .pl-offer-card .pl-reveal,
  .elementor .pl-offer-card .e-con.pl-reveal {
    position: static !important;
    transform: none !important;
    left: auto !important;
    right: auto !important;
    bottom: auto !important;
    margin: 0 !important;
    width: 100% !important;
    background: transparent !important;
    border: 0 !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
    border-radius: 0 !important;
  }
  /* "Explore our brands" broke over two lines in the 214px panel. */
  .elementor .pl-offer-card .pl-reveal .elementor-button {
    white-space: nowrap;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .elementor .pl-offer-card .pl-reveal .elementor-widget-button { width: auto; }

  /* --- 26.3 Stats band: 2 x 2 grid ------------------------------------
     Was a single 782px-tall column of four 90px numbers. */
  .elementor .e-con.pl-stat-row {
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    align-items: flex-start;
  }
  .elementor .e-con.pl-stat-cell {
    width: 47% !important;
    flex: 1 1 0 !important;
    min-width: 0;
  }
  .elementor .pl-stats-band .pl-stat-label .elementor-heading-title { opacity: 0.92; }
  /* "9 provinces" is a mixed-size line: 0.893em/0.401em of 90px is fine, of
     40px it drops "provinces" to 16px against a 36px 9. Even it out. */
  .elementor .pl-stats-band .pl-stat-9   { font-size: 1em !important; line-height: 1.15 !important; }
  .elementor .pl-stats-band .pl-stat-sub {
    font-size: 0.45em !important;
    line-height: 1.15 !important;
    font-weight: 600;
    display: block;
    margin-top: -2px;
  }

  /* --- 26.4 Delivered nationwide: CTA cards ---------------------------
     Cards stack; the desktop artwork percentages (dark box measured
     x 44 -> 450 against a 32 -> 358 card, photo 3 -> 421) get reframed to the
     card box so nothing is half-cropped. */
  .elementor .e-con.pl-cta-card { min-height: 230px !important; }
  .elementor .pl-cta-card--dark .pl-card-art {
    left: 0 !important;
    right: 0 !important;
    top: auto !important;
    bottom: 0 !important;
    width: 100% !important;
    /* 62% left the box floating in a big dead middle; 76% fills the well under
       the heading without touching it. */
    height: 76% !important;
    object-fit: contain !important;
    object-position: bottom center !important;
  }
  /* cta2-paws-rot.png is 765 x 1024 with the two paws in the top ~45% and
     transparency below. Desktop squashes it with object-fit:fill to hit a
     Figma frame; at mobile any crop either stretches the fur or slices through
     it. Rendering at natural aspect (width:100% -> 326 x 436) and letting the
     transparent tail fall past the card keeps the paws whole and un-squashed —
     the card's `overflow: hidden` does the clipping. */
  .elementor .pl-cta-card--light .pl-card-art {
    left: 0 !important;
    right: auto !important;
    bottom: auto !important;
    top: 26% !important;
    width: 100% !important;
    height: auto !important;
    object-fit: contain !important;
  }
  .elementor .pl-cta-card--photo {
    min-height: 200px !important;
  }
  .elementor .pl-cta-card--photo .pl-card-art {
    left: 0 !important;
    top: 0 !important;
    width: 100% !important;
    height: 100% !important;
    object-fit: cover !important;
    object-position: center center !important;
  }
  /* Touch devices never reach the :hover state, so the resting rgba(0,0,0,0.2)
     scrim is all a phone user gets — cream type over a bright kitchen. Deepen
     it toward the forest hover value for legible contrast. */
  .elementor .e-con.pl-cta-card--photo::before {
    background-color: rgba(23, 52, 52, 0.48) !important;
  }
  /* Arrow chip was 37 x 33 — under the 44px touch minimum. */
  .elementor .pl-cta-card .pl-arrow-chip {
    width: 44px;
    height: 44px;
    border-radius: 10px;
  }
  .elementor .e-con.pl-card-top { flex-wrap: nowrap !important; gap: 12px; }
  .elementor .pl-cta-card .pl-card-top .elementor-widget-heading { min-width: 0; }

  /* --- 26.5 Why partners choose us ------------------------------------
     §10 already stacks the row; the icon+title sub-row still wrapped (row 3's
     paw measured at x 16 on its own line while rows 1/2/4 sat at x 85).
     Direction and alignment are the containers' own Mobile values in Elementor
     (mobile QA 2026-10-15: paw above a centred title), no longer forced here. */
  .elementor .e-con.pl-why-head {
    flex-wrap: nowrap !important;
    gap: 14px !important;
    width: 100% !important;
  }
  .elementor .pl-why-head .elementor-widget-heading {
    min-width: 0;
    flex: 1 1 auto;
  }
  .elementor .pl-why-head .elementor-widget-html,
  .elementor .pl-why-head .elementor-widget-icon { flex: 0 0 28px; padding-top: 1px; }
}


/* ===== §25 MOBILE HEADER+FOOTER ===== */
/* Owner: header/footer templates (build/build-header.php, build/build-footer.php).
   Everything here is scoped to the header/footer theme-builder documents and to
   <= 1024px, so it cannot reach page content or the desktop layout. */

@media (max-width: 1024px) {
  /* --- 25.1 The pill must never wrap -------------------------------------
     Elementor's frontend.min.css reassigns `--flex-wrap: var(--flex-wrap-mobile)`
     inside @media (max-width:767px), and `flex_direction: row` sets
     `--flex-wrap-mobile: wrap`. That is what broke the pill into three rows
     (145px tall). The Elementor `flex_wrap_mobile` setting fixes it, this is
     the belt-and-braces backstop. */
  [data-elementor-type="header"] .e-con.pl-nav,
  [data-elementor-type="header"] .e-con.pl-nav > .e-con {
    --flex-wrap: nowrap;
    flex-wrap: nowrap !important;
  }
  [data-elementor-type="header"] .e-con.pl-nav > .e-con {
    min-width: 0;                 /* let the zones actually shrink */
    flex-shrink: 1;
  }

  /* --- 25.2 Burger: 44x44 tap target, on the RIGHT ----------------------
     Mobile bar order (client feedback): logo LEFT, burger RIGHT, and no
     Contact button in the bar at all — it moves into the popup card as its
     closing CTA (cloned there by pl-main.js so the label/link stay whatever
     the client sets on the header button in Elementor). The zones are
     reordered with flex `order`, so the Elementor template itself — and the
     desktop header built from it — is untouched. */
  [data-elementor-type="header"] .elementor-menu-toggle {
    min-width: 44px;
    min-height: 44px;
    padding: 0 !important;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    background: transparent !important;
    border-radius: 8px;
    margin-left: auto;
  }
  [data-elementor-type="header"] .e-con.pl-nav > .e-con:has(.elementor-widget-image) {
    order: 1;
    justify-content: flex-start;
  }
  [data-elementor-type="header"] .e-con.pl-nav > .e-con:has(.elementor-widget-nav-menu) {
    order: 3;
    justify-content: flex-end;
  }
  [data-elementor-type="header"] .pl-nav .elementor-widget-image,
  [data-elementor-type="header"] .pl-nav .elementor-widget-image .elementor-widget-container {
    text-align: left;
  }
  /* The whole button ZONE, not just the widget: the empty zone still held
     its ~101px flex slot at order 0, shoving the logo back toward center. */
  [data-elementor-type="header"] .e-con.pl-nav > .e-con:has(.elementor-widget-button) {
    display: none;
  }
  /* The relocated header actions: a two-button row closing the popup sheet.
     "Partner Log In" is the solid primary (the nav's #1D8167, 29:9033);
     "Contact us" — a text link in the desktop bar — becomes the outline
     secondary here, since a bare text link at the foot of a sheet reads as
     an afterthought. Lives inside nav.elementor-nav-menu--dropdown, which
     desktop never shows, so it needs no width gate of its own. */
  .pl-nav .pl-menu-ctas {
    display: flex;
    gap: 10px;
    margin: 10px 6px 6px;
  }
  .pl-nav .pl-menu-cta {
    flex: 1 1 0;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 52px;
    padding: 0 12px;
    border-radius: 14px;
    background: var(--pl-btn) !important;   /* Elementor's widget-scoped dropdown link colours outrank a plain double-class */
    border: 1px solid var(--pl-btn);
    color: var(--pl-cream) !important;
    font-size: 16px;
    font-weight: 600;
    letter-spacing: 0;
    text-align: center;
    text-decoration: none;
  }
  .pl-nav .pl-menu-cta:hover,
  .pl-nav .pl-menu-cta:focus {
    background: var(--pl-forest) !important;
    border-color: var(--pl-forest);
    color: var(--pl-cream) !important;
  }
  .pl-nav .pl-menu-cta--ghost {
    background: transparent !important;
    border-color: rgba(23, 52, 52, 0.3);
    color: var(--pl-forest) !important;
  }

  /* --- 25.3 Logo + CTA keep clear of the pill's rounded ends ------------- */
  [data-elementor-type="header"] .pl-nav .elementor-widget-image,
  [data-elementor-type="header"] .pl-nav .elementor-widget-image img {
    max-width: 100%;
    height: auto;
  }
  [data-elementor-type="header"] .pl-nav .elementor-widget-button {
    max-width: 100%;
  }
  [data-elementor-type="header"] .pl-nav .elementor-button {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
  }

  /* --- 25.4b Scrim + scroll lock behind the popup card ------------------
     The scrim div is inserted by pl-main.js on every page; its BASE styles
     are deliberately inside this <=1024 block so it costs the desktop
     nothing, but everything that makes it inert (opacity 0, pointer-events
     none) lives right here on the base rule — the open state only ever
     exists at these widths because only here does the burger exist to set
     body.pl-menu-open. z-index 99 sits UNDER the fixed header stack
     (measured z:100) — the card and the burger/X stay interactive — and
     over everything else. */
  .pl-nav-scrim {
    position: fixed;
    inset: 0;
    z-index: 99;
    background: rgba(23, 52, 52, 0.4);
    opacity: 0;
    pointer-events: none;
    transition: opacity .25s ease;
  }
  body.pl-menu-open .pl-nav-scrim {
    opacity: 1;
    pointer-events: auto;
  }
  body.pl-menu-open {
    overflow: hidden;
  }

  /* --- 25.4 Burger panel: a POPUP CARD, not a push-down list -------------
     Client feedback ("mobile header is a mess"): the old panel was eighteen
     flat hairline rows — four pages plus all fourteen brands as full-width
     rows with letterspaced caps — hanging square off the header with the
     page showing through. Reworked to the site's own language: one rounded
     cream card floating under the header (scrim + scroll-lock behind it,
     added in pl-main.js), page links as big rounded rows, and each submenu
     a collapsible section (below: two columns of text links under a
     chevron row; it was a cloud of pill chips until 2026-10-15). */
  [data-elementor-type="header"] .pl-nav .elementor-nav-menu--dropdown {
    background-color: var(--pl-cream) !important;
    border-radius: 22px !important;
    box-shadow: 0 18px 44px rgba(23, 52, 52, 0.28) !important;
    max-height: calc(100vh - 120px);
    overflow-y: auto;
    padding: 10px !important;
  }
  [data-elementor-type="header"] .pl-nav .elementor-nav-menu--dropdown a.elementor-item {
    min-height: 50px;
    display: flex;
    align-items: center;
    padding: 0 16px !important;
    border-radius: 14px;
    background-color: transparent !important;
    color: var(--pl-forest) !important;
    font-size: 17px !important;
    font-weight: 600 !important;
    letter-spacing: 0 !important;
  }
  [data-elementor-type="header"] .pl-nav .elementor-nav-menu--dropdown a.elementor-item:hover,
  [data-elementor-type="header"] .pl-nav .elementor-nav-menu--dropdown a.elementor-item:focus,
  [data-elementor-type="header"] .pl-nav .elementor-nav-menu--dropdown a.elementor-item:active {
    background-color: rgba(23, 52, 52, 0.07) !important;
    color: var(--pl-forest) !important;
  }
  /* :not([href*="#"]) — same WP quirk as the desktop mega (§39): fragment
     links get current-menu-item on /brands/ despite pointing at a section,
     and must not read as the current page. */
  [data-elementor-type="header"] .pl-nav .elementor-nav-menu--dropdown li.current-menu-item > a.elementor-item:not([href*="#"]) {
    background-color: var(--pl-forest) !important;
    color: var(--pl-cream) !important;
  }
  [data-elementor-type="header"] .pl-nav .elementor-nav-menu--dropdown li > a {
    border-bottom: 0 !important;
  }
  /* Elementor anchors the dropdown to the nav *widget*, which now sits in the
     narrow 30% left zone — the panel came out 44px wide and opened *on top of*
     the burger, swallowing every tap. Make the pill the containing block so
     the panel spans the pill and hangs below it. Scoped to `nav.` so it can
     never touch `ul.sub-menu.elementor-nav-menu--dropdown`. */
  [data-elementor-type="header"] .pl-nav {
    position: relative;
  }
  [data-elementor-type="header"] .pl-nav > .e-con,
  [data-elementor-type="header"] .pl-nav > .e-con > .e-con-inner,
  [data-elementor-type="header"] .pl-nav .elementor-widget-nav-menu,
  [data-elementor-type="header"] .pl-nav .elementor-widget-nav-menu > .elementor-widget-container {
    position: static !important;
  }
  [data-elementor-type="header"] .pl-nav nav.elementor-nav-menu--dropdown {
    position: absolute !important;
    top: calc(100% + 10px) !important;
    left: 0 !important;
    right: 0 !important;
    width: auto !important;
    margin: 0 !important;
  }
  /* OPEN = a full-screen sheet. Scoped to [aria-hidden="false"] because
     Elementor's closed state is NOT display:none (it parks the panel
     visible-but-collapsed for its animation) — unconditional fixed
     geometry would paint a cream sheet over the page while "closed".
     The sheet starts under the live header bar (--pl-menu-top is measured
     and set by pl-main.js on every open, so the sticky pill header works
     too) and runs to the bottom edge; flex column so the Contact CTA's
     auto top margin pins it to the sheet's foot whenever the menu is
     shorter than the screen. */
  [data-elementor-type="header"] .pl-nav nav.elementor-nav-menu--dropdown[aria-hidden="false"] {
    position: fixed !important;
    inset: 0 !important;
    width: auto !important;
    height: auto !important;
    max-height: none !important;
    margin: 0 !important;
    border-radius: 0 !important;
    display: flex !important;
    flex-direction: column;
    overflow-y: auto;
    /* One SURFACE, not a bar above a sheet: the sheet covers the whole
       screen and the bar's logo + X float on top of it (raised below), so
       they read as part of the popup. Content starts under them via the
       measured bar-bottom offset. */
    padding: calc(var(--pl-menu-top, 84px)) 12px calc(14px + env(safe-area-inset-bottom)) !important;
  }
  /* Raise the bar's logo and toggle above the full-screen sheet — same
     stacking context (the fixed header), so a bare z-index does it. The
     bar's own pill chrome is flattened while open so logo/X sit directly
     on the popup surface instead of in a visible strip of their own. */
  /* `!important` because the containing-block fix above pins every zone to
     `position: static !important` — a bare `relative` loses and the z-index
     is silently ignored (the logo vanished under the sheet exactly so).
     z-index 9999, not a small value: z:2 was still buried under something
     in Elementor's widget stack (verified empirically — 2 lost, 9999 wins),
     and the value only competes INSIDE the bar's own z:100 stacking
     context, so it can't leak above anything outside the header. Scoped to
     the open state; the closed panel anchors inside the BURGER zone's
     widget, not these elements, so raising them changes nothing about the
     closed geometry. */
  body.pl-menu-open [data-elementor-type="header"] .e-con.pl-nav > .e-con:has(.elementor-widget-image) {
    position: relative !important;
    z-index: 9999;
  }
  body.pl-menu-open [data-elementor-type="header"] .elementor-menu-toggle {
    position: relative !important;
    z-index: 9999;
  }
  body.pl-menu-open [data-elementor-type="header"] .e-con.pl-nav {
    background: transparent !important;
    box-shadow: none !important;
    border-color: transparent !important;
  }
  [data-elementor-type="header"] .pl-nav nav.elementor-nav-menu--dropdown[aria-hidden="false"] > ul {
    flex: 0 0 auto;
  }
  [data-elementor-type="header"] .pl-nav nav.elementor-nav-menu--dropdown[aria-hidden="false"] .pl-menu-ctas {
    margin: auto 6px 6px !important;   /* top:auto = pinned to the sheet's foot */
  }
  /* Submenus in the sheet: collapsible sections (2026-10-15, client: "alternate layout than pills" — was every
     submenu always open as a cloud of pill chips, Brands' fourteen as six rows of them). Brands and Campaigns are
     rows with a chevron; a tap opens the list under the row as two columns of plain text links on a soft panel, and
     on a brand's own page that section opens with the sheet (pl-main.js). A second tap on "Brands" opens the Brands
     page; "Campaigns" has no page of its own, so it closes again. The opening and closing is Elementor's own menu
     script (SmartMenus' collapsible mode, which also keeps aria-expanded / aria-hidden true to what is shown); this
     only styles it, so the lists still come from Appearance › Menus. */
  [data-elementor-type="header"] .pl-nav nav.elementor-nav-menu--dropdown ul.sub-menu {
    position: static !important;
    width: auto !important;
    min-width: 0 !important;
    margin: 8px 0 10px !important;   /* 8px under the open row (client 2026-10-15: "spacing after the brands row") */
    padding: 6px !important;   /* + the links' 10px = the rows' 16px: the names line up with "Brands" above */
    box-shadow: none !important;
    background: rgba(23, 52, 52, 0.05) !important;
    border: 0 !important;
    border-radius: 14px !important;
    columns: 2;
    column-gap: 2px;
    animation: none !important;
  }
  [data-elementor-type="header"] .pl-nav nav.elementor-nav-menu--dropdown ul.sub-menu > li {
    width: auto !important;
    float: none;
    break-inside: avoid;
  }
  [data-elementor-type="header"] .pl-nav .elementor-nav-menu--dropdown a.elementor-sub-item {
    display: flex !important;
    align-items: center;
    min-height: 44px;
    padding: 0 2px 0 10px !important;   /* "Company of Animals" (147px) on one line at 360 */
    border: 0 !important;
    border-radius: 10px !important;
    background-color: transparent !important;
    color: var(--pl-forest) !important;
    font-size: 15px !important;
    font-weight: 500 !important;
    line-height: 1.25 !important;
    letter-spacing: 0 !important;
  }
  [data-elementor-type="header"] .pl-nav .elementor-nav-menu--dropdown a.elementor-sub-item:hover,
  [data-elementor-type="header"] .pl-nav .elementor-nav-menu--dropdown a.elementor-sub-item:focus,
  [data-elementor-type="header"] .pl-nav .elementor-nav-menu--dropdown a.elementor-sub-item:active {
    background-color: rgba(23, 52, 52, 0.08) !important;
    color: var(--pl-forest) !important;
  }
  [data-elementor-type="header"] .pl-nav .elementor-nav-menu--dropdown ul.sub-menu li.current-menu-item > a.elementor-sub-item:not([href*="#"]) {
    background-color: var(--pl-forest) !important;
    color: var(--pl-cream) !important;
  }
  /* An open section's row is tinted like its panel, however it was opened (a tap, or a brand's own page; there
     Elementor marks "Brands" active, which the anchor-quirk rule below would otherwise clear). */
  [data-elementor-type="header"] .pl-nav nav.elementor-nav-menu--dropdown li.menu-item-has-children > a.elementor-item.has-submenu.highlighted:not(:hover):not(:focus):not(:active),
  [data-elementor-type="header"] .pl-nav nav.elementor-nav-menu--dropdown li.menu-item-has-children > a.elementor-item.highlighted {
    background-color: rgba(23, 52, 52, 0.07) !important;
  }
  /* The row's chevron: §31.9's stroked chevron at the row's far end, turned up while its section is open. */
  [data-elementor-type="header"] .pl-nav nav.elementor-nav-menu--dropdown .sub-arrow {
    display: block !important;
    flex: 0 0 24px;
    width: 24px;
    height: 24px;
    margin: 0 -4px 0 auto;
    padding: 0 !important;
  }
  [data-elementor-type="header"] .pl-nav nav.elementor-nav-menu--dropdown .sub-arrow::after {
    width: 9px;
    height: 9px;
    margin: -6px 0 0 -5px;
    border-right-width: 1.6px;
    border-bottom-width: 1.6px;
    transition: transform .2s ease;
  }
  [data-elementor-type="header"] .pl-nav nav.elementor-nav-menu--dropdown a.highlighted .sub-arrow::after {
    margin-top: -2px;
    transform: rotate(225deg);
  }
  /* Same Elementor anchor-active quirk as the desktop mega (see §39): on
     /brands/ every /brands/#brand-* link would light up dark at once because
     Elementor's active flag ignores the #fragment. WP's current-menu-item
     stays the only highlight trigger; interaction states excluded so taps
     still respond. */
  [data-elementor-type="header"] .pl-nav .elementor-nav-menu--dropdown li:not(.current-menu-item) > a.elementor-item.elementor-item-active:not(:hover):not(:focus):not(:active) {
    background-color: transparent !important;
    color: var(--pl-forest) !important;
  }
  [data-elementor-type="header"] .pl-nav .elementor-nav-menu--dropdown li:not(.current-menu-item) > a.elementor-sub-item.elementor-item-active:not(:hover):not(:focus):not(:active) {
    background-color: transparent !important;
    color: var(--pl-forest) !important;
  }

  /* --- 25.5 Footer: readable link rows with legal tap targets ----------- */
  [data-elementor-type="footer"] .elementor-icon-list-items .elementor-icon-list-item > a {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
  [data-elementor-type="footer"] .elementor-icon-list-item {
    margin-bottom: 0 !important;
  }

  /* --- 25.6 Connect band ------------------------------------------------
     The arrow is an Icon widget: its Size is 117 / 64 (tablet) / 52 (phone)
     in the footer template — 100px squeezed the copy into a 174px measure.
     (The heading's 34px tablet / 25px phone sizes are the widget's own.) */
  [data-elementor-type="footer"] .pl-connect .elementor-widget-html,
  [data-elementor-type="footer"] .pl-connect .elementor-widget-icon {
    flex: 0 0 auto;
  }

  /* --- 25.7 Copyright strip on one line --------------------------------- */
  [data-elementor-type="footer"] .elementor-widget-text-editor p {
    margin: 0;
  }
}

@media (max-width: 767px) {
  /* The 4 footer columns stack; give the brand block and the lists a clear
     visual break instead of one undifferentiated ribbon of text. */
  [data-elementor-type="footer"] .pl-footer-brand p {
    max-width: 30ch;
  }
  /* 25.8 Sticky header height is 68px; nothing in the header may exceed it. */
  [data-elementor-type="header"] .pl-nav .elementor-button {
    min-height: 44px;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
  }

  /* --- 25.10 Logo link tap target ---------------------------------------
     The logo <a> hugged the 118x23px image. The pill has 52px of inner
     height, so the anchor can carry a 44px target without the logo itself
     changing size by a pixel. */
  [data-elementor-type="header"] .pl-nav .elementor-widget-image a {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
  }
}

@media (max-width: 380px) {
  /* 360px Android: the CTA is the first thing to run out of room. 12px is the
     floor — buy the space back from the horizontal padding, not the type.
     Measured at 360: 80.9px wide in a 92.4px zone. */
  [data-elementor-type="header"] .pl-nav .elementor-button {
    font-size: 12px !important;
    padding-left: 9px !important;
    padding-right: 9px !important;
  }
}

/* ===== §28 MOBILE BSC ===== */
/* Mobile QA (360 / 390 / 414) of Brands (1:402), Stockists (1:471) and
   Contact (1:369). There are no mobile designs in the Figma file, so these
   are responsive-judgement fixes kept consistent with the desktop system.
   Scoped to those three pages' own wrapper classes; must stay last. */

@media (max-width: 767px) {

  /* -- 28.1 Brands: ribbon weight --------------------------------------
     §22.1 derives ribbon thickness from the viewport with a curve
     calibrated at 1440. At 390 it resolved to 38px of strip on a 358px
     band — 10.6% of the band width against 4.8% at 1440 — so the two
     ribbons read as heavy black wedges with half-cropped logos rather
     than as ribbons. Re-derive: ~26px at 390, still continuous with the
     tablet curve at 767 (47.9px). */
  .pl-near-band .pl-ribbon .pl-marquee__track img.pl-marquee__strip {
    height: calc(3.34px + 5.81vw);
  }

  /* -- 28.2 Brands: CTA tap targets ------------------------------------
     "Find a stockist" 124x36 and "Contact us" 101x36 on the manifesto
     card, "Find a stockist" 124x36 in the near-you band. */
  .pl-overlap-47 .elementor-button,
  .pl-near-band .elementor-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding-top: 10px;
    padding-bottom: 10px;
  }

  /* -- 28.3 Stockists: locator controls + result-card actions ----------
     Measured at 390: address input 204x40, Find 55x33, "Get directions"
     128x36, "Call now" 81x35 — all short of the 44px minimum. */
  .pl-locator .Filter_section .sl-search-group { height: 50px; }
  .pl-locator .asl-cont input.asl-search-address { height: 48px !important; }
  /* The radius control sits in the lower half of a phone viewport, so the
     multiselect flipped to a drop-UP: it covered the address field and its
     first option was sliced off by §18.6's overflow:hidden on the panel.
     Pin it below the control and let it escape the panel. The results list
     has its own scroll container, so the panel does not need the clip. */
  .pl-locator .asl-panel-inner { overflow: visible !important; }
  .pl-locator .Filter_section { position: relative; z-index: 30; }
  .pl-locator .asl-cont .sl-dropdown-cont .multiselect-container.adropdown-menu {
    top: 100% !important;
    bottom: auto !important;
    margin: 6px 0 0 !important;
    /* Popper writes an inline translate3d(0,-172px,0) to flip the menu up;
       author !important outranks a non-important inline declaration. */
    transform: none !important;
  }
  .pl-locator .asl-cont button.asl-search-event {
    height: 44px !important;
    min-width: 64px;
  }
  .pl-locator .asl-cont .sl-dropdown-cont,
  .pl-locator .asl-cont .sl-dropdown-cont .btn-group,
  .pl-locator .asl-cont .sl-dropdown-cont .btn-group > button.multiselect {
    height: 48px !important;
  }
  /* The map wrapper carries a plugin min-height of 540px, which beats
     §18.8's `height: 420px !important` — the canvas drew 420px and the card
     then held 120px of dead cream below the map. */
  .pl-locator .asl-map,
  .pl-locator .asl-map .map-image,
  .pl-locator .asl-map #asl-map-canv {
    height: 380px !important;
    min-height: 0 !important;
  }
  /* At 44px tall the two result-card actions (128px + 81px + the plugin's
     own margins) no longer fit the 226px row and wrapped onto two lines. */
  .pl-locator .asl-cont .sl-act-btns { flex-wrap: nowrap; gap: 8px; align-items: stretch; }
  .pl-locator .asl-cont .sl-act-btns > a {
    flex: 1 1 0 !important;
    margin: 0 !important;
    justify-content: center;
    white-space: nowrap;
    padding-left: 8px !important;
    padding-right: 8px !important;
  }
  /* "Get directions" needs ~98px of text; two equal halves of the 226px row
     are 111px, so the desktop label broke onto two lines. */
  .pl-locator .asl-cont a.s-direction::after { content: none; } /* was 'Directions'; label now = Store Locator "Directions" */
  /* Agile Store Locator's own stylesheet loads after pl-global and pins a
     height on .btn, so "Get directions" stayed 128x36 until this carried
     !important. .pl-call-now is ours and needed neither. */
  .pl-locator .asl-cont .sl-act-btns a.btn.s-direction,
  .pl-locator .asl-cont .sl-act-btns a.btn.btn-asl,
  .pl-locator .asl-cont .sl-act-btns .btn-asl,
  .pl-locator .asl-cont a.s-direction,
  .pl-locator .asl-cont a.pl-call-now {
    min-height: 44px !important;
    height: auto !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
  }

  /* -- 28.4 Contact: submit button (87x42) -----------------------------
     Stacked above the privacy note at mobile, there is no reason for it
     to stay shrink-to-fit. */
  .pl-form .elementor-field-group.elementor-field-type-submit.pl-form-actions button.elementor-button {
    width: 100% !important;
    flex: 1 1 100% !important;
    min-height: 48px;
  }
  .pl-form .elementor-field-group.elementor-field-type-submit.pl-form-actions { gap: 12px; }
}

@media (max-width: 380px) {
  /* 360px Android: "Grooming and everyday care" is the widest pill
     (268px at 390) and the 23px side padding pushed it to the edge. */
  .pl-brand-directory .pl-filter-bar { gap: 8px; }
  .pl-brand-directory button.pl-filter-pill {
    padding-left: 17px;
    padding-right: 17px;
  }
}

/* ===== §27 MOBILE ABOUT+TEAM ===== */
/* /about-us/ (Figma 1:296) and /our-team/ (1:432) have no mobile design; these
   rules extend the desktop system down to 360-414px. Everything is scoped to
   the two pages' own component classes. §17 and §21 are the rules being
   corrected, so every selector here carries one extra class so it wins
   regardless of source order. */

/* 27.1 Team intro group photo. §21.6 crops the 1800x1210 photo through a
   Figma-derived 118.28% x 151.52% window tuned for the desktop 582x306 frame.
   At 390px the frame is 272x220, so that window rendered the image 284x348 — a
   1.5x zoom that cut every face in the top three rows off the top edge. Below
   767px use a plain cover crop instead: at 272x220 the scale is 0.182, so the
   full height of the group is in frame and only ~150 source px are lost from
   each side. */
@media (max-width: 767px) {
  .elementor .pl-fcard.pl-team-intro .elementor-widget-image {
    height: 220px;
  }
  .elementor .pl-fcard.pl-team-intro .elementor-widget-image img {
    left: 0;
    top: 0;
    width: 100%;
    height: 100% !important;
    object-fit: cover;
    object-position: 50% 50%;
  }
}

/* 27.2 Go Natural ingredient collage. §21.5 lays the artwork out at its own
   1104x388 (2.85:1) bounding box, which inside the banner's 28px padding is
   264x93 at 390px — a strip, with the produce too small to read. Bleed it to
   the banner edges and down to the foot of the panel (the build script drops
   the banner's bottom padding on mobile) and zoom 1.355x, giving a 320x152
   band at 390px. The zoom crops 13.3% off each end of the collage; the
   banner's own 50px radius plus overflow:hidden rounds the bottom corners so
   it reads as the base of the panel rather than a floating strip. */
@media (max-width: 767px) {
  /* §17g's `.pl-gn-band > .e-con-inner > .elementor-widget` sets
     width:100% !important at (0,3,0) — this must out-specify it. */
  .elementor .pl-gn-band > .e-con-inner > .elementor-widget.pl-gn-ingredients {
    width: calc(100% + 56px) !important;
    /* Elementor caps every widget at max-width:100% of the inner track, which
       silently clamped the calc back to 264px. */
    max-width: none !important;
    margin: 26px -28px 0 -28px;
    aspect-ratio: 1104 / 526;
    border-radius: 0;
    overflow: hidden;
  }
  .elementor .pl-gn-band .pl-gn-ingredients img {
    left: -17.75%;
    top: -68.06%;
    width: 171.8%;
    border-radius: 0;
  }
}

/* 27.3 Team "Join our pack" photo band. The source is 1800x384 (4.69:1), so
   §17g was right to drop it as a background below 767px — cover on a 320x333
   panel would have shown an 82px slice of grass. But a flat forest fill left
   this as the only section on either page with no image at all. The build
   script adds a real <img> at the foot of the panel instead: full-bleed, 190px
   tall, framed on the woman and dog (they sit at x 44-67% of the strip).
   Desktop keeps the background photo, so the widget is hidden there. */
@media (min-width: 768px) {
  .elementor .pl-join-band .pl-join-photo { display: none !important; }
}
@media (max-width: 767px) {
  .elementor .pl-join-band > .e-con-inner > .elementor-widget.pl-join-photo {
    width: calc(100% + 56px) !important;
    max-width: none !important;
    margin: 4px -28px 0 -28px;
    align-self: stretch;
  }
  .elementor .pl-join-band .pl-join-photo img {
    display: block;
    width: 100%;
    height: 190px;
    object-fit: cover;
    object-position: 56% 50%;
    border-radius: 0;
  }
}

/* 27.4 Touch targets. The Figma button is a 33px pill (14px/0.9em + 10px
   padding), under the 44px minimum. The build scripts now emit
   text_padding_mobile; this is the floor in case a widget misses it. Scoped to
   the two pages' own bands so the header and footer stay untouched. */
@media (max-width: 767px) {
  .pl-fcard .elementor-button,
  .pl-personal .elementor-button,
  .pl-gn-band .elementor-button,
  .pl-join-band .elementor-button {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}

/* ===== §29 CONSISTENCY ===== */
/* Owner: cross-page consistency pass. Everything below exists only to make the
   SAME pattern resolve to the SAME value on every page. Per-page differences
   that Figma genuinely specifies are NOT touched here.

   29.1 Mobile section rhythm.
   Figma has no mobile artboards, so the mobile scale is derived from the
   desktop gaps (which do match Figma on all six pages) by banding them:
       desktop <=35 -> 24    36-60 -> 32    61-80 -> 40    81-120 -> 48
   The values themselves now live in the build scripts as margin_mobile, so
   there is one source of truth. §26.6 predates that and sets Home's three
   bands with !important at a higher specificity than Elementor's own output,
   which would silently pin Home to 20/20/40 and re-create the drift. §26.6 and
   the three hand-back rules that were here are gone (build/be-spacing.php). */


/* ===== §30 TEXTURE ===== */
/* The riso stipple is the design's main tactile device (Figma applies it with
   mix-blend soft-light at 31-89%). The perf pass shrank the tile to the point
   where it stopped reading, leaving every green band and beige panel flat.
   soft-light preserves the underlying hue far better than overlay on the
   dark forest surfaces. */
.pl-texture::after,
.pl-texture-soft::after {
  opacity: 0.85 !important;
  mix-blend-mode: soft-light !important;
  background-size: 160px 160px !important;
}


/* ===== §31 VISUAL QA ===== */
/* Designer QA round 5. Everything below is either a token that removes a
   per-page drift, or a Figma-measured correction. Measurements were taken off
   the 1440-wide page exports in assets/figma/<page>/_page-export.png, which are
   1:1 with the design. */

/* -- 31.1 One page-gutter token ------------------------------------------
   Below the desktop breakpoint every top-level panel — hero bands included —
   now resolves to the same gutter. Previously each container carried its own
   number and, worse, only some declared a tablet value: the rest fell through
   to their desktop gutter (35 / 48 / 83.5 / 91), so between 768 and 1024
   Brands and Stockists rendered a 35px hero above 24px panels and the card
   visibly stepped outside the band it overlaps. Measured before:
     home 24 + 48 · about 35 · team 35 · brands 35→24 · stockists 35→24 · contact 35
   After: 24 everywhere at tablet, 16 everywhere at mobile.
   The selector is deliberately 0,4,0 so it beats §26's per-card !important
   rules but still loses to anything more specific that genuinely needs it. */
:root { --pl-gutter: 16px; }
@media (min-width: 768px) and (max-width: 1024px) {
  :root { --pl-gutter: 24px; }
}
/* fix-be-styles pages (36-41) carry these gutters as their containers' own Elementor
   tablet/mobile Margin (build/be-spacing.php); Go Natural (45) too, since 2026-09-30
   (build/fix-gonatural-be.php). */

/* -- 31.2 One display-heading leading token ------------------------------
   Elementor's own `.elementor-widget-heading .elementor-heading-title{line-height:1}`
   landed on every heading that did not set a line height explicitly, so
   multi-line display type ran at 1.0 and descenders touched the next line's
   ascenders (Brands "Find Pack Leader / brands near you" worst, at 51/51).
   Figma's display leading, measured baseline to baseline off the exports:
     brands H1  81 / 64px = 1.266     brands H2   64 / 51px  = 1.255
     home CTA   47 / 37px = 1.270     home offer  44.5/36px  = 1.236
   1.266 is both the mean and the value the build already uses for Home's
   "Delivered nationwide" and "Why partners choose us", so it becomes the token.
   Specificity 0,3,0: beats Elementor's default, loses to the per-widget CSS
   Elementor prints (0,4,0) — so headings carrying a genuine Figma line height,
   such as About's 55/63 = 1.145, keep it. */
:root { --pl-lh-display: 1.266; }
.elementor .elementor-widget-heading .elementor-heading-title {
  line-height: var(--pl-lh-display);
}

/* -- 31.4 Photography framing -------------------------------------------- */
/* About "What we do": Figma frames source region (7,10,1942,675) of the
   2000x745 photo, which is background-size 103% at 12% 14%. Live sat 4px right
   and 1.4px low of that. (The band's darkening layer is NOT reverted — §21.3
   raised it deliberately to hold the copy at 5.5:1, where Figma's lighter
   scrim measures 3.05:1.) */
.pl-ww-band {
  background-position: 12% 14% !important;
}
/* Contact photo: frame size and image scale already match Figma exactly; only
   the horizontal window was wrong. Figma shows source x 568..1560 of 1600 —
   the right-hand 62% — which is what keeps the bird's head in frame. Centre
   cropping pushed it off the right edge. */
.elementor .pl-contact-media img {
  object-position: 93% 50% !important;
}
/* Home hero at mobile: a 358x470 portrait box takes a 78% horizontal crop out
   of a 16:9 frame, and at 80% that window landed on empty grass to the right
   of the subject. 26% centres the window on the patterned legs — the subject
   the 1440 design centres.
   Retired (mobile QA 2026-10-15): the legs alone showed no pet. The phone crop
   is the hero's Mobile background position in Elementor (Center Right: hand,
   ball and dog; the #FFF7F2 28-30px H1 is 4.5:1 or more on 99% of the pixels
   behind it, median 7.4-7.9:1, worst 2.9:1 on a sliver of the sunlit hand),
   so a !important here no longer overrides it. */

/* -- 31.5 "Delivered nationwide" CTA cards -------------------------------- */
/* Figma node 1:53 fills the light card's hover with #DFC191. The build sets
   exactly that, but §1 overrode it with --pl-gold (#E2CD96). --pl-gold has no
   other consumer, so this is scoped rather than re-pointing the token. */
.pl-cta-card--light:hover {
  background-color: #DFC191 !important;
}
/* The photo card centres heading + arrow as one group. Figma puts the arrow
   17px under the heading box; §14's 16px margin-top plus the heading's own
   trailing space measured 33px, dropping the glyph onto the dog's forehead.
   Moving that space below the arrow keeps the group's height — and therefore
   the heading's centred position — identical while lifting the arrow 16px. */
.pl-photo-arrow {
  margin-top: 0 !important;
  margin-bottom: 16px !important;
}

/* -- 31.5b Riso texture on the light panels ------------------------------
   §30's `soft-light` is the right blend for the forest surfaces, but on a
   beige base soft-light compresses almost to nothing. Measured on a clean
   interior patch of the Brands "near you" panel:
     Figma  mean 236  std 6.91  range 32
     live   mean 221  std 2.07  range 11   (~3x too weak)
   The dark bands are already close (Figma std 8.5 / live 5.2), so only the
   light surfaces are re-blended — multiply is how a riso stipple actually
   sits on light stock, and it restores the amplitude without tinting. */
.pl-cta-card--light.pl-texture::after,
.pl-texture.pl-near-band::after,
.pl-texture.pl-locations::after,
.pl-texture.pl-personal::after {
  mix-blend-mode: multiply !important;
  opacity: 0.5 !important;
}

/* -- 31.6 Brand cards ----------------------------------------------------
   Figma's card is 407px wide with the image inset to 379; ours inset to 377,
   i.e. 14px of padding against the design's 13. */
.pl-brand-directory .pl-brand-card { padding: 13px; }

/* -- 31.7 (retired) Team "Join our pack" scrim — the 2026-09 board 29:9215
   is exactly §7's shared forest ramp (solid → clear by 70.2%), so the band no
   longer carries its own heavier override. */

/* -- 31.8 Footer --------------------------------------------------------- */
/* The strapline block is 382px in Figma and the type in it is 18/24, which is
   what breaks the line after "natural pet food". Keep the measure pinned so a
   change of column width cannot reintroduce the "and premium" break. */
.pl-footer-brand,
.elementor .pl-footer-brand {
  max-width: 382px;
}

/* -- 31.9 "Campaigns" dropdown caret -------------------------------------
   Elementor ships Font Awesome's solid caret-down; the design uses a light
   stroked chevron. Replace the glyph rather than restyle it. */
[data-elementor-type="header"] .pl-nav .sub-arrow svg { display: none; }
[data-elementor-type="header"] .pl-nav .sub-arrow {
  position: relative;
  width: 14px;
  margin-left: 5px;
}
[data-elementor-type="header"] .pl-nav .sub-arrow::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 7px;
  height: 7px;
  margin: -5px 0 0 -4px;
  border: 0;
  border-right: 1.3px solid currentColor;
  border-bottom: 1.3px solid currentColor;
  transform: rotate(45deg);
}

/* -- 31.10 Store locator copy -------------------------------------------- */
/* Figma 1:512 labels the action "Get directions" at every size; §28 shortened
   it to "Directions" to fit a two-up row at 390. Restore the design's wording
   and let the button take the room instead. */
@media (max-width: 767px) {
  .pl-locator .asl-cont a.s-direction::after { content: none !important; } /* the button's own text: Store Locator label "Directions" */
}
/* The plugin prints the value as "50 Km" and capitalises it, and §22.4 appends
   " radius" — which rendered "50 Km Radius". Lower-casing gives "50 km radius".
   (An earlier pass also closed the number/unit space with a negative
   word-spacing to read "50km"; the client wants the space kept.) */
.pl-locator .asl-cont .sl-dropdown-cont .btn-group > button.multiselect .multiselect-selected-text,
.pl-locator #asl-storelocator .sl-dropdown-cont button.multiselect .multiselect-selected-text {
  text-transform: lowercase !important;
}
/* The radius control kept its 136px desktop width at 390, so it wrapped to a
   second row and sat there at a third of the measure — the "unfinished" read.
   Full width under a full-width search row is a finished mobile form; the
   alternative (three controls on one 266px row) leaves a ~100px address
   field. */
@media (max-width: 767px) {
  /* ID-qualified: the Agile Store Locator stylesheet loads after pl-global, so
     an equal-specificity !important would lose to its own 136px rule. */
  .pl-locator #asl-storelocator .Filter_section .search_filter,
  .pl-locator #asl-storelocator .asl-advance-filters,
  .pl-locator #asl-storelocator .range_filter,
  .pl-locator #asl-storelocator .asl-filter-cntrl,
  .pl-locator #asl-storelocator .sl-dropdown-cont,
  .pl-locator #asl-storelocator .sl-dropdown-cont .btn-group,
  .pl-locator #asl-storelocator .sl-dropdown-cont .btn-group > button.multiselect {
    width: 100% !important;
    max-width: none !important;
    flex: 1 1 100% !important;
  }
  .pl-locator #asl-storelocator .sl-dropdown-cont .btn-group > button.multiselect {
    text-align: left;
  }
}

/* -- 31.10b "Buy online" grid ---------------------------------------------
   13 retailers in a 2-up grid leaves the last row half empty, and because the
   cells are outlined the empty slot reads as a bordered cell with nothing in
   it. Let an odd last cell span the row instead. */
@media (max-width: 767px) {
  .pl-dash-grid .pl-dash-cell:last-child:nth-child(odd) { grid-column: span 2; }
  /* keep the spanning logo the same optical size as its neighbours */
  .pl-dash-grid .pl-dash-cell:last-child:nth-child(odd) img { max-width: 40%; }
}

/* -- 31.11 Mobile specifics ---------------------------------------------- */
@media (max-width: 767px) {
  /* "9 provinces" is one stat value: 9 at display size, "provinces" as a small
     run beside it. §26.3 set that run to `display:block`, which pushed it onto
     its own line — the reported orphan — and made the cell 65px tall against
     46px for "120+", breaking the baseline it shares with "Employees".
     Inline at 17px the pair measures ~106px inside a 157px cell.
     Relative to the heading (40px on phones = its Elementor mobile size), so
     changing that size in Elementor scales both parts: 1em / 0.425em. */
  .elementor .pl-stats-band .pl-stat-9 { font-size: 1em !important; }
  .elementor .pl-stats-band .pl-stat-sub {
    display: inline !important;
    margin-top: 0 !important;
    font-size: max(14px, 0.425em) !important;   /* the numerals are 32–38px on phones since the 2026-10-13 type scale */
  }
  .elementor .pl-stats-band .pl-stat-value-w .elementor-heading-title {
    white-space: nowrap;
  }

  /* Brands ribbon panel: the two diagonal marquees are 1500px wide and rotated,
     so at 390 they clip to a pair of green triangles carrying unreadable word
     fragments. Below the breakpoint they are decoration that no longer reads —
     drop them and reclaim the padding reserved for them. */
  .pl-near-band .pl-ribbon { display: none !important; }
  .elementor .e-con.pl-near-band { padding-top: 48px !important; }
}
/* Connect arrow: §15's `@media (hover:none)` reset it to 0deg, so a touch
   viewport showed the design's diagonal as a plain horizontal arrow. The
   resting state is ↗ at every size; only the hover transition is dropped. */
@media (hover: none) {
  .pl-connect .pl-connect-arrow svg { transform: rotate(-45deg); }
}


/* ===== §32 LOCATOR CARD — Figma 1:481 / 1:492 =====
   The Figma card is 238px tall because it holds one short two-line address.
   Real records have long practice names and addresses that wrap, so the card
   must be a FLOW layout with 238px as a minimum, not a fixed height with the
   action row pinned absolutely — that collided with the phone row on 12 of the
   36 live stores. Spacing below reproduces the design's rhythm:
   title 11-41, address lines at a 22px pitch, email/phone 20px rows,
   action row 18px clear of the last row, 24px bottom padding. */
.pl-locator .asl-panel-inner .sl-list { padding: 0 !important; }
.pl-locator .sl-item {
  display: flex !important;
  flex-direction: column !important;
  height: auto !important;
  border-radius: 17px !important;
  border: 1px solid rgba(23, 52, 52, 0.11) !important;
  background: #FCFCFB !important;
  padding: 11px 19px 20px !important;
}
/* ASL zeroes this margin from TWO ID-qualified rules
   (`#asl-storelocator.asl-cont .sl-main-cont .asl-panel-inner .sl-item`),
   and an ID beats any class-only selector no matter how many !importants we
   add — so the override has to carry the ID too. */
#asl-storelocator.asl-cont .sl-main-cont .asl-panel-inner ul.sl-list > li.sl-item,
#asl-storelocator.asl-cont .asl-wrapper .sl-main-cont .asl-panel-inner ul.sl-list > li.sl-item {
  margin: 0 0 13px !important;
}
#asl-storelocator.asl-cont .sl-main-cont .asl-panel-inner ul.sl-list > li.sl-item:last-child {
  margin-bottom: 0 !important;
}
.pl-locator .sl-item .sl-addr-sec {
  padding: 0 !important;
  display: flex; flex-direction: column; flex: 1 1 auto;
}
.pl-locator .sl-item .sl-row.addr-loc { margin: 0 !important; }
.pl-locator .sl-item .pol-12 { padding: 0 !important; }

/* title + globe share a row (design puts the globe beside the name) */
.pl-locator .sl-item .sl-addr-list-title {
  font-size: 16px !important;
  font-weight: 600 !important;
  line-height: 30px !important;
  color: var(--pl-forest) !important;
  margin: 0 !important;
  padding: 0 !important;
  display: inline;
}
.pl-locator .sl-item .pl-site {
  display: inline-flex;
  vertical-align: middle;
  margin-left: 8px;
  width: 20px; height: 20px;
  color: var(--pl-forest); opacity: .7;
}
.pl-locator .sl-item .pl-site svg { display: block; }
/* 20px glyph, 44px touch target — expanded with a pseudo-element so the
   inline flow beside the store name is unaffected. */
.pl-locator .sl-item .pl-site { position: relative; }
.pl-locator .sl-item .pl-site::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  width: 44px; height: 44px;
  transform: translate(-50%, -50%);
}

.pl-locator .sl-item ul { list-style: none !important; margin: 4px 0 0 !important; padding: 0 !important; }

/* address: plain lines, no pin icon */
.pl-locator .sl-item li.sl-addr { padding: 0 !important; margin: 0 !important; }
.pl-locator .sl-item li.sl-addr i { display: none !important; }
.pl-locator .sl-item li.sl-addr .pl-addr-line,
.pl-locator .sl-item li.sl-addr span {
  display: block;
  font-size: 14px !important;
  font-weight: 500 !important;
  line-height: 22px !important;
  color: rgba(23, 52, 52, 0.58) !important;
}
/* email + phone rows */
.pl-locator .sl-item li.sl-email,
.pl-locator .sl-item li.sl-phone {
  display: flex !important;
  align-items: center;
  gap: 8px;
  padding: 0 !important;
  margin: 6px 0 0 !important;
  min-height: 20px;
}
.pl-locator .sl-item li.sl-email a,
.pl-locator .sl-item li.sl-phone a,
.pl-locator .sl-item li.sl-email span,
.pl-locator .sl-item li.sl-phone span {
  font-size: 14px !important;
  font-weight: 400 !important;
  line-height: 20px !important;
  color: rgba(23, 52, 52, 0.4) !important;
  word-break: break-word;
}
.pl-locator .sl-item li.sl-email i,
.pl-locator .sl-item li.sl-phone i {
  font-size: 16px !important;
  width: 20px; flex: 0 0 20px;
  color: var(--pl-forest) !important;
  opacity: 0.75;
}

/* action row sits at the foot of the card, in flow */
/* A fixed gap keeps every card's internal rhythm identical. Pinning the row to
   the bottom of a 238px floor made the space above it swing 70px -> 26px. */
.pl-locator .sl-item .sl-act-btns {
  display: flex !important;
  gap: 6px !important;
  margin: 18px 0 0 !important;
  padding-top: 0 !important;
  position: static !important;
}
.pl-locator .sl-item .sl-act-btns .s-direction {
  border-radius: 8px !important;
  padding: 10px 13px !important;
  background: var(--pl-forest) !important;
  border: 1px solid rgba(255, 255, 255, 0.15) !important;
  min-height: 0 !important; height: auto !important;
}
.pl-locator .sl-item .sl-act-btns .s-direction::after {
  font-size: 14px !important; font-weight: 500 !important; line-height: 12.6px !important; color: #FFFFFF !important;
}
.pl-locator .sl-item .sl-act-btns .pl-call-now {
  border-radius: 9.85px !important;
  padding: 10px 13px !important;
  border: 0.821px solid rgba(23, 52, 52, 0.22) !important;
  background: transparent !important;
  font-size: 14px !important; font-weight: 500 !important; line-height: 11.8px !important;
  color: var(--pl-forest) !important;
  min-height: 0 !important; height: auto !important;
  display: inline-flex; align-items: center;
}
/* panel + map shells (1:482 / 1:546) */
.pl-locator .asl-panel-inner {
  border-radius: 19px !important;
  border: 1px solid rgba(23, 52, 52, 0.16) !important;
  background: #FCFCFB !important;
  padding: 23px 25px !important;
}
.pl-locator .asl-map { border-radius: 26px !important; }

/* The results scroller is ASL's `.sl-main-cont-box`, not the <ul>. Left
   unstyled its bar sat hard against the panel edge and clipped the 19px
   radius. Inset it and make it subtle. */
.pl-locator .sl-main-cont-box {
  padding-right: 10px !important;
  scrollbar-width: thin;
  scrollbar-color: rgba(23, 52, 52, 0.28) transparent;
  border-radius: 12px;
}
.pl-locator .sl-main-cont-box::-webkit-scrollbar { width: 6px; }
.pl-locator .sl-main-cont-box::-webkit-scrollbar-track { background: transparent; margin: 4px 0; }
.pl-locator .sl-main-cont-box::-webkit-scrollbar-thumb {
  background: rgba(23, 52, 52, 0.28);
  border-radius: 999px;
}
.pl-locator .sl-main-cont-box::-webkit-scrollbar-thumb:hover { background: rgba(23, 52, 52, 0.45); }
@media (max-width: 767px) {
  .pl-locator .sl-item { min-height: 0 !important; padding: 14px 16px 18px !important; }
  .pl-locator .asl-panel-inner { padding: 16px !important; }
  /* With the real 36-store list the results panel ran 9,456px and pushed the
     page to 12,529px. Keep the list a scrollable panel on phones, as it is on
     desktop, so the map and the rest of the page stay reachable. */
  /* §18 line ~1299 pins `.pl-locator ul.sl-list { max-height:none !important }`
     — match its specificity or the constraint silently loses. */
  .pl-locator ul.sl-list,
  .pl-locator #asl-list {
    max-height: 62vh !important;
    height: auto !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch;
  }
  .pl-locator .asl-panel,
  .pl-locator .asl-panel-inner { height: auto !important; }
}


/* ===== §33 TABLET HAT ===== */
/* Owner: home / about / team (build/build-home.php, build-about.php,
   build-team.php). Tablet was never QA'd: §26 (mobile home), §27 (mobile
   about+team) and §28 all stop at `max-width: 767px`, and §16's tablet block
   only moves gutters, so 768-1024 inherited the raw desktop layout with
   desktop type, desktop padding and desktop min-heights.

   EVERY rule below is gated to `(min-width: 768px) and (max-width: 1024px)`,
   so nothing at >= 1025px (the Figma-matched desktop rhythm) or <= 767px
   (the phone work in §26/§27/§28) can be reached. Rules that exist only
   because of *touch* behaviour additionally carry `(hover: none)` so a
   desktop-pointer window at 1024 keeps its working hover interaction.
   All measurements taken at 768 / 820 / 1024 in a touch context. */

/* --- 33.1 Home offer cards, touch: stop the reveal painting over the art ---
   `@media (hover: none)` (§15 / §23.5) makes `.pl-reveal` static on a touch
   tablet, but `.pl-card-art` stays absolute to its Figma percentages, so the
   panel is permanently parked on top of the product photography. Measured at
   768: card 0 box y 725-1334, art y 674-1342 (absolute, full bleed), reveal
   y 952-1284 sitting straight over it; same at 1024 (art y 679-1286, reveal
   y 906-1116). §26.2 already solves this for phones — this is the same
   treatment for 768-1024: heading -> image -> paragraph -> button, in flow,
   nothing overlapping. Also on touch screens wider than 1024 (landscape iPads 1180 / 1366 — spacing review
   2026-10-13: the same parked panel, 146–193px over the art). */
@media (min-width: 768px) and (hover: none) {
  .elementor .e-con.pl-offer-card {
    min-height: 0 !important;
    display: flex;
    flex-direction: column;
  }
  .elementor .pl-offer-card > .elementor-widget-heading { order: 1; }
  .elementor .pl-offer-card > .elementor-widget-html,
  .elementor .pl-offer-card > .elementor-widget-pl_card_art { order: 2; width: 100%; }
  .elementor .pl-offer-card > .pl-reveal                { order: 3; }
  /* §1 pins `.pl-card-art { position: absolute !important }`, so every inset
     has to be unwound explicitly before the image can join the flow. */
  .elementor .pl-offer-card .pl-card-art {
    position: static !important;
    left: auto !important;
    top: auto !important;
    right: auto !important;
    bottom: auto !important;
    width: 100% !important;
    max-width: 100% !important;
    height: 236px !important;
    object-fit: cover !important;
    /* Both sources carry transparent headroom above the product row (§26.2). */
    object-position: center 82% !important;
    border-radius: 12px;
  }
  .elementor .pl-offer-card + .pl-offer-card .pl-card-art {
    object-position: center 72% !important;
  }
  /* In flow the frosted panel is just a floating rectangle — drop the glass
     and let the copy sit on the card the way the heading does. §1's
     `position: absolute !important`, §20's 11px insets and §23.5's 11px
     margin all have to be unwound here. */
  .elementor .pl-offer-card .pl-reveal,
  .elementor .pl-offer-card .e-con.pl-reveal {
    position: static !important;
    transform: none !important;
    left: auto !important;
    right: auto !important;
    bottom: auto !important;
    margin: 0 !important;
    width: 100% !important;
    padding: 16px 0 0 !important;
    background: transparent !important;
    border: 0 !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
    border-radius: 0 !important;
  }
  .elementor .pl-offer-card .pl-reveal .elementor-widget-button { width: auto; }
}

/* --- 33.2 Home offer cards: desktop padding / type at tablet --------------
   Measured at 768: card 332 wide with the desktop 38/43 padding = 246px of
   content, and the h3 still at 36px; the reveal paragraph measured 182px
   wide and 234px tall (13 lines). Applies on pointer and touch alike — the
   squeeze is a width problem, not a hover problem. */
/* (28 / 24 tablet padding: the two offer cards' own Elementor tablet Padding.) */

/* --- 33.3 Home stats band: the tablet numerals (clamp(52px, 8.8vw, 90px) / 1.16)
   are the stat headings' own Elementor tablet typography. */

/* --- 33.4 Home "Delivered nationwide" CTA cards --------------------------
   Three 33.3% cards keep the desktop 25/33/34 padding and 37px headings. At
   768 that is a 208px card with 141px of content: measured h3 "Become a
   stockist" scrollWidth 152 in an 85px box (+67) and "Partner with us" 131
   in 81 (+50) — the first word ran out under the arrow chip. Still +12 at
   1024. */
@media (min-width: 768px) and (max-width: 1024px) {
  .elementor .e-con.pl-cta-card {
    min-height: clamp(260px, 32.7vw, 335px) !important;   /* padding 24/22: the cards' tablet Padding */
  }
  .elementor .pl-cta-card .pl-card-top .elementor-widget-heading {
    width: 68% !important;
    min-width: 0;
  }
  .elementor .e-con.pl-card-top { flex-wrap: nowrap !important; gap: 10px; }
}

/* --- 33.5 Touch tap targets, 768-1024 ------------------------------------
   Measured under 40px in a touch context: the offer-card "Explore our
   brands" button 187 x 34 (at 768 it only cleared 40 by breaking onto two
   lines), the card arrow chips 37 x 33, and the About/Team text buttons
   35px tall ("Find out more" 120 x 35, "Contact us" 101 x 35, "Get in
   touch" 109 x 35, "Apply now" 98 x 35). Height only — the 14px/500/r8
   button style and its padding are untouched. */
@media (min-width: 768px) and (max-width: 1024px) and (hover: none) {
  /* Scoped to the sections these three pages own — `main.pl-main` wraps every
     page, including ones other agents own, so it is deliberately not used. */
  .elementor .pl-offer-card .pl-reveal .elementor-button,
  .elementor .pl-gn-band .elementor-button,
  .elementor .pl-team-intro .elementor-button,
  .elementor .pl-personal .elementor-button,
  .elementor .pl-join-band .elementor-button {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
  }
  .elementor .pl-cta-card .pl-arrow-chip {
    width: 44px;
    height: 44px;
    border-radius: 10px;
  }
  /* A touch tablet never reaches :hover either, so the resting
     rgba(0,0,0,0.2) scrim is all it gets — cream type and a cream arrow over
     a bright, near-white dog photo. §26.4 already deepens this for phones;
     the same value applies here. */
  .elementor .e-con.pl-cta-card--photo::before {
    background-color: rgba(23, 52, 52, 0.48) !important;
  }
}

/* --- 33.6 About "Our philosophy" columns ---------------------------------
   The three columns carry 74.75px of desktop side padding. At 768 that left
   the middle column 111px of text box against a 119px scrollWidth (+8) and
   broke "Products that actually serve real pet needs" over six lines. */
/* 2026-09 board 29:8867/29:8877: the first two philosophy sentences sit in
   text boxes WIDER than their columns (319 in 291, 326 in 299) — that is what
   produces the board's line breaks. The widgets carry those widths
   (_element_custom_width); Elementor's own max-width:100% was clamping them
   back to the column. Desktop only; ≤1024 resets the widths to 100%.
   The overhang is capped at the board's 28px: uncapped, the 319/326px boxes
   ran across the dividers once the columns narrowed (1025-1280). */
@media (min-width: 1025px) {
  .elementor .e-con.pl-phil-col > .elementor-widget-heading.elementor-widget__width-initial { max-width: calc(100% + 28px); }
}
@media (min-width: 768px) and (max-width: 1024px) {
}

/* --- 33.7 Home section rhythm at tablet ----------------------------------
   About and Team already carry a tablet rhythm (About's `margin_tablet`
   drops 107/115/108/108 to a flat 70; Team's 53/51/51 are tight enough to
   stand). Home is the page that was never tuned: measured 24 / 46 / 94 gaps
   plus 93 to the footer at 768, 820 AND 1024 — byte-identical to 1440,
   where they sit against a 1273px canvas rather than a 720px one. The 94,
   plus the 65px padding-top on the section's inner container, put 159px of
   empty cream between the Delivered panel and the "Why partners choose us"
   heading on a 768px screen. Retuned on About's own tablet ratio
   (107 -> 70, x0.65): 94 -> 64, 93 -> 64, inner 65 -> 44. The 24 and 46
   gaps above are already small and are left alone. Desktop (>= 1025px, the
   Figma-matched 94/93) and phone (<= 767px, §26.6's 40/40) are untouched. */
/* 64 / 64: the section's own Elementor tablet Margin (build/be-spacing.php). */

/* ===== §34 TABLET BSC ===== */
/* Tablet QA (1024 / 820 / 768, touch context) of Brands (1:402),
   Stockists (1:471) and Contact (1:369). The 768-1024 band had never been
   QA'd: §18.8 stacks the locator and drops the brand grid to two columns
   there, but the round of repairs that followed the real 36-store import
   and the mobile pass (§28, §31, §32) only ever ran inside `max-width:
   767px`, so the tablet range kept the broken behaviour. Everything here is
   scoped to those three pages' own wrapper classes and must stay last. */

@media (min-width: 768px) and (max-width: 1024px) {

  /* -- 34.1 Stockists: the results list had no cap between 768 and 1024 ---
     §18 gives the panel a fixed 625px and lets `.sl-main-cont-box` scroll
     inside it; §18.8 releases that to `height: auto; min-height: 360px` so
     the stacked panel can size to its content. With one seeded store that
     was right. With the client's 36 it is not: measured panel 8,747px at
     1024 and 8,883px at 820 and 768, taking the page to 11,837 / 11,740 /
     11,673px — the map and "Buy online" sat below nine thousand pixels of
     list. §32 caps the list at 62vh below 767 for the same reason; this is
     that cap for the tablet range, expressed as a panel height so the flex
     column already inside `.asl-panel-inner` does the scrolling and the
     search row stays pinned above it. */
  .pl-locator #asl-panel.asl-panel {
    height: 620px !important;
    min-height: 0 !important;
  }
  .pl-locator .sl-main-cont-box {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch;
  }

  /* -- 34.2 Stockists: 120px of dead cream under the map ------------------
     The same defect §28 fixed at mobile. The Agile Store Locator wrapper
     carries its own `min-height: 540px`, which outranks §18.8's
     `height: 420px !important`, so the canvas drew 420px inside a 540px box.
     Measured wrapper 540 / canvas 420 at all three tablet widths. */
  .pl-locator .asl-map,
  .pl-locator .asl-map .map-image,
  .pl-locator .asl-map #asl-map-canv {
    height: 460px !important;
    min-height: 0 !important;
  }

  /* -- 34.3 Stockists: "Buy online" grid orphan --------------------------
     13 retailers in the 3-up tablet grid leave the last row one cell wide
     and two cells empty. The cells are outlined in dashes, so the two empty
     slots read as broken cells. §31.10b does this for the 2-up mobile grid;
     the 3n+2 arm covers a future 14th retailer. */
  .pl-dash-grid .pl-dash-cell:last-child:nth-child(3n+1) { grid-column: span 3; }
  .pl-dash-grid .pl-dash-cell:last-child:nth-child(3n+1) img { max-width: 27%; }
  .pl-dash-grid .pl-dash-cell:last-child:nth-child(3n+2) { grid-column: span 2; }
  .pl-dash-grid .pl-dash-cell:last-child:nth-child(3n+2) img { max-width: 40%; }

  /* -- 34.5 Contact: "Locations" type at tablet --------------------------
     Companion to the tablet column gap set in build-contact.php. Even at a
     40px gutter the columns come out ~208px at 1024 and ~180px at 768, where
     18px still breaks "Northlands Commercial Park". 16px is the size mobile
     already uses (§31.11).
     At 768 even 16px is 7px short: the column measures 211px and JHB's two
     long lines want 218px and 213px, so "Northlands Commercial Park" broke
     after "Commercial" and the column ran seven lines against Cape Town's
     five. 1.95vw resolves to 15px at 768 (204px / 200px, both fit) and hits
     the 16px ceiling from 821 up, so there is no visible step. Now set as the
     three address widgets' tablet typography (clamp(15px, 1.95vw, 16px) / 1.75). */
}

/* -- 34.4 Contact: the form card is unusable as a row below ~900px --------
   The card holds a 603px form beside a 647px photo. Those become proportions
   once the card narrows, so at 820 the form column measured 324px and the
   photo 331px, and at 768 it was 300px / 303px — a 300px form on a 768px
   screen, next to a 303x653 portrait sliver cropped out of a 1439x809
   landscape (a 3.5x aspect change; the dog's head left the frame at 768).
   Stack it the way it stacks below 767 and give the photo a banner crop.
   1024 keeps the row: 420px / 439px still reads as the design. */
@media (min-width: 768px) and (max-width: 900px) {
  .elementor .pl-contact-card { flex-wrap: wrap !important; }
  .elementor .pl-contact-card > .e-con.pl-form,
  .elementor .pl-contact-card > .elementor-widget-image.pl-contact-media {
    width: 100% !important;
    max-width: 100% !important;
    flex: 1 1 100% !important;
  }
  .elementor .pl-contact-card > .elementor-widget-image.pl-contact-media {
    align-self: auto !important;
  }
  /* §22.8 stretches the photo to the card height for the ROW layout in this
     range and floors it at 420px. Stacked, the floor is what decides the box,
     so it has to be released explicitly — a plain `height` loses to a
     min-height. Give it the source's own 16:9 instead of a px value, so the
     banner needs almost no crop at either 768 or 820 (photo is 1439x809 =
     1.779). */
  .elementor .pl-contact-media img {
    height: auto !important;
    min-height: 0 !important;
    aspect-ratio: 16 / 9;
  }
  /* the desktop card has no left padding because the photo bleeds right;
     stacked, that reads as an asymmetry, exactly as it did at mobile */
  .elementor .e-con.pl-contact-card { padding: 18px !important; }
  .elementor .pl-contact-card > .e-con.pl-form { padding: 20px 14px 0 !important; }
}

/* -- 34.6 Tap targets at touch widths ------------------------------------
   `(hover: none)` only — a 1024px desktop-pointer window keeps the Figma
   button box exactly. Font size, weight and radius are untouched, so the
   14px/500 r8 (outline r10) spec still holds; only the vertical padding
   grows to clear 40px. Measured before: hero-card buttons 124x36 and
   101x36, locator search button 55x33, store-card actions 128x35 and
   85x34. §28 already did this below 767 for the search button and the
   radius control, but never for the two store-card actions. All touch
   screens (2026-10-13: landscape iPads had 33px store actions). */
@media (hover: none) {
  .elementor .pl-overlap-47 .elementor-button,
  .elementor .pl-overlap-69 .elementor-button,
  .elementor .pl-near-band .elementor-button {
    padding-top: 12px !important;
    padding-bottom: 12px !important;
  }
  .pl-locator .asl-cont .sl-act-btns .btn-asl,
  .pl-locator .asl-cont a.s-direction,
  .pl-locator .sl-item .sl-act-btns .s-direction,
  .pl-locator .asl-cont a.pl-call-now,
  .pl-locator .sl-item .sl-act-btns .pl-call-now {
    padding-top: 13px !important;
    padding-bottom: 13px !important;
    min-height: 44px !important;
  }
}

/* -- 34.7 Stockists: the search row at tablet touch ----------------------
   The Find button grows to 44px above, but §18.6 wraps a 40px input in a
   42px `overflow: hidden` search group, so on its own the button was sliced
   top and bottom and read as breaking out of the field (verified in clipped
   shots of .Filter_section at 1024 and 768). §28 raises the group to 50 /
   input 48 / radius control 48 below 767, so this is only ever needed in the
   tablet range — held to `min-width: 768px` so §28's mobile row, which was
   signed off at 64px-wide Find and a 48px control, is left exactly as it is. */
@media (min-width: 768px) and (max-width: 1024px) and (hover: none) {
  .pl-locator .Filter_section .sl-search-group { height: 50px !important; }
  .pl-locator .asl-cont input.asl-search-address { height: 48px !important; }
  .pl-locator .asl-cont button.asl-search-event {
    height: 44px !important;
    min-height: 44px !important;
  }
  .pl-locator .asl-cont .sl-dropdown-cont,
  .pl-locator .asl-cont .sl-dropdown-cont .btn-group,
  .pl-locator .asl-cont .sl-dropdown-cont .btn-group > button,
  .pl-locator .asl-cont .sl-dropdown-cont .dropdown-toggle { height: 50px !important; }
}

/* ===== §35 GONATURAL ===== */
/* Moved 2026-09-30 (fix-be-gonatural) to assets/css/pl-gonatural.css, keyed to
   CSS classes instead of `.page-id-45 .elementor-element-<id>`: showcase pack
   sizing 769-1100 + focus ring (§3 there), "What you won't find" title colour
   (now the accordion's own title colours), lead <h1> (`gn-lead`), burger tap
   target (`gn-nav`). */

/* ===== §36 HEADER: PILL ON STICK ONLY =====
   The Figma page exports show the nav flush on the page cream at rest -- at y=50
   the only fills across all six pages are #FFF9F0 plus the logo/nav greys, with
   no distinct pill fill, radius or shadow. The rounded cream pill belongs to the
   stuck state, which a static export can't show; build-header.php therefore ships
   the bar unstyled and the pill is added here on Elementor's stuck class.

   Elementor Pro adds .elementor-sticky--effects to the sticky element once it
   detaches, so this is a pure state hook -- no JS of our own. */
header .elementor-sticky--effects .pl-nav {
  border-radius: 999px;
  box-shadow: 0 6px 24px rgba( 23, 52, 52, 0.06 );
  transition: border-radius .25s ease, box-shadow .25s ease;
}
/* Width is deliberately NOT changed on stick -- the bar keeps the same measure as
   the page sections in both states, so nothing shifts sideways under the user.
   Sticking only adds the radius and shadow. */
header .pl-nav {
  transition: border-radius .25s ease, box-shadow .25s ease;
}

/* ===== §37 CARD ART: PHANTOM FLEX SLOT =====
   `.pl-card-art` is `position:absolute`, but Elementor wraps it in a widget div
   that is NOT absolute. That wrapper stays in flow as a zero-height flex item,
   so the card's `row-gap` fires between it and the heading and pushes every
   following child down by exactly one gap.

   Measured on the home offer card: card padding-top 38, row-gap 20, art wrapper
   at y39 with height 0, heading at y59 -- against the design's 48px ink inset
   versus our 68px. Precisely the 20px gap.

   `display: contents` removes the wrapper's box entirely. The art keeps its
   absolute positioning and the same containing block (the card, which is
   positioned), so the artwork does not move -- only the phantom slot goes.
   No-op on cards whose gap is already 0, such as the CTA cards. */
.e-con:has(> * > .pl-card-art) > *:has(> .pl-card-art),
.pl-offer-card > .elementor-widget:has(.pl-card-art),
.pl-cta-card > .elementor-widget:has(.pl-card-art) {
  display: contents;
}

/* ===== §38 BRAND CARD -> DESTINATION =====
   EVERY card is a whole-card link. The four brands with designed pages go to
   their page; the other eight go straight out to the brand's own site in a new
   tab. It is a stretched overlay rather than wrapping the card in an <a>, so
   the arrow chip keeps its own accessible name and the card markup is
   unchanged.

   Keyed off the LINK, not `.has-page` — that class marks "has a page on this
   site", and scoping the hit area to it left the eight off-site cards lighting
   up on hover while only the 33px chip actually did anything. */
.pl-brand-card:has(> .pl-brand-card__link) { position: relative; }
.pl-brand-card__link {
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
}
/* The chip sits above the overlay and is the one that carries the accessible
   name (the overlay is tabindex="-1" aria-hidden, so a card is ONE tab stop,
   not two to the same URL). */
.pl-brand-card .pl-arrow-chip { position: relative; z-index: 3; }
.pl-brand-card:has(> .pl-brand-card__link):hover { cursor: pointer; }
.pl-brand-card .pl-arrow-chip:focus-visible {
  outline: 2px solid var(--pl-green-hover);
  outline-offset: 3px;
}

/* ===== §39 BRANDS MEGA DROPDOWN (3 columns) =====
   Twelve brands in one column would run past the fold, so the Brands panel is
   a 3x4 grid. Everything else about it is the dropdown the design already
   specifies — Figma 1:2071 (the Campaigns panel): white, radius 25, items at
   14px/500 in rgba(96,96,96,0.75) with a 34px left inset on a ~56px row. Those
   are reused verbatim so the two panels read as one component.

   Only the panel keyed by `.pl-mega` becomes a grid; Campaigns stays a plain
   single-column list.

   BUG FOUND LIVE (2026-08-18): the selector list here originally included
   `li.pl-mega.menu-item-has-children > ul.sub-menu` with NO `:hover` /
   `:focus-within` qualifier, so `display: grid !important` applied
   UNCONDITIONALLY — the panel sat permanently open at 296px, overlapping
   whatever hero image sat beneath it, on every page load, hover or not.
   Confirmed with the mouse at (10,10) and zero interaction
   (build/mega-always-on.js): `display: grid`, `height: 198`, on first paint.
   That is what read as "the menu is glitchy".

   Fix: only `display` needs to be conditional on hover/focus. Everything else
   below (grid columns, sizing, colour, position) is inert while the panel is
   `display:none`, so it is safe — and clearer — to declare unconditionally in
   its own rule, with `display` split into a separate, correctly-gated one.

   SPECIFICITY: §23.1 forces `display:block !important` on
   `...li.menu-item-has-children:hover > ul.sub-menu` — (0,5,2). A rule at
   (0,4,2) loses to it even with !important, so `display` is set at (0,6,2). */
.pl-nav .elementor-nav-menu--main li.pl-mega.menu-item-has-children > ul.sub-menu {
  grid-template-columns: repeat( 3, minmax( 0, 1fr ) );
  gap: 2px 6px;
  /* Wide enough that no brand name wraps — "Company of Animals" is the longest
     at 15ch. Capped against the viewport so the panel can never force a
     horizontal scrollbar on a narrow desktop window. */
  width: max-content;
  max-width: min( 640px, calc( 100vw - 40px ) );
  padding: 16px 12px;
  background: #FFFFFF;              /* 1:2071 bg-white, NOT the cream pill */
  border-radius: 25px;              /* 1:2071 rounded-[25px] */
  box-shadow: 0 12px 30px rgba( 23, 52, 52, 0.14 );
  /* Anchored to the parent's LEFT edge, not centred on it. The nav is
     left-aligned in the band (About us / Our Team / Stockists / Brands /
     Campaigns; the logo is centred separately), so Brands sits near x130 at
     1440 — centring a 640px panel on it put the left edge at -16 and pushed the
     first column off-screen. Opening rightward from there ends around x770,
     inside the viewport at every width down to the 1024 breakpoint below. */
  left: 0;
  transform: none;
  /* Elementor's own dropdown default sets `margin-top: 14px` on every
     `ul.sub-menu` — invisible on a normal in-flow dropdown, but this panel is
     `position:absolute`, so that margin becomes a genuine 14px DEAD ZONE
     between the trigger's bottom edge and the panel's top edge: nothing
     hoverable occupies it. Reproduced with a realistic diagonal mouse path
     toward the first link (build/mega-realistic-hover.js): the panel closed
     the instant the cursor crossed y=85 (one pixel past the trigger's own
     bottom edge at y=84) and a subsequent click failed outright — this is
     what read as "can't click a submenu item, it disappears". Zeroed here
     rather than bridged with a spacer element, since a bridge only covers
     whatever width it's given and this panel's width is itself dynamic
     (`max-content`, capped at 640px) — zero margin removes the dead zone
     unconditionally, for any panel width, with no separate element to keep in
     sync. Plain `margin-top:0` did NOT win here even though `left:0` in the
     same block did — some other rule targets margin-top specifically (not
     tracked down to its exact source; not worth the archaeology when
     `!important` is already the established pattern in this file for
     exactly this situation, e.g. the `display` rule right below). */
  margin-top: 0 !important;
}
.pl-nav .elementor-nav-menu--main li.pl-mega.menu-item-has-children:hover > ul.sub-menu,
.pl-nav .elementor-nav-menu--main li.pl-mega.menu-item-has-children:focus-within > ul.sub-menu {
  display: grid !important;
}
/* SmartMenus writes inline `width`/`min-width` onto the panel when it measures
   it, which would pin the grid to one column's worth. */
.pl-nav .elementor-nav-menu--main li.pl-mega > ul.sub-menu > li {
  width: auto;
  float: none;
}
.pl-nav .elementor-nav-menu--main li.pl-mega > ul.sub-menu a.elementor-sub-item {
  display: block;
  /* 34px is the design's inset on a 138px single-item panel; at three columns
     that much padding on each of six edges eats the measure, so the inset is
     16px and the row keeps the design's height. */
  padding: 12px 16px;
  border-radius: 14px;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.15;
  color: var(--pl-nav);   /* 1:2071's rgba(96,96,96,.75) is 3.6:1 on white; nearest grey at 4.5:1 (build/header-qa-v2.php) */
  white-space: nowrap;
}
.pl-nav .elementor-nav-menu--main li.pl-mega > ul.sub-menu a.elementor-sub-item:hover,
.pl-nav .elementor-nav-menu--main li.pl-mega > ul.sub-menu a.elementor-sub-item:focus-visible {
  background: var( --pl-forest, var(--pl-panel) );
  color: var( --pl-cream, var(--pl-cream) ) !important;
}
/* The CURRENT page's own row: Elementor's active-item setting paints the
   forest pill but supplies no text colour, so the base rgba(96,96,96) above
   sat unreadable on the dark fill. Same forest/cream pair as hover, and the
   same `!important` that pair already needed to beat Elementor's own item
   colour.
   `:not([href*="#"])` is load-bearing: WP compares menu URLs against the
   current page with the #fragment STRIPPED, so on /brands/ it stamps
   `current-menu-item` on every retargeted /brands/#brand-<slug> item — all
   ten external brands lit up as dark pills at once. A fragment link points
   at a section of a page, never "you are here", so it is excluded from the
   current-page treatment wholesale. The neutralizer below additionally
   unpaints any active styling Elementor's own anchor module applies
   (hover/focus excluded so interaction states stay live). */
.pl-nav .elementor-nav-menu--main li.pl-mega > ul.sub-menu li.current-menu-item > a.elementor-sub-item:not([href*="#"]) {
  background: var( --pl-forest, var(--pl-panel) );
  color: var( --pl-cream, var(--pl-cream) ) !important;
}
.pl-nav .elementor-nav-menu--main li.pl-mega > ul.sub-menu li:not(.current-menu-item) > a.elementor-sub-item.elementor-item-active:not(:hover):not(:focus-visible) {
  background: transparent !important;
  color: var(--pl-nav) !important;
}

/* No mobile override is needed here, and adding one would be dead code:
   `.elementor-nav-menu--main` is display:none at <=1024 (measured — visible at
   1025, hidden at 1024), where Elementor swaps in its own off-canvas menu built
   from a SEPARATE `.elementor-nav-menu--dropdown` container. Nothing in this
   block reaches that copy, and it already renders the twelve brands as a
   stacked list that fits at 1024 / 768 / 390.

   Desktop fit is verified rather than assumed (build/mega-narrow.js): the panel
   holds at 640px within [304..944] at 1440, 1280, 1200, 1100 and 1025 with no
   document overflow at any of them, because the nav band is fixed-width. */

/* ===== §40 HOME 2026-09 (Figma 29:8679) =====
   Data changes are in build/home-v2.php; these are the layout pieces Elementor
   settings can't express. */

/* "Explore our brands" now matches its siblings: title top-left + chip. Its
   photo needs a darkening ramp under the title (29:8699: black 76% → 0 over the
   top 199px) — ::before is already the card's rest/hover tint, so ::after. */
.elementor .e-con.pl-cta-card--photo::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -9px;
  height: 199px;
  z-index: 1;
  pointer-events: none;
  border-radius: inherit;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.76), rgba(0, 0, 0, 0));
}

/* Stats band: the soft dark glow behind "Global brands" (29:8770, 273x51
   #12262B blurred 50px at band x830 / y54) that lifts the label off the sky. */
.elementor .e-con.pl-stats-band::after {
  content: "";
  position: absolute;
  left: 65.24%;
  top: 54px;
  width: 273px;
  height: 51px;
  border-radius: 50%;
  background: #12262B;
  filter: blur(50px);
  pointer-events: none;
  z-index: 0;
}
.elementor .e-con.pl-stats-band .pl-stat-row { position: relative; z-index: 1; }
@media (max-width: 1024px) {
  .elementor .e-con.pl-stats-band::after { display: none; }
}

/* "As featured in:" (29:8783) — the heading sits in a gap cut into the top
   edge of an outlined 1248px box: a cream-backed heading pulled down over the
   border, 26.5px (half its line box). */
.elementor .pl-featured > .pl-featured-title {
  position: relative;
  z-index: 1;
  margin-bottom: -26.5px !important;   /* Elementor's widget spacing zeroes a plain margin-block-end */
  padding: 0 45px;
  background: var(--pl-cream);
}
.elementor .e-con.pl-featured-box {
  width: 100%;
  min-height: 204.89px;
  border: 1px solid rgba(23, 52, 52, 0.21);
  border-radius: 38px;
}
.elementor .pl-featured-logo a { display: block; transition: opacity 0.2s ease; }
.elementor .pl-featured-logo a:hover { opacity: 0.75; }
@media (max-width: 767px) {
  .elementor .pl-featured > .pl-featured-title { padding: 0 14px; margin-bottom: -19px !important; }
  .elementor .e-con.pl-featured-box { min-height: 0; gap: 22px 20px !important; border-radius: 26px; }
  /* 34vw keeps the two widest logos (The Citizen, Get It) side by side: a 2x2 grid, not a 2-1-1 stack. */
  .elementor .pl-featured-logo img { width: auto !important; max-width: 34vw; height: 40px !important; }
}

/* "Why partners choose us" row widths: see §44.1 (the 11px overhang of row 1's
   copy is now its own -11px margin, so the copy can shrink below 1330px). */

/* ===== §41 BRANDS 2026-09 (Figma 29:8938) ===== */
/* A text widget whose paragraph must not add a trailing margin (Brands intro,
   "Want to stock" line) — the design spaces these with the container gap. */
.elementor .pl-tight-p p:last-child { margin-bottom: 0; }
/* Directory columns: 18px (29:8952), was 19. */
.pl-brand-directory .pl-brand-grid { column-gap: 18px; }
/* "Buy online" (brand pages + Brands) lands on Stockists' retailer section —
   clear the fixed header rather than scrolling under it. Any section a link
   lands on (its CSS ID is the address's #part: #buy-online, or wherever
   Settings › Pack Leader › Store locator › "Skip link jumps to" points), not
   one fixed ID (editability round 2026-10-15). :where() keeps it at zero
   specificity, so a section's own scroll margin (brand cards, Go Natural
   anchors) still wins. Tablet and phone values: "C7/C8 Section links" below. */
:where(.pl-main :target) { scroll-margin-top: 130px; }
/* "Want to stock our brands?" (29:8977): Figma shows the square box PNG
   cropped low so the open flaps sit at the top of a 418x219 frame. */
/* Beats Elementor's own `.elementor-40 .elementor-element-<id> img` (0,3,1). */
.elementor .e-con .elementor-element.pl-stock-card__img img { object-position: 50% 88.8%; }
/* Glass "Buy online" on the Where-to-buy photo (29:8963). */
.pl-where-to-buy .pl-btn-glass .elementor-button {
  -webkit-backdrop-filter: blur(11.7px);
  backdrop-filter: blur(11.7px);
}
/* Directory rows (29:8952) are 436 or 396 tall — a short-copy row (Flexi /
   VIP Products / Chuckit!) keeps the 396 floor instead of shrinking to fit. */
@media (min-width: 1025px) {
  .pl-brand-directory .pl-brand-card { min-height: 396px; }
}

/* ===== §42 STOCKISTS 2026-09 (Figma 29:9235) ===== */
/* "Buy Online" strip (29:9324): one looping row of retailer logos on the page
   background, 56px apart, 90px row. Items carry their spacing as margin, not
   flex `gap`, so the -50% loop lands exactly on the copy — with `gap` the row
   jumps by half a gap every cycle. The clip box is 16px taller than the row
   each way because padded logos (Absolute Pets) overhang it. */
.pl-marquee.pl-marquee--logos {
  background: none;
  padding: 16px 0;
  margin: -16px 0;
}
.pl-marquee--logos .pl-marquee__track {
  height: 90px;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  animation-duration: 45s;
}
.pl-marquee--logos:hover .pl-marquee__track,
.pl-marquee--logos:focus-within .pl-marquee__track { animation-play-state: paused; }
/* Held still until pl-main.js has centred the first retailer and the strip is in view (plMarqueeStart() adds
   .is-moving): on a slow connection it waits rather than scrolling off before the script arrives. */
.pl-marquee--logos .pl-marquee__track:not(.is-moving) { animation-play-state: paused; }
.pl-logo-strip__item {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  margin: 0 56px 0 0;
  padding: 0;
}
.pl-logo-strip__item a { display: block; line-height: 0; border-radius: 8px; }
.pl-marquee--logos .pl-marquee__track img {
  height: var(--logo-h, 64px);
  width: auto;
  max-width: none;
  opacity: 1;
}
@media (max-width: 767px) {
  .pl-marquee--logos .pl-marquee__track { height: 64px; }
  .pl-marquee--logos .pl-marquee__track img { height: calc(var(--logo-h, 64px) * 0.7); }
  .pl-logo-strip__item { margin-right: 36px; }
}
/* No motion: show every logo once, wrapped and centred, instead of a frozen
   strip cut off at the viewport edge. */
@media (prefers-reduced-motion: reduce) {
  .pl-marquee--logos .pl-marquee__track {
    width: auto;
    height: auto;
    flex-wrap: wrap;
    justify-content: center;
    row-gap: 24px;
  }
  .pl-marquee--logos .is-clone { display: none; }
  .pl-logo-strip__item { margin: 0 28px; }
}
/* The strip stays edge to edge below 1024 too: its Elementor tablet/mobile Margin is 0
   (the page gutter is per-container now, so no opt-out is needed). */

/* ===== §43 QA FIXES 2026-09-30 — Team / Contact / Brands / site-wide ===== */

/* Buttons: Elementor gives button widgets the kit's "Accent (Eyebrow)"
   typography, which carries 2px tracking; no button in the design is tracked.
   (0,3,0) beats that default (0,2,0) and still loses to a letter-spacing set
   on the widget itself (0,4,0). */
.elementor .elementor-widget-button .elementor-button,
.elementor .elementor-widget-form .elementor-button { letter-spacing: 0; }

/* Touch: every content button is at least 44px tall on phones and on
   coarse-pointer tablets (desktop keeps the design's 33–37px). */
@media (max-width: 767px), (pointer: coarse) {
  [data-elementor-type="wp-page"] .elementor-widget-button .elementor-button,
  [data-elementor-type="wp-post"] .elementor-widget-button .elementor-button,
  [data-elementor-type="error-404"] .elementor-widget-button .elementor-button,
  .pl-form .elementor-field-type-submit button.elementor-button {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}

/* Contact — the privacy line is one line (Figma 29:8927) only where the form
   column is wide enough for it; between 1025 and 1439 it ran under the photo
   (to 1365 before the 2026-10-13 laptop spacing scale narrowed the column). */
@media (min-width: 1025px) and (max-width: 1439px) {
  .pl-form .elementor-field-group.elementor-field-type-submit.pl-form-actions {
    gap: 12px 32px;
    flex-wrap: wrap !important;
  }
  .pl-form .elementor-field-group.elementor-field-type-submit.pl-form-actions .pl-form-legal {
    flex: 1 1 190px !important;
  }
  .pl-form .pl-form-actions .pl-form-legal p { white-space: normal; }
}
/* Submit is 37px (29:8926); Elementor's small form button has a 40px floor.
   Touch keeps the 44px rule above. */
@media (min-width: 768px) and (pointer: fine) {
  .pl-form .elementor-field-type-submit button.elementor-button { min-height: 0; }
}
/* Textarea → Submit row is 19.5px (29:8918 → 29:8925); the form's row gap is 10. */
@media (min-width: 1025px) {
  .pl-form .elementor-field-group.elementor-field-type-submit.pl-form-actions { margin-top: 9.5px; }
}
/* Phone / email links: 44px hit area on mobile without moving the text. */
@media (max-width: 767px) {
  .pl-locations a[href^="tel:"],
  .pl-locations a[href^="mailto:"],
  .pl-contact-email a[href^="mailto:"] {
    display: inline-block;
    padding: 11px 0;
    margin: -11px 0;
    position: relative;   /* above the next line box, which otherwise took the lower 11px */
    z-index: 1;
  }
}

/* Our Team — "Join our pack": §17f sizes the photo by width (148.14%), which
   below ~1100 leaves it shorter than the 333px band. Cover it instead and keep
   the woman and dog in view, with the scrim fading out behind them. */
@media (min-width: 768px) and (max-width: 1100px) {
  .pl-join-band {
    background-size: cover !important;
    background-position: 30% 40% !important;
  }
  .pl-scrim-forest.pl-join-band::after {
    background: linear-gradient(90deg, rgb(23, 52, 52) 0%, rgba(23, 52, 52, 0.8) 55%, rgba(23, 52, 52, 0.2) 100%);
  }
}

/* Header, 1025–1199: the five nav items need 447px but the left zone (half of
   what the centred logo leaves) drops below that, so "Campaigns" wrapped to a
   second row. Tighten the items instead of wrapping. */
@media (min-width: 1025px) and (max-width: 1199px) {
  [data-elementor-type="header"] .elementor-nav-menu--main .elementor-item {
    padding-left: 7px !important;
    padding-right: 7px !important;
  }
}
@media (min-width: 1025px) and (max-width: 1149px) {
  [data-elementor-type="header"] .elementor-nav-menu--main .elementor-item {
    padding-left: 5px !important;
    padding-right: 5px !important;
    font-size: 13px !important;
  }
  /* keep daylight between "Campaigns" and the logo */
  [data-elementor-type="header"] .elementor-widget-image img { max-width: 124px; }
}

/* Headings: no lone word on a last line. `pretty` only re-breaks the last few
   lines — measured on all 11 pages it changes nothing at 1440 (Figma breaks
   kept) and clears the orphans at 1024/820/390. */
h1, h2, h3, h4,
.elementor-heading-title { text-wrap: pretty; }   /* h1–h4 too: brand cards and brand-page headings aren't heading widgets */
/* …except on the old-site pages rebuilt as they were (ACANA Podcast, ORIJEN K9 Unit, 2026-10-20): their text breaks
   where the old site's did. The class `pl-asis` is on those pages' sections (Advanced › CSS Classes). */
.pl-asis h1, .pl-asis h2, .pl-asis h3, .pl-asis h4, .pl-asis p,
.pl-asis .elementor-heading-title { text-wrap: wrap; }

/* Mega menu on /brands/: Elementor's scroll-spy gives every `/brands/#brand-*`
   item the active class as its card scrolls past (5 at once), painting the
   forest active fill under grey text (1.75:1). A fragment link is never "the
   current page" — only real brand pages keep the active state. */
[data-elementor-type="header"] .elementor-nav-menu--main .sub-menu a.elementor-item-active[href*="#"]:not(:hover):not(:focus-visible) {
  background-color: transparent !important;
}

/* Mobile menu scroll lock: <html> has overflow-x: clip, so body's
   overflow:hidden never reached the viewport and the page scrolled behind the
   sheet (touch, wheel and PageDown). pl-main.js mirrors the state onto <html>. */
html.pl-menu-open { overflow: hidden !important; }
nav.elementor-nav-menu--dropdown { overscroll-behavior: contain; }

/* Focus rings that are visible on their own background. */
@media (max-width: 1024px) {
  [data-elementor-type="header"] nav.elementor-nav-menu--dropdown a:focus-visible,
  [data-elementor-type="header"] .pl-menu-cta:focus-visible {
    outline: 2px solid var(--pl-forest) !important;
    outline-offset: 3px;
  }
}
[data-elementor-type="footer"] a:focus-visible,
[data-elementor-type="footer"] .pl-connect:focus-visible {
  outline: 2px solid var(--pl-cream) !important;
  outline-offset: 3px;
}
[data-elementor-type="header"] .pl-nav-cta .elementor-button:focus-visible,
[data-elementor-type="header"] .pl-nav-textlink .elementor-button:focus-visible {
  outline: 2px solid var(--pl-forest) !important;
  outline-offset: 3px;
}

/* Current page in the desktop nav: SemiBold as drawn on the boards
   (e.g. About board "About us", I29:8902;29:8821;29:9339). */
@media (min-width: 1025px) {
  [data-elementor-type="header"] .elementor-nav-menu--main > ul > li.current-menu-item > a:not([href*="#"]),
  [data-elementor-type="header"] .elementor-nav-menu--main > ul > li.current-menu-ancestor > a {
    font-weight: 600 !important;   /* the widget's own 500 is (0,5,0) */
  }
}

/* Footer without the "Connect" band (Contact, Figma 29:8928): the panel's own
   29px top padding only spaced the band — content starts 49px in, logo 58.9.
   The panel carries the class pl-footer-panel (inc/qa-sync-editability.php);
   its element ID stays as the fallback until that sync has run. */
body.pl-hide-connect [data-elementor-type="footer"] .pl-footer-panel,
body.pl-hide-connect [data-elementor-type="footer"] .elementor-element-9437374 { padding-top: 0 !important; }

/* Texture: Figma's own riso grain (riso_texture on 29:11270 / 29:8905 — an
   irregular halftone) replaces the regular 160px dot tile. pl-riso.webp is a
   seamless 512px tile cut from that asset. Strengths calibrated against the
   boards on text-free patches (luminance std, Figma → live):
     dark footer 6.7 → 6.2 · light Locations 8.2 → 8.6
   Browsers' soft-light barely marks light surfaces, so light panels multiply
   (as §31.5 found); dark panels keep Figma's soft-light (footer 28%). */
.pl-texture::after,
.pl-texture-soft::after {
  background-image: url('../img/pl-riso.webp') !important;
  background-size: 420px 420px !important;
}
.pl-texture::after {
  mix-blend-mode: soft-light !important;
  opacity: 0.3 !important;
}
.pl-texture--light.pl-texture::after,
.pl-cta-card--light.pl-texture::after,
.pl-texture.pl-near-band::after,
.pl-texture.pl-locations::after,
.pl-texture.pl-personal::after {
  mix-blend-mode: multiply !important;
  opacity: 0.18 !important;
}

/* ===== §44 HOME + ABOUT QA FIXES 2026-09-30 =====
   Home (Figma 29:8679) and About us (29:8832). Element data lives in
   build/home-v2.php and build/about-v2.php ("QA 2026-09-30" blocks); these
   are the parts Elementor can't express. */

/* -- 44.1 Home "Why partners choose us" (29:8700) ---------------------------
   The row frame is 1244px on the board, but its panel is 1273 at 1440 and 858
   at 1025: capped at the panel it can't run off the page. Heads are 50.075%
   of the row (build script) and hold; the copy shrinks into what is left, so
   every row's copy still starts at the same x. Row 1 hugs its three lines
   (29:8701 has no fixed height: 72 + 12 = 84); rows 2-4 keep §20's 90. */
@media (min-width: 1025px) {
  .elementor .e-con.pl-why-list { max-width: 100%; }
  .elementor .e-con.pl-why-row > .e-con.pl-why-head { flex-shrink: 0; }
  .elementor .e-con.pl-why-row > .elementor-widget-text-editor { flex-shrink: 1; min-width: 0; }
}
.elementor .e-con.pl-why-row:first-child { min-height: 0; }

/* -- 44.2 Home "What we offer" card 2 art (29:8688) -------------------------
   The inline geometry is the 1440 frame: an 815.6 x 810 photo hung 149.7px
   left of and 128.6px below the card. Sized in % of the card and cover-fit,
   it grew with wider cards (the products rose into the title from 1536) and
   stayed full size in narrower ones while the title wrapped to 5-6 lines
   (1025-1293). Pin it to the card's bottom centre and scale it with the card
   instead — never below 81%, the size that still covers the card's top edge.
   Identical at 1440. Touch screens put the art in flow (§26.2 / §33.1 — on
   landscape iPads too since 2026-10-13), so they are left alone: this rule
   had pushed card 2's photo out of its stacked card at 1180 / 1366 touch. */
@media (min-width: 768px) and (hover: hover) {
  .elementor .pl-offer-card + .pl-offer-card .pl-card-art {
    left: 50% !important;
    top: auto !important;
    bottom: 0 !important;
    width: max(659.5px, min(815.6px, 134.59%)) !important;
    height: auto !important;
    object-fit: fill !important;
    transform: translate(-55.5%, 15.88%);
  }
}
/* 1025-1069: at 36px the title needs six lines of a 313px column; 34px keeps
   it to five, clear of the products. Both cards, so the pair still match. */
@media (min-width: 1025px) and (max-width: 1069px) {
  .elementor .pl-offer-card h3.elementor-heading-title { font-size: 34px !important; }
}

/* -- 44.3 Home "Delivered nationwide" CTA cards (29:8695) -------------------
   Chip glyph: Figma's 22 x 15 arrow at its own size (§20 blew the old square
   glyph up to 25 x 25). The Partner chip is #FFF9F0 like its siblings
   (29:8629) — hover still clears it (§2). */
.elementor .pl-cta-card .pl-arrow-chip svg { width: 22px; height: 15px; }
.pl-cta-card--light .pl-arrow-chip--white { background-color: var(--pl-cream); }
/* 1025-1309: 37px titles in 254-350px cards broke one word per line
   ("Become / a / stockist"). Use the tablet card's side padding (§33.4) and a
   10px chip gap, let the title take the rest of the row, and scale it with
   the card (37px again from 1300) — two lines throughout. */
@media (min-width: 1025px) and (max-width: 1309px) {
  .elementor .e-con.pl-cta-card { padding-left: 24px !important; padding-right: 22px !important; }
  .elementor .e-con.pl-cta-card .e-con.pl-card-top { gap: 10px !important; }
  .elementor .pl-cta-card .pl-card-top > .elementor-widget-heading {
    width: auto !important;
    max-width: none !important;
    flex: 1 1 0;
    min-width: 0;
  }
}
/* Partner paws: the build script locks the art box to the 1440 frame's
   proportions; §26.4's phone `contain` would letterbox the stretched PNG
   inside it, so phones fill the box too. */
@media (max-width: 767px) {
  .elementor .pl-cta-card--light .pl-card-art { object-fit: fill !important; }
}

/* -- 44.4 Home stats band (29:8769) -----------------------------------------
   The board scales as one piece; from 1025 to 1439 the photo scaled (§20) but
   the 90px numerals and 22px labels did not, so "2010" ran onto the dog's
   ear and "9 / provinces" split over two 113px lines. Scale the type with
   the viewport (90 / 22 at 1440) and keep each stat on one line. */
@media (min-width: 1025px) and (max-width: 1439px) {
  .elementor .pl-stats-band .pl-stat-value-w .elementor-heading-title,
  .elementor .pl-stats-band .pl-stat-label .elementor-heading-title { white-space: nowrap; }
}
/* Phones: the four stats sit on the dog's pale fur. A soft forest pool behind
   each stat (fading to nothing at the cell edge, so no box shows) and a
   tighter label shadow lift the lightest patches under the text from 2.7:1 to
   3.1-3.5:1 (labels) and 4.4 to 5-5.5:1 (numerals) without dimming the whole
   photo. Labels (14px) stay on one line — at 360 "Distribution across all"
   is 2px wider than its cell and would strand "all" — and values sit at the
   foot of each cell so a row's two numbers always share a baseline. */
@media (max-width: 767px) {
  .elementor .pl-stats-band .e-con.pl-stat-row { align-items: stretch !important; }
  .elementor .pl-stats-band .e-con.pl-stat-cell {
    justify-content: space-between;
    background: radial-gradient(closest-side, rgba(23, 52, 52, 0.6) 35%, rgba(23, 52, 52, 0));
  }
  .elementor .pl-stats-band .pl-stat-label .elementor-heading-title {
    white-space: nowrap;
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.55);
  }
}

/* -- 44.5 Home "As featured in" (29:8783) -----------------------------------
   One row needs 969px (fits from ~1210); below that the logos wrapped 3 + 1
   with "Get It" alone. A 640px row box pairs them 2 + 2. */
@media (min-width: 768px) and (max-width: 1219px) {
  .elementor .e-con.pl-featured-box {
    padding-left: max(24px, calc(50% - 320px)) !important;
    padding-right: max(24px, calc(50% - 320px)) !important;
    /* two rows: clear the heading notch as the phone box does (§40) */
    padding-top: 48px !important;
    padding-bottom: 36px !important;
    row-gap: 36px !important;
  }
}

/* -- 44.6 About "What we do" band (29:8853) ---------------------------------
   §17c/§31.4 frame the photo by width (103.24% at 12% 14% — the board's
   crop), which only covers the 475px band from 1306px up: below that it left
   a tan strip (8px at 1280, a third of the band at 768). Cover there instead,
   and on the tall tablet/phone bands slide the crop onto the dog (§17g's 62%
   was being overridden by §31.4 at every width, leaving wall and door). */
@media (max-width: 1305px) {
  .elementor .e-con.pl-ww-band { background-size: cover !important; }
}
@media (max-width: 1024px) {
  .elementor .e-con.pl-ww-band { background-position: 40% center !important; }
}
@media (max-width: 767px) {
  .elementor .e-con.pl-ww-band { background-position: 66% center !important; }
}
/* Desktop scrim: the board's 20% black (29:8854) and its stone ramp fading out
   by 70.2% (29:8856), but the ramp holds a deeper stone behind the text column.
   The board's exact ramp gives the 21px/500 paragraph 3.2:1 (fails WCAG AA);
   this measures 5.3:1 median, 4.9:1 at the lightest tenth (build/qa-contrast-band.js).
   Exact-Figma alternative: rgb(136,133,128) 0% -> transparent 70.2%.
   Tablet/phone keep §21.3's deeper full-width scrims. */
@media (min-width: 1025px) {
  .elementor .e-con.pl-ww-band::before { background: rgba(0, 0, 0, 0.2); }
  .elementor .pl-scrim-stone.pl-ww-band::after {
    background: linear-gradient(90deg, rgb(100, 98, 94) 0%, rgba(100, 98, 94, 0.8) 48%, rgba(136, 133, 128, 0) 70.2%);
  }
}

/* -- 44.7 About Go Natural band (29:8894) -----------------------------------
   The collage hangs at 47.448% of the band — x650 at 1440, 122px clear of the
   528px copy — but that is x489 at 1100, where the kale touched "that".
   Never nearer than 596px (68px clear). */
@media (min-width: 1025px) {
  .elementor .pl-gn-band .pl-gn-ingredients { left: max(47.448%, 596px); }
}

/* ===== §46 HOME / ABOUT / TEAM QA 2026-10-08 =====
   Pre-launch QA, qa/e2e/FINDINGS.md § A (owner fix-home-about-team). Wide
   screens keep the 1440 composition as the reference; rules above 1440 start
   at 1441 so 1440 and below are untouched unless a block says otherwise.
   Element data changes: inc/qa-sync-home.php (pl_qa_sync_home). */

/* -- 46.1 Home "What we offer" photos above 1440 (A2, A3) -------------------
   The cards widen with the panel (848 at 1920, 1168 at 2560) but stay 553
   tall. Card 2's 815.6px photo (§44.2) stopped short of the card: hard seams
   61px in at 1920, 131 + 221px at 2560. Card 1's cover-fit photo grew with
   the width and cut off the pack bottoms and the Weruva can (72% of its
   height left at 1920, 52% at 2560). Both photos keep their 1440 size and
   place; the card behind each continues the photo's own backdrop (the file's
   left/right edge colours) and the photo's sides fade into it over 40px, so a
   wider card reads as one backdrop. */
@media (min-width: 1441px) {
  .elementor .e-con.pl-offer-card:first-child {
    background-image: linear-gradient(90deg, rgb(213, 190, 172) calc(50% - 264px), rgb(234, 212, 192) calc(50% + 264px));
  }
  .elementor .pl-offer-card:first-child .pl-card-art {
    object-fit: contain !important;   /* 607 x 571 as at 1440, centred */
    -webkit-mask-image: linear-gradient(90deg, transparent calc(50% - 303.7px), #000 calc(50% - 263.7px), #000 calc(50% + 263.7px), transparent calc(50% + 303.7px));
    mask-image: linear-gradient(90deg, transparent calc(50% - 303.7px), #000 calc(50% - 263.7px), #000 calc(50% + 263.7px), transparent calc(50% + 303.7px));
  }
  /* §44.2 hangs the 815.6px photo from 50% - 452.66px to 50% + 362.94px. */
  .elementor .e-con.pl-offer-card + .pl-offer-card {
    background-image: linear-gradient(90deg, rgb(207, 206, 184) calc(50% - 412.66px), rgb(231, 231, 215) calc(50% + 322.94px));
  }
  .elementor .pl-offer-card + .pl-offer-card .pl-card-art {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 40px, #000 calc(100% - 40px), transparent);
    mask-image: linear-gradient(90deg, transparent, #000 40px, #000 calc(100% - 40px), transparent);
  }
}

/* -- 46.2 Home "Partner with us" paws above 1440 (A3) -----------------------
   The paws artwork spans the card's width (both cats' legs run off its
   edges), so it grows with the card while the card stays 335 tall: from 42.85%
   down only 45% of it showed at 1600, 36% at 1920, 26% at 2560 and the paws
   slid out of the bottom. Pin the paws' meeting point (22% down the artwork)
   where it is at 1440 instead — 224.9px from the card top (142.7 + 22% of the
   373.8px artwork) — so the art rises as it grows: 48% / 43% / 37% visible,
   the right leg's top 12-50px clear of the title. */
@media (min-width: 1441px) {
  .elementor .pl-cta-card--light .pl-card-art {
    top: 224.9px !important;
    transform: translateY(-22%);
  }
}

/* -- 46.3 Home "Why partners choose us" paws on tablets (A4) ----------------
   768-1024: the paw icon is a flex item beside its title, so the long titles
   (rows 1 and 3) squeezed it to 25-31px while rows 2 and 4 kept 35, and the
   titles started at x 83 / 87 / 93. The icon keeps its 35px; the title wraps. */
@media (min-width: 768px) and (max-width: 1024px) {
  .elementor .e-con.pl-why-head > .elementor-widget-icon { flex-shrink: 0; }
  .elementor .e-con.pl-why-head > .elementor-widget-heading { min-width: 0; }
}

/* -- 46.4 Home "Explore our brands" chip hover (A7) -------------------------
   The Partner and Stockist chips turn into an outline on hover; the photo
   card's stayed a cream tile. Same as the dark card (its hover tint is the
   forest one): outlined cream. */
.pl-cta-card--photo:hover .pl-arrow-chip {
  background-color: transparent !important;
  border: 1px solid var(--pl-cream) !important;
  color: var(--pl-cream) !important;
}

/* -- 46.5 About "How it started" / Team intro card above 1440 (A8) ----------
   The two equal columns widen with the card. The copy re-flowed into 822 /
   1142px lines, so the card got shorter (337 → 285 → 259) and the photo, which
   takes the card's height, became a strip (46% / 29% of the Salvador frame
   at 1920 / 2560; the Team group photo the same). Above 1440 the copy keeps
   its 1440 measure (581.5px — same line breaks) and the photo keeps its 1440
   frame (582.5 x 263 / 582.5 x 306), so it grows in proportion and sets the
   card's height; the copy stays vertically centred beside it. */
@media (min-width: 1441px) {
  .elementor .e-con.pl-fcard > .e-con-inner > .e-con > * { max-width: 581.5px; }
  .elementor .e-con.pl-fcard--stretch > .e-con-inner > .elementor-widget-image { aspect-ratio: 582.5 / 263; }
  .elementor .e-con.pl-fcard.pl-team-intro .elementor-widget-image {
    height: auto;
    aspect-ratio: 582.5 / 306;
  }
}

/* -- 46.6 About philosophy columns above 1440 (A9) --------------------------
   Columns 1 and 2 hold their statements at 319 / 326px (Elementor widths);
   column 3 had none and ran the full column (583px at 1920). It keeps its
   1440 width (344px) like the other two. */
@media (min-width: 1441px) {
  .elementor .e-con.pl-phil-col:last-child > .elementor-widget-heading { max-width: 344px; }
}

/* -- 46.7 Team "Join our pack" on tablets (A12) -----------------------------
   768-1100 (§43): the copy's line ends ran over the woman's fair hair, where
   §43's scrim had already faded to ~0.6 — 3.1-4.1:1 at the lightest tenth of
   the line ends (900 / 820). Hold the scrim deeper for longer (0.88 at 62%,
   0.62 at 84%): every 60px stretch of copy now ≥ 4.5:1 at 768-1100, and the
   woman and dog still show on the right. */
@media (min-width: 768px) and (max-width: 1100px) {
  .pl-scrim-forest.pl-join-band::after {
    background: linear-gradient(90deg, rgb(23, 52, 52) 0%, rgba(23, 52, 52, 0.88) 62%, rgba(23, 52, 52, 0.62) 84%, rgba(23, 52, 52, 0.25) 100%);
  }
}

/* -- 46.8 Home stats labels on phones (A12) ---------------------------------
   §44.4's pool sits behind the whole cell, so the 14px labels at the top of
   the lower cells were still on the dog's pale fur ("Distribution across
   all", "Established in" and "Employees" 2.8-3.6:1 at the lightest tenth of
   a 60px stretch at 360). Each label gets its own small pool: every stretch
   ≥ 4.5:1 at 390 and 360. The padding is cancelled by the margin, so nothing
   moves. */
@media (max-width: 767px) {
  .elementor .pl-stats-band .pl-stat-label .elementor-heading-title {
    background: radial-gradient(closest-side, rgba(23, 52, 52, 0.8) 45%, rgba(23, 52, 52, 0));
    padding: 6px 14px;
    margin: -6px -14px;
  }
}

/* -- 46.9 Home "Explore our brands" on touch screens (A12) ------------------
   §26.4 / §33 deepened the photo card's resting scrim to forest 0.48 for the
   title's contrast before §40 added the title's own 76% → 0 ramp; with both,
   the dog almost disappeared on phones. Back to the desktop resting scrim
   (black 0.2): the ramp alone keeps the title ≥ 6.8:1 (lightest tenth, 360). */
@media (max-width: 767px), (min-width: 768px) and (max-width: 1024px) and (hover: none) {
  .elementor .e-con.pl-cta-card--photo.pl-cta-card--photo::before {
    background-color: rgba(0, 0, 0, 0.2) !important;
  }
}

/* Wider than the 1440 design (2026-10, client decision): use the whole screen. Panels are sized by
   side margins, so they run to the page gutters at any width; the boxed content inside them keeps the
   1370 measure (Elementor's container width), and so do the brand pages' card grids (pl-brand.css).
   Until 2026-10 the page, footer and nav were capped at 1440/1370 and centred, which left 240px+ of
   empty margin on 1920 screens. */
@media (min-width: 1441px) {
  /* Boxed content grows with its panel too (client, 2026-10-08: sections were "not expanding"): the kit's
     Content Width (1370, Site Settings › Layout) becomes the screen minus the page gutters — exactly what
     it is at 1440, where every panel is ≤1370. The kit CSS sets it on every container (`.e-con { --container-max-width: 1370px }`). */
  body .e-con { --container-max-width: calc(100vw - 70px); }
  /* Home "Why partners choose us": the list is 1244px in Elementor (the board's 1244 of a 1273 panel) —
     wider screens keep that proportion instead of stopping at 1244 (§44.1). */
  body .elementor .e-con.pl-why-list { --width: calc(100% * 1244 / 1273); }
}

/* The 404 template (theme-builder type error-404) sizes its panel by side
   margins like a page; same top-level rule, same 1440 cap. */
[data-elementor-type="error-404"] > .e-con,
[data-elementor-type="error-404"] > :where(.elementor-section-wrap) > .e-con { width: auto !important; max-width: none !important; }
/* Large light panels (Contact hero 29:8904, the 404): Figma's grain is softer
   there — std 6.4 on the board vs 8.7 at 0.18 multiply. */
.pl-texture--light.pl-texture::after { opacity: 0.12 !important; }

/* ===== §45 GONATURAL QA FIXES 2026-09-30 ===== */
/* Moved 2026-09-30 (fix-be-gonatural) to assets/css/pl-gonatural.css §4, keyed
   to CSS classes (`gn-nav`, `gn-hero-carousel`, `gn-logo-link`, `gn-nowrap`,
   `gn-header`) instead of page-45 element ids. */

/* Escape on a desktop dropdown (pl-main.js): the panel stays closed while
   focus is still on its parent item. */
/* (0,7,3): above the :focus-within openers, the strongest being §45's (0,6,2) */
body .elementor-nav-menu--main li.menu-item-has-children.pl-sub-dismissed.pl-sub-dismissed.pl-sub-dismissed > ul.sub-menu.sub-menu { display: none !important; }

/* Header logo link: 44px tap height on tablets/phones without moving the logo. */
@media (max-width: 1024px) {
  [data-elementor-type="header"] .elementor-widget-image a {
    display: inline-block;
    padding: 8px 0;
    margin: -8px 0;
  }
}
/* "Contact us" on /contact/ (pl-main.js marks it): same current state as the menu. */
@media (min-width: 1025px) {
  [data-elementor-type="header"] .pl-nav-textlink a.is-current { color: var(--pl-forest) !important; font-weight: 600 !important; }
}

/* "Want to stock our brands?" card, 1025–1279: the 418px box image kept its
   width while the card narrowed, squeezing the heading to 5 lines at 1025.
   Let the image take a share of the card instead, keeping Figma's 418:219. */
@media (min-width: 1025px) and (max-width: 1279px) {
  .elementor .e-con.pl-stock-card > .elementor-widget.pl-stock-card__img {
    width: 36% !important;
    flex: 0 0 36% !important;
  }
  .elementor .e-con.pl-stock-card .pl-stock-card__img img {
    width: 100%;
    height: auto !important;
    aspect-ratio: 418 / 219;
  }
  .elementor .e-con.pl-stock-card > .e-con { flex: 1 1 0 !important; width: auto !important; min-width: 0; }
}

/* Editor only: card artwork ignores the pointer on the site (so the card stays
   clickable), which also made it unselectable in Elementor — let it take clicks there. */
.elementor-editor-active .pl-card-art { pointer-events: auto; }

/* ===== QA 2026-10-08 §C — HEADER / FOOTER / BURGER SHEET =====
   Owner: fix-chrome. Element data (header spacing, logo centring, footer
   rel=noopener, the 404's <main>) is in inc/qa-sync-chrome.php; these are the
   pieces Elementor can't express. */

/* -- C2 Header, 1025-1149: the nav links drop to 13px here (§43) but
   "Contact us" — set exactly like them (§12) — stayed 14px. Its button
   widget's 24px line box then sat the 13px link 1.5px low, so the link is
   centred in its zone instead (no change at 14px). "Partner Log In" is a
   button and keeps 14px. */
@media (min-width: 1025px) {
  [data-elementor-type="header"] .pl-nav .elementor-widget-button.pl-nav-textlink {
    display: flex;
    align-items: center;
  }
}
@media (min-width: 1025px) and (max-width: 1149px) {
  [data-elementor-type="header"] .pl-nav .pl-nav-textlink .elementor-button { font-size: 13px !important; }
}

/* -- C5 Footer, 1025-1439: "POPIA Compliance" wrapped below ~1325px, so its
   links sat 20px lower than the other columns'. Column headings stay on one
   line and a link column is never narrower than its content; to pay for it
   the column gap eases from the design's 63px (1325 and up) to 40px at 1025,
   so the logo column keeps its width. No change from 1325. */
@media (min-width: 1025px) and (max-width: 1439px) {
  [data-elementor-type="footer"] .e-con:has(> .e-con > .elementor-widget-icon-list) {
    column-gap: clamp(40px, calc(7.667vw - 38.6px), 63px) !important;
  }
  [data-elementor-type="footer"] .e-con:has(> .e-con > .elementor-widget-icon-list) > .e-con:has(> .elementor-widget-icon-list) {
    min-width: max-content;
  }
  [data-elementor-type="footer"] .e-con:has(> .e-con > .elementor-widget-icon-list) > .e-con:has(> .elementor-widget-icon-list) .elementor-heading-title {
    white-space: nowrap;
  }
}

/* -- C4 Burger sheet (<=1024): the LIST scrolls, not the sheet. On short
   screens (375x667, 360x640, phones in landscape) the whole sheet scrolled
   and its rows slid up under the transparent bar — the current-page pill
   over the logo and the close button. The list now scrolls below the bar,
   and the two buttons stay pinned at the foot (at 667px tall they started
   off-screen). The list's 6px padding keeps focus rings inside its clip. */
@media (max-width: 1024px) {
  [data-elementor-type="header"] .pl-nav nav.elementor-nav-menu--dropdown[aria-hidden="false"] {
    overflow: hidden !important;
  }
  [data-elementor-type="header"] .pl-nav nav.elementor-nav-menu--dropdown[aria-hidden="false"] > ul {
    flex: 0 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    margin: -6px -12px 0 !important;
    padding: 6px 12px !important;
  }
  [data-elementor-type="header"] .pl-nav nav.elementor-nav-menu--dropdown[aria-hidden="false"] .pl-menu-ctas {
    flex: 0 0 auto;
  }
  /* Brand and campaign chips: 44px tap targets like every other touch
     control on the site (were 40). (C6) */
  [data-elementor-type="header"] .pl-nav .elementor-nav-menu--dropdown a.elementor-sub-item {
    min-height: 44px;
  }
}

/* -- C7/C8 Section links land 10px under the fixed header: 130px on desktop
   (header 120), but tablets (header 88) and phones (68) used the same 130 and
   left a 42-62px gap above /stockists/#buy-online and the /brands/ cards.
   pl-main.js keeps a fresh-load landing there while the page above it is
   still growing (the store locator).
   "Skip to content" (#content, the page's <main>) lands right under the
   header instead of scrolling the top of the page beneath it. */
#content { scroll-margin-top: 120px; }
@media (max-width: 1024px) {
  :where(.pl-main :target),
  .pl-brand-card { scroll-margin-top: 98px; }
  #content { scroll-margin-top: 88px; }
}
@media (max-width: 767px) {
  :where(.pl-main :target),
  .pl-brand-card { scroll-margin-top: 78px; }
  #content { scroll-margin-top: 68px; }
}

/* ===== QA 2026-10-08 §B — CONTACT / BRANDS / 404 =====
   Pre-launch QA, qa/e2e/FINDINGS.md §B (fix-contact-brands-404). Element
   settings (Contact card height and colours, 404 margins, per-breakpoint hero
   images) are data — inc/qa-sync-contact.php, pl_qa_sync_contact(). These are
   the wide-screen parts Elementor can't express; ≤1440 is untouched. */

/* -- B1 Contact hero card above 1440 (Figma 29:8907) ----------------------
   The card grows with the page (wide-screen decision) but the form (603px)
   and the photo (647px) kept their 1440 widths, pinned left: an empty block
   of 182px at 1600, 502 at 1920, 1142 at 2560. Both keep their 1440 share of
   the card instead (603 : 647 around the fixed 50px gap), so the photo ends
   at the card's 19px inset at every width. The photo is 16:9, so the wider
   frame shows more of it (cover, §31 window 93% 50%). The privacy line stays
   on the right edge of the fields, as at 1440 (29:8927). From 1025 up
   (2026-10-13): the same shares keep the form column in proportion on laptops
   (1440 itself keeps Elementor's own 603 / 647px widths). */
@media (min-width: 1025px) and (max-width: 1439px), (min-width: 1441px) {
  .elementor .e-con.pl-contact-card > .e-con.pl-form {
    flex: 603 1 603px !important;
    width: auto !important;
    max-width: none !important;
  }
  .elementor .e-con.pl-contact-card > .elementor-widget-image.pl-contact-media {
    flex: 647 1 647px !important;
    width: auto !important;
    max-width: none !important;
    position: relative;
  }
  /* The form sets the card's height, never the photo: at 2560 its own 16:9
     height (691px) would have pushed the card from 632 to 727. */
  .elementor .pl-contact-card > .pl-contact-media img { position: absolute; inset: 0; }
  .pl-form .elementor-field-group.elementor-field-type-submit.pl-form-actions { justify-content: space-between; }
}

/* -- B5 Brands grid card images above 1440 (29:8938, 379x191) -------------
   §18.3 fixes the frame at 191px, so wider cards turned it into a letterbox
   (539x191 at 1920, 753x191 at 2560) and the crop cut pack names and logos.
   Keep the 1440 frame's proportion instead — from 1025 up (2026-10-13: on
   laptops the fixed 191px made the crop squarer; 379 wide at 1440 = 191). */
@media (min-width: 1025px) {
  .elementor .pl-brand-directory .pl-brand-card .pl-brand-card__img img,
  .pl-brand-directory .pl-brand-card .pl-brand-card__img img {
    height: auto;
    aspect-ratio: 379 / 191;
  }
}

/* -- B6 Brands intro paragraph above 1440 ---------------------------------
   The intro card grows with the page; its paragraph ran as one 149-character
   line (1673px) at 1920. It keeps its 1440 measure (1193px: 127 + 22
   characters, as on the board). (0,6,0): Elementor's `.e-con.e-con >
   .e-con-inner > .elementor-widget { max-width: 100% }` is (0,4,0) and later. */
@media (min-width: 1441px) {
  .elementor .e-con.pl-overlap-47 > .e-con-inner > .elementor-widget.elementor-widget-text-editor { max-width: 1193px; }
}

/* -- B9 Photo bands above 1440: keep the subject in frame -----------------
   Brands hero e63d006, Stockists hero 7785145, About "What we do" bed928c and
   Team "Join our pack" 32a1809 (CSS classes pl-wide-brands-hero,
   pl-wide-stockists-hero, pl-wide-about-band, pl-wide-team-band, added by
   inc/qa-sync-editability.php; each rule keeps the element ID as the fallback
   until that sync has run) size their photo as a % of the band's WIDTH
   inside a fixed HEIGHT, so every extra pixel of width zoomed the photo and
   the window showed a thinner strip of it. At 2560 that was 35% / 24% / 50% /
   42% of the photo's height (1440: 64% / 45% / 90% / 77%): the setter cut at
   the eyes, the swimmer's crown gone, the bowl gone, the woman's hair and
   both figures cut at the waist.
   1. Each band keeps its 1440 proportion (its height grows with 100vw - 70px,
      the band's width), so the crop is the 1440 one at any width up to the
      cap. (Not `aspect-ratio`: it hands min/max-height on to the width — the
      380px floor would force a 1370px band, wider than a 1441px window with
      a scrollbar. A scrollbar inside 100vw adds at most ~5px of height.)
   2. Cap: 1.5x the 1440 height, reached at ~2125px: 570 / 480 / 713 / 500px.
      On a 2560x1440 screen that is 40 / 33 / 49 / 35% of its height, under
      the design's own 42 / 36 / 53 / 37% of a 1440x900 one; growing on with
      the width would make the bands 690 / 582 / 863 / 605 there.
   3. Past the cap the photo still zooms, so its window is pinned at its 1440
      top edge (the heads) and only floor / grass / water goes at the bottom:
      calc(s% - s x cap) keeps the window's top at s of the photo's height for
      any photo size (s = 7.572 / 25.946 / 1.378 / 8.312%, the 1440 values).
   4. Brands / Stockists headline: Elementor puts it 95px down; in a taller
      hero it would ride up onto the dog's face. It is centred instead, with
      the bottom padding that leaves it exactly where it is at 1440 (123 / 144
      = 380 / 320 - 95 - its 162 / 81px height). About / Team copy is already
      centred (Elementor justify: center).
   ≤1440 untouched. */
@media (min-width: 1441px) {
  /* Elementor's Min Height (--min-height) of each band, grown with the width;
     (0,4,1) over Elementor's own (0,3,0) element rule */
  body .elementor .e-con.pl-hero-h1.pl-wide-brands-hero,
  body .elementor .e-con.pl-hero-h1.elementor-element-e63d006 {
    --min-height: clamp(380px, calc((100vw - 70px) * 380 / 1370), 570px);
    --justify-content: center;
    --padding-bottom: 123px;
  }
  body .elementor .e-con.pl-hero-h1.pl-wide-stockists-hero,
  body .elementor .e-con.pl-hero-h1.elementor-element-7785145 {
    --min-height: clamp(320px, calc((100vw - 70px) * 320 / 1370), 480px);
    --justify-content: center;
    --padding-bottom: 144px;
  }
  body .elementor .e-con.pl-ww-band.pl-wide-about-band,
  body .elementor .e-con.pl-ww-band.elementor-element-bed928c { --min-height: clamp(475px, calc((100vw - 70px) * 475 / 1370), 712.5px); }
  body .elementor .e-con.pl-join-band.pl-wide-team-band,
  body .elementor .e-con.pl-join-band.elementor-element-32a1809 { --min-height: clamp(333px, calc((100vw - 70px) * 333 / 1370), 499.5px); }
}
@media (min-width: 2126px) {
  .elementor .e-con.pl-hero-h1.pl-wide-brands-hero,
  .elementor .e-con.pl-hero-h1.elementor-element-e63d006 { background-position-y: calc(7.572% - 43.16px) !important; }
  .elementor .e-con.pl-hero-h1.pl-wide-stockists-hero,
  .elementor .e-con.pl-hero-h1.elementor-element-7785145 { background-position-y: calc(25.946% - 124.54px) !important; }
  .elementor .e-con.pl-ww-band.pl-wide-about-band,
  .elementor .e-con.pl-ww-band.elementor-element-bed928c { background-position-y: calc(1.378% - 9.82px) !important; }
  .elementor .e-con.pl-join-band.pl-wide-team-band,
  .elementor .e-con.pl-join-band.elementor-element-32a1809 { background-position-y: calc(8.312% - 41.52px) !important; }
}

/* "Cookie settings" beside the footer copyright (inc/analytics.php): only where the cookie banner runs (the live
   site), so staging and local don't show a link that has nothing to open. */
.pl-cookie-settings { display: none; }
.pl-has-consent .pl-cookie-settings { display: inline; }
.pl-has-consent .pl-cookie-settings a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

/* Type scale (client 2026-10-13): paragraphs get the same "no lone word on the last line" as headings, on the
   screens where the scale changes their size — 1440–1599 keeps Figma's own breaks. */
@media (max-width: 1439px), (min-width: 1600px) {
  .pl-fluid-type p { text-wrap: pretty; }
}

/* Type scale, layout half (client 2026-10-13): text sizes follow inc/fluid-type.php on every screen. */
@media (min-width: 1025px) and (max-width: 1439px) {
  /* "Want to stock our brands?" card (Brands, Stockists): its margins, padding and 418px box image are fixed px,
     so the copy column took all of the narrowing (377px at 1280) and the heading broke onto two lines. Here they
     keep their 1440 share of the screen, like the type, so the card is the 1440 card scaled down (supersedes the
     1025–1279 rule above). */
  .pl-fluid-type .elementor .e-con.pl-stock-card {
    --margin-left: 11.0069vw; --margin-right: 11.0069vw;   /* 158.5 */
    --padding-left: 5.3472vw; --padding-right: 5.4167vw;   /* 77 / 78 */
    --min-height: 20.2083vw;                               /* 291 */
  }
  .pl-fluid-type .elementor .e-con.pl-stock-card > .elementor-widget.pl-stock-card__img {
    width: 29.0278vw !important;                           /* 418 */
    flex: 0 0 29.0278vw !important;
  }
  .pl-fluid-type .elementor .e-con.pl-stock-card .pl-stock-card__img img {
    width: 100%;
    height: auto !important;
    aspect-ratio: 418 / 219;
  }
  .pl-fluid-type .elementor .e-con.pl-stock-card > .e-con { flex: 1 1 0 !important; width: auto !important; min-width: 0; }
  /* Contact card: its form fields don't scale, so the card keeps its 1440 height (632) — scaled, the Submit row
     ended 24px from the card's edge at 1280. */
  .pl-fluid-type .elementor .e-con.pl-contact-card { --min-height: 632px; }
}

/* Touch screens wider than 1024 (landscape iPads 1180 / 1366 — spacing review 2026-10-13): the 44px tap floor that
   touch screens up to 1024 already get, for the targets that were 14–36px tall there. A mouse at the same width keeps
   the Figma sizes. */
@media (min-width: 1025px) and (hover: none) and (pointer: coarse) {
  [data-elementor-type="footer"] .elementor-icon-list-items .elementor-icon-list-item > a {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
  [data-elementor-type="footer"] .elementor-icon-list-item { margin-bottom: 0 !important; }
  [data-elementor-type="header"] .pl-nav-textlink a,
  [data-elementor-type="header"] .pl-nav .elementor-button {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  .pl-brand-page .pl-btn { min-height: 44px; }
}

/* Home "Why partners choose us" on tablets (spacing review 2026-10-13): the rows' 90px minimum (Figma's fixed bands
   at 1440) left the one-line rows 37px above their divider and the three-line rows 14px. Below desktop each row hugs
   its copy, so every row sits the same distance above its line. */
@media (max-width: 1024px) {
  .elementor .pl-why-row { min-height: 0; }
}

/* Home "Delivered nationwide" cards at 768–900 (spacing review 2026-10-13): three 207px cards leave the title ~107px
   beside the 44px arrow chip — "stockist" ran into the chip and "Explore our brands" took three lines. Here the chip
   drops below the title, which gets the card's full width (two lines each). 901–1024 keeps the chip beside it. */
@media (min-width: 768px) and (max-width: 900px) {
  .elementor .e-con.pl-card-top { flex-wrap: wrap !important; row-gap: 12px; }
  .elementor .pl-cta-card .pl-card-top .elementor-widget-heading { width: 100% !important; }
}

/* Home offer cards on touch tablets (spacing review 2026-10-13): in the stacked touch layout (§33.1) the two cards'
   copy differs in length, so their "View our brands" buttons sat 8–28px apart. The copy block takes the card's spare
   height and the button sits at its foot, level across the row. */
@media (min-width: 768px) and (hover: none) {
  .elementor .pl-offer-card > .pl-reveal { flex-grow: 1; }
  .elementor .pl-offer-card .e-con.pl-reveal > .elementor-widget-button { margin-top: auto; }
}

/* "Want to stock our brands?" box image below desktop (spacing review 2026-10-13): the frame was ~128px tall at every
   tablet / phone width while its width varied (255–530), so wide frames (744, 1024) sliced the box's flaps off. The
   frame keeps the desktop's own Figma crop instead (418 : 219, low), at most 360px wide and centred: the box sits
   at 46–91% of its square image, which that crop shows whole (2026-10-15 client: "box is cut off" — the earlier
   1.6 : 1 frame cut off its bottom edge). */
@media (max-width: 1024px) {
  .elementor .e-con .elementor-element.pl-stock-card__img img {
    width: 100% !important;
    max-width: 360px;
    height: auto !important;
    aspect-ratio: 418 / 219;
    margin: 0 auto;
    display: block;
    object-fit: cover !important;
    object-position: 50% 88.8% !important;
  }
}

/* Our Team "It's personal" photos above 1440 (desktop sign-off 2026-10-13): 335px tall at any width, so at 2560 the
   strip was 2.4 : 1 and cut the middle dog at the muzzle. They keep their 1440 frame (423 × 335) instead. */
@media (min-width: 1441px) {
  .elementor .pl-img3 .elementor-widget-image img { height: auto; aspect-ratio: 423 / 335; }
}

/* Brands directory card titles on tablets and phones (final type check 2026-10-13): at the scale's ~20px (weight 500)
   they read as the 16px description's first line. A clear step up instead; desktop follows the type scale. */
@media (max-width: 767px) {
  .pl-fluid-type .elementor .pl-brand-directory .pl-brand-card__title { font-size: 22px; line-height: 1.26; }
}
@media (min-width: 768px) and (max-width: 1024px) {
  .pl-fluid-type .elementor .pl-brand-directory .pl-brand-card__title { font-size: 24px; line-height: 1.26; }
}

/* ===== Phones: centred layout (mobile QA 2026-10-15) =====
   Phones read on one centred axis; the alignment itself is each element's Mobile value in Elementor
   (inc/qa-sync-mobile-centre.php lists them), so it stays editable there. This block holds only what those settings
   can't do. Everything is gated to phones (max-width: 767px; the burger fade also to landscape phones,
   max-height: 500px), so tablets and desktops are untouched. */
@media (max-width: 767px) {
  /* Footer strapline: its paragraph keeps a 30ch measure (§25), and a block that narrow stayed on the left edge of the
     column (36px off-centre at 430). The widget's own 382px cap does the same on wide phones. */
  [data-elementor-type="footer"] .elementor-widget.pl-footer-brand,
  [data-elementor-type="footer"] .pl-footer-brand p {
    margin-left: auto;
    margin-right: auto;
  }
  /* …and its lines even (2026-10-15, client: the strapline "is not correctly aligned"): at 360 "South Africa." sat
     alone under two full lines and read as off-axis; balanced, the lines are near equal on every phone. */
  [data-elementor-type="footer"] .pl-footer-brand p { text-wrap: balance; }
  /* Home "As featured in": the logo links were 40px tall (the logos' phone height); 2px more above and below, given
     back by the margin, makes 44px tap targets without moving a logo. */
  .elementor .pl-featured-logo a { padding: 2px 0; margin: -2px 0; }
}

/* Burger sheet on short screens (360 x 640, 375 x 667, phones in landscape): the link list scrolls above the pinned
   Contact us / Partner Log In row (§C4) and was simply cut off at its edge, with nothing to say more was below. While
   the list can still scroll down, its last 36px fade out into the sheet; the fade shrinks away over the final stretch
   of the scroll, and a list that fits (taller phones) has no scroll timeline, so no fade. Browsers without
   scroll-driven animations show the list as before. The header bar itself is untouched. */
@property --pl-menu-fade {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}
@keyframes pl-menu-fade {
  from, 75% { --pl-menu-fade: 36px; }
  to { --pl-menu-fade: 0px; }
}
@media (max-width: 767px), (max-height: 500px) and (max-width: 1024px) {
  @supports (animation-timeline: scroll()) {
    [data-elementor-type="header"] .pl-nav nav.elementor-nav-menu--dropdown[aria-hidden="false"] > ul {
      -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - var(--pl-menu-fade)), transparent);
      mask-image: linear-gradient(to bottom, #000 calc(100% - var(--pl-menu-fade)), transparent);
      animation: pl-menu-fade linear both;
      animation-timeline: scroll(self block);
    }
  }
}

/* Buy Online retailer strip with reduced motion (§42): the static fallback wrapped as many logos as fit per row,
   2-2-2-2-2-2-1 at 360 and 2-2-2-2-3-2 at 390. Phones get a fixed two-column grid instead, each logo centred in its
   cell and an odd last logo centred under the pair above. */
@media (max-width: 767px) and (prefers-reduced-motion: reduce) {
  .pl-marquee--logos .pl-marquee__track {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    justify-items: center;
    align-items: center;
    column-gap: 16px;
    row-gap: 24px;
    width: auto;
    padding: 0 16px;
  }
  .pl-marquee--logos .pl-logo-strip__item { margin: 0 !important; max-width: 100%; }
  .pl-marquee--logos .pl-logo-strip__item:nth-last-child(1 of :not(.is-clone)):nth-child(odd of :not(.is-clone)) {
    grid-column: 1 / -1;
  }
  .pl-marquee--logos .pl-marquee__track img { max-width: 100%; object-fit: contain; }
}

/* Home hero headline on phones (mobile QA 2026-10-15): the phone crop now shows the hand, ball and dog; a sunlit sliver
   of the hand behind the white headline measured 2.9 : 1 at 360–375 (large text needs 3 : 1). A soft shadow keeps
   every letter readable, the same treatment as the stats band's labels. */
@media (max-width: 767px) {
  .elementor .e-con.pl-home-hero .elementor-heading-title {
    text-shadow: 0 1px 12px rgba(0, 0, 0, 0.45);
  }
}

/* Our Team › It's personal photos on phones: a swipe slider (2026-10-15, client: "make this a slider on mobile").
   The three photos sit in one row (the container's Mobile direction is Row in Elementor); each takes 84% of the width
   so the next one peeks in at the edge, and snaps to the centre. Swipe on touch, trackpad / shift-scroll with a mouse;
   the row itself is keyboard-scrollable. Tablets and desktops keep the three photos side by side. */
@media (max-width: 767px) {
  .elementor .e-con.pl-img3 {
    --flex-direction: row !important;
    --flex-wrap: nowrap !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .elementor .e-con.pl-img3::-webkit-scrollbar { display: none; }
  .elementor .e-con.pl-img3 > .elementor-widget {
    flex: 0 0 84% !important;
    width: 84% !important;
    scroll-snap-align: center;
  }
  .elementor .pl-img3 .elementor-widget-image img { height: auto; aspect-ratio: 423 / 335; }
}

/* Video over an image (Image widget › "Video over the image", inc/media-video.php; About › How it started, Contact).
   pl-main.js gives the video its picture's exact box, crop and corners. It stays invisible until its first frame
   plays (that frame is the picture), then fades in. */
.elementor .pl-media-video {
  position: absolute;
  display: block;
  max-width: none;
  margin: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity .5s ease;
}
.elementor .pl-media-video.is-playing { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .elementor .pl-media-video { display: none; }
}

/* Home hero background video (Elementor › Style › Background › Video; its Background Fallback is the poster). The
   video takes the poster's crop at every size, so its first frame, which is the poster, lands on it pixel for
   pixel: centred and filling the panel on tablets (Elementor's own sizing); held to the right on phones (the dog and
   its ball); and from 1025px the hero's tuned crop (§20 HOME QA › Hero above: 100.478% of the panel, at least
   1376.545px wide, its right edge 7.183px past the panel, its top 14.32% of the overflow above it, less 102.39px).
   The rounded corners clip it. Reduced motion and Data Saver turn it off (pl-main.js), leaving the poster. */
/* Elementor writes the fallback as a `background:` shorthand, which turns repeat back on: at 1440 the tuned crop
   leaves 0.6px on the left that then tiled. */
.elementor .e-con.pl-home-hero { background-repeat: no-repeat !important; }
.elementor .e-con.pl-home-hero > .elementor-background-video-container { border-radius: inherit; }
.elementor .pl-video-off { display: none; }
@media (max-width: 767px) {
  .elementor .e-con.pl-home-hero { background-position: 100% 50% !important; }
  .elementor .e-con.pl-home-hero .elementor-background-video-hosted { object-position: 100% 50%; }
}
@media (min-width: 1025px) {
  .elementor .e-con.pl-home-hero .elementor-background-video-hosted {
    width: max(100.478%, 1376.545px) !important;
    max-width: none !important;   /* Elementor caps every video at 100% */
    height: auto !important;
    aspect-ratio: 16 / 9;
    object-fit: fill;
    inset-inline-start: auto !important;
    right: -7.183px;
    inset-block-start: calc(14.3203% - 102.39px) !important;
    transform: translateY(-14.3203%) !important;
  }
}
