/* ═══════════════════════════════════════════════════════════════
   HEIGHTS TELECOM — MASTER SITE CSS  (smart-home + press-room + blog)
   Hosted on Cloudflare R2 · loaded via <link rel="stylesheet"> in
   Webflow's Page Head panel.

   Editing rules:
   · This file is the single source of truth — never paste CSS into
     Webflow panels again.
   · Rule ORDER is preserved from the original panels — do not
     reorder sections (cascade-sensitive).
   · Mobile/tablet overrides live in @media (max-width: 991px)
     blocks inside their section.

   INDEX
   01. HERO SLIDER (nested hero-slider-main sizing, hotspot clicks)
   02. NAV + TABS
   03. SWIPER NAV
   04. CONTACT FORM
   05. BLOG INLINE GALLERY (press-room/blog templates)
   06. WBD — "WE ARE BUILD DIFFERENT" SCROLL SECTION (+ mobile)
   07. PRODUCTS — bunched reveal helpers
   08. HERO ACCORDION CHEVRON
   09. SOLUTIONS SLIDER (focused-card description, icon freeze, arrows)
   10. PRESS ROOM SLIDER (focused-card behavior, arrows) (+ WBD mobile tail)
   11. MOBILE / TABLET PASS (hero, sliders, tabs, WBD type, contact form)
   12. HERO SLIDES (all 4) — mobile centered layout, 2026-09-01 (rev.2)
   13. PRODUCT TABS - CENTRE SHORT CATEGORIES (desktop), 2026-09-01
   14. HERO + PRODUCTS - MOBILE POLISH PASS, 2026-09-01
   15. HERO FULL-BLEED VIDEOS - KILL THE PILLARBOX, 2026-09-01
   ═══════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════════════════════════
   01. HERO SLIDER
   ═══════════════════════════════════════════════════════════ */

/* Fix hotspot clicks being blocked by header5_content overlay */
.header5_content { pointer-events: none; }
.header5_content > * { pointer-events: auto; }

/* Slider height fix */
.hero-slider-main.w-slider,
.hero-slider-main .w-slider-mask,
.hero-slider-main .w-slide { height: 100% !important; }
.hero-slider-main .w-slide > div {
  display: flex; flex-direction: column;
  justify-content: center; height: 100%;
}

.hero-slider-main .w-slide {
  padding-left: 20px;
  padding-right: 20px;
  box-sizing: border-box;
}
.hero-slider-main .w-slide .hero-accordion-slide-content {
  margin-left: -20px;
  margin-right: -20px;
}

/* ═══════════════════════════════════════════════════════════
   02. NAV + TABS
   ═══════════════════════════════════════════════════════════ */

.navbar1_link { position: relative; }
.navbar1_link::after {
  content: '';
  position: absolute;
  bottom: 0; left: 0;
  width: 0%; height: 2px;
  background: currentcolor;
  transition: width 0.3s ease;
}
.navbar1_link:hover::after { width: 100%; }

.tab2_tab-link::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 0%;
  height: 2px;
  background: linear-gradient(to right, #FFFFFF 0%, #2865FF 22%, #2865FF 80%, #FFFFFF 100%);
  transition: width 0.35s ease;
}
.tab2_tab-link.w--current::after { width: 100%; }

/* ═══════════════════════════════════════════════════════════
   03. SWIPER NAV
   ═══════════════════════════════════════════════════════════ */

.swiper-button-next,
.swiper-button-prev {
  transition: opacity 0.2s ease !important;
}

/* ═══════════════════════════════════════════════════════════
   04. CONTACT FORM
   ═══════════════════════════════════════════════════════════ */

.form_input {
  transition: box-shadow 0.3s ease, background 0.3s ease;
}
.form_input:focus,
.form_input:focus-visible {
  outline: none;
}

/* ═══════════════════════════════════════════════════════════
   05. BLOG INLINE GALLERY (press-room/blog templates)
   ═══════════════════════════════════════════════════════════ */

.inline-gallery-card {
  margin: 2.5rem 0;
  overflow: hidden;
  background: #fff;
}

.inline-gallery-card__image-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  cursor: pointer;
}

.inline-gallery-card__image-wrap.is-single { cursor: default; }

.inline-gallery-card__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.4s ease;
}

.inline-gallery-card__image-wrap:not(.is-single):hover .inline-gallery-card__image {
  transform: scale(1.03);
}

.inline-gallery-card__watch-btn {
  position: absolute;
  left: 16px;
  bottom: 16px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 8px 16px 8px 8px;
  background: rgba(19, 12, 162, 0.92);
  color: #fff;
  border: none;
  border-radius: 999px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  backdrop-filter: blur(4px);
  transition: background 0.2s ease, transform 0.2s ease;
}

.inline-gallery-card__watch-btn:hover {
  background: rgba(40, 101, 255, 0.95);
  transform: translateY(-1px);
}

