
Standing letters with a long shadow
Text, Scroll, 3D
NewFree
Scroll inside the preview
Four pale cards with a figure each, which counts up from zero as it arrives. Then the scroll lights them one at a time: the pale veil lifts off a room, the words turn white and the card before goes back to sleep.
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 figures that light up</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/instrument-serif@5.3.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/instrument-serif@5.3.0/400-italic.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/roboto-condensed@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- the about section of a made-up interior studio. Four pale cards with a figure each count up from zero when they
arrive; then, as you scroll, one card at a time lights up: the pale veil lifts off a room and the words turn
white, and the card before goes back to sleep -->
<main>
<section class="apertura">
<p class="etichetta">The studio</p>
<h1 class="titolo">Nothing in a room<br>is there by chance.</h1>
<p class="testo">Scroll down to read us in four figures.</p>
</section>
<section class="racconto" data-racconto>
<div class="palco">
<header class="testa">
<p class="etichetta etichetta--parentesi">
<svg viewBox="0 0 6 16" aria-hidden="true"><path d="M5 1H1v14h4" fill="none" stroke="currentColor" stroke-width="1"/></svg>
in figures
<svg viewBox="0 0 6 16" aria-hidden="true"><path d="M1 1h4v14H1" fill="none" stroke="currentColor" stroke-width="1"/></svg>
</p>
<h2 class="titolo titolo--medio">About us.</h2>
</header>
<div class="finestra" data-finestra>
<ol class="carte" data-carte>
<li class="carta" data-carta>
<div class="carta__stanza" data-stanza="5"></div>
<div class="carta__buio"></div>
<div class="carta__velo" data-velo></div>
<p class="carta__testo" data-testo><span>Years in Seville</span><b class="carta__cifra" data-cifra="12">12</b></p>
</li>
<li class="carta" data-carta>
<div class="carta__stanza" data-stanza="18"></div>
<div class="carta__buio"></div>
<div class="carta__velo" data-velo></div>
<p class="carta__testo" data-testo><span>Years in practice</span><b class="carta__cifra" data-cifra="19">19</b></p>
</li>
<li class="carta" data-carta>
<div class="carta__stanza" data-stanza="33"></div>
<div class="carta__buio"></div>
<div class="carta__velo" data-velo></div>
<p class="carta__testo" data-testo><span>Homes in Spain</span><b class="carta__cifra" data-cifra="41">41</b></p>
</li>
<li class="carta" data-carta>
<div class="carta__stanza" data-stanza="52"></div>
<div class="carta__buio"></div>
<div class="carta__velo" data-velo></div>
<p class="carta__testo" data-testo><span>Homes abroad</span><b class="carta__cifra" data-cifra="96">96</b></p>
</li>
</ol>
</div>
<p class="testo testo--sotto">Proportion sets the structure, material sets the tone, and light shapes the space.</p>
</div>
</section>
<section class="apertura apertura--fine">
<h2 class="titolo titolo--medio">Start with a conversation.</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 figures that light up” from Animorio and fit it into my siteEach card has four layers one over the other: the drawn room, a half black veil, the cream veil and the words. When asleep, the cream veil covers everything and the words are the --spenta colour; when lit, the cream veil is transparent and the words are LIT. The black veil never moves: it is there only so white words read over the room.
An IntersectionObserver watches the cards and, when one is on screen by at least COUNT_AT, makes its figure count up from zero once only: a tween on a number, in COUNT_TIME seconds with power1.out, that writes the rounded value at every step. It is the same curve as the site, 1 minus the square of what is left.
The section is 420lvh tall and the stage inside it is sticky. A timeline with ScrollTrigger, from START to the end of the section with scrub SCRUB, lights card number i at beat i, over one beat, and puts it out at beat i + 1, while the next one lights up. The last one has no putting out, so it stays lit. The curves are EASE.
The words go from one colour to the other with a tween on color. The starting value is read from --spenta with getComputedStyle, so changing the colour in the CSS also changes the one the card goes back to when it goes out.
Below 768 pixels the cards are three quarters of the screen wide and sit in a row wider than the screen. gsap.matchMedia adds to the same timeline, at the same beat as each lighting, a sideways move that brings the card to the middle, with power2.inOut and without leaving the edges of the row.
| Name | File | Default | What it changes |
|---|---|---|---|
SCRUB | script.js | 0.8 | How long the cards take to catch up with the scroll (0.8 on the site). |
START | script.js | 'top -20%' | When the first card lights up (top -20% on the site). |
EASE | script.js | 'power2.out' | The curve of the veil and the words (power2.out on the site). |
COUNT_TIME | script.js | 1 | How many seconds a figure takes to count (1 on the site). |
COUNT_AT | script.js | 0.2 | How much of a card must show before its figure counts (0.2 on the site). |
LIT | script.js | '#ffffff' | The colour of the words on a lit card. |
For the figures of a studio, a company, an association: years, projects, people, cities. Four figures is the right number; with more cards the section must be made longer.
The same, with wide cards and the row sliding sideways along with the scroll, one card in the middle at a time.
The figures are already written and all four cards are already lit, with no counting and no movement; on a phone the row scrolls under the finger.
GSAP 3.15.0, ScrollTrigger (GSAP) 3.15.0, Instrument Serif 5.3.0, Roboto Condensed (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 6.6 KB; the libraries: GSAP + ScrollTrigger 45 KB.
Tested on 8 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.