Instruction

Webflow Template User Guide

GSAP Guide
Every GSAP code used on this template is here. How to edit them and find them is explain on this page. In every code block on this page, we added additional explanation to help you understand everything.

You can find the code in (Site settings) Footer Code.
Scrambel Text GSAP Animation
GSAP-powered text scrambling that dynamically transforms key messages across the site. Applied selectively to class .scramble v1–v4, this animation enhances emphasis across the Hero, About Us, Features, Lab, and Call-to-Action sections without disrupting readability.
<script defer>
  document.addEventListener("DOMContentLoaded", () => {

    gsap.registerPlugin(ScrambleTextPlugin);

    const tl = gsap.timeline({
      repeat: -1
    });

    tl.to(".scramble.v1", {
      duration: 1.2,
      scrambleText: {
        text: "{original}",
        chars: "+?84564XERS",
        speed: 0.6
      }
    })
    .to(".scramble.v2", {
      duration: 1.6,
      scrambleText: {
        text: "{original}",
        chars: "+?84564XERS",
        speed: 0.7
      }
    }, "-=0.6")
    .to(".scramble.v3", {
      duration: 2.1,
      scrambleText: {
        text: "{original}",
        chars: "+?84564XERS",
        speed: 0.8
      }
    }, "-=0.8");

  });
</script>
Scroll Driven Rotation
GSAP scroll-synced animation applied to feature sections. In the Features section, the .radial-mask rotates and sharpens from blur, .circle-empty scales as a depth layer, .wrapper-text-counting shifts border color to indicate activation, and .big-text counts from 0 to 100 all driven smoothly by scroll position.
<script>
  gsap.registerPlugin(ScrollTrigger);

  document.querySelectorAll(".content-feature").forEach((section) => {
    const mask = section.querySelector(".radial-mask");
    const empty = section.querySelector(".circle-empty");
    const number = section.querySelector(".big-text");
    const thinBorder = section.querySelector(".wrapper-text-counting");

    gsap.set(mask, {
      rotate: 0,
      scale: 0.95,
      filter: "blur(6px)",
      opacity: 0.8,
      transformOrigin: "50% 50%"
    });

    gsap.set(thinBorder, {
      borderColor: "rgba(156,163,175,0.35)"
    });

    gsap.set(empty, {
      scale: 1,
      filter: "blur(10px)",
      opacity: 0.35
    });

    gsap.set(number, { innerText: 0 });

    gsap.timeline({
      scrollTrigger: {
        trigger: section,
        start: "top 75%",
        end: "bottom 75%",
        scrub: 0.6
      }
    })

    .to(mask, {
      rotate: 360,
      ease: "none"
    }, 0)

    .to(mask, {
      scale: 1.05,
      filter: "blur(0px)",
      opacity: 1,
      ease: "none"
    }, 0)

    .to(thinBorder, {
      borderColor: "rgba(59,130,246,0.7)",
      ease: "none"
    }, 0)

    .to(empty, {
      scale: 1.15,
      filter: "blur(4px)",
      opacity: 0.55,
      ease: "none"
    }, 0)

    .to(number, {
      innerText: 100,
      snap: { innerText: 1 },
      ease: "none"
    }, 0);
  });
</script>
Hover Font Weight Shift
When hovering .button-secondary, the nested .scramble text dynamically shifts font weight from 300 → 600, creating a subtle emphasis effect. The interaction is scoped per button, ensuring only the hovered pricing card button action responds.
<script>
  document.addEventListener("DOMContentLoaded", () => {

    const buttons = document.querySelectorAll(".button-secondary");

    buttons.forEach(button => {
      const text = button.querySelector(".scramble");

      button.addEventListener("mouseenter", () => {
        gsap.to(text, {
          fontWeight: 600,
          duration: 0.25,
          ease: "power2.out"
        });
      });

      button.addEventListener("mouseleave", () => {
        gsap.to(text, {
          fontWeight: 300,
          duration: 0.15,
          ease: "power4.out"
        });
      });
    });

  });
</script>