.inline-gallery-card__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 28px;
  height: 28px;
  padding: 0 8px;
  background: #fff;
  color: #130CA2;
  border-radius: 999px;
  font-weight: 700;
  font-size: 13px;
}

.inline-gallery-card__caption {
  padding: 14px 18px 16px;
  font-size: 15px;
  line-height: 1.5;
  color: #4a5568;
}

.inline-gallery-card__caption-title {
  font-weight: 700;
  color: #1a202c;
  margin-right: 6px;
}

.inline-gallery-card__caption:empty { display: none; }

#gallery-source { display: none !important; }

/* ═══════════════════════════════════════════════════════════
   06. WBD — "WE ARE BUILD DIFFERENT" SCROLL SECTION
   ═══════════════════════════════════════════════════════════ */

.wbd_section { position: relative; }
.wbd_sticky { overflow: hidden; }

.wbd_left {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.1em;
  align-self: start;
}

.wbd_left::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0; right: 0;
  width: 45%;
  background: linear-gradient(to right, rgba(255,255,255,0) 0%, #FFFFFF 92%);
  opacity: 0;
  transition: opacity 0.5s ease;
  pointer-events: none;
  z-index: 3;
}
.wbd-bullets-active .wbd_left::after { opacity: 1; }

.wbd_word {
  margin: 0 0 -0.12em;
  padding-bottom: 0.12em; /* FIX: paint room for descenders (g/p/y) during background-clip:text sweep */
  line-height: 1.05;
  will-change: opacity, transform;
  position: relative;
  z-index: 1;
}

.wbd_word-base-1,
.wbd_word-base-2 { opacity: 1; }

.wbd_word-step-1,
.wbd_word-step-2,
.wbd_word-step-3 {
  opacity: 0;
  transform: translateY(40px);
}

