Setup Guide

Instructions

Everything you need to edit, tune, or strip the motion that gives Noir Bean its editorial feel — written for designers who may have never touched GSAP. No JavaScript required.

This is some text inside of a div block.
Inventory

Where every custom code lives

A complete location map of each custom code entry. Open Webflow Designer, follow the path shown in the left column, and you will find the contents listed in the middle column.

Location
Contents
Purpose
Site Settings → Custom Code → Head Code
GSAP 3.12.5 CDN (core + ScrollTrigger) & font-smoothing <style>
Loads the GSAP animation library for the whole site and applies -webkit-font-smoothing: antialiased to the body for crisp serif rendering. Two <script> tags plus a three-line <style> block.
Home page → Page Settings → Before </body>
hero-bundle.js (single IIFE, ~950 lines)
This is some text inside of a div block.
Assets Manager → Images
hero-numeral-01.svg · flourish-divider.svg
This is some text inside of a div block.
Page Settings → SEO → Exclude from indexing
Noindex meta on Licenses, Changelog, Password, 404, Instructions
Toggled via Webflow’s native page settings. No custom code written — the Webflow compiler injects <meta name="robots" content="noindex"> automatically on publish.
This is some text inside of a div block.
GSAP Animations

How to Edit GSAP Animations

Noir Bean’s motion is orchestrated by a single 950-line JavaScript bundle pasted into the Home page’s Before </body> slot. The three subsections below map every animated selector, show the exact knobs for speed and timing, and explain how to safely disable motion without breaking the layout.

This is some text inside of a div block.
Element Map

Element Map

Selectors are grouped by module. Each row pairs an element with a short description of the motion it carries. Open hero-bundle.js to find the exact gsap.to or gsap.timeline call that drives each one.

Preloader · The Batch Drop

First-visit curtain reveal that splits open to expose the hero. Session-stored so it only plays once per tab.

#preloader
Root container — autoAlpha 0 + display: none on timeline complete.
[data-preloader-gutter]
Left decorative gutter — autoAlpha 0→1, x -12→0 (0.7s power2.out).
[data-preloader-meta]
Header meta line — autoAlpha 0→1, y 12→0, offset 0.15s.
[data-preloader-numeral]
Large issue numeral — autoAlpha 0→1, scale 0.9→1 (0.9s power3.out).
[data-preloader-hairline]
Horizontal rule — scaleX 0→1 (1.4s power1.inOut).
[data-preloader-phase]
Three rotating phase strings — sequenced autoAlpha cycle (0.25s each).
[data-preloader-curtain]
Top + bottom split curtains — yPercent ±100 on complete (0.5s expo.out).

Hero · Page-load Choreography

Orchestrated entrance timeline that stages every hero element in sequence. Runs once per page load after the preloader splits.

.hero_backdrop_image, .hero_backdrop_video
Cinematic zoom-out — scale 1.18→1.04 (2.6s power3.out).
[data-parallax="backdrop"]
Lerped mouse parallax — ±10px X / ±6px Y on pointer-fine only.
[data-animate="hero-eyebrow"]
Fade + rise — autoAlpha 0→1, y 24→0 (1.0s).
[data-animate="hero-top-meta"]
Fade + rise — offset 0.1s after eyebrow.
[data-animate="hero-gutter"]
Slide from left — x -12→0, alpha 0→1 (1.4s).
[data-animate="hero-numeral"]
Scale 1.18→1 + fade (2.4s power3.out).
.hero_heading_line_inner
Line-by-line mask reveal — yPercent 115→0 (1.3s, 0.13s stagger between lines).
[data-animate="hero-intro"], [data-animate="hero-cta"]
Fade + rise, offset 1.2s / 1.35s into timeline.

Hero · Polaroid Stack

Three polaroid cards drop from infinity into a loose stack, then fan out when the user hovers the cluster.

.hero_accent_card.is-back
Drop entrance — y -1400→0 (2.2s expo.out, delay 0.8s). Hover: xPercent 8, yPercent 18, rotate 5°.
.hero_accent_card.is-middle
Drop entrance — delay 1.15s. Hover: xPercent -22, yPercent -8, rotate -9°.
.hero_accent_card.is-front
Drop entrance — delay 1.5s. Hover: xPercent 16, yPercent -8, rotate 13°, scale 1.10.
.hero_accent (mouseenter / mouseleave)
Cluster listener — tweens each card to hover or rest state (0.7s power2.out, overwrite auto).

