/** Shopify CDN: Minification failed

Line 811:9 Unexpected "{"
Line 811:14 Expected ":"
Line 812:9 Unexpected "{"
Line 812:14 Expected ":"

**/
/* ============================================================
   IOTREND — CUSTOM STYLESHEET
   Ref: GPM-IOT-002 | Growth Pulse Media (Pty) Ltd

   Loaded from layout/theme.liquid immediately after pages.css,
   so these rules win without needing !important. Avone loads
   default.css late in the body — if a rule here is ever
   ignored, add specificity (prefix with "body ") rather than
   reaching for !important.

   Do not edit Avone's own CSS files. Everything custom lives
   here so it survives a theme update or reinstall.
   ============================================================ */


/* ============================================================
   BRAND TOKENS — single source of truth for colours, radii
   and shared values. Change a brand colour here and it
   updates everywhere it is referenced.
   ============================================================ */

:root {
  --iot-red:        #DE0000;
  --iot-red-dark:   #B80000;
  --iot-black:      #0B0B0B;
  --iot-white:      #FFFFFF;
  --iot-muted:      #9AA0A6;
  --iot-radius:     3px;
  --iot-radius-lg:  10px;
}

/* ============================================================
   HOMEPAGE HEADER BACKGROUND — the homepage header sits
   transparent over the hero image so the banner runs full
   bleed behind it. Avone's native transparent-header setting
   handles the positioning; this only clears the background
   the theme's global (white) header colour would otherwise
   paint in. Inner pages keep the white header from settings.

   The red announcement bar above it is deliberately NOT
   included — it keeps its own brand-red background.

   29 Sep 2026: all rules skip .sticky-header. Once the
   visitor scrolls, the sticky header turns solid white with
   the dark logo and dark menu, same as inner pages.
   ============================================================ */

.template-index .header-wrap:not(.sticky-header) {
  background-color: transparent !important;
  box-shadow: none;
}

.template-index .header-wrap:not(.sticky-header) a,
.template-index .header-wrap:not(.sticky-header) .btn,
.template-index .header-wrap:not(.sticky-header) svg {
  color: var(--iot-white);
  fill: var(--iot-white);
  stroke: var(--iot-white);
}

.template-index .header-wrap:not(.sticky-header) a:hover,
.template-index .header-wrap:not(.sticky-header) svg:hover {
  color: var(--iot-red);
  fill: var(--iot-red);
}



/* ============================================================
   HOMEPAGE NAVIGATION COLOUR — keeps the menu legible over
   the dark header. The theme's nav link colour (#222222) is
   set for white inner pages and reasserts itself on hover,
   turning the menu near-invisible on the homepage. Desktop
   only; mobile uses the theme's own menu treatment.
   ============================================================ */

@media screen and (min-width: 750px) {
  .template-index .header-wrap:not(.sticky-header) #main-nav a,
  .template-index .header-wrap:not(.sticky-header) #main-nav > li > a {
    color: var(--iot-white);
  }

  .template-index .header-wrap:not(.sticky-header) #main-nav a:hover,
  .template-index .header-wrap:not(.sticky-header) #main-nav a:focus {
    color: var(--iot-red);
  }
}


/* ============================================================
   HERO PRIMARY CTA ARROW — adds the circular white arrow
   badge inside the red "Shop Security" button, matching the
   approved design. Scoped to .hero-section because btn1 is
   used site-wide, including Add to Cart. Arrow is an inline
   SVG data URI, so no extra HTTP request.
   ============================================================ */

.hero-section .btn1 {
  display: inline-flex;
  align-items: center;
  gap: 12px;
}

.hero-section .btn1::after {
  content: '';
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background-color: var(--iot-white);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23DE0000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h13M13 6l6 6-6 6'/%3E%3C/svg%3E");
  background-size: 12px 12px;
  background-repeat: no-repeat;
  background-position: center;
  transition: transform .2s ease;
}

.hero-section .btn1:hover::after {
  transform: translateX(3px);
}


/* ============================================================
   HERO BUTTON LAYOUT — places the two hero CTAs side by side.
   Avone wraps each button in its own .btnWrap inside a flex
   column (.group-bk), so they stack by default. This switches
   the container to a wrapping row and forces every non-button
   child to full width, leaving only the buttons inline.
   Desktop only — buttons stay stacked on mobile.
   ============================================================ */

@media screen and (min-width: 750px) {
  .hero-section .group-bk {
    flex-flow: row wrap;
    align-items: flex-start;
  }

  .hero-section .group-bk > *:not(.btnWrap) {
    flex: 0 0 100%;
  }

  .hero-section .group-bk .btnWrap {
    flex: 0 0 auto;
  }
}


/* ============================================================
   HERO SCROLL CUE — animated chevron at the base of the
   banner indicating there is content below. Added because the
   full-height hero gives no visual signal to scroll.
   ============================================================ */

.hero-section {
  position: relative;
}

.hero-section::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 26px;
  width: 14px;
  height: 14px;
  margin-left: -7px;
  border-right: 2px solid rgba(255, 255, 255, .7);
  border-bottom: 2px solid rgba(255, 255, 255, .7);
  transform: rotate(45deg);
  animation: iot-scroll-cue 2s ease-in-out infinite;
  pointer-events: none;
  z-index: 2;
}

@keyframes iot-scroll-cue {
  0%, 100% { transform: rotate(45deg) translate(0, 0); opacity: .55; }
  50%      { transform: rotate(45deg) translate(4px, 4px); opacity: 1; }
}