.wbd_word.is-sweeping {
  background: linear-gradient(90deg, #2865FF 0%, #2865FF 35%, #1ECBE9 50%, #2865FF 65%, #2865FF 100%);
  background-size: 250% 100%;
  background-position: 100% 0;
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: wbd-sweep 1.2s ease-out forwards;
}
@keyframes wbd-sweep {
  0%   { background-position: 100% 0; }
  100% { background-position: -50% 0; }
}
.wbd_word.is-swept {
  background: none;
  -webkit-text-fill-color: initial;
  color: #2865FF;
}

.wbd_right { position: relative; }

.wbd_feature {
  position: relative;
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: 20px;
  opacity: 0;
  transform: translateY(40px);
  will-change: opacity, transform;
}

.wbd_feature_bullet {
  width: 14px; height: 14px;
  border-radius: 50%;
  background: #7F94B3;
  margin-top: 0.5em;
  position: relative;
  z-index: 2;
}

.wbd_feature:not(:last-child)::before {
  content: "";
  position: absolute;
  top: calc(0.5em + 14px + 8px);
  bottom: -28px;
  left: 7px;
  width: 1px;
  background: #C8D2DD;
  transform-origin: top;
  transform: scaleY(0);
  transition: transform 0.6s ease 0.2s;
  z-index: 1;
}
.wbd_feature.is-revealed:not(:last-child)::before { transform: scaleY(1); }

.wbd_feature_content { display: flex; flex-direction: column; gap: 12px; }
.wbd_feature_title { margin: 0; font-weight: 700; color: #69696A; }
.wbd_feature_text  { margin: 0; color: #7F94B3; line-height: 1.5; }

@keyframes wbd-bullet-pulse {
  0%   { transform: scale(1);    box-shadow: 0 0 0 0  rgba(127, 148, 179, 0.55); }
  50%  { transform: scale(1.35); box-shadow: 0 0 0 12px rgba(127, 148, 179, 0); }
  100% { transform: scale(1);    box-shadow: 0 0 0 0  rgba(127, 148, 179, 0); }
}
.wbd_feature_bullet.is-pulsing { animation: wbd-bullet-pulse 0.9s ease-out; }

/* ── DESKTOP CAROUSEL MODE (class added by JS) ── */
.wbd-carousel .wbd_left { align-self: center; }      /* FIX 1: re-centre the title */

.wbd-carousel .wbd_right {
  overflow: hidden;
  /* FIX: widen the clip box left so the bullet pulse ring isn't cut — content position unchanged */
  padding-left: 20px;
  margin-left: -20px;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 30%, #000 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 30%, #000 100%);
  visibility: hidden;
}
.wbd-carousel.wbd-ready .wbd_right { visibility: visible; }

.wbd-carousel .wbd_features_track {
  position: absolute;
  top: 0; left: 20px; right: 0; /* FIX: 20px in from the widened clip edge (see .wbd_right) — absolute children ignore padding */
  will-change: transform;
}

/* FIX 2: continuous timeline spine the bullets ride on */
.wbd-carousel .wbd_features_spine {
  position: absolute;
  left: 7px;
  width: 1px;
  background: #C8D2DD;
  z-index: 0;
}

.wbd-carousel .wbd_feature {
  position: absolute;
  left: 0; right: 0;
  opacity: 1;
  transform: none;
  z-index: 1;                  /* dots/content sit above the spine */
}
.wbd-carousel .wbd_feature::before { display: none; }

/* ── MOBILE / TABLET (≤991px) ── */
@media (max-width: 991px) {
  .wbd_section { height: auto; }
  .wbd_sticky { position: static; height: auto; padding: 60px 0; }
  .wbd_grid { grid-template-columns: 1fr; gap: 40px; }
  .wbd_right { padding-top: 0; }
  .wbd_word-step-1, .wbd_word-step-2, .wbd_word-step-3, .wbd_feature {
    transition: opacity 0.6s ease, transform 0.6s ease;
  }
  .wbd_word-step-1.is-mobile-visible, .wbd_word-step-2.is-mobile-visible,
  .wbd_word-step-3.is-mobile-visible, .wbd_feature.is-mobile-visible {
    opacity: 1; transform: translateY(0);
  }
}

/* ═══════════════════════════════════════════════════════════
   07. PRODUCTS — bunched reveal helpers
   ═══════════════════════════════════════════════════════════ */

.section_gallery19 .swiper-container.is-pre-reveal .swiper-slide {
  transition: none !important;
}

.section_gallery19 .swiper-slide [class*="text"],
.section_gallery19 .swiper-slide h1,
.section_gallery19 .swiper-slide h2,
.section_gallery19 .swiper-slide h3,
.section_gallery19 .swiper-slide h4,
.section_gallery19 .swiper-slide p {
  will-change: opacity;
}

/* ── Card-wide hover: the "See more" button fills when hovering ANYWHERE
   on the product card (whole card is a link), not just the button ── */
.slider-btn,
.slider-btn * {
  transition: background-color 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}
.section_gallery19 .swiper-slide:not(.solutions):hover .slider-btn {
  background-color: #2865FF;
  border-color: #2865FF;
  color: #fff;
}
.section_gallery19 .swiper-slide:not(.solutions):hover .slider-btn * {
  color: #fff;
}

/* ═══════════════════════════════════════════════════════════
   08. HERO ACCORDION CHEVRON — smooth 180° rotate on open/close
   ═══════════════════════════════════════════════════════════ */

#accordion-1 .chevron-hero,
#accordion-2 .chevron-hero,
#accordion-3 .chevron-hero {
  transform: rotate(0deg);
  transition: transform 0.3s ease !important;
  transform-origin: center;
  transform-box: fill-box;
}
#accordion-1:has(.hero-accordion-answer:not(.closed)) .chevron-hero,
#accordion-2:has(.hero-accordion-answer:not(.closed)) .chevron-hero,
#accordion-3:has(.hero-accordion-answer:not(.closed)) .chevron-hero {
  transform: rotate(180deg);
}

/* ═══════════════════════════════════════════════════════════
   09. SOLUTIONS SLIDER — description on focused card only
   (paragraph renders once the CMS description field is filled;
    Webflow hides it automatically while the field is empty)
   ═══════════════════════════════════════════════════════════ */

/* The paragraph is fully collapsed (not just invisible) on non-focused
   cards so they shrink to icon + title, and grows open smoothly when a
   card gains focus. */
.swiper-slide.solutions p {
  opacity: 0;
  transform: translateY(8px);
  max-height: 0;
  overflow: hidden;
  margin-top: 0;
  margin-bottom: 0;
  transition: opacity 0.3s ease, transform 0.3s ease, max-height 0.4s ease, margin 0.4s ease;
}
.swiper-slide.solutions.swiper-slide-active p {
  opacity: 1;
  transform: translateY(0);
  max-height: 220px;
  margin-top: 8px;
  margin-bottom: 8px;
  transition-delay: 0.1s;
}

/* ── Solutions icon freeze — animated WebP plays only on the focused card.
   JS overlays a first-frame canvas snapshot per card; the live (animating)
   image is revealed only on the active slide. The .has-freeze guard means
   the real image is never hidden before its snapshot has drawn. ── */
.slider-img-wrap-solutions { position: relative; }
.sol-freeze-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.swiper-slide.solutions.swiper-slide-active .sol-freeze-canvas { display: none; }
.swiper-slide.solutions:not(.swiper-slide-active) .slider-img-wrap-solutions.has-freeze .slider-image {
  visibility: hidden;
}

/* ── Slider arrows — must sit above the full-width cards (partial edge cards
   were covering them), with a backdrop so they read on white cards ── */
.swiper_component .swiper-button-prev,
.swiper_component .swiper-button-next {
  z-index: 20 !important;
  background: rgba(255, 255, 255, 0.92);
  border-radius: 50%;
  box-shadow: 0 2px 10px rgba(19, 12, 162, 0.14);
}

/* ═══════════════════════════════════════════════════════════
   10. PRESS ROOM SLIDER — focused-card behavior
   (base card look — bg, radius, shadow, padding — is styled on
    .press-card in the Designer; this only drives focus states)
   ═══════════════════════════════════════════════════════════ */

/* Description: 2 clamped lines on side cards, expands on the focused card */
.swiper-slide.press-card .press-card-desc {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  max-height: 3.2em;
  transition: max-height 0.4s ease;
}
.swiper-slide.press-card.swiper-slide-active .press-card-desc {
  -webkit-line-clamp: 8;
  max-height: 13em;
}

/* Title (.press-card-title): 2 lines on side cards, up to 4 when focused,
   so long titles can't blow up the card proportions */
.swiper-slide.press-card .press-card-title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  max-height: 2.9em;
  transition: max-height 0.4s ease;
}
.swiper-slide.press-card.swiper-slide-active .press-card-title {
  -webkit-line-clamp: 4;
  max-height: 5.8em;
}

