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.
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.
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.
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.
Hero · Page-load Choreography
Orchestrated entrance timeline that stages every hero element in sequence. Runs once per page load after the preloader splits.
Hero · Polaroid Stack
Three polaroid cards drop from infinity into a loose stack, then fan out when the user hovers the cluster.
Hero · Ticker & Scroll Indicator
Two continuous loops — a horizontal marquee at the hero footer and a vertical pulse inside the scroll indicator.
Story · The Editorial Pin
Sticky visual on the right, narrative chapters on the left. Scroll progress crossfades four frames in sync with chapter activation.
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.
Menu · Editorial Header + Categories
Header sequence (eyebrow → title lines → aside) then six menu categories stagger-reveal on scroll enter.
Selection · Cards Stagger & Hover
Header reveals above, card grid staggers in on scroll, each card scales its media and shifts its arrow on hover.
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.
Gallery · Horizontal Pin
Header reveal above stage, then stage pins while track translates horizontally. Slide images scale on scrub via containerAnimation.
Voices · Editorial Pull-Quotes
Header sequence then three pull-quotes batch-reveal on scroll via ScrollTrigger.batch.
Contact · Header & Pair Reveal
Header sequence, then info column and reserve form pair-reveal together on scroll enter.
Global · Nav Active State & Custom Cursor
Two persistent site-wide behaviors running outside of any timeline. Cursor is pointer-fine only (disabled on touch).
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.
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
var tl = gsap.timeline({
defaults: { ease: "power2.out" },
delay: 0.5 // was 0.25 — raise to wait longer before entrance
});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
gsap.to(tickerTrack, {
xPercent: -50,
duration: 40, // was 60 — lower = faster, higher = slower
ease: "none",
repeat: -1
});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
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).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
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.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
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"
});
});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
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);
}
});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, …)
.to(titleLines, {
yPercent: 0,
duration: 1.4,
stagger: 0.14 // lower (0.08) = tighter · higher (0.22) = more theatrical
}, 0.15);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
// 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
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.
Open the Webflow Designer, select the Home page in the left panel, then open Page Settings (gear icon) and scroll down to Before </body>.
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.
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.
Delete only the two GSAP CDN <script> lines. Keep the font-smoothing <style> block — it controls serif rendering quality and is independent of motion.
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.
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.
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
// gsap.to(tickerTrack, {
// xPercent: -50,
// duration: 60,
// ease: "none",
// repeat: -1
// });
// Now the bottom ticker stays static; every other hero animation remains.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.