Instructions

This template uses custom-built GSAP-powered systems to create smooth, responsive, and performant animations in Webflow.

Utility-page-banner

Counter animation

How it works

This animates any element tagged data-counter by counting up from 0 to its target value as it scrolls into view. The target number (and an optional suffix like + or %) is read straight from the attribute, so data-counter="250+" counts up to 250 and appends the + automatically. The count only plays once, triggered the moment the element is 85% up the viewport.

Customization options

  • Set the target value and suffix directly in the attribute, e.g. data-counter="1,200+" or data-counter="98%".
  • Adjust the animation duration (currently 2 seconds) to make the count faster or slower.
  • Change the ease (currently power1.out) for a different counting feel — e.g. linear for a constant tick-up.
  • Modify the ScrollTrigger start value ("top 85%") to trigger the count earlier or later on scroll.
  • Change toggleActions if you want the counter to replay every time it re-enters view instead of only once.

Features

  • Reads target number and suffix straight from a single HTML attribute
  • Comma-formats large numbers automatically (e.g. 1,200)
  • Triggered individually as each counter scrolls into view
  • Plays only once per element by default
  • Zero extra markup needed beyond data-counter="value"

Infinite ticker / marquee (train)

How it works

This creates a seamless, infinitely-looping horizontal ticker out of any element tagged with a train attribute. The wrapper's contents are duplicated once so the loop has no visible seam, then GSAP scrolls it continuously left or right, wrapping the position back around with a modifier once it's scrolled a full copy's width.

Customization options

  • Set the direction with train="left" or add the train-reverse attribute to reverse it.
  • Control speed with the duration attribute, e.g. duration="30" — higher numbers move slower.
  • Add marquee-pause to pause the scroll on hover, and remove it for a marquee that never stops.
  • Add more or fewer child items inside the wrapper to change the loop's visual density.

Features

  • Fully seamless infinite loop with no visible jump or reset
  • Direction and speed controlled per-instance via HTML attributes
  • Optional hover-to-pause behavior
  • Guarded against duplicate content if re-initialized
  • Ideal for logo rows, testimonial tickers, and scrolling announcements

Smooth scroll

How it works

This sets up buttery, inertia-based page scrolling using the Lenis library in place of native browser scrolling. Lenis and its stylesheet are loaded dynamically from a CDN, then initialized with a light lerp (interpolation) value so the page glides to a stop instead of snapping. A requestAnimationFrame loop keeps Lenis in sync with the browser's render cycle, and any in-page anchor link (href="#section") is intercepted so clicking it triggers a smooth 1.5-second scroll to the target instead of an instant jump.

Customization options

  • Adjust lerp to control scroll smoothness.
    • Lower value → smoother, more "floaty" scroll
    • Higher value → snappier, more direct scroll
  • Adjust wheelMultiplier and touchMultiplier to change scroll speed for mouse wheel and touch input independently.
  • Change the anchor-link scroll duration (currently 1.5) to speed up or slow down jump-to-section scrolling.
  • Adjust the anchor offset if you need scroll targets to stop short of or past the element (e.g. to account for a sticky header).
  • Set infinite: true if you want the page to loop instead of stopping at the bottom.

Features

  • Smooth, inertia-based scrolling across the whole page
  • Automatically loads its own dependency (Lenis) with no manual script tag needed
  • Smooth-scrolls to any href="#id" anchor link automatically
  • Syncs with requestAnimationFrame for consistent, jank-free motion
  • Exposed globally as window.lenis for use in other scripts

FAQ tab toggle

How it works

This powers a two-tab FAQ/switcher (e.g. "Services" vs. "Support") that swaps visible answer panels and a sliding text-layer indicator. Clicking a tab measures the incoming panel's natural height, animates the wrapper smoothly to that height, slides the tab-label layer into position, and swaps which answer panel and side card are visible — all without a jarring layout jump.