/* CMS rich-text short description (.press-room-shortdesc): JS module 11 caps it
   at ~260 chars; this clamps 2 lines on side cards, up to 8 when focused */
.swiper-slide.press-card .press-room-shortdesc,
.swiper-slide.press-card .press-room-shortdesc p { margin: 0; }
.swiper-slide.press-card .press-room-shortdesc {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  max-height: 3.2em;
  transition: max-height 0.4s ease;
}
.swiper-slide.press-card.swiper-slide-active .press-room-shortdesc {
  -webkit-line-clamp: 8;
  max-height: 13em;
}

/* Read More: collapsed out of the layout on side cards, revealed on focus */
.swiper-slide.press-card .press-card-link {
  display: block;
  opacity: 0;
  transform: translateY(6px);
  max-height: 0;
  overflow: hidden;
  margin-top: 0;
  transition: opacity 0.3s ease, transform 0.3s ease, max-height 0.4s ease, margin 0.4s ease;
}
.swiper-slide.press-card.swiper-slide-active .press-card-link {
  opacity: 1;
  transform: translateY(0);
  max-height: 3em;
  margin-top: 12px;
  transition-delay: 0.1s;
}

/* Focused card enlarged; side cards slightly scaled down.
   max-width:none guards against Designer width caps on the card class —
   Swiper computes slide widths itself and a CSS cap breaks its layout. */
.swiper-slide.press-card {
  max-width: none !important;
  height: auto !important;  /* undo Swiper's height:100% so side cards hug their content */
  min-height: 0 !important; /* beat any Designer min-height that inflates the card */
  transform: scale(0.94);
  box-shadow: 0 8px 24px rgba(19, 12, 162, 0.14); /* side cards get a visible resting shadow */
  transition: box-shadow 0.35s ease, transform 0.35s ease;
}
.swiper-slide.press-card .pressroom-post-bottom {
  height: auto !important;
  min-height: 0 !important; /* same guard on the text wrapper */
}
.swiper-slide.press-card.swiper-slide-active {
  transform: scale(1);
  box-shadow: 0 16px 44px rgba(19, 12, 162, 0.14);
}

/* Contained slider: clip the looping neighbours at the SIDES only — card
   shadows flow past the top/bottom instead of being cut above the dots */
.swiper-container.press-swiper {
  overflow: visible !important;
  clip-path: inset(-80px 0 -120px 0);
}

/* Slider track narrower than its wrapper: edge cards end before the arrows */
.press_swiper_component .swiper-container.press-swiper {
  width: calc(100% - 176px);
  margin-left: auto;
  margin-right: auto;
}

/* No scroll-anchoring bounce when card heights animate on focus change */
.press_swiper_component,
.swiper-container.press-swiper {
  overflow-anchor: none;
}

/* Default arrow styling so the bare prev/next divs render out of the box.
   Restyle freely in the Designer — these only apply what's not set there. */
.press_swiper_component { position: relative; }
.press_swiper_component .swiper-button-prev,
.press_swiper_component .swiper-button-next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 2px 10px rgba(19, 12, 162, 0.14);
  cursor: pointer;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
}
.press_swiper_component .swiper-button-prev { left: 16px; }
.press_swiper_component .swiper-button-next { right: 16px; }
.press_swiper_component .swiper-button-prev::after,
.press_swiper_component .swiper-button-next::after {
  content: "";
  width: 10px;
  height: 10px;
  border-right: 2px solid #2865FF;
  border-bottom: 2px solid #2865FF;
}
.press_swiper_component .swiper-button-prev::after { transform: rotate(135deg); margin-left: 4px; }
.press_swiper_component .swiper-button-next::after { transform: rotate(-45deg); margin-right: 4px; }

