Buy template

Instructions

This guide is here to give you basic instructions and help you understand the GSAP animations that were created using code in case you want to make edits to it.

1. Getting Started

Introduction

Nordic is a refined Webflow template crafted for bold studios and visionary teams. Featuring a high-contrast design system, seamless scroll animations, and editorial-inspired layouts, it’s made to elevate portfolios with precision and confidence. This template includes 6 polished pages — from pitch-ready case studies to studio insights — helping you present your work with authority.

Website homepage showing Nordic™ studio with a large tablet held by two hands and navigation menu including Home, About, Works, Blog, Contact, and contact options.
Preview of Nordic template

Webflow basics

If you're new to Webflow, we recommend watching the Getting Started with Webflow course on Webflow University. It covers the essential tools and concepts you'll need to confidently use and customize this template.

Glowing neon blue icons representing a cursor, pencil, database, rocket, group of people, sliders, and accessibility on a dark curved background.
Webflow online course thumbnail

2. Image trail animation (GSAP)

This part explains how to manage and customize the CTA mouse trail animation included in the template. You’ll learn how to update the images used in the effect, add the section to new pages, adjust the animation behavior, and safely modify the component without breaking its functionality.

A digital contact form overlay on a dark background with stacked images of people, technology, and lifestyle scenes, inviting users to start a project.
Mouse trail GSAP animation preview

Updating the images

To change the images used in the animation:

  • Open the CTA section component in Webflow by double-clicking the component on a page.
  • Use the Navigator panel to locate the element named .interaction_cms_list.
  • Inside it, you’ll find several .interaction_cms_item elements, each containing an image with the class .interaction_cms-img_img.
  • Select any image, go to the Settings tab in the right sidebar, and click Replace image to upload a new one.
  • To add more images, simply duplicate any .interaction_cms_item and update the image inside.

⚠️ The animation cycles through these images in order, so more images = more variation.

Adding the section and activating the animation

To use the CTA animation on another page:

  1. Add the CTA section component to your page from the Symbols or Components panel.
  2. Go to the page’s Settings (click the gear icon in the page list).
  3. Scroll to the Before </body> tag section and paste in the GSAP animation script.

✅ Here is the full animation code in case you need:

1<!-- Mouse trail CTA animation powered by GSAP -->
2<script>
3  $(".section_cta").each(function () {
4    // Select key elements inside each CTA section
5    let visualWrap = $(this).find(".interaction_visual_wrap"); // Container where the image clones will be animated
6    let template = $(this).find(".interaction_img_wrap"); // Image template to clone
7    let cmsItem = $(this).find(".interaction_cms_item"); // All CMS items with images
8    let activeItem = cmsItem.first(); // Start with the first CMS item
9
10    // Function to get the next image URL (loops through CMS items)
11    function getNextUrl() {
12      activeItem = activeItem.next(); // Move to the next item
13      if (activeItem.length === 0) activeItem = cmsItem.first(); // Loop back if at the end
14      return activeItem.find("img").attr("src"); // Return the image URL
15    }
16
17    // Track mouse position (relative to the visual wrap)
18    let xPosition = 0;
19    let yPosition = 0;
20
21    // Mouse move handler
22    $(this).on("mousemove", function (e) {
23      // Get mouse position relative to the visual wrap
24      let wrapOffset = visualWrap.offset();
25      let x = e.pageX - wrapOffset.left;
26      let y = e.pageY - wrapOffset.top;
27
28      let xDistance = xPosition;
29      let yDistance = yPosition;
30
31      // Only trigger animation if mouse moved significantly
32      if (Math.abs(xPosition - x) > 120 || Math.abs(yPosition - y) > 100) {
33        xPosition = x;
34        yPosition = y;
35
36        // Clone the image template and append to the visual container
37        let imageWrap = template.clone().appendTo(visualWrap);
38        imageWrap.find("img").attr("src", getNextUrl()); // Set image source
39
40        // Create GSAP timeline animation
41        let tl = gsap.timeline({ 
42          onComplete: () => { imageWrap.remove(); } // Remove the clone after animation completes
43        });
44
45        // Fade in the image clone
46        tl.fromTo(imageWrap, { opacity: 0 }, { opacity: 1, duration: 0.1 });
47
48        // Animate movement from previous to current mouse position
49        tl.fromTo(
50          imageWrap, 
51          { x: xDistance, y: yDistance }, 
52          { x: xPosition, y: yPosition, duration: 0.75, ease: "power2.out" }, 
53          "<" // Start at same time as previous animation
54        );
55
56        // Fade out the image
57        tl.to(imageWrap.find("img"), { opacity: 0, duration: 0.2 });
58      }
59    });
60  });
61</script>