Hero · Ticker & Scroll Indicator

Two continuous loops — a horizontal marquee at the hero footer and a vertical pulse inside the scroll indicator.

.hero_ticker_track
Infinite marquee — xPercent 0→-50 (60s linear, repeat -1).
.hero_scroll-indicator_line_fill
Vertical traveling line — yPercent -100→150→-100 yoyo (1.2s power1.inOut, repeat -1).
.hero_scroll-indicator, .hero_location-tag
Stagger fade-in — autoAlpha 0→1, y 12→0 (1.0s, 0.08s stagger at 1.7s).
.hero_ticker
Fade-in at 1.85s into master timeline (autoAlpha 0→1, 1.0s).

Story · The Editorial Pin

Sticky visual on the right, narrative chapters on the left. Scroll progress crossfades four frames in sync with chapter activation.

.story_meta
Intro reveal on enter — autoAlpha 0→1, y 20→0 (1.0s power3.out).
.story_title .story_title_line_inner
Line-level mask reveal — yPercent 115→0 (1.4s, 0.14s stagger).
.story_chapter (×4)
Progress-based dimming — active autoAlpha 1 / inactive 0.4 (0.7s power2.out).
.story_chapter_indicator
Brand-color left bar — scaleY 0↔1 synced to active chapter.
.story_frame (×4)
Crossfade stack — active autoAlpha 1 + scale 1 (2.4s) / inactive 0 + scale 1.06 (0.9s).
.story_frame_caption
Caption autoAlpha synced with frame + 0.2s delay after active fade.
.story_narrative (ScrollTrigger)
Maps scroll progress to chapter index — start: top 70%, end: bottom 60%.
.story_signature_rule
Horizontal bar — scaleX 0→1 on footer enter (0.9s power2.inOut, once).

Origin · Pinned Cinematic Scrub

Four origin scenes stacked absolute, crossfaded via a scrubbed pinned timeline across 400% viewport height. HUD text variants swap via autoAlpha — no text mutation.

.section_origin (ScrollTrigger pin)
Pinned 400vh — pin: true, pinType: fixed, scrub 0.6, anticipatePin 1.
.origin_scene (×4)
Crossfade autoAlpha 0↔1 scrubbed along timeline (ease: none).
.origin_scene_image
Scale 1.08↔1 on active scene / 1→0.98 on leaving.
.origin_numeral, .origin_label, .origin_caption, .origin_counter
HUD variant swap — autoAlpha 0↔1 on active index (0.4s power2.out).
.origin_progress_fill
scaleX 0.25→1 tied to ScrollTrigger progress (live onUpdate).

Menu · Editorial Header + Categories

Header sequence (eyebrow → title lines → aside) then six menu categories stagger-reveal on scroll enter.

.menu_header .eyebrow
Fade + rise — autoAlpha 0→1, y 18→0 (0.9s power3.out).
.menu_title .menu_title_line_inner
Line mask reveal — yPercent 115→0 (1.3s, 0.14s stagger), offset 0.1s.
.menu_header_aside
Fade + rise — offset 0.25s.
.menu_category (×6)
Stagger reveal — autoAlpha 0→1, y 40→0 (1.1s, 0.1s stagger).
.menu_footer
Fade + rise on footer enter — 1.0s power3.out.

Selection · Cards Stagger & Hover

Header reveals above, card grid staggers in on scroll, each card scales its media and shifts its arrow on hover.

.selection_header (eyebrow, title, aside)
Sequenced reveal — eyebrow, title lines (0.14s stagger), aside.
.selection_card + .selection_panel
Stagger reveal on grid enter — autoAlpha 0→1, y 48→0 (1.1s, 0.08s stagger).
.selection_card_media_inner (hover)
Scale 1→1.045 on mouseenter (0.9s power2.out, overwrite auto).
.selection_card_cta_arrow (hover)
Translate x 0→6 on mouseenter (0.4s power2.out).
.selection_footer
Fade + rise on footer enter — 1.0s power3.out.