/* ── WBD RESPONSIVE TAIL (tablet & below) — kept last, original order ── */
@media (max-width: 991px) {
  .wbd_left::after { display: none !important; }
}

/* ═══════════════════════════════════════════════════════════
   11. MOBILE / TABLET PASS (≤991px tablet, ≤767px phone)
   Added 2026-08-26. Breakpoint widths mirror Webflow's own
   .page-padding steps (2.5rem tablet / 1.25rem phone) so the
   slider bleeds land exactly on the viewport edge.
   ═══════════════════════════════════════════════════════════ */

@media (max-width: 991px) {

  /* Safety net: nothing below may widen the page (was 448px on phone) */
  .page-wrapper { overflow-x: clip; }

  /* ── HERO — every slide exactly one viewport tall.
     Slides 3/4 wrap their content in a 100svh box PLUS the section's
     vertical padding, which stretched the slider to 940px while slides
     1/2 stayed at 844px (white band under them, dots floating in it). */
  .section_header5 .header5_content { min-height: 100svh; max-height: none; }
  .section_header5 .padding-section-medium { padding-top: 0; padding-bottom: 0; }
  .section_header5 .hero-slider-content-wrap { height: 100svh; }
  /* H1 kept its desktop 70px line-height at a 40px font (2-line titles
     were 140px tall with big gaps) */
  .section_header5 .heading-style-h1 { line-height: 1.1; }
  /* Slide 2 modem: the desktop 15% corner overhang put it under the dots
     and past the slide edge on phones — smaller, flush right, above dots */
  .section_header5 .modems-img { width: 68%; bottom: 72px; transform: none; }
  /* WBD feature titles: fixed 44px line-height at 22px font */
  .wbd_feature_title { line-height: 1.25; }

  /* WBD connector line — the vertical line between bullets was keyed to
     .is-revealed, which only the DESKTOP scroll module adds. The mobile
     branch of module 07 adds .is-mobile-visible instead, so the line never
     appeared on phones. (Pseudo-element — can't be styled in the Designer.) */
  .wbd_feature.is-mobile-visible:not(:last-child)::before { transform: scaleY(1); }

  /* SOLUTIONS focused card — the 220px description cap (section 09) is fine
     in a wide desktop card but cut sentences mid-word in a 218px-wide phone
     column. Raised, not removed, so the open/close transition still animates. */
  .swiper-slide.solutions.swiper-slide-active p { max-height: 600px; }

  /* ── PRODUCTS + SOLUTIONS + PRESS ROOM sliders.
     Designer's .swiper-slide{max-width:300px} fought Swiper's inline
     width and threw the active card to x=-80. Containers bleed to the
     viewport edge and clip there (solutions' visible overflow was
     pushing the page to 6850px wide). Arrows go — touch swipes, and
     the peeking side cards signal it. */
  .section_gallery19 .swiper-slide { max-width: none !important; }
  .section_gallery19 .swiper-container,
  .press_swiper_component .swiper-container.press-swiper {
    /* These MUST clip, not overflow. Letting them overflow (clip-path alone)
       left the parent section a ~9,400px-wide scroll box, and iOS Safari pans
       overflow:hidden boxes by touch — so a vertical swipe anywhere over
       Solutions drove that box instead of the page, and scrolling died.

       The vertical room the cards need (the active solutions icon is pulled
       110px above its card, press cards cast a 44px shadow) comes from
       padding plus an equal negative margin: the box grows to contain the
       overhang without moving anything or letting it escape. */
    overflow: hidden !important;
    clip-path: none !important;
    margin-left: -2.5rem;
    margin-right: -2.5rem;
    width: calc(100% + 5rem) !important;
  }
  .section_gallery19 .swiper-container {
    padding-top: 130px;
    margin-top: -130px;
    padding-bottom: 60px;
    margin-bottom: -60px;
  }
  .press_swiper_component .swiper-container.press-swiper {
    padding-top: 80px;
    margin-top: -80px;
    padding-bottom: 120px;
    margin-bottom: -120px;
  }
  .section_gallery19 .swiper-button-prev,
  .section_gallery19 .swiper-button-next,
  .press_swiper_component .swiper-button-prev,
  .press_swiper_component .swiper-button-next { display: none !important; }
}

