Overview
Where the code lives
What is included
- Magic Navigation — GSAP-powered desktop mega-menu and mobile drawer, both bound to data attributes.
- Inverted Navigation — automatically switches the nav bar to its light/dark variant over marked sections.
- GSAP Interactions — scroll animations built inside Webflow Interactions, triggered by data attributes.
- Draggable Marquee — a horizontal marquee you can drag and throw, powered by GSAP Observer and ScrollTrigger.
- Vertical Ticker — an auto-scrolling, looping card ticker with a centred active state.
- Industry Switcher — hover a list item and its matching background image crossfades in.
- Typing Dots — an animated, chat-style “typing…” indicator.
- Infinite Slider — clones a native Webflow slider's slides so it loops endlessly.
- Smooth Scroll — Lenis smooth scrolling connected to GSAP's ticker.
- Type Smoothener — minimal global font-smoothing declarations.
Required libraries
Number Odometer
Required attributes
data-odometer (required)— the element containing the number; its text content is the end value the digits roll to.data-odometer-group (optional)— wrapper around multiple odometers; when present, the group itself is used as the scroll trigger so all odometers inside animate together.
Tuning
data-odometer-start (optional)— the digit each strip starts on. Defaults to 0.data-odometer-duration (optional)— roll duration in seconds. Defaults to 1.2.data-odometer-ease (optional)— any GSAP easing string. Defaults to power3.outdata-odometer-stagger (optional)— delay in seconds between each digit starting its roll. Defaults to 0.03.
Draggable Marquee
What it does
Build the marquee as a track containing one set of items. The script clones that set automatically until the track is wide enough to loop seamlessly, so you never duplicate content by hand.
data-marquee="true"— the marquee wrapper.data-marquee-track— the moving track inside it.data-marquee-list— the one set of items to loop; gets cloned as needed.data-speed="60"— pixels per second (optional, defaults to 60).data-direction="left"— or"right"(optional, defaults to left).
Dragging and pausing
How to remove
data-marquee attribute from a specific wrapper to stop just that one.GSAP Interactions
For quick reference, the six attributes and where each one goes:
data-gsap="fade"— single element fade-in.data-gsap="stagger"— parent element, animates direct children.data-gsap="text"— text wrapper, runs heading split + tag fade + body reveal.data-gsap="parallax"— wrapper with.media-fillchild, subtle parallax.
Why data attributes
- Non-destructive — adding or removing an attribute never affects an element's classes or styling.
- Reusable — the same animation can be applied to any element on any page without touching the interaction itself.
- Easy to audit — you can scan the Webflow Designer's attribute panel to see which elements animate and how.
Where the interactions are defined
[DATA-GSAP]. They use Webflow's "Element Trigger → On Scroll" with the trigger set to a custom attribute selector. The animation logic itself is built with GSAP timelines inside the Action.Fade
A simple fade-in. The element appears with an opacity transition as it enters the viewport. It is the workhorse animation of the template and the safest default when you want something to feel intentional without drawing attention to the motion itself.
- Attribute:
data-gsap="fade" - Best for: images, individual cards, body text, single buttons, section content blocks.
- Visual: the element fades from invisible to fully visible as it enters the viewport.
- To remove: delete the
data-gsapattribute from the element.
Stagger
Animates multiple child elements in sequence. The trigger element itself does not animate — its direct children do, one after the other. This is the right choice for any list-like layout where items should reveal as a group.
- Attribute:
data-gsap="stagger"(placed on the parent / wrapper element). - Best for: grids of cards, feature lists, gallery rows, navigation lists, tag groups.
- Visual: children fade and slide in one after another in source order.
- To remove: delete the attribute from the parent. Children return to their static state.
- Note: the script targets direct children, so wrap your items in a single parent and avoid nesting extra wrapper divs around individual items.
Text
A composite text animation built for typographic content. It runs three coordinated actions: a heading split, a tag fade, and a body text reveal. Use it on text-heavy sections where you want a refined, progressive reading experience.
- Attribute:
data-gsap="text"(on the section or text wrapper). - Best for: hero sections, section intros, editorial blocks, anywhere a heading, eyebrow tag and paragraph appear together.
- Visual: the heading reveals in a split, the eyebrow tag fades in, and the supporting body text animates in sequence.
- To remove: delete the attribute from the wrapper.
- Note: works best when applied to a wrapper that contains a heading, an optional tag and supporting text. If the wrapper holds only one of these, the unused actions simply have nothing to animate.
Parallax Media
Adds a subtle vertical parallax movement to media as the viewport scrolls past it. The interaction looks for an inner .media-fill element inside the trigger and moves it relative to the scroll position. The outer trigger element does not move — only the media inside.
- Attribute:
data-gsap="medium" - Required structure: the trigger element must contain a child with the class
.media-fill. - Best for: hero images, section background imagery, large editorial photos, any framed media.
- Visual: the inner media drifts vertically against the scroll, giving the section gentle depth.
- To remove: delete the attribute from the trigger element.
Magic Navigation
Desktop behaviour
- On hover of a
[data-menu]element, the panels wrapper expands to the height of the matching panel, which fades in. The overlay fades in behind the page. - Moving the cursor off the nav starts a 120 ms timer; if the cursor does not return, the panel closes and the nav loses its
solidclass. - Hovering a
[data-menu-close]link closes the active panel immediately.
Tuning
- Hover delay before close — change the
120value (ms) in the desktopmouseleavehandler. - Open / close durations — adjust the
durationvalues insideopenMenu,closeMenu,openPanel, andclosePanel. - Breakpoint — the desktop script fires at
min-width: 992px, mobile atmax-width: 991px. Change both values together if you move your breakpoint.
Required attributes
data-nav-content— desktop nav wrapper. Scope for the desktop script.data-nav-panels— panels container. The expanding area below the nav bar.data-navigation-overlay— full-page overlay (optional). Dims the page behind an open panel.data-menu="[name]"— each nav menu trigger. Opens the panel with the matching name on hover.data-panel="[name]"— each panel. Must match adata-menuname exactly.data-mobile-nav— mobile nav wrapper. Scope for the mobile script.data-mobile-menu— mobile menu drawer. The content that expands on open.data-mobile-menu-toggle— hamburger / close button. Toggles open and close.
Regular links in the top navigation — any link inside data-nav-content that doesn't carry data-menu — close the open dropdown automatically when hovered. No extra attribute needed. Links inside the dropdown panels are excluded from this, so moving into a panel to click something never closes it early.
Mobile behaviour
- The script is scoped to viewports ≤ 991px and does nothing on desktop.
- The nav bar is locked to its closed height, measured automatically from the DOM — no CSS variable to set. On toggle it expands to
scrollHeightand the menu drawer fades in, while the hamburger icon animates into an X. On close, everything reverses.
No CSS variable needed
data-mobile-nav.To remove
- Desktop mega-menu — delete the Magic Navigation desktop script block and the
data-nav-content,data-nav-panels,data-menu,data-panel, anddata-navigation-overlayattributes. - Mobile drawer — delete the Magic Mobile Navigation script block and the
data-mobile-nav,data-mobile-menu, anddata-mobile-menu-toggleattributes.
Industry Switcher
Required attributes
data-industry-list— the list wrapper.data-industry-item— each hoverable item, paired with adata-industry-indexnumber.data-industry-bg— each background layer, using the samedata-industry-indexnumber as its matching item.data-industry-default-bg— the background shown when nothing is hovered.data-industry-scope(optional) — wraps the backgrounds if they don't live in the same section as the list.
How it behaves
- Hovering an item brings its background to full opacity and dims the other list items.
- Leaving the whole list waits 2 seconds before fading back to the default background, so briefly moving between items doesn't flicker back and forth.
- Hovering triggered by page scroll — the cursor staying still while the list scrolls under it — is ignored, so scrolling never fires a hover by accident.
Tuning
- Dim opacity — change the 0.32 value for inactive list items.
- Return delay — change the 2 (seconds) value before the default background returns.
How to remove
data-industry-list, data-industry-item, data-industry-bg, data-industry-default-bg, and data-industry-index attributes.Inverted Navigation
Required attribute
data-nav="inverted" to any full-width section the navigation should invert over. The value must be the exact string inverted.How it behaves
data-nav="inverted", the nav bar gets an inverted class; otherwise it doesn't. It also re-checks after the page finishes loading and after any ScrollTrigger refresh, so late-loading images or dynamic content won't leave it stuck in the wrong state.How to remove
data-nav="inverted" attribute from any sections using it.Infinite Slider
Required attributes
data-slider-loop="true"— put this on the .w-slider element itself.data-slider-clones— how many full slide sets to clone on each side (optional, defaults to 3).data-slider-start— which original slide to open on, zero-based (optional, defaults to 0).
How it works
How to remove
data-slider-loop, data-slider-clones, and data-slider-start attributes. The slider falls back to Webflow's regular, non-looping behaviour.Vertical Ticker
Required attributes
data-ticker— the ticker wrapper.data-ticker-list— the moving list inside it.data-ticker-card— each card; the script clones your set automatically to loop endlessly.data-interval="2.2"— seconds between steps (optional).data-shift="0.6"— seconds per step animation (optional).
How it behaves
is-active class partway through each step. The ticker pauses automatically via ScrollTrigger whenever it's scrolled out of view.How to remove
data-ticker, data-ticker-list, and data-ticker-card attributes.Typing Dots
Required attributes
data-typing— the chat bubble wrapper.data-typing-dot— each dot inside it (usually three).
Each dot rises, falls, and pauses in sequence, offset from the next by 0.12s, so the wave visibly travels left to right before it loops.
Tuning
- Wave speed — change the 0.22 / 0.28 duration values on the rise and fall tweens.
- Offset between dots — change the 0.12 stagger value used for each dot's start time.
- Pause between loops — change the 0.5s pause at the end of the timeline.
How to remove
data-typing and data-typing-dot if you're also removing the markup.Lenis Smooth Scroll
What it does
- Paste the script below before the closing
</body>tag in Site Settings → Custom Code. - Make sure GSAP and ScrollTrigger are loaded before this snippet.
- Only one global smooth scroll instance per page — do not duplicate.
The script
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lenis@1.2.3/dist/lenis.css" />
<script src="https://cdn.jsdelivr.net/npm/lenis@1.2.3/dist/lenis.min.js"></script>
<script>
/**
* 108™ Smooth Scroll
*
* What this is:
* - Lenis smooth scrolling connected to GSAP.
*
* What it does:
* - Creates smoother page scrolling.
* - Keeps ScrollTrigger in sync with Lenis.
* - Uses GSAP's ticker to drive Lenis on every frame.
*
* Instructions:
* - Load Lenis before this script.
* - Load GSAP and ScrollTrigger before this script.
* - Add this globally in the project head or before the closing body tag.
* - Use only one global smooth scroll setup per page.
*/
const lenis = new Lenis();
lenis.on('scroll', ScrollTrigger.update);
gsap.ticker.add((time) => {
lenis.raf(time * 1000);
});
gsap.ticker.lagSmoothing(0);
</script>How to remove
Light and Dark
body to invert the entire site. Instead, dark sections are achieved with Webflow Variable Modes — specifically, by setting a section's variable color mode to Inverted Mode.How it works
- The template defines all colors as variables — surface, text, border, accents — rather than hard-coded hex values.
- Light sections use the default variable mode.
- Dark sections are individual sections with their variable mode set to Inverted. Every variable inside that section resolves to its inverted equivalent.
- Child elements automatically inherit the inverted values, so no extra dark-mode classes are needed.
Why this approach
Customizing dark colors
Adding a new dark section
- Add or duplicate a section in the Designer.
- Select the section and switch its Variable Mode to Inverted.
- Do not assign any extra dark-mode utility classes to the children — they will resolve correctly through inheritance.
What to avoid
SVG Icons and Logos
Why Code Embeds, not images
- currentColor — inline SVGs can use
fill="currentColor"andstroke="currentColor", which inherits the CSScolorof the parent. The icon adopts whichever variable is active in that section. - Image uploads can't do this — media browser SVGs render as
<img>tags, which cannot inherit colors. - Sharpness and scaling — same advantages as any SVG: clean at any size, any pixel density.
How to swap an icon
- Select the icon, click the gear icon on the Code Embed.
- Delete the existing code, drag your new SVG file into the code box. If drag-drop fails, open the SVG in a text editor and paste the code in.
How to make any new SVG fit the template
Most SVG files ship with hard-coded colors and explicit dimensions. A couple of edits make any new icon behave like the ones already in the template:
- Recolor — replace every
fill="#..."andstroke="#..."withfill="currentColor"andstroke="currentColor". The icon now follows the active color variable. - Resize — remove the
widthandheightattributes from the opening<svg>tag. Keep theviewBox. The icon now respects the size set by its parent class.
Quick checklist
- Code Embed, not Image element.
- All colors →
currentColor. widthandheightremoved from the SVG tag,viewBoxkept.- Logos only:
style="height:100%;"added, unique class with ratio set.
How to Remove or Disable Effects
Remove smooth scrolling
Remove the Draggable Marquee
data-marquee attribute from a specific wrapper to stop just that one loop.Remove a single scroll animation
data-gsap attribute from the element.Remove all scroll animations
[DATA-GSAP]. The data attributes can stay on the elements — without an interaction listening to them, they have no effect.Remove the Magic Navigation
data-nav-content, data-nav-panels, data-menu, data-panel, data-navigation-overlay, data-mobile-nav, data-mobile-menu, and data-mobile-menu-toggle from the elements.Remove the type smoothener
108™ Type Smoothener style block from the global custom code. Typography returns to browser defaults.Remove the Vertical Ticker
data-ticker, data-ticker-list, and data-ticker-card attributes. The cloned cards it generates at runtime disappear with it — nothing to clean up by hand.Remove the Industry Switcher
data-industry-list, data-industry-item, data-industry-bg, data-industry-default-bg, and data-industry-index attributes.Remove Typing Dots
data-typing and data-typing-dot attributes.Remove Inverted Navigation
data-nav="inverted" attribute from any sections using it. The nav bar keeps whatever variant it's set to by default.Remove the Infinite Slider
data-slider-loop, data-slider-clones, and data-slider-start attributes. The slider falls back to Webflow's regular, non-looping behaviour.Best Practices
Don't duplicate global scripts
Use attributes over classes for animation
Keep the nav attribute names exact
data-menu and data-panel attributes. If the values don't match exactly (including capitalisation), the panel will not open.Use variables, not hex codes
Test scroll animations in Preview
One Lenis instance only
Don't delete the state classes the scripts add
solid, open, is-active, inverted, and is-clone don't exist anywhere until a script adds them at runtime — so it's easy to assume they're unused and delete them from the Designer's style panel. Leave them defined even at 0 elements; the moment a script toggles one on, it needs real CSS to fall back on. The same goes for the "ready" flags scripts set on themselves (data-marquee="ready", data-industry-list="ready", data-ticker="ready") to avoid initialising twice — don't hand-edit those values.Match data-nav="inverted" exactly
data-nav="inverted" — not "invert", not "true". Copy the attribute value exactly, including capitalisation, or the section is silently ignored.Leave marquee, slider, and ticker clones alone
data-marquee-clone, data-ticker-clone, or is-clone. Only edit the original set — editing or deleting a clone by hand just gets overwritten, or breaks the loop, the next time the page reloads.