CTA · The Ritual Reveal

Sequential reveal of eyebrow, heading, intro, meta items, and button, with the visual column rising in parallel. Once-only on scroll enter.

.cta_eyebrow
Fade + rise — autoAlpha 0→1, y 20→0 (0.9s power3.out).
.cta_visual
Fade + rise — offset 0.15s, duration 1.2s.
.cta_heading
Fade + rise — y 28→0, offset 0.2s (1.1s).
.cta_intro
Fade + rise — offset 0.4s, 1.0s.
.cta_meta_item
Stagger reveal — 0.8s duration, 0.1s stagger, offset 0.55s.
.cta_actions
Fade + rise — offset 0.75s, 0.9s.

Gallery · Horizontal Pin

Header reveal above stage, then stage pins while track translates horizontally. Slide images scale on scrub via containerAnimation.

.gallery_header (eyebrow, title, aside)
Sequenced reveal — eyebrow, title lines (0.14s stagger), aside.
.gallery_stage (pin)
Pin trigger — start: top top, end: +=track-distance, pinType: fixed, scrub 0.6.
.gallery_track
Horizontal translate — x 0→-(scrollWidth - stageWidth), ease: none, scrubbed.
.gallery_slide_image
Scale 1.06→1 via containerAnimation scrub (start: left 85%, end: right 40%).
.gallery_progress_fill
scaleX tied to horizontal scroll progress (live onUpdate).

Voices · Editorial Pull-Quotes

Header sequence then three pull-quotes batch-reveal on scroll via ScrollTrigger.batch.

.voices_header (eyebrow, title, aside)
Sequenced reveal — standard editorial header sequence.
.voices_item (×3)
Batch reveal — autoAlpha 0→1, y 40→0 (1.2s, 0.12s stagger on enter).
.voices_footer
Fade + rise on footer enter — 1.0s power3.out.

Contact · Header & Pair Reveal

Header sequence, then info column and reserve form pair-reveal together on scroll enter.

.contact_header (eyebrow, title, aside)
Sequenced reveal — standard editorial header sequence.
.contact_info + .contact_form_wrap
Paired stagger reveal — autoAlpha 0→1, y 32→0 (1.1s, 0.12s stagger).

Global · Nav Active State & Custom Cursor

Two persistent site-wide behaviors running outside of any timeline. Cursor is pointer-fine only (disabled on touch).

.navbar_link
Active class toggle — is-active added when linked section is in viewport (start: top 40%, end: bottom 40%).
#site-cursor
Follower — gsap.quickTo on x/y (0.45s power3.out). Hidden on mouseleave.
.site_cursor_ring (hover targets)
Scale 1→1.8 on hover over a, button, input, select, textarea, .navbar_link (0.4s power2.out).
.site_cursor_dot (hover targets)
Scale 1→0 on hover — dot vanishes as ring enlarges for clean state.
.site_cursor_ring (mousedown / mouseup)
Scale 1→0.75 on press, returns to 1 on release (0.2–0.3s power2.out).
This is some text inside of a div block.
Customizing Key Variables

Customizing Key Variables

Each block below lists a common edit, its exact location in hero-bundle.js, and the line of code to change. Values follow GSAP conventions — duration in seconds, ease from the GSAP easing library, stagger in seconds between siblings.

01 · Entrance Speed

Slow or speed up the hero load-in

The master hero timeline carries a delay that controls how long the browser waits before starting the orchestrated reveal. Higher values give the preloader more breathing room before hero elements stage in.

hero-bundle.js · inside runHero() · the master timeline declaration

hero-bundle.js
Edit
var tl = gsap.timeline({
  defaults: { ease: "power2.out" },
  delay: 0.5          // was 0.25 — raise to wait longer before entrance
});
02 · Ticker Speed

Make the bottom ticker faster or slower

The marquee at the hero footer loops continuously. Its duration is the number of seconds for one full pass of the track. Lower the value for a faster scroll, raise it for a slower reading pace.

hero-bundle.js · inside the “Ticker infinite marquee” block