Disabling the animation (optional)

If you want to temporarily disable the animation but keep the code:

  • Wrap the entire script in an HTML comment like this:
1<!-- 
2ALL THE CODE HERE
3-->

This will stop the animation from running but retain the code for later use.

Classes you should not change

To ensure the animation works correctly, do not rename or remove the following classes:

  • .section_cta
  • .interaction_visual_wrap
  • .interaction_img_wrap
  • .interaction_cms_list
  • .interaction_cms_item
  • .interaction_cms-img_img

❗Changing these class names may break the functionality of the script, since they are directly referenced in the code. We recommend you not changing any class inside the component to avoid bugs on the animation.

Customizing the animation behavior

You can fine-tune the animation by editing values inside the script:

  • Opacity fade in/out:
    opacity: 0 → 1 and back to 0
  • Movement speed:
    Adjust duration: 0.5 to increase or decrease how quickly the image moves
  • Trigger distance:
    The line Math.abs(xPosition - e.pageX) > 100 controls how far the mouse must move before a new animation is triggered

🛠 Feel free to experiment with values to match your site’s motion style. Just keep a backup of the original if needed.

3. Services marquee (GSAP)

The services section at the Homepage features a vertically scrolling services marquee powered by GSAP (as code). As each service title reaches the center of the list, it becomes active and automatically updates the accompanying description and image. The animation creates a smooth, editorial-style storytelling experience, guiding attention through each service while keeping content and visuals perfectly in sync.

A hand holds a colorful design mockup sheet against a blue sky next to text about tailored digital services for business focusing on design.
Services marquee animation preview

✅ Here is the full animation code in case you need:

1<!-- Services vertical marquee (GSAP) opaciting work-->
2<script>
3// set variables
4let items = $(".marquee_item");
5let textItem = $(".marquee_text-item");
6let wrap = $(".marquee_wrap");
7let imageItem = $(".marquee_image");
8let totalItems = items.length / 2 + 1;
9let duration = totalItems * 3.2;
10
11// switch which item is active
12function makeItemActive(myIndex) {
13  items.removeClass("is-active");
14  $(".marquee_list").each(function (index) {
15    $(this).find(".marquee_item").eq(myIndex).addClass("is-active");
16  });
17  textItem.removeClass("is-active");
18  textItem.eq(myIndex).addClass("is-active");
19  imageItem.removeClass("is-active");
20  imageItem.eq(myIndex).addClass("is-active");
21}
22makeItemActive(3);
23
24// check if item is in center of wrapper
25function checkPosition() {
26  let wrapCenter = wrap.offset().top + wrap.height() / 2;
27  items.each(function (index) {
28    let itemHeight = $(this).height() / 2;
29    let offsetTop = $(this).offset().top + itemHeight;
30    if (offsetTop < wrapCenter + itemHeight / 2 && offsetTop > wrapCenter) {
31      let myIndex = $(this).index();
32      makeItemActive(myIndex);
33    }
34  });
35}
36
37// create vertical loop
38let marquee = gsap.timeline({ repeat: -1 }).fromTo(
39  ".marquee_track",
40  { yPercent: 0 },
41  {
42    yPercent: -50,
43    duration: duration,
44    ease: "none",
45    onUpdate: () => {
46      checkPosition();
47    }
48  }
49);
50</script>

