Skip to content
animorio
IT
All components

The password on the time ruler

Forms, SVG, PhysicsGSAPAdvancedCompressed weight: Demo 13 KBGSAP 28 KBFreeDownload the zip

On black, the new password of an account measured in time: how long a computer would need to guess it, on a logarithmic ruler from a second to ten thousand years. The needle sits on a spring and the ticks near it rise as it passes; past the dashed line of a century the ruler turns amber. The estimate is made here, reading the password in pieces (common passwords, words, years, runs, keyboard rows, repeats), and the weak pieces are bracketed under the password, drawn as a row of thin bars.

The code

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 password on the time ruler</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/hubot-sans@5.3.0/wdth.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/jetbrains-mono@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- a new password measured in time: how long a computer would take to guess it, on a ruler that runs from a
         second to ten thousand years. The weak parts are bracketed under the password. Creating the account is
         pretended: see post() in the script -->
    <form class="pw" action="#" novalidate aria-labelledby="pw-title" data-pw data-autoclic>
      <h2 class="pw__title" id="pw-title">Choose a password</h2>
      <p class="pw__for">for your Margin account, mira@kiln.studio</p>
      <input class="sr" type="email" name="username" autocomplete="username" value="mira@kiln.studio" readonly tabindex="-1" aria-hidden="true">

      <label class="pw__label" for="pw-input">Password</label>
      <div class="pw__box" data-box>
        <div class="pw__slot" data-slot>
          <input class="pw__input" id="pw-input" name="password" type="password" autocomplete="new-password" autocapitalize="off" autocorrect="off" spellcheck="false" enterkeyhint="done" maxlength="64" aria-describedby="pw-status" aria-invalid="false" data-input>
          <span class="pw__cells" aria-hidden="true" data-cells></span>
          <span class="pw__caret" aria-hidden="true" data-caret></span>
        </div>
        <button class="pw__show" type="button" aria-pressed="false" aria-controls="pw-input" data-show>Show</button>
      </div>
      <div class="pw__marks-clip"><div class="pw__marks" aria-hidden="true" data-marks></div></div>

      <div class="ruler" aria-hidden="true" data-ruler>
        <span class="ruler__tag" data-tag><span data-tag-text>a second</span></span>
        <svg class="ruler__svg" data-svg>
          <path class="ruler__ticks" data-ticks/>
          <path class="ruler__base" data-base/>
          <path class="ruler__fill" data-fill/>
          <path class="ruler__goal" data-goal/>
          <path class="ruler__needle" data-needle/>
        </svg>
        <div class="ruler__units" data-units></div>
      </div>

      <p class="pw__status" id="pw-status" data-status><span class="status__line">Measured in the time a computer would need to guess it.</span></p>

      <button class="make" type="submit" data-make>
        <span class="make__bg" aria-hidden="true"></span>
        <span class="make__label" data-make-label>Create account</span>
      </button>
      <p class="sr" role="status" aria-live="polite" data-live></p>
    </form>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="script.js"></script>
</body>
</html>

Playground

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.

22 values to change

Or ask Claude Code for it

With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:

Take “The password on the time ruler” from Animorio and fit it into my site

What it does

On a black page the title Choose a password and under it for your Margin account, mira@kiln.studio. Below, the dark Password field with Show on the right, and under it a thin ruler full of ticks, with the words second, minute, hour, day, month, year and, in amber, century beside a dashed line; above the ruler, on the left, a second. On arrival the needle runs to the middle of the ruler and back, and the ticks rise as it passes. Every character typed is a white bar growing from below with a small bounce. As you type the needle moves back and forth on the ruler, on a spring, with the ticks near it raised in a dome and the words above saying how long it takes to guess it (in 2 minutes); under the password thin brackets appear over the weak pieces, with their name: word, year, common, run, key row, repeat, and the line under the ruler spells them out (garden is in every word list, and 1994 looks like a year.). Show turns the bars into the letters one after the other, Hide turns them back into bars. Pressing Create account with a weak password the field takes an amber edge and jolts, the needle tries to run to the century line and falls back, and the line says to aim past a century. Past the line the ruler up to the needle, the needle and the words turn amber, so does the button, and it reads Strong enough. Pressing it the button says Creating your account and then Account created, the bars rise in a wave and settle, and the line says Saved. with Start over.