/* ============================================================
   REDUCED MOTION — disables the arrow nudge and scroll cue
   animation for users who have requested reduced motion in
   their operating system settings.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  .hero-section .btn1::after,
  .hero-section::after {
    transition: none;
    animation: none;
  }
}

/* ============================================================
   TOP HEADER ALIGNMENT — the theme gives each announcement
   block equal flexible width, centring items within their own
   half and leaving a large gap in the middle. This collapses
   the blocks to their natural width and centres the whole
   group as one row.
   ============================================================ */

@media screen and (min-width: 750px) {
  .top-header .section-cover > div {
    justify-content: center;
  }

  .top-header .ttxt {
    flex: 0 0 auto;
  }
}

/* ============================================================
   TOP HEADER DIVIDERS — vertical pipes between announcement
   items, both within a block and between adjacent blocks.
   ============================================================ */

.top-header .ttxt > *:not(:last-child) {
  padding-right: 15px;
  border-right: 1px solid rgba(255, 255, 255, .35);
}

@media screen and (min-width: 750px) {
  .top-header .ttxt + .ttxt {
    margin-left: 15px;
    padding-left: 15px;
    border-left: 1px solid rgba(255, 255, 255, .35);
  }
}

/* ============================================================
   TOP HEADER MOBILE — show only the first announcement item;
   remaining items are desktop-only.
   ============================================================ */

@media screen and (max-width: 749px) {
  .top-header .ttxt > *:not(:first-child),
  .top-header .ttxt:not(:first-child) {
    display: none;
  }

  .top-header .ttxt > *:first-child {
    border-right: 0;
    padding-right: 0;
  }
}

/* ============================================================
   NATIVE SECTION HEADINGS — restyles Avone's own homepage
   section headings (Trending Now product carousel, and any
   other native sections added later) to match the custom
   sections: centred, uppercase, bold, short red underline.
   Scoped to the homepage; inner pages keep Avone defaults.
   ============================================================ */

.template-index .section-header {
  text-align: center;
}

.template-index .section-header h2,
.template-index .section-header .h2 {
  font-size: clamp(20px, 2.2vw, 28px);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .02em;
  color: #111111;
  margin-bottom: 0;
}

.template-index .section-header h2::after,
.template-index .section-header .h2::after {
  content: '';
  display: block;
  width: 44px;
  height: 3px;
  margin: 10px auto 0;
  background: var(--iot-red);
}

/* Hide the eyebrow and description lines native sections
   render around the heading, if the section settings can't
   remove them */
.template-index .section-header > p,
.template-index .section-header .sub-heading,
.template-index .section-header .rte {
  display: none;
}

/* ============================================================
   PRODUCT CARDS — homepage carousel: red pricing, bordered
   cards, and two-line title clamp so long catalogue titles
   don't break the card rhythm.
   ============================================================ */

.template-index .grid_products product-card {
  background: #FFFFFF;
  border: 1px solid #ECECEC;
  border-radius: 3px;
  overflow: hidden;
}

.template-index .grid_products .grid-meta .price,
.template-index .grid_products .grid-meta [class*="price"] {
  color: var(--iot-red);
  font-weight: 700;
}