@media (max-width: 767px) {

  /* Slider bleed follows the phone page-padding step */
  .section_gallery19 .swiper-container,
  .press_swiper_component .swiper-container.press-swiper {
    margin-left: -1.25rem;
    margin-right: -1.25rem;
    width: calc(100% + 2.5rem) !important;
  }

  /* Tab menus (products + press room): all four tabs fit at 390px
     instead of silently scrolling behind a hidden scrollbar */
  .tab2_tabs-menu { gap: 12px; padding-left: 12px; padding-right: 12px; }

  /* WBD type scale for a 350px column */
  .wbd_word { font-size: 34px; }
  .wbd_feature_title { font-size: 22px; }
  .wbd_feature_text { font-size: 16px; }
  .wbd_right { gap: 28px; }

  /* CONTACT FORM — single column (was 1fr 1fr: left column collapsed to
     65px, right column overflowed the viewport). Order rewritten so the
     stack reads Name → Phone → Email → Company → Service → Title →
     Message → Submit instead of alternating left/right cells. */
  .contact2_form { grid-template-columns: 1fr; }
  .contact2_form > :nth-child(1) { order: 1; }
  .contact2_form > :nth-child(3) { order: 2; }
  .contact2_form > :nth-child(5) { order: 3; }
  .contact2_form > :nth-child(7) { order: 4; }
  .contact2_form > :nth-child(2) { order: 5; }
  .contact2_form > :nth-child(4) { order: 6; }
  .contact2_form > :nth-child(6) { order: 7; }
  .contact2_form > :nth-child(8) { order: 8; }
}

/* ═══════════════════════════════════════════════════════════
   12. SLIDER FIRST-PAINT (all breakpoints)
   Added 2026-08-26. Before Swiper runs, the CMS list renders as a
   raw stack of items — the "mess" visible on a slow connection.
   Sliders start transparent and fade in when Swiper adds its
   .swiper-initialized class.

   The animation is a self-heal: if Swiper never initialises (JS
   blocked, CDN down), the keyframe reveals the content anyway at
   6s, so the page can never end up permanently blank.
   ═══════════════════════════════════════════════════════════ */

.section_gallery19 .swiper-container,
.swiper-container.press-swiper {
  opacity: 0;
  animation: sh-slider-failsafe 0.3s ease 6s forwards;
}
.section_gallery19 .swiper-container.swiper-initialized,
.swiper-container.press-swiper.swiper-initialized {
  opacity: 1;
  animation: none;
  transition: opacity 0.35s ease;
}
@keyframes sh-slider-failsafe { to { opacity: 1; } }


/* ═══════════════════════════════════════════════════════════
   13. SLIDER TOUCH BEHAVIOUR (all breakpoints)
   Added 2026-08-26. Swiper 11's own stylesheet puts
   touch-action:pan-y on ".swiper", but this site's markup uses
   the Swiper 6 name ".swiper-container", so that rule never
   matched and the containers computed touch-action:auto.

   With auto, the browser can't tell a vertical swipe from a
   horizontal one and lets Swiper claim the gesture — so dragging
   up/down over a slider stopped the page scrolling. pan-y hands
   vertical gestures back to the browser and leaves horizontal
   ones to Swiper.
   ═══════════════════════════════════════════════════════════ */

.swiper-container,
.swiper-container .swiper-wrapper {
  touch-action: pan-y;
}


/* ----
   12. HERO SLIDES (all 4) — mobile centered layout, 2026-09-01 (rev.2)
   ----
   Client wants all four hero slides (Tailor Made, WiFi 7, WiFi 8,
   prpl) to use the same mobile pattern: centered heading+copy near
   the top, product graphic large below.

   IMPORTANT: .hero-slide2-video is a SHARED Webflow style class
   reused on 3 different slides (Tailor Made, WiFi 8, prpl) — it is
   NOT unique to one slide. An earlier revision scoped rules via
   :has(.hero-slide2-video) which accidentally applied to all three
   at once, inflating their content past 100svh and pushing the
   slider's nav dots below the visible blue area. Fixed by scoping
   every rule via each slide's actual unique marker instead:
     - Tailor Made -> .code-embed-2
     - WiFi 7      -> .modems-img
     - WiFi 8      -> .slide-3-content
     - prpl        -> .slide-4-content
   The max-height/overflow safety net below is a second line of
   defense so no single slide's content can ever inflate the shared
   slider height again. */
.hero-slide-new:has(.code-embed-2) .heading-style-h1 { text-transform: uppercase; }