Customization options

  • Set the initial active tab by adjusting the default display values in the "initial state" block.
  • Change the slide distance for the second tab (currently "9.3rem") to match your tab-label layout.
  • Adjust the height-transition duration (currently 0.4) for a faster or slower panel resize.
  • Change the ease (currently power2.out) for a different transition feel.
  • Add a fade transition between panels if you want a cross-fade instead of an instant swap.

Features

  • Smooth animated height transition between differently-sized panels
  • Sliding indicator synced to the active tab
  • Prevents scroll-position jumps via overflow-anchor handling
  • Debounced against double-clicks via an isAnimating guard
  • Recalculates cleanly on orientation change for mobile

Program hover tabs

How it works

This powers a hover-activated set of program/activity cards with a matching image panel. One card is active by default; hovering any other card swaps the active state — recoloring the previous card back to default, recoloring the new card and its text/icons to the active palette, and cross-fading in its corresponding image.

Customization options

  • Change the default active card by adjusting activeIndex (currently 2, i.e. the third card).
  • Change the active background color (currently #E85D7A) to match your brand palette.
  • Adjust the cross-fade duration (currently 0.4 for images, 0.3 for card colors) for faster or slower transitions.
  • Add more cards and matching images — the script automatically indexes them by position.

Features

  • Hover-to-switch active card with synchronized image cross-fade
  • Automatically restyles text and icon colors on state change
  • Smooth, independently-timed color and fade transitions
  • Default active state set on page load
  • Scales to any number of cards without code changes

Scroll-driven step timeline

How it works

This drives a multi-step, scroll-scrubbed story (e.g. a "how it works" process) inside a data-step="wrapper" element. As the user scrolls through the wrapper, a vertical progress line fills, and content steps hand off to one another in sequence: each step's text collapses and its image fades out exactly as the next step's text expands and its image fades in, with the background color shifting to mark the active step. The whole sequence is tied directly to scroll position (scrubbed, not just triggered), and only runs on viewports 992px and wider.

Customization options

  • Update totalSteps if you add or remove steps from the sequence.
  • Change colorActive and colorInactive to adjust the active/inactive step background colors.
  • Adjust the ScrollTrigger start/end (currently "top top" to "bottom bottom") to change how much scroll distance the sequence spans.
  • Change the scrub value (currently 1.2) for tighter or looser scroll-syncing.
  • Adjust each transition's ease (currently power2.inOut) for a different handoff feel.

Features

  • Fully scroll-scrubbed step-by-step narrative
  • Synchronized text, image, and background-color transitions per step
  • Animated vertical progress line
  • Desktop-only by default, with automatic cleanup below 992px
  • Ideal for process explainers, "how it works" sections, and feature walkthroughs

Scroll-driven step timeline

How it works

This drives a multi-step, scroll-scrubbed story (e.g. a "how it works" process) inside a data-step="wrapper" element. As the user scrolls through the wrapper, a vertical progress line fills, and content steps hand off to one another in sequence: each step's text collapses and its image fades out exactly as the next step's text expands and its image fades in, with the background color shifting to mark the active step. The whole sequence is tied directly to scroll position (scrubbed, not just triggered), and only runs on viewports 992px and wider.

Customization options

  • Update totalSteps if you add or remove steps from the sequence.
  • Change colorActive and colorInactive to adjust the active/inactive step background colors.
  • Adjust the ScrollTrigger start/end (currently "top top" to "bottom bottom") to change how much scroll distance the sequence spans.
  • Change the scrub value (currently 1.2) for tighter or looser scroll-syncing.
  • Adjust each transition's ease (currently power2.inOut) for a different handoff feel.

Features

  • Fully scroll-scrubbed step-by-step narrative
  • Synchronized text, image, and background-color transitions per step
  • Animated vertical progress line
  • Desktop-only by default, with automatic cleanup below 992px
  • Ideal for process explainers, "how it works" sections, and feature walkthroughs