.template-index .grid_products .grid-meta a {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ============================================================
   PRODUCT CARDS — "Add to Cart"-style button on homepage
   carousel cards. Visual preview built from the card's
   existing product link; navigates to the product rather
   than adding to cart. Replace with true quick-add once the
   native toggle or snippet route is settled.
   ============================================================ */

.template-index .grid_products .grid-meta::after {
  content: 'View Product';
  display: block;
  margin: 10px auto 4px;
  width: fit-content;
  padding: 8px 22px;
  border: 1px solid var(--iot-red);
  border-radius: 3px;
  color: var(--iot-red);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  transition: background .2s ease, color .2s ease;
  pointer-events: none;
}

.template-index .grid_products product-card:hover .grid-meta::after {
  background: var(--iot-red);
  color: #FFFFFF;
}
/* Make the card's title link cover the whole meta area,
   including the View Product button, so the button is
   clickable */
.template-index .grid_products .grid-meta {
  position: relative;
}

.template-index .grid_products .grid-meta a::before {
  content: '';
  position: absolute;
  inset: 0;
}

/* ============================================================
   SOLUTION FINDER PAGE — hide the theme page title and
   breadcrumb, and collapse the template's inline section
   padding so the page opens straight into the custom content.
   ============================================================ */

body:has(#iot-finder) .page-title,
body:has(#iot-finder) .bc-wrapper {
  display: none;
}

body:has(#iot-finder) .content-page .section-cover {
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}

body:has(#iot-finder) .content-page .rte {
  margin-top: 0;
}

/* ============================================================
   PRODUCT CARDS — unified treatment wherever Avone renders a
   product card: homepage carousels, collection grids, search
   results, product-page recommendation and recently-viewed
   sliders, and the cart page's recommendation row.

   Deliberately NOT scoped to a template class. Product cards
   must look identical everywhere, and each new template that
   turns out to use them (the cart page being the latest)
   would otherwise need adding by hand. Matching the geometry
   block above, which is scoped the same way.

   Note the two container spellings: the homepage carousel
   uses grid_products with an UNDERSCORE, everywhere else uses
   grid-products with a HYPHEN. Both are listed throughout.

   body-prefixed because Avone's default.css loads late in the
   body and outguns lighter selectors.
   ============================================================ */

body .grid_products product-card,
body .grid-products product-card {
  background: #FFFFFF;
  border: 1px solid #ECECEC;
  border-radius: 3px;
  overflow: hidden;
}

/* Prices in brand red, bold. Attribute selector catches the
   theme's several price classes (regular, sale, compare-at). */
body .grid_products .grid-meta [class*="price"],
body .grid-products .grid-meta [class*="price"] {
  color: var(--iot-red);
  font-weight: 700;
}

/* Titles clamp to two lines. Catalogue titles run long
   ("Centurion D10 SMART+ Gate Motor Kit incl 4m Steel Rack
   and Bracket"), so without this the rows never align. */
body .grid_products .grid-meta a,
body .grid-products .grid-meta a {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

body .grid_products .grid-meta,
body .grid-products .grid-meta {
  position: relative;
}

/* "View Product" button drawn in CSS rather than markup,
   since Avone exposes no add-to-cart toggle on these cards.
   pointer-events: none keeps it visually a button while the
   stretched title link below does the actual clicking. */
body .grid_products .grid-meta::after,
body .grid-products .grid-meta::after {
  content: 'View Product';
  display: block;
  margin: 10px auto 4px;
  width: fit-content;
  padding: 8px 22px;
  border: 1px solid var(--iot-red);
  border-radius: 3px;
  color: var(--iot-red);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  transition: background .2s ease, color .2s ease;
  pointer-events: none;
}

body .grid_products product-card:hover .grid-meta::after,
body .grid-products product-card:hover .grid-meta::after {
  background: var(--iot-red);
  color: #FFFFFF;
}

/* Stretched overlay makes the whole card clickable via the
   title link, without nesting anchors. */
body .grid_products .grid-meta a::before,
body .grid-products .grid-meta a::before {
  content: '';
  position: absolute;
  inset: 0;
}

/* ============================================================
   HERO — MOBILE CROP

   Avone centre-crops the landscape hero into portrait on
   mobile, which pushes the gate to the right edge and leaves
   a band of empty sky above the headline. Shifting the crop
   origin rightward brings the subject back into frame while
   keeping the dark left zone the copy sits on.

   Try this before committing to a second image asset — it is
   often enough on its own, and there is no extra file to
   maintain or re-upload after a theme update.
   ============================================================ */

@media screen and (max-width: 749px) {
  body .hero-section .banner-image img {
    object-fit: cover;
    object-position: 65% center;
  }
}

/* ============================================================
   HERO — MOBILE CONTRAST SCRIM

   Darkens the hero image behind the headline and CTAs on
   mobile only. The desktop crop keeps the copy over genuine
   shadow; the portrait crop does not, so the type can fall
   over lit paving or a window and lose legibility.

   A gradient rather than a flat tint: heaviest at the top
   where the header overlays, lightest across the middle so
   the gate stays visible, darkening again at the foot behind
   the scroll cue.

   Brand red is deliberately untouched — the scrim solves
   contrast without introducing a second mobile palette.
   ============================================================ */

@media screen and (max-width: 749px) {
  body .hero-section .banner-image::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(
      to bottom,
      rgba(0, 0, 0, .85) 0%,
      rgba(0, 0, 0, .55) 45%,
      rgba(0, 0, 0, .75) 100%
    );
    pointer-events: none;
  }
}

/* ============================================================
   PRODUCT CARD TITLE — two-line box, exact height

   Catalogue titles range from one line to three. The card
   clamps them to two, and the box must reserve exactly two
   lines so shorter titles do not pull the price and button
   upward.

   line-height, min-height and max-height are all derived from
   the same value: min-height reserves the space, max-height
   with overflow hidden stops a third line bleeding past the
   clamp and being sliced mid-character.

   Change --iot-card-title-lh alone to adjust; the other two
   follow.
   ============================================================ */

body product-card .grid-meta a {
  --iot-card-title-lh: 1.4em;

  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;

  line-height: var(--iot-card-title-lh);
  min-height: calc(var(--iot-card-title-lh) * 2);
  max-height: calc(var(--iot-card-title-lh) * 2);
}

/* ============================================================
   PRODUCT PAGE — MOBILE BUY ROW

   Stacks the quantity stepper and Add to Cart on their own
   full-width rows on mobile. The primary action should not
   share a line with the stepper: full width improves thumb
   reach and gives the one button that matters its own visual
   moment.

   The stepper spans the row as three EQUAL segments — minus,
   value, plus — separated by internal dividers, so the width
   reads as structure rather than dead space. Modelled on the
   proven GPM layout from previous builds.

   Verified markup: the row is div.fl.gap.mb10 directly inside
   .product-form__buttons, holding quantity-input.qty-field
   (qty-btn.minus / input.qty / qty-btn.plus) and
   button.product-form__submit. Scoped with :has() so only the
   buy row is touched — .fl.gap is a generic Avone utility
   combination used elsewhere.

   Desktop keeps the theme's side-by-side layout.

   body-prefixed because Avone's default.css loads late in the
   body and outguns lighter selectors.
   ============================================================ */

@media screen and (max-width: 749px) {
  body .product-form__buttons > .fl.gap:has(> quantity-input) {
    flex-wrap: wrap;
    row-gap: 12px;
  }

  /* Stepper: full row, three equal cells with dividers. */
  body .product-form__buttons quantity-input.qty-field {
    flex: 1 1 100%;
    max-width: 100%;
    margin: 0;
    display: flex;
    align-items: stretch;
    border: 1px solid #E4E4E4;
    border-radius: 3px;
    overflow: hidden;
  }

  body .product-form__buttons quantity-input.qty-field .qty-btn,
  body .product-form__buttons quantity-input.qty-field .qty,
  body .product-form__buttons quantity-input.qty-field input {
    flex: 1 1 33.33%;
    width: auto;
    min-height: 52px;
    border: 0;
    text-align: center;
  }

  /* Internal dividers on the centre cell only — one line
     each side, no doubling. */
  body .product-form__buttons quantity-input.qty-field .qty,
  body .product-form__buttons quantity-input.qty-field input {
    border-left: 1px solid #E4E4E4;
    border-right: 1px solid #E4E4E4;
    border-radius: 0;
  }

  /* Add to Cart: full row, matched height, unmissable. */
  body .product-form__buttons .product-form__submit {
    flex: 1 1 100%;
    width: 100%;
    min-height: 52px;
    padding-top: 16px;
    padding-bottom: 16px;
  }
}

/* ============================================================
   PRODUCT STOCK STATUS — MOBILE CENTRING

   Centres the status chip on mobile, aligning it with the
   column's axis alongside the stepper, Add to Cart and
   WhatsApp bar. Deliberately NOT full width: a status chip
   reads as a live indicator because it hugs its content —
   stretched, it becomes just another banner, and the
   out-of-stock state would become a giant red band.

   Desktop keeps the left placement, matching the left-aligned
   title and price above it.
   ============================================================ */

@media screen and (max-width: 749px) {
  body .iot-stock {
    display: inline-flex;
    margin-left: auto;
    margin-right: auto;
  }
}

/* ============================================================
   PRODUCT PAGE — MOBILE UTILITY LINKS

   Centres the wishlist / ask-a-question row on mobile so the
   action zone (stock chip, links, stepper, Add to Cart,
   WhatsApp bar) sits on one centre axis. The identity zone
   above — title, SKU, price, tax — stays left-aligned, giving
   two coherent zones instead of alternating alignment.

   Wrapper class is Avone's own spelling: "additonal-links".

   body-prefixed because Avone's default.css loads late in the
   body and outguns lighter selectors.
   ============================================================ */

@media screen and (max-width: 749px) {
  body .product-meta__wrapper .additonal-links {
    justify-content: center;
  }
}

/* ============================================================
   PRODUCT GALLERY — SLIDER ARROWS

   White circular arrows with a dark glyph and soft elevation,
   replacing the theme default. White-on-any-photo is the one
   combination that stays visible across mixed supplier
   imagery, most of which sits on white studio backgrounds.
   Hover goes brand red, matching the sitewide state
   convention (checkboxes, swatches, dots).

   Verified markup: .swiper-arrows.swiper-button-next /
   .swiper-button-prev inside .product-image__slider. Scoped
   to the product gallery so collection and homepage sliders
   keep their own treatment.

   body-prefixed because Avone's default.css loads late in the
   body and outguns lighter selectors.
   ============================================================ */

body .product-image__slider .swiper-arrows {
  --arbg: #FFFFFF;
  --ar: #0B0B0B;
  background: #FFFFFF;
  color: #0B0B0B;
  border: 1px solid #ECECEC;
  border-radius: 50%;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .12);
  transition: background .18s ease, color .18s ease, border-color .18s ease;
}

body .product-image__slider .swiper-arrows:hover {
  --arbg: #DE0000;
  --ar: #FFFFFF;
  background: #DE0000;
  color: #FFFFFF;
  border-color: #DE0000;
}

/* ============================================================
   PRODUCT PAGE — DELIVERY ESTIMATE CARD

   Restyles Avone's shipping-estimate block to match the buy
   column's card language (Payflex bar, WhatsApp bar): white,
   hairline border, 3px radius, grey icon. It was the last
   element in the column on the theme's bare default — text
   floating without a container — which read as unfinished
   next to the styled bars around it.

   Content caveat: this styles the dates, it does not verify
   them. The day offsets must match real courier lead times —
   confirm with the client before launch, and hide the block
   on request-only items.

   Verified markup: div.fl.shipping-msg inside the product
   meta column. body-prefixed because Avone's default.css
   loads late in the body and outguns lighter selectors.
   ============================================================ */

body .product-meta__wrapper .shipping-msg {
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid #E4E4E4;
  border-radius: 3px;
  background: #FFFFFF;
  font-size: 13px;
  color: #333333;
  line-height: 1.4;
  --icns: 19px;
}

body .product-meta__wrapper .shipping-msg svg {
  flex: 0 0 auto;
  color: #6B7680;
  fill: currentColor;
  stroke: currentColor;
}

body .product-meta__wrapper .shipping-msg strong,
body .product-meta__wrapper .shipping-msg b {
  color: #0B0B0B;
}

/* ============================================================
   SECTION HEADINGS — INNER PAGES
   Extends the homepage section-header treatment to product,
   collection, search and cart templates. Markup is identical
   (div.section-header > h2.section-header__title) — only the
   template scope differed. body-prefixed to outrank Avone's
   late-loading default.css without !important.
   ============================================================ */

body .section-header__title {
  text-align: center;
  text-transform: uppercase;
  color: #0B0B0B;
  letter-spacing: .02em;
}

body .section-header__title::after {
  content: "";
  display: block;
  width: 44px;
  height: 2px;
  margin: 12px auto 0;
  background: #DE0000;
}

/* ============================================================
   PRODUCT PAGE — SKU SIZE
   Avone's theme setting writes --fs on the .group-bk parent
   but .product-sku doesn't consume it, so the control does
   nothing. Sized directly here instead. Inline style is on the
   parent, not this element, so body-prefix specificity is
   enough — no !important needed.
   Identity zone: SKU sits under the title, above price.
   ============================================================ */

body.template-product .product-sku,
body.template-product .product-sku .lbl,
body.template-product .product-sku .variant-sku {
  font-size: 12px;
  line-height: 1.4;
}

body.template-product .product-sku .lbl {
  color: #6B7680;
  font-weight: 400;
}

/* ============================================================
   ACCESSORIES CAROUSEL — edge fade width correction
   Scope: sections/custom-cross-sell.liquid
   Rationale: 42px fades overlapped card text, making titles
   and prices read as faded/broken. 20px covers the clip edge
   and gutter only. Fix in the section file, not custom.css —
   the fades belong to that section.
   ============================================================ */
#iot-xs-{{ uid }} .iot-xs__viewport::before,
#iot-xs-{{ uid }} .iot-xs__viewport::after {
  width: 20px;
}