How to update services (name, description, and image)

This section is fully connected to the Webflow CMS. Here is how to update:

  • Open the Services CMS collection.
  • Each item controls one service in the animation.
  • Edit the name, description, and image fields.
  • Save the items to apply your changes

Animation speed

The content change speed is controlled by the GSAP timeline.

  • Open the page settings and locate the GSAP marquee script.
  • Find the line that defines the duration: let duration = totalItems * 3.2;
  • Lower the value (3.2) to make the animation faster.
  • Increase the value to make the animation slower.
  • Publish the site to apply changes.

Disabling the animation (optional)

If you want to temporarily disable the animation but keep the code:

  • Wrap the entire script in an HTML comment like this:
1<!-- 
2ALL THE CODE HERE
3-->

This will stop the animation from running but retain the code for later use.

Classes you should not change

To ensure the services marquee animation works correctly, do not rename or remove the following classes:

  • .marquee_wrap
  • .marquee_track
  • .marquee_list
  • .marquee_item
  • .marquee_text-item
  • .marquee_image
  • .is-active

❗Changing these class names may break the functionality of the script, since they are directly referenced in the code. We recommend you not changing any class inside the component to avoid bugs on the animation.

Lenis smooth scroll

This template uses Lenis to create a smooth, modern scrolling experience across all pages. Lenis replaces the browser’s default scroll behavior with a more fluid and refined motion, enhancing the feel of animations and transitions throughout the site.

Red digital screen with text 'LENIS' and smaller text below reading 'GET SMOOTH OR DIE TRYING'.

This is handled entirely through custom code added in your Site Settings.

Where the code is added

Head tag

In your Webflow Site Settings, under the Custom Code → Head section, the following code loads the Lenis script and stylesheet:

<!-- Lenis script and styles -->
<script src="https://unpkg.com/lenis@1.3.4/dist/lenis.min.js"></script> 
<link rel="stylesheet" href="https://unpkg.com/lenis@1.3.4/dist/lenis.css">

This makes the Lenis library available globally across your project.

Before </body> tag

Also in Site Settings, scroll to the Custom Code → Before </body> tag section and you'll see the initialization script:

<!-- Lenis setup -->
<script>
// Initialize Lenis
const lenis = new Lenis({
  smooth: true,
  lerp: 0.1,
  wheelMultiplier: 1,
  infinite: false,
});

// Use requestAnimationFrame to continuously update the scroll
function raf(time) {
  lenis.raf(time);
  requestAnimationFrame(raf);
}

requestAnimationFrame(raf);
</script>

This script starts the smooth scrolling effect and keeps it running as the user interacts with the page.

How to disable the animation (optional)

To temporarily disable Lenis without deleting your code:

  • Comment out both script blocks like this:
<!-- 
ALL THE CODE HERE
-->

This will stop the animation from running but retain the code for later use. You can also just delete the entire code and put it back again if you want to have the smooth scroll in the future.

How to adjust the scroll speed

The scroll behavior can be fine-tuned inside the second script:

lerp: 0.1,

This controls how smooth and slow the scroll feels:

  • Lower values (e.g. 0.05) = slower and smoother
  • Higher values (e.g. 0.2) = snappier and faster

You can also tweak:

wheelMultiplier: 1,

This controls how sensitive scroll input is on the mouse/touchpad. Increase the value to make it scroll farther with each scroll input.

Support

If you run into any issues or have questions while customizing the template, feel free to reach out. We are here to help! Just send a message through the support form on our website, and we’ll get back to you as soon as possible.

Support page with form for selecting help topic, entering name, email, and message, contact email and response time, Brazil office address with clock, local time clock, and FAQ section with questions on template customization, usage, Figma design, service customizations, and refund policy.
Template Supply support page