/* ==========================================================================
   Duvaltex — brand page styles (scaffolding)
   --------------------------------------------------------------------------
   Scoped under `#duvaltex-page` / `.duvaltex`. FLUID-FIRST like Storm Audio
   and Moovia: one clamp() type + space scale from ~360px to ~1600px — reach
   for the tokens before writing a one-off px value or @media query.

   Tokens:
     --dx-step--1 … --dx-step-6      fluid font sizes (step-0 = body)
     --dx-space-3xs … --dx-space-2xl fluid spacing
     --dx-gutter                     fluid page side-gutter
     --dx-shell-max                  1024px content column
     --dx-header-shell               966px — the Elementor header's INNER
                                     content column (measured live); use for
                                     anything that must sit on the header line
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */
#duvaltex-page {
  /* — Fluid TYPE scale (≈1.25 ratio; min @360px viewport, max @1600px) — */
  --dx-step--1: clamp(0.80rem, 0.76rem + 0.18vw, 0.94rem);
  --dx-step-0:  clamp(1.00rem, 0.94rem + 0.27vw, 1.18rem);   /* body */
  --dx-step-1:  clamp(1.20rem, 1.08rem + 0.55vw, 1.55rem);
  --dx-step-2:  clamp(1.44rem, 1.22rem + 0.98vw, 2.05rem);
  --dx-step-3:  clamp(1.73rem, 1.37rem + 1.60vw, 2.70rem);
  --dx-step-4:  clamp(2.07rem, 1.50rem + 2.55vw, 3.55rem);
  --dx-step-5:  clamp(2.49rem, 1.62rem + 3.85vw, 4.70rem);
  --dx-step-6:  clamp(2.99rem, 1.55rem + 6.40vw, 6.50rem);   /* hero display */

  /* — Fluid SPACE scale — */
  --dx-space-3xs: clamp(0.25rem, 0.23rem + 0.09vw, 0.31rem);
  --dx-space-2xs: clamp(0.50rem, 0.46rem + 0.18vw, 0.63rem);
  --dx-space-xs:  clamp(0.75rem, 0.69rem + 0.27vw, 0.94rem);
  --dx-space-s:   clamp(1.00rem, 0.91rem + 0.36vw, 1.25rem);
  --dx-space-m:   clamp(1.50rem, 1.24rem + 1.16vw, 2.50rem);
  --dx-space-l:   clamp(2.00rem, 1.48rem + 2.32vw, 4.00rem);
  --dx-space-xl:  clamp(3.00rem, 1.96rem + 4.64vw, 7.00rem);
  --dx-space-2xl: clamp(4.00rem, 2.43rem + 6.96vw, 10.00rem);

  /* — Containers — */
  --dx-shell-max: 1024px;
  --dx-header-shell: 966px;      /* the header's inner column (measured live) */
  --dx-gutter: clamp(1rem, 0.4rem + 3vw, 4rem);

  /* — Palette — the page is LIGHT in essence (every section is white or
     #f5f4f6), so the backdrop is white too: nothing dark can peek through
     sub-pixel gaps, and the skip link inverts against it. — */
  --dx-bg: #ffffff;
  --dx-fg: #1a1a1a;
  --dx-muted: rgba(235, 235, 245, 0.72);
  --dx-accent: #4c8dff;
}

/* --------------------------------------------------------------------------
   2. RESET & SCOPE
   -------------------------------------------------------------------------- */
#duvaltex-page,
#duvaltex-page *,
#duvaltex-page *::before,
#duvaltex-page *::after {
  box-sizing: border-box;
}

#duvaltex-page {
  position: relative;
  width: 100%;
  margin: 0;
  padding: 0;
  background: var(--dx-bg);
  color: var(--dx-fg);
  /* Clip the inline axis only — a blanket overflow:hidden would silently
     disable position:sticky (the pinned scenes + slider navs rely on it). */
  overflow-x: clip;
  overflow-y: visible;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-size: var(--dx-step-0);
  line-height: 1.6;
}

/* Defensive: body{overflow-x:hidden} would make <body> a scroll container and
   kill sticky. Re-assert `clip` on this brand only. */
body.sonic-brand-duvaltex {
  overflow-x: clip !important;
  /* Explicit per-brand backdrop (the global body-black was breaking the
     Gutenberg editor and is being phased out) — Duvaltex is a light page. */
  background-color: #ffffff !important;
}

/* SUB-PIXEL SEAM GUARD. Hebrew line-lengths land section heights on
   fractional pixels; on mobile DPR the page's DARK backdrop then shows
   through a hairline gap between sections and reads as a dark-gray
   "border" (reported: below the New Benchmark tabs and above Make it
   right — HE only, and shifting on every tab switch, which re-lays-out
   the heights). Overlapping every section 1px over the one above seals
   the seam; solid section backgrounds make the overlap invisible. */
#duvaltex-page section + section,
#duvaltex-page div + section {
  margin-block-start: -1px;
}

/* --------------------------------------------------------------------------
   3. CONTENT SHELLS
   -------------------------------------------------------------------------- */
.dx-shell {
  width: 100%;
  max-width: var(--dx-shell-max);
  margin-inline: auto;
  padding-inline: var(--dx-gutter);
}
/* Align content to the HEADER's inner column (start-edge trick from the
   sibling brands) — use on blocks that must sit exactly on the header's line. */
.dx-align-header {
  padding-inline: max(16px, calc((100% - var(--dx-header-shell)) / 2));
}

/* --------------------------------------------------------------------------
   4. A11Y — skip link, focus policy, reduced motion baseline
   -------------------------------------------------------------------------- */
.duvaltex-skip-link {
  position: absolute;
  inset-inline-start: var(--dx-space-s);
  inset-block-start: var(--dx-space-s);
  z-index: 1000;
  padding: var(--dx-space-2xs) var(--dx-space-s);
  background: var(--dx-fg);
  color: var(--dx-bg);
  border-radius: 8px;
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform 0.2s ease;
}
.duvaltex-skip-link:focus { transform: translateY(0); }

/* NO focus rings on this page's interactive elements (client requirement;
   Safari repaints them on programmatic refocus even with :focus-visible).
   Screen-reader users navigate with their own cursor/highlight. */
#duvaltex-page a:focus,
#duvaltex-page button:focus,
#duvaltex-page [tabindex]:focus,
#duvaltex-page a:focus-visible,
#duvaltex-page button:focus-visible {
  outline: none !important;
}
#duvaltex-page a,
#duvaltex-page button {
  -webkit-tap-highlight-color: transparent;
}