hero-bundle.js
Edit
gsap.to(tickerTrack, {
  xPercent: -50,
  duration: 40,       // was 60 — lower = faster, higher = slower
  ease: "none",
  repeat: -1
});
03 · Heading Reveal

Tighten or loosen line-by-line stagger

Each hero heading line is masked and slides up in sequence. Raise the offset between lines for a more theatrical feel, lower it for a crisp, near-simultaneous reveal.

hero-bundle.js · inside runHero() · three tl.to calls for hero-line-1/2/3

hero-bundle.js
Edit
tl.to('[data-animate="hero-line-1"] .hero_heading_line_inner', { yPercent: 0, duration: 1.3, ease: "power3.out" }, 0.55)
  .to('[data-animate="hero-line-2"] .hero_heading_line_inner', { yPercent: 0, duration: 1.3, ease: "power3.out" }, 0.68)
  .to('[data-animate="hero-line-3"] .hero_heading_line_inner', { yPercent: 0, duration: 1.3, ease: "power3.out" }, 0.81);
// Position numbers 0.55 / 0.68 / 0.81 = gap between line reveals (0.13s each).
04 · Polaroid Hover

Adjust how far polaroids fan out on hover

The three accent cards rest in a loose stack and fan out when the cluster is hovered. Each card has its own rest and hover offset — xPercent shifts horizontally, yPercent vertically, rotate tilts, scale zooms.

hero-bundle.js · inside runHero() · the cardStates object

hero-bundle.js
Edit
var cardStates = {
  back:   { hover: { xPercent:   8, yPercent:  18, rotate:  5, scale: 1    } },
  middle: { hover: { xPercent: -22, yPercent:  -8, rotate: -9, scale: 1    } },
  front:  { hover: { xPercent:  16, yPercent:  -8, rotate: 13, scale: 1.10 } }
};
// Lower xPercent / yPercent = tighter fan. Lower rotate = more parallel.
05 · Story Crossfade

Make story frame transitions cinematic or snappy

As the reader scrolls through the four chapters, frames crossfade behind them. The active frame animates in slowly (2.4s) while the outgoing frame clears quickly (0.9s). Match these values for an equal dissolve, or raise the active duration for a more cinematic zoom-in.

hero-bundle.js · inside runStory() · the activate() helper · frames.forEach

hero-bundle.js
Edit
frames.forEach(function (fr, i) {
  gsap.to(fr, {
    autoAlpha: i === idx ? 1    : 0,
    scale:     i === idx ? 1    : 1.06,
    duration:  i === idx ? 2.4  : 0.9,    // active vs inactive speed
    ease: "power2.out",
    overwrite: "auto"
  });
});
06 · Story Scroll Window

Give readers more time per chapter

The story section maps scroll progress to chapter index. Push the end value lower (for example "bottom 40%") to give each chapter more reading time before the next activates. Raise the start value to delay when the scroll-linked activation begins.

hero-bundle.js · inside runStory() · the main ScrollTrigger.create call

hero-bundle.js
Edit
ScrollTrigger.create({
  trigger: narrative,
  start: "top 70%",     // when narrative top hits 70% of viewport
  end:   "bottom 60%",  // when narrative bottom hits 60% — push lower for more reading time
  onUpdate: function (self) {
    var idx = Math.min(chapters.length - 1, Math.floor(self.progress * chapters.length));
    activate(idx);
  }
});
07 · Story Title Stagger

Tighter or more theatrical title reveal

When the story section enters the viewport, its multi-line heading reveals line by line. The stagger value controls how much time passes between each line — lower it for a snappier reveal, raise it for a stretched, editorial pace.

hero-bundle.js · inside runStory() · intro timeline tl.to(titleLines, …)

hero-bundle.js
Edit
.to(titleLines, {
  yPercent: 0,
  duration: 1.4,
  stagger: 0.14      // lower (0.08) = tighter · higher (0.22) = more theatrical
}, 0.15);
08 · Duration & Easing Reference

Which numbers make sense where

Use this cheatsheet when tuning any tween in the bundle. Durations outside these ranges will feel either robotic (too fast) or lazy (too slow). Easing should almost always stay in the power family — they are gentle, modern, and match editorial motion.