/* ============================================================
   AVONE SLIDER ARROWS — GIVE THE WHITE BUTTON AN EDGE
   ============================================================
   PURPOSE
   Make Avone's arrows read as buttons rather than a floating
   chevron, matching the custom FBT and Accessories carousels.

   WHAT WAS ACTUALLY WRONG
   Nothing. Diagnostics showed the arrow already computes to a
   40px white box (--arbg #FFFFFF) with a dark glyph (--ar
   #0B0B0B). On white studio product photography a white box
   with no border and no shadow is invisible, so only the
   chevron shows. The fix is an edge, not a recolour.

   GLYPH MECHANISM — confirmed by computed styles
   The chevron is an ICON FONT, not an SVG: ::after carries
   content "next" / "prev" in font-family 'swiper-icons'. It is
   therefore coloured by `color`, never `fill` or `stroke`.
   Earlier SVG-targeted rules in this file were inert for this
   reason. Avone drives the colour through --ar and the
   background through --arbg, so setting those two variables is
   the correct lever — do not hardcode over them.

   SCOPE
   Shared .swiper-arrows class, so one rule covers the product
   gallery, Recently Viewed, Recommended and Related. Note the
   modifier classes differ per slider (hide-arrows__mob on the
   gallery, hide-sm on Recently Viewed) — targeting a modifier
   is what made a previous attempt miss entirely.

   POSITION IS DELIBERATELY UNTOUCHED
   An earlier attempt moved these arrows with a negative top
   offset and they vanished, almost certainly clipped by an
   overflow:hidden ancestor. This rule adds border, radius and
   shadow only. Do not add position, top, or transform here.
   ============================================================ */