How it works

Reading the password in pieces

From every position the longest known piece is looked for: one of the nearly hundred most used passwords, a word (about 450, each with its rank times 20, as if among the words of a real dictionary), with the usual swaps (4 for a, 0 for o, @ for a) and capitals, a year between 1900 and 2099, a run like abcd or 4321, a keyboard row, a repeated character. Each piece is worth the guesses it takes to reach it; the characters left over are worth as many as the password’s possible characters, one by one. The product, divided by RATE guesses a second, is the seconds.

The logarithmic ruler

The ruler goes from a tenth of a second to ten thousand years in powers of ten: small ticks every quarter power, medium ones at every power, tall ones on second, minute, hour, day, month, year and GOAL years, marked by a dashed line. The ticks’ SVG path is rewritten at every frame: each rises BULGE pixels times a Gaussian of its distance from the needle, so the ticks make a dome that follows the needle.

The needle on the spring

The needle is a spring (STIFF, DAMP) integrated in small steps on the GSAP ticker, which sleeps when it is still: as you type the target changes at every key and the needle chases it without jumps. Pressing the button with a weak password it gets a push towards the century line and falls back. The words above follow it while staying inside the ruler, and change with a small vertical fade.

A real password field, drawn as bars

The field is an input type=password with autocomplete new-password and a hidden username for password managers; its dots are transparent and over it sits one cell per character, as wide as a character of JetBrains Mono (the field’s own type, so the caret falls right). In the cell there are a bar and the letter: Show switches to type=text and folds the bars into the letters one after the other. The new cells are found with the longest common subsequence, so typing in the middle only moves the ones after it.

Values to change

NameFileDefaultWhat it changes
RATEscript.js10000The guesses a second of the attack measured: 10,000 is a stolen list of passwords stored with a slow hash.
GOALscript.js100The years a password has to hold out to be strong enough.
SHORTESTscript.js8The fewest characters a password may have.
STIFFscript.js240How stiff the needle’s spring is.
DAMPscript.js20How much the needle’s spring is held back: lower, it swings further past.
BULGEscript.js14How far the ticks near the needle rise, in pixels.
WAITscript.js0.8How many seconds the pretended account creation takes.

Try them in the Playground

When to use it

In the sign-up or password change of an app, a service, a customer area: a time (in 2 minutes, in billions of years) is understood better than a red or green bar, and the brackets say why a password is weak. It also works in the security settings of an account.

On phones

The block takes the width of the screen; the ruler keeps second, hour, day, year and century (minute and month are hidden) and the ticks get closer. The field opens the keyboard without autocorrect and the Enter key says Done; Show is tapped as a 42-pixel button. A password longer than the field scrolls and the bars and brackets scroll with it.

With reduced motion

The needle jumps straight to its place, with no spring and no opening sweep; the ticks stay raised where the needle is. The bars appear without growing, Show swaps bars and letters in one go, the brackets and messages fade in, and on sending there is no wave.

Pitfalls

  • With a dictionary of a few hundred words, each was worth its place in the list, and a sentence of four real words came out guessable in a month. Now a word’s place counts twenty times, as if in the list of the commonest words of a real dictionary: four random words pass the century, a word and a year do not.
  • With a password longer than the field, the input scrolls and the bars follow it, but the brackets underneath came out past the field’s left edge: they now sit in a strip that clips whatever leaves it.
  • The dots of a password field and the letters of JetBrains Mono are the same width in Chrome (449 pixels for 44 characters in both modes): that is what makes the real caret fall on the drawn bars. In Safari the dots are another character and it needs trying.
  • Redrawing the brackets with an empty list called GSAP on nothing and the console said target not found: it is now checked first.

Libraries

GSAP 3.15.0, Hubot Sans (font variabile) 5.3.0, JetBrains Mono (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 13 KB; the libraries: GSAP 28 KB.

Testing

Tested on 19 October 2026

  • Desktop: Done
  • Phone: Done
  • Reduced motion: Done
  • Safari on iPhone: To do

License

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.

All components