General reference — applies to any gsap.to, tl.to, or ScrollTrigger config

GSAP conventions
Reference
// DURATION (seconds)
micro-interaction    0.2 — 0.5    // hover scale, button press, arrow shift
scroll reveal        1.0 — 1.6    // fade + rise for incoming content
page-load entrance   1.8 — 2.6    // cinematic hero choreography

// EASING
power2.out    // standard scroll reveal · smooth decelerate
power3.out    // more deceleration · cinematic page-load
power1.inOut  // looped pulses, yoyo, scroll-linked
sine.inOut    // natural, organic — progress bars, ambient
expo.out      // dramatic — use sparingly for "landing" moments

// STAGGER (seconds between siblings)
tight        0.04 — 0.08      // character or small-item chorus
medium       0.1  — 0.14      // section headers, card grids
theatrical   0.18 — 0.22      // editorial title lines

// FORBIDDEN — never use in this template
bounce / elastic  // feels toyish, breaks editorial tone
power4 / expo.in  // too aggressive for scroll reveals
This is some text inside of a div block.
Removing GSAP Animations

Removing GSAP Animations

Follow the steps below to remove every GSAP animation from the template. To disable just one, comment out the relevant gsap.to line in hero-bundle.js — selectors are listed in Element Map above.

STEP 01

Open the Webflow Designer, select the Home page in the left panel, then open Page Settings (gear icon) and scroll down to Before </body>.

STEP 02

Delete the entire <script>…</script> block that you see in that field. This is the animation bundle — remove it to disable every GSAP tween and ScrollTrigger on the Home page.

STEP 03

In the top-left menu, open Site Settings → Custom Code → Head Code. You will see two <script src=…gsap…> lines and a short <style> block.

STEP 04

Delete only the two GSAP CDN <script> lines. Keep the font-smoothing <style> block — it controls serif rendering quality and is independent of motion.

STEP 05

Click Save Changes on both fields, then publish the site. The live version will now render all elements at their static CSS rest positions — no animation, no layout breaks.

After removing motion

All elements fall back to their CSS default positions — readable and accessible, but without choreographed reveals. Preloader, hero stack, and story pin will show their rest states immediately on page load. No layout breaks, no missing content.

Disable one animation only

Comment a single gsap.to to kill its motion

If you want to keep most animations and only disable one — say, the ticker marquee — open hero-bundle.js, find the relevant gsap.to block (selectors match the Element Map above), and prefix the line with two forward slashes. Save and republish. The rest of the motion stays untouched.

hero-bundle.js · example: disabling only the ticker marquee

hero-bundle.js
Edit
// gsap.to(tickerTrack, {
//   xPercent: -50,
//   duration: 60,
//   ease: "none",
//   repeat: -1
// });
// Now the bottom ticker stays static; every other hero animation remains.
Side effects by module

What each section looks like without motion

If you disable motion entirely — or per module — the page still renders and remains readable. The list below summarises how each animated module falls back when its GSAP call is removed or commented out.

Preloader
Hidden instantly on load. The hero appears immediately with no curtain reveal. Session flag is set, so future visits already skipped.
Hero
All elements render at their CSS rest positions. No heading mask reveal, no staggered eyebrow, no backdrop zoom. Layout and copy are fully intact.
Polaroids
Three cards stack in their rest offsets without dropping in or fanning on hover. Still visually interesting, just static.
Ticker
Stops scrolling — freezes at the initial x position. Content still reads, so consider trimming string length if the track overflows.
Story
First chapter stays active; other three chapters remain dimmed (autoAlpha 0.4). First frame visible, others stacked behind. Either re-enable runStory or delete the three extra chapters and frames manually.
Origin
Pin released; all four scenes stack in document flow. Consider either keeping the pin or converting the section to a simple 4-column grid in Designer.
Gallery
Pin released; horizontal track becomes a static horizontal row that overflows. Either keep the pin or convert to a native Webflow slider.
Nav & Cursor
Active-state class no longer auto-applies to navbar links (Webflow’s native current-state still works for hash links). Custom cursor disappears — system cursor returns. Nothing breaks.