body .swiper-arrows {
  --arbg: #FFFFFF;
  --ar: #0B0B0B;

  border: 1px solid #E4E4E4;
  border-radius: 3px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .10);
  transition: border-color .18s ease, background-color .18s ease, color .18s ease;
}

/* Hover — red, per the sitewide state convention. Driven
   through Avone's own variables so the glyph follows. */
body .swiper-arrows:hover {
  --arbg: #DE0000;
  --ar: #FFFFFF;
  border-color: #DE0000;
}

/* Disabled — Avone's own state class */
body .swiper-arrows.swiper-button-disabled {
  opacity: .35;
  pointer-events: none;
}

body .swiper-arrows.swiper-button-disabled:hover {
  --arbg: #FFFFFF;
  --ar: #0B0B0B;
  border-color: #E4E4E4;
}

@media (prefers-reduced-motion: reduce) {
  body .swiper-arrows { transition: none; }
}

/* ============================================================
   COMPARE PAGE — honour the hidden attribute
   The shell toggles [hidden] on the toolbar, board and note.
   Their display rules (flex/grid) outrank the UA's
   [hidden]{display:none}, so the toolbar rendered on the empty
   state. Scoped to #iot-compare so nothing else is affected.
   ============================================================ */
#iot-compare [hidden] { display: none !important; }

/* ============================================================
   COMPARE PAGE — suppress theme page furniture
   The section carries its own heading; Avone's page title and
   breadcrumb duplicate it. Mirrors the Solution Finder rules.
   ============================================================ */
body:has(#iot-compare) .page-title,
body:has(#iot-compare) .bc-wrapper { display: none; }
body:has(#iot-compare) .content-page .section-cover { padding: 0 !important; }

/* ============================================================
   CUSTOM — Dropdown menu: flyout indicator on items with children
   Avone's dropdown renders nested ddmenu ULs but gives parent
   items no visual cue. Adds a right-chevron to any dropdown item
   that contains a submenu. Uses :has(), supported in all current
   browsers; older browsers simply show no chevron (no breakage).
   ============================================================ */
#main-nav .ddmenu li:has(> .ddmenu) > a{
  display:flex; align-items:center; justify-content:space-between;
  gap:10px;
}
#main-nav .ddmenu li:has(> .ddmenu) > a::after{
  content:""; flex:0 0 7px; width:7px; height:7px;
  border-right:1.5px solid currentColor;
  border-top:1.5px solid currentColor;
  transform:rotate(45deg);
  opacity:.55; transition:opacity .2s ease, transform .2s ease;
}
#main-nav .ddmenu li:has(> .ddmenu):hover > a::after{
  opacity:1; transform:rotate(45deg) translate(1px,-1px);
}

/* ============================================================
   CUSTOM — Dropdown menu: hover state + flyout indicator
   Avone's dropdown gives items no hover feedback and no cue on
   items with children. Adds: red text + subtle wash on hover,
   and a right-chevron on any item containing a submenu.
   :has() is fine in all current browsers; older ones just get
   no chevron (no breakage).
   ============================================================ */

/* -- hover/focus state on every dropdown item -- */
#main-nav .ddmenu li > a{
  transition:color .18s ease, background .18s ease, padding-left .18s ease;
}
#main-nav .ddmenu li > a:hover,
#main-nav .ddmenu li > a:focus-visible{
  color:#DE0000;
  background:#FBEAEA;
}

/* -- flyout indicator on items with children -- */
#main-nav .ddmenu li:has(> .ddmenu) > a{
  display:flex; align-items:center; justify-content:space-between;
  gap:10px;
}
#main-nav .ddmenu li:has(> .ddmenu) > a::after{
  content:""; flex:0 0 7px; width:7px; height:7px;
  border-right:1.5px solid currentColor;
  border-top:1.5px solid currentColor;
  transform:rotate(45deg);
  opacity:.55; transition:opacity .2s ease, transform .2s ease;
}
#main-nav .ddmenu li:has(> .ddmenu):hover > a::after{
  opacity:1; transform:rotate(45deg) translate(1px,-1px);
}
/* Avone renders its own caret on some header styles — hide it,
   ours is the consistent one across dark/light headers */
