HomeStylesTemplates

Loading the story...

Sci-Fi HUD
Kawaii Minimal
←Back to Docs/The Feature
StoryAnatomyPaletteComponents
StyleKit
Data Feature

Scroll to watch the
numbers move

A sticky canvas, stepped narration, one focus at a time — the grammar of a scroll-driven data story.

Start the story ↓
Scroll
’17’18’19’20’21’22’23’24crossover
STEP 01 / 05
Step 01

One line, falling

We start with a single series — a rate sliding downward across eight years. Nothing else on the canvas yet.

Step 02

A second line appears

Now a counter-series fades in and climbs. Two trends, moving in opposite directions.

Step 03

They cross

Around 2020 the lines meet and swap order. This crossover is the whole point of the story.

Step 04

The gap widens

After the crossover the distance between them grows fast — the reversal isn't a blip, it's a trend.

Step 05

Where it lands

By 2024 the reversal is complete. The number that started at the top now sits at the bottom.

0 cross the line

AAnatomy

How the scrolly is wired

No continuous scrub, no layout thrash. A sticky canvas plus IntersectionObserver-triggered discrete states — readable, maintainable, accessible.

01

Sticky canvas

position: sticky; top: 0; height: 100vh pins the visualization while the text column scrolls beside it.

02

IntersectionObserver steps

Each step block is observed with rootMargin -45% 0px -45%, so the canvas flips state only when a step is centered.

03

Discrete states

The canvas moves between a handful of explicit states (0-4) with transform/opacity — never a per-pixel scroll scrub.

const io = new IntersectionObserver((entries) => {
  entries.forEach((e) => {
    if (e.isIntersecting) setState(Number(e.target.dataset.step));
  });
}, { rootMargin: "-45% 0px -45% 0px" });   // fire when centered
steps.forEach((s) => io.observe(s));
BPalette

Dark stage, one signal, one alert

A deep feature base, a signal blue that marks the current focus, and a vermilion reserved for the single contrast moment.

#0E1116
Base
Feature stage
#1C2530
Surface
Panels & inputs
#F7F5F0
Paper
Text & data ink
#2F6FED
Signal
Current focus
#E8503A
Alert
Contrast moment
CComponents

Built for reading data

Clear focus rings, step rails, dark form fields — the controls of an interactive feature, not a marketing page.

DGuidelines

Do / Don't

Do

  • +Pin a sticky canvas; scroll text steps over it
  • +Trigger discrete states with IntersectionObserver
  • +Reveal one focus per step
  • +Keep real numbers in the DOM (aria-label) beside count-ups
  • +Transition canvas states with transform/opacity only
  • +Make transitions instant under prefers-reduced-motion

Don't

  • ×Read offsetTop in a scroll handler for continuous scrub
  • ×Cram multiple new facts into one step
  • ×Animate layout props (top/width/height) on states
  • ×Let a count-up be the only source of a number
  • ×Let the canvas crowd out text on mobile
  • ×Use more than one signal and one alert color

Scrollytelling — scrolling is playback.

←Back to all styles