@media (max-width: 991px) {
  /* Safety net: no slide's content may exceed one screen, or the
     shared slider height grows and pushes the nav dots below the
     visible background on every slide (not just the offending one). */
  .section_header5 .header5_content { max-height: 100svh; overflow: hidden; }

  .hero-slide-new:has(.code-embed-2) .header5_content,
  .hero-slide-new:has(.modems-img) .header5_content,
  .hero-slide-new:has(.slide-3-content) .header5_content,
  .hero-slide-new:has(.slide-4-content) .header5_content {
    flex-direction: column;
    justify-content: flex-start;
    align-items: center;
    text-align: center;
  }
  /* WiFi 8 and prpl route their text through an extra
     .hero-slider-content-wrap layer that isn't present on the other
     two slides; it defaults to justify-content:center, which fights
     the padding-top below. Override it so all four slides align the
     same way. */
  .hero-slide-new:has(.slide-3-content) .hero-slider-content-wrap,
  .hero-slide-new:has(.slide-4-content) .hero-slider-content-wrap {
    justify-content: flex-start;
  }
  .hero-slide-new:has(.code-embed-2) .max-width-medium,
  .hero-slide-new:has(.modems-img) .max-width-medium,
  .hero-slide-new:has(.slide-3-content) .max-width-medium,
  .hero-slide-new:has(.slide-4-content) .max-width-medium {
    max-width: 100%;
    padding-top: 9svh;
  }
  .hero-slide-new:has(.code-embed-2) .heading-style-h1,
  .hero-slide-new:has(.modems-img) .heading-style-h1,
  .hero-slide-new:has(.slide-3-content) .heading-style-h1,
  .hero-slide-new:has(.slide-4-content) .heading-style-h1 {
    font-size: 36px; line-height: 1.15; margin-bottom: 12px;
  }
  .hero-slide-new:has(.code-embed-2) .text-size-medium-2,
  .hero-slide-new:has(.modems-img) .text-size-medium-2,
  .hero-slide-new:has(.slide-3-content) .text-size-medium-2,
  .hero-slide-new:has(.slide-4-content) .text-size-medium-2 {
    font-size: 17px; line-height: 1.4; max-width: 34ch; margin: 0 auto;
  }

  /* Tailor Made product video. mix-blend-mode:screen hides the black
     background, so enlarging is free visually — but the product
     itself sits right-of-center within its own 880x454 frame, so the
     left offset below is tuned (not simply centered) to keep the
     wood panel from clipping off the right edge. */
  .hero-slide-new:has(.code-embed-2) .code-embed-2 {
    width: 155%; left: -39%; right: auto; top: 26%; bottom: auto; aspect-ratio: 880 / 454;
  }

  /* WiFi 8 (robot) and prpl (cube) backgrounds are 1920x1080 videos.
     Their existing wrapper was a small, oddly cropped box (WiFi 8) or
     a full-bleed stretch that squeezed the whole 16:9 frame into a
     very tall narrow box (prpl), shrinking the subject drastically.
     Both get a properly aspect-ratio'd, enlarged, bottom-anchored box
     instead; left offsets are tuned per-video to keep the subject
     (robot / cube) centered rather than cropped. */
  .hero-slide-new:has(.slide-3-content) .hero-video-absolute {
    width: 190%; left: -73%; right: auto; top: auto; bottom: 3svh; height: auto; aspect-ratio: 16 / 9;
  }
  .hero-slide-new:has(.slide-4-content) .hero-video-absolute {
    width: 190%; left: -92%; right: auto; top: auto; bottom: 3svh; height: auto; aspect-ratio: 16 / 9;
  }
}


/* ----
/* ----
   13. PRODUCT TABS - SHORT CATEGORIES  [SUPERSEDED 2026-09-01]
   ----
   This section used to centre the whole group of cards as a block
   (justify-content: center on the wrapper). That was the wrong reading of the
   brief: the client wants ONE product dead centre with any others flanking it,
   not the group centred. Handled in JS instead - short desktop sets now init
   with slidesPerView:"auto" so Swiper measures the real card widths and its
   own centeredSlides lands the active card exactly on the container centre.
   Rules removed here because justify-content would fight Swiper transforms. */


/* ----
   14. HERO + PRODUCTS - MOBILE POLISH PASS, 2026-09-01
   ---- */

@media (max-width: 991px) {
  /* Tailor Made and WiFi 7 sat too high: heading pinned near the nav with a
     large dead area under the product. Drop the copy and lift the product so
     the pair reads as one centred composition. WiFi 8 / prpl already fill the
     frame and keep their existing 9svh. */
  .hero-slide-new:has(.code-embed-2) .max-width-medium,
  .hero-slide-new:has(.modems-img) .max-width-medium {
    padding-top: 24svh;
  }
  .hero-slide-new:has(.code-embed-2) .code-embed-2 {
    top: 43%;
  }
  .hero-slide-new:has(.modems-img) .modems-img {
    bottom: 16svh;
  }

  /* WiFi 8 / prpl: the 3svh bottom offset exposed a dark strip under the
     video, since on those slides the video IS the background. Flush to base. */
  .hero-slide-new:has(.slide-3-content) .hero-video-absolute,
  .hero-slide-new:has(.slide-4-content) .hero-video-absolute {
    bottom: 0;
  }
}

/* Two glows behind the product cards. Every tab carries one .slider-gradient-bg
   on .swiper_component; the Gateways tab has a SECOND one misplaced inside its
   .swiper-container, so both render and overlap. Suppress any that sit inside a
   swiper container - verified no correctly-placed one ever does.
   NOTE: the real fix is to delete that stray div in the Designer; this is a
   safety net so it cannot show up again. */
.section_gallery19 .swiper-container .slider-gradient-bg {
  display: none;
}