#main-nav .ddmenu li:has(> .ddmenu) > a > svg,
#main-nav .ddmenu li:has(> .ddmenu) > a > .icon,
#main-nav .ddmenu li:has(> .ddmenu) > a > i{
  display:none !important;
}

/* ============================================================
   IOTREND — PRODUCT PAGE TABS + DESCRIPTION STYLING (11 Sep 2026) — v2
   ------------------------------------------------------------
   Append to assets/custom.css on the GPM 3.0 theme (or paste
   into Theme settings → Custom CSS). Scoped to #PrSecTabs, the
   product tabs section (Avone "productTabs"), so nothing else
   on the site changes. Restyles the tab headers and gives every
   product description one look: red section labels, tidy lists,
   spec tables that match the Specifications tab. No content
   edits — the descriptions stay as written.
   ============================================================ */

/* ---------- Section frame ---------- */
#PrSecTabs .tab-section{
  --tab-color:#6B7680; --tab-color-active:#0B0B0B;
  --tab-border:transparent; --tab-border-active:#DE0000; --tab-bg:#FFFFFF;
  border:1px solid #E4E4E4 !important; border-radius:3px !important;
  background:#FFFFFF; overflow:hidden;
}

/* ---------- Tab headers ---------- */
#PrSecTabs .ft1.tabs{
  gap:0 !important; background:#FAFAFA; border-bottom:1px solid #E4E4E4;
  padding:0 8px; overflow:hidden; flex-wrap:wrap !important;
}
#PrSecTabs .ft1.tabs > *{
  position:relative; flex:0 0 auto; margin:0 !important;
  padding:16px 22px !important; border:0 !important; border-radius:0 !important;
  background:transparent !important; box-shadow:none !important;
  font-size:11.5px !important; font-weight:700 !important; letter-spacing:.12em !important;
  text-transform:uppercase !important; color:#6B7680 !important; cursor:pointer;
  white-space:nowrap; transition:color .2s ease;
}
#PrSecTabs .ft1.tabs > *::after{
  content:""; position:absolute; left:22px; right:22px; bottom:0; height:2px;
  background:#DE0000; transform:scaleX(0); transition:transform .2s ease;
}
#PrSecTabs .ft1.tabs > .active,
#PrSecTabs .ft1.tabs > [aria-selected="true"],
#PrSecTabs .ft1.tabs > .is-active{ color:#0B0B0B !important; background:#FFFFFF !important; }
#PrSecTabs .ft1.tabs > .active::after,
#PrSecTabs .ft1.tabs > [aria-selected="true"]::after,
#PrSecTabs .ft1.tabs > .is-active::after{ transform:scaleX(1); }
@media (hover:hover) and (pointer:fine){
  #PrSecTabs .ft1.tabs > *:hover{ color:#0B0B0B !important; }
}

/* ---------- Tab content: base type ---------- */
#PrSecTabs .tab-content{ padding:28px 28px 32px !important; font-size:14px; line-height:1.7; color:#3A3A3A; }
#PrSecTabs .tab-content p{ margin:0 0 14px; max-width:78ch; }
#PrSecTabs .tab-content p:empty, #PrSecTabs .tab-content br + br{ display:none; }
#PrSecTabs .tab-content strong, #PrSecTabs .tab-content b{ color:#0B0B0B; font-weight:700; }
#PrSecTabs .tab-content a:not([class]){ color:#DE0000; text-decoration:underline; text-underline-offset:2px; }

/* Section labels inside descriptions (APPLICATIONS, FEATURES…) —
   whatever tag IOTREND used: h2–h5, or a paragraph that is only bold. */
#PrSecTabs .tab-content h2, #PrSecTabs .tab-content h3,
#PrSecTabs .tab-content h4, #PrSecTabs .tab-content h5,
#PrSecTabs .tab-content p > strong:only-child,
#PrSecTabs .tab-content p > b:only-child{
  display:block; margin:28px 0 10px; padding-left:12px; border-left:3px solid #DE0000;
  font-size:12px; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  color:#0B0B0B; line-height:1.4;
}
#PrSecTabs .tab-content h2:first-child, #PrSecTabs .tab-content h3:first-child,
#PrSecTabs .tab-content h4:first-child{ margin-top:0; }

/* Lists */
#PrSecTabs .tab-content ul, #PrSecTabs .tab-content ol{ margin:0 0 18px; padding:0 0 0 2px; list-style:none; }
#PrSecTabs .tab-content li{ position:relative; padding:4px 0 4px 20px; margin:0; }
#PrSecTabs .tab-content ul li::before{
  content:""; position:absolute; left:2px; top:13px; width:6px; height:6px; border-radius:50%; background:#DE0000;
}
#PrSecTabs .tab-content ol{ counter-reset:iot; }
#PrSecTabs .tab-content ol li::before{
  counter-increment:iot; content:counter(iot) "."; position:absolute; left:0; top:4px;
  font-size:12px; font-weight:700; color:#DE0000;
}

/* Spec tables inside descriptions — same look as the Specifications tab */
#PrSecTabs .tab-content table{
  width:100%; border-collapse:collapse; margin:6px 0 22px; font-size:13.5px;
  border:1px solid #E4E4E4; border-radius:3px; overflow:hidden;
}
#PrSecTabs .tab-content table tr{ border-bottom:1px solid #E4E4E4; }
#PrSecTabs .tab-content table tr:last-child{ border-bottom:0; }
#PrSecTabs .tab-content table tr:nth-child(odd){ background:#FAFAFA; }
#PrSecTabs .tab-content table td, #PrSecTabs .tab-content table th{
  padding:10px 14px; vertical-align:top; border:0 !important; text-align:left;
}
#PrSecTabs .tab-content table td:first-child, #PrSecTabs .tab-content table th{
  width:38%; font-size:12px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; color:#6B7680;
}
#PrSecTabs .tab-content table td:last-child{ color:#0B0B0B; font-weight:600; overflow-wrap:anywhere; }