.dx-sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0);
  white-space: nowrap; border: 0;
}

@media (prefers-reduced-motion: reduce) {
  #duvaltex-page *,
  #duvaltex-page *::before,
  #duvaltex-page *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* --------------------------------------------------------------------------
   5. HERO — full-WHITE stage (the header light-swaps over it). The clip's
   own background is white, so it melts into the stage; it is CONTAINED,
   never full-bleed. Copy sits beneath it. Everything starts hidden;
   initHero() runs the reveal (and shows all instantly under reduced motion
   / missing gsap).
   -------------------------------------------------------------------------- */
.dx-hero {
  position: relative;
  /* svh at the top of the page (the URL bar is expanded there);
     freezePinHeights() then pins it in px (data-dx-pin). */
  height: 100vh;                 /* fallback */
  height: 100svh;
  background: #ffffff;
  overflow: hidden;
}
.dx-hero__stage {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  /* Clear the fixed header + air: its pill bottoms at ~117px @1440 and
     ~158px on mobile — the LOGO is the topmost element and must never hide
     behind it. Desktop carries EXTRA air (the logo read glued to the pill). */
  padding-block-start: clamp(151px, 16vh, 196px);
  padding-block-end: clamp(2.5rem, 7vh, 5rem);
  padding-inline: var(--dx-gutter);
  gap: clamp(0.75rem, 1.8vh, 1.25rem);
}
.dx-hero__videowrap {
  --dx-hero-video-h: 46vh;
  width: min(94vw, calc(var(--dx-hero-video-h) * 16 / 9), 1400px);
  aspect-ratio: 16 / 9;
  flex: 0 0 auto;
  /* Pulled up toward the logo (~10px), and the copy cluster pulled up
     under it (~15px more) — no overlap, just tight seams. */
  /* top -26 / bottom +1: the clip rides higher again while the copy cluster
     below stays put. */
  margin-block: calc(clamp(0.1rem, 0.5vh, 0.3rem) - 26px)
                calc(-1 * clamp(0.2rem, 0.9vh, 0.6rem) + 1px);
  opacity: 0;                    /* initHero() melts it in */
}
.dx-hero__video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
/* Desktop: the clip's subject is cut at its right edge — melt it into the
   white stage with a transparent-to-white wash. Physical `right` on
   purpose: the footage itself never flips under RTL. */
@media (min-width: 768px) {
  .dx-hero__videowrap { position: relative; }
  .dx-hero__videowrap::after {
    content: '';
    position: absolute;
    /* 2px overshoot on every edge: on very large screens sub-pixel
       rounding of the aspect-ratio box left a hairline of raw clip
       peeking past the wash on the right. */
    top: -2px;
    bottom: -2px;
    right: -2px;
    width: calc(42% + 4px);
    /* Eased ramp (not linear) — a long transparent run-up that leans into
       white only near the edge reads like light, not like a sticker. */
    background: linear-gradient(to right,
      rgba(255, 255, 255, 0)    0%,
      rgba(255, 255, 255, 0.05) 30%,
      rgba(255, 255, 255, 0.2)  55%,
      rgba(255, 255, 255, 0.55) 78%,
      rgba(255, 255, 255, 0.9)  93%,
      #ffffff                   100%);
    pointer-events: none;
  }
  /* The clip rides a touch lower off the header (the logo above it leads),
     and the copy cluster below hugs up ~10px closer to the clip. */
  .dx-hero__videowrap {
    margin-block-end: calc(-1 * clamp(0.2rem, 0.9vh, 0.6rem) - 9px);
  }
}
@media (max-width: 767px) {
  .dx-hero__stage {
    /* Mobile pill bottoms at ~158px — the logo is the topmost element.
       (initHero() refines this live off the measured pill.) */
    padding-block-start: 172px;
    padding-block-end: clamp(4.5rem, 11vh, 7rem);
  }
  /* Taller mobile stage, cover-cropped sides (the clip's bg is white, so the
     crop is invisible and the subject scales up). */
  .dx-hero__videowrap {
    width: 100vw;
    aspect-ratio: auto;
    height: min(38vh, 100vw);
  }
  .dx-hero__video { object-fit: cover; }
}
.dx-hero__logo {
  display: block;
  position: relative;
  z-index: 2;                    /* ALWAYS above the clip (it rides up under it) */
  width: clamp(92px, 9.5vw, 132px);
  height: auto;
  opacity: 0;                    /* initHero() reveals it first */
  will-change: opacity, transform;
}
.dx-hero__title {
  margin: 0;
  position: relative;
  z-index: 1;                    /* rides over the clip's bottom whitespace */
  max-width: 16em;
  /* Sized to hold TWO lines at most on every width. */
  font-size: clamp(1.65rem, 1.05rem + 2.65vw, 3.35rem);
  line-height: 1.12;
  font-weight: 600;              /* hero title is the page's one 600 */
  letter-spacing: -0.015em;
  color: #1a1a1a;
  opacity: 0;                    /* initHero() reveals */
  transform-origin: 50% 50%;
  will-change: opacity, transform;
}
.dx-hero__line { display: block; }
/* Opening fragment reads softer than the punch line. */
.dx-hero__line--soft { font-weight: 400; }
.dx-hero__subtitle {
  /* A breath of air below the title. */
  margin: clamp(0.2rem, 1vh, 0.6rem) 0 0;
  max-width: 40em;
  color: #86868b;
  font-size: var(--dx-step-0);
  line-height: 1.6;
  font-weight: 400;
  opacity: 0;                    /* initHero() reveals */
  will-change: opacity, transform;
}
.dx-hero__cta {
  display: inline-flex;
  align-items: center;
  margin-block-start: clamp(0.1rem, 0.6vh, 0.4rem);   /* hugs the paragraph */
  padding: 0.8em 1.9em;
  border-radius: 999px;
  background: #0065ff;           /* the site-wide CTA blue */
  border: 0;
  color: #ffffff !important;             /* beat the theme/kit link color */
  font-size: var(--dx-step-0);
  font-weight: 500;
  line-height: 1;
  text-decoration: none !important;
  opacity: 0;                    /* initHero() reveals */
  transition: background-color 0.3s ease;
}
.dx-hero__cta:hover {
  background: #0053d6;
}

/* --------------------------------------------------------------------------
   5b. S2 — INTRO. Quiet #f5f4f6 band: black title, gray copy, one-shot
   staggered reveal (initIntro() adds .is-in).
   -------------------------------------------------------------------------- */
.dx-intro {
  background: #f5f4f6;
  padding-block: var(--dx-space-2xl);
}
.dx-intro__inner { text-align: start; }
.dx-intro__title {
  margin: 0;
  color: #1a1a1a;
  /* One clear step BELOW the hero H1 (hero tops at 3.7rem/600) — a section
     H2 must support, not compete: ~1.4x smaller, weight 500. */
  font-size: clamp(1.35rem, 0.95rem + 1.8vw, 2.35rem);
  font-weight: 500;
  line-height: 1.18;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
.dx-intro__text {
  margin: var(--dx-space-s) 0 0;
  max-width: 62ch;
  color: #77767a;
  /* Same size as the hero paragraph. */
  font-size: var(--dx-step-0);
  line-height: 1.6;
  font-weight: 400;
  text-wrap: pretty;
}
.dx-intro__text:first-of-type { margin-block-start: var(--dx-space-m); }
.dx-intro__img {
  display: block;
  width: 100%;
  height: auto;
  margin-block-start: var(--dx-space-l);
  border-radius: clamp(14px, 1.8vw, 22px);
}
/* Sibling story blocks (Designed to Disappear / Built to Last / ...) —
   generous air between each composition. */
.dx-intro__inner + .dx-intro__inner { margin-block-start: var(--dx-space-2xl); }
/* Desktop: copy | image, 50/50. The image fills its column height. */
@media (min-width: 768px) {
  .dx-intro__inner {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: clamp(2rem, 4vw, 4.5rem);
    align-items: center;
  }
  /* ONE copy cell | ONE image cell. (The old per-element rows stretched
     to the tall image and pushed each paragraph away from its title.) */
  .dx-intro__copy { grid-column: 1; grid-row: 1; }
  .dx-intro__img {
    grid-column: 2;
    grid-row: 1;
    height: 100%;
    object-fit: cover;
    margin-block-start: 0;
  }
}
/* --------------------------------------------------------------------------
   LOGO MARQUEE — inside the "Trusted in Iconic Spaces" copy cell.
   Embla Carousel (the house slider engine) + its Auto Scroll plugin run
   the infinite rail (initLogoMarquee() in js/duvaltex-scroll.js):
   loop:true keeps the logos cycling out one side and back in the other,
   drag works, RTL is native. One logo reads centered with two peeking
   at the edges; section-colored gradients melt both sides.
   -------------------------------------------------------------------------- */
.dx-marquee {
  position: relative;
  margin-block-start: var(--dx-space-m);
  /* ~1 full logo centered + 2 edge peeks at any column width. */
  --dx-mq-item: clamp(150px, 42%, 230px);
}
.dx-marquee__viewport { overflow: hidden; }
.dx-marquee__track {
  display: flex;
  align-items: center;
  touch-action: pan-y pinch-zoom;   /* vertical scroll stays native */
}
.dx-marquee__slide {
  flex: 0 0 var(--dx-mq-item);
  min-width: 0;
  /* No extra gap — the re-exported logos carry their padding BAKED IN. */
  padding-inline: 0;
}
.dx-marquee__logo {
  display: block;
  width: 100%;
  height: auto;
  user-select: none;
  -webkit-user-drag: none;
}
/* Side fades — the SECTION's color (#f5f4f6 band), not pure white, so
   the melt looks native to the surface it sits on. PHYSICAL sides. */
.dx-marquee::before,
.dx-marquee::after {
  content: '';
  position: absolute;
  inset-block: 0;
  width: 16%;
  z-index: 2;
  pointer-events: none;
}
.dx-marquee::before {
  left: 0;
  background: linear-gradient(90deg, #f5f4f6 0%, rgba(245, 244, 246, 0) 100%);
}
.dx-marquee::after {
  right: 0;
  background: linear-gradient(-90deg, #f5f4f6 0%, rgba(245, 244, 246, 0) 100%);
}
/* Rides the block's reveal like a third copy line. */
.dx-marquee {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.9s linear, transform 1s cubic-bezier(0.22, 1, 0.36, 1);
}
.dx-intro__inner.is-in .dx-marquee {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 0.3s;
}
@media (prefers-reduced-motion: reduce) {
  .dx-marquee { opacity: 1; transform: none; }
}

/* Reveal — PER BLOCK (initIntro() adds .is-in to each .dx-intro__inner
   as it enters view; one section-level flag fired too late once the
   section grew to five compositions). Static under reduced motion. */
.dx-intro__title,
.dx-intro__text,
.dx-intro__img {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.9s linear, transform 1s cubic-bezier(0.22, 1, 0.36, 1);
}
.dx-intro__inner.is-in .dx-intro__title,
.dx-intro__inner.is-in .dx-intro__text,
.dx-intro__inner.is-in .dx-intro__img {
  opacity: 1;
  transform: translateY(0);
}
.dx-intro__inner.is-in .dx-intro__text:first-of-type { transition-delay: 0.12s; }
.dx-intro__inner.is-in .dx-intro__text:last-of-type  { transition-delay: 0.22s; }
.dx-intro__inner.is-in .dx-intro__img                { transition-delay: 0.32s; }
.dx-intro--static .dx-intro__title,
.dx-intro--static .dx-intro__text,
.dx-intro--static .dx-intro__img {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}

/* --------------------------------------------------------------------------
   5c. S3 — COMPARE. White band with the two inlined Illustrator diagrams.
   Only the sound waves animate: a looping traveling pulse via
   stroke-dashoffset (every wave path carries pathLength="1", so the dash
   math is normalized regardless of real path length).
     Bad fabric:   offset  1.02 -> 0 draws from the path START (the room,
                   right side) toward the fabric — the end hook IS the
                   reflection, so it renders last, exactly on impact.
     Good before:  offset -1.02 -> 0 draws from the path END (the room)
                   toward the fabric (the path starts AT the fabric).
     Good through: same trick, delayed until the incoming front touches
                   the fabric, then dies into the absorber.
   Loop reset happens while the stroke is faded out, so it never flashes.
   initCompare() adds .is-in (reveal) and per-figure .is-run (waves run
   only on screen).
   -------------------------------------------------------------------------- */
.dx-compare {
  background: #ffffff;
  padding-block: var(--dx-space-2xl);
}
.dx-compare__inner { text-align: start; }
.dx-compare__title {
  margin: 0;
  color: #1a1a1a;
  /* Same rank as the S2 intro title — sibling section H2s. */
  font-size: clamp(1.35rem, 0.95rem + 1.8vw, 2.35rem);
  font-weight: 500;
  line-height: 1.18;
  letter-spacing: -0.015em;
  text-wrap: balance;
  max-width: 18em;
}
.dx-compare__fig {
  margin: var(--dx-space-m) 0 0;   /* below the panel's paragraph */
  max-width: 860px;
}
/* — The goo-birth tab bar (ported from Storm's products tabs, light theme;
   the #ss-goo filter is declared inline in the section). initCompare()
   plays the "birth" once on section enter and drives the thumb. — */
.dx-compare__tabs-wrap {
  width: 100%;
  margin-block: var(--dx-space-l) var(--dx-space-m);
}
.dx-tabs {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  padding: 5px;
  border-radius: 999px;
  background: transparent;       /* the light surface is the __glass layer */
}
.dx-tabs.dx-tabs-prebirth { visibility: hidden; }
@media (min-width: 768px) {
  /* Start-aligned bar (left in EN, right in HE) — S3 + S4 alike. */
  .dx-tabs { width: fit-content; }
}
.dx-tabs__goo {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  filter: url(#ss-goo);
}
.dx-tabs__goo-a,
.dx-tabs__goo-b {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  border-radius: 999px;
  background: #e7e7ea;
}
.dx-tabs__glass {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.055);  /* the birth fades this in */
  opacity: 0;
  pointer-events: none;
}
.dx-tabs__thumb {
  position: absolute;
  top: 5px;
  bottom: 5px;
  left: 0;
  width: 0;                      /* JS sets left + width to the active tab */
  z-index: 1;
  background: #fff;
  border-radius: 999px;
  /* gentle glide, no spring overshoot — reads finer on the light control */
  transition: left 0.45s cubic-bezier(0.22, 1, 0.36, 1),
              width 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
.dx-tab,
.dx-tab:hover,
.dx-tab:focus,
.dx-tab:focus-visible,
.dx-tab:active {
  position: relative;
  z-index: 2;
  flex: 1 1 0;
  text-align: center;
  appearance: none;
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  outline: none !important;
  margin: 0;
  padding: 0.5rem clamp(1.4rem, 5vw, 2.4rem);
  border-radius: 999px;
  font-size: clamp(0.9rem, 2.4vw, 1.05rem);
  font-weight: 400;
  line-height: 1.1;
  color: rgba(60, 60, 67, 0.62) !important;
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.3s ease;
}
.dx-tab.is-active { color: #1a1a1a !important; font-weight: 500; }

/* — Tab panels: paragraph + its animation — */
.dx-compare__panel { width: 100%; }
.dx-compare__panel[hidden] { display: none !important; }
/* One-shot entrance replayed on every switch (initGooTabs() re-adds it).
   FADE ONLY — any vertical motion here reads as a jump, because the two
   diagrams are aligned to sit exactly on top of each other. */
.dx-compare__panel.is-switch,
.dx-measure__panel.is-switch {
  animation: dx-panel-in 0.45s ease;
}
@keyframes dx-panel-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.dx-compare__desc {
  margin: 0;
  max-width: 62ch;
  color: #77767a;
  font-size: var(--dx-step-0);
  line-height: 1.6;
  font-weight: 400;
  text-wrap: pretty;
}
/* Closing copy below the two animations. */
.dx-compare__text {
  margin: 0;
  max-width: 62ch;
  color: #77767a;
  font-size: var(--dx-step-0);
  line-height: 1.6;
  font-weight: 400;
  text-wrap: pretty;
}
.dx-compare__text + .dx-compare__text { margin-block-start: var(--dx-space-s); }
/* Sub-heading inside a closing block ("Easy to Live With") — a clear
   step below the section H2. */
.dx-compare__foot-title {
  margin: 0 0 var(--dx-space-s);
  color: #1a1a1a;
  font-size: clamp(1.15rem, 0.95rem + 0.9vw, 1.6rem);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: -0.012em;
  text-wrap: balance;
}
/* Closing block, under a quiet rule. Mobile: copy then image. */
.dx-compare__foot {
  margin-block-start: var(--dx-space-l);
  padding-block-start: var(--dx-space-l);
  border-block-start: 1px solid #e5e5e7;
}
.dx-compare__img {
  display: block;
  width: 100%;
  height: auto;
  margin-block-start: var(--dx-space-l);
  border-radius: clamp(14px, 1.8vw, 22px);
}
/* Desktop: image | copy, 50/50 — the image sits PHYSICALLY left in both
   languages (the grid runs LTR; the copy flips itself back under RTL). */
@media (min-width: 768px) {
  .dx-compare__foot {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: clamp(2rem, 4vw, 4.5rem);
    align-items: center;
    direction: ltr;
  }
  .dx-compare__img       { grid-column: 1; grid-row: 1; margin-block-start: 0; }
  .dx-compare__foot-copy { grid-column: 2; grid-row: 1; }
  html[dir="rtl"] .dx-compare__foot-copy { direction: rtl; }
  /* The SECOND closing block mirrors: copy left, image PHYSICALLY right. */
  .dx-compare__foot--rev .dx-compare__img       { grid-column: 2; }
  .dx-compare__foot--rev .dx-compare__foot-copy { grid-column: 1; }
}
/* The physics diagram never mirrors — keep it LTR under the Hebrew page. */
.dx-compare__svg {
  display: block;
  width: 100%;
  height: auto;
  direction: ltr;
}

/* — Diagram structure (panel / fabric / speaker / mic): static, as drawn
   in Illustrator. Page-scoped — shared by S3 (compare) and S4 (measure). — */
#duvaltex-page .dx-cmp-s1,
#duvaltex-page .dx-cmp-s3,
#duvaltex-page .dx-cmp-s4 {
  fill: none;
  stroke: #000;
  stroke-linecap: round;
  stroke-linejoin: round;
}
#duvaltex-page .dx-cmp-s1 { stroke-width: 1.02px; }
#duvaltex-page .dx-cmp-s2 { fill: #fff; stroke: #000; stroke-miterlimit: 10; }
#duvaltex-page .dx-cmp-s3 { stroke-width: 0.87px; }
#duvaltex-page .dx-cmp-s4 { stroke-width: 0.26px; }
/* S4 extras: speaker horn / cone / driver, mic plane + its fine grid. */
#duvaltex-page .dx-cmp-s5 { fill: #f0efef; stroke: #231f20; stroke-miterlimit: 10; }
#duvaltex-page .dx-cmp-s6 { fill: #fff;    stroke: #231f20; stroke-miterlimit: 10; }
#duvaltex-page .dx-cmp-s7 { fill: #231f20; }
#duvaltex-page .dx-cmp-s8 { fill: none;    stroke: #231f20; stroke-miterlimit: 10; }
#duvaltex-page .dx-cmp-s9 { fill: none;    stroke: #231f20; stroke-miterlimit: 10; stroke-width: 0.23px; }

/* — Sound waves: drawn LIVE by the JS engines — the path `d` is
   regenerated every frame from one shared clock (real traveling waves,
   all diagrams in perfect sync). CSS only styles the strokes. — */
#duvaltex-page .dx-wave {
  fill: none;
  stroke-width: 2px;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* The bad fabric's echo is the star of the problem — near-full presence. */
.dx-compare .dx-wave--bad-refl { opacity: 0.9; }

/* Reveal (initCompare() adds .is-in once; static under reduced motion).
   The tab bar itself is NOT here — its entrance is the goo birth. */
.dx-compare__title,
.dx-compare__panel,
.dx-compare__text,
.dx-compare__img {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.9s linear, transform 1s cubic-bezier(0.22, 1, 0.36, 1);
}
.dx-compare.is-in .dx-compare__title,
.dx-compare.is-in .dx-compare__panel,
.dx-compare.is-in .dx-compare__text,
.dx-compare.is-in .dx-compare__img {
  opacity: 1;
  transform: translateY(0);
}
.dx-compare.is-in .dx-compare__panel              { transition-delay: 0.25s; }
.dx-compare.is-in .dx-compare__text:first-of-type { transition-delay: 0.45s; }
.dx-compare.is-in .dx-compare__text:last-of-type  { transition-delay: 0.55s; }
.dx-compare.is-in .dx-compare__img                { transition-delay: 0.65s; }
.dx-compare--static .dx-compare__title,
.dx-compare--static .dx-compare__panel,
.dx-compare--static .dx-compare__text,
.dx-compare--static .dx-compare__img {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}
/* (Under reduced motion the engine draws one static frame — no CSS needed.) */

/* --------------------------------------------------------------------------
   5d. S4 — MEASURE. Quiet #f5f4f6 band with the test-rig diagram
   (Animation C): speaker -> measuring mic -> fabric -> absorber. The
   waves are drawn live by initMeasure() (same engine as S3, one clock,
   continuous phase across the three segments); the mic grid pulses.
   -------------------------------------------------------------------------- */
.dx-measure {
  background: #f5f4f6;
  padding-block: var(--dx-space-2xl);
}
.dx-measure__title {
  margin: 0;
  color: #1a1a1a;
  font-size: clamp(1.35rem, 0.95rem + 1.8vw, 2.35rem);  /* section H2 rank */
  font-weight: 500;
  line-height: 1.18;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
/* The shared goo-birth tab bar hosts the two methods. */
.dx-measure__tabs-wrap {
  width: 100%;
  margin-block: var(--dx-space-m) var(--dx-space-m);
}
.dx-measure__panel { width: 100%; }
.dx-measure__panel[hidden] { display: none !important; }
.dx-measure__text {
  margin: 0;
  max-width: 62ch;
  color: #77767a;
  font-size: var(--dx-step-0);
  line-height: 1.6;
  font-weight: 400;
  text-wrap: pretty;
}
/* "Impedance Tube" — emphasized within the house rules (500 max). */
.dx-measure__hl { color: #1a1a1a; font-weight: 500; }
.dx-measure__fig {
  margin: var(--dx-space-l) auto 0;   /* below the panel's paragraph */
  max-width: 900px;
}
/* — Element labels: HTML row under the diagram; each anchored to its
   element's x-center (% of the 636.62 viewBox). Long labels wrap. — */
.dx-measure__labels {
  position: relative;
  margin-block-start: var(--dx-space-2xs);
  min-height: 2.9em;
  font-size: clamp(0.68rem, 0.58rem + 0.42vw, 0.92rem);
  line-height: 1.35;
  color: #77767a;
}
.dx-measure__label { position: absolute; top: 0; }
.dx-measure__label--absorb  { left: 0; width: 21%; min-width: 6.2em; text-align: start; }
.dx-measure__label--fabric  { left: 36.9%; transform: translateX(-50%); text-align: center; }
.dx-measure__label--mic     { left: 67.5%; transform: translateX(-50%); text-align: center; }
.dx-measure__label--speaker { right: 0; text-align: end; }
.dx-measure__svg {
  display: block;
  width: 100%;
  height: auto;
  direction: ltr;      /* the physics diagram never mirrors under RTL */
}
/* Art parity: Animation C is drawn with finer wave strokes than A/B. */
.dx-measure .dx-wave { stroke-width: 1.4px; }
/* The mic "keeps measuring" — a slow breath on its grid plane. */
.dx-measure__grid {
  animation: dx-mic-pulse 2.2s ease-in-out infinite alternate;
}
@keyframes dx-mic-pulse {
  from { opacity: 0.55; }
  to   { opacity: 1; }
}
/* Reveal (initMeasure() adds .is-in once; static under reduced motion).
   The tab bar itself is NOT here — its entrance is the goo birth. */
.dx-measure__title,
.dx-measure__panel {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.9s linear, transform 1s cubic-bezier(0.22, 1, 0.36, 1);
}
.dx-measure.is-in .dx-measure__title,
.dx-measure.is-in .dx-measure__panel {
  opacity: 1;
  transform: translateY(0);
}
.dx-measure.is-in .dx-measure__panel { transition-delay: 0.25s; }
.dx-measure--static .dx-measure__title,
.dx-measure--static .dx-measure__panel {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}
.dx-measure--static .dx-measure__grid { animation: none !important; }

/* --------------------------------------------------------------------------
   5e. S5 — COLORS. White pinned stage: three counter-rotating rings of
   real swatch circles around a fabric core. The spin is pure CSS (paused
   while off-screen via .is-run); initColors() scroll-scrubs the rings'
   opacity/scale and the copy swap. Plain vh on purpose (mid-page pin —
   see the stage-height house rule); data-dx-pin freezes it in px.
   -------------------------------------------------------------------------- */
.dx-colors {
  position: relative;
  height: 300vh;                 /* scroll length: rings + a LONG copy hold */
  background: #ffffff;
}
.dx-colors__stage {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.dx-colors__rings {
  position: absolute;
  inset: 0;
  opacity: 0;                    /* initColors() scrubs it in */
  will-change: opacity, transform;
}
.dx-colors__ring {
  position: absolute;
  inset: 0;
  animation: dx-ring-spin var(--dur, 90s) linear infinite;
  animation-play-state: paused;  /* .is-run flips it on */
}
.dx-colors.is-run .dx-colors__ring { animation-play-state: running; }
.dx-colors__ring[data-rev] { animation-direction: reverse; }
@keyframes dx-ring-spin { to { transform: rotate(360deg); } }
/* Per-ring dot size + orbit radius. */
.dx-colors__ring--1 { --s: clamp(42px, 10vmin, 86px);  --r: clamp(110px, 16vmin, 205px); }
.dx-colors__ring--2 { --s: clamp(36px, 8.4vmin, 74px); --r: clamp(185px, 27vmin, 345px); }
.dx-colors__ring--3 { --s: clamp(30px, 7vmin, 62px);   --r: clamp(260px, 38vmin, 485px); }
/* Desktop: SPREAD — vw-based radii so the galaxy claims the full viewport
   width; the outer rings run past the stage's top/bottom edges (clipped by
   overflow) and the dots get generous breathing room between them. */
@media (min-width: 768px) {
  .dx-colors__ring--1 { --s: clamp(40px, 4.6vw, 74px); --r: clamp(150px, 15vw, 240px); }
  .dx-colors__ring--2 { --s: clamp(36px, 4vw, 64px);   --r: clamp(280px, 28vw, 450px); }
  .dx-colors__ring--3 { --s: clamp(30px, 3.4vw, 56px); --r: clamp(430px, 44vw, 700px); }
}
.dx-colors__dot {
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--s);
  height: var(--s);
  margin: calc(var(--s) / -2) 0 0 calc(var(--s) / -2);
  transform: rotate(var(--a, 0deg)) translateY(calc(-1 * var(--r)));
  border-radius: 50%;
  /* Pure CSS swatch — the fabric's averaged hex, flat. */
  background: var(--dot, #cccccc);
}
/* The copy that replaces the galaxy. */
.dx-colors__copy {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding-inline: var(--dx-gutter);
  opacity: 0;                    /* initColors() scrubs it in */
  will-change: opacity, transform;
}
.dx-colors__title {
  margin: 0;
  color: #1a1a1a;
  font-size: clamp(1.35rem, 0.95rem + 1.8vw, 2.35rem);  /* section H2 rank */
  font-weight: 500;
  line-height: 1.18;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
/* Both title lines wear Moovia's signature gradient; "Thousands" is the
   big one. */
.dx-colors__title-big,
.dx-colors__title-rest {
  display: block;
  background: linear-gradient(90deg, #042640 0%, #346a92 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}
html[dir="rtl"] .dx-colors__title-big,
html[dir="rtl"] .dx-colors__title-rest {
  background: linear-gradient(-90deg, #042640 0%, #346a92 100%);
  -webkit-background-clip: text;
  background-clip: text;
}
.dx-colors__title-big {
  font-size: clamp(2.5rem, 1.5rem + 4.6vw, 4.9rem);
  line-height: 1.05;
}
.dx-colors__title-rest {
  margin-block-start: 0.15em;
}
.dx-colors__text {
  margin: var(--dx-space-2xs) 0 0;
  max-width: 36em;
  color: #77767a;
  font-size: var(--dx-step-0);
  line-height: 1.6;
  font-weight: 400;
  text-wrap: pretty;
}
/* Reduced motion: un-pin — static rings, copy below. */
@media (prefers-reduced-motion: reduce) {
  .dx-colors { height: auto !important; }
  .dx-colors__stage {
    position: relative;
    height: auto;
    display: block;
    padding-block: var(--dx-space-2xl);
    overflow: visible;
  }
  .dx-colors__rings {
    position: relative;
    inset: auto;
    height: 88vmin;
    opacity: 1 !important;
    transform: none !important;
  }
  .dx-colors__copy {
    position: relative;
    inset: auto;
    margin-block-start: var(--dx-space-l);
    opacity: 1 !important;
    transform: none !important;
  }
}

/* --------------------------------------------------------------------------
   5f. BREAK — full-bleed video parallax transition (normal scroll). The
   media layer is 30% taller than the frame; initBreaks() slides it ±14%
   as the section crosses the viewport. The black logo SVG is served
   WHITE via filter.
   -------------------------------------------------------------------------- */
.dx-break {
  position: relative;
  height: clamp(340px, 72vh, 780px);
  overflow: hidden;
  background: #0d131a;           /* holds the frame until the clip arrives */
}
.dx-break__media {
  position: absolute;
  inset: -15% 0;                 /* travel room for the parallax */
  will-change: transform;
}
.dx-break__video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.dx-break__logo {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: clamp(150px, 22vw, 300px);
  height: auto;
  filter: brightness(0) invert(1);   /* black SVG -> white */
}
@media (prefers-reduced-motion: reduce) {
  .dx-break__media { inset: 0; transform: none !important; }
}

/* --------------------------------------------------------------------------
   5g. S6 — STORY (the Duvaltex highlights, no eyebrow). The Moovia
   stanza mechanic, shortened to four highlights: white pinned scene,
   caption track traveling through the emerge/brighten/fade mask.
   -------------------------------------------------------------------------- */
.dx-story {
  position: relative;
  /* Pin length ~= the track's real travel so scroll-to-motion stays ~1:1
     (five title+sub stanzas — much shorter than Moovia's ride). */
  --dx-story-scroll: 325vh;
  height: var(--dx-story-scroll);
  background: #ffffff;
}
@media (max-width: 767px) {
  .dx-story { --dx-story-scroll: 305vh; }
}
.dx-story__stage {
  position: sticky;
  top: 0;
  /* Plain vh on purpose (mid-page pin) — see the stage-height house rule. */
  height: 100vh;
  overflow: hidden;
  background: #ffffff;
}
/* Emerge/brighten/fade mask. The top fade COMPLETES ~8px below the real
   header pill (--dx-story-fade; initStory() measures it live, these are
   the pre-JS fallbacks) and runs TALL — all the way down to ~46% of the
   stage — so headlines dissolve gradually, not against a hard band. */
.dx-story { --dx-story-fade: 128px; }              /* pill ~117px @1440 + 8 */
@media (max-width: 767px) {
  .dx-story { --dx-story-fade: 166px; }            /* mobile pill ~158px + 8 */
}
.dx-story__captions {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, transparent var(--dx-story-fade), #000 46%, #000 68%, transparent 90%);
          mask-image: linear-gradient(to bottom, transparent var(--dx-story-fade), #000 46%, #000 68%, transparent 90%);
}
@media (max-width: 767px) {
  .dx-story__captions {
    -webkit-mask-image: linear-gradient(to bottom, transparent var(--dx-story-fade), #000 48%, #000 70%, transparent 90%);
            mask-image: linear-gradient(to bottom, transparent var(--dx-story-fade), #000 48%, #000 70%, transparent 90%);
  }
}
.dx-story__track {
  position: absolute;
  inset-inline: 0;
  inset-block-start: 0;          /* JS drives translateY */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  padding-inline: max(var(--dx-gutter), calc((100% - var(--dx-header-shell)) / 2));
  will-change: transform;
}
.dx-story__group { text-align: start; }
.dx-story__group + .dx-story__group {
  border-top: 1px solid #e3e3e6;
  margin-top: clamp(2rem, 1rem + 4vh, 5rem);
  padding-top: clamp(2rem, 1rem + 4vh, 5rem);
}
/* Gradient headline — the page's signature ramp; fit-content so the full
   gradient lands on the letters. */
.dx-story__line {
  margin: 0;
  width: fit-content;
  max-width: min(100%, 24ch);
  font-size: clamp(1.45rem, 1rem + 1.9vw, 2.6rem);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.015em;
  text-wrap: pretty;
  background: linear-gradient(90deg, #042640 0%, #346a92 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}
html[dir="rtl"] .dx-story__line {
  background: linear-gradient(-90deg, #042640 0%, #346a92 100%);
  -webkit-background-clip: text;
  background-clip: text;
}
.dx-story__sub {
  margin: var(--dx-space-2xs) 0 0;
  max-width: 52ch;
  color: #77767a;
  font-size: var(--dx-step-0);
  line-height: 1.6;
  font-weight: 400;
  text-wrap: pretty;
}
/* Desktop: centered stanzas (mobile stays start-aligned). */
@media (min-width: 768px) {
  .dx-story__group { text-align: center; }
  .dx-story__line,
  .dx-story__sub { margin-inline: auto; }
}
/* Reduced motion / no-JS: static white column, no mask, no pin. */
.dx-story--static { height: auto; }
.dx-story--static .dx-story__stage {
  position: relative;
  height: auto;
  overflow: visible;
  padding-block-end: var(--dx-space-2xl);
}
.dx-story--static .dx-story__captions {
  position: relative;
  inset: auto;
  margin-block-start: var(--dx-space-l);
  overflow: visible;
  -webkit-mask-image: none;
          mask-image: none;
}
.dx-story--static .dx-story__track {
  position: relative;
  inset: auto;
  transform: none !important;
}

/* --------------------------------------------------------------------------
   5h. S7 — PRODUCTS ("Choose your fabric"). Moovia's carousel pattern:
   one light sonic-slider on every breakpoint, square slides. The fabric
   shots are FULL-BLEED texture closeups (not white studio renders), so
   the image covers the card and a soft white wash tops the slide to keep
   the dark title/sub legible on any texture.
   -------------------------------------------------------------------------- */
.dx-products {
  background: #ffffff;
  padding-block: clamp(2.5rem, 6vh, 4.5rem) var(--dx-space-2xl);
  --dx-white-pad: max(16px, calc((100% - var(--dx-header-shell)) / 2));
}
.dx-products__head {
  width: 100%;
  padding-inline: var(--dx-white-pad);
  margin-bottom: var(--dx-space-l);
  text-align: start;
}
.dx-wtitle {
  margin: 0;
  color: #1a1a1a;
  font-size: clamp(1.75rem, 1.25rem + 2vw, 3rem);
  font-weight: 500;
  line-height: 1.14;
  letter-spacing: -0.02em;
  text-wrap: pretty;
}
.dx-products .sonic-slider--shop { --ss-slide-aspect: 1 / 1; }
@media (min-width: 768px) {
  .dx-products .sonic-slider--shop { --ss-slide-w: 30%; }
}
.dx-products .sonic-slider--shop .sonic-slider__slide {
  background: #ffffff;
  border: 1px solid #e3e3e6;
}
.dx-products .sonic-slider--shop .sonic-slider__img {
  background: #ffffff;
  object-fit: cover;             /* texture closeups fill the square */
}
.dx-products .sonic-slider__card-head { z-index: 2; }
.dx-products .sonic-slider__card-title { color: #1a1a1a; }
/* THIS page only: fabric names are CENTERED (LTR text, both languages). */
.dx-products .sonic-slider__card-head,
[dir="rtl"] .dx-products .sonic-slider__card-head {
  direction: ltr;
  text-align: center !important;
  padding-inline: clamp(1.1rem, 4vw, 1.8rem);
  top: clamp(0.9rem, 3.5vw, 1.5rem);
}
[dir="rtl"] .dx-products .sonic-slider__card-title {
  text-align: center !important;
}
/* The Acoustic Transparency line parks CENTERED at the card's bottom
   (both languages) so it never rides over the texture's focal top area. */
.dx-products .sonic-slider__card-sub,
[dir="rtl"] .dx-products .sonic-slider__card-sub {
  position: absolute;
  bottom: clamp(0.9rem, 3.5vw, 1.5rem);
  left: 0;
  right: 0;
  margin: 0;
  z-index: 2;
  direction: ltr;
  text-align: center !important;
  color: rgba(0, 0, 0, 0.58);
}

/* --------------------------------------------------------------------------
   5i. S8 — OUTRO (#f5f5f7 band): Make it right | For dealers, then
   Contact us with the WhatsApp chip — the Moovia/Storm outro, dx-scoped,
   WITHOUT the block dividers (dropped on Moovia too by request).
   -------------------------------------------------------------------------- */
.dx-outro {
  background: #f5f5f7;
  padding-block: var(--dx-space-xl) clamp(7rem, 15vh, 11rem);
  --dx-white-pad: max(16px, calc((100% - var(--dx-header-shell)) / 2));
}
.dx-wtitle--sm {
  font-size: clamp(1.15rem, 1rem + 0.7vw, 1.55rem);
}
@media (max-width: 767px) {
  .dx-outro .dx-wtitle--sm { font-size: 1.35rem; }
}
.dx-outro__inner {
  width: 100%;
  text-align: start;
  /* A touch more side padding than the rest of the page. */
  padding-inline: calc(var(--dx-white-pad) + 10px);
}
.dx-outro__cols { display: grid; gap: var(--dx-space-l); }
@media (min-width: 768px) {
  .dx-outro__cols { grid-template-columns: 1fr 1fr; gap: clamp(24px, 3vw, 48px); }
}
/* Light divider UNDER each top block (between the Make it right / For
   dealers row and Contact us). NOT to be confused with the dark hairline
   that used to show at the section's TOP — that was the sub-pixel seam
   (sealed by the seam guard at the top of this file). */
.dx-outro__cols .dx-outro__block {
  padding-bottom: var(--dx-space-l);
  border-bottom: 1px solid #e3e3e6;
}
.dx-outro__block--contact { margin-top: var(--dx-space-xl); }
.dx-outro__text {
  margin: var(--dx-space-xs) 0 0;
  max-width: 58ch;
  color: #98989d;
  font-size: clamp(0.92rem, 0.86rem + 0.3vw, 1.1rem);
  line-height: 1.55;
  text-wrap: pretty;
}
.dx-outro__contact {
  list-style: none;
  margin: var(--dx-space-xs) 0 0;
  padding: 0;
  color: #98989d;
  font-size: clamp(0.92rem, 0.86rem + 0.3vw, 1.1rem);
  line-height: 1.9;
}
/* Round WhatsApp chip above the phone number. */
#duvaltex-page .dx-outro__contact .dx-outro__wa-btn,
#duvaltex-page .dx-outro__wa-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: #25d366;
  color: #fff !important;
  margin-bottom: 4px;
  text-decoration: none !important;
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1), background 0.2s ease;
}
#duvaltex-page .dx-outro__contact .dx-outro__wa-btn:hover  { background: #1fb85a; transform: translateY(-2px); }
#duvaltex-page .dx-outro__contact .dx-outro__wa-btn:active { transform: translateY(0); }
.dx-outro__wa-btn svg { width: 20px; height: 20px; }
/* !important + the page id: the theme/Elementor kit paints links white,
   which would make these invisible on the light band. */
#duvaltex-page .dx-outro__contact a {
  color: #0066ff !important;
  text-decoration: underline !important;
  text-underline-offset: 0.15em;
}
#duvaltex-page .dx-outro__contact a:hover { color: #0052d6 !important; }

/* --------------------------------------------------------------------------
   6. HEADER LIGHT SKIN — the proven recipe (see memory:
   feedback_header_light_swap; NEVER server-render header template 5861 — it
   fatals). initHeaderSwap() in js/duvaltex-scroll.js toggles
   body.dx-header-light while a [data-dx-header="light"] section sits under
   the header, tags the glass pill with .dx-hdr-pill, flips svg ink inline,
   swaps the logo, and sets the hamburger plugin's data-theme.
   -------------------------------------------------------------------------- */
[data-elementor-type="header"] a { transition: color 0.35s ease; }
body.dx-header-light [data-elementor-type="header"] a,
body.dx-header-light [data-elementor-type="header"] .elementor-item,
body.dx-header-light [data-elementor-type="header"] .elementor-nav-menu a {
  color: rgba(49, 49, 49, 0.97) !important;
}
body.dx-header-light [data-elementor-type="header"] .dub-dropdown {
  background: rgba(255, 255, 255, 0.92) !important;
  color: #1d1d1f !important;
}
/* Non-link labels (the "EN" language switcher is a span) + widget toggles. */
body.dx-header-light [data-elementor-type="header"] .dub-lang-current,
body.dx-header-light [data-elementor-type="header"] .dub-lang-toggle,
body.dx-header-light [data-elementor-type="header"] .dub-user-toggle,
body.dx-header-light [data-elementor-type="header"] .dub-cart-toggle {
  color: rgba(49, 49, 49, 0.97) !important;
}
body.dx-header-light [data-elementor-type="header"] .dub-input {
  background: rgba(0, 0, 0, 0.04) !important;
  color: #1d1d1f !important;
}
/* The glass pill (tagged .dx-hdr-pill by JS). Elementor's scrolled state uses
   !important — the doubled class + !important here wins. */
[data-elementor-type="header"] .dx-hdr-pill { transition: background-color 0.35s ease, border-color 0.35s ease; }
body.dx-header-light [data-elementor-type="header"] .dx-hdr-pill.dx-hdr-pill {
  background-color: rgba(255, 255, 255, 0.47) !important;
  border: 1px solid rgba(0, 0, 0, 0.11) !important;
}
/* Icon svgs that carry stroke/fill ATTRIBUTES; computed-white ones are flipped
   inline by the JS. */
body.dx-header-light [data-elementor-type="header"] svg [stroke],
body.dx-header-light [data-elementor-type="header"] svg[stroke] {
  stroke: rgb(26, 26, 26) !important;
}
body.dx-header-light [data-elementor-type="header"] svg [fill="white"],
body.dx-header-light [data-elementor-type="header"] svg [fill="#fff"],
body.dx-header-light [data-elementor-type="header"] svg [fill="#ffffff"] {
  fill: rgb(26, 26, 26) !important;
}
/* Mobile cart (FunnelKit shortcode) — white icon -> black ink; the count badge
   keeps its own red/white (scoped to the svg only). */
body.dx-header-light [data-elementor-type="header"] .fkcart-shortcode-container svg,
body.dx-header-light [data-elementor-type="header"] .fkcart-shortcode-icon-wrap svg {
  color: rgb(0, 0, 0) !important;
  fill: rgb(0, 0, 0) !important;
}
/* Cart DRAWER — FunnelKit styles via `#fkcart-modal ... !important`, so these
   must use the ID too. */
body.dx-header-light #fkcart-modal {
  --fkcart-primary-text-color: rgb(26, 26, 26);
}
body.dx-header-light #fkcart-modal .fkcart-preview-ui {
  background: rgba(250, 248, 255, 0.85) !important;
}
body.dx-header-light #fkcart-modal .fkcart-title,
body.dx-header-light #fkcart-modal .fkcart-zero-state-title {
  color: rgb(26, 26, 26) !important;
}
body.dx-header-light #fkcart-modal .fkcart-zero-state-text {
  color: rgb(99, 99, 102) !important;
}
body.dx-header-light #fkcart-modal .fkcart-modal-close,
body.dx-header-light #fkcart-modal .fkcart-modal-close svg,
body.dx-header-light #fkcart-modal .fkcart-modal-close svg * {
  color: rgb(26, 26, 26) !important;
  fill: rgb(26, 26, 26) !important;
}