/* ----
   15. HERO FULL-BLEED VIDEOS - KILL THE PILLARBOX, 2026-09-01
   ----
   A dark strip showed down the right edge of the WiFi 8 and prpl slides.
   It is NOT baked into the mp4: both videos are 1920x1080 (ratio 1.778) but
   their box is the full slide, e.g. 1905x1054 (ratio 1.807). With
   object-fit: contain the video fits by height and renders 1874 wide, leaving
   ~31px of empty box split 16px each side. Only the right side reads as a
   black strip because the left sits under the blue gradient behind the copy.
   cover fills the width instead, cropping ~18px vertically (9px top/bottom),
   which is imperceptible on these soft renders. */

.hero-slide-new:has(.slide-3-content) .hero-video-absolute video,
.hero-slide-new:has(.slide-4-content) .hero-video-absolute video {
  object-fit: cover;
}


/* ═══════════════════════════════════════════════════════════════
   PRESS ROOM - TAB MENU TAP FIX (2026-09-02)
   .press-swiper uses margin-top:-80px + padding-top:80px for card
   shadow breathing room; that transparent strip overlays the tabs
   menu and swallowed taps (News/Events/Articles unclickable on
   phones). Lift the menus above the slider so taps land.
   ═══════════════════════════════════════════════════════════════ */

.tab2_tabs-menu { position: relative; z-index: 5; }


/* ═══════════════════════════════════════════════════════════════
   HERO SLIDES - MOBILE IMAGE SCALE (2026-09-02, v2)
   Per the designer mobile mocks: the WiFi7 product cluster
   (.modems-img) and the WiFi8 robot video rendered too small on
   phones. Scale near-full-bleed, re-anchor bottom-center.
   v2: the robot rule is scoped to .slide-3-content so the prpl
   slide (.hero-video-absolute.full) keeps its Designer styles,
   and the offset uses left:calc() instead of transform - the
   videos rely on mix-blend-mode:screen to melt their black
   frames into the gradient, and a transform on the wrapper
   creates a stacking context that isolates (breaks) the blend.
   The robot sits at ~65% of its video frame, so the -126vw
   (= 72% of 175vw) offset centers the robot, not the frame.
   Desktop and tablet are untouched.
   ═══════════════════════════════════════════════════════════════ */

@media (max-width: 767px) {
  .modems-img {
    width: 125vw !important;
    max-width: none !important;
    left: 50% !important;
    right: auto !important;
    top: auto !important;
    bottom: 4vh !important;
    transform: translateX(-50%) !important;
  }
  .slide-3-content .hero-video-absolute {
    width: 175vw !important;
    left: calc(50% - 126vw) !important;
    right: auto !important;
    top: auto !important;
    bottom: -4vh !important; /* robot stays anchored to the page bottom */
  }
  /* WiFi8 slide (3rd) only: drop the text block ~10vh so it sits closer
     to the bottom-anchored robot and the frame reads balanced. Scoped by
     child index because .hero-slider-content-wrap is shared with the
     prpl slide (2026-09-02). */
  .w-slider-mask .w-slide:nth-child(3) .hero-slider-content-wrap {
    margin-top: 10vh !important;
  }
}


/* ═══════════════════════════════════════════════════════════════
   PRODUCTS + SOLUTIONS - MOBILE SLIDER ARROWS (2026-09-02)
   Designer request: on phones it was not obvious the sliders scroll.
   The prev/next buttons already exist in every .swiper_component and
   are already wired into Swiper by JS module 02 - the Designer simply
   hides them below 768px and offsets them 40px outward via transform
   for the desktop look. Here we re-show them on phones as bare blue
   chevrons (the inline SVGs stroke with currentColor) pinned inside
   the component edges. Scoped to .swiper_component, so the press-room
   slider (.press_swiper_component) and desktop are untouched.
   ═══════════════════════════════════════════════════════════════ */

@media (max-width: 767px) {
  .swiper_component .swiper-button-prev,
  .swiper_component .swiper-button-next {
    display: flex !important;
    width: 32px !important;
    height: 32px !important;
    background: transparent !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    color: #0082f3 !important;
    z-index: 20;
    transform: none !important; /* Designer transform pushes them off-screen at this width */
  }
  .swiper_component .swiper-button-prev { left: 0 !important; }
  .swiper_component .swiper-button-next { right: 0 !important; left: auto !important; }
  .swiper_component .swiper-button-prev svg,
  .swiper_component .swiper-button-next svg { width: 18px !important; height: 18px !important; }

  /* Solutions cards are much taller than product cards on phones and the
     Designer pins the arrows at a fixed desktop top of 210px, which sits
     near the icon. 54% tracks the card centre of the solutions block. */
  .swiper_component:has(.swiper-slide.solutions) .swiper-button-prev,
  .swiper_component:has(.swiper-slide.solutions) .swiper-button-next {
    top: 54% !important;
    margin-top: -16px !important;
  }
}
