Command Palette

Search for a command to run...

Hectal
Shots in this scene
SHOT 0.5Beginner ~19 min · shot 5 of 6

The lumen-motion Project

In one line

You will build one project all course: the launch page of the Lumen Volt e-bike. It starts complete and still; each phase gives one part motion. Every file has a place in one folder layout that never changes.

0/6 · 0%

Think of it like this

Animators on a film do not start by drawing a new world. The set and the characters are designed first; then each scene is brought to life, shot by shot. The Lumen Volt page is your finished set. Each phase animates one scene.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

build-along
A course where one project grows from phase to phase, instead of separate small demos.
motion token
A named value for motion, such as --dur-base: 220ms, used everywhere instead of typing numbers by hand. Phase 2 starts them; Phase 18 finishes them.
motion spec
A short document that lists each animation: what triggers it, what changes, how long it takes, its easing, and its reduced-motion version.
storyboard
A few sketches of key moments of an animation, drawn before any code, so the team agrees on what should happen.

Step by step

01The folder tree

This is the layout you will have by the end. You start with four files and add the rest phase by phase.

lumen-motion/whole filetext
lumen-motion/
├── package.json            scripts and pinned versions
├── vite.config.js          two pages: index.html and ride.html (Phase 11)
├── index.html              the Lumen Volt launch page
├── ride.html               the ride page (Phase 11)
├── src/
│   ├── styles/
│   │   ├── tokens.css      motion tokens (Phase 2, finished in 18)
│   │   ├── base.css        page layout and type
│   │   ├── components.css  buttons, toast, drawer, cards, gallery
│   │   ├── scroll.css      scroll-driven effects (Phase 12)
│   │   └── motion-safe.css reduced motion and the site toggle (Phase 7)
│   ├── js/
│   │   ├── main.js         wires everything
│   │   ├── motion/         loop.js, prefers-reduced.js, spring.js, flip.js
│   │   ├── components/     toast, cart, drawer, gallery, transitions, mascot, confetti
│   │   └── gsap/           the launch timeline (Phase 14)
│   ├── react/              the bike configurator (Phase 15)
│   └── assets/
│       ├── svg/            logo and route line (Phase 13)
│       └── mascot/         headlight.lottie (Phase 16)
├── docs/
│   └── motion-spec.md      storyboard and spec (Phase 2)
└── tests/
    ├── motion.test.js      Vitest (Phase 18)
    └── launch.spec.js      Playwright (Phases 18 and 19)

02Replace the starter files

Vite's starter has src/main.js, src/counter.js and src/style.css. Delete counter.js and style.css, and create src/styles/ and src/js/. Topic 0.6 gives you the four files of the still page.

03One part per phase

Each phase animates one part of the page: the buttons in Phase 3, a toast in Phase 4, the accessory grid in Phase 5, and so on. Click a part of the map below to see which phases touch it.

04Keep the names

Later phases import functions and find elements by name: showToast in toast.js, the cart count #cart-count, the gallery's .photo elements. Keep the names the build topics use, so every phase's code fits the last one.

Try it yourself

  1. 1

    Plan your own order

    Click every part of the map. Which part gets the most phases? (The hero: a loading bar, a jank fix, a GSAP launch timeline and the confetti.) Pick the part you are most curious about and look up its phase in the course outline.

  2. 2

    Look at the highlight's track

    Click one part, then another, and look at the timeline. The first click starts five tracks, not two: background-color, plus one for each side of the border (border-top-color, border-right-color, border-bottom-color, border-left-color), because border-color is a shorthand the browser splits into four properties. The second click on another part shows ten: five for the part that turns on and five for the part that turns off (they replace the first click's five). All are 160 ms. The background track is green (Chromium composites background-colour animations); the four border tracks are amber, because border colours repaint.

Code & diagrams

Which phase animates which part?

A map of the launch page. Click a part: it highlights with 160 ms colour transitions (the timeline shows which repaint) and the line below names the phases that animate it.

Press Run to see the page.
00:00.000
animations
0.00s0.10s0.20s0.30s0.40s0.50s0.60s0.70s0.80s0.90s

Nothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.

frames

Console

Nothing logged yet.

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Rename a part's class

In the HTML of "Which phase animates which part?", change the first class="part" to class="parts", then click "Header · cart".

terminal
$ Click "Header · cart"
── what you'll see ──
Nothing happens: no highlight, no text below, no error in the console.

Myth vs fact

Myth

A demo per technique teaches as much as one project.

Fact

Demos skip the hard part: making many animations live together with shared tokens, one reduced-motion system and clean-up when parts are removed. The growing project makes you solve that.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    Keeping motion values in tokens.css from Phase 2 means a later change ("make everything 20% faster on mobile") is one edit, not a search through every file. Phase 18 adds a JavaScript mirror so CSS and JavaScript animations share the same numbers.

  • ▸

    The page works with JavaScript off and with reduced motion on before any animation is added. Every phase keeps both true: motion is an enhancement on top of a working page, never a requirement for it.

Remember this

  1. 1

    The problem this solves: small separate demos teach techniques but not how they live together: one motion system, one set of tokens, reduced motion everywhere, nothing leaking when a part is removed. A single growing project forces those questions, the way a real job does.

  2. 2

    The story. Lumen Bikes rents bikes across the island city of Ardenvale and is launching its first e-bike, the Volt. The team: Ama (head of design, wants "alive but calm"), Kofi (frontend engineer, owns the code), Mei (motion designer, makes storyboards and animation files), Lena (QA, tests on a cheap Android phone and a 120 Hz iPhone), Ravi (accessibility tester, who has a vestibular disorder and uses reduced motion and a screen reader) and Tomás (the founder). Each phase opens with the moment that needs its skill.

  3. 3

    The page. A header with the Lumen logo and a cart button; a hero with the Volt, its price and a Reserve button; six accessories you can add to the cart; a gallery you can filter by colour; specs in collapsible sections; a footer. In later phases it gains a toast area, a cart drawer, a ride page, a scroll story, a React configurator, a mascot and confetti.

  4. 4

    The folder layout (it stays the same all course, and each build topic says which files it adds or changes): index.html and later ride.html at the top; src/styles/ for tokens.css (motion tokens), base.css, components.css, scroll.css and motion-safe.css; src/js/ for main.js, your own helpers in motion/, the parts in components/ and the GSAP code in gsap/; src/react/ for the configurator; src/assets/ for SVG and the mascot file; docs/motion-spec.md; and tests/. The full tree is below.

  5. 5

    From this page to your files. Examples on this page are single pages: HTML, CSS and JavaScript tabs. Your project splits the same code across files. Each build topic shows every changed file in full under "Your project files", and its last live example is the same code merged into one page, so you can see it run here before you copy it.

Explain it without notes

01

Why does the course build one project instead of separate demos?

02

What are motion tokens and why start them early?

Practice

01

Draw the launch page on paper, one box per part, and write next to each box what you would like it to do when it moves. Keep the sheet: Phase 2 turns it into a motion spec.

02

In your Vite project, create the folders src/styles, src/js, src/js/motion, src/js/components and docs, and delete the starter's counter.js and style.css.

Done when you can

  • You can describe the Lumen Volt page and its parts

  • You know the folder layout and where each kind of file goes

  • You know the team and why Ravi's reduced-motion rule matters