
Standing letters with a long shadow
Text, Scroll, 3D
NewFree
Scroll inside the preview
The index of a long story on a personal journal, in the minimal style: as you scroll, the chapter you are reading sits at the top, large and heavy, with a thin blue bookmark; once finished it shrinks, steps aside and goes down to the bottom among the ones already read, grey and narrow on the wdth axis, while the others climb one row each on a spring and the next one grows into its place. At the top the minutes left count down.
A folder that runs on its own: index.html, style.css, script.js and the libraries from a CDN. The React and Vue tabs hold the same demo as a ready component, which switches its animations off when it leaves the page.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>The index that follows the reading</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/instrument-sans@5.3.0/wdth.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- the index of a long essay on a made-up personal journal. Scrolling, the chapter being read climbs to the top of
the index and grows; when it is done it steps aside, shrinks, narrows and goes to the bottom with the chapters
already read, while the next one rises in its place -->
<main>
<section class="apertura">
<p class="piccolo">Odalo, a journal</p>
<h1 class="titolo">A year<br>on foot.</h1>
<p class="piccolo piccolo--tenue">Scroll to read along.</p>
</section>
<section class="racconto" data-racconto>
<div class="palco" data-palco>
<header class="testa">
<p class="marchio">Odalo</p>
<p class="piccolo piccolo--tenue"><span class="resto" data-resto>25</span> min left</p>
</header>
<nav class="indice" aria-label="Chapters" data-indice>
<ol class="voci" data-voci></ol>
<i class="filo filo--sopra" data-filo-sopra aria-hidden="true"></i>
<i class="filo filo--letti" data-filo-letti aria-hidden="true"></i>
<i class="nastro" data-nastro aria-hidden="true"></i>
</nav>
</div>
</section>
<section class="apertura apertura--fine">
<h2 class="titolo titolo--medio">Thanks for<br>walking along.</h2>
</section>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/ScrollTrigger.min.js"></script>
<script src="script.js"></script>
</body>
</html>Change values, colours and text with the controls and watch the animation respond live. Or write in the code yourself. Then download the folder with your changes.
29 values to change
With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:
Take “The index that follows the reading” from Animorio and fit it into my siteThe chapters are absolute li elements inside a pinned stage (position: sticky, 100lvh tall) and never change order in the DOM. At chapter k every entry j sits in place (j − k + N) mod N: place 0 is the top, then the ones to read, then the read ones, set apart by a small gap. A function gives the y of every place, and the drawing only sets transform, font-size and font-variation-settings.
The timeline, with scrub SCRUB, takes a number p from 0 to the number of chapters minus one. The whole part is the chapter being read, the rest is the change: for the first part (HOLD) the index stays still, for the rest every entry goes from its place to the place of the next chapter. Everything is computed from p, so scrolling back the index puts itself back in order.
The chapter just read shrinks in the first half (power3.inOut), then goes down on an arc: x = sin(π·t) times a distance, so it passes beside the other entries, and it arrives last. The others climb one row with the SETTLE curve, each STAGGER later than the one above, and clear the place before it arrives. The next one rises and grows with the same curve: the top goes a hair too far and comes back.
Instrument Sans is variable in weight (400–700) and width (75–100). The three kinds of entry each have their look (being read 640 and 100, to read 470 and 100, read 420 and 76 in grey) and during the change the values blend: the read entry narrows and greys as it goes down. The colour blends with gsap.utils.interpolate between the two CSS variables.
The bookmark is a 2 pixel wide element scaled in height: it closes with power2.in and opens again with the SETTLE curve. The hairline over the read chapters draws itself with scaleX the first time, then sits halfway in the gap above the first read one. The minutes left take away each chapter’s minutes as you pass it.
| Name | File | Default | What it changes |
|---|---|---|---|
CHAPTERS | script.js | [['Leaving', 4], ['The coast road', 7], …] | The chapters: title and minutes of reading. |
BIG | script.js | 1 | How big the chapter being read is, compared to the page (0.6 to 1.4). |
SETTLE | script.js | 'back.out(1.5)' | The curve the chapters land in their rows with: the number in brackets is how far they overshoot. |
STAGGER | script.js | 0.07 | How far apart the climbing entries leave, as a part of the change. |
HOLD | script.js | 0.35 | The part of every chapter in which the index stays still, from 0 to 0.8. |
SCRUB | script.js | 0.6 | How many seconds the index takes to catch up with the scroll. |
For a long article, a story in chapters, a guide or a manual: beside the real text, as a pinned index that says where you are and how much is left. It works with three to seven chapters with short titles; with more the list no longer fits on a screen.
The same, with adapted measures: the index takes the whole width, the title at the top is smaller, the rows tighter and the arc of the chapter going down wider, to pass beside the other entries.
No flights and no bounces: at the end of every chapter the index fades out and comes back already in its new order, with the bookmark beside the next chapter; the minutes still count.
GSAP 3.15.0, ScrollTrigger (GSAP) 3.15.0, Instrument Sans (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 6.1 KB; the libraries: GSAP + ScrollTrigger 45 KB.
Tested on 19 October 2026
Use it in your own projects and in your clients’ projects. Do not resell it or redistribute it as is. GSAP stays under its own Standard license. Full license.
With your account’s email and password.
or with your email
You’re signed in as .
With your account, you can download the zip of every animation and every pack, for free.