/* Images and download buttons in descriptions */
#PrSecTabs .tab-content img{ max-width:100%; height:auto; }
#PrSecTabs .tab-content .iot-specs{ margin:0; }

/* ---------- Mobile ---------- */
@media screen and (max-width:749px){
  #PrSecTabs .ft1.tabs > *{ padding:14px 14px !important; font-size:11px !important; letter-spacing:.08em !important; }
  #PrSecTabs .ft1.tabs > *::after{ left:14px; right:14px; }
  #PrSecTabs .tab-content{ padding:20px 16px 24px !important; font-size:13.5px; }
  #PrSecTabs .tab-content table td:first-child, #PrSecTabs .tab-content table th{ width:44%; padding:9px 10px; font-size:11px; }
  #PrSecTabs .tab-content table td{ padding:9px 10px; font-size:13px; }
}

/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   HOMEPAGE HEADER DROPDOWNS (29 Sep 2026) — the white-link
   rules above target every link inside the transparent
   homepage header, which also turned the Shop Security
   dropdown and the Brands mega menu text white on a white
   panel. Dropdown panels keep the theme's dark text.
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

.template-index .header-wrap ul.ddmenu a,
.template-index .header-wrap .mgmenu a {
  color: #333333 !important;
}

.template-index .header-wrap ul.ddmenu a:hover,
.template-index .header-wrap .mgmenu a:hover {
  color: #DE0000 !important;
}

.template-index .header-wrap ul.ddmenu svg,
.template-index .header-wrap .mgmenu svg {
  fill: #333333 !important;
  stroke: none !important;
}

/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   BRANDS MEGA MENU (29 Sep 2026) — "View all brands" is the
   last item in the brands-header menu and has no logo. Style
   it as a clear red link so it reads as the way to the full
   Brands page.
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

.header-wrap .mgmenu a[href="/pages/brands"] {
  color: #DE0000 !important;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 4px;
}


/* ============================================================
   Homepage hero (hero_VCMPtV) - desktop framing
   Desktop height follows the image ratio (1721x715 = 2.407:1)
   so the banner shows the same framing as the client mockup at
   every screen width. Overrides the "Desktop height" setting.
   ============================================================ */
@media only screen and (min-width: 1024px) {
  [id$="__hero_VCMPtV"] .hero-wrapper {
    --mht: max(500px, calc(100vw / 2.1117)) !important;
  }
}


/* Hero overlay: short dark band behind the transparent header only,
   so the heading area stays bright like the client mockup. */
[id$="__hero_VCMPtV"] .overlay.top::before {
  background: linear-gradient(to bottom, rgba(0,0,0,.55) 0, rgba(0,0,0,.25) 90px, rgba(0,0,0,0) 170px) !important;
}


/* Hero buttons: larger on desktop to match the client mockup */
@media only screen and (min-width: 1024px) {
  [id$="__hero_VCMPtV"] .btn {
    font-size: clamp(14px, 1.05vw, 19px) !important;
    padding: clamp(15px, 1.2vw, 22px) clamp(22px, 1.9vw, 34px) !important;
  }
  [id$="__hero_VCMPtV"] h2.head { font-size: clamp(44px, 4.1vw, 80px) !important; line-height: 1.1 !important; }
  [id$="__hero_VCMPtV"] .hero-wrapper { padding-top: 20px !important; padding-bottom: 20px !important; }
  [id$="__text_q3KJTw"], [id$="__text_q3KJTw"] p { font-size: clamp(15px, 1.25vw, 22px) !important; }
}


/* Hero on mobile: text sits bottom-left in white over a soft
   dark gradient, so the camera, door and doorbell stay visible.
   Desktop keeps the dark text from the client mockup. */
@media only screen and (max-width: 767px) {
  [id$="__heading_PqUUH3"], [id$="__heading_nVRXgH"] { --hdcl: #ffffff !important; }
  [id$="__hero_VCMPtV"] h2.head { text-shadow: 0 2px 14px rgba(0,0,0,.45); }
  [id$="__hero_VCMPtV"] .overlay.top::before {
    background:
      linear-gradient(to top, rgba(0,0,0,.62) 0, rgba(0,0,0,.35) 30%, rgba(0,0,0,0) 55%),
      linear-gradient(to bottom, rgba(0,0,0,.45) 0, rgba(0,0,0,0) 110px) !important;
  }
}


/* Hero desktop layout v2: text block is placed from the left edge of the
   screen (6% like the client mockup), not inside the 1400px container,
   and all sizes scale with screen width so the layout stays the same
   on 1366, 1920, 2560 and ultrawide screens. */
@media only screen and (min-width: 1024px) {
  [id$="__hero_VCMPtV"] .hero-wrapper {
    max-width: none !important;
    padding-left: calc(6vw - 30px) !important;
    padding-right: 4vw !important;
    padding-top: 85px !important;
    padding-bottom: 15px !important;
  }
  [id$="__hero_VCMPtV"] .group-bk { --wd: max(560px, 40vw) !important; }
  [id$="__hero_VCMPtV"] h2.head { font-size: clamp(40px, 3.5vw, 124px) !important; }
  [id$="__text_q3KJTw"], [id$="__text_q3KJTw"] p { font-size: clamp(14px, 1.02vw, 34px) !important; }
  [id$="__hero_VCMPtV"] .btn {
    font-size: clamp(13px, 0.88vw, 28px) !important;
    padding: clamp(13px, 0.95vw, 32px) clamp(20px, 1.55vw, 52px) !important;
  }
  [id$="__hero_VCMPtV"] .btn svg, [id$="__hero_VCMPtV"] .btn .icon { width: 1.3em; height: 1.3em; }
}


/* Hero mobile height follows the 3:4 mobile image, so wider phones
   (390-767px) show the same framing as a 375px phone. */
@media only screen and (max-width: 767px) {
  [id$="__hero_VCMPtV"] .hero-wrapper { --mhtm: calc(100vw * 4 / 3) !important; }
}


/* Hero desktop: image has extra space at the top (v4_topspace, 2.1117:1),
   so the camera sits below the menu. Image v6_realtop has real photo at the top; a faded black
   shade sits behind the menu and ends before the camera. */
@media only screen and (min-width: 1024px) {
  [id$="__hero_VCMPtV"] .overlay.top::before {
    background: linear-gradient(to bottom, rgba(0,0,0,.7) 0, rgba(0,0,0,.5) 55px, rgba(0,0,0,.18) 95px, rgba(0,0,0,0) 125px) !important;
  }
}


/* Homepage transparent header: menu hover colour black instead of red
   (red was hard to see over the hero). Top-level links and header icons
   only; dropdown panels and the sticky header keep the theme colours. */
.template-index .header-wrap:not(.sticky-header) #main-nav .lvl1:hover > a,
.template-index .header-wrap:not(.sticky-header) #main-nav .lvl1 > a:hover,
.template-index .header-wrap:not(.sticky-header) #main-nav .lvl1 > a:focus-visible,
.template-index .header-wrap:not(.sticky-header) .hdicon:hover,
.template-index .header-wrap:not(.sticky-header) .hdicon:hover svg {
  color: #000000 !important;
}


/* Brands mega menu: tidy logo grid (13 brands + "View all brands").
   Theme logos are a fixed 200px box, which overlapped in 7 columns and
   made the panel scroll sideways. Grid of 7 equal columns, logos scale
   into a 150x100 box, "View all brands" sits centred on its own row. */
#main-nav li.lvl1:has(> a[href="/pages/brands"]) .mgmenu .rwcols-6 {
  display: grid !important;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  column-gap: 16px; row-gap: 22px;
  width: 100%; max-width: 1180px; margin: 0 auto;
  padding: 26px 16px 22px;
}
#main-nav li.lvl1:has(> a[href="/pages/brands"]) .mgmenu .rwcols-6 > .gitem {
  width: auto !important; padding: 0 !important; min-width: 0;
}
#main-nav li.lvl1:has(> a[href="/pages/brands"]) .mgmenu .mm-cat-img {
  width: 100% !important; max-width: 165px; height: 115px !important;
  margin: 0 auto 8px; overflow: hidden;
}
#main-nav li.lvl1:has(> a[href="/pages/brands"]) .mgmenu .mm-cat-img img {
  width: 100% !important; height: 100% !important; object-fit: cover; object-position: center;
}
#main-nav li.lvl1:has(> a[href="/pages/brands"]) .mgmenu .mcatLink {
  width: 100%; align-items: center; text-align: center;
}
#main-nav li.lvl1:has(> a[href="/pages/brands"]) .mgmenu .rwcols-6 > .gitem:last-child {
  grid-column: 1 / -1; text-align: center; justify-self: center;
}
#main-nav li.lvl1:has(> a[href="/pages/brands"]) .mgmenu { overflow-x: hidden; }


/* ==========================================================
   Quantity box: show 2-3 digit numbers in full (29 Sep)
   The general input padding (18px left/right) left only 14px
   for the number inside the 50px .qty box, so "32" showed as "3:".
   ========================================================== */
body .qty-field input.qty {
  padding-left: 4px !important;
  padding-right: 4px !important;
  min-width: 56px;
  text-align: center;
  -moz-appearance: textfield;
  appearance: textfield;
}
body .qty-field.sm input.qty { min-width: 40px; }
body .qty-field input.qty::-webkit-outer-spin-button,
body .qty-field input.qty::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }


/* ==========================================================
   Cart page: coupon box only as tall as its content (29 Sep)
   The footer row stretched the coupon box to the height of the
   totals box, which left a large empty grey area.
   ========================================================== */
@media (min-width: 768px) {
  body .cart_footer.f-row-md { align-items: flex-start; }
}


/* ==========================================================
   Product gallery: fixed square frame for every image (30 Sep)
   Tall, narrow product images (e.g. a side view 3000px high)
   made the whole slider as tall as the tallest image, which
   pushed the thumbnails and description far down the page.
   Every slide is now a square; the image fits inside it.
   ========================================================== */
body media-gallery .product-image__slider .swiper-wrapper { align-items: flex-start; }
body media-gallery .product-image__slider .swiper-slide.product-image-lg {
  aspect-ratio: 1 / 1;
  height: auto !important;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: #fff;
}
body media-gallery .product-image__slider .swiper-slide.product-image-lg > .img-wrapper { width: 100%; height: 100%; max-width: none !important; }
body media-gallery .product-image__slider .swiper-slide.product-image-lg img {
  width: 100% !important;
  height: 100% !important;
  object-fit: contain;
}


/* ==========================================================
   PageFly product layout: hidden (1 Oct 2026)
   PageFly re-publishes add its old product layout section
   (pf-2f198971) to the end of the product template. It renders
   invisible (opacity 0) but still takes ~6,000px, leaving a huge
   gap above the footer. The theme sections show the product.
   ========================================================== */
.shopify-section[id*="__pf-2f198971"] { display: